- New i18n.js module: window.DCI18n.t(key), language dropdown selector - Supports 5 languages (en, es, fr, de, ar) with RTL for Arabic - Translations loaded from /api/v1/i18n/translations/:lang - Language preference persisted in localStorage - Added to features.js bundle
1989 lines
1.1 MiB
Plaintext
1989 lines
1.1 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 y=document.getElementById("logo-modal"),C=document.getElementById("logo-preview-dark"),O=document.getElementById("logo-preview-light"),E=document.getElementById("logo-status"),M=document.getElementById("logo-same-both"),R=document.getElementById("logo-dual-uploads"),P=document.getElementById("logo-single-upload"),A=document.getElementById("logo-upload-dark"),p=document.getElementById("logo-upload-light"),T=document.getElementById("logo-upload-single"),x=document.querySelector("#brand .brand-logo-dark"),$=document.querySelector("#brand .brand-logo-light"),k=document.querySelector(".top-row"),H=document.getElementById("dashboard-title"),L=DC.NAME;let u=null,j=null,v=null,N="left",g=L;M?.addEventListener("change",()=>{M.checked?(R.style.display="none",P.style.display="",u=null,j=null):(R.style.display="flex",P.style.display="none",v=null)});function D(n,e){if(!n||!n.type.startsWith("image/")){showNotification("Please select an image file","warning");return}const t=new FileReader;t.onload=o=>e(o.target.result),t.readAsDataURL(n)}A?.addEventListener("change",n=>{D(n.target.files[0],e=>{u=e,C.src=e,E.textContent="New dark logo ready to save"})}),p?.addEventListener("change",n=>{D(n.target.files[0],e=>{j=e,O.src=e,E.textContent="New light logo ready to save"})}),T?.addEventListener("change",n=>{D(n.target.files[0],e=>{v=e,C.src=e,O.src=e,E.textContent="New logo ready to save (both themes)"})});function B(n){k.setAttribute("data-logo-pos",n),document.querySelectorAll(".logo-pos-btn").forEach(e=>{e.style.background=e.dataset.pos===n?"var(--accent)":"var(--card-bg)",e.style.color=e.dataset.pos===n?"white":"var(--fg)"})}function f(n){g=n||L,document.title=g;const e=document.querySelector(".dashboard-title");e&&(e.textContent=g)}async function I(){try{const n=await fetch("/api/v1/logo");if(n.ok){const e=await n.json();e.customLogoDark&&(x.src=e.customLogoDark,C.src=e.customLogoDark),e.customLogoLight&&($.src=e.customLogoLight,O.src=e.customLogoLight),!e.customLogoDark&&!e.customLogoLight&&e.customLogo&&(x.src=e.customLogo,$.src=e.customLogo,C.src=e.customLogo,O.src=e.customLogo),e.isDefault||(E.textContent="Using custom logo"),e.position&&(N=e.position,B(e.position)),e.dashboardTitle&&f(e.dashboardTitle)}}catch(n){console.warn("Could not load custom logo:",n.message)}}document.querySelectorAll(".logo-pos-btn").forEach(n=>{n.addEventListener("click",()=>{N=n.dataset.pos,B(N)})}),document.getElementById("brand")?.addEventListener("click",()=>{u=null,j=null,v=null,A&&(A.value=""),p&&(p.value=""),T&&(T.value=""),M&&(M.checked=!1),R.style.display="flex",P.style.display="none",C.src=x.src,O.src=$.src;const n=x.src.includes("custom-logo")||$.src.includes("custom-logo");E.textContent=n?"Using custom logo":"Using default logos",B(N),H.value=g,y.classList.add("show")}),document.getElementById("logo-save")?.addEventListener("click",async()=>{try{const n=H.value.trim()||L,e={position:N,dashboardTitle:n};M?.checked&&v?(e.dataDark=v,e.dataLight=v):(u&&(e.dataDark=u),j&&(e.dataLight=j));const t=await secureFetch("/api/v1/logo",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(t.ok){const o=await t.json(),r="?t="+Date.now();o.pathDark&&(x.src=o.pathDark+r,C.src=o.pathDark+r),o.pathLight&&($.src=o.pathLight+r,O.src=o.pathLight+r),B(N),f(n),y.classList.remove("show")}else{const o=await t.json();showNotification("Failed to save: "+o.error,"error")}}catch(n){showNotification("Error saving: "+n.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",C.src="/assets/dashcaddy-logo-dark.png",O.src="/assets/dashcaddy-logo-light.png",E.textContent="Using default logos",u=null,j=null,v=null,H.value=L,f(L),N="left",B("left")),(await secureFetch("/api/v1/favicon",{method:"DELETE"})).ok){const t=document.querySelector('link[rel="icon"]'),o=document.getElementById("favicon-preview"),r=document.getElementById("favicon-status");t&&(t.href="/assets/dashcaddy-favicon.ico?t="+Date.now()),o&&(o.src="/assets/dashcaddy-favicon.ico?t="+Date.now()),r&&(r.textContent="Using DashCaddy favicon"),l=null}}catch(n){showNotification("Error resetting branding: "+n.message,"error")}}),wireModal(y,document.getElementById("logo-cancel"));const b=document.getElementById("favicon-preview"),z=document.getElementById("favicon-status"),i=document.getElementById("favicon-upload"),c=document.querySelector('link[rel="icon"]')||document.createElement("link");let l=null;document.querySelector('link[rel="icon"]')||(c.rel="icon",c.href="/assets/dashcaddy-favicon.ico",document.head.appendChild(c));async function w(){try{const n=await fetch("/api/v1/favicon");if(n.ok){const e=await n.json();e.customFavicon&&(c.href=e.customFavicon+"?t="+Date.now(),b.src=e.customFavicon+"?t="+Date.now(),z.textContent="Using custom favicon")}}catch(n){console.warn("Could not load custom favicon:",n.message)}}i?.addEventListener("change",n=>{const e=n.target.files[0];if(!e)return;if(!e.type.match(/^image\/(png|svg\+xml)$/)){showNotification("Please select a PNG or SVG file","warning"),i.value="";return}const t=new FileReader;t.onload=o=>{l=o.target.result,b.src=l,z.textContent="New favicon ready to save"},t.readAsDataURL(e)}),document.getElementById("logo-save")?.addEventListener("click",async()=>{if(l)try{const n=await secureFetch("/api/v1/favicon",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:l})});if(n.ok){const e=await n.json();c.href=e.path+"?t="+Date.now(),b.src=e.path+"?t="+Date.now(),z.textContent="Using custom favicon",l=null}else{const e=await n.json();showNotification("Failed to save favicon: "+e.error,"error")}}catch(n){showNotification("Error saving favicon: "+n.message,"error")}}),w(),I();const m=document.getElementById("settings-timezone");m&&(new MutationObserver(()=>{y.classList.contains("show")&&m.options.length===0&&(async()=>{let e;try{const t=await fetch("/api/v1/config");t.ok&&(e=(await t.json()).timezone)}catch{}window.populateTimezoneSelect(m,e)})()}).observe(y,{attributes:!0,attributeFilter:["class"]}),document.getElementById("logo-save")?.addEventListener("click",async()=>{const e=m.value;if(e)try{const t=await fetch("/api/v1/config");if(!t.ok)return;const o=await t.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(t){console.warn("Failed to save timezone:",t.message)}}))})(),window.populateTimezoneSelect=function(y,C){const O=Intl.supportedValuesOf("timeZone"),E=C||Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC";y.innerHTML="";for(const M of O){const R=document.createElement("option");R.value=M,R.textContent=M.replace(/_/g," "),M===E&&(R.selected=!0),y.appendChild(R)}},(function(){let y="homelab",C=null;async function O(){try{const D=await fetch("/api/v1/config");if(D.ok&&(C=await D.json(),C&&C.setupComplete))return document.getElementById("setup-wizard").style.display="none",!0}catch(D){console.warn("Could not fetch server config, checking localStorage fallback:",D.message)}return safeGet("dashcaddy-setup")?(document.getElementById("setup-wizard").style.display="none",!0):(document.getElementById("setup-wizard").style.display="flex",!1)}O();const E=document.getElementById("setup-timezone");E&&window.populateTimezoneSelect(E);function M(g){document.querySelectorAll(".setup-step").forEach(B=>{B.style.display="none"});const D=document.getElementById(g);D&&(D.style.display="block")}function R(){const g=document.getElementById("setup-summary-content");if(!g)return;let D='<div style="display: grid; gap: 20px;">';if(y==="homelab"){const f=document.getElementById("setup-tld")?.value?.trim()||".home",I=document.getElementById("setup-ca-name")?.value?.trim()||"",b=document.getElementById("setup-dns-ip")?.value?.trim()||"",z=document.getElementById("setup-dns-port")?.value?.trim()||DC.DEFAULTS.DNS_PORT;D+=`
|
|
<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> ${f}</div>
|
|
<div><strong>Certificate Authority:</strong> ${I}</div>
|
|
<div><strong>DNS Server:</strong> ${b}:${z}</div>
|
|
<div><strong>Example URLs:</strong> https://uptime${f}, https://nextcloud${f}</div>
|
|
</div>
|
|
</div>
|
|
`}else if(y==="simple"){const f=document.getElementById("setup-simple-ip")?.value?.trim()||"localhost";D+=`
|
|
<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> ${f}</div>
|
|
<div><strong>SSL:</strong> None (HTTP only)</div>
|
|
<div><strong>Example URLs:</strong> http://${f}:8080, http://${f}:3000</div>
|
|
</div>
|
|
</div>
|
|
`}else if(y==="public"){const f=document.getElementById("setup-public-domain")?.value?.trim()||"",I=document.getElementById("setup-public-email")?.value?.trim()||"",b=document.querySelector('input[name="routing-mode"]:checked')?.value||"subdirectory",z=b==="subdirectory"?`https://${f}/sonarr, https://${f}/grafana`:`https://sonarr.${f}, https://grafana.${f}`;D+=`
|
|
<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> ${f}</div>
|
|
<div><strong>SSL:</strong> Let's Encrypt</div>
|
|
<div><strong>Email:</strong> ${I}</div>
|
|
<div><strong>Routing:</strong> ${b==="subdirectory"?"Subdirectory (domain.com/app)":"Subdomain (app.domain.com)"}</div>
|
|
<div><strong>Example URLs:</strong> ${z}</div>
|
|
</div>
|
|
</div>
|
|
`}const B=document.getElementById("setup-timezone")?.value||Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC";D+=`
|
|
<div style="margin-top: 8px; padding-top: 12px; border-top: 1px solid var(--border);">
|
|
<div style="font-size: 0.95rem;"><strong>Timezone:</strong> ${B.replace(/_/g," ")}</div>
|
|
</div>
|
|
`,D+=`
|
|
<div style="margin-top: 12px; padding: 12px 14px; border-radius: 8px; border: 1px solid var(--warn-fg, #f39c12); background: color-mix(in srgb, var(--warn-fg, #f39c12) 8%, transparent);">
|
|
<div style="display: flex; gap: 8px; align-items: flex-start;">
|
|
<span style="font-size: 1.1rem;">\u{1F4BE}</span>
|
|
<div style="font-size: 0.85rem; line-height: 1.45;">
|
|
<strong style="color: var(--warn-fg, #f39c12);">Disk-space tip:</strong>
|
|
Health-check monitoring records uptime, response-time, and incident data continuously.
|
|
By default DashCaddy keeps <strong>30 days</strong> of history and warns at <strong>80% disk usage</strong>.
|
|
You can tune the retention period, polling interval, and disk threshold later under
|
|
<strong>Health \u2192 Configure \u2192 Global Settings</strong>.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`,D+="</div>",g.innerHTML=D,M("setup-step-summary")}async function P(g){try{const D=await secureFetch("/api/v1/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(g)});return D.ok?(await D.json(),!0):(errorHandler.logError("[SetupWizard] Save Config",new Error(`Server returned ${D.status}`),{function:"saveConfigToServer"}),!1)}catch(D){return errorHandler.logError("[SetupWizard] Save Config",D,{function:"saveConfigToServer"}),!1}}async function A(){const g={setupComplete:!0,configurationType:y,timestamp:new Date().toISOString(),timezone:document.getElementById("setup-timezone")?.value||Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC"};if(y==="homelab"){g.tld=document.getElementById("setup-tld")?.value?.trim()||".home",g.caName=document.getElementById("setup-ca-name")?.value?.trim()||"";const I=document.getElementById("setup-dns-provider")?.value||"technitium";g.dns={provider:I,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()||""},g.defaults={dnsType:"private",sslType:"internal",targetIP:"localhost"}}else y==="simple"?(g.defaultIP=document.getElementById("setup-simple-ip")?.value?.trim()||"localhost",g.defaults={dnsType:"none",sslType:"none",targetIP:g.defaultIP}):y==="public"&&(g.domain=document.getElementById("setup-public-domain")?.value?.trim()||"",g.email=document.getElementById("setup-public-email")?.value?.trim()||"",g.routingMode=document.querySelector('input[name="routing-mode"]:checked')?.value||"subdirectory",g.defaults={dnsType:g.routingMode==="subdirectory"?"none":"public",sslType:"letsencrypt",targetIP:"localhost"});const D=await P(g);safeSet("dashcaddy-config",JSON.stringify(g)),safeSet("dashcaddy-setup","completed"),document.getElementById("setup-wizard").style.display="none";const B=y==="homelab"?"Professional Home Lab":y==="simple"?"Simple Setup":"Public Server",f=D?"server (shared across all devices)":"locally (this browser only)";showNotification(`Setup Complete! Configured for: ${B}. Settings saved to: ${f}`,"success",5e3),setTimeout(()=>location.reload(),500)}const p=document.getElementById("setup-step-1-next");p&&(p.onclick=function(g){g.preventDefault();const D=document.querySelector('input[name="config-type"]:checked');D&&(y=D.value),M(y==="homelab"?"setup-step-homelab":y==="simple"?"setup-step-simple":y==="public"?"setup-step-public":"setup-step-homelab")});const T=document.getElementById("setup-skip");T&&(T.onclick=async function(g){g.preventDefault(),confirm("Skip setup? You can run it later from Settings.")&&(await P({setupComplete:!0,skipped:!0,timestamp:new Date().toISOString()}),safeSet("dashcaddy-setup","skipped"),document.getElementById("setup-wizard").style.display="none")});const x=document.getElementById("setup-tld");x&&(x.oninput=function(g){const D=g.target.value||".home",B=document.getElementById("tld-preview"),f=document.getElementById("tld-preview-2");B&&(B.textContent=D),f&&(f.textContent=D)});const $=document.getElementById("setup-homelab-back");$&&($.onclick=function(g){g.preventDefault(),M("setup-step-1")});const k=document.getElementById("setup-homelab-next");k&&(k.onclick=function(g){g.preventDefault();const D=document.getElementById("setup-tld")?.value?.trim()||"",B=document.getElementById("setup-ca-name")?.value?.trim()||"",f=document.getElementById("setup-dns-ip")?.value?.trim()||"";if(!D||!D.startsWith(".")){showNotification("Please enter a valid TLD starting with a dot (e.g., .home)","warning");return}if(!B){showNotification("Please enter a Certificate Authority name","warning");return}if(!f){showNotification("Please enter your DNS server IP address","warning");return}R()});const H=document.getElementById("setup-simple-back");H&&(H.onclick=function(g){g.preventDefault(),M("setup-step-1")});const L=document.getElementById("setup-simple-next");L&&(L.onclick=function(g){g.preventDefault(),R()}),document.querySelectorAll('input[name="routing-mode"]').forEach(function(g){g.onchange=function(){var D=document.getElementById("dns-requirement-note");D&&(D.textContent=this.value==="subdirectory"?"Only one DNS record needed (for the main domain)":"You'll need to configure DNS manually for each subdomain")}});const u=document.getElementById("setup-public-back");u&&(u.onclick=function(g){g.preventDefault(),M("setup-step-1")});const j=document.getElementById("setup-public-next");j&&(j.onclick=function(g){g.preventDefault();const D=document.getElementById("setup-public-domain")?.value?.trim()||"",B=document.getElementById("setup-public-email")?.value?.trim()||"";if(!D){showNotification("Please enter your domain name","warning");return}if(!B||!B.includes("@")){showNotification("Please enter a valid email address","warning");return}R()});const v=document.getElementById("setup-summary-back");v&&(v.onclick=function(g){g.preventDefault(),y==="homelab"?M("setup-step-homelab"):y==="simple"?M("setup-step-simple"):y==="public"&&M("setup-step-public")});const N=document.getElementById("setup-finish");N&&(N.onclick=function(g){g.preventDefault(),A()}),window.getGlobalConfig=async function(){try{const D=await fetch("/api/v1/config");if(D.ok){const B=await D.json();if(B&&B.setupComplete)return B}}catch{console.warn("Could not fetch config from server")}const g=safeGet("dashcaddy-config");return g?JSON.parse(g):{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 y=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 C="custom-apps";let O=null,E=null;const M=document.getElementById("app-selector-modal"),R=document.getElementById("app-selector-grid");async function P(){try{const c=await(await fetch("/api/v1/apps/templates")).json();if(c.success)return O=c.templates,E=c.categories,!0}catch(i){y.logError("[AppSelector] Fetch Templates",i,{function:"fetchApiTemplates"})}return!1}async function A(i){try{return await(await fetch(`/api/v1/apps/ports/${i}/check`)).json()}catch(c){return y.logError("[AppSelector] Check Port",c,{function:"checkPortAvailability"}),{available:!0}}}async function p(i){try{const l=await(await fetch(`/api/v1/apps/ports/${i}/suggest`)).json();if(l.success)return l.suggestedPort}catch(c){y.logError("[AppSelector] Get Suggested Port",c,{function:"getSuggestedPort"})}return i}async function T(){if(R.innerHTML='<div style="text-align: center; padding: 40px; color: var(--muted);">Loading app templates...</div>',!O&&!await P()){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 i={};for(const[l,w]of Object.entries(O)){const m=w.category||"Other";i[m]||(i[m]=[]),i[m].push({id:l,...w})}const c=E?Object.keys(E):Object.keys(i).sort();for(const l of c){const w=i[l];if(!w||w.length===0)continue;w.sort((e,t)=>(t.popularity||0)-(e.popularity||0));const m=document.createElement("div");m.className="app-category-header";const n=E?.[l]||{};m.innerHTML=`${escapeHtml(n.icon||"")} ${escapeHtml(l)}`,n.color&&(m.style.borderBottomColor=n.color),R.appendChild(m),w.forEach(e=>{const t=document.createElement("div");t.className="app-option";const o=e.isDashboardWidget,r=o&&safeGet("widget-"+e.id+"-enabled")!=="false",a=o?`<div style="font-size: 0.65rem; padding: 2px 6px; border-radius: 4px; margin-top: 4px; background: ${r?"#2ecc7130":"#e74c3c30"}; color: ${r?"#2ecc71":"#e74c3c"}; font-weight: 600;">${r?"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>`:"";t.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>
|
|
${a}${s}
|
|
`,o?t.onclick=()=>x(e,t):t.onclick=()=>$(e),R.appendChild(t)})}window.renderRecipeCards&&await window.renderRecipeCards(R)}function x(i,c){const l="widget-"+i.id+"-enabled",m=!(safeGet(l)!=="false");safeSet(l,String(m));const n=i.widgetSelector;if(n){const t=document.querySelector(n);t&&(t.style.display=m?"":"none")}const e=c.querySelector('div[style*="border-radius: 4px"]');e&&(e.textContent=m?"ON":"OFF",e.style.background=m?"#2ecc7130":"#e74c3c30",e.style.color=m?"#2ecc71":"#e74c3c"),showNotification(`${i.name} widget ${m?"enabled":"disabled"}`,"success",2e3)}async function $(i){const c=document.getElementById("app-deploy-modal"),l=document.getElementById("app-deploy-title"),w=document.getElementById("deploy-subdomain"),m=document.getElementById("deploy-url-preview"),n=document.getElementById("deploy-ip"),e=document.getElementById("deploy-port"),t=document.getElementById("deploy-tailscale-only"),o=document.getElementById("tailscale-status");try{const G=await(await secureFetch("/api/v1/apps/check-existing",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:i.id})})).json();if(G.success&&G.exists){const V=G.container;confirm(`Found existing ${i.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.`)&&(i._useExisting=!0,i._existingContainer=V)}}catch{}l.textContent=`Deploy ${i.name}`;const r=i.subdomain||i.id.replace(/-/g,"");w.value=r;const a=document.getElementById("subpath-compat-warning");if(a)if(SITE.routingMode==="subdirectory"){const q=i.subpathSupport||"strip";q==="none"?(a.style.display="block",a.innerHTML='<span style="color: #ff9800;">⚠ <strong>'+i.name+"</strong> does not support subdirectory mode. It may not work correctly at a subpath.</span>"):q==="strip"?(a.style.display="block",a.innerHTML='<span style="color: var(--muted);">ⓘ '+i.name+" has unverified subdirectory support. It may require additional configuration.</span>"):a.style.display="none"}else a.style.display="none";const s=SITE.defaults.dnsType||(SITE.configurationType==="public"?"public":"private"),d=SITE.defaults.sslType||(SITE.configurationType==="public"?"letsencrypt":"internal"),S=document.querySelector(`input[name="dns-type"][value="${s}"]`),h=document.querySelector(`input[name="ssl-type"][value="${d}"]`);S?S.checked=!0:document.querySelector('input[name="dns-type"][value="private"]').checked=!0,h?h.checked=!0:document.querySelector('input[name="ssl-type"][value="internal"]').checked=!0,n.value=SITE.defaults.targetIP||"localhost",t.checked=!1;const U=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 q=document.querySelectorAll('#app-deploy-modal input[name="dns-type"]')[0]?.closest("div.flex-col-gap")?.parentElement,G=document.querySelectorAll('#app-deploy-modal input[name="ssl-type"]')[0]?.closest("div.flex-col-gap")?.parentElement;q&&!q.dataset.moved&&(F.appendChild(q),q.dataset.moved="1"),G&&!G.dataset.moved&&(F.appendChild(G),G.dataset.moved="1")}const W=document.getElementById("media-path-section"),J=document.getElementById("deploy-media-path"),X=document.getElementById("media-path-description");if(i.mediaMount){W.style.display="block",J.value="",J.placeholder="/media/Movies, /media/TVShows or click Browse";const q=document.getElementById("detected-mounts-container"),G=document.getElementById("detected-mounts-list");try{const K=await(await fetch("/api/v1/media/detected-mounts")).json();if(K.success&&K.mounts.length>0){q.style.display="block",G.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(", ")},G.appendChild(Z)})}else q.style.display="none"}catch{q.style.display="none"}document.getElementById("browse-media-btn").onclick=()=>{openFolderBrowser(J)}}else W.style.display="none",J.value="",document.getElementById("detected-mounts-container").style.display="none";const Q=document.getElementById("plex-claim-section");Q&&(i.id==="plex"||i.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="",i.docker?.volumes?.length){const q=i.mediaMount?.containerPath,G=i.docker.volumes.filter(V=>!V.includes("{{MEDIA_PATH}}")&&!(q&&V.endsWith(":"+q)));G.length>0?(ne.style.display="block",G.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=i.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 q=e.value||se;Y.innerHTML='<span style="color: var(--muted);">Checking port...</span>';const G=await A(q);if(G.available)Y.innerHTML=`<span style="color: #4caf50;">Port ${escapeHtml(String(q))} is available</span>`;else{const V=await p(se);Y.innerHTML=`
|
|
<span style="color: #e74c3c;">Port ${escapeHtml(q)} in use by ${escapeHtml(G.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 G=await(await fetch("/api/v1/tailscale/status")).json();G.success&&G.installed&&G.connected?o.innerHTML=`
|
|
<span style="color: #4caf50;">Connected</span>
|
|
<span style="color: var(--muted); margin-left: 8px;">${G.self?.hostname} (${G.self?.ip})</span>
|
|
<span style="color: var(--muted); margin-left: 8px;">| ${G.deviceCount} devices</span>
|
|
`:G.installed?o.innerHTML='<span style="color: #ff9800;">Not connected</span>':(o.innerHTML='<span style="color: var(--muted);">Not available</span>',t.disabled=!0)}catch{o.innerHTML='<span style="color: var(--muted);">Could not check status</span>'}function ae(){const q=w.value||"subdomain",G=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}/${q}`;else if(G==="private")K=`${V==="none"?"http":"https"}://${buildDomain(q)}`;else if(G==="public"){const te=V==="none"?"http":"https",ee=SITE.domain||q;K=SITE.domain?`${te}://${q}.${SITE.domain}`:`${te}://${q}`}else{const te=e.value||i.defaultPort||DC.DEFAULTS.SERVICE_PORT;K=`http://${n.value}:${te}`}m.textContent=K}w.oninput=ae,n.oninput=ae,e.oninput=ae,document.querySelectorAll('input[name="dns-type"]').forEach(q=>{q.onchange=ae}),document.querySelectorAll('input[name="ssl-type"]').forEach(q=>{q.onchange=ae}),ae(),M.classList.remove("show"),c.classList.add("show"),c.dataset.appTemplate=JSON.stringify(i)}async function k(i){const c=i.appTemplate,l=safeGetJSON(C,[]),w=c._useExisting&&c._existingContainer,m=l.find(n=>n.id===i.subdomain);if(!(m&&!w&&!confirm(`An app with subdomain "${i.subdomain}" already exists. Redeploy?`))){if(m){const n=l.indexOf(m);l.splice(n,1),safeSet(C,JSON.stringify(l))}if(w)i.port=c._existingContainer.primaryPort;else{const n=i.port||c.defaultPort||8080;showNotification(`Checking port ${n} availability...`,"info",0);const e=await A(n);if(!e.available){const t=await p(c.defaultPort||8080);if(confirm(`Port ${n} is already in use by ${e.conflict?.usedBy||"another container"}.
|
|
|
|
Would you like to use port ${t} instead?`))i.port=t;else{showNotification("Deployment cancelled - port conflict","error",5e3);return}}}showNotification(w?`Configuring ${c.name} with existing container...`:`Deploying ${c.name}...`,"info",0);try{const n={appId:c.id,config:{subdomain:i.subdomain,ip:i.ip,createDns:i.dnsType==="private",port:i.port||c.defaultPort||null,sslType:i.sslType,dnsType:i.dnsType,tailscaleOnly:i.tailscaleOnly||!1,mediaPath:i.mediaPath||null,plexClaimToken:i.plexClaimToken||null,customVolumes:i.customVolumes||null}};w&&(n.config.useExisting=!0,n.config.existingContainerId=c._existingContainer.id,n.config.existingPort=c._existingContainer.primaryPort,!i.port&&c._existingContainer.primaryPort&&(n.config.port=c._existingContainer.primaryPort));const t=await(await secureFetch("/api/v1/apps/deploy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)})).json();if(t.success){const o={id:i.subdomain,name:c.name,logo:`/assets/${c.id}.png`,containerId:t.containerId,url:t.url,ip:i.ip,appTemplate:c.id,tailscaleOnly:i.tailscaleOnly||!1};l.push(o),safeSet(C,JSON.stringify(l)),window.APPS&&!window.APPS.some(a=>a.id===c.id)&&(window.APPS.push(o),typeof window.buildGrid=="function"&&window.buildGrid(),typeof window.refreshAll=="function"&&setTimeout(()=>window.refreshAll(),500));let r=t.usedExisting?`${c.name} configured with existing container!
|
|
URL: ${t.url}`:`${c.name} deployed successfully!
|
|
URL: ${t.url}`;t.warning&&(r+=`
|
|
|
|
\u26A0 Warning: ${t.warning}`),showNotification(r,"success",8e3),delete c._useExisting,delete c._existingContainer,t.url&&t.url.startsWith("https://")&&H(t.url,c.name),t.setupInstructions&&t.setupInstructions.length>0&&setTimeout(()=>{const a=t.setupInstructions.join(`
|
|
`);showNotification(`Setup Instructions for ${c.name}: ${a}`,"info",1e4)},1e3)}else throw new Error(t.error||"Deployment failed")}catch(n){y.logError("[AppSelector] Deployment",n,{function:"deploy"}),showNotification(`Failed to deploy ${c.name}: ${n.message}`,"error",8e3)}}}async function H(i,c){showNotification(`\u23F3 Generating SSL certificate for ${c}...`,"warning",6e4);let l=0;const w=12,m=async()=>{l++;try{const n=await fetch(i,{method:"HEAD",mode:"no-cors"});return showNotification(`\u2705 ${c} is ready! SSL certificate generated.`,"success",5e3),!0}catch{return l<w?setTimeout(m,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(m,3e3)}function L(){safeGetJSON(C,[]).forEach(c=>{window.APPS.some(l=>l.id===c.id)||window.APPS.push(c)})}document.getElementById("add-service-btn")?.addEventListener("click",()=>{T(),M.classList.add("show")}),wireModal(M,document.getElementById("app-selector-cancel"));const u=document.getElementById("app-deploy-modal");document.getElementById("app-deploy-cancel")?.addEventListener("click",()=>{u.classList.remove("show")}),document.getElementById("app-deploy-confirm")?.addEventListener("click",()=>{const i=JSON.parse(u.dataset.appTemplate),c=document.getElementById("deploy-media-path").value.trim(),l=[];document.querySelectorAll("#volume-mounts-list .vol-host-path").forEach(m=>{l.push({hostPath:m.value.trim(),containerPath:m.dataset.containerPath})});const w={appTemplate:i,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:l.length>0?l: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(i.mediaMount?.required&&!c){showNotification("Please enter a media library path for this application","warning");return}u.classList.remove("show"),k(w)}),wireModal(u);const j=document.getElementById("folder-browser-modal"),v=document.getElementById("folder-browser-path"),N=document.getElementById("folder-browser-list"),g=document.getElementById("folder-browser-selected"),D=document.getElementById("folder-browser-selected-list");let B="",f=[],I=null;window.openFolderBrowser=function(i){I=i,f=i.value.split(",").map(c=>c.trim()).filter(c=>c),B="",z(),b(""),j.classList.add("show")};async function b(i){v.textContent=i||"Select a drive...",N.innerHTML='<div style="padding: 20px; text-align: center; color: var(--muted);">Loading...</div>';try{const l=await(await fetch(`/api/v1/browse/directories?path=${encodeURIComponent(i)}`)).json();if(!l.success){N.innerHTML=`<div style="padding: 20px; text-align: center; color: var(--error);">Error: ${escapeHtml(l.error)}</div>`;return}B=l.path||"",v.textContent=B||"Select a drive...";let w="";l.parent&&l.parent!==l.path&&(w+=`<div class="folder-item" data-path="${escapeHtml(l.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>`),l.items.length===0&&!l.parent?w+='<div style="padding: 20px; text-align: center; color: var(--muted);">No browseable drives configured. Check your docker-compose.yml volume mounts.</div>':l.items.length===0?w+='<div style="padding: 20px; text-align: center; color: var(--muted);">No subfolders found</div>':l.items.forEach(m=>{const n=m.type==="drive"?"\u{1F4BE}":"\u{1F4C1}",e=f.includes(m.path),t=e?"background: color-mix(in srgb, var(--success) 20%, transparent);":"";w+=`<div class="folder-item" data-path="${escapeHtml(m.path)}" style="padding: 12px 16px; border-bottom: 1px solid var(--border); cursor: pointer; display: flex; align-items: center; gap: 10px; ${t}">
|
|
<span style="font-size: 1.2rem;">${n}</span>
|
|
<span style="flex: 1;">${escapeHtml(m.name)}</span>
|
|
${e?'<span style="color: var(--success);">\u2713</span>':""}
|
|
</div>`}),N.innerHTML=w,N.querySelectorAll(".folder-item").forEach(m=>{m.addEventListener("click",()=>{b(m.dataset.path)}),m.addEventListener("mouseenter",()=>{m.style.background="var(--card-bg)"}),m.addEventListener("mouseleave",()=>{const n=f.includes(m.dataset.path);m.style.background=n?"color-mix(in srgb, var(--success) 20%, transparent)":""})})}catch(c){N.innerHTML=`<div style="padding: 20px; text-align: center; color: var(--error);">Failed to load: ${escapeHtml(c.message)}</div>`}}function z(){if(f.length===0){g.style.display="none";return}g.style.display="block",D.innerHTML=f.map(i=>`
|
|
<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(i)}
|
|
<button type="button" onclick="removeSelectedFolder('${escapeHtml(i)}')" style="background: none; border: none; cursor: pointer; color: var(--error); font-size: 1rem; padding: 0;">\xD7</button>
|
|
</span>
|
|
`).join("")}window.removeSelectedFolder=function(i){f=f.filter(c=>c!==i),z(),b(B)},document.getElementById("folder-browser-select-current").addEventListener("click",()=>{B&&!f.includes(B)&&(f.push(B),z(),b(B))}),wireModal(j,document.getElementById("folder-browser-cancel")),document.getElementById("folder-browser-done").addEventListener("click",()=>{I&&(I.value=f.join(", ")),j.classList.remove("show")}),L()})(),(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 y=null,C=null,O=null,E=1,M=!1;const R=document.getElementById("recipe-deploy-modal"),P=document.getElementById("recipe-cancel"),A=document.getElementById("recipe-prev"),p=document.getElementById("recipe-next");wireModal(R,P);async function T(){try{const B=await fetch("/api/v1/recipes/templates"),f=await B.json();if(f.success)return y=f.templates,C=f.categories,!0;if(B.status===403)return M=!1,!1}catch(B){console.warn("Failed to fetch recipe templates:",B.message)}return!1}async function x(){try{M=(await(await fetch("/api/v1/license/feature/recipes")).json()).available}catch{M=!1}return M}window.renderRecipeCards=async function(B){await x();let f;if(M&&y?f=y:f=$(),!f||f.length===0)return;const I=document.createElement("div");I.className="app-category-header",I.innerHTML="\u{1F9EA} Recipes",I.style.borderBottomColor="#8e44ad",B.appendChild(I);const b=Array.isArray(f)?f:Object.values(f);b.sort((z,i)=>(i.popularity||0)-(z.popularity||0));for(const z of b){const i=document.createElement("div");i.className="app-option",i.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>`,l=M?"":'<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>';i.innerHTML=`
|
|
${l}
|
|
<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}
|
|
`,i.onclick=()=>{if(!M){showNotification("Recipes require a DashCaddy Premium license. Click the License button to activate.","warning",5e3),window.openLicenseModal&&window.openLicenseModal();return}k(z)},B.appendChild(i)}};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 k(B){O=B,E=1;const f=document.getElementById("app-selector-modal");f&&f.classList.remove("show"),document.getElementById("recipe-deploy-title").textContent=`Deploy ${B.name}`,H(),L(),R.classList.add("show")}function H(){document.querySelectorAll("#recipe-steps .recipe-step").forEach(B=>{const f=parseInt(B.dataset.step);B.classList.toggle("active",f===E),B.classList.toggle("completed",f<E)});for(let B=1;B<=4;B++){const f=document.getElementById(`recipe-step-${B}`);f&&(f.style.display=B===E?"":"none")}A.style.display=E>1&&E<4?"":"none",E===4?(p.style.display="none",P.textContent="Close"):E===3?(p.textContent="\u{1F680} Deploy",p.style.display="",P.textContent="Cancel"):(p.textContent="Next",p.style.display="",P.textContent="Cancel")}function L(){const B=document.getElementById("recipe-component-list");B.innerHTML="";const f=O.components||[];for(const I of f){const b=document.createElement("div");b.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=I.required,i=I.internal;b.innerHTML=`
|
|
<input type="checkbox" ${z?"checked disabled":"checked"} data-component-id="${I.id}"
|
|
style="width: 18px; height: 18px; accent-color: var(--accent);" />
|
|
<div style="flex: 1;">
|
|
<div style="font-weight: 600; font-size: 0.9rem;">${escapeHtml(I.role||I.id)}</div>
|
|
<div style="font-size: 0.78rem; color: var(--muted);">
|
|
${I.templateRef?escapeHtml(I.templateRef):"Built-in"}
|
|
${z?'<span style="color: var(--accent); margin-left: 6px;">Required</span>':'<span style="color: var(--muted); margin-left: 6px;">Optional</span>'}
|
|
${i?'<span style="color: var(--muted); margin-left: 6px;">(Internal)</span>':""}
|
|
</div>
|
|
${I.note?`<div style="font-size: 0.75rem; color: var(--warn-fg); margin-top: 4px;">\u26A0 ${escapeHtml(I.note)}</div>`:""}
|
|
</div>
|
|
`,B.appendChild(b)}}function u(){const B=document.getElementById("recipe-volumes-section"),f=document.getElementById("recipe-volume-list"),I=O.sharedVolumes;if(I&&Object.keys(I).length>0){B.style.display="",f.innerHTML="";for(const[b,z]of Object.entries(I)){const i=document.createElement("div");i.style.cssText="display: grid; gap: 4px;",i.innerHTML=`
|
|
<label style="font-weight: 500; font-size: 0.85rem;">${escapeHtml(z.label||b)}</label>
|
|
<input type="text" data-volume-key="${b}" 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>
|
|
`,f.appendChild(i)}}else B.style.display="none"}function j(){const B=document.getElementById("recipe-review-content"),f=v(),I=document.querySelectorAll("#recipe-volume-list input[data-volume-key]"),b={};I.forEach(l=>{b[l.dataset.volumeKey]=l.value});const z=document.getElementById("recipe-timezone").value||"UTC",i=document.getElementById("recipe-ip").value||"host.docker.internal",c=document.getElementById("recipe-tailscale").checked;B.innerHTML=`
|
|
<div style="font-weight: 600; font-size: 1rem; margin-bottom: 12px;">${escapeHtml(O.name)}</div>
|
|
<div style="color: var(--muted); margin-bottom: 16px;">${escapeHtml(O.description||"")}</div>
|
|
|
|
<div style="margin-bottom: 12px;">
|
|
<strong>Components (${f.length}):</strong>
|
|
<div style="display: grid; gap: 4px; margin-top: 6px;">
|
|
${f.map(l=>`<div style="padding: 4px 0; font-size: 0.85rem;">
|
|
\u2022 <strong>${escapeHtml(l.role||l.id)}</strong> ${l.internal?'<span style="color:var(--muted)">(internal)</span>':""}
|
|
</div>`).join("")}
|
|
</div>
|
|
</div>
|
|
|
|
${Object.keys(b).length>0?`<div style="margin-bottom: 12px;">
|
|
<strong>Volumes:</strong>
|
|
${Object.entries(b).map(([l,w])=>`<div style="font-size: 0.85rem; font-family: monospace; color: var(--muted);">${l}: ${escapeHtml(w)}</div>`).join("")}
|
|
</div>`:""}
|
|
|
|
<div style="font-size: 0.85rem; color: var(--muted);">
|
|
Timezone: ${escapeHtml(z)} • IP: ${escapeHtml(i)} ${c?"• Tailscale only":""}
|
|
</div>
|
|
|
|
${O.network?`<div style="font-size: 0.85rem; color: var(--muted); margin-top: 4px;">Docker network: <code>${escapeHtml(O.network.name)}</code></div>`:""}
|
|
`}function v(){const B=document.querySelectorAll("#recipe-component-list input[data-component-id]"),f=new Set;B.forEach(b=>{b.checked&&f.add(b.dataset.componentId)});const I=O.components||[];return I.filter(b=>b.required).forEach(b=>f.add(b.id)),I.filter(b=>f.has(b.id))}async function N(){const B=document.getElementById("recipe-progress-list"),f=document.getElementById("recipe-deploy-result");f.style.display="none",B.innerHTML="";const I=v();for(const c of I){const l=document.createElement("div");l.id=`recipe-progress-${c.id}`,l.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;",l.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>
|
|
`,B.appendChild(l)}const b=document.querySelectorAll("#recipe-volume-list input[data-volume-key]"),z={};b.forEach(c=>{z[c.dataset.volumeKey]=c.value});const i={selectedComponents:I.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 I)g(c.id,"deploying","Deploying...");try{const l=await(await secureFetch("/api/v1/recipes/deploy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({recipeId:O.id,config:i})})).json();if(l.success){for(const w of l.deployed||[])g(w.id,"success",w.url?`Running \u2192 ${w.url}`:"Running");for(const w of l.errors||[])g(w.componentId,"error",w.error);f.style.display="",f.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(l.message||"Deployed!")}</div>
|
|
${l.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;">${l.setupInstructions.map(w=>`<li>${escapeHtml(w)}</li>`).join("")}</ul>
|
|
</div>`:""}
|
|
</div>
|
|
`,showNotification(`${O.name} recipe deployed successfully!`,"success",5e3),window.loadServices&&window.loadServices()}else f.style.display="",f.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(l.error||"Unknown error")}
|
|
</div>`,showNotification(`Recipe deployment failed: ${l.error}`,"error",5e3)}catch(c){f.style.display="",f.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 g(B,f,I){const b=document.getElementById(`recipe-progress-${B}`);if(!b)return;const z=b.querySelector(".recipe-progress-icon"),i=b.querySelector(".recipe-progress-status");f==="deploying"?(z.textContent="\u23F3",i.style.color="var(--accent)"):f==="success"?(z.textContent="\u2705",i.style.color="var(--ok-fg)"):f==="error"&&(z.textContent="\u274C",i.style.color="var(--bad-fg)"),i.textContent=I}p.addEventListener("click",()=>{if(E===3){E=4,H(),N();return}E<3&&(E++,H(),E===2&&u(),E===3&&j())}),A.addEventListener("click",()=>{E>1&&E<4&&(E--,H())}),window.groupRecipeCards=function(){const B=document.querySelectorAll(".service-card[data-recipe-id]");if(B.length===0)return;const f={};B.forEach(I=>{const b=I.dataset.recipeId;f[b]||(f[b]=[]),f[b].push(I)});for(const[I,b]of Object.entries(f))b.length<2||b.forEach((z,i)=>{if(z.style.borderLeft="3px solid rgba(142,68,173,0.5)",i===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=I.replace(/-/g," "),z.style.position="relative",z.appendChild(c))}})},window.manageRecipe=async function(B,f){const I=`/api/v1/recipes/${B}/${f}`,b=f==="remove"?"DELETE":"POST",z=f==="remove"?`/api/v1/recipes/${B}`:I;if(!(f==="remove"&&!confirm(`Remove the entire ${B} recipe? This will delete all containers and configuration.`)))try{const c=await(await secureFetch(z,{method:b})).json();c.success?(showNotification(`Recipe ${f}: ${c.results?.filter(l=>l.status!=="failed").length||0} components processed`,"success",4e3),window.loadServices&&window.loadServices()):showNotification(`Recipe ${f} failed: ${c.error}`,"error",5e3)}catch(i){showNotification(`Network error: ${i.message}`,"error",5e3)}};const D=document.createElement("style");D.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(D),x()})(),(function(){document.getElementById("reload-caddy-top")?.addEventListener("click",async()=>{const y=document.getElementById("reload-caddy-top"),C=y.textContent;try{y.textContent="\u23F3 Reloading...",y.disabled=!0;const O=await secureFetch("/api/v1/caddy/reload",{method:"POST",headers:{"Content-Type":"application/json"}}),E=await O.json();if(O.ok&&E.success)y.textContent="\u2705 Reloaded!",setTimeout(()=>{y.textContent=C,y.disabled=!1},2e3);else throw new Error(E.error||"Reload failed")}catch(O){y.textContent="\u274C Failed",showNotification(`Failed to reload Caddy: ${O.message}`,"error"),setTimeout(()=>{y.textContent=C,y.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 y=document.getElementById("error-log-modal"),C=document.getElementById("error-log-content"),O=document.getElementById("view-error-logs"),E=document.getElementById("error-log-refresh"),M=document.getElementById("error-log-clear"),R=document.getElementById("error-log-close");async function P(){C.innerHTML='<div class="logs-loading">Loading error logs...</div>';try{const T=await(await fetch("/api/v1/error-logs")).json();T.success&&T.logs?T.logs.length===0?C.innerHTML='<div style="padding: 20px; text-align: center; color: var(--muted);">\u2705 No errors logged! Everything is working smoothly.</div>':C.innerHTML=T.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(""):C.innerHTML='<div style="padding: 20px; color: var(--bad-fg);">\u274C Failed to load error logs</div>'}catch(p){C.innerHTML=`<div style="padding: 20px; color: var(--bad-fg);">\u274C Error loading logs: ${escapeHtml(p.message)}</div>`}}async function A(){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),P()):showNotification("\u274C Failed to clear logs","error",3e3)}catch(p){showNotification(`\u274C Error: ${p.message}`,"error",3e3)}}O?.addEventListener("click",()=>{y.classList.add("show"),P()}),E?.addEventListener("click",P),M?.addEventListener("click",A),wireModal(y,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 y=document.getElementById("container-logs-modal"),C=document.getElementById("cl-container-select"),O=document.getElementById("cl-log-content"),E=document.getElementById("cl-log-search"),M=document.getElementById("cl-log-tail"),R=document.getElementById("cl-refresh"),P=document.getElementById("cl-stream"),A=document.getElementById("cl-download"),p=document.getElementById("cl-clear-search"),T=document.getElementById("cl-close"),x=document.getElementById("cl-close-btn"),$=document.getElementById("cl-stream-status"),k=document.getElementById("cl-stream-indicator"),H=document.getElementById("cl-stream-text"),L=document.getElementById("cl-line-count"),u=document.getElementById("cl-filter-count"),j=document.getElementById("cl-image"),v=document.getElementById("cl-status"),N=document.getElementById("cl-created");let g=null,D=[],B=[],f=null,I=!1,b=null;function z(s){if(!s)return"-";const d=new Date(s);return isNaN(d.getTime())?s:d.toLocaleString()}function i(s){if(!s)return"";const d=document.createElement("div");return d.textContent=s,d.innerHTML}function c(s,d){const S=s.stream==="stderr"?"log-stderr":"log-stdout",h=s.stream==="stderr"?"\u26A0\uFE0F":"\u{1F4E4}";return`
|
|
<div class="log-entry ${S}" data-index="${d}" 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;">${d+1}</span>
|
|
<span class="log-stream-icon" style="color: ${s.stream==="stderr"?"#f59e0b":"#22c55e"};">${h}</span>
|
|
<span class="log-text" style="flex: 1; white-space: pre-wrap; word-break: break-all; color: #e5e5e5;">${i(s.text)}</span>
|
|
</div>
|
|
`}function l(s,d=""){if(!s||s.length===0){O.innerHTML='<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">No logs available</div>',L.textContent="0 lines",u.textContent="0 filtered";return}if(D=s,B=d?s.filter(S=>S.text&&S.text.toLowerCase().includes(d.toLowerCase())):s,L.textContent=`${s.length} lines`,u.textContent=d?`${B.length} of ${s.length} shown`:`${s.length} shown`,B.length===0){O.innerHTML=`<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">No logs match "${i(d)}"</div>`;return}O.innerHTML=B.map((S,h)=>c(S,h)).join(""),O.scrollTop=O.scrollHeight}async function w(){try{const d=(await getJSON("/api/v1/logs/containers")).containers||[],S=C.value;C.innerHTML='<option value="">Select a container...</option>',d.forEach(h=>{const U=document.createElement("option");U.value=h.id,U.textContent=`${h.name} (${h.image.split(":")[0]}) - ${h.status}`,U.dataset.name=h.name,U.dataset.image=h.image,U.dataset.status=h.status,U.dataset.created=h.created,C.appendChild(U)}),S&&C.querySelector(`option[value="${S}"]`)&&(C.value=S,m(S))}catch(s){console.error("Failed to load containers:",s)}}function m(s){const d=C.querySelector(`option[value="${s}"]`);d&&(j.textContent=d.dataset.image||"-",v.textContent=d.dataset.status||"-",v.style.color=d.dataset.status==="running"?"var(--ok-fg, #4ade80)":"var(--bad-fg, #ef4444)",N.textContent=z(d.dataset.created))}async function n(){const s=C.value;if(!s){O.innerHTML='<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">Select a container to view logs</div>';return}t(),g=s,m(s);const d=M.value,S=E.value.trim();O.innerHTML='<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">Loading logs...</div>';try{const h=`/api/v1/logs/container/${s}${d!=="all"?`?tail=${d}`:""}`,U=await getJSON(h);U.logs&&U.logs.length>0?l(U.logs,S):(O.innerHTML='<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">No logs found for this container</div>',L.textContent="0 lines",u.textContent="0 filtered")}catch(h){O.innerHTML=`<div class="logs-loading" style="color: var(--bad-fg, #ef4444); text-align: center; padding: 40px;">Error loading logs: ${i(h.message)}</div>`}}function e(){const s=C.value;if(!s)return;t(),I=!0,P.textContent="\u23F9 Stop",$.style.display="flex",k.textContent="\u{1F7E2}",H.textContent="Connecting...";const d=`/api/v1/logs/stream/${s}`;f=new EventSource(d),f.onopen=()=>{k.textContent="\u{1F7E2}",H.textContent="Connected - streaming logs"},f.onmessage=S=>{try{const h=JSON.parse(S.data);if(h.error){k.textContent="\u{1F534}",H.textContent=`Error: ${h.error}`;return}D.push(h),B.push(h),L.textContent=`${D.length} lines`,u.textContent=`${B.length} shown`;const U=E.value.trim();if(!U||h.text&&h.text.toLowerCase().includes(U.toLowerCase())){const _=document.createElement("div");_.innerHTML=c(h,B.length-1);const F=_.firstElementChild;F.style.background="#1a3a1a",O.appendChild(F),O.scrollTop=O.scrollHeight}}catch(h){console.error("Error parsing log:",h)}},f.onerror=()=>{k.textContent="\u{1F534}",H.textContent="Disconnected",I=!1,P.textContent="\u25B6 Stream"},y._eventSource=f}function t(){f&&(f.close(),f=null),y._eventSource&&(y._eventSource.close(),y._eventSource=null),I=!1,P.textContent="\u25B6 Stream",$.style.display="none"}function o(){if(!D||D.length===0){showNotification("No logs to download","error");return}const s=C.querySelector(`option[value="${g}"]`)?.dataset.name||g,d=new Date().toISOString().replace(/[:.]/g,"-"),S=`${s}-logs-${d}.txt`,h=D.map(W=>{const J=W.timestamp||"",X=W.stream==="stderr"?"[ERR]":"[OUT]";return`${J?J+" ":""}${X} ${W.text}`}).join(`
|
|
`),U=new Blob([h],{type:"text/plain"}),_=URL.createObjectURL(U),F=document.createElement("a");F.href=_,F.download=S,document.body.appendChild(F),F.click(),document.body.removeChild(F),URL.revokeObjectURL(_),showNotification(`Downloaded ${D.length} log lines`,"success")}C?.addEventListener("change",()=>{n()}),M?.addEventListener("change",()=>{n()}),R?.addEventListener("click",()=>{n()}),P?.addEventListener("click",()=>{I?t():e()}),A?.addEventListener("click",()=>{o()}),p?.addEventListener("click",()=>{E.value="",l(D,"")}),E?.addEventListener("input",()=>{clearTimeout(b),b=setTimeout(()=>{l(D,E.value.trim())},300)}),E?.addEventListener("keydown",s=>{s.key==="Escape"&&(E.value="",l(D,""))}),document.getElementById("view-container-logs")?.addEventListener("click",()=>{y.classList.add("show"),w()});function a(){t(),y.classList.remove("show")}T?.addEventListener("click",a),x?.addEventListener("click",a),document.addEventListener("keydown",s=>{s.key==="Escape"&&y.classList.contains("show")&&a()}),y.addEventListener("click",s=>{s.target===y&&a()}),window.openContainerLogsModal=function(s,d){y.classList.add("show"),w().then(()=>{const S=Array.from(C.options).find(h=>h.value===s||h.dataset.name===d);S?(C.value=S.value,m(S.value),n()):s?(g=s,j.textContent=d||s,v.textContent="-",N.textContent="-",n()):O.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 y=document.getElementById("snapshot-modal"),C=document.getElementById("snapshot-btn"),O=document.getElementById("snapshot-close"),E=document.getElementById("snapshot-container-select"),M=document.getElementById("snapshot-details"),R=document.getElementById("snapshot-create-btn"),P=document.getElementById("snapshot-create-status");let A=null;async function p(){try{const L=await(await fetch("/api/v1/containers")).json();if(!L.success||!L.containers)return;E.innerHTML='<option value="">-- Select a container --</option>';for(const u of L.containers){const j=document.createElement("option");j.value=u.id,j.textContent=`${u.name||u.id} (${u.image||"unknown"})`,j.dataset.name=u.name,j.dataset.image=u.image,j.dataset.status=u.status,j.dataset.created=u.created,E.appendChild(j)}}catch(H){console.error("Failed to load containers:",H)}}function T(H){if(!H||!H.value){M.style.display="none",A=null;return}A=H.value,document.getElementById("snapshot-image").textContent=H.dataset.image||"-",document.getElementById("snapshot-status").textContent=H.dataset.status||"-",document.getElementById("snapshot-created").textContent=H.dataset.created?new Date(H.dataset.created*1e3).toLocaleString():"-",document.getElementById("snapshot-id").textContent=H.value.substring(0,12),M.style.display=""}async function x(){if(!A){P.textContent="Please select a container first",P.style.color="var(--bad-fg)";return}const H=document.getElementById("snapshot-name").value.trim();if(!H){P.textContent="Please enter a snapshot name",P.style.color="var(--bad-fg)";return}const L=document.getElementById("snapshot-leave-running").checked;R.disabled=!0,R.textContent="Creating...",P.textContent="";try{const j=await(await fetch(`/api/v1/containers/${encodeURIComponent(A)}/checkpoint`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:H,leaveRunning:L})})).json();j.success?(P.textContent=`\u2713 Snapshot "${H}" created successfully`,P.style.color="var(--ok-fg)",document.getElementById("snapshot-name").value=""):(P.textContent=`\u2717 Failed: ${j.error||"Unknown error"}`,P.style.color="var(--bad-fg)")}catch(u){P.textContent=`\u2717 Error: ${u.message}`,P.style.color="var(--bad-fg)"}finally{R.disabled=!1,R.textContent="\u{1F4BE} Create Snapshot"}}function $(){y.classList.add("show"),p()}function k(){y.classList.remove("show"),M.style.display="none",A=null,E.selectedIndex=0}C?.addEventListener("click",$),O?.addEventListener("click",k),wireModal(y,O),E?.addEventListener("change",H=>{const L=E.options[E.selectedIndex];T(L)}),R?.addEventListener("click",x),y?.querySelectorAll(".panel-tab").forEach(H=>{H.addEventListener("click",()=>{y.querySelectorAll(".panel-tab").forEach(L=>L.classList.remove("active")),y.querySelectorAll(".panel-section").forEach(L=>L.classList.remove("active")),H.classList.add("active"),y.querySelector(`#${H.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 y=document.getElementById("arr-setup-modal"),C=document.getElementById("arr-setup-btn"),O=document.getElementById("arr-setup-cancel"),E=document.getElementById("smart-connect-btn"),M=document.getElementById("smart-phase-detect"),R=document.getElementById("smart-phase-credentials"),P=document.getElementById("smart-phase-progress"),A=document.getElementById("smart-phase-results"),p=document.getElementById("smart-detect-results"),T=document.getElementById("smart-credential-inputs"),x=document.getElementById("smart-progress-steps"),$=document.getElementById("smart-results-content"),k=document.getElementById("smart-plex-libraries"),H=document.getElementById("smart-retry-btn");let L=null;const u={plex:"\u{1F3AC}",radarr:"\u{1F3AC}",sonarr:"\u{1F4FA}",prowlarr:"\u{1F50D}",seerr:"\u{1F4CB}"},j={plex:"Plex",radarr:"Radarr (Movies)",sonarr:"Sonarr (TV)",prowlarr:"Prowlarr (Indexers)",seerr:"Seerr"};function v(b){M.style.display=b==="detect"?"block":"none",R.style.display=b==="credentials"?"block":"none",P.style.display=b==="progress"?"block":"none",A.style.display=b==="results"?"block":"none"}function N(b){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"}},i=z[b]||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, ${i.bg} 20%, transparent); color: ${i.bg};">${i.icon} ${i.text}</span>`}async function g(){v("detect"),p.style.display="none";try{if(L=await(await fetch("/api/v1/arr/smart-detect")).json(),!L.success){p.innerHTML=`<div style="padding: 12px; color: var(--bad-fg);">Detection failed: ${escapeHtml(L.error)}</div>`,p.style.display="block";return}let z='<div style="display: flex; flex-direction: column; gap: 8px;">';for(const[c,l]of Object.entries(L.services)){const w=u[c]||"\u{1F4E6}",m=j[c]||c,n=l.source?`<span style="font-size: 0.7rem; color: var(--muted); padding: 1px 6px; background: var(--card-bg); border-radius: 3px;">${escapeHtml(l.source)}</span>`:"",e=l.version?`<span style="font-size: 0.7rem; color: var(--muted);">v${escapeHtml(l.version)}</span>`:"",t=(l.hasApiKey||l.hasToken)&&l.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;">${m}</div>
|
|
<div style="display: flex; gap: 6px; align-items: center; flex-wrap: wrap;">
|
|
${n} ${e} ${t}
|
|
</div>
|
|
</div>
|
|
${N(l.status)}
|
|
</div>`}z+="</div>";const i=L.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(i.fullyConnected))}/${escapeHtml(String(i.totalDetected+(5-i.totalDetected)))} services detected ·
|
|
${escapeHtml(String(i.fullyConnected))} connected${i.needsApiKey>0?` · <strong>${escapeHtml(String(i.needsApiKey))} needs API key</strong>`:""}
|
|
</div>`,p.innerHTML=z,p.style.display="block",D(L),setTimeout(()=>{v("credentials")},800)}catch(b){p.innerHTML=`<div style="padding: 12px; color: var(--bad-fg);">Error: ${escapeHtml(b.message)}</div>`,p.style.display="block"}}function D(b){let z="";const i=b.services,c=["radarr","sonarr","prowlarr"];for(const m of c){const n=i[m];if(!n||n.status==="not_found"&&!n.url)continue;const e=u[m],t=j[m],o=n.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;">${t}</span>
|
|
<span id="smart-${m}-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-${m}-url" value="${escapeHtml(n.url||"")}" placeholder="https://seedbox.com/${m}/"
|
|
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-${m}-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('${m}')" style="margin-top: 8px; padding: 4px 12px; font-size: 0.75rem; cursor: pointer;">Test</button>
|
|
</div>`}const l=i.plex;if(l){const m=l.status==="connected";z+=`<div style="padding: 10px 12px; background: var(--card-base); border-radius: 8px; border: 1px solid ${m?"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>
|
|
${N(l.status)}
|
|
<span style="margin-left: auto; font-size: 0.75rem; color: var(--muted);">${escapeHtml(l.source||"")}</span>
|
|
</div>
|
|
</div>`}const w=i.seerr;if(w){const m=w.status==="connected";let n="";if(w.configuredServices){const e=w.configuredServices;n=`<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 ${m?"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>
|
|
${N(w.status)}
|
|
</div>
|
|
${n}
|
|
</div>`}T.innerHTML=z}window.smartTestConnection=async function(b){const z=document.getElementById(`smart-${b}-url`),i=document.getElementById(`smart-${b}-key`),c=document.getElementById(`smart-${b}-status`),l=z?.value.trim(),w=i?.value.trim();if(!l||!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 n=await(await secureFetch("/api/v1/arr/test-connection",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({service:b,url:l,apiKey:w})})).json();n.success?c.innerHTML=`<span style="color: var(--ok-fg);">✓ ${escapeHtml(n.appName||"Connected")} v${escapeHtml(n.version||"")}</span>`:c.innerHTML=`<span style="color: var(--bad-fg);">✗ ${escapeHtml(n.error)}</span>`}catch(m){c.innerHTML=`<span style="color: var(--bad-fg);">✗ ${escapeHtml(m.message)}</span>`}};async function B(){v("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 b={};for(const i of["radarr","sonarr","prowlarr"]){const c=document.getElementById(`smart-${i}-url`)?.value.trim(),l=document.getElementById(`smart-${i}-key`)?.value.trim();l&&c?b[i]={apiKey:l,url:c}:l&&(b[i]={apiKey:l})}const z={services:Object.keys(b).length>0?b: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 l="";for(const w of c.steps||[]){const m=w.status==="success"?'<span style="color: var(--ok-fg);">✓</span>':'<span style="color: var(--bad-fg);">✗</span>',n=w.status==="success"?"var(--muted)":"var(--bad-fg)";l+=`<div style="display: flex; align-items: center; gap: 8px; padding: 6px 10px; background: var(--card-base); border-radius: 6px; font-size: 0.85rem;">
|
|
${m}
|
|
<span>${escapeHtml(w.step)}</span>
|
|
<span style="margin-left: auto; font-size: 0.75rem; color: ${n};">${escapeHtml(w.details||"")}</span>
|
|
</div>`}x.innerHTML=l,setTimeout(()=>f(c),500)}catch(i){x.innerHTML=`<div style="padding: 12px; color: var(--bad-fg);">Connection error: ${escapeHtml(i.message)}</div>`}}function f(b){v("results");const z=b.summary||{},i=z.failed===0&&z.succeeded>0,c=i?"var(--ok-fg)":"#f39c12",l=i?"✓":"⚠",w=i?"All Connected!":`${escapeHtml(String(z.succeeded))}/${escapeHtml(String(z.totalSteps))} Steps Succeeded`;let m=`<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};">${l}</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>`;m+='<div style="display: flex; flex-direction: column; gap: 4px;">';for(const n of b.steps||[]){const e=n.status==="success"?'<span style="color: var(--ok-fg);">✓</span>':'<span style="color: var(--bad-fg);">✗</span>';m+=`<div style="display: flex; align-items: center; gap: 8px; padding: 4px 8px; font-size: 0.8rem;">
|
|
${e} ${escapeHtml(n.step)} <span style="margin-left: auto; color: var(--muted); font-size: 0.75rem;">${escapeHtml(n.details||"")}</span>
|
|
</div>`}m+="</div>",$.innerHTML=m,H.style.display=z.failed>0?"block":"none",b.steps?.some(n=>n.step.includes("Plex")&&n.status==="success")&&I()}async function I(){try{const z=await(await fetch("/api/v1/plex/libraries")).json();if(z.success&&z.libraries?.length>0){let i=`<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 l=c.type==="movie"?"\u{1F3AC}":c.type==="show"?"\u{1F4FA}":"\u{1F3B5}";i+=`<div style="padding: 8px 12px; background: var(--card-bg); border-radius: 6px; font-size: 0.85rem;">
|
|
${l} <strong>${escapeHtml(c.title)}</strong>
|
|
<span style="color: var(--muted); font-size: 0.75rem;">${escapeHtml(String(c.count))} items</span>
|
|
</div>`}i+="</div></div>",k.innerHTML=i,k.style.display="block"}}catch{}}C?.addEventListener("click",()=>{y.classList.add("show"),k.style.display="none",g()}),wireModal(y,O),E?.addEventListener("click",B),H?.addEventListener("click",B)})(),(function(){const y=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 C=document.getElementById("notifications-modal"),O=document.getElementById("manage-notifications"),E=document.getElementById("notifications-save"),M=document.getElementById("notifications-cancel");["discord","telegram","ntfy","email"].forEach(k=>{const H=document.getElementById(`${k}-enabled`),L=document.getElementById(`${k}-config`);H?.addEventListener("change",()=>{L.style.display=H.checked?"block":"none"})});const R=document.getElementById("health-check-enabled"),P=document.getElementById("health-check-config");R?.addEventListener("change",()=>{P.style.opacity=R.checked?"1":"0.5"});async function A(){try{const H=await(await fetch("/api/v1/notifications/config")).json();if(H.success){const L=H.config;document.getElementById("notifications-enabled").checked=L.enabled,document.getElementById("discord-enabled").checked=L.providers?.discord?.enabled||!1,document.getElementById("telegram-enabled").checked=L.providers?.telegram?.enabled||!1,document.getElementById("ntfy-enabled").checked=L.providers?.ntfy?.enabled||!1,document.getElementById("email-enabled").checked=L.providers?.email?.enabled||!1,document.getElementById("discord-config").style.display=L.providers?.discord?.enabled?"block":"none",document.getElementById("telegram-config").style.display=L.providers?.telegram?.enabled?"block":"none",document.getElementById("ntfy-config").style.display=L.providers?.ntfy?.enabled?"block":"none",document.getElementById("email-config").style.display=L.providers?.email?.enabled?"block":"none",L.providers?.ntfy?.serverUrl&&(document.getElementById("ntfy-server").value=L.providers.ntfy.serverUrl),L.providers?.email?.host&&(document.getElementById("email-host").value=L.providers.email.host),L.providers?.email?.from&&(document.getElementById("email-from").value=L.providers.email.from),document.getElementById("health-check-enabled").checked=L.healthCheck?.enabled||!1,L.healthCheck?.intervalMinutes&&(document.getElementById("health-check-interval").value=L.healthCheck.intervalMinutes),L.healthCheck?.lastCheck&&(document.getElementById("health-check-status").textContent=`Last check: ${new Date(L.healthCheck.lastCheck).toLocaleString()}`),document.getElementById("event-container-down").checked=L.events?.containerDown!==!1,document.getElementById("event-container-up").checked=L.events?.containerUp!==!1,document.getElementById("event-deploy-success").checked=L.events?.deploymentSuccess!==!1,document.getElementById("event-deploy-failed").checked=L.events?.deploymentFailed!==!1,document.getElementById("event-resource-alert").checked=L.events?.resourceAlert!==!1}}catch(k){y.logError("[Notifications] Load Config",k,{function:"loadConfig"})}}async function p(){try{const H=await(await fetch("/api/v1/notifications/history?limit=10")).json(),L=document.getElementById("notification-history");H.success&&H.history?.length>0?L.innerHTML=H.history.map(u=>{const j=new Date(u.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)"}[u.type]||"var(--muted)"}">${u.type==="success"?"\u2713":u.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(u.title)}</div>
|
|
<div style="font-size: 0.7rem; color: var(--muted);">${j}</div>
|
|
</div>
|
|
</div>
|
|
`}).join(""):L.innerHTML='<div style="color: var(--muted); text-align: center; padding: 20px;">No notifications yet</div>'}catch(k){y.logError("[Notifications] Load History",k,{function:"loadHistory"})}}async function T(){try{const k={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}},L=await(await secureFetch("/api/v1/notifications/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(k)})).json();L.success?(showNotification("Notification settings saved","success",3e3),C.classList.remove("show")):showNotification(`Failed to save: ${L.error}`,"error",3e3)}catch(k){showNotification(`Error: ${k.message}`,"error",3e3)}}async function x(k){try{const L=await(await secureFetch("/api/v1/notifications/test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:k})})).json();L.success?showNotification(`Test ${k} notification sent!`,"success",3e3):showNotification(`Test failed: ${L.error}`,"error",3e3)}catch(H){showNotification(`Error: ${H.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 H=await(await secureFetch("/api/v1/notifications/health-check",{method:"POST"})).json();H.success&&(document.getElementById("health-check-status").textContent=`Last check: ${new Date(H.lastCheck).toLocaleString()} (${H.containersMonitored} containers)`,showNotification("Health check completed","success",2e3))}catch(k){showNotification(`Error: ${k.message}`,"error",3e3)}}),O?.addEventListener("click",()=>{C.classList.add("show"),A(),p()}),E?.addEventListener("click",T),document.getElementById("notifications-send-test")?.addEventListener("click",async()=>{const k=document.getElementById("notifications-send-test"),H=k.textContent;k.textContent="Sending...",k.disabled=!0;try{const u=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();u.success?(showNotification("Test notification sent!","success",3e3),$()):showNotification(`Test failed: ${u.results?.map(j=>`${j.provider}: ${j.error||"ok"}`).join(", ")}`,"error",5e3)}catch(L){showNotification(`Error: ${L.message}`,"error",3e3)}finally{k.textContent=H,k.disabled=!1}});async function $(){try{const H=await(await fetch("/api/v1/notifications/status")).json();if(H.success&&H.lastSent){const L=document.getElementById("last-notification-sent");L&&(L.textContent=`Last sent: ${new Date(H.lastSent).toLocaleString()}`)}}catch{}}wireModal(C,M)})(),(function(){document.addEventListener("click",y=>{const C=y.target.closest(".panel-tab");if(!C)return;const O=C.dataset.panel;if(!O)return;const E=C.closest(".panel-tabs"),M=E.closest(".weather-modal-content");E.querySelectorAll(".panel-tab").forEach(P=>P.classList.remove("active")),C.classList.add("active"),M.querySelectorAll(".panel-section").forEach(P=>P.classList.remove("active"));const R=M.querySelector("#"+O);R&&R.classList.add("active")})})(),(function(){var y=["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 C(){for(var e={},t=0;t<y.length;t++){var o=y[t],r=safeGet(o);r!=null&&(e[o]=r)}try{for(var a=0;a<localStorage.length;a++){var s=localStorage.key(a);/^widget-.+-enabled$/.test(s)&&(e[s]=localStorage.getItem(s))}}catch{}return e}function O(e){if(!e||typeof e!="object")return 0;var t=0;for(var o in e)e.hasOwnProperty(o)&&(safeSet(o,e[o]),t++);return t}function E(e){return e.version&&!e.files&&e.services}function M(e){var t={};e.customServices&&(t["custom-services"]=JSON.stringify(e.customServices)),e.customApps&&(t["custom-apps"]=JSON.stringify(e.customApps)),e.weatherZip&&(t["weather-zip"]=e.weatherZip),e.theme&&(t.theme=e.theme),e.userThemes&&Object.keys(e.userThemes).length&&(t["user-themes"]=JSON.stringify(e.userThemes)),O(t),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 r=e.userThemes[o],a={};(window.THEME_PROPS||[]).forEach(function(s){r[s]&&(a[s]=r[s])}),secureFetch("/api/v1/themes/"+o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:r.name||o,colors:a})}).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"),P=document.getElementById("backup-restore-btn"),A=document.getElementById("backup-cancel"),p=document.getElementById("backup-export-btn"),T=document.getElementById("backup-select-file"),x=document.getElementById("backup-file-input"),$=document.getElementById("backup-file-name"),k=document.getElementById("backup-preview"),H=document.getElementById("backup-preview-content"),L=document.getElementById("backup-do-restore-btn"),u=document.getElementById("backup-result"),j=document.getElementById("backup-schedules-container"),v=document.getElementById("backup-history-container"),N=document.getElementById("backup-disk-container"),g=document.getElementById("pointintime-container"),D=null;P?.addEventListener("click",function(){R.classList.add("show"),u&&(u.style.display="none"),k&&(k.style.display="none"),$&&($.style.display="none"),D=null}),wireModal(R,A),p?.addEventListener("click",async function(){p.disabled=!0,p.innerHTML='<span class="brand-spinner"></span> Exporting...';try{var e=await fetch("/api/v1/backup/export"),t=await e.json();t.browserState=C();var o=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),r=URL.createObjectURL(o),a=document.createElement("a");a.href=r,a.download="dashcaddy-backup-"+new Date().toISOString().split("T")[0]+".json",document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(r);var s=Object.keys(t.browserState).length,d=t.themes?Object.keys(t.themes).length:0;u.innerHTML="\u2705 Full backup downloaded \u2014 server config + "+s+" browser settings"+(d?" + "+d+" themes":""),u.style.display="block",u.style.background="color-mix(in srgb, var(--ok-fg) 15%, transparent)",u.style.border="1px solid var(--ok-fg)"}catch(S){u.innerHTML="\u274C Export failed: "+escapeHtml(S.message),u.style.display="block",u.style.background="color-mix(in srgb, var(--bad-fg) 15%, transparent)",u.style.border="1px solid var(--bad-fg)"}p.disabled=!1,p.innerHTML="\u2B07\uFE0F Download Full Backup"}),T?.addEventListener("click",function(){x.click()}),x?.addEventListener("change",async function(e){var t=e.target.files[0];if(t){$.textContent="\u{1F4C4} "+t.name,$.style.display="block",u.style.display="none";try{var o=await t.text(),r=JSON.parse(o);if(E(r)){D=r;var a='<div style="margin-bottom: 8px; color: var(--muted); font-size: 0.8rem;">Legacy format (v'+escapeHtml(r.version)+")</div>";a+='<div style="display: flex; flex-wrap: wrap; gap: 6px;">',r.services?.length&&(a+='<span style="padding: 4px 8px; background: var(--base); border-radius: 4px; font-size: 0.8rem;">\u{1F4CB} '+r.services.length+" services</span>"),r.customApps?.length&&(a+='<span style="padding: 4px 8px; background: var(--base); border-radius: 4px; font-size: 0.8rem;">\u{1F4E6} '+r.customApps.length+" custom apps</span>"),r.theme&&(a+='<span style="padding: 4px 8px; background: var(--base); border-radius: 4px; font-size: 0.8rem;">\u{1F3A8} Theme: '+escapeHtml(r.theme)+"</span>"),r.userThemes&&(a+='<span style="padding: 4px 8px; background: var(--base); border-radius: 4px; font-size: 0.8rem;">\u{1F3A8} '+Object.keys(r.userThemes).length+" custom themes</span>"),a+="</div>",H.innerHTML=a,k.style.display="block";return}var s=await secureFetch("/api/v1/backup/preview",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)}),d=await s.json();if(d.success){D=r;var a='<div style="margin-bottom: 8px; color: var(--muted); font-size: 0.8rem;">Exported: '+new Date(r.exportedAt).toLocaleString()+" (v"+escapeHtml(r.version)+")</div>";a+='<div style="margin-bottom: 6px; font-size: 0.75rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px;">Server Config</div>',a+='<div style="display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px;">';for(var S in d.preview.files){var h=d.preview.files[S],U=h.action==="create"?"\u{1F195}":"\u{1F4DD}";a+='<span style="padding: 4px 8px; background: var(--base); border-radius: 4px; font-size: 0.8rem;">'+U+" "+escapeHtml(h.description)+"</span>"}a+="</div>",d.preview.serviceCount&&(a+='<div style="font-size: 0.8rem; color: var(--accent); margin-bottom: 6px;">'+d.preview.serviceCount+" services</div>"),d.preview.themeCount&&(a+='<div style="font-size: 0.8rem; color: var(--accent); margin-bottom: 6px;">\u{1F3A8} '+d.preview.themeCount+" custom themes</div>"),d.preview.browserStateCount&&(a+='<div style="margin-top: 6px; font-size: 0.75rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px;">Browser Preferences</div>',a+='<div style="font-size: 0.8rem; color: var(--accent);">\u{1F5A5}\uFE0F '+d.preview.browserStateCount+" saved settings (theme, weather, clock, widgets, etc.)</div>"),H.innerHTML=a,k.style.display="block"}else u.innerHTML="\u26A0\uFE0F Invalid backup file: "+escapeHtml(d.error),u.style.display="block",u.style.background="color-mix(in srgb, #f39c12 15%, transparent)",u.style.border="1px solid #f39c12",k.style.display="none"}catch(_){u.innerHTML="\u274C Could not read file: "+escapeHtml(_.message),u.style.display="block",u.style.background="color-mix(in srgb, var(--bad-fg) 15%, transparent)",u.style.border="1px solid var(--bad-fg)",k.style.display="none"}}}),L?.addEventListener("click",async function(){if(D&&confirm("This will overwrite your current configuration and browser preferences. Continue?")){L.disabled=!0,L.innerHTML='<span class="brand-spinner"></span> Restoring...';try{if(E(D)){M(D),u.innerHTML="\u2705 Legacy backup restored \u2014 browser settings and services imported.",u.style.background="color-mix(in srgb, var(--ok-fg) 15%, transparent)",u.style.border="1px solid var(--ok-fg)",u.style.display="block",setTimeout(function(){location.reload()},2e3),L.disabled=!1,L.innerHTML="\u26A1 Restore Everything";return}var e=document.getElementById("backup-reload-caddy")?.checked??!0,t=await secureFetch("/api/v1/backup/restore",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({backup:D,options:{reloadCaddy:e}})}),o=await t.json(),r=0;if(D.browserState&&(r=O(D.browserState)),o.success){var a="\u2705 "+o.message;r>0&&(a+='<br><small style="color: var(--muted);">'+r+" browser settings restored</small>"),o.results.caddyReloaded&&(a+='<br><small style="color: var(--muted);">Caddy configuration reloaded</small>'),u.innerHTML=a,u.style.background="color-mix(in srgb, var(--ok-fg) 15%, transparent)",u.style.border="1px solid var(--ok-fg)",setTimeout(function(){location.reload()},2e3)}else u.innerHTML="\u26A0\uFE0F "+escapeHtml(o.message),r>0&&(u.innerHTML+='<br><small style="color: var(--muted);">'+r+" browser settings were restored</small>"),o.results?.errors?.length>0&&(u.innerHTML+="<br><small>"+o.results.errors.map(function(s){return escapeHtml(s.file)+": "+escapeHtml(s.error)}).join(", ")+"</small>"),u.style.background="color-mix(in srgb, #f39c12 15%, transparent)",u.style.border="1px solid #f39c12";u.style.display="block"}catch(s){u.innerHTML="\u274C Restore failed: "+escapeHtml(s.message),u.style.display="block",u.style.background="color-mix(in srgb, var(--bad-fg) 15%, transparent)",u.style.border="1px solid var(--bad-fg)"}L.disabled=!1,L.innerHTML="\u26A1 Restore Everything"}});async function B(){if(j){j.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';try{var e=await fetch("/api/v1/backups/schedule"),t=await e.json();if(t.premiumRequired){j.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(!t.success)throw new Error(t.error||"Failed to load schedules");var o=t.schedules||[];if(o.length===0){j.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 r='<div style="display: flex; flex-direction: column; gap: 8px;">',a=0;a<o.length;a++){var s=o[a],d=s.nextRun?new Date(s.nextRun).toLocaleString():"Not scheduled",S=s.lastRun?new Date(s.lastRun).toLocaleString():"Never";r+='<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(d)+"</div> <div>Last run: "+escapeHtml(S)+'</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>'}r+="</div>",r+='<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>',j.innerHTML=r,j.querySelectorAll(".schedule-toggle").forEach(function(h){h.addEventListener("change",function(){f(h.dataset.appid,{enabled:h.checked})})}),j.querySelectorAll(".schedule-select").forEach(function(h){h.addEventListener("change",function(){f(h.dataset.appid,{schedule:h.value})})}),j.querySelectorAll(".retention-input").forEach(function(h){h.addEventListener("change",function(){f(h.dataset.appid,{retention:{keep:parseInt(h.value)||7}})})}),j.querySelectorAll(".schedule-run-now").forEach(function(h){h.addEventListener("click",function(){I(h.dataset.appid)})}),j.querySelectorAll(".schedule-delete").forEach(function(h){h.addEventListener("click",function(){b(h.dataset.appid)})}),document.getElementById("add-schedule-btn")?.addEventListener("click",z)}catch(h){j.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed to load: '+escapeHtml(h.message)+"</div>"}}}async function f(e,t){try{var o=await secureFetch("/api/v1/backups/schedule",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:e,...t})}),r=await o.json();r.success?showNotification("Schedule updated for "+e,"success"):(showNotification("Update failed: "+(r.error||"Unknown"),"error"),B())}catch(a){showNotification("Error: "+a.message,"error")}}async function I(e){try{var t=await secureFetch("/api/v1/backups/backup/"+encodeURIComponent(e),{method:"POST",headers:{"Content-Type":"application/json"}}),o=await t.json();o.success?showNotification("Backup started for "+e+"!","success"):showNotification("Backup failed: "+(o.error||"Unknown"),"error")}catch(r){showNotification("Error: "+r.message,"error")}}async function b(e){if(confirm("Remove backup schedule for "+e+"?"))try{var t=await secureFetch("/api/v1/backups/schedule/"+encodeURIComponent(e),{method:"DELETE"}),o=await t.json();o.success?(showNotification("Schedule removed for "+e,"success"),B()):showNotification("Delete failed: "+(o.error||"Unknown"),"error")}catch(r){showNotification("Error: "+r.message,"error")}}async function z(){var e=document.getElementById("new-schedule-appid")?.value?.trim(),t=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 r=await secureFetch("/api/v1/backups/schedule",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:e,schedule:t,retention:{keep:o},enabled:!0})}),a=await r.json();if(a.success){showNotification("Schedule created for "+e,"success"),B();var s=document.getElementById("new-schedule-appid");s&&(s.value="")}else showNotification("Failed: "+(a.error||"Unknown"),"error")}catch(d){showNotification("Error: "+d.message,"error")}}async function i(){if(N){N.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';try{var e=await fetch("/api/v1/backups/files"),t=await e.json();if(!t.success)throw new Error(t.error||"Failed to load");var o=t.files||[];if(o.length===0){N.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 r={},a=0;a<o.length;a++){var s=o[a],d=s.appId||"unknown";r[d]||(r[d]=[]),r[d].push(s)}var S='<div style="font-size: 0.75rem; color: var(--muted); margin-bottom: 12px;">'+o.length+" backup file(s) across "+Object.keys(r).length+" app(s)</div>";S+='<div style="display: flex; flex-direction: column; gap: 12px;">';for(var h=Object.keys(r).sort(),U=0;U<h.length;U++){var d=h[U],_=r[d];S+='<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(d)+' <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],W=new Date(s.timestamp).toLocaleString();S+='<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;">'+W+'</div><div style="display: flex; gap: 6px;"> <button class="disk-compare-btn" data-appid="'+escapeHtml(d)+'" 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(d)+'" 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>'}S+="</div>"}S+="</div>",N.innerHTML=S,N.querySelectorAll(".disk-compare-btn").forEach(function(J){J.addEventListener("click",function(){m(J.dataset.appid,J.dataset.filename)})}),N.querySelectorAll(".disk-restore-btn").forEach(function(J){J.addEventListener("click",function(){n(J.dataset.appid,J.dataset.filename)})})}catch(J){N.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed: '+escapeHtml(J.message)+"</div>"}}}async function c(){if(v){v.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';try{var e=await fetch("/api/v1/backups/history?limit=50"),t=await e.json();if(!t.success||!t.history?.length){v.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;">',r=0;r<t.history.length;r++){var a=t.history[r],s=a.size?(a.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(a.name||"backup")+"</span>",o+=' <div style="display: flex; align-items: center; gap: 8px;">',o+=' <span class="status-badge '+(a.status==="success"?"success":"down")+'">'+escapeHtml(a.status)+"</span>",a.status==="success"&&(o+=' <button class="backup-restore-btn" data-backup-id="'+escapeHtml(a.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(a.timestamp).toLocaleString()+" | "+s+" MB | "+(a.duration?(a.duration/1e3).toFixed(1)+"s":"--"),a.encrypted&&(o+=" | \u{1F512}"),o+=" </div>",o+="</div>"}o+="</div>",v.innerHTML=o,v.querySelectorAll(".backup-restore-btn").forEach(function(d){d.addEventListener("click",function(){window.__restoreServerBackup(d.dataset.backupId)})})}catch(d){v.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed: '+escapeHtml(d.message)+"</div>"}}}window.__restoreServerBackup=async function(e){if(confirm("Restore from this server backup? This will overwrite current configuration."))try{var t=await secureFetch("/api/v1/backups/restore/"+e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({restoreServices:!0,restoreConfig:!0})}),o=await t.json();o.success?(showNotification("Restore completed successfully!","success"),location.reload()):showNotification("Restore failed: "+(o.error||"Unknown error"),"error")}catch(r){showNotification("Restore error: "+r.message,"error")}},document.querySelector('[data-panel="backup-schedules-tab"]')?.addEventListener("click",B),document.querySelector('[data-panel="backup-disk-tab"]')?.addEventListener("click",i),document.querySelector('[data-panel="backup-pointintime-tab"]')?.addEventListener("click",l),document.querySelector('[data-panel="backup-history-tab"]')?.addEventListener("click",c);async function l(){if(g){try{var e=await fetch("/api/v1/license/status"),t=await e.json();if(t.tier!=="premium"){g.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{}g.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';try{var o=await fetch("/api/v1/services"),r=await o.json(),a=r.services||[];if(a.length===0){g.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;">',d=0;d<a.length;d++)s+='<option value="'+escapeHtml(a[d].id||a[d].name||"")+'">'+escapeHtml(a[d].name||a[d].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>',g.innerHTML=s,document.getElementById("pit-load-btn")?.addEventListener("click",function(){var S=document.getElementById("pit-app-select")?.value;S&&w(S)})}catch(S){g.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed: '+escapeHtml(S.message)+"</div>"}}}async function w(e){var t=document.getElementById("pit-backups-list");if(t){t.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)),r=await o.json();if(!r.success||!r.files||r.files.length===0){t.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4BE}</span> No backup files for '+escapeHtml(e)+"</div>";return}for(var a='<div style="font-size: 0.75rem; color: var(--muted); margin-bottom: 8px;">'+r.files.length+' backup(s)</div><div style="display: flex; flex-direction: column; gap: 6px;">',s=0;s<r.files.length;s++){var d=r.files[s],S=new Date(d.timestamp).toLocaleString();a+='<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(d.name)+'</div> <div style="font-size: 0.75rem; color: var(--muted);">'+d.sizeFormatted+'</div></div><div style="font-size: 0.75rem; color: var(--muted); margin-bottom: 8px;">'+S+'</div><div style="display: flex; gap: 6px;"> <button class="pit-compare-btn" data-appid="'+escapeHtml(e)+'" data-filename="'+escapeHtml(d.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(d.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>'}a+="</div>",t.innerHTML=a,t.querySelectorAll(".pit-compare-btn").forEach(function(h){h.addEventListener("click",function(){m(h.dataset.appid,h.dataset.filename)})}),t.querySelectorAll(".pit-restore-btn").forEach(function(h){h.addEventListener("click",function(){n(h.dataset.appid,h.dataset.filename)})})}catch(h){t.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed: '+escapeHtml(h.message)+"</div>"}}}async function m(e,t){try{var o=await secureFetch("/api/v1/backups/compare/"+encodeURIComponent(t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({})}),r=await o.json();if(!r.success){showNotification("Compare failed: "+(r.error||"Unknown"),"error");return}var a=r.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(t)+'</h4><div style="font-size: 0.8rem; color: var(--muted); margin-bottom: 16px;">Size: '+(a.sizeFormatted||"?")+" | Created: "+new Date(a.timestamp).toLocaleString()+"</div>";if(a.services){var d=a.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;">'+d+' Services (backup vs current)</div><div style="font-size: 0.8rem; color: var(--muted);">Backup: '+a.services.backupCount+" services | Current: "+a.services.currentCount+" services</div>",a.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(a.config){var S=a.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;">'+S+" Configuration</div>",a.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(h){h.target===this&&this.remove()})}catch(h){showNotification("Compare error: "+h.message,"error")}}async function n(e,t){if(confirm("Restore "+t+" 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(t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({restartContainers:!0})}),r=await o.json();r.success?(showNotification(e+" restored to "+t,"success"),setTimeout(function(){location.reload()},1500)):showNotification("Restore failed: "+(r.error||"Unknown"),"error")}catch(a){showNotification("Restore error: "+a.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 y=document.getElementById("stats-modal"),C=document.getElementById("container-stats-btn"),O=document.getElementById("stats-cancel"),E=document.getElementById("stats-refresh-btn"),M=document.getElementById("stats-auto-refresh"),R=document.getElementById("stats-container"),P=document.getElementById("stats-aggregated-container"),A=document.getElementById("stats-alerts-container"),p=document.getElementById("stats-last-update");let T=null,x=null;function $(l){if(l===0||!l)return"0 B";const w=1024,m=["B","KB","MB","GB"],n=Math.floor(Math.log(l)/Math.log(w));return parseFloat((l/Math.pow(w,n)).toFixed(1))+" "+m[n]}function k(l){return l<30?"#2ecc71":l<70?"#f39c12":"#e74c3c"}function H(l){return l<50?"#2ecc71":l<80?"#f39c12":"#e74c3c"}async function L(){try{let l=null,w=!1;try{const e=await(await fetch("/api/v1/monitoring/stats")).json();e.success&&e.stats&&(l=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){l={};for(const t of e.stats)l[t.name]={name:t.name,current:{cpu:t.cpu,memory:{percent:t.memory.percent,usage:t.memory.used,limit:t.memory.limit,usageMB:Math.round(t.memory.used/1048576),limitMB:Math.round(t.memory.limit/1048576)},network:{rxBytes:t.network.rx,txBytes:t.network.tx,rxMB:(t.network.rx/1048576).toFixed(1),txMB:(t.network.tx/1048576).toFixed(1)},disk:{readMB:0,writeMB:0}},status:t.status};x=l}}if(!l||Object.keys(l).length===0){R.innerHTML='<div style="text-align: center; padding: 40px; color: var(--muted);">No running containers found</div>';return}let m='<div style="display: flex; flex-direction: column; gap: 8px;">';for(const[n,e]of Object.entries(l)){const t=e.current||e,o=t.cpu?.percent||0,r=t.memory?.percent||0,a=k(o),s=H(r),d=t.memory?.usage||t.memory?.used||0,S=t.memory?.limit||0,h=t.network?.rxBytes||t.network?.rx||0,U=t.network?.txBytes||t.network?.tx||0,_=e.aggregated;m+=`
|
|
<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||n}</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: ${a}; border-radius: 3px; transition: width 0.3s;"></div>
|
|
</div>
|
|
<span style="font-size: 0.8rem; font-weight: 500; color: ${a}; 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(r,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;">${r.toFixed(1)}%</span>
|
|
</div>
|
|
<div style="font-size: 0.65rem; color: var(--muted); margin-top: 2px;">${$(d)} / ${$(S)}</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 ${$(h)}</span>
|
|
<span style="color: var(--muted); margin: 0 4px;">/</span>
|
|
<span style="color: #e74c3c;">\u2191 ${$(U)}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>`}m+="</div>",R.innerHTML=m,p.textContent="Updated: "+new Date().toLocaleTimeString()}catch(l){R.innerHTML=`<div style="text-align: center; padding: 40px; color: var(--bad-fg);">\u274C Failed to load stats: ${escapeHtml(l.message)}</div>`}}async function u(){if(!P)return;const l=x;if(!l||Object.keys(l).length===0){P.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[m,n]of Object.entries(l)){const e=n.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;">${n.name||m}</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>",P.innerHTML=w}async function j(){if(!A)return;A.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading alerts...</div>';const l=x;if(!l||Object.keys(l).length===0){A.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 m=[];try{const s=await(await fetch("/api/v1/monitoring/alerts?limit=50")).json();s.success&&(m=s.history||[])}catch{}let n={};try{const s=await(await fetch("/api/v1/monitoring/alerts/config")).json();s.success&&(n=s.configs||{})}catch{}const t=Object.entries(l).map(([a,s])=>{const d=n[a]||{cpuThreshold:80,memoryThreshold:90,diskIOThreshold:50,autoRestart:!1,enabled:!1};return`
|
|
<tr data-container="${a}">
|
|
<td style="font-weight: 600; padding: 8px;">${s.name||a}</td>
|
|
<td style="padding: 4px 8px;"><input type="number" class="alert-cpu" value="${d.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="${d.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="${d.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" ${d.autoRestart?"checked":""} ${w?"":"disabled"} /></td>
|
|
<td style="padding: 4px 8px;">
|
|
<button class="alert-test-btn btn-xs" data-container="${a}" data-name="${s.name||a}" 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=m.map(a=>{const s=new Date(a.timestamp).toLocaleString(),d=a.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;">${a.containerName||a.containerId}</td>
|
|
<td style="padding: 6px 8px; text-transform: capitalize;">${a.metric||a.type}</td>
|
|
<td style="padding: 6px 8px;">${typeof a.value=="number"?a.value.toFixed(1):a.value}${a.metric==="disk"?" MB/s":"%"}</td>
|
|
<td style="padding: 6px 8px; text-align: center;">${d}</td>
|
|
<td style="padding: 6px 8px; font-size: 0.75rem; color: ${a.autoRestartTriggered?"#f39c12":"var(--muted)"};">${a.autoRestartTriggered?"\u21BB":""}</td>
|
|
</tr>
|
|
`}).join(""),r=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>${t}</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>
|
|
`;A.innerHTML=`
|
|
${r}
|
|
<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 a={};document.querySelectorAll("#stats-alerts-container tr[data-container]").forEach(s=>{const d=s.dataset.container;a[d]={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 d=await(await secureFetch("/api/v1/monitoring/alerts/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:a})})).json(),S=document.getElementById("save-all-alerts");S.textContent=d.success?"\u2705 Saved":"\u274C Failed",setTimeout(()=>{S.textContent="Save All"},2e3)}catch{const d=document.getElementById("save-all-alerts");d.textContent="\u274C Error",setTimeout(()=>{d.textContent="Save All"},2e3)}}),document.getElementById("go-to-notifications")?.addEventListener("click",a=>{a.preventDefault(),y.classList.remove("show"),N(),document.getElementById("manage-notifications")?.click()}),document.querySelectorAll(".alert-test-btn").forEach(a=>{a.addEventListener("click",async()=>{const s=a.textContent;a.textContent="...";try{await secureFetch(`/api/v1/monitoring/alerts/${a.dataset.container}/test`,{method:"POST"}),a.textContent="\u2705",showNotification("Test alert sent for "+a.dataset.name,"success",3e3)}catch{a.textContent="\u274C"}setTimeout(()=>{a.textContent=s},2e3)})}),document.getElementById("upgrade-for-alerts")?.addEventListener("click",()=>{y.classList.remove("show"),N(),typeof openLicenseModal=="function"&&openLicenseModal()})}function v(){T&&clearInterval(T),M?.checked&&(T=setInterval(L,DC.POLL.STATS))}function N(){T&&(clearInterval(T),T=null)}C?.addEventListener("click",()=>{y.classList.add("show"),L(),v()}),O?.addEventListener("click",()=>{y.classList.remove("show"),N()}),y?.addEventListener("click",l=>{l.target===y&&(y.classList.remove("show"),N())}),E?.addEventListener("click",L),M?.addEventListener("change",()=>{M.checked?v():N()}),document.querySelector('[data-panel="stats-aggregated"]')?.addEventListener("click",u),document.querySelector('[data-panel="stats-alerts"]')?.addEventListener("click",j);const g=document.getElementById("stats-history-container"),D=document.getElementById("stats-history-container-area"),B=document.querySelectorAll(".stats-range-btn");let f="1h";function I(l){switch(l){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 b(l){return l==="raw"?"live (10s samples)":l==="hourly"?"hourly average":l==="daily"?"daily average":l}function z(l,w,m,n,e){if(!l||l.length===0)return`<div style="text-align: center; color: var(--muted); padding: 20px;">No data for ${escapeHtml(n)}</div>`;const t=l.map(w).filter(W=>W!=null);if(t.length===0)return`<div style="text-align: center; color: var(--muted); padding: 20px;">No data for ${escapeHtml(n)}</div>`;const o=Math.max(...t,1),r=Math.min(...t,0),a=o-r||1,s=600,d=80,S=4,h=(s-S*2)/Math.max(t.length-1,1),U=t.map((W,J)=>{const X=S+J*h,Q=d-S-(W-r)/a*(d-S*2);return`${X.toFixed(1)},${Q.toFixed(1)}`}).join(" "),_=t[t.length-1],F=t.reduce((W,J)=>W+J,0)/t.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(n)}</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} ${d}" preserveAspectRatio="none" style="width: 100%; height: ${d}px; background: var(--base); border-radius: 4px;">
|
|
<polyline fill="none" stroke="${m}" stroke-width="1.5" points="${U}" />
|
|
</svg>
|
|
</div>
|
|
`}function i(){if(!g)return;const l=x||{},w=g.value,m=Object.entries(l);if(m.length===0){g.innerHTML='<option value="">No containers</option>';return}g.innerHTML=m.map(([n,e])=>`<option value="${escapeHtml(n)}">${escapeHtml(e.name||n)}</option>`).join(""),w&&l[w]&&(g.value=w)}async function c(){if(!D||!g)return;const l=g.value;if(!l){D.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4CA}</span>No container selected.</div>';return}const w=Date.now(),m=w-I(f);D.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading history...</div>';try{const e=await(await fetch(`/api/v1/monitoring/history/${encodeURIComponent(l)}?startTime=${m}&endTime=${w}`)).json();if(!e.success)throw new Error(e.error||"Failed to load history");const t=e.samples||[],o=e.tier||"raw";if(t.length===0){D.innerHTML=`<div class="panel-empty"><span class="empty-icon">\u{1F4CA}</span>No data for the last ${f}. Tier: ${b(o)}.</div>`;return}const r=o==="raw",a=r?U=>U.cpu?.percent:U=>U.cpu?.avg,s=r?U=>U.memory?.percent:U=>U.memory?.avgPercent,d=r?U=>U.network?.rxMB||0:U=>U.network?.rxMB||0,S=r?U=>U.network?.txMB||0:U=>U.network?.txMB||0;let h=`
|
|
<div style="font-size: 0.75rem; color: var(--muted); margin-bottom: 8px;">
|
|
${t.length} samples \xB7 ${escapeHtml(b(o))} \xB7 ${new Date(m).toLocaleString()} \u2192 ${new Date(w).toLocaleString()}
|
|
</div>
|
|
`;h+=z(t,a,"#2ecc71","CPU","%"),h+=z(t,s,"#3498db","Memory","%"),h+=z(t,d,"#9b59b6","Network RX"," MB"),h+=z(t,S,"#e67e22","Network TX"," MB"),D.innerHTML=h}catch(n){D.innerHTML=`<div class="panel-empty"><span class="empty-icon">\u26A0\uFE0F</span>Failed to load history: ${escapeHtml(n.message)}</div>`}}B.forEach(l=>{l.addEventListener("click",()=>{B.forEach(w=>w.classList.remove("active")),l.classList.add("active"),f=l.dataset.range,c()})}),g?.addEventListener("change",c),document.querySelector('[data-panel="stats-history"]')?.addEventListener("click",()=>{i(),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 interval, 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 1fr; gap: 12px;">
|
|
<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">Polling Interval (seconds)</label>
|
|
<input type="number" id="health-setting-interval" value="30" min="5" max="3600" class="form-input" />
|
|
<div style="font-size: 0.72rem; color: var(--muted); margin-top: 2px;">How often each service is checked.</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 y=document.getElementById("health-modal"),C=document.getElementById("health-check-btn"),O=document.getElementById("health-cancel"),E=document.getElementById("health-refresh-btn"),M=document.getElementById("health-status-container"),R=document.getElementById("health-incidents-container"),P=document.getElementById("health-config-container"),A=document.getElementById("health-last-update"),p=document.getElementById("health-add-btn"),T=document.getElementById("health-config-form"),x=document.getElementById("health-form-title"),$=document.getElementById("health-form-cancel"),k=document.getElementById("health-form-save"),H="dashcaddy-health-settings",L={retentionDays:30,pollingInterval:30,diskUsageThreshold:80},u=document.getElementById("health-global-save"),j=document.getElementById("health-global-reset"),v=document.getElementById("health-global-status"),N=document.getElementById("health-setting-retention"),g=document.getElementById("health-setting-interval"),D=document.getElementById("health-setting-disk-threshold");function B(){try{const t=safeGet(H),o=t?JSON.parse(t):{};return Object.assign({},L,o)}catch{return Object.assign({},L)}}function f(){const t=B();N&&(N.value=t.retentionDays),g&&(g.value=t.pollingInterval),D&&(D.value=t.diskUsageThreshold)}function I(){const t={retentionDays:Math.max(1,Math.min(3650,parseInt(N?.value)||L.retentionDays)),pollingInterval:Math.max(5,Math.min(3600,parseInt(g?.value)||L.pollingInterval)),diskUsageThreshold:Math.max(50,Math.min(99,parseInt(D?.value)||L.diskUsageThreshold))};try{safeSet(H,JSON.stringify(t)),f(),v&&(v.textContent="Saved \u2713",v.style.color="var(--ok-fg)",setTimeout(()=>{v&&(v.textContent="")},2500)),typeof showNotification=="function"&&showNotification("Global health settings saved","success")}catch(o){v&&(v.textContent="Save failed",v.style.color="var(--bad-fg)"),typeof showNotification=="function"&&showNotification("Failed to save settings: "+o.message,"error")}}function b(){try{safeSet(H,JSON.stringify(L))}catch{}f(),v&&(v.textContent="Reset to defaults \u2713",v.style.color="var(--ok-fg)",setTimeout(()=>{v&&(v.textContent="")},2500))}f(),u?.addEventListener("click",I),j?.addEventListener("click",b);let z=null;function i(t){return t>=99.9?"var(--ok-fg)":t>=95?"#f39c12":"var(--bad-fg)"}function c(t){const o={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: ${o[t]||"var(--muted)"}20; color: ${o[t]||"var(--muted)"};">${t}</span>`}async function l(){try{const o=await(await fetch("/api/v1/health-checks/status")).json();if(!o.success||!o.status||Object.keys(o.status).length===0){M.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 r=Object.values(o.status);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); text-align: left;">',a+='<th style="padding: 8px;">Service</th><th style="padding: 8px;">Status</th>',a+='<th style="padding: 8px;">Uptime 24h</th><th style="padding: 8px;">Uptime 7d</th>',a+='<th style="padding: 8px;">Avg Response</th><th style="padding: 8px;">Last Check</th></tr>';for(const s of r){const d=s.status==="up",S=d?"var(--dot-ok)":"var(--dot-bad)",h=s.uptime?.["24h"]??"-",U=s.uptime?.["7d"]??"-",_=s.avgResponseTime!=null?Math.round(s.avgResponseTime)+"ms":"-",F=s.timestamp?timeAgo(s.timestamp):"-";a+=`<tr style="border-bottom: 1px solid var(--border); cursor: pointer;" data-health-id="${escapeHtml(s.serviceId)}">`,a+=`<td style="padding: 8px; font-weight: 500;">${escapeHtml(s.name||s.serviceId)}</td>`,a+=`<td style="padding: 8px;"><span style="display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: ${S}; margin-right: 6px;"></span>${d?"Up":"Down"}</td>`,a+=`<td style="padding: 8px; color: ${typeof h=="number"?i(h):"var(--muted)"};">${typeof h=="number"?h.toFixed(1)+"%":h}</td>`,a+=`<td style="padding: 8px; color: ${typeof U=="number"?i(U):"var(--muted)"};">${typeof U=="number"?U.toFixed(1)+"%":U}</td>`,a+=`<td style="padding: 8px;">${_}</td>`,a+=`<td style="padding: 8px; color: var(--muted);">${F}</td>`,a+="</tr>",a+=`<tr id="health-detail-${escapeHtml(s.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>`}a+="</table>",M.innerHTML=a,A.textContent="Updated "+new Date().toLocaleTimeString(),M.querySelectorAll("tr[data-health-id]").forEach(s=>{s.addEventListener("click",async()=>{const d=s.dataset.healthId,S=document.getElementById("health-detail-"+d);if(S){if(S.style.display!=="none"){S.style.display="none";return}S.style.display="";try{const U=await(await fetch(`/api/v1/health-checks/${d}/stats?hours=24`)).json();if(U.success&&U.stats){const _=U.stats,F=_.responseTime||{};S.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>${_.totalChecks||0}</strong></div>
|
|
<div><span style="color: var(--muted);">Uptime</span><br><strong style="color: ${i(_.uptime||0)};">${(_.uptime||0).toFixed(2)}%</strong></div>
|
|
<div><span style="color: var(--muted);">Avg Response</span><br><strong>${Math.round(F.avg||0)}ms</strong></div>
|
|
<div><span style="color: var(--muted);">P95 / P99</span><br><strong>${Math.round(F.p95||0)}ms / ${Math.round(F.p99||0)}ms</strong></div>
|
|
<div><span style="color: var(--muted);">Min Response</span><br><strong>${Math.round(F.min||0)}ms</strong></div>
|
|
<div><span style="color: var(--muted);">Max Response</span><br><strong>${Math.round(F.max||0)}ms</strong></div>
|
|
<div><span style="color: var(--muted);">Up Checks</span><br><strong style="color: var(--ok-fg);">${_.upChecks||0}</strong></div>
|
|
<div><span style="color: var(--muted);">Down Checks</span><br><strong style="color: var(--bad-fg);">${_.downChecks||0}</strong></div>
|
|
</div>`}else S.querySelector("td").innerHTML='<div class="panel-empty">No detailed stats available for this period.</div>'}catch(h){S.querySelector("td").innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(h.message)}</div>`}}})})}catch(t){M.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed to load health status: ${escapeHtml(t.message)}</div>`}}async function w(){try{const[t,o]=await Promise.all([fetch("/api/v1/health-checks/incidents"),fetch("/api/v1/health-checks/incidents/history?limit=50")]),r=await t.json(),a=await o.json();let s="";const d=r.success&&r.incidents?r.incidents:[];if(d.length>0){s+='<div style="margin-bottom: 16px;"><h4 style="color: var(--bad-fg); margin: 0 0 8px;">Open Incidents ('+d.length+")</h4>";for(const h of d)s+=`<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(h.serviceId)}</span>
|
|
<span>${c(h.severity)}</span>
|
|
</div>
|
|
<div style="font-size: 0.82rem; color: var(--muted); margin-top: 4px;">${escapeHtml(h.message)}</div>
|
|
<div style="font-size: 0.75rem; color: var(--muted); margin-top: 4px;">Started ${timeAgo(h.createdAt)} \xB7 ${h.occurrences||1} occurrence(s)</div>
|
|
</div>`;s+="</div>"}else s+='<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 S=a.success&&a.history?a.history:[];if(S.length>0){s+='<h4 style="margin: 0 0 8px; color: var(--muted);">Incident History</h4>',s+='<table style="width: 100%; border-collapse: collapse; font-size: 0.82rem;">',s+='<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 h of S){const U=h.status==="resolved",_=U&&h.duration?h.duration<6e4?Math.round(h.duration/1e3)+"s":Math.round(h.duration/6e4)+"m":"-";s+='<tr style="border-bottom: 1px solid var(--border);">',s+=`<td style="padding: 6px;">${escapeHtml(h.serviceId)}</td>`,s+=`<td style="padding: 6px;">${escapeHtml(h.type)}</td>`,s+=`<td style="padding: 6px;">${c(h.severity)}</td>`,s+=`<td style="padding: 6px;"><span style="color: ${U?"var(--ok-fg)":"var(--bad-fg)"};">${h.status}</span></td>`,s+=`<td style="padding: 6px;">${_}</td>`,s+=`<td style="padding: 6px; color: var(--muted);">${timeAgo(h.createdAt)}</td>`,s+="</tr>"}s+="</table>"}R.innerHTML=s||'<div class="panel-empty"><span class="empty-icon">\u{1F6A8}</span>No incidents recorded yet.</div>'}catch(t){R.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(t.message)}</div>`}}async function m(){try{const o=await(await fetch("/api/v1/health-checks/status")).json(),r=o.success&&o.status?Object.values(o.status):[];if(r.length===0){P.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 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;">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 s of r){const d=s.status==="up";a+='<tr style="border-bottom: 1px solid var(--border);">',a+=`<td style="padding: 8px; font-weight: 500;">${escapeHtml(s.name||s.serviceId)}</td>`,a+=`<td style="padding: 8px; color: ${d?"var(--ok-fg)":"var(--bad-fg)"};">${d?"Up":"Down"}</td>`,a+=`<td style="padding: 8px;">${s.sla?.target?s.sla.target+"%":"-"}</td>`,a+='<td style="padding: 8px; text-align: right;">',a+=`<button onclick="document.dispatchEvent(new CustomEvent('health-edit', {detail:'${escapeHtml(s.serviceId)}'}))" style="padding: 4px 10px; font-size: 0.78rem; margin-right: 4px;">Edit</button>`,a+=`<button onclick="document.dispatchEvent(new CustomEvent('health-delete', {detail:'${escapeHtml(s.serviceId)}'}))" style="padding: 4px 10px; font-size: 0.78rem; color: var(--bad-fg); border-color: var(--bad-fg);">Delete</button>`,a+="</td></tr>"}a+="</table>",P.innerHTML=a}catch(t){P.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(t.message)}</div>`}}function n(t,o,r,a,s,d,S){z=t||null,x.textContent=t?"Edit Health Check":"Add Health Check",document.getElementById("health-form-id").value=t||"",document.getElementById("health-form-id").disabled=!!t,document.getElementById("health-form-name").value=o||"",document.getElementById("health-form-url").value=r||"",document.getElementById("health-form-timeout").value=a||1e4,document.getElementById("health-form-codes").value=s||"200",document.getElementById("health-form-sla").value=d||99.9,document.getElementById("health-form-slow").value=S||5e3,T.style.display="",p.style.display="none"}function e(){T.style.display="none",p.style.display="",z=null}p?.addEventListener("click",()=>n("","","",1e4,"200",99.9,5e3)),$?.addEventListener("click",e),k?.addEventListener("click",async()=>{const t=z||document.getElementById("health-form-id").value.trim();if(!t)return showNotification("Service ID is required","warning");const o=document.getElementById("health-form-url").value.trim();if(!o)return showNotification("URL is required","warning");const r=document.getElementById("health-form-codes").value.split(",").map(s=>parseInt(s.trim())).filter(Boolean),a={name:document.getElementById("health-form-name").value.trim()||t,url:o,timeout:parseInt(document.getElementById("health-form-timeout").value)||1e4,expectedStatusCodes:r.length?r:[200],sla:{target:parseFloat(document.getElementById("health-form-sla").value)||99.9},slowResponseThreshold:parseInt(document.getElementById("health-form-slow").value)||5e3};try{k.textContent="Saving...",k.disabled=!0;const d=await(await secureFetch(`/api/v1/health-checks/${encodeURIComponent(t)}/configure`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)})).json();if(!d.success)throw new Error(d.error||"Save failed");e(),m(),l()}catch(s){showNotification("Error: "+s.message,"error")}finally{k.textContent="Save",k.disabled=!1}}),document.addEventListener("health-edit",async t=>{const o=t.detail;n(o,"","",1e4,"200",99.9,5e3)}),document.addEventListener("health-delete",async t=>{const o=t.detail;if(confirm(`Delete health check for "${o}"?`))try{const a=await(await secureFetch(`/api/v1/health-checks/${encodeURIComponent(o)}/configure`,{method:"DELETE"})).json();if(!a.success)throw new Error(a.error);m(),l()}catch(r){showNotification("Error: "+r.message,"error")}}),C?.addEventListener("click",()=>{y?.classList.add("show"),l()}),wireModal(y,O),E?.addEventListener("click",l),document.querySelector('[data-panel="health-incidents"]')?.addEventListener("click",w),document.querySelector('[data-panel="health-config"]')?.addEventListener("click",m)})(),(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 y=document.getElementById("updates-modal"),C=document.getElementById("updates-btn"),O=document.getElementById("updates-cancel"),E=document.getElementById("updates-check-btn"),M=document.getElementById("updates-available-container"),R=document.getElementById("updates-history-container"),P=document.getElementById("updates-auto-container"),A=document.getElementById("updates-last-check");async function p(){try{const n=await(await fetch("/api/v1/updates/available")).json();if(!n.success)throw new Error(n.error);const e=n.updates||[];if(e.length===0){M.innerHTML='<div class="panel-empty"><span class="empty-icon">\u2705</span>All containers are up to date.</div>',A.textContent="",document.getElementById("updates-update-all-btn").style.display="none",document.getElementById("updates-count-badge").style.display="none",window._pendingUpdates=[];return}let t='<table style="width: 100%; border-collapse: collapse; font-size: 0.85rem;">';t+='<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 a of e){const s=(()=>{const d=window.APPS||[];for(const S of d)if(S.containerId===a.containerId||S.name===a.containerName||S.id===a.containerName)return S.id;return a.containerName})();t+=`<tr data-app-id="${escapeHtml(s)}" style="border-bottom: 1px solid var(--border);">`,t+=`<td style="padding: 8px; font-weight: 500;">${escapeHtml(a.containerName)}</td>`,t+=`<td style="padding: 8px; color: var(--muted);">${escapeHtml(a.imageName)}</td>`,t+=`<td style="padding: 8px;"><code style="font-size: 0.78rem; background: var(--bg); padding: 2px 6px; border-radius: 4px;">${escapeHtml(a.currentDigest)}</code></td>`,t+=`<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(a.latestDigest)}</code></td>`,t+='<td style="padding: 8px; text-align: right;">',t+=`<button class="update-now-btn" data-id="${escapeHtml(a.containerId)}" data-name="${escapeHtml(a.containerName)}" style="padding: 4px 10px; font-size: 0.78rem; background: var(--accent); color: var(--bg); border-color: var(--accent); margin-right: 4px;">Update</button>`,t+=`<button class="rollback-btn" data-id="${escapeHtml(a.containerId)}" data-name="${escapeHtml(a.containerName)}" style="padding: 4px 10px; font-size: 0.78rem;">Rollback</button>`,t+="</td></tr>"}t+="</table>",M.innerHTML=t,A.textContent=e.length+" update(s) available";const o=document.getElementById("updates-count-badge"),r=document.getElementById("updates-update-all-btn");o&&(o.textContent=e.length+" pending",o.style.display=""),r&&e.length>0&&(r.style.display=""),window._pendingUpdates=e,M.querySelectorAll(".update-now-btn").forEach(a=>{a.addEventListener("click",async()=>{const s=a.dataset.id,d=a.dataset.name;if(confirm(`Update "${d}" to the latest version? The container will restart.`)){a.textContent="Updating...",a.disabled=!0;try{const h=await(await secureFetch(`/api/v1/updates/update/${encodeURIComponent(s)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({autoRollback:!0})})).json();if(h.success)a.textContent="Done!",a.style.background="var(--ok-fg)",setTimeout(()=>p(),2e3);else throw new Error(h.error||"Update failed")}catch(S){a.textContent="Failed",a.style.color="var(--bad-fg)",showNotification("Update error: "+S.message,"error"),setTimeout(()=>{a.textContent="Update",a.disabled=!1,a.style.color="",a.style.background=""},3e3)}}})}),M.querySelectorAll(".rollback-btn").forEach(a=>{a.addEventListener("click",async()=>{const s=a.dataset.id,d=a.dataset.name;if(confirm(`Rollback "${d}" to its previous version?`)){a.textContent="Rolling back...",a.disabled=!0;try{const h=await(await secureFetch(`/api/v1/updates/rollback/${encodeURIComponent(s)}`,{method:"POST"})).json();if(h.success)a.textContent="Rolled back!",setTimeout(()=>p(),2e3);else throw new Error(h.error||"Rollback failed")}catch(S){a.textContent="Failed",showNotification("Rollback error: "+S.message,"error"),setTimeout(()=>{a.textContent="Rollback",a.disabled=!1},3e3)}}})})}catch(m){M.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(m.message)}</div>`}}async function T(){const m=window._pendingUpdates||[];if(!m.length)return;const n=document.getElementById("updates-update-all-btn");if(!confirm(`Update all ${m.length} containers? Each will restart.`))return;n.textContent="\u23F3 Updating...",n.disabled=!0;let e=0,t=0;for(const o of m)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++:t++}catch{t++}n.textContent="\u2705 Done",showNotification(`Update all: ${e} succeeded, ${t} failed.`,e>0&&t===0?"success":"error"),setTimeout(()=>{n.textContent="\u2B06\uFE0F Update All",n.disabled=!1,p()},3e3)}document.getElementById("updates-update-all-btn")?.addEventListener("click",T);async function x(){E.textContent="\u{1F50D} Checking...",E.disabled=!0;try{const n=await(await secureFetch("/api/v1/updates/check",{method:"POST"})).json();if(!n.success)throw new Error(n.error);E.textContent="\u2705 Done!",await p()}catch(m){E.textContent="\u274C Failed",showNotification("Check error: "+m.message,"error")}setTimeout(()=>{E.textContent="\u{1F50D} Check for Updates",E.disabled=!1},3e3)}async function $(){try{R.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';const n=await(await fetch("/api/v1/updates/history?limit=50")).json(),e=n.success&&n.history?n.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 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;">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 r=o.status==="success",a=o.duration?o.duration<1e3?o.duration+"ms":Math.round(o.duration/1e3)+"s":"-";t+='<tr style="border-bottom: 1px solid var(--border);">',t+=`<td style="padding: 6px; color: var(--muted);">${timeAgo(o.timestamp)}</td>`,t+=`<td style="padding: 6px; font-weight: 500;">${escapeHtml(o.containerName)}</td>`,t+=`<td style="padding: 6px; color: var(--muted);">${escapeHtml(o.imageName)}</td>`,t+=`<td style="padding: 6px;">${a}</td>`,t+=`<td style="padding: 6px;"><span style="color: ${r?"var(--ok-fg)":"var(--bad-fg)"};">${r?"\u2713 success":"\u2717 failed"}</span></td>`,t+="</tr>",!r&&o.error&&(t+=`<tr><td colspan="5" style="padding: 4px 6px 8px; font-size: 0.78rem; color: var(--bad-fg);">${escapeHtml(o.error)}</td></tr>`)}t+="</table>",R.innerHTML=t}catch(m){R.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(m.message)}</div>`}}async function k(){try{P.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>';const[m,n]=await Promise.all([fetch("/api/v1/stats/containers"),fetch("/api/v1/updates/auto-update")]),e=await m.json(),t=await n.json(),o=e.success&&e.stats?e.stats:[],r=t.success&&t.config?t.config:{};if(o.length===0){P.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F916}</span>No running containers found.</div>';return}let a='<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>';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;">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 d=s.name||s.Names?.[0]?.replace(/^\//,"")||s.Id?.substring(0,12),S=s.containerId||s.Id,h=r[S]||{},U=h.enabled?h.schedule||"weekly":"",_=h.autoRollback!==!1,F=h.maintenanceWindow||"",W=h.lastAutoUpdate?timeAgo(h.lastAutoUpdate):"Never";a+=`<tr style="border-bottom: 1px solid var(--border);" data-container-id="${escapeHtml(S)}">`,a+=`<td style="padding: 8px; font-weight: 500;">${escapeHtml(d)}</td>`,a+=`<td style="padding: 8px;">
|
|
<select class="auto-schedule" data-id="${escapeHtml(S)}" style="padding: 4px 8px; border-radius: 4px; border: 1px solid var(--border); background: var(--bg); color: var(--fg); font-size: 0.82rem;">
|
|
<option value=""${U?"":" selected"}>Disabled</option>
|
|
<option value="daily"${U==="daily"?" selected":""}>Daily</option>
|
|
<option value="weekly"${U==="weekly"?" selected":""}>Weekly</option>
|
|
<option value="monthly"${U==="monthly"?" selected":""}>Monthly</option>
|
|
</select></td>`,a+=`<td style="padding: 8px;"><input type="text" class="auto-window" data-id="${escapeHtml(S)}" 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>`,a+=`<td style="padding: 8px;"><input type="checkbox" class="auto-rollback" data-id="${escapeHtml(S)}"${_?" checked":""} /></td>`,a+=`<td style="padding: 8px; font-size: 0.78rem; color: var(--muted);">${W}</td>`,a+=`<td style="padding: 8px; text-align: right;"><button class="save-auto-btn" data-id="${escapeHtml(S)}" data-name="${escapeHtml(d)}" style="padding: 4px 10px; font-size: 0.78rem;">Save</button></td>`,a+="</tr>"}a+="</table>",P.innerHTML=a,P.querySelectorAll(".save-auto-btn").forEach(s=>{s.addEventListener("click",async()=>{const d=s.dataset.id,S=s.closest("tr"),h=S.querySelector(".auto-schedule").value,U=S.querySelector(".auto-rollback").checked,_=S.querySelector(".auto-window").value.trim();s.textContent="Saving...",s.disabled=!0;try{const W=await(await secureFetch(`/api/v1/updates/auto-update/${encodeURIComponent(d)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({enabled:!!h,schedule:h||"weekly",autoRollback:U,maintenanceWindow:_||void 0})})).json();if(W.success)s.textContent="\u2713 Saved";else throw new Error(W.error)}catch(F){s.textContent="\u2717 Error",showNotification("Save error: "+F.message,"error")}setTimeout(()=>{s.textContent="Save",s.disabled=!1},2e3)})})}catch(m){P.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(m.message)}</div>`}}const H=document.getElementById("dashcaddy-current-version"),L=document.getElementById("dashcaddy-update-badge"),u=document.getElementById("dashcaddy-update-details"),j=document.getElementById("dashcaddy-new-version"),v=document.getElementById("dashcaddy-changelog"),N=document.getElementById("dashcaddy-apply-btn"),g=document.getElementById("dashcaddy-check-btn"),D=document.getElementById("dashcaddy-rollback-btn"),B=document.getElementById("dashcaddy-status-bar"),f=document.getElementById("dashcaddy-history-container");let I=null;function b(m,n){B&&(B.style.display="block",B.style.background=n==="error"?"var(--bad-bg)":n==="success"?"var(--ok-bg)":"var(--bg)",B.style.color=n==="error"?"var(--bad-fg)":n==="success"?"var(--ok-fg)":"var(--fg)",B.textContent=m)}async function z(){try{const n=await(await fetch("/api/v1/system/version")).json();if(n.success){const e=n.commit&&n.commit!=="unknown"?n.commit:null;H.textContent="v"+n.version+(e?" ("+e.substring(0,7)+")":"")}}catch{H.textContent="Unable to fetch version"}}async function i(m){m||(g.textContent="Checking...",g.disabled=!0);try{const e=await(await fetch("/api/v1/system/update-check")).json();if(I=e,e.success&&e.available&&e.remote){L.style.display="",u.style.display="",j.textContent="v"+e.remote.version,v.textContent=e.remote.changelog||"No changelog available.";const t=document.getElementById("updates-btn");if(t&&!t.querySelector(".update-dot")){const r=document.createElement("span");r.className="update-dot",r.style.cssText="position:absolute;top:2px;right:2px;width:8px;height:8px;border-radius:50%;background:var(--accent);",t.style.position="relative",t.appendChild(r)}const o=document.getElementById("updates-dashcaddy-tab");if(o&&!o.querySelector(".update-dot")){const r=document.createElement("span");r.className="update-dot",r.style.cssText="display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--accent);margin-left:4px;vertical-align:middle;",o.appendChild(r)}}else L.style.display="none",u.style.display="none",await z(),m||b("You are running the latest version.","success");m||(g.textContent="Check for Updates",g.disabled=!1)}catch(n){m||(b("Failed to check: "+n.message,"error"),g.textContent="Check for Updates",g.disabled=!1)}}async function c(){if(!confirm("Apply DashCaddy update? The API container will restart."))return!1;N.textContent="Updating...",N.disabled=!0,b("Downloading and applying update...","info");try{const n=await(await secureFetch("/api/v1/system/update-apply",{method:"POST"})).json();if(n.success)return b("Update initiated: v"+(n.fromVersion||"?")+" \u2192 v"+(n.toVersion||"?")+". The container will restart shortly.","success"),N.textContent="Applied!",document.querySelectorAll(".update-dot").forEach(e=>e.remove()),!0;throw new Error(n.error||"Update failed")}catch(m){throw b("Update failed: "+m.message,"error"),N.textContent="Update Now",N.disabled=!1,m}}async function l(){try{const n=await(await fetch("/api/v1/system/update-history")).json(),e=n.success&&n.history?n.history:[];if(e.length===0){f.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4E6}</span>No self-update history.</div>';return}let 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;">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 r=o.status==="success"?"\u2713 success":o.status==="pending"?"\u23F3 pending":o.status==="partial"?"\u26A0 partial":"\u2717 "+o.status,a=o.status==="success"?"var(--ok-fg)":o.status==="pending"?"var(--muted)":"var(--bad-fg)";t+='<tr style="border-bottom: 1px solid var(--border);">',t+='<td style="padding: 6px; color: var(--muted);">'+timeAgo(o.timestamp)+"</td>",t+='<td style="padding: 6px; font-weight: 500;">v'+escapeHtml(o.version)+(o.rollback?" (rollback)":"")+"</td>",t+='<td style="padding: 6px; color: var(--muted);">v'+escapeHtml(o.fromVersion||"?")+"</td>",t+='<td style="padding: 6px;"><span style="color: '+a+';">'+r+"</span></td>",t+="</tr>",o.error&&(t+='<tr><td colspan="4" style="padding: 4px 6px 8px; font-size: 0.78rem; color: var(--bad-fg);">'+escapeHtml(o.error)+"</td></tr>"),o.note&&(t+='<tr><td colspan="4" style="padding: 4px 6px 8px; font-size: 0.78rem; color: var(--muted);">'+escapeHtml(o.note)+"</td></tr>")}t+="</table>",f.innerHTML=t}catch(m){f.innerHTML='<div class="panel-empty" style="color: var(--bad-fg);">Failed: '+escapeHtml(m.message)+"</div>"}}async function w(){try{const n=await(await fetch("/api/v1/system/rollback-versions")).json(),e=n.success&&n.versions?n.versions:[];if(e.length===0){showNotification("No rollback versions available.","info");return}const t=prompt(`Available rollback versions:
|
|
`+e.join(`
|
|
`)+`
|
|
|
|
Enter version to rollback to:`);if(!t)return;if(!e.includes(t)){showNotification("Invalid version: "+t,"error");return}if(!confirm("Rollback DashCaddy to v"+t+"? The container will restart."))return;b("Rolling back to v"+t+"...","info");const r=await(await secureFetch("/api/v1/system/rollback",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({version:t})})).json();if(r.success)b("Rollback to v"+t+" initiated. Container will restart.","success");else throw new Error(r.error||"Rollback failed")}catch(m){b("Rollback failed: "+m.message,"error")}}g?.addEventListener("click",()=>i(!1)),N?.addEventListener("click",()=>c().catch(()=>{})),D?.addEventListener("click",w),E?.addEventListener("click",x),C?.addEventListener("click",()=>{y?.classList.add("show"),p()}),wireModal(y,O),window.openUpdateModal=function(m){y?.classList.add("show"),p().then(()=>{if(!m)return;const n=M.querySelector(`[data-app-id="${m}"]`);n&&(n.scrollIntoView({behavior:"smooth",block:"center"}),n.style.background="rgba(249,115,22,0.15)",setTimeout(()=>{n.style.background=""},3e3))})},document.querySelector('[data-panel="updates-history"]')?.addEventListener("click",$),document.querySelector('[data-panel="updates-auto"]')?.addEventListener("click",k),document.querySelector('[data-panel="updates-dashcaddy"]')?.addEventListener("click",()=>{z(),l(),I||i(!0)}),window.dcApplyUpdate=c,window.dcCheckForUpdate=i,setTimeout(()=>i(!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 y=document.getElementById("docker-resources-modal"),C=document.getElementById("docker-resources-btn"),O=document.getElementById("dr-close");function E(A){if(!A||A===0)return"0 B";const p=["B","KB","MB","GB","TB"],T=Math.floor(Math.log(Math.abs(A))/Math.log(1024));return(A/Math.pow(1024,T)).toFixed(1)+" "+p[T]}async function M(){const A=document.getElementById("dr-vol-list");try{const T=(await getJSON("/api/v1/docker/volumes")).volumes||[];if(T.length===0){A.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 T){const k=$.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;">',k||(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>",A.innerHTML=x,A.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`),M()}catch(k){showNotification("Delete failed: "+k.message,"error"),$.textContent="Delete",$.disabled=!1}}})})}catch(p){A.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(p.message)}</div>`}}document.getElementById("dr-vol-create")?.addEventListener("click",async()=>{const A=document.getElementById("dr-vol-name"),p=A.value.trim();if(!p){showNotification("Enter a volume name","warning");return}try{await postJSON("/api/v1/docker/volumes",{name:p}),A.value="",showNotification(`Volume "${p}" created`,"success"),M()}catch(T){showNotification("Create failed: "+T.message,"error")}});async function R(){const A=document.getElementById("dr-net-list");try{const T=(await getJSON("/api/v1/docker/networks")).networks||[];if(T.length===0){A.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 T){const k=["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;">',k||(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>",A.innerHTML=x,A.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(k){showNotification("Delete failed: "+k.message,"error"),$.textContent="Delete",$.disabled=!1}}})})}catch(p){A.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(p.message)}</div>`}}document.getElementById("dr-net-create")?.addEventListener("click",async()=>{const A=document.getElementById("dr-net-name"),p=document.getElementById("dr-net-driver"),T=A.value.trim();if(!T){showNotification("Enter a network name","warning");return}try{await postJSON("/api/v1/docker/networks",{name:T,driver:p.value}),A.value="",showNotification(`Network "${T}" created`,"success"),R()}catch(x){showNotification("Create failed: "+x.message,"error")}});async function P(){const A=document.getElementById("dr-disk-content");try{const p=await getJSON("/api/v1/docker/disk-usage"),T=[{label:"Images",icon:"\u{1F4C0}",count:p.images.count,size:p.images.size,reclaimable:p.images.reclaimable},{label:"Containers",icon:"\u{1F4E6}",count:p.containers.count,size:p.containers.size,extra:`${p.containers.running} running`},{label:"Volumes",icon:"\u{1F4BE}",count:p.volumes.count,size:p.volumes.size,reclaimable:p.volumes.reclaimable},{label:"Build Cache",icon:"\u{1F527}",count:p.buildCache.count,size:p.buildCache.size,reclaimable:p.buildCache.reclaimable}];let x=`<div style="font-size: 1.1rem; font-weight: 600; margin-bottom: 16px;">Total: ${E(p.totalSize)}</div>`;x+='<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">';for(const $ of T)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);">${E($.size)}</div>`,$.reclaimable>0&&(x+=`<div style="font-size: 0.78rem; color: var(--muted);">Reclaimable: ${E($.reclaimable)}</div>`),$.extra&&(x+=`<div style="font-size: 0.78rem; color: var(--muted);">${$.extra}</div>`),x+="</div>";x+="</div>",A.innerHTML=x}catch(p){A.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(p.message)}</div>`}}C?.addEventListener("click",()=>{y?.classList.add("show"),M()}),wireModal(y,O),document.querySelector('[data-panel="dr-networks"]')?.addEventListener("click",R),document.querySelector('[data-panel="dr-disk"]')?.addEventListener("click",P)})(),(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 y=document.getElementById("compose-import-modal"),C=document.getElementById("compose-import-btn"),O=document.getElementById("compose-cancel");wireModal(y,O);let E=null;function M(P){document.getElementById("compose-step-paste").style.display=P==="paste"?"":"none",document.getElementById("compose-step-preview").style.display=P==="preview"?"":"none",document.getElementById("compose-step-progress").style.display=P==="progress"?"":"none"}C?.addEventListener("click",()=>{M("paste"),E=null,document.getElementById("compose-yaml").value="",document.getElementById("compose-stack-name").value="",y?.classList.add("show")}),document.getElementById("compose-file-upload")?.addEventListener("change",P=>{const A=P.target.files[0];if(!A)return;const p=new FileReader;p.onload=()=>{document.getElementById("compose-yaml").value=p.result},p.readAsText(A)}),document.getElementById("compose-parse-btn")?.addEventListener("click",async()=>{const P=document.getElementById("compose-yaml").value.trim(),A=document.getElementById("compose-stack-name").value.trim()||"stack";if(!P){showNotification("Paste a docker-compose.yml","warning");return}const p=document.getElementById("compose-parse-btn"),T=p.textContent;p.textContent="Parsing...",p.disabled=!0;try{const x=await postJSON("/api/v1/apps/import-compose",{yaml:P,stackName:A});E=x,E.stackName=A,R(x),M("preview")}catch(x){showNotification("Parse failed: "+x.message,"error")}finally{p.textContent=T,p.disabled=!1}});function R(P){const A=document.getElementById("compose-preview-content");let p="";P.networks&&P.networks.length>0&&(p+=`<div style="margin-bottom: 12px; font-size: 0.82rem; color: var(--muted);">Networks: ${P.networks.map(T=>`<code>${escapeHtml(T)}</code>`).join(", ")}</div>`),P.volumes&&P.volumes.length>0&&(p+=`<div style="margin-bottom: 12px; font-size: 0.82rem; color: var(--muted);">Volumes: ${P.volumes.map(T=>`<code>${escapeHtml(T)}</code>`).join(", ")}</div>`),p+=`<div style="font-weight: 600; margin-bottom: 8px;">${P.services.length} service(s)</div>`,p+='<div class="scroll-container" style="max-height: 350px;">';for(const T of P.services){const x=T.skip?"var(--bad-fg)":"var(--border)";if(p+=`<div style="padding: 10px 14px; border: 1px solid ${x}; border-radius: 8px; margin-bottom: 8px; background: var(--bg);">`,p+=`<div style="font-weight: 600; font-size: 0.9rem;">${escapeHtml(T.name)}`,T.skip&&(p+=` <span style="color: var(--bad-fg); font-weight: 400; font-size: 0.78rem;">\u2014 skipped: ${escapeHtml(T.reason)}</span>`),p+="</div>",!T.skip&&(p+=`<div style="font-size: 0.8rem; color: var(--muted); margin-top: 4px;">Image: <code>${escapeHtml(T.image)}</code></div>`,T.ports?.length&&(p+=`<div style="font-size: 0.8rem; color: var(--muted);">Ports: ${T.ports.map($=>`${$.host}:${$.container}`).join(", ")}</div>`),T.volumes?.length&&(p+=`<div style="font-size: 0.8rem; color: var(--muted);">Volumes: ${T.volumes.length}</div>`),Object.keys(T.environment||{}).length&&(p+=`<div style="font-size: 0.8rem; color: var(--muted);">Env vars: ${Object.keys(T.environment).length}</div>`),T.envFileWarning&&(p+=`<div style="font-size: 0.78rem; color: var(--bad-fg);">\u26A0 ${escapeHtml(T.envFileWarning)}</div>`),T.resources?.cpus||T.resources?.memory)){const $=[];T.resources.cpus&&$.push(`CPU: ${T.resources.cpus}`),T.resources.memory&&$.push(`Mem: ${T.resources.memory}MB`),p+=`<div style="font-size: 0.8rem; color: var(--muted);">Limits: ${$.join(", ")}</div>`}p+="</div>"}p+="</div>",A.innerHTML=p}document.getElementById("compose-back-btn")?.addEventListener("click",()=>M("paste")),document.getElementById("compose-deploy-btn")?.addEventListener("click",async()=>{if(!E)return;const P=document.getElementById("compose-deploy-btn");P.textContent="Deploying...",P.disabled=!0,M("progress");const A=document.getElementById("compose-progress-content");A.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Deploying services...</div>';try{const p=await postJSON("/api/v1/apps/deploy-compose",{services:E.services,networks:E.networks,stackName:E.stackName});let T=`<div style="font-weight: 600; margin-bottom: 12px;">Stack "${escapeHtml(p.stackName)}" \u2014 Deployment Complete</div>`;T+='<div class="scroll-container" style="max-height: 350px;">';for(const x of p.results){const $=x.status==="deployed"||x.status==="created"?"\u2705":x.status==="exists"?"\u26A1":x.status==="skipped"?"\u23ED":"\u274C";T+='<div style="padding: 8px 12px; border-bottom: 1px solid var(--border); font-size: 0.85rem;">',T+=`${$} <strong>${escapeHtml(x.name)}</strong> (${x.type}) \u2014 ${escapeHtml(x.status)}`,x.error&&(T+=` <span style="color: var(--bad-fg);">${escapeHtml(x.error)}</span>`),x.subdomain&&(T+=` \u2192 <code>${escapeHtml(x.subdomain)}</code>`),x.reason&&(T+=` <span style="color: var(--muted);">(${escapeHtml(x.reason)})</span>`),T+="</div>"}T+="</div>",T+='<div class="weather-modal-buttons modal-footer-bar" style="margin-top: 16px;"><button id="compose-done-btn">Done</button></div>',A.innerHTML=T,document.getElementById("compose-done-btn")?.addEventListener("click",()=>{y?.classList.remove("show"),typeof window.loadServices=="function"&&window.loadServices().then(()=>{typeof window.buildGrid=="function"&&window.buildGrid()})}),showNotification(`Stack "${p.stackName}" deployed`,"success")}catch(p){A.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Deployment failed: ${escapeHtml(p.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",()=>M("paste"))}finally{P.textContent="Deploy All",P.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 y=document.getElementById("exec-modal"),C=document.getElementById("exec-terminal"),O=document.getElementById("exec-close");let E=null,M=null,R=null;function P(){if(M){try{M.close()}catch{}M=null}if(E){try{E.dispose()}catch{}E=null}R=null,C.innerHTML=""}function A(p,T){if(P(),document.getElementById("exec-title").textContent=`Terminal \u2014 ${T||p}`,y?.classList.add("show"),typeof Terminal>"u"){C.innerHTML='<div style="color: #f44; padding: 20px; font-family: monospace;">xterm.js not loaded</div>';return}E=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,E.loadAddon(R)),E.open(C),R&&setTimeout(()=>R.fit(),50);const x=location.protocol==="https:"?"wss:":"ws:";M=new WebSocket(`${x}//${location.host}/ws/exec/${encodeURIComponent(p)}`),M.binaryType="arraybuffer",M.onopen=()=>{if(E.writeln("\x1B[32mConnecting...\x1B[0m"),R){const k=R.proposeDimensions();k&&M.send(JSON.stringify({type:"resize",cols:k.cols,rows:k.rows}))}},M.onmessage=k=>{if(typeof k.data=="string"){try{const H=JSON.parse(k.data);if(H.type==="connected"){E.writeln(`\x1B[32mConnected (${H.shell})\x1B[0m\r
|
|
`);return}if(H.type==="error"){E.writeln(`\x1B[31mError: ${H.message}\x1B[0m`);return}if(H.type==="exit"){E.writeln(`\r
|
|
\x1B[33mSession ended.\x1B[0m`);return}}catch{}E.write(k.data)}else E.write(new Uint8Array(k.data))},M.onclose=()=>{E&&E.writeln(`\r
|
|
\x1B[33mDisconnected.\x1B[0m`)},M.onerror=()=>{E&&E.writeln(`\r
|
|
\x1B[31mConnection error.\x1B[0m`)},E.onData(k=>{M&&M.readyState===WebSocket.OPEN&&M.send(k)}),E.onResize(({cols:k,rows:H})=>{M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"resize",cols:k,rows:H}))});const $=()=>{R&&R.fit()};window.addEventListener("resize",$),y._resizeHandler=$}O?.addEventListener("click",()=>{P(),y._resizeHandler&&window.removeEventListener("resize",y._resizeHandler),y?.classList.remove("show")}),y?.addEventListener("click",p=>{p.target===y&&(P(),y._resizeHandler&&window.removeEventListener("resize",y._resizeHandler),y?.classList.remove("show"))}),window.openExecModal=A})(),(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 y=document.getElementById("audit-modal"),C=document.getElementById("audit-log-btn"),O=document.getElementById("audit-cancel"),E=document.getElementById("audit-refresh-btn"),M=document.getElementById("audit-clear-btn"),R=document.getElementById("audit-filter"),P=document.getElementById("audit-log-container"),A=document.getElementById("audit-load-more");let p=0;const T=50;async function x($){try{$||(p=0,P.innerHTML='<div class="panel-empty"><span class="brand-spinner"></span> Loading...</div>');const k=R.value;let H=`/api/v1/audit-logs?limit=${T}&offset=${p}`;k&&(H+=`&action=${encodeURIComponent(k)}`);const u=await(await fetch(H)).json(),j=u.success&&u.entries?u.entries:[];if(j.length===0&&!$){P.innerHTML='<div class="panel-empty"><span class="empty-icon">\u{1F4DC}</span>No audit log entries yet. Actions will be logged automatically.</div>',A.style.display="none";return}let v="";$||(v='<table style="width: 100%; border-collapse: collapse; font-size: 0.82rem;">',v+='<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 N of j){const g=N.outcome==="success";v+='<tr style="border-bottom: 1px solid var(--border); cursor: pointer;" class="audit-row">',v+=`<td style="padding: 6px; color: var(--muted);">${timeAgo(N.timestamp)}</td>`,v+=`<td style="padding: 6px; font-family: monospace; font-size: 0.78rem;">${escapeHtml(N.ip||"-")}</td>`,v+=`<td style="padding: 6px; font-weight: 500;">${escapeHtml(N.action||"-")}</td>`,v+=`<td style="padding: 6px;">${escapeHtml(N.resource||"-")}</td>`,v+=`<td style="padding: 6px;"><span style="color: ${g?"var(--ok-fg)":"var(--bad-fg)"};">${g?"\u2713":"\u2717"}</span></td>`,v+="</tr>",N.details&&Object.keys(N.details).length>0&&(v+=`<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(N.details,null,2))}</pre></td></tr>`)}if(!$)v+="</table>",P.innerHTML=v;else{const N=P.querySelector("table");N&&N.insertAdjacentHTML("beforeend",v)}p+=j.length,A.style.display=j.length>=T?"":"none",P.querySelectorAll(".audit-row").forEach(N=>{N.dataset.wired||(N.dataset.wired="true",N.addEventListener("click",()=>{const g=N.nextElementSibling;g&&g.classList.contains("audit-detail")&&(g.style.display=g.style.display==="none"?"":"none")}))})}catch(k){P.innerHTML=`<div class="panel-empty" style="color: var(--bad-fg);">Failed: ${escapeHtml(k.message)}</div>`}}C?.addEventListener("click",()=>{y?.classList.add("show"),x(!1)}),wireModal(y,O),E?.addEventListener("click",()=>x(!1)),R?.addEventListener("change",()=>x(!1)),A?.addEventListener("click",()=>x(!0)),M?.addEventListener("click",async()=>{if(confirm("Clear the entire audit log? This cannot be undone."))try{const k=await(await secureFetch("/api/v1/audit-logs",{method:"DELETE"})).json();k.success?x(!1):showNotification("Error: "+(k.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 y=document.getElementById("security-modal"),C=document.getElementById("security-center-btn"),O=document.getElementById("sec-cancel"),E=y.querySelectorAll(".sec-tab"),M=y.querySelectorAll(".sec-panel");let R=[],P=[],A=null;E.forEach(i=>{i.addEventListener("click",()=>{E.forEach(c=>c.classList.toggle("active",c===i)),M.forEach(c=>c.style.display=c.dataset.panel===i.dataset.tab?"":"none"),i.dataset.tab==="overview"&&$(),i.dataset.tab==="events"&&N(),i.dataset.tab==="hosts"&&f()})}),C&&C.addEventListener("click",()=>{y.classList.add("show"),$(),T()}),O.addEventListener("click",p),y.addEventListener("click",i=>{i.target===y&&p()});function p(){y.classList.remove("show"),x()}function T(){if(x(),!!document.getElementById("sec-live-tail").checked&&!(typeof EventSource>"u"))try{A=new EventSource("/api/v1/security/events/stream"),A.addEventListener("init",i=>{try{R=JSON.parse(i.data).events||[],g()}catch{}}),A.addEventListener("security",i=>{try{const c=JSON.parse(i.data);R.unshift(c),R.length>500&&(R.length=500);const l=y.querySelector(".sec-tab.active")?.dataset?.tab;l==="events"?g():l==="overview"&&$()}catch{}}),A.onerror=()=>{}}catch(i){console.warn("[security] SSE failed:",i.message)}}function x(){if(A){try{A.close()}catch{}A=null}}document.getElementById("sec-live-tail").addEventListener("change",()=>{y.classList.contains("show")&&T()});async function $(){try{const i=new Date(Date.now()-864e5).toISOString(),[c,l,w]=await Promise.all([fetch(`/api/v1/security/events/stats?since=${encodeURIComponent(i)}`),fetch("/api/v1/security/hosts"),fetch(`/api/v1/security/events?limit=1&since=${encodeURIComponent(i)}`)]),m=(await c.json()).data||{},n=(await l.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=`${m.by_severity?.warn||0} warnings`,document.querySelector('#sec-stats [data-key="error"]').textContent=`${m.by_severity?.error||0} errors`,document.querySelector('#sec-stats [data-key="denied"]').textContent=`${m.by_outcome?.denied||0} denied`,document.querySelector('#sec-stats [data-key="hosts"]').textContent=`${n.length} hosts`,k("sec-top-actors",m.top_actors||[]),k("sec-top-targets",m.top_targets||[])}catch(i){console.warn("[security] refreshOverview failed:",i.message)}}function k(i,c){const l=document.getElementById(i);if(!c.length){l.innerHTML='<div class="panel-empty">No data</div>';return}l.innerHTML='<table style="width:100%;font-size:0.85rem;">'+c.map(w=>`<tr><td style="padding:3px 0;word-break:break-all;">${b(String(w.key))}</td><td style="text-align:right;color:var(--muted);">${w.count}</td></tr>`).join("")+"</table>"}const H=document.getElementById("sec-filter-source"),L=document.getElementById("sec-filter-severity"),u=document.getElementById("sec-filter-host"),j=document.getElementById("sec-filter-actor"),v=document.getElementById("sec-refresh-btn");[H,L,u].forEach(i=>i.addEventListener("change",N)),j.addEventListener("input",z(N,250)),v.addEventListener("click",N);async function N(){try{const i=new URLSearchParams;i.set("limit","200"),H.value&&i.set("source_type",H.value),L.value&&i.set("severity",L.value),u.value&&i.set("source_host",u.value),j.value&&i.set("actor_prefix",j.value),R=(await(await fetch(`/api/v1/security/events?${i}`)).json()).data.events||[],g(),(!u.options.length||u.options.length===1)&&await B()}catch(i){document.getElementById("sec-events-container").innerHTML='<div class="panel-empty">Load failed: '+b(i.message)+"</div>"}}function g(){const i=document.getElementById("sec-events-container");if(!R.length){i.innerHTML='<div class="panel-empty">No events</div>';return}i.innerHTML=R.slice(0,200).map(D).join("")}function D(i){const c=i.severity||"info",l={critical:"#c0392b",error:"#e74c3c",warn:"#f39c12",notice:"#3498db",info:"#7f8c8d"}[c]||"#7f8c8d",w=i.ts?new Date(i.ts).toLocaleTimeString():"",m=i.source_type||"",n=i.actor||"\u2014",e=i.target||"",t=i.action||"",o=i.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:${l};font-weight:600;">${b(c)}</span>
|
|
<span style="color:var(--muted);font-size:0.75rem;">${b(m)}</span>
|
|
<span title="${b(n)}" style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${b(n)}</span>
|
|
<span title="${b(e)}" style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${b(t)} ${b(e)}</span>
|
|
<span style="color:var(--muted);font-size:0.75rem;">${b(o)}</span>
|
|
<span style="color:var(--muted);font-size:0.75rem;text-align:right;">${b(w)}</span>
|
|
</div>`}async function B(){try{const c=(await(await fetch("/api/v1/security/hosts")).json()).data?.hosts||[],l=u.value;u.innerHTML='<option value="">All hosts</option>'+c.map(w=>`<option value="${b(w.id)}">${b(w.label||w.id)}</option>`).join(""),l&&(u.value=l)}catch{}}document.getElementById("sec-host-register-btn").addEventListener("click",I),document.getElementById("sec-hosts-refresh").addEventListener("click",f);async function f(){try{const c=(await(await fetch("/api/v1/security/hosts")).json()).data?.hosts||[];P=c;const l=document.getElementById("sec-hosts-container");if(!c.length){l.innerHTML='<div class="panel-empty">No hosts registered. Click \u2795 Register Host to add one.</div>';return}l.innerHTML=c.map(w=>{const m=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>${b(w.label||w.id)}</strong>
|
|
<span style="color:var(--muted);margin-left:8px;font-size:0.8rem;">${b(w.type)}</span>
|
|
<div style="color:var(--muted);font-size:0.78rem;margin-top:2px;">
|
|
id: ${b(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;">${m}</span>
|
|
${w.id==="self"?"":`<button class="btn-sm sec-host-del" data-id="${b(w.id)}" style="color:var(--bad-fg);">Remove</button>`}
|
|
</div>
|
|
</div>`}).join(""),l.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"}),f())})})}catch(i){document.getElementById("sec-hosts-container").innerHTML='<div class="panel-empty">Load failed: '+b(i.message)+"</div>"}}async function I(){const i=prompt("Host id (lowercase, no spaces):");if(!i)return;const c=prompt("Display label:",i)||i,l=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:i,label:c,type:l})}),m=await w.json();if(!w.ok){alert("Failed: "+(m?.error?.message||w.statusText));return}alert(`\u2705 Host registered!
|
|
|
|
id: ${m.data.host.id}
|
|
label: ${m.data.host.label}
|
|
type: ${m.data.host.type}
|
|
|
|
\u{1F511} API KEY (save this NOW \u2014 won't be shown again):
|
|
|
|
${m.data.api_key}
|
|
|
|
Send this key as: Authorization: Bearer <api_key>
|
|
To endpoint: POST /api/v1/security/events/ingest or /events/batch`),f()}catch(w){alert("Failed: "+w.message)}}function b(i){return String(i).replace(/[&<>"']/g,c=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[c])}function z(i,c){let l;return function(){clearTimeout(l),l=setTimeout(()=>i.apply(this,arguments),c)}}})(),(function(){const y=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 C="weather-location",O="weather-zip",E="weather-geo",M="weather-unit";!safeGet(C)&&safeGet(O)&&safeSet(C,safeGet(O));function R(){return safeGet(M)||"imperial"}function P(){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 A={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"},p={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"},T=["N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"];function x(v){return T[Math.round(v/22.5)%16]}async function $(v){const N=safeGet(E);if(N)try{const I=JSON.parse(N);if(I.query===v)return I}catch{}const g=await fetch(`https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(v)}&count=1&language=en&format=json`);if(!g.ok)throw new Error("Geocoding failed");const D=await g.json();if(!D.results||!D.results.length)throw new Error("Location not found");const B=D.results[0],f={query:v,lat:B.latitude,lon:B.longitude,city:B.name,state:B.admin1||"",country:B.country||"",countryCode:B.country_code||""};return safeSet(E,JSON.stringify(f)),f}function k(v){return v.countryCode==="US"&&v.state?`${v.city}, ${v.state}`:v.country?`${v.city}, ${v.country}`:v.city}async function H(v){try{const N=await $(v),g=R(),D=g==="metric"?"celsius":"fahrenheit",B=g==="metric"?"kmh":"mph",f=`https://api.open-meteo.com/v1/forecast?latitude=${N.lat}&longitude=${N.lon}¤t=temperature_2m,weather_code,wind_speed_10m,wind_direction_10m&temperature_unit=${D}&wind_speed_unit=${B}`,I=await fetch(f);if(!I.ok)throw new Error("Weather fetch failed");const z=(await I.json()).current,i=z.weather_code;return{temp:Math.round(z.temperature_2m),condition:A[i]||"Unknown",icon:p[i]||"\u{1F324}\uFE0F",locationStr:k(N),windSpeed:Math.round(z.wind_speed_10m),windDir:x(z.wind_direction_10m),unit:g}}catch(N){return console.warn("Weather fetch failed:",N),null}}async function L(){const v=P();if(!v.icon||!v.temp||!v.condition||!v.location||!v.wind){console.warn("Weather widget elements not found");return}const N=safeGet(C);if(!N){v.location.textContent="Set Location",v.temp.textContent="--\xB0",v.condition.textContent="Click \u2699\uFE0F to configure",v.wind.textContent="--",v.icon.innerHTML='<span class="weather-emoji">\u{1F324}\uFE0F</span>';return}try{const g=await H(N);if(g){const D=g.unit==="metric"?"\xB0C":"\xB0F",B=g.unit==="metric"?"km/h":"mph";v.location.textContent=g.locationStr,v.temp.textContent=`${g.temp}${D}`,v.condition.textContent=g.condition,v.wind.textContent=`Wind: ${g.windSpeed} ${B} ${g.windDir}`,v.icon.innerHTML=`<span class="weather-emoji">${escapeHtml(g.icon)}</span>`}}catch(g){y.logError("[Weather] Update Error",g,{function:"updateWeather"}),v.location.textContent="Weather Error",v.temp.textContent="Error",v.condition.textContent="Failed to load",v.wind.textContent="--"}}const u=document.getElementById("weather-modal"),j=document.getElementById("weather-location-input");document.getElementById("weather-settings")?.addEventListener("click",()=>{j.value=safeGet(C)||"";const v=R(),N=u.querySelector(`input[name="weather-unit-radio"][value="${v}"]`);N&&(N.checked=!0),u.classList.add("show"),j.focus()}),document.getElementById("weather-cancel")?.addEventListener("click",()=>{u.classList.remove("show")}),document.getElementById("weather-save")?.addEventListener("click",()=>{const v=j.value.trim();if(v){safeGet(C)!==v&&safeSet(E,""),safeSet(C,v);const g=u.querySelector('input[name="weather-unit-radio"]:checked'),D=g?g.value:"imperial",B=R();safeSet(M,D),B!==D&&safeSet(E,""),u.classList.remove("show"),L()}else showNotification("Please enter a location (e.g., Hamburg, London, 90210)","warning")}),wireModal(u),document.addEventListener("keydown",v=>{v.key==="Escape"&&u.classList.contains("show")&&u.classList.remove("show")}),L(),setInterval(L,DC.POLL.WEATHER)})(),(function(){const y=document.getElementById("clock-widget"),C=document.getElementById("clock-render");if(!y||!C)return;const O=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],E=["January","February","March","April","May","June","July","August","September","October","November","December"],M=["XII","I","II","III","IV","V","VI","VII","VIII","IX","X","XI"];let R=safeGet("clock-style")||"default",P=-1,A=!1,p="",T="",x=null,$=null;function k(n){if(A||safeGet("clock-chimes")!=="true")return;A=!0;const e=parseInt(safeGet("clock-chime-volume")||"50",10)/100;let t=0;function o(){if(t>=n){A=!1;return}const r=new Audio("/assets/sounds/church-bell.mp3");r.volume=e,r.play().catch(()=>{}),t++,t<n?setTimeout(o,2500):setTimeout(()=>{A=!1},2500)}o()}function H(n){return O[n.getDay()]+", "+E[n.getMonth()]+" "+n.getDate()+", "+n.getFullYear()}function L(){T="",x=null}function u(){return T!=="digital"&&(C.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:C.querySelector(".clock-main"),seconds:C.querySelector(".clock-seconds"),ampm:C.querySelector(".clock-ampm"),date:C.querySelector(".clock-date")},T="digital"),x}function j(n){const e=n.getHours(),t=n.getMinutes(),o=n.getSeconds(),r=e>=12?"PM":"AM",a=e%12||12,s=u();s.main.textContent=`${a}:${String(t).padStart(2,"0")}`,s.seconds.textContent=`:${String(o).padStart(2,"0")}`,s.ampm.textContent=r,s.date.textContent=H(n)}function v(n,e){const t=n.getHours(),o=n.getMinutes(),r=n.getSeconds(),a=t>=12?"PM":"AM",s=t%12||12,d=u();d.main.textContent=`${String(s).padStart(2,"0")}:${String(o).padStart(2,"0")}`,d.seconds.textContent=`:${String(r).padStart(2,"0")}`,d.ampm.textContent=a,d.date.textContent=H(n)}function N(n){const e=n.getHours(),t=n.getMinutes(),o=n.getSeconds(),r=e>=12?"PM":"AM",a=e%12||12,s=String(a).padStart(2," ")+String(t).padStart(2,"0")+String(o).padStart(2,"0");let d='<div class="flip-clock-row">';if(d+=g(s[0],0),d+=g(s[1],1),d+='<span class="flip-colon">:</span>',d+=g(s[2],2),d+=g(s[3],3),d+='<span class="flip-colon">:</span>',d+=g(s[4],4),d+=g(s[5],5),d+=`<span class="flip-ampm">${r}</span>`,d+="</div>",d+=`<div class="clock-date">${H(n)}</div>`,C.innerHTML=d,T="flip",p){for(let S=0;S<6;S++)if(s[S]!==p[S]){const h=C.querySelector(`.flip-card[data-idx="${S}"]`);h&&h.classList.add("flipping")}}p=s}function g(n,e){const t=n===" "?"":n;return`<div class="flip-card" data-idx="${e}"><div class="flip-top">${t}</div><div class="flip-bottom">${t}</div></div>`}function D(n){const e=n.getHours(),t=n.getMinutes(),o=n.getSeconds(),r=e%12||12,a=e>=12?"PM":"AM",s=[Math.floor(r/10),r%10,Math.floor(t/10),t%10,Math.floor(o/10),o%10];let d='<div class="binary-clock">';d+='<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 S=3;S>=0;S--){d+='<div class="binary-row">';for(let h=0;h<6;h++){const U=s[h]>>S&1;d+=`<div class="binary-dot ${U?"on":""}"></div>`}d+="</div>"}d+='<div class="binary-values">';for(let S=0;S<6;S++)d+=`<span>${s[S]}</span>`;d+="</div>",d+=`<div class="binary-ampm">${a}</div>`,d+="</div>",d+=`<div class="clock-date">${H(n)}</div>`,C.innerHTML=d,T="binary"}function B(n,e){const t=n.getHours(),o=n.getMinutes(),r=n.getSeconds(),a=120,s=a/2,d=a/2,S=r/60*360-90,h=(o+r/60)/60*360-90,U=(t%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=d+ne*Math.sin(Q),Y=e?M[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=d+oe*Math.sin(Q),ie=s+ne*Math.cos(Q),re=d+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 W=`<svg class="analog-clock-svg" viewBox="0 0 ${a} ${a}" width="${a}" height="${a}">
|
|
<circle cx="${s}" cy="${d}" r="58" fill="none" stroke="var(--border)" stroke-width="2"/>
|
|
${F}
|
|
${_}
|
|
<line x1="${s}" y1="${d}" x2="${s+28*Math.cos(U*Math.PI/180)}" y2="${d+28*Math.sin(U*Math.PI/180)}" stroke="var(--fg)" stroke-width="3" stroke-linecap="round"/>
|
|
<line x1="${s}" y1="${d}" x2="${s+38*Math.cos(h*Math.PI/180)}" y2="${d+38*Math.sin(h*Math.PI/180)}" stroke="var(--fg)" stroke-width="2" stroke-linecap="round"/>
|
|
<line x1="${s}" y1="${d}" x2="${s+42*Math.cos(S*Math.PI/180)}" y2="${d+42*Math.sin(S*Math.PI/180)}" stroke="#e74c3c" stroke-width="1" stroke-linecap="round"/>
|
|
<circle cx="${s}" cy="${d}" r="3" fill="var(--fg)"/>
|
|
</svg>`,J=n.getHours()>=12?"PM":"AM";C.innerHTML=`<div class="analog-clock-wrap">${W}<div class="analog-info"><span class="analog-digital">${n.getHours()%12||12}:${String(o).padStart(2,"0")} ${J}</span><span class="analog-date-sm">${H(n)}</span></div></div>`,T="analog"}function f(){const n=new Date,e=n.getHours()%12||12,t=n.getMinutes(),o=n.getSeconds(),r="clock-widget"+(R!=="default"?" "+R:"");switch(y.className!==r&&(y.className=r),R){case"lcd":v(n);break;case"lcd-blue":v(n);break;case"lcd-amber":v(n);break;case"lcd-retro":v(n);break;case"lcd-taxi":v(n);break;case"flip":N(n);break;case"binary":D(n);break;case"analog":B(n,!1);break;case"roman":B(n,!0);break;default:j(n)}t===0&&o===0&&e!==P&&(P=e,k(e)),t!==0&&(P=-1)}function I(){clearTimeout($);const n=document.hidden?6e4:1e3,e=n-Date.now()%n+25;$=setTimeout(()=>{f(),I()},e)}document.addEventListener("visibilitychange",()=>{p="",L(),f(),I()}),f(),I();const b=[{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">';b.forEach(n=>{z+=`<label class="clock-style-option">
|
|
<input type="radio" name="clock-style-radio" value="${n.id}">
|
|
<span class="clock-style-card"><span class="clock-style-icon">${n.icon}</span><span class="clock-style-label">${n.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 i=document.getElementById("clock-settings-modal"),c=document.getElementById("clock-chimes-toggle"),l=document.getElementById("clock-chime-volume"),w=document.getElementById("clock-volume-section");function m(){const n=safeGet("clock-style")||"default",e=i.querySelector(`input[value="${n}"]`);e&&(e.checked=!0),c.checked=safeGet("clock-chimes")==="true",l.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",()=>{m(),i.classList.add("show")}),document.getElementById("clock-chime-test")?.addEventListener("click",()=>{const n=parseInt(l.value,10)/100,e=new Audio("/assets/sounds/church-bell.mp3");e.volume=n,e.play().catch(()=>{})}),document.getElementById("clock-settings-save")?.addEventListener("click",()=>{const n=i.querySelector('input[name="clock-style-radio"]:checked'),e=n?n.value:"default";safeSet("clock-style",e),safeSet("clock-chimes",String(c.checked)),safeSet("clock-chime-volume",l.value),R=e,p="",L(),f(),I(),i.classList.remove("show"),showNotification("Clock settings saved","success",2e3)}),document.getElementById("clock-settings-cancel")?.addEventListener("click",()=>{i.classList.remove("show")}),wireModal(i),i?.querySelectorAll('input[name="clock-style-radio"]').forEach(n=>{n.addEventListener("change",()=>{R=n.value,p="",L(),f()})})})(),(function(){async function y(){try{const A=await(await fetch("/api/v1/health-checks/status")).json();if(!A.success||!A.status)return;for(const[p,T]of Object.entries(A.status)){const x=document.getElementById("uptime-"+p),$=document.getElementById("uptime-bar-"+p);if(!x)continue;const k=T.uptime?.["24h"];if(k!=null){const H=k.toFixed(1);x.textContent=`${H}% uptime`,x.className="uptime-chip",k>=99.9?x.classList.add("excellent"):k>=99?x.classList.add("good"):k>=95?x.classList.add("degraded"):x.classList.add("poor"),$&&($.style.width=H+"%")}}}catch{console.warn("[Card Badges] Health check API unavailable")}}let C;try{C=new Set(JSON.parse(safeSessionGet("dismissed-updates")||"[]"))}catch{C=new Set}let O=[];async function E(P){try{const p=await(await fetch("/api/v1/updates/available")).json();if(!p.success)return;document.querySelectorAll(".update-available-badge").forEach(x=>x.classList.remove("visible"));const T=p.updates||[];if(O=T,P&&T.length>0){const x=window._lastKnownUpdateCount||0;x>0&&T.length>x&&showNotification(`${T.length} container update(s) available \u2014 click Update Management to review.`,"info"),window._lastKnownUpdateCount=T.length}if(!T.length)return;for(const x of T){const $=window.APPS||[];for(const k of $)if(k.containerId===x.containerId||k.id===x.containerName||k.name===x.containerName){if(C.has(k.id))break;const H=document.getElementById("update-badge-"+k.id),L=document.getElementById("update-btn-"+k.id);H&&(H.classList.add("visible"),H.title="Update available \u2014 click to open Update Management.",H.style.cursor="pointer",H.onclick=u=>{u.stopPropagation(),window.openUpdateModal&&window.openUpdateModal(k.id)}),L&&(L.style.background="#f97316",L.style.borderColor="#f97316",L.style.boxShadow="0 0 6px #f9731688",L.title="Update available \u2014 click to open Update Management.");break}}}catch{console.warn("[Card Badges] Updates API unavailable")}}function M(){setTimeout(()=>{y(),E()},5e3),setInterval(()=>{y(),E(!0)},6e4)}const R=window.refreshAll;R&&(window.refreshAll=async function(){try{await R(),setTimeout(y,1e3)}catch(P){console.warn("[Card Badges] Error in refreshAll hook:",P.message)}}),M()})(),(function(){var y=null,C=null,O={},E={dark:"Dark",light:"Light",blue:"Blue",black:"Black",nord:"Nord",dracula:"Dracula","solarized-dark":"Solarized Dark","solarized-light":"Solarized Light",taxi:"Taxi",ocean:"Ocean"},M=[["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 P=document.getElementById("theme-label");function A(o){if(E[o])return E[o];var r=safeGetJSON(window.USER_THEMES_KEY,{});return r[o]&&r[o].name||o}function p(){P&&(P.textContent=A(window.getActiveTheme()))}R.addEventListener("click",function(){var o=window.THEMES.slice(),r=window.getActiveTheme(),a=o.indexOf(r),s=o[(a+1)%o.length];window.applyTheme(s),p()}),p();function T(){var o={base:"Base Colors",accent:"Accent",status:"Status",advanced:"Advanced (auto-derived)"},r={};M.forEach(function(s){r[s[2]]||(r[s[2]]=[]),r[s[2]].push(s)});var a="";return Object.keys(o).forEach(function(s){s==="advanced"?(a+='<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>',a+='<div id="theme-builder-advanced" class="theme-builder-section" style="display:none;">'):a+='<div class="theme-builder-section">',a+='<div class="theme-builder-section-title">'+o[s]+"</div>",(r[s]||[]).forEach(function(d){a+='<div class="theme-builder-row"><span class="theme-builder-label">'+d[1]+'</span><input type="color" class="theme-builder-color" data-prop="'+d[0]+'"'+(s==="advanced"?' data-advanced="1"':"")+' value="#000000" /><span class="theme-builder-hex" data-hex="'+d[0]+'">#000000</span></div>'}),a+="</div>"}),a}function x(){return window.THEMES.map(function(o){return'<option value="'+o+'">'+A(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>'+T()+'<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 k=document.getElementById("theme-builder-modal"),H=document.getElementById("theme-builder-start"),L=document.getElementById("theme-builder-name"),u=document.getElementById("theme-builder-edit-select"),j=document.getElementById("theme-builder-existing"),v=document.getElementById("theme-builder-lightbg"),N=k.querySelectorAll(".theme-builder-color"),g=document.getElementById("theme-builder-advanced"),D=document.getElementById("theme-builder-advanced-toggle"),B=document.getElementById("theme-builder-export"),f=!1;D.addEventListener("click",function(){f=!f,g.style.display=f?"":"none",D.innerHTML=f?"Hide advanced colors ▲":"Show advanced colors ▼"});function I(){var o={};return N.forEach(function(r){o[r.dataset.prop]=r.value}),o["card-bg"]=o["card-base"],o}function b(){var o={};return N.forEach(function(r){r.dataset.advanced||(o[r.dataset.prop]=r.value)}),o["card-bg"]=o["card-base"],v.checked&&(o.lightBg=!0),o}function z(){var o=b(),r=window.deriveExtendedColors?window.deriveExtendedColors(o):{};N.forEach(function(a){if(a.dataset.advanced&&!O[a.dataset.prop]){var s=r[a.dataset.prop]||"#333333";a.value=s;var d=k.querySelector('[data-hex="'+a.dataset.prop+'"]');d&&(d.textContent=s.toUpperCase())}})}function i(o){var r=window.THEME_COLORS[o];r&&(O={},N.forEach(function(a){var s=r[a.dataset.prop]||"#000000";(s.startsWith("rgba")||s.startsWith("color-mix"))&&(s="#333333"),a.value=s;var d=k.querySelector('[data-hex="'+a.dataset.prop+'"]');d&&(d.textContent=s.toUpperCase())}),v.checked=!!r.lightBg,l())}function c(o){var r=safeGetJSON(window.USER_THEMES_KEY,{}),a=r[o];a&&(O={},N.forEach(function(s){var d=a[s.dataset.prop]||"#000000";s.value=d;var S=k.querySelector('[data-hex="'+s.dataset.prop+'"]');S&&(S.textContent=d.toUpperCase()),s.dataset.advanced&&a[s.dataset.prop]&&(O[s.dataset.prop]=!0)}),L.value=a.name||"",v.checked=!!a.lightBg,z(),l())}function l(){var o=I(),r=document.getElementById("theme-builder-preview"),a=document.getElementById("theme-preview-card"),s=a.querySelector(".preview-title"),d=a.querySelector(".preview-muted"),S=document.getElementById("preview-badge-ok"),h=document.getElementById("preview-badge-bad"),U=document.getElementById("preview-dot-ok"),_=document.getElementById("preview-dot-bad"),F=document.getElementById("preview-accent-btn"),W=a.querySelector(".preview-dots");r.style.background=o.bg,a.style.background=o["card-base"],a.style.borderColor=o.border,s.style.color=o.fg,d.style.color=o.muted,S.style.background=o["ok-bg"],S.style.color=o["ok-fg"],h.style.background=o["bad-bg"],h.style.color=o["bad-fg"],U.style.background=o["dot-ok"],_.style.background=o["dot-bad"],W.style.color=o.fg,F.style.background=o.accent,F.style.color=o.bg}function w(o){var r=window.deriveExtendedColors?window.deriveExtendedColors(o):{};window.THEME_PROPS.forEach(function(a){var s=o[a]||r[a];s&&document.documentElement.style.setProperty("--"+a,s)})}N.forEach(function(o){o.addEventListener("input",function(){var r=k.querySelector('[data-hex="'+o.dataset.prop+'"]');r&&(r.textContent=o.value.toUpperCase()),o.dataset.advanced?O[o.dataset.prop]=!0:z(),l(),w(I())})}),v.addEventListener("change",function(){z(),l(),w(I())}),H.addEventListener("change",function(){O={},i(H.value),w(I())});function m(){var o=safeGetJSON(window.USER_THEMES_KEY,{}),r=Object.keys(o);u.innerHTML='<option value="">\u2014 New Theme \u2014</option>',r.forEach(function(a){var s=document.createElement("option");s.value=a,s.textContent=o[a].name||a,u.appendChild(s)}),j.style.display=r.length?"":"none"}function n(){H.innerHTML=x()}u.addEventListener("change",function(){var o=this.value;o?(C=o,c(o),w(I())):(C=null,O={},L.value="",H.value=window.getActiveTheme(),i(H.value)),B.style.display=C?"":"none"});function e(){y=window.getActiveTheme(),C=null,O={},f=!1,g.style.display="none",D.innerHTML="Show advanced colors ▼",m(),n();var o=safeGetJSON(window.USER_THEMES_KEY,{});o[y]?(u.value=y,C=y,c(y)):(u.value="",L.value="",H.value=y,i(y)),B.style.display=C?"":"none",k.classList.add("show")}var t=document.getElementById("theme-customize-btn");t&&t.addEventListener("click",function(){e()}),document.getElementById("theme-builder-save").addEventListener("click",function(){var o=I(),r=L.value.trim();if(!r){showNotification("Please enter a theme name","warning",3e3),L.focus();return}var a=safeGetJSON(window.USER_THEMES_KEY,{}),s,d=null;if(C){s=C;var S=window.slugifyThemeName(r,C);if(S!==C){d=C,delete a[C];var h=window.THEMES.indexOf(C);h!==-1&&window.THEMES.splice(h,1),delete window.THEME_COLORS[C],s=S}}else s=window.slugifyThemeName(r);var U={name:r};v.checked&&(U.lightBg=!0),window.THEME_PROPS.forEach(function(F){o[F]&&(U[F]=o[F])}),a[s]=U,safeSet(window.USER_THEMES_KEY,JSON.stringify(a)),window.clearCustomProperties(),window.injectUserThemeStyles(),window.applyTheme(s),k.classList.remove("show"),p();var _={};window.THEME_PROPS.forEach(function(F){o[F]&&(_[F]=o[F])}),d&&secureFetch("/api/v1/themes/"+d,{method:"DELETE"}).catch(function(){}),secureFetch("/api/v1/themes/"+s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:r,colors:_,lightBg:v.checked})}).then(function(){showNotification(r+" theme saved","success",3e3)}).catch(function(){showNotification(r+" theme saved locally (server sync failed)","warning",3e3)})}),document.getElementById("theme-builder-cancel").addEventListener("click",function(){k.classList.remove("show"),window.clearCustomProperties(),y&&window.applyTheme(y)}),document.getElementById("theme-builder-delete").addEventListener("click",function(){if(C){var o=safeGetJSON(window.USER_THEMES_KEY,{}),r=o[C]?o[C].name:C;if(confirm('Delete "'+r+'" theme?')){var a=C;delete o[a],safeSet(window.USER_THEMES_KEY,JSON.stringify(o));var s=window.THEMES.indexOf(a);s!==-1&&window.THEMES.splice(s,1),delete window.THEME_COLORS[a],window.clearCustomProperties(),window.injectUserThemeStyles();var d=y&&y!==a?y:"dark";window.applyTheme(d),C=null,k.classList.remove("show"),p(),secureFetch("/api/v1/themes/"+a,{method:"DELETE"}).then(function(){showNotification(r+" theme deleted","success",3e3)}).catch(function(){showNotification(r+" theme deleted locally (server sync failed)","warning",3e3)})}}}),document.getElementById("theme-builder-export").addEventListener("click",function(){if(!C){showNotification("Save the theme first, then export","warning",3e3);return}var o=safeGetJSON(window.USER_THEMES_KEY,{}),r=o[C];if(r){var a={_dashcaddy_theme:!0,version:"1.0",exportDate:new Date().toISOString(),slug:C,name:r.name,lightBg:r.lightBg||!1,colors:{}};window.THEME_PROPS.forEach(function(h){r[h]&&(a.colors[h]=r[h])});var s=new Blob([JSON.stringify(a,null,2)],{type:"application/json"}),d=URL.createObjectURL(s),S=document.createElement("a");S.href=d,S.download=C+"-theme.json",document.body.appendChild(S),S.click(),document.body.removeChild(S),URL.revokeObjectURL(d),showNotification("Theme exported as "+C+"-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(r){var a=r.target.files[0];if(a){var s=new FileReader;s.onload=function(d){try{var S=JSON.parse(d.target.result),h,U,_;if(S._dashcaddy_theme&&S.colors)h=S.name||"Imported",U=S.colors,_=S.lightBg||!1;else if(S.name&&(S.bg||S["card-base"]))h=S.name,U={},window.THEME_PROPS.forEach(function(F){S[F]&&(U[F]=S[F])}),_=S.lightBg||!1;else throw new Error("Not a valid DashCaddy theme file");L.value=h,v.checked=!!_,C=null,u.value="",O={},N.forEach(function(F){var W=U[F.dataset.prop]||"#000000";F.value=W;var J=k.querySelector('[data-hex="'+F.dataset.prop+'"]');J&&(J.textContent=W.toUpperCase()),F.dataset.advanced&&U[F.dataset.prop]&&(O[F.dataset.prop]=!0)}),z(),l(),w(I()),B.style.display="none",showNotification('"'+h+'" loaded into builder. Click Save to keep it.',"success",5e3)}catch(F){showNotification("Import failed: "+F.message,"error",5e3)}},s.readAsText(a)}},o.click()}),wireModal(k),k.addEventListener("click",function(o){o.target===k&&(window.clearCustomProperties(),y&&window.applyTheme(y))})})(),(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 y=document.getElementById("license-modal"),C=document.getElementById("license-code-input"),O=document.getElementById("license-activate"),E=document.getElementById("license-deactivate"),M=document.getElementById("license-error"),R=document.getElementById("license-success"),P=document.getElementById("license-badge-icon"),A=document.getElementById("license-badge-text"),p=document.getElementById("license-badge"),T=document.getElementById("license-details"),x=document.getElementById("license-feature-list"),$=document.getElementById("license-activate-section");let k=null;function H(){M.style.display="none",R.style.display="none"}function L(I){H(),M.textContent=I,M.style.display="block"}function u(I){H(),R.textContent=I,R.style.display="block"}function j(I){if(k=I,I.active){p.style.background="rgba(46,204,113,0.15)",p.style.color="var(--ok-fg)",P.textContent="\u2605",A.textContent="Premium Active";const i=I.lifetime?"<div>License: <strong>LIFETIME</strong></div>":`<div>Expires: <strong>${new Date(I.expiresAt).toLocaleDateString()}</strong> (${I.daysRemaining} days remaining)</div>`;T.innerHTML=`
|
|
<div>Code: <code style="font-family: monospace;">${I.code||"***"}</code></div>
|
|
${i}
|
|
`,$.style.display="none",O.style.display="none",E.style.display=""}else p.style.background="rgba(149,165,166,0.15)",p.style.color="var(--muted)",P.textContent="\u2606",A.textContent=I.expired?"License Expired":"Free Tier",T.innerHTML=I.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="",O.style.display="",E.style.display="none";const b=I.premiumFeatures||{},z=new Set(I.features||[]);x.innerHTML=Object.entries(b).map(([i,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(i)?"\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 v(){try{const b=await(await fetch("/api/v1/license/status")).json();b.success&&(j(b.license),D(b.license))}catch(I){console.warn("Failed to load license status:",I.message)}}async function N(){const I=C.value.trim();if(!I){L("Please enter a license code.");return}H(),O.disabled=!0,O.textContent="Activating...";try{const z=await(await secureFetch("/api/v1/license/activate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:I})})).json();z.success?(u(z.message),C.value="",j(z.license),showNotification("License activated! Premium features unlocked.","success",5e3),D(z.license)):L(z.error||"Activation failed")}catch(b){L("Network error: "+b.message)}finally{O.disabled=!1,O.textContent="Activate"}}async function g(){if(confirm("Deactivate your license? You can reuse the code on another machine.")){E.disabled=!0,E.textContent="Deactivating...";try{const b=await(await secureFetch("/api/v1/license/deactivate",{method:"POST"})).json();b.success?(u(b.message),await v(),showNotification("License deactivated.","info",3e3),D({active:!1})):L(b.error||"Deactivation failed")}catch(I){L("Network error: "+I.message)}finally{E.disabled=!1,E.textContent="Deactivate"}}}function D(I){const b=document.getElementById("license-status-topbar"),z=document.getElementById("license-topbar-icon"),i=document.getElementById("license-topbar-text"),c=document.getElementById("license-topbar-time");if(b)if(b.className="license-status-topbar "+(I.active?"premium":"free"),I.active)if(z.textContent="\u2605",i.textContent="PREMIUM",I.lifetime)c.textContent="\xB7 LIFETIME";else{const l=I.daysRemaining;c.textContent=l!=null?"\xB7 "+l+"d remaining":""}else z.textContent="\u2606",i.textContent=I.expired?"EXPIRED":"FREE TIER",c.textContent=""}function B(){H(),v(),y.classList.add("show")}C.addEventListener("input",function(){let I=this.value.toUpperCase().replace(/[^A-Z0-9-]/g,"");if(I.length>this._prevLength&&(I=I.replace(/-/g,""),I.length>2&&!I.startsWith("DC")&&(I="DC"+I),I.startsWith("DC")&&I.length>2)){const b=["DC"],z=I.substring(2);for(let i=0;i<z.length;i+=5)b.push(z.substring(i,i+5));I=b.join("-")}this._prevLength=I.length,this.value=I}),O.addEventListener("click",N),E.addEventListener("click",g),C.addEventListener("keydown",I=>{I.key==="Enter"&&N()}),wireModal(y,document.getElementById("license-cancel"));const f=document.getElementById("license-status-topbar");f&&f.addEventListener("click",()=>window.openLicenseModal&&window.openLicenseModal()),window.openLicenseModal=B,window.checkPremiumFeature=async function(I){try{return(await(await fetch(`/api/v1/license/feature/${I}`)).json()).available}catch{return!1}},v().then(I=>{k&&D(k)})})(),(function(){"use strict";if(window.__dc_058_share_modal_loaded)return;window.__dc_058_share_modal_loaded=!0;const y=[{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;">
|
|
${y.map(n=>`<option value="${n.ms}">${n.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 C=document.getElementById("share-modal"),O=document.getElementById("share-modal-service-name"),E=document.getElementById("share-issued"),M=document.getElementById("share-issued-url"),R=document.getElementById("share-issued-copy"),P=document.getElementById("share-issued-meta"),A=document.getElementById("share-error"),p=document.getElementById("share-success"),T=document.getElementById("share-outstanding-list"),x=document.getElementById("share-cancel"),$=document.getElementById("share-public-create"),k=document.getElementById("share-ts-create"),H=document.getElementById("share-ts-email"),L=document.getElementById("share-public-ttl");let u=null,j="public";function v(){A.style.display="none",p.style.display="none",E.style.display="none"}function N(n){p.style.display="none",E.style.display="none",A.textContent=n,A.style.display="block"}function g(n){A.style.display="none",p.textContent=n,p.style.display="block"}function D(){return window.location.origin}function B(n){return n.startsWith("http")?n:D()+n}function f(n){if(!n)return"";const e=new Date(n);return Number.isNaN(e.getTime())?"":e.toLocaleString()}function I(n){if(n<=0)return"expired";const e=Math.floor(n/36e5);if(e>=24)return`${Math.floor(e/24)}d ${e%24}h left`;const t=Math.floor(n%36e5/6e4);return`${e}h ${t}m left`}function b(n){j=n,v(),C.querySelectorAll(".share-tab").forEach(e=>{const t=e.dataset.tab===n;e.classList.toggle("active",t),e.style.borderBottomColor=t?"var(--accent)":"transparent",e.style.color=t?"var(--fg)":"var(--muted)",e.style.fontWeight=t?"600":"400"}),C.querySelectorAll(".share-tab-panel").forEach(e=>{e.style.display=e.dataset.panel===n?"":"none"})}async function z(){T.innerHTML='<span style="color: var(--muted);">Loading\u2026</span>';try{const n=await fetch("/api/v1/share",{credentials:"same-origin"});if(!n.ok){T.innerHTML='<span style="color: var(--muted);">No shares listed.</span>';return}const e=await n.json(),o=(e&&e.data||[]).filter(r=>r.serviceId===u.id);if(o.length===0){T.innerHTML='<span style="color: var(--muted);">No outstanding shares for this service.</span>';return}T.innerHTML=o.map(r=>{const a=r.expiresAt?I(new Date(r.expiresAt).getTime()-Date.now()):"";return`
|
|
<div class="share-row" data-share-id="${escapeHtml(r.id)}"
|
|
style="display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px dashed var(--border);">
|
|
<span style="flex: 1;">
|
|
<strong>${r.kind==="tailscale"?"Tailscale":"Public"}</strong>
|
|
<span style="color: var(--muted);"> \xB7 expires ${escapeHtml(f(r.expiresAt))} (${a})</span>
|
|
</span>
|
|
<button class="share-revoke" data-share-id="${escapeHtml(r.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(""),T.querySelectorAll(".share-revoke").forEach(r=>{r.addEventListener("click",()=>i(r.dataset.shareId))})}catch{T.innerHTML='<span style="color: var(--muted);">Could not load outstanding shares.</span>'}}async function i(n){try{const e=await fetch(`/api/v1/share/${encodeURIComponent(n)}`,{method:"DELETE",credentials:"same-origin"});if(!e.ok){const t=await e.json().catch(()=>({}));N(t&&t.error||`Revoke failed (HTTP ${e.status}).`);return}g("Share revoked."),z()}catch{N("Network error while revoking.")}}async function c(){if(!u)return;v(),$.disabled=!0;const n=$.textContent;$.textContent="Creating\u2026";try{const e=parseInt(L.value,10),t=await fetch("/api/v1/share",{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify({serviceId:u.id,ttlMs:e})}),o=await t.json().catch(()=>({}));if(!t.ok||!o.success){w(t.status,o);return}const r=o.data.urlPath;M.value=B(r),P.textContent=`Public link \xB7 expires ${f(o.data.expiresAt)}`,E.style.display="block",g("Share link created."),z()}catch{N("Network error while creating share.")}finally{$.disabled=!1,$.textContent=n}}async function l(){if(!u)return;const n=(H.value||"").trim();if(!n||!n.includes("@")){N("A valid recipient email is required.");return}v(),k.disabled=!0;const e=k.textContent;k.textContent="Creating\u2026";try{const t=await fetch("/api/v1/share/tailscale",{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify({serviceId:u.id,email:n})}),o=await t.json().catch(()=>({}));if(!t.ok||!o.success){w(t.status,o);return}const r=o.data&&o.data.urlPath;r?(M.value=B(r),P.textContent=`Tailscale invite \xB7 emailed to ${n} (or use this URL manually if delivery failed).`):(M.value="",P.textContent=`Tailscale invite sent to ${n}.`),E.style.display="block",g("Tailscale invite created."),H.value="",z()}catch{N("Network error while creating Tailscale invite.")}finally{k.disabled=!1,k.textContent=e}}function w(n,e){const t=e&&e.error||"";if(n===402){N("Share is a Pro feature. Activate a license to unlock.");return}if(n===400&&/tailscale/i.test(t)){N("Tailscale is not configured on this host. Set up Tailscale in the dashboard first.");return}if(n===403){N("You do not have permission to share services.");return}if(n===404){N("Service not found. It may have been deleted.");return}N(t||`Request failed (HTTP ${n}).`)}function m(n){!n||!n.id||(u={id:n.id,name:n.name||n.id},O.textContent=u.name,v(),b("public"),H.value="",L.value=String(y[1].ms),C.classList.add("show"),z())}C.querySelectorAll(".share-tab").forEach(n=>{n.addEventListener("click",()=>b(n.dataset.tab))}),$.addEventListener("click",c),k.addEventListener("click",l),x.addEventListener("click",()=>C.classList.remove("show")),wireModal(C,x),R.addEventListener("click",async()=>{const n=M.value;if(n)try{navigator.clipboard&&navigator.clipboard.writeText?await navigator.clipboard.writeText(n):(M.select(),document.execCommand("copy"));const e=R.textContent;R.textContent="Copied!",setTimeout(()=>{R.textContent=e},1200)}catch{N("Could not copy to clipboard. Select the URL manually.")}}),window.openShareModal=m})(),(function(){"use strict";const y="dashcaddy-language",O=["en","es","fr","de","ar"],E={en:"English",es:"Espa\xF1ol",fr:"Fran\xE7ais",de:"Deutsch",ar:"\u0627\u0644\u0639\u0631\u0628\u064A\u0629"};let M=localStorage.getItem(y)||"en",R={},P=!1;async function A(u){if(u==="en"){R={},P=!0;return}try{const j=await fetch(`/api/v1/i18n/translations/${u}`);j.ok&&(R=(await j.json()).translations||{},P=!0)}catch(j){console.warn("[i18n] Failed to load translations for",u,j)}}function p(u){return M==="en"?u:R[u]||u}function T(u){if(!O.includes(u))return;M=u,localStorage.setItem(y,u);const j=u==="ar";document.documentElement.dir=j?"rtl":"ltr",document.documentElement.lang=u,A(u).then(()=>{$()})}function x(){return M}function $(){document.querySelectorAll("[data-i18n]").forEach(u=>{const j=u.getAttribute("data-i18n"),v=p(j);v&&v!==j&&(u.textContent=v)}),document.querySelectorAll("[data-i18n-placeholder]").forEach(u=>{const j=u.getAttribute("data-i18n-placeholder"),v=p(j);v&&v!==j&&(u.placeholder=v)}),document.querySelectorAll("[data-i18n-title]").forEach(u=>{const j=u.getAttribute("data-i18n-title"),v=p(j);v&&v!==j&&(u.title=v)})}function k(){const u=document.querySelector(".header-actions")||document.querySelector("#auth-settings-btn")?.parentElement||document.querySelector(".top-bar-actions");if(!u){const j=document.getElementById("auth-settings-btn");return j&&j.parentElement?H(j.parentElement):null}return H(u)}function H(u){if(document.getElementById("dc-lang-selector"))return;const j=document.createElement("div");j.id="dc-lang-selector",j.style.cssText="display: inline-flex; align-items: center; gap: 4px; margin: 0 8px; position: relative;";const v=document.createElement("button");v.id="dc-lang-btn",v.className="lang-selector-btn",v.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;",v.innerHTML=`\u{1F310} <span class="lang-current">${M.toUpperCase()}</span>`,v.title="Language / Idioma / Langue / Sprache / \u0627\u0644\u0644\u063A\u0629";const N=document.createElement("div");return N.id="dc-lang-dropdown",N.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: 140px; overflow: hidden;",O.forEach(g=>{const D=document.createElement("div");D.className="lang-option",D.style.cssText="padding: 8px 14px; cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 0.85rem; color: var(--text-primary, #e0e0e0);",D.onmouseenter=()=>D.style.background="var(--card-hover, rgba(255,255,255,0.05))",D.onmouseleave=()=>D.style.background="transparent";const B=document.createElement("span");B.textContent=g===M?"\u2713":"",B.style.cssText="width: 16px; color: var(--ok-fg, #4ade80);";const f=document.createElement("span");f.textContent=E[g],D.appendChild(B),D.appendChild(f),D.onclick=()=>{T(g),N.style.display="none",v.querySelector(".lang-current").textContent=g.toUpperCase(),N.querySelectorAll(".lang-option").forEach((I,b)=>{I.querySelector("span").textContent=O[b]===g?"\u2713":""}),window.showNotification&&window.showNotification(`Language: ${E[g]}`,"info")},N.appendChild(D)}),v.onclick=g=>{g.stopPropagation(),N.style.display=N.style.display==="none"?"block":"none"},document.addEventListener("click",g=>{j.contains(g.target)||(N.style.display="none")}),j.appendChild(v),j.appendChild(N),u.insertBefore(j,u.firstChild),j}function L(){M==="ar"&&(document.documentElement.dir="rtl",document.documentElement.lang="ar"),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{k(),M!=="en"&&A(M).then($)}):(k(),M!=="en"&&A(M).then($))}window.DCI18n={t:p,setLanguage:T,getLanguage:x,applyTranslations:$,loadTranslations:A},L()})();
|
|
//# 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+XG4gICAgYDtcblxuICAgIC8vIERpc2stc2FmZXR5IHJlbWluZGVyICh1bml2ZXJzYWwgYWNyb3NzIGFsbCBjb25maWcgdHlwZXMpXG4gICAgaHRtbCArPSBgXG4gICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogMTJweDsgcGFkZGluZzogMTJweCAxNHB4OyBib3JkZXItcmFkaXVzOiA4cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLXdhcm4tZmcsICNmMzljMTIpOyBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0td2Fybi1mZywgI2YzOWMxMikgOCUsIHRyYW5zcGFyZW50KTtcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyBhbGlnbi1pdGVtczogZmxleC1zdGFydDtcIj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMS4xcmVtO1wiPlx1RDgzRFx1RENCRTwvc3Bhbj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtOyBsaW5lLWhlaWdodDogMS40NTtcIj5cbiAgICAgICAgICAgIDxzdHJvbmcgc3R5bGU9XCJjb2xvcjogdmFyKC0td2Fybi1mZywgI2YzOWMxMik7XCI+RGlzay1zcGFjZSB0aXA6PC9zdHJvbmc+XG4gICAgICAgICAgICBIZWFsdGgtY2hlY2sgbW9uaXRvcmluZyByZWNvcmRzIHVwdGltZSwgcmVzcG9uc2UtdGltZSwgYW5kIGluY2lkZW50IGRhdGEgY29udGludW91c2x5LlxuICAgICAgICAgICAgQnkgZGVmYXVsdCBEYXNoQ2FkZHkga2VlcHMgPHN0cm9uZz4zMCBkYXlzPC9zdHJvbmc+IG9mIGhpc3RvcnkgYW5kIHdhcm5zIGF0IDxzdHJvbmc+ODAlIGRpc2sgdXNhZ2U8L3N0cm9uZz4uXG4gICAgICAgICAgICBZb3UgY2FuIHR1bmUgdGhlIHJldGVudGlvbiBwZXJpb2QsIHBvbGxpbmcgaW50ZXJ2YWwsIGFuZCBkaXNrIHRocmVzaG9sZCBsYXRlciB1bmRlclxuICAgICAgICAgICAgPHN0cm9uZz5IZWFsdGggXHUyMTkyIENvbmZpZ3VyZSBcdTIxOTIgR2xvYmFsIFNldHRpbmdzPC9zdHJvbmc+LlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIGA7XG5cbiAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgIHN1bW1hcnlDb250ZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgc2hvd1N0ZXAoJ3NldHVwLXN0ZXAtc3VtbWFyeScpO1xuICB9XG5cbiAgLy8gU2F2ZSBjb25maWcgdG8gc2VydmVyXG4gIGFzeW5jIGZ1bmN0aW9uIHNhdmVDb25maWdUb1NlcnZlcihjb25maWcpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9jb25maWcnLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoY29uZmlnKVxuICAgICAgfSk7XG5cbiAgICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgICBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3JIYW5kbGVyLmxvZ0Vycm9yKCdbU2V0dXBXaXphcmRdIFNhdmUgQ29uZmlnJywgbmV3IEVycm9yKGBTZXJ2ZXIgcmV0dXJuZWQgJHtyZXNwb25zZS5zdGF0dXN9YCksIHsgZnVuY3Rpb246ICdzYXZlQ29uZmlnVG9TZXJ2ZXInIH0pO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGVycm9ySGFuZGxlci5sb2dFcnJvcignW1NldHVwV2l6YXJkXSBTYXZlIENvbmZpZycsIGVycm9yLCB7IGZ1bmN0aW9uOiAnc2F2ZUNvbmZpZ1RvU2VydmVyJyB9KTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvLyBGaW5pc2ggc2V0dXAgaGFuZGxlclxuICBhc3luYyBmdW5jdGlvbiBmaW5pc2hTZXR1cCgpIHtcbiAgICBjb25zdCBjb25maWcgPSB7XG4gICAgICBzZXR1cENvbXBsZXRlOiB0cnVlLFxuICAgICAgY29uZmlndXJhdGlvblR5cGU6IGN1cnJlbnRDb25maWdUeXBlLFxuICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICB0aW1lem9uZTogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXRpbWV6b25lJyk/LnZhbHVlIHx8IEludGwuRGF0ZVRpbWVGb3JtYXQoKS5yZXNvbHZlZE9wdGlvbnMoKS50aW1lWm9uZSB8fCAnVVRDJ1xuICAgIH07XG5cbiAgICBpZiAoY3VycmVudENvbmZpZ1R5cGUgPT09ICdob21lbGFiJykge1xuICAgICAgY29uZmlnLnRsZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC10bGQnKT8udmFsdWU/LnRyaW0oKSB8fCAnLmhvbWUnO1xuICAgICAgY29uZmlnLmNhTmFtZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1jYS1uYW1lJyk/LnZhbHVlPy50cmltKCkgfHwgJyc7XG4gICAgICBjb25zdCBzZWxlY3RlZFByb3ZpZGVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLWRucy1wcm92aWRlcicpPy52YWx1ZSB8fCAndGVjaG5pdGl1bSc7XG4gICAgICBjb25maWcuZG5zID0ge1xuICAgICAgICBwcm92aWRlcjogc2VsZWN0ZWRQcm92aWRlcixcbiAgICAgICAgaXA6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1kbnMtaXAnKT8udmFsdWU/LnRyaW0oKSB8fCAnJyxcbiAgICAgICAgcG9ydDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLWRucy1wb3J0Jyk/LnZhbHVlPy50cmltKCkgfHwgREMuREVGQVVMVFMuRE5TX1BPUlQsXG4gICAgICAgIHRva2VuOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtZG5zLXRva2VuJyk/LnZhbHVlPy50cmltKCkgfHwgJydcbiAgICAgIH07XG4gICAgICBjb25maWcuZGVmYXVsdHMgPSB7XG4gICAgICAgIGRuc1R5cGU6ICdwcml2YXRlJyxcbiAgICAgICAgc3NsVHlwZTogJ2ludGVybmFsJyxcbiAgICAgICAgdGFyZ2V0SVA6ICdsb2NhbGhvc3QnXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoY3VycmVudENvbmZpZ1R5cGUgPT09ICdzaW1wbGUnKSB7XG4gICAgICBjb25maWcuZGVmYXVsdElQID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXNpbXBsZS1pcCcpPy52YWx1ZT8udHJpbSgpIHx8ICdsb2NhbGhvc3QnO1xuICAgICAgY29uZmlnLmRlZmF1bHRzID0ge1xuICAgICAgICBkbnNUeXBlOiAnbm9uZScsXG4gICAgICAgIHNzbFR5cGU6ICdub25lJyxcbiAgICAgICAgdGFyZ2V0SVA6IGNvbmZpZy5kZWZhdWx0SVBcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChjdXJyZW50Q29uZmlnVHlwZSA9PT0gJ3B1YmxpYycpIHtcbiAgICAgIGNvbmZpZy5kb21haW4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtcHVibGljLWRvbWFpbicpPy52YWx1ZT8udHJpbSgpIHx8ICcnO1xuICAgICAgY29uZmlnLmVtYWlsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXB1YmxpYy1lbWFpbCcpPy52YWx1ZT8udHJpbSgpIHx8ICcnO1xuICAgICAgY29uZmlnLnJvdXRpbmdNb2RlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cInJvdXRpbmctbW9kZVwiXTpjaGVja2VkJyk/LnZhbHVlIHx8ICdzdWJkaXJlY3RvcnknO1xuICAgICAgY29uZmlnLmRlZmF1bHRzID0ge1xuICAgICAgICBkbnNUeXBlOiBjb25maWcucm91dGluZ01vZGUgPT09ICdzdWJkaXJlY3RvcnknID8gJ25vbmUnIDogJ3B1YmxpYycsXG4gICAgICAgIHNzbFR5cGU6ICdsZXRzZW5jcnlwdCcsXG4gICAgICAgIHRhcmdldElQOiAnbG9jYWxob3N0J1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBTYXZlIHRvIHNlcnZlciAocHJpbWFyeSkgYW5kIGxvY2FsU3RvcmFnZSAoZmFsbGJhY2spXG4gICAgY29uc3Qgc2F2ZWRUb1NlcnZlciA9IGF3YWl0IHNhdmVDb25maWdUb1NlcnZlcihjb25maWcpO1xuICAgIHNhZmVTZXQoJ2Rhc2hjYWRkeS1jb25maWcnLCBKU09OLnN0cmluZ2lmeShjb25maWcpKTtcbiAgICBzYWZlU2V0KCdkYXNoY2FkZHktc2V0dXAnLCAnY29tcGxldGVkJyk7XG5cbiAgICAvLyBIaWRlIHdpemFyZFxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC13aXphcmQnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXG4gICAgLy8gU2hvdyBzdWNjZXNzIG5vdGlmaWNhdGlvblxuICAgIGNvbnN0IGNvbmZpZ05hbWUgPSBjdXJyZW50Q29uZmlnVHlwZSA9PT0gJ2hvbWVsYWInID8gJ1Byb2Zlc3Npb25hbCBIb21lIExhYicgOlxuICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDb25maWdUeXBlID09PSAnc2ltcGxlJyA/ICdTaW1wbGUgU2V0dXAnIDogJ1B1YmxpYyBTZXJ2ZXInO1xuICAgIGNvbnN0IHNhdmVMb2NhdGlvbiA9IHNhdmVkVG9TZXJ2ZXIgPyAnc2VydmVyIChzaGFyZWQgYWNyb3NzIGFsbCBkZXZpY2VzKScgOiAnbG9jYWxseSAodGhpcyBicm93c2VyIG9ubHkpJztcblxuICAgIHNob3dOb3RpZmljYXRpb24oYFNldHVwIENvbXBsZXRlISBDb25maWd1cmVkIGZvcjogJHtjb25maWdOYW1lfS4gU2V0dGluZ3Mgc2F2ZWQgdG86ICR7c2F2ZUxvY2F0aW9ufWAsICdzdWNjZXNzJywgNTAwMCk7XG5cbiAgICAvLyBSZWxvYWQgcGFnZSB0byBhcHBseSBjb25maWd1cmF0aW9uXG4gICAgc2V0VGltZW91dCgoKSA9PiBsb2NhdGlvbi5yZWxvYWQoKSwgNTAwKTtcbiAgfVxuXG4gIC8vID09PT09IEV2ZW50IEhhbmRsZXJzIHVzaW5nIGRpcmVjdCBvbmNsaWNrIGZvciByZWxpYWJpbGl0eSA9PT09PVxuXG4gIC8vIFN0ZXAgMTogQ29udGludWUgYnV0dG9uXG4gIGNvbnN0IHN0ZXAxTmV4dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1zdGVwLTEtbmV4dCcpO1xuICBpZiAoc3RlcDFOZXh0KSB7XG4gICAgc3RlcDFOZXh0Lm9uY2xpY2sgPSBmdW5jdGlvbihlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBjb25zdCBzZWxlY3RlZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9XCJjb25maWctdHlwZVwiXTpjaGVja2VkJyk7XG4gICAgICBpZiAoc2VsZWN0ZWQpIHtcbiAgICAgICAgY3VycmVudENvbmZpZ1R5cGUgPSBzZWxlY3RlZC52YWx1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChjdXJyZW50Q29uZmlnVHlwZSA9PT0gJ2hvbWVsYWInKSB7XG4gICAgICAgIHNob3dTdGVwKCdzZXR1cC1zdGVwLWhvbWVsYWInKTtcbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudENvbmZpZ1R5cGUgPT09ICdzaW1wbGUnKSB7XG4gICAgICAgIHNob3dTdGVwKCdzZXR1cC1zdGVwLXNpbXBsZScpO1xuICAgICAgfSBlbHNlIGlmIChjdXJyZW50Q29uZmlnVHlwZSA9PT0gJ3B1YmxpYycpIHtcbiAgICAgICAgc2hvd1N0ZXAoJ3NldHVwLXN0ZXAtcHVibGljJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzaG93U3RlcCgnc2V0dXAtc3RlcC1ob21lbGFiJyk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8vIFNraXAgc2V0dXAgYnV0dG9uXG4gIGNvbnN0IHNraXBCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtc2tpcCcpO1xuICBpZiAoc2tpcEJ0bikge1xuICAgIHNraXBCdG4ub25jbGljayA9IGFzeW5jIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGlmIChjb25maXJtKCdTa2lwIHNldHVwPyBZb3UgY2FuIHJ1biBpdCBsYXRlciBmcm9tIFNldHRpbmdzLicpKSB7XG4gICAgICAgIC8vIFNhdmUgc2tpcCBzdGF0dXMgdG8gc2VydmVyXG4gICAgICAgIGF3YWl0IHNhdmVDb25maWdUb1NlcnZlcih7IHNldHVwQ29tcGxldGU6IHRydWUsIHNraXBwZWQ6IHRydWUsIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpIH0pO1xuICAgICAgICBzYWZlU2V0KCdkYXNoY2FkZHktc2V0dXAnLCAnc2tpcHBlZCcpO1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtd2l6YXJkJykuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gSG9tZSBMYWI6IFRMRCBQcmV2aWV3XG4gIGNvbnN0IHRsZElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXRsZCcpO1xuICBpZiAodGxkSW5wdXQpIHtcbiAgICB0bGRJbnB1dC5vbmlucHV0ID0gZnVuY3Rpb24oZSkge1xuICAgICAgY29uc3QgdGxkID0gZS50YXJnZXQudmFsdWUgfHwgJy5ob21lJztcbiAgICAgIGNvbnN0IHByZXZpZXcxID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RsZC1wcmV2aWV3Jyk7XG4gICAgICBjb25zdCBwcmV2aWV3MiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0bGQtcHJldmlldy0yJyk7XG4gICAgICBpZiAocHJldmlldzEpIHByZXZpZXcxLnRleHRDb250ZW50ID0gdGxkO1xuICAgICAgaWYgKHByZXZpZXcyKSBwcmV2aWV3Mi50ZXh0Q29udGVudCA9IHRsZDtcbiAgICB9O1xuICB9XG5cbiAgLy8gSG9tZSBMYWIgbmF2aWdhdGlvblxuICBjb25zdCBob21lbGFiQmFjayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1ob21lbGFiLWJhY2snKTtcbiAgaWYgKGhvbWVsYWJCYWNrKSB7XG4gICAgaG9tZWxhYkJhY2sub25jbGljayA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHNob3dTdGVwKCdzZXR1cC1zdGVwLTEnKTtcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgaG9tZWxhYk5leHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtaG9tZWxhYi1uZXh0Jyk7XG4gIGlmIChob21lbGFiTmV4dCkge1xuICAgIGhvbWVsYWJOZXh0Lm9uY2xpY2sgPSBmdW5jdGlvbihlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBjb25zdCB0bGQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtdGxkJyk/LnZhbHVlPy50cmltKCkgfHwgJyc7XG4gICAgICBjb25zdCBjYU5hbWUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtY2EtbmFtZScpPy52YWx1ZT8udHJpbSgpIHx8ICcnO1xuICAgICAgY29uc3QgZG5zSVAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtZG5zLWlwJyk/LnZhbHVlPy50cmltKCkgfHwgJyc7XG5cbiAgICAgIGlmICghdGxkIHx8ICF0bGQuc3RhcnRzV2l0aCgnLicpKSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1BsZWFzZSBlbnRlciBhIHZhbGlkIFRMRCBzdGFydGluZyB3aXRoIGEgZG90IChlLmcuLCAuaG9tZSknLCAnd2FybmluZycpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIWNhTmFtZSkge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdQbGVhc2UgZW50ZXIgYSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgbmFtZScsICd3YXJuaW5nJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICghZG5zSVApIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignUGxlYXNlIGVudGVyIHlvdXIgRE5TIHNlcnZlciBJUCBhZGRyZXNzJywgJ3dhcm5pbmcnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2hvd1N1bW1hcnkoKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gU2ltcGxlIG5hdmlnYXRpb25cbiAgY29uc3Qgc2ltcGxlQmFjayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1zaW1wbGUtYmFjaycpO1xuICBpZiAoc2ltcGxlQmFjaykge1xuICAgIHNpbXBsZUJhY2sub25jbGljayA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHNob3dTdGVwKCdzZXR1cC1zdGVwLTEnKTtcbiAgICB9O1xuICB9XG5cbiAgY29uc3Qgc2ltcGxlTmV4dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXR1cC1zaW1wbGUtbmV4dCcpO1xuICBpZiAoc2ltcGxlTmV4dCkge1xuICAgIHNpbXBsZU5leHQub25jbGljayA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHNob3dTdW1tYXJ5KCk7XG4gICAgfTtcbiAgfVxuXG4gIC8vIFB1YmxpYyByb3V0aW5nIG1vZGUgdG9nZ2xlIFx1MjAxNCB1cGRhdGUgcmVxdWlyZW1lbnQgdGV4dFxuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFtuYW1lPVwicm91dGluZy1tb2RlXCJdJykuZm9yRWFjaChmdW5jdGlvbihyYWRpbykge1xuICAgIHJhZGlvLm9uY2hhbmdlID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgbm90ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkbnMtcmVxdWlyZW1lbnQtbm90ZScpO1xuICAgICAgaWYgKG5vdGUpIHtcbiAgICAgICAgbm90ZS50ZXh0Q29udGVudCA9IHRoaXMudmFsdWUgPT09ICdzdWJkaXJlY3RvcnknXG4gICAgICAgICAgPyAnT25seSBvbmUgRE5TIHJlY29yZCBuZWVkZWQgKGZvciB0aGUgbWFpbiBkb21haW4pJ1xuICAgICAgICAgIDogJ1lvdVxcJ2xsIG5lZWQgdG8gY29uZmlndXJlIEROUyBtYW51YWxseSBmb3IgZWFjaCBzdWJkb21haW4nO1xuICAgICAgfVxuICAgIH07XG4gIH0pO1xuXG4gIC8vIFB1YmxpYyBuYXZpZ2F0aW9uXG4gIGNvbnN0IHB1YmxpY0JhY2sgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtcHVibGljLWJhY2snKTtcbiAgaWYgKHB1YmxpY0JhY2spIHtcbiAgICBwdWJsaWNCYWNrLm9uY2xpY2sgPSBmdW5jdGlvbihlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBzaG93U3RlcCgnc2V0dXAtc3RlcC0xJyk7XG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IHB1YmxpY05leHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtcHVibGljLW5leHQnKTtcbiAgaWYgKHB1YmxpY05leHQpIHtcbiAgICBwdWJsaWNOZXh0Lm9uY2xpY2sgPSBmdW5jdGlvbihlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBjb25zdCBkb21haW4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtcHVibGljLWRvbWFpbicpPy52YWx1ZT8udHJpbSgpIHx8ICcnO1xuICAgICAgY29uc3QgZW1haWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtcHVibGljLWVtYWlsJyk/LnZhbHVlPy50cmltKCkgfHwgJyc7XG5cbiAgICAgIGlmICghZG9tYWluKSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1BsZWFzZSBlbnRlciB5b3VyIGRvbWFpbiBuYW1lJywgJ3dhcm5pbmcnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCFlbWFpbCB8fCAhZW1haWwuaW5jbHVkZXMoJ0AnKSkge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdQbGVhc2UgZW50ZXIgYSB2YWxpZCBlbWFpbCBhZGRyZXNzJywgJ3dhcm5pbmcnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2hvd1N1bW1hcnkoKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gU3VtbWFyeSBuYXZpZ2F0aW9uXG4gIGNvbnN0IHN1bW1hcnlCYWNrID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NldHVwLXN1bW1hcnktYmFjaycpO1xuICBpZiAoc3VtbWFyeUJhY2spIHtcbiAgICBzdW1tYXJ5QmFjay5vbmNsaWNrID0gZnVuY3Rpb24oZSkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKGN1cnJlbnRDb25maWdUeXBlID09PSAnaG9tZWxhYicpIHtcbiAgICAgICAgc2hvd1N0ZXAoJ3NldHVwLXN0ZXAtaG9tZWxhYicpO1xuICAgICAgfSBlbHNlIGlmIChjdXJyZW50Q29uZmlnVHlwZSA9PT0gJ3NpbXBsZScpIHtcbiAgICAgICAgc2hvd1N0ZXAoJ3NldHVwLXN0ZXAtc2ltcGxlJyk7XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRDb25maWdUeXBlID09PSAncHVibGljJykge1xuICAgICAgICBzaG93U3RlcCgnc2V0dXAtc3RlcC1wdWJsaWMnKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gRmluaXNoIHNldHVwIGJ1dHRvblxuICBjb25zdCBmaW5pc2hCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2V0dXAtZmluaXNoJyk7XG4gIGlmIChmaW5pc2hCdG4pIHtcbiAgICBmaW5pc2hCdG4ub25jbGljayA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGZpbmlzaFNldHVwKCk7XG4gICAgfTtcbiAgfVxuXG4gIC8vIEV4cG9zZSBmdW5jdGlvbiB0byBnZXQgZ2xvYmFsIGNvbmZpZyAoZnJvbSBzZXJ2ZXIgb3IgbG9jYWxTdG9yYWdlKVxuICB3aW5kb3cuZ2V0R2xvYmFsQ29uZmlnID0gYXN5bmMgZnVuY3Rpb24oKSB7XG4gICAgLy8gVHJ5IHNlcnZlciBmaXJzdFxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2NvbmZpZycpO1xuICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgaWYgKGNvbmZpZyAmJiBjb25maWcuc2V0dXBDb21wbGV0ZSkge1xuICAgICAgICAgIHJldHVybiBjb25maWc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ0NvdWxkIG5vdCBmZXRjaCBjb25maWcgZnJvbSBzZXJ2ZXInKTtcbiAgICB9XG5cbiAgICAvLyBGYWxsYmFjayB0byBsb2NhbFN0b3JhZ2VcbiAgICBjb25zdCBjb25maWdTdHIgPSBzYWZlR2V0KCdkYXNoY2FkZHktY29uZmlnJyk7XG4gICAgaWYgKGNvbmZpZ1N0cikge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoY29uZmlnU3RyKTtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gZGVmYXVsdCBjb25maWcgaWYgbm90IHNldFxuICAgIHJldHVybiB7XG4gICAgICBzZXR1cENvbXBsZXRlOiBmYWxzZSxcbiAgICAgIGNvbmZpZ3VyYXRpb25UeXBlOiAnaG9tZWxhYicsXG4gICAgICB0bGQ6ICcuaG9tZScsXG4gICAgICBjYU5hbWU6ICcnLFxuICAgICAgZGVmYXVsdHM6IHtcbiAgICAgICAgZG5zVHlwZTogJ3ByaXZhdGUnLFxuICAgICAgICBzc2xUeXBlOiAnaW50ZXJuYWwnLFxuICAgICAgICB0YXJnZXRJUDogJ2xvY2FsaG9zdCdcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuXG4gIC8vIEV4cG9zZSByZXNldCBmdW5jdGlvbiBmb3Igc2V0dGluZ3NcbiAgd2luZG93LnJlc2V0U2V0dXBXaXphcmQgPSBhc3luYyBmdW5jdGlvbigpIHtcbiAgICBpZiAoY29uZmlybSgnUmVzZXQgRGFzaENhZGR5IGNvbmZpZ3VyYXRpb24/IFRoaXMgd2lsbCBzaG93IHRoZSBzZXR1cCB3aXphcmQgYWdhaW4uJykpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2NvbmZpZycsIHsgbWV0aG9kOiAnREVMRVRFJyB9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdDb3VsZCBub3QgZGVsZXRlIHNlcnZlciBjb25maWcnKTtcbiAgICAgIH1cbiAgICAgIHNhZmVSZW1vdmUoJ2Rhc2hjYWRkeS1zZXR1cCcpO1xuICAgICAgc2FmZVJlbW92ZSgnZGFzaGNhZGR5LWNvbmZpZycpO1xuICAgICAgbG9jYXRpb24ucmVsb2FkKCk7XG4gICAgfVxuICB9O1xufSkoKTtcbjtcbi8vIEFwcCBTZWxlY3RvciBTeXN0ZW1cbihmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGVycm9ySGFuZGxlciA9IG5ldyBFcnJvckhhbmRsZXIoKTtcbiAgaW5qZWN0TW9kYWwoJ2FwcC1zZWxlY3Rvci1tb2RhbCcsIGA8ZGl2IGlkPVwiYXBwLXNlbGVjdG9yLW1vZGFsXCIgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsXCI+XG4gICAgPGRpdiBjbGFzcz1cImFwcC1zZWxlY3Rvci1jb250ZW50XCI+XG4gICAgICA8aDIgc3R5bGU9XCJtYXJnaW46IDAgMCAyNHB4OyBjb2xvcjogdmFyKC0tZmcpOyB0ZXh0LWFsaWduOiBjZW50ZXI7XCI+Q2hvb3NlIGFuIEFwcDwvaDI+XG4gICAgICA8ZGl2IGlkPVwiYXBwLXNlbGVjdG9yLWdyaWRcIiBjbGFzcz1cImFwcC1zZWxlY3Rvci1ncmlkXCI+PC9kaXY+XG4gICAgICA8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBtYXJnaW4tdG9wOiAyNHB4O1wiPlxuICAgICAgICA8YnV0dG9uIGlkPVwiYXBwLXNlbGVjdG9yLWNhbmNlbFwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PmApO1xuXG4gIGluamVjdE1vZGFsKCdhcHAtZGVwbG95LW1vZGFsJywgYDxkaXYgaWQ9XCJhcHAtZGVwbG95LW1vZGFsXCIgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsXCI+XG4gICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtY29udGVudFwiIHN0eWxlPVwibWluLXdpZHRoOiA2MDBweDsgbWF4LXdpZHRoOiA3MDBweDtcIj5cbiAgICAgIDxoMyBpZD1cImFwcC1kZXBsb3ktdGl0bGVcIj5EZXBsb3kgQXBwbGljYXRpb248L2gzPlxuXG4gICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnI7IGdhcDogMTZweDsgbWFyZ2luLXRvcDogMTZweDtcIj5cbiAgICAgICAgPCEtLSBTdWJkb21haW4vRG9tYWluIC0tPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxsYWJlbCBmb3I9XCJkZXBsb3ktc3ViZG9tYWluXCIgY2xhc3M9XCJmb3JtLWxhYmVsLWFjY2VudC1zbVwiPlxuICAgICAgICAgICAgXHVEODNDXHVERjEwIFN1YmRvbWFpbiBvciBEb21haW5cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwiZGVwbG95LXN1YmRvbWFpblwiIHBsYWNlaG9sZGVyPVwidXB0aW1lXCJcbiAgICAgICAgICAgICAgICAgc3R5bGU9XCJ3aWR0aDogMTAwJTsgcGFkZGluZzogMTBweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDZweDsgZm9udC1zaXplOiAwLjk1cmVtO1wiIC8+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0taGludC1zbVwiPlxuICAgICAgICAgICAgWW91ciBhcHAgd2lsbCBiZSBhdmFpbGFibGUgYXQ6IDxzcGFuIGlkPVwiZGVwbG95LXVybC1wcmV2aWV3XCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tYWNjZW50KTsgZm9udC13ZWlnaHQ6IDUwMDtcIj51cHRpbWUuaG9tZTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGlkPVwic3VicGF0aC1jb21wYXQtd2FybmluZ1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTsgcGFkZGluZzogOHB4IDEycHg7IGJvcmRlci1yYWRpdXM6IDZweDsgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsICNmZjk4MDAgMTAlLCB2YXIoLS1jYXJkLWJnKSk7IGJvcmRlcjogMXB4IHNvbGlkIGNvbG9yLW1peChpbiBzcmdiLCAjZmY5ODAwIDMwJSwgdHJhbnNwYXJlbnQpOyBtYXJnaW4tdG9wOiA4cHg7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBETlMgQ29uZmlndXJhdGlvbiAtLT5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsLWFjY2VudFwiPlxuICAgICAgICAgICAgXHVEODNEXHVEREMyXHVGRTBGIEROUyBDb25maWd1cmF0aW9uXG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1jb2wtZ2FwXCI+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJyYWRpby1vcHRpb25cIj5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJkbnMtdHlwZVwiIHZhbHVlPVwicHJpdmF0ZVwiIGNoZWNrZWQgc3R5bGU9XCJtYXJnaW4tcmlnaHQ6IDEwcHg7XCIgLz5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnctNTAwXCI+UHJpdmF0ZSBETlMgKFRlY2huaXRpdW0pPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtaGludFwiPlVzZSB5b3VyIGxvY2FsIEROUyBzZXJ2ZXIgd2l0aCBjdXN0b20gVExEICguc2FtaSwgLmhvbWUsIGV0Yy4pPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInJhZGlvLW9wdGlvblwiPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgbmFtZT1cImRucy10eXBlXCIgdmFsdWU9XCJwdWJsaWNcIiBzdHlsZT1cIm1hcmdpbi1yaWdodDogMTBweDtcIiAvPlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdy01MDBcIj5QdWJsaWMgRE5TPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtaGludFwiPlVzZSBhIHJlYWwgZG9tYWluIChleGFtcGxlLmNvbSkgLSByZXF1aXJlcyBETlMgcHJvdmlkZXIgc2V0dXA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwicmFkaW8tb3B0aW9uXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwiZG5zLXR5cGVcIiB2YWx1ZT1cIm5vbmVcIiBzdHlsZT1cIm1hcmdpbi1yaWdodDogMTBweDtcIiAvPlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdy01MDBcIj5ObyBETlMgKElQOlBvcnQgb25seSk8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1oaW50XCI+QWNjZXNzIHZpYSBJUCBhZGRyZXNzIGFuZCBwb3J0IC0gbm8gZG9tYWluIHNldHVwPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBTU0wgQ29uZmlndXJhdGlvbiAtLT5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsLWFjY2VudFwiPlxuICAgICAgICAgICAgXHVEODNEXHVERDEyIFNTTC9UTFMgQ2VydGlmaWNhdGVcbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWNvbC1nYXBcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInJhZGlvLW9wdGlvblwiPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgbmFtZT1cInNzbC10eXBlXCIgdmFsdWU9XCJpbnRlcm5hbFwiIGNoZWNrZWQgc3R5bGU9XCJtYXJnaW4tcmlnaHQ6IDEwcHg7XCIgLz5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnctNTAwXCI+SW50ZXJuYWwgQ0E8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1oaW50XCI+VXNlIENhZGR5J3MgaW50ZXJuYWwgY2VydGlmaWNhdGUgYXV0aG9yaXR5IChzZWxmLXNpZ25lZCk8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwicmFkaW8tb3B0aW9uXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwic3NsLXR5cGVcIiB2YWx1ZT1cImxldHNlbmNyeXB0XCIgc3R5bGU9XCJtYXJnaW4tcmlnaHQ6IDEwcHg7XCIgLz5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnctNTAwXCI+TGV0J3MgRW5jcnlwdDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWhpbnRcIj5GcmVlIHB1YmxpYyBTU0wgY2VydGlmaWNhdGUgKHJlcXVpcmVzIHB1YmxpYyBkb21haW4pPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInJhZGlvLW9wdGlvblwiPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgbmFtZT1cInNzbC10eXBlXCIgdmFsdWU9XCJub25lXCIgc3R5bGU9XCJtYXJnaW4tcmlnaHQ6IDEwcHg7XCIgLz5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnctNTAwXCI+Tm8gU1NMIChIVFRQIG9ubHkpPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtaGludFwiPlx1MjZBMFx1RkUwRiBOb3QgcmVjb21tZW5kZWQgLSB0cmFmZmljIHdpbGwgYmUgdW5lbmNyeXB0ZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIE1lZGlhIExpYnJhcnkgUGF0aCAoc2hvd24gZm9yIG1lZGlhIGFwcHMpIC0tPlxuICAgICAgICA8ZGl2IGlkPVwibWVkaWEtcGF0aC1zZWN0aW9uXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwtYWNjZW50XCI+XG4gICAgICAgICAgICBcdUQ4M0RcdURDQzEgTWVkaWEgTGlicmFyeSBMb2NhdGlvblxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGdhcDogMTBweDtcIj5cbiAgICAgICAgICAgIDwhLS0gRGV0ZWN0ZWQgbW91bnRzIGZyb20gZXhpc3RpbmcgbWVkaWEgc2VydmVycyAtLT5cbiAgICAgICAgICAgIDxkaXYgaWQ9XCJkZXRlY3RlZC1tb3VudHMtY29udGFpbmVyXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tc3VjY2Vzcyk7IG1hcmdpbi1ib3R0b206IDZweDtcIj5cbiAgICAgICAgICAgICAgICBcdTI3MTMgRGV0ZWN0ZWQgZnJvbSBleGlzdGluZyBtZWRpYSBzZXJ2ZXJzOlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBpZD1cImRldGVjdGVkLW1vdW50cy1saXN0XCIgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDhweDsgZmxleC13cmFwOiB3cmFwO1wiPjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gUGF0aCBpbnB1dCB3aXRoIGJyb3dzZSBidXR0b24gLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1yb3ctZ2FwXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwiZGVwbG95LW1lZGlhLXBhdGhcIiBwbGFjZWhvbGRlcj1cIi9tZWRpYS9Nb3ZpZXMsIC9tZWRpYS9UVlNob3dzXCJcbiAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5wdXQtZmxleFwiIHN0eWxlPVwiZm9udC1zaXplOiAwLjk1cmVtO1wiIC8+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGlkPVwiYnJvd3NlLW1lZGlhLWJ0blwiIHN0eWxlPVwicGFkZGluZzogMTBweCAxNnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1hY2NlbnQpOyBjb2xvcjogd2hpdGU7IGJvcmRlcjogbm9uZTsgYm9yZGVyLXJhZGl1czogNnB4OyBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtd2VpZ2h0OiA1MDA7IHdoaXRlLXNwYWNlOiBub3dyYXA7XCI+XG4gICAgICAgICAgICAgICAgXHVEODNEXHVEQ0MyIEJyb3dzZVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGlkPVwibWVkaWEtcGF0aC1kZXNjcmlwdGlvblwiIGNsYXNzPVwidGV4dC1oaW50XCI+XG4gICAgICAgICAgICAgIFNlbGVjdCBmb2xkZXJzIGZyb20gZXhpc3Rpbmcgc2VydmVycywgYnJvd3NlLCBvciB0eXBlIHBhdGhzIG1hbnVhbGx5LiBTZXBhcmF0ZSBtdWx0aXBsZSB3aXRoIGNvbW1hcy5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIFNlbGVjdGVkIHBhdGhzIGRpc3BsYXkgLS0+XG4gICAgICAgICAgICA8ZGl2IGlkPVwic2VsZWN0ZWQtbWVkaWEtcGF0aHNcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7IGZsZXgtd3JhcDogd3JhcDsgZ2FwOiA2cHg7XCI+PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gUGxleCBDbGFpbSBUb2tlbiAoc2hvd24gb25seSBmb3IgUGxleCBkZXBsb3ltZW50cykgLS0+XG4gICAgICAgIDxkaXYgaWQ9XCJwbGV4LWNsYWltLXNlY3Rpb25cIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbC1hY2NlbnRcIj5cbiAgICAgICAgICAgIFx1RDgzRFx1REQxMSBQbGV4IENsYWltIFRva2VuXG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1yb3ctZ2FwXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cImRlcGxveS1wbGV4LWNsYWltXCIgcGxhY2Vob2xkZXI9XCJjbGFpbS14eHh4eHh4eHh4eHh4eHh4eHh4eFwiXG4gICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbnB1dC1mbGV4XCIgc3R5bGU9XCJmb250LXNpemU6IDAuOTVyZW07XCIgLz5cbiAgICAgICAgICAgIDxhIGhyZWY9XCJodHRwczovL3BsZXgudHYvY2xhaW1cIiB0YXJnZXQ9XCJfYmxhbmtcIiByZWw9XCJub29wZW5lciBub3JlZmVycmVyXCJcbiAgICAgICAgICAgICAgIHN0eWxlPVwicGFkZGluZzogMTBweCAxNnB4OyBiYWNrZ3JvdW5kOiAjZTVhMDBkOyBjb2xvcjogIzAwMDsgYm9yZGVyOiBub25lOyBib3JkZXItcmFkaXVzOiA2cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDUwMDsgd2hpdGUtc3BhY2U6IG5vd3JhcDsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyO1wiPlxuICAgICAgICAgICAgICBHZXQgVG9rZW5cbiAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiAjZTVhMDBkOyBtYXJnaW4tdG9wOiA0cHg7XCI+XG4gICAgICAgICAgICBUb2tlbiBleHBpcmVzIGluIDQgbWludXRlcyEgR2V0IGl0IHJpZ2h0IGJlZm9yZSBjbGlja2luZyBEZXBsb3kuIExlYXZlIGVtcHR5IHRvIGNvbmZpZ3VyZSBQbGV4IG1hbnVhbGx5IGxhdGVyLlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFRhaWxzY2FsZSBTZWN1cml0eSAtLT5cbiAgICAgICAgPGRpdiBpZD1cInRhaWxzY2FsZS1zZWN0aW9uXCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbC1hY2NlbnRcIj5cbiAgICAgICAgICAgIFx1RDgzRFx1REQxMCBUYWlsc2NhbGUgU2VjdXJpdHlcbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWNvbC1nYXBcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInJhZGlvLW9wdGlvblwiPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJkZXBsb3ktdGFpbHNjYWxlLW9ubHlcIiBzdHlsZT1cIm1hcmdpbi1yaWdodDogMTBweDsgd2lkdGg6IDE4cHg7IGhlaWdodDogMThweDtcIiAvPlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdy01MDBcIj5UYWlsc2NhbGUtT25seSBBY2Nlc3M8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1oaW50XCI+UmVzdHJpY3QgdGhpcyBzZXJ2aWNlIHRvIFRhaWxzY2FsZSB1c2VycyBvbmx5ICgxMDAueC54LnggSVBzKTwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICA8ZGl2IGlkPVwidGFpbHNjYWxlLXN0YXR1c1wiIHN0eWxlPVwicGFkZGluZzogOHB4IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmcpOyBib3JkZXItcmFkaXVzOiA2cHg7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj5cbiAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkNoZWNraW5nIFRhaWxzY2FsZSBzdGF0dXMuLi48L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBBZHZhbmNlZCBPcHRpb25zIChDb2xsYXBzaWJsZSkgLS0+XG4gICAgICAgIDxkZXRhaWxzPlxuICAgICAgICAgIDxzdW1tYXJ5IHN0eWxlPVwiY3Vyc29yOiBwb2ludGVyOyBjb2xvcjogdmFyKC0tYWNjZW50KTsgZm9udC13ZWlnaHQ6IDUwMDsgbWFyZ2luLWJvdHRvbTogOHB4O1wiPlx1MjY5OVx1RkUwRiBBZHZhbmNlZCBPcHRpb25zPC9zdW1tYXJ5PlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tdG9wOiAxMnB4OyBkaXNwbGF5OiBncmlkOyBnYXA6IDEycHg7XCI+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgZm9yPVwiZGVwbG95LXBvcnRcIiBzdHlsZT1cImRpc3BsYXk6IGJsb2NrOyBtYXJnaW4tYm90dG9tOiA2cHg7XCI+Q3VzdG9tIFBvcnQgKG9wdGlvbmFsKTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgaWQ9XCJkZXBsb3ktcG9ydFwiIHBsYWNlaG9sZGVyPVwiTGVhdmUgZW1wdHkgZm9yIGRlZmF1bHRcIlxuICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWlucHV0LWNhcmRcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgZm9yPVwiZGVwbG95LWlwXCIgc3R5bGU9XCJkaXNwbGF5OiBibG9jazsgbWFyZ2luLWJvdHRvbTogNnB4O1wiPlRhcmdldCBJUCBBZGRyZXNzPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJkZXBsb3ktaXBcIiB2YWx1ZT1cImxvY2FsaG9zdFwiXG4gICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0taW5wdXQtY2FyZFwiIC8+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWhpbnQtc21cIj5cbiAgICAgICAgICAgICAgICBVc2UgJ2xvY2FsaG9zdCcgZm9yIHNhbWUtaG9zdCBjb250YWluZXJzLCBvciBzcGVjaWZpYyBJUCBmb3IgcmVtb3RlIHNlcnZpY2VzXG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGlkPVwidm9sdW1lLW1vdW50cy1zZWN0aW9uXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsLWFjY2VudC1zbVwiPlx1RDgzRFx1RENDMiBWb2x1bWUgTW91bnRzPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tYm90dG9tOiA4cHg7XCI+XG4gICAgICAgICAgICAgICAgQ3VzdG9taXplIHdoZXJlIGNvbnRhaW5lciBkYXRhIGlzIHN0b3JlZCBvbiB0aGUgaG9zdC4gTWVkaWEgdm9sdW1lcyBhcmUgY29uZmlndXJlZCBhYm92ZS5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgaWQ9XCJ2b2x1bWUtbW91bnRzLWxpc3RcIiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdhcDogOHB4O1wiPjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogMTJweDtcIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbC1hY2NlbnQtc21cIj5cdTI2OTlcdUZFMEYgUmVzb3VyY2UgTGltaXRzPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tYm90dG9tOiA4cHg7XCI+XG4gICAgICAgICAgICAgICAgT3B0aW9uYWwgQ1BVIGFuZCBtZW1vcnkgY29uc3RyYWludHMuIExlYXZlIGF0IDAgZm9yIHVubGltaXRlZC5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDFmciAxZnI7IGdhcDogMTBweDtcIj5cbiAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgPGxhYmVsIGZvcj1cImRlcGxveS1jcHUtbGltaXRcIiBzdHlsZT1cImRpc3BsYXk6IGJsb2NrOyBmb250LXNpemU6IDAuNzhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDRweDtcIj5DUFUgQ29yZXM8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBpZD1cImRlcGxveS1jcHUtbGltaXRcIiB2YWx1ZT1cIjBcIiBtaW49XCIwXCIgbWF4PVwiNjRcIiBzdGVwPVwiMC4yNVwiIGNsYXNzPVwiZm9ybS1pbnB1dC1jYXJkXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTtcIiBwbGFjZWhvbGRlcj1cIjAgPSB1bmxpbWl0ZWRcIiAvPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPVwiZGVwbG95LW1lbW9yeS1saW1pdFwiIHN0eWxlPVwiZGlzcGxheTogYmxvY2s7IGZvbnQtc2l6ZTogMC43OHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWJvdHRvbTogNHB4O1wiPk1lbW9yeSAoTUIpPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgaWQ9XCJkZXBsb3ktbWVtb3J5LWxpbWl0XCIgdmFsdWU9XCIwXCIgbWluPVwiMFwiIG1heD1cIjEzMTA3MlwiIHN0ZXA9XCI2NFwiIGNsYXNzPVwiZm9ybS1pbnB1dC1jYXJkXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTtcIiBwbGFjZWhvbGRlcj1cIjAgPSB1bmxpbWl0ZWRcIiAvPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2RldGFpbHM+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9uc1wiIHN0eWxlPVwibWFyZ2luLXRvcDogMjRweDtcIj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cImFwcC1kZXBsb3ktY2FuY2VsXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gaWQ9XCJhcHAtZGVwbG95LWNvbmZpcm1cIiBjbGFzcz1cImJ0bi1hY2NlbnRcIj5cbiAgICAgICAgICBcdUQ4M0RcdURFODAgRGVwbG95XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PmApO1xuXG4gIGNvbnN0IEFQUFNfS0VZID0gJ2N1c3RvbS1hcHBzJztcblxuICAvLyBDYWNoZSBmb3IgQVBJIHRlbXBsYXRlc1xuICBsZXQgYXBpVGVtcGxhdGVzID0gbnVsbDtcbiAgbGV0IGFwaUNhdGVnb3JpZXMgPSBudWxsO1xuXG4gIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcC1zZWxlY3Rvci1tb2RhbCcpO1xuICBjb25zdCBncmlkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcC1zZWxlY3Rvci1ncmlkJyk7XG5cbiAgLy8gRmV0Y2ggYXBwIHRlbXBsYXRlcyBmcm9tIEFQSVxuICBhc3luYyBmdW5jdGlvbiBmZXRjaEFwcFRlbXBsYXRlcygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9hcHBzL3RlbXBsYXRlcycpO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgYXBpVGVtcGxhdGVzID0gZGF0YS50ZW1wbGF0ZXM7XG4gICAgICAgIGFwaUNhdGVnb3JpZXMgPSBkYXRhLmNhdGVnb3JpZXM7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGVycm9ySGFuZGxlci5sb2dFcnJvcignW0FwcFNlbGVjdG9yXSBGZXRjaCBUZW1wbGF0ZXMnLCBlLCB7IGZ1bmN0aW9uOiAnZmV0Y2hBcGlUZW1wbGF0ZXMnIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBDaGVjayBwb3J0IGF2YWlsYWJpbGl0eVxuICBhc3luYyBmdW5jdGlvbiBjaGVja1BvcnRBdmFpbGFiaWxpdHkocG9ydCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAvYXBpL3YxL2FwcHMvcG9ydHMvJHtwb3J0fS9jaGVja2ApO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGVycm9ySGFuZGxlci5sb2dFcnJvcignW0FwcFNlbGVjdG9yXSBDaGVjayBQb3J0JywgZSwgeyBmdW5jdGlvbjogJ2NoZWNrUG9ydEF2YWlsYWJpbGl0eScgfSk7XG4gICAgICByZXR1cm4geyBhdmFpbGFibGU6IHRydWUgfTsgLy8gQXNzdW1lIGF2YWlsYWJsZSBvbiBlcnJvclxuICAgIH1cbiAgfVxuXG4gIC8vIEdldCBzdWdnZXN0ZWQgYXZhaWxhYmxlIHBvcnRcbiAgYXN5bmMgZnVuY3Rpb24gZ2V0U3VnZ2VzdGVkUG9ydChiYXNlUG9ydCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAvYXBpL3YxL2FwcHMvcG9ydHMvJHtiYXNlUG9ydH0vc3VnZ2VzdGApO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgcmV0dXJuIGRhdGEuc3VnZ2VzdGVkUG9ydDtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBlcnJvckhhbmRsZXIubG9nRXJyb3IoJ1tBcHBTZWxlY3Rvcl0gR2V0IFN1Z2dlc3RlZCBQb3J0JywgZSwgeyBmdW5jdGlvbjogJ2dldFN1Z2dlc3RlZFBvcnQnIH0pO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZVBvcnQ7XG4gIH1cblxuICAvLyBCdWlsZCBhcHAgc2VsZWN0b3IgZ3JpZCBmcm9tIEFQSSB0ZW1wbGF0ZXNcbiAgYXN5bmMgZnVuY3Rpb24gYnVpbGRBcHBTZWxlY3RvcigpIHtcbiAgICBncmlkLmlubmVySFRNTCA9ICc8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiA0MHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkxvYWRpbmcgYXBwIHRlbXBsYXRlcy4uLjwvZGl2Pic7XG5cbiAgICAvLyBGZXRjaCB0ZW1wbGF0ZXMgaWYgbm90IGNhY2hlZFxuICAgIGlmICghYXBpVGVtcGxhdGVzKSB7XG4gICAgICBjb25zdCBzdWNjZXNzID0gYXdhaXQgZmV0Y2hBcHBUZW1wbGF0ZXMoKTtcbiAgICAgIGlmICghc3VjY2Vzcykge1xuICAgICAgICBncmlkLmlubmVySFRNTCA9ICc8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiA0MHB4OyBjb2xvcjogdmFyKC0tZXJyb3IpO1wiPkZhaWxlZCB0byBsb2FkIGFwcCB0ZW1wbGF0ZXMuIFBsZWFzZSB0cnkgYWdhaW4uPC9kaXY+JztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGdyaWQuaW5uZXJIVE1MID0gJyc7XG5cbiAgICAvLyBHcm91cCB0ZW1wbGF0ZXMgYnkgY2F0ZWdvcnlcbiAgICBjb25zdCBieUNhdGVnb3J5ID0ge307XG4gICAgZm9yIChjb25zdCBbYXBwSWQsIHRlbXBsYXRlXSBvZiBPYmplY3QuZW50cmllcyhhcGlUZW1wbGF0ZXMpKSB7XG4gICAgICBjb25zdCBjYXRlZ29yeSA9IHRlbXBsYXRlLmNhdGVnb3J5IHx8ICdPdGhlcic7XG4gICAgICBpZiAoIWJ5Q2F0ZWdvcnlbY2F0ZWdvcnldKSB7XG4gICAgICAgIGJ5Q2F0ZWdvcnlbY2F0ZWdvcnldID0gW107XG4gICAgICB9XG4gICAgICBieUNhdGVnb3J5W2NhdGVnb3J5XS5wdXNoKHsgaWQ6IGFwcElkLCAuLi50ZW1wbGF0ZSB9KTtcbiAgICB9XG5cbiAgICAvLyBTb3J0IGNhdGVnb3JpZXMgYnkgdGhlIG9yZGVyIGluIGFwaUNhdGVnb3JpZXMgaWYgYXZhaWxhYmxlXG4gICAgY29uc3QgY2F0ZWdvcnlPcmRlciA9IGFwaUNhdGVnb3JpZXMgPyBPYmplY3Qua2V5cyhhcGlDYXRlZ29yaWVzKSA6IE9iamVjdC5rZXlzKGJ5Q2F0ZWdvcnkpLnNvcnQoKTtcblxuICAgIGZvciAoY29uc3QgY2F0ZWdvcnkgb2YgY2F0ZWdvcnlPcmRlcikge1xuICAgICAgY29uc3QgYXBwcyA9IGJ5Q2F0ZWdvcnlbY2F0ZWdvcnldO1xuICAgICAgaWYgKCFhcHBzIHx8IGFwcHMubGVuZ3RoID09PSAwKSBjb250aW51ZTtcblxuICAgICAgLy8gU29ydCBhcHBzIGJ5IHBvcHVsYXJpdHkgKGRlc2NlbmRpbmcpXG4gICAgICBhcHBzLnNvcnQoKGEsIGIpID0+IChiLnBvcHVsYXJpdHkgfHwgMCkgLSAoYS5wb3B1bGFyaXR5IHx8IDApKTtcblxuICAgICAgLy8gQ2F0ZWdvcnkgaGVhZGVyIHdpdGggaWNvbiBhbmQgY29sb3IgZnJvbSBBUElcbiAgICAgIGNvbnN0IGhlYWRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgaGVhZGVyLmNsYXNzTmFtZSA9ICdhcHAtY2F0ZWdvcnktaGVhZGVyJztcbiAgICAgIGNvbnN0IGNhdGVnb3J5SW5mbyA9IGFwaUNhdGVnb3JpZXM/LltjYXRlZ29yeV0gfHwge307XG4gICAgICBoZWFkZXIuaW5uZXJIVE1MID0gYCR7ZXNjYXBlSHRtbChjYXRlZ29yeUluZm8uaWNvbiB8fCAnJyl9ICR7ZXNjYXBlSHRtbChjYXRlZ29yeSl9YDtcbiAgICAgIGlmIChjYXRlZ29yeUluZm8uY29sb3IpIHtcbiAgICAgICAgaGVhZGVyLnN0eWxlLmJvcmRlckJvdHRvbUNvbG9yID0gY2F0ZWdvcnlJbmZvLmNvbG9yO1xuICAgICAgfVxuICAgICAgZ3JpZC5hcHBlbmRDaGlsZChoZWFkZXIpO1xuXG4gICAgICAvLyBBcHAgb3B0aW9uc1xuICAgICAgYXBwcy5mb3JFYWNoKGFwcCA9PiB7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBvcHRpb24uY2xhc3NOYW1lID0gJ2FwcC1vcHRpb24nO1xuXG4gICAgICAgIC8vIFdpZGdldCBlbmFibGVkIGJhZGdlXG4gICAgICAgIGNvbnN0IGlzV2lkZ2V0ID0gYXBwLmlzRGFzaGJvYXJkV2lkZ2V0O1xuICAgICAgICBjb25zdCB3aWRnZXRFbmFibGVkID0gaXNXaWRnZXQgJiYgc2FmZUdldCgnd2lkZ2V0LScgKyBhcHAuaWQgKyAnLWVuYWJsZWQnKSAhPT0gJ2ZhbHNlJztcbiAgICAgICAgY29uc3Qgd2lkZ2V0QmFkZ2UgPSBpc1dpZGdldFxuICAgICAgICAgID8gYDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNjVyZW07IHBhZGRpbmc6IDJweCA2cHg7IGJvcmRlci1yYWRpdXM6IDRweDsgbWFyZ2luLXRvcDogNHB4OyBiYWNrZ3JvdW5kOiAke3dpZGdldEVuYWJsZWQgPyAnIzJlY2M3MTMwJyA6ICcjZTc0YzNjMzAnfTsgY29sb3I6ICR7d2lkZ2V0RW5hYmxlZCA/ICcjMmVjYzcxJyA6ICcjZTc0YzNjJ307IGZvbnQtd2VpZ2h0OiA2MDA7XCI+JHt3aWRnZXRFbmFibGVkID8gJ09OJyA6ICdPRkYnfTwvZGl2PmBcbiAgICAgICAgICA6ICcnO1xuXG4gICAgICAgIC8vIFNob3cgZGlmZmljdWx0eSBiYWRnZSAobm9uLXdpZGdldHMgb25seSlcbiAgICAgICAgY29uc3QgZGlmZmljdWx0eUJhZGdlID0gIWlzV2lkZ2V0ICYmIGFwcC5kaWZmaWN1bHR5ID9cbiAgICAgICAgICBgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC42NXJlbTsgcGFkZGluZzogMnB4IDZweDsgYm9yZGVyLXJhZGl1czogNHB4OyBtYXJnaW4tdG9wOiA0cHg7IGJhY2tncm91bmQ6ICR7XG4gICAgICAgICAgICBhcHAuZGlmZmljdWx0eSA9PT0gJ0Vhc3knID8gJyMyZWNjNzEnIDpcbiAgICAgICAgICAgIGFwcC5kaWZmaWN1bHR5ID09PSAnSW50ZXJtZWRpYXRlJyA/ICcjZjM5YzEyJyA6ICcjZTc0YzNjJ1xuICAgICAgICAgIH0yMDsgY29sb3I6ICR7XG4gICAgICAgICAgICBhcHAuZGlmZmljdWx0eSA9PT0gJ0Vhc3knID8gJyMyZWNjNzEnIDpcbiAgICAgICAgICAgIGFwcC5kaWZmaWN1bHR5ID09PSAnSW50ZXJtZWRpYXRlJyA/ICcjZjM5YzEyJyA6ICcjZTc0YzNjJ1xuICAgICAgICAgIH07XCI+JHtlc2NhcGVIdG1sKGFwcC5kaWZmaWN1bHR5KX08L2Rpdj5gIDogJyc7XG5cbiAgICAgICAgb3B0aW9uLmlubmVySFRNTCA9IGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXBwLW9wdGlvbi1pY29uXCI+JHtlc2NhcGVIdG1sKGFwcC5pY29uIHx8ICdcdUQ4M0RcdURDRTYnKX08L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXBwLW9wdGlvbi1uYW1lXCI+JHtlc2NhcGVIdG1sKGFwcC5uYW1lKX08L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXBwLW9wdGlvbi1kZXNjXCI+JHtlc2NhcGVIdG1sKGFwcC5kZXNjcmlwdGlvbiB8fCAnJyl9PC9kaXY+XG4gICAgICAgICAgJHt3aWRnZXRCYWRnZX0ke2RpZmZpY3VsdHlCYWRnZX1cbiAgICAgICAgYDtcblxuICAgICAgICBpZiAoaXNXaWRnZXQpIHtcbiAgICAgICAgICBvcHRpb24ub25jbGljayA9ICgpID0+IHRvZ2dsZURhc2hib2FyZFdpZGdldChhcHAsIG9wdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3B0aW9uLm9uY2xpY2sgPSAoKSA9PiBzaG93RGVwbG95Q29uZmlnKGFwcCk7XG4gICAgICAgIH1cbiAgICAgICAgZ3JpZC5hcHBlbmRDaGlsZChvcHRpb24pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gUmVuZGVyIHJlY2lwZSBjYXJkcyBhdCB0aGUgZW5kIG9mIHRoZSBncmlkXG4gICAgaWYgKHdpbmRvdy5yZW5kZXJSZWNpcGVDYXJkcykge1xuICAgICAgYXdhaXQgd2luZG93LnJlbmRlclJlY2lwZUNhcmRzKGdyaWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRvZ2dsZSBhIGRhc2hib2FyZCB3aWRnZXQgb24vb2ZmXG4gIGZ1bmN0aW9uIHRvZ2dsZURhc2hib2FyZFdpZGdldChhcHAsIG9wdGlvbkVsKSB7XG4gICAgY29uc3Qga2V5ID0gJ3dpZGdldC0nICsgYXBwLmlkICsgJy1lbmFibGVkJztcbiAgICBjb25zdCBjdXJyZW50bHlFbmFibGVkID0gc2FmZUdldChrZXkpICE9PSAnZmFsc2UnO1xuICAgIGNvbnN0IG5ld1N0YXRlID0gIWN1cnJlbnRseUVuYWJsZWQ7XG4gICAgc2FmZVNldChrZXksIFN0cmluZyhuZXdTdGF0ZSkpO1xuXG4gICAgLy8gVXBkYXRlIHZpc2liaWxpdHkgaW1tZWRpYXRlbHlcbiAgICBjb25zdCBzZWxlY3RvciA9IGFwcC53aWRnZXRTZWxlY3RvcjtcbiAgICBpZiAoc2VsZWN0b3IpIHtcbiAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgICBpZiAoZWwpIGVsLnN0eWxlLmRpc3BsYXkgPSBuZXdTdGF0ZSA/ICcnIDogJ25vbmUnO1xuICAgIH1cblxuICAgIC8vIFVwZGF0ZSB0aGUgYmFkZ2UgaW4gdGhlIGFwcCBzZWxlY3RvciBjYXJkXG4gICAgY29uc3QgYmFkZ2UgPSBvcHRpb25FbC5xdWVyeVNlbGVjdG9yKCdkaXZbc3R5bGUqPVwiYm9yZGVyLXJhZGl1czogNHB4XCJdJyk7XG4gICAgaWYgKGJhZGdlKSB7XG4gICAgICBiYWRnZS50ZXh0Q29udGVudCA9IG5ld1N0YXRlID8gJ09OJyA6ICdPRkYnO1xuICAgICAgYmFkZ2Uuc3R5bGUuYmFja2dyb3VuZCA9IG5ld1N0YXRlID8gJyMyZWNjNzEzMCcgOiAnI2U3NGMzYzMwJztcbiAgICAgIGJhZGdlLnN0eWxlLmNvbG9yID0gbmV3U3RhdGUgPyAnIzJlY2M3MScgOiAnI2U3NGMzYyc7XG4gICAgfVxuXG4gICAgc2hvd05vdGlmaWNhdGlvbihgJHthcHAubmFtZX0gd2lkZ2V0ICR7bmV3U3RhdGUgPyAnZW5hYmxlZCcgOiAnZGlzYWJsZWQnfWAsICdzdWNjZXNzJywgMjAwMCk7XG4gIH1cblxuICAvLyBTaG93IGRlcGxveW1lbnQgY29uZmlndXJhdGlvbiBtb2RhbFxuICBhc3luYyBmdW5jdGlvbiBzaG93RGVwbG95Q29uZmlnKGFwcFRlbXBsYXRlKSB7XG4gICAgY29uc3QgZGVwbG95TW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXBwLWRlcGxveS1tb2RhbCcpO1xuICAgIGNvbnN0IHRpdGxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcC1kZXBsb3ktdGl0bGUnKTtcbiAgICBjb25zdCBzdWJkb21haW5JbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktc3ViZG9tYWluJyk7XG4gICAgY29uc3QgdXJsUHJldmlldyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktdXJsLXByZXZpZXcnKTtcbiAgICBjb25zdCBpcElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS1pcCcpO1xuICAgIGNvbnN0IHBvcnRJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktcG9ydCcpO1xuICAgIGNvbnN0IHRhaWxzY2FsZUNoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS10YWlsc2NhbGUtb25seScpO1xuICAgIGNvbnN0IHRhaWxzY2FsZVN0YXR1cyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0YWlsc2NhbGUtc3RhdHVzJyk7XG5cbiAgICAvLyBDaGVjayBmb3IgZXhpc3RpbmcgY29udGFpbmVyIHdpdGggc2FtZSBpbWFnZVxuICAgIHRyeSB7XG4gICAgICBjb25zdCBjaGVja1Jlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvYXBwcy9jaGVjay1leGlzdGluZycsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IGFwcElkOiBhcHBUZW1wbGF0ZS5pZCB9KVxuICAgICAgfSk7XG4gICAgICBjb25zdCBjaGVja1Jlc3VsdCA9IGF3YWl0IGNoZWNrUmVzcG9uc2UuanNvbigpO1xuXG4gICAgICBpZiAoY2hlY2tSZXN1bHQuc3VjY2VzcyAmJiBjaGVja1Jlc3VsdC5leGlzdHMpIHtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gY2hlY2tSZXN1bHQuY29udGFpbmVyO1xuICAgICAgICBjb25zdCB1c2VFeGlzdGluZyA9IGNvbmZpcm0oXG4gICAgICAgICAgYEZvdW5kIGV4aXN0aW5nICR7YXBwVGVtcGxhdGUubmFtZX0gY29udGFpbmVyOlxcblxcbmAgK1xuICAgICAgICAgIGBDb250YWluZXI6ICR7Y29udGFpbmVyLm5hbWV9XFxuYCArXG4gICAgICAgICAgYFN0YXR1czogJHtjb250YWluZXIuc3RhdHVzfVxcbmAgK1xuICAgICAgICAgIGBQb3J0OiAke2NvbnRhaW5lci5wcmltYXJ5UG9ydCB8fCAnTi9BJ31cXG5cXG5gICtcbiAgICAgICAgICBgV291bGQgeW91IGxpa2UgdG8gdXNlIHRoaXMgZXhpc3RpbmcgY29udGFpbmVyP1xcblxcbmAgK1xuICAgICAgICAgIGBDbGljayBPSyB0byBjb25maWd1cmUgRE5TL0NhZGR5IGZvciB0aGUgZXhpc3RpbmcgY29udGFpbmVyLlxcbmAgK1xuICAgICAgICAgIGBDbGljayBDYW5jZWwgdG8gZGVwbG95IGEgbmV3IGNvbnRhaW5lci5gXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHVzZUV4aXN0aW5nKSB7XG4gICAgICAgICAgLy8gU3RvcmUgZXhpc3RpbmcgY29udGFpbmVyIGluZm8gZm9yIGRlcGxveW1lbnRcbiAgICAgICAgICBhcHBUZW1wbGF0ZS5fdXNlRXhpc3RpbmcgPSB0cnVlO1xuICAgICAgICAgIGFwcFRlbXBsYXRlLl9leGlzdGluZ0NvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIElnbm9yZSBjb250YWluZXIgY2hlY2sgZXJyb3JzXG4gICAgfVxuXG4gICAgLy8gU2V0IHRpdGxlIHdpdGggYXBwIGluZm9cbiAgICB0aXRsZS50ZXh0Q29udGVudCA9IGBEZXBsb3kgJHthcHBUZW1wbGF0ZS5uYW1lfWA7XG5cbiAgICAvLyBQcmUtZmlsbCBzdWJkb21haW4gZnJvbSB0ZW1wbGF0ZSBvciBhcHAgSURcbiAgICBjb25zdCBkZWZhdWx0U3ViZG9tYWluID0gYXBwVGVtcGxhdGUuc3ViZG9tYWluIHx8IGFwcFRlbXBsYXRlLmlkLnJlcGxhY2UoLy0vZywgJycpO1xuICAgIHN1YmRvbWFpbklucHV0LnZhbHVlID0gZGVmYXVsdFN1YmRvbWFpbjtcblxuICAgIC8vIFNob3cgc3VicGF0aCBjb21wYXRpYmlsaXR5IHdhcm5pbmcgaW4gc3ViZGlyZWN0b3J5IG1vZGVcbiAgICBjb25zdCBzdWJwYXRoV2FybmluZyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdWJwYXRoLWNvbXBhdC13YXJuaW5nJyk7XG4gICAgaWYgKHN1YnBhdGhXYXJuaW5nKSB7XG4gICAgICBpZiAoU0lURS5yb3V0aW5nTW9kZSA9PT0gJ3N1YmRpcmVjdG9yeScpIHtcbiAgICAgICAgY29uc3Qgc3VwcG9ydCA9IGFwcFRlbXBsYXRlLnN1YnBhdGhTdXBwb3J0IHx8ICdzdHJpcCc7XG4gICAgICAgIGlmIChzdXBwb3J0ID09PSAnbm9uZScpIHtcbiAgICAgICAgICBzdWJwYXRoV2FybmluZy5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgICBzdWJwYXRoV2FybmluZy5pbm5lckhUTUwgPSAnPHNwYW4gc3R5bGU9XCJjb2xvcjogI2ZmOTgwMDtcIj4mIzk4ODg7IDxzdHJvbmc+JyArIGFwcFRlbXBsYXRlLm5hbWUgKyAnPC9zdHJvbmc+IGRvZXMgbm90IHN1cHBvcnQgc3ViZGlyZWN0b3J5IG1vZGUuIEl0IG1heSBub3Qgd29yayBjb3JyZWN0bHkgYXQgYSBzdWJwYXRoLjwvc3Bhbj4nO1xuICAgICAgICB9IGVsc2UgaWYgKHN1cHBvcnQgPT09ICdzdHJpcCcpIHtcbiAgICAgICAgICBzdWJwYXRoV2FybmluZy5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgICBzdWJwYXRoV2FybmluZy5pbm5lckhUTUwgPSAnPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPiYjOTQzMjsgJyArIGFwcFRlbXBsYXRlLm5hbWUgKyAnIGhhcyB1bnZlcmlmaWVkIHN1YmRpcmVjdG9yeSBzdXBwb3J0LiBJdCBtYXkgcmVxdWlyZSBhZGRpdGlvbmFsIGNvbmZpZ3VyYXRpb24uPC9zcGFuPic7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3VicGF0aFdhcm5pbmcuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3VicGF0aFdhcm5pbmcuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBQcmUtc2VsZWN0IEROUy9TU0wgZnJvbSBzaXRlIGNvbmZpZyAoc2V0IGR1cmluZyBzZXR1cCB3aXphcmQpXG4gICAgY29uc3QgY2ZnRG5zVHlwZSA9IFNJVEUuZGVmYXVsdHMuZG5zVHlwZSB8fCAoU0lURS5jb25maWd1cmF0aW9uVHlwZSA9PT0gJ3B1YmxpYycgPyAncHVibGljJyA6ICdwcml2YXRlJyk7XG4gICAgY29uc3QgY2ZnU3NsVHlwZSA9IFNJVEUuZGVmYXVsdHMuc3NsVHlwZSB8fCAoU0lURS5jb25maWd1cmF0aW9uVHlwZSA9PT0gJ3B1YmxpYycgPyAnbGV0c2VuY3J5cHQnIDogJ2ludGVybmFsJyk7XG4gICAgY29uc3QgZG5zUmFkaW8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBpbnB1dFtuYW1lPVwiZG5zLXR5cGVcIl1bdmFsdWU9XCIke2NmZ0Ruc1R5cGV9XCJdYCk7XG4gICAgY29uc3Qgc3NsUmFkaW8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBpbnB1dFtuYW1lPVwic3NsLXR5cGVcIl1bdmFsdWU9XCIke2NmZ1NzbFR5cGV9XCJdYCk7XG4gICAgaWYgKGRuc1JhZGlvKSBkbnNSYWRpby5jaGVja2VkID0gdHJ1ZTtcbiAgICBlbHNlIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9XCJkbnMtdHlwZVwiXVt2YWx1ZT1cInByaXZhdGVcIl0nKS5jaGVja2VkID0gdHJ1ZTtcbiAgICBpZiAoc3NsUmFkaW8pIHNzbFJhZGlvLmNoZWNrZWQgPSB0cnVlO1xuICAgIGVsc2UgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cInNzbC10eXBlXCJdW3ZhbHVlPVwiaW50ZXJuYWxcIl0nKS5jaGVja2VkID0gdHJ1ZTtcbiAgICBpcElucHV0LnZhbHVlID0gU0lURS5kZWZhdWx0cy50YXJnZXRJUCB8fCAnbG9jYWxob3N0JztcbiAgICB0YWlsc2NhbGVDaGVja2JveC5jaGVja2VkID0gZmFsc2U7XG5cbiAgICAvLyBNb3ZlIEROUy9TU0wgaW50byBBZHZhbmNlZCBzZWN0aW9uIHdoZW4gYWxyZWFkeSBjb25maWd1cmVkXG4gICAgY29uc3QgZG5zU2VjdGlvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNhcHAtZGVwbG95LW1vZGFsIC5mbGV4LWNvbC1nYXAnKT8uY2xvc2VzdCgnZGl2Jyk7XG4gICAgY29uc3QgYWR2YW5jZWREZXRhaWxzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2FwcC1kZXBsb3ktbW9kYWwgZGV0YWlscycpO1xuICAgIGNvbnN0IGFkdmFuY2VkQ29udGVudCA9IGFkdmFuY2VkRGV0YWlscz8ucXVlcnlTZWxlY3RvcignZGl2Jyk7XG4gICAgaWYgKGFkdmFuY2VkRGV0YWlscyAmJiBhZHZhbmNlZENvbnRlbnQgJiYgKFNJVEUuY29uZmlndXJhdGlvblR5cGUgPT09ICdwdWJsaWMnIHx8IFNJVEUuY29uZmlndXJhdGlvblR5cGUgPT09ICdob21lbGFiJykpIHtcbiAgICAgIC8vIE1vdmUgRE5TIGFuZCBTU0wgc2VjdGlvbnMgaW5zaWRlIEFkdmFuY2VkXG4gICAgICBjb25zdCBkbnNTZWN0aW9uRWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjYXBwLWRlcGxveS1tb2RhbCBpbnB1dFtuYW1lPVwiZG5zLXR5cGVcIl0nKVswXT8uY2xvc2VzdCgnZGl2LmZsZXgtY29sLWdhcCcpPy5wYXJlbnRFbGVtZW50O1xuICAgICAgY29uc3Qgc3NsU2VjdGlvbkVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI2FwcC1kZXBsb3ktbW9kYWwgaW5wdXRbbmFtZT1cInNzbC10eXBlXCJdJylbMF0/LmNsb3Nlc3QoJ2Rpdi5mbGV4LWNvbC1nYXAnKT8ucGFyZW50RWxlbWVudDtcbiAgICAgIGlmIChkbnNTZWN0aW9uRWwgJiYgIWRuc1NlY3Rpb25FbC5kYXRhc2V0Lm1vdmVkKSB7XG4gICAgICAgIGFkdmFuY2VkQ29udGVudC5hcHBlbmRDaGlsZChkbnNTZWN0aW9uRWwpO1xuICAgICAgICBkbnNTZWN0aW9uRWwuZGF0YXNldC5tb3ZlZCA9ICcxJztcbiAgICAgIH1cbiAgICAgIGlmIChzc2xTZWN0aW9uRWwgJiYgIXNzbFNlY3Rpb25FbC5kYXRhc2V0Lm1vdmVkKSB7XG4gICAgICAgIGFkdmFuY2VkQ29udGVudC5hcHBlbmRDaGlsZChzc2xTZWN0aW9uRWwpO1xuICAgICAgICBzc2xTZWN0aW9uRWwuZGF0YXNldC5tb3ZlZCA9ICcxJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgbWVkaWEgcGF0aCBzZWN0aW9uIGZvciBtZWRpYSBhcHBzXG4gICAgY29uc3QgbWVkaWFQYXRoU2VjdGlvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtZWRpYS1wYXRoLXNlY3Rpb24nKTtcbiAgICBjb25zdCBtZWRpYVBhdGhJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktbWVkaWEtcGF0aCcpO1xuICAgIGNvbnN0IG1lZGlhUGF0aERlc2NyaXB0aW9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21lZGlhLXBhdGgtZGVzY3JpcHRpb24nKTtcblxuICAgIGlmIChhcHBUZW1wbGF0ZS5tZWRpYU1vdW50KSB7XG4gICAgICBtZWRpYVBhdGhTZWN0aW9uLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgbWVkaWFQYXRoSW5wdXQudmFsdWUgPSAnJztcbiAgICAgIG1lZGlhUGF0aElucHV0LnBsYWNlaG9sZGVyID0gJy9tZWRpYS9Nb3ZpZXMsIC9tZWRpYS9UVlNob3dzIG9yIGNsaWNrIEJyb3dzZSc7XG5cbiAgICAgIC8vIEZldGNoIGRldGVjdGVkIG1vdW50cyBmcm9tIGV4aXN0aW5nIG1lZGlhIHNlcnZlcnNcbiAgICAgIGNvbnN0IGRldGVjdGVkTW91bnRzQ29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RldGVjdGVkLW1vdW50cy1jb250YWluZXInKTtcbiAgICAgIGNvbnN0IGRldGVjdGVkTW91bnRzTGlzdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXRlY3RlZC1tb3VudHMtbGlzdCcpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBtb3VudHNSZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL21lZGlhL2RldGVjdGVkLW1vdW50cycpO1xuICAgICAgICBjb25zdCBtb3VudHNSZXN1bHQgPSBhd2FpdCBtb3VudHNSZXNwb25zZS5qc29uKCk7XG5cbiAgICAgICAgaWYgKG1vdW50c1Jlc3VsdC5zdWNjZXNzICYmIG1vdW50c1Jlc3VsdC5tb3VudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGRldGVjdGVkTW91bnRzQ29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICAgIGRldGVjdGVkTW91bnRzTGlzdC5pbm5lckhUTUwgPSAnJztcblxuICAgICAgICAgIC8vIEF1dG8tZmlsbCBtZWRpYSBwYXRoIHdpdGggYWxsIGRldGVjdGVkIG1vdW50c1xuICAgICAgICAgIGNvbnN0IGF1dG9QYXRocyA9IFsuLi5uZXcgU2V0KG1vdW50c1Jlc3VsdC5tb3VudHMubWFwKG0gPT4gbS5ob3N0UGF0aCkpXTtcbiAgICAgICAgICBtZWRpYVBhdGhJbnB1dC52YWx1ZSA9IGF1dG9QYXRocy5qb2luKCcsICcpO1xuXG4gICAgICAgICAgbW91bnRzUmVzdWx0Lm1vdW50cy5mb3JFYWNoKG1vdW50ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ0biA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgICAgICAgICAgYnRuLnR5cGUgPSAnYnV0dG9uJztcbiAgICAgICAgICAgIGNvbnN0IGlzU2VsZWN0ZWQgPSBhdXRvUGF0aHMuaW5jbHVkZXMobW91bnQuaG9zdFBhdGgpO1xuICAgICAgICAgICAgYnRuLnN0eWxlLmNzc1RleHQgPSBgcGFkZGluZzogOHB4IDE0cHg7IGZvbnQtc2l6ZTogMC44NXJlbTsgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLXN1Y2Nlc3MpICR7aXNTZWxlY3RlZCA/ICc0MCUnIDogJzE1JSd9LCB2YXIoLS1jYXJkLWJnKSk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLXN1Y2Nlc3MpOyBib3JkZXItcmFkaXVzOiA2cHg7IGN1cnNvcjogcG9pbnRlcjsgY29sb3I6IHZhcigtLWZnKTtgO1xuICAgICAgICAgICAgYnRuLmlubmVySFRNTCA9IGA8c3BhbiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA1MDA7XCI+JHtlc2NhcGVIdG1sKG1vdW50LmZvbGRlck5hbWUpfTwvc3Bhbj48YnI+PHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDAuN3JlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5mcm9tICR7ZXNjYXBlSHRtbChtb3VudC5zb3VyY2VJbWFnZSl9PC9zcGFuPmA7XG4gICAgICAgICAgICBidG4udGl0bGUgPSBgJHttb3VudC5ob3N0UGF0aH0gKGZyb20gJHttb3VudC5zb3VyY2VDb250YWluZXJ9KWA7XG4gICAgICAgICAgICBidG4ub25jbGljayA9ICgpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgY3VycmVudFBhdGhzID0gbWVkaWFQYXRoSW5wdXQudmFsdWUuc3BsaXQoJywnKS5tYXAocCA9PiBwLnRyaW0oKSkuZmlsdGVyKHAgPT4gcCk7XG4gICAgICAgICAgICAgIGNvbnN0IGlkeCA9IGN1cnJlbnRQYXRocy5pbmRleE9mKG1vdW50Lmhvc3RQYXRoKTtcbiAgICAgICAgICAgICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFBhdGhzLnNwbGljZShpZHgsIDEpO1xuICAgICAgICAgICAgICAgIGJ0bi5zdHlsZS5iYWNrZ3JvdW5kID0gJ2NvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1zdWNjZXNzKSAxNSUsIHZhcigtLWNhcmQtYmcpKSc7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFBhdGhzLnB1c2gobW91bnQuaG9zdFBhdGgpO1xuICAgICAgICAgICAgICAgIGJ0bi5zdHlsZS5iYWNrZ3JvdW5kID0gJ2NvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1zdWNjZXNzKSA0MCUsIHZhcigtLWNhcmQtYmcpKSc7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbWVkaWFQYXRoSW5wdXQudmFsdWUgPSBjdXJyZW50UGF0aHMuam9pbignLCAnKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBkZXRlY3RlZE1vdW50c0xpc3QuYXBwZW5kQ2hpbGQoYnRuKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZXRlY3RlZE1vdW50c0NvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGRldGVjdGVkTW91bnRzQ29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICB9XG5cbiAgICAgIC8vIFNldCB1cCBicm93c2UgYnV0dG9uXG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYnJvd3NlLW1lZGlhLWJ0bicpLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgIG9wZW5Gb2xkZXJCcm93c2VyKG1lZGlhUGF0aElucHV0KTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIG1lZGlhUGF0aFNlY3Rpb24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIG1lZGlhUGF0aElucHV0LnZhbHVlID0gJyc7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGV0ZWN0ZWQtbW91bnRzLWNvbnRhaW5lcicpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgfVxuXG4gICAgLy8gU2hvdyBQbGV4IGNsYWltIHRva2VuIHNlY3Rpb24gZm9yIFBsZXggZGVwbG95bWVudHNcbiAgICBjb25zdCBwbGV4Q2xhaW1TZWN0aW9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BsZXgtY2xhaW0tc2VjdGlvbicpO1xuICAgIGlmIChwbGV4Q2xhaW1TZWN0aW9uKSB7XG4gICAgICBpZiAoYXBwVGVtcGxhdGUuaWQgPT09ICdwbGV4JyB8fCBhcHBUZW1wbGF0ZS5jbGFpbVRva2VuKSB7XG4gICAgICAgIHBsZXhDbGFpbVNlY3Rpb24uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktcGxleC1jbGFpbScpLnZhbHVlID0gJyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwbGV4Q2xhaW1TZWN0aW9uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUG9wdWxhdGUgdm9sdW1lIG1vdW50cyBpbiBBZHZhbmNlZCBPcHRpb25zXG4gICAgY29uc3Qgdm9sdW1lU2VjdGlvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2b2x1bWUtbW91bnRzLXNlY3Rpb24nKTtcbiAgICBjb25zdCB2b2x1bWVMaXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZvbHVtZS1tb3VudHMtbGlzdCcpO1xuICAgIHZvbHVtZUxpc3QuaW5uZXJIVE1MID0gJyc7XG5cbiAgICBpZiAoYXBwVGVtcGxhdGUuZG9ja2VyPy52b2x1bWVzPy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG1lZGlhQ29udGFpbmVyUGF0aCA9IGFwcFRlbXBsYXRlLm1lZGlhTW91bnQ/LmNvbnRhaW5lclBhdGg7XG4gICAgICBjb25zdCBub25NZWRpYVZvbHVtZXMgPSBhcHBUZW1wbGF0ZS5kb2NrZXIudm9sdW1lcy5maWx0ZXIodiA9PiAhdi5pbmNsdWRlcygne3tNRURJQV9QQVRIfX0nKSAmJiAhKG1lZGlhQ29udGFpbmVyUGF0aCAmJiB2LmVuZHNXaXRoKCc6JyArIG1lZGlhQ29udGFpbmVyUGF0aCkpKTtcblxuICAgICAgaWYgKG5vbk1lZGlhVm9sdW1lcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHZvbHVtZVNlY3Rpb24uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgIG5vbk1lZGlhVm9sdW1lcy5mb3JFYWNoKCh2b2wsIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBbaG9zdERlZmF1bHQsIGNvbnRhaW5lclBhdGhdID0gdm9sLnNwbGl0KCc6Jyk7XG4gICAgICAgICAgY29uc3Qgcm93ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgcm93LnN0eWxlLmNzc1RleHQgPSAnZGlzcGxheTogZmxleDsgZ2FwOiA2cHg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7JztcbiAgICAgICAgICByb3cuaW5uZXJIVE1MID0gYFxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJ2b2wtaG9zdC1wYXRoXCIgZGF0YS1jb250YWluZXItcGF0aD1cIiR7Y29udGFpbmVyUGF0aH1cIiB2YWx1ZT1cIiR7aG9zdERlZmF1bHR9XCJcbiAgICAgICAgICAgICAgICAgICBzdHlsZT1cImZsZXg6IDE7IHBhZGRpbmc6IDhweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDZweDsgZm9udC1zaXplOiAwLjg1cmVtO1wiIC8+XG4gICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IGZvbnQtc2l6ZTogMC44NXJlbTsgd2hpdGUtc3BhY2U6IG5vd3JhcDtcIj5cdTIxOTIgJHtjb250YWluZXJQYXRofTwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidm9sLWJyb3dzZS1idG5cIiBzdHlsZT1cInBhZGRpbmc6IDhweCAxMHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1hY2NlbnQpOyBjb2xvcjogd2hpdGU7IGJvcmRlcjogbm9uZTsgYm9yZGVyLXJhZGl1czogNnB4OyBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtc2l6ZTogMC44cmVtO1wiPlx1RDgzRFx1RENDMjwvYnV0dG9uPlxuICAgICAgICAgIGA7XG4gICAgICAgICAgdm9sdW1lTGlzdC5hcHBlbmRDaGlsZChyb3cpO1xuICAgICAgICAgIHJvdy5xdWVyeVNlbGVjdG9yKCcudm9sLWJyb3dzZS1idG4nKS5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5wdXQgPSByb3cucXVlcnlTZWxlY3RvcignLnZvbC1ob3N0LXBhdGgnKTtcbiAgICAgICAgICAgIG9wZW5Gb2xkZXJCcm93c2VyKGlucHV0KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZvbHVtZVNlY3Rpb24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdm9sdW1lU2VjdGlvbi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIH1cblxuICAgIC8vIFNldCBkZWZhdWx0IHBvcnQgZnJvbSB0ZW1wbGF0ZSBhbmQgY2hlY2sgYXZhaWxhYmlsaXR5XG4gICAgY29uc3QgZGVmYXVsdFBvcnQgPSBhcHBUZW1wbGF0ZS5kZWZhdWx0UG9ydCB8fCA4MDgwO1xuICAgIHBvcnRJbnB1dC52YWx1ZSA9ICcnO1xuICAgIHBvcnRJbnB1dC5wbGFjZWhvbGRlciA9IGBEZWZhdWx0OiAke2RlZmF1bHRQb3J0fWA7XG5cbiAgICAvLyBBZGQgcG9ydCBzdGF0dXMgZWxlbWVudCBpZiBub3QgZXhpc3RzXG4gICAgbGV0IHBvcnRTdGF0dXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGVwbG95LXBvcnQtc3RhdHVzJyk7XG4gICAgaWYgKCFwb3J0U3RhdHVzKSB7XG4gICAgICBwb3J0U3RhdHVzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBwb3J0U3RhdHVzLmlkID0gJ2RlcGxveS1wb3J0LXN0YXR1cyc7XG4gICAgICBwb3J0U3RhdHVzLnN0eWxlLmNzc1RleHQgPSAnZm9udC1zaXplOiAwLjhyZW07IG1hcmdpbi10b3A6IDRweDsnO1xuICAgICAgcG9ydElucHV0LnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQocG9ydFN0YXR1cyk7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZGVmYXVsdCBwb3J0IGF2YWlsYWJpbGl0eVxuICAgIGFzeW5jIGZ1bmN0aW9uIGNoZWNrQW5kVXBkYXRlUG9ydFN0YXR1cygpIHtcbiAgICAgIGNvbnN0IHBvcnRUb0NoZWNrID0gcG9ydElucHV0LnZhbHVlIHx8IGRlZmF1bHRQb3J0O1xuICAgICAgcG9ydFN0YXR1cy5pbm5lckhUTUwgPSAnPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkNoZWNraW5nIHBvcnQuLi48L3NwYW4+JztcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY2hlY2tQb3J0QXZhaWxhYmlsaXR5KHBvcnRUb0NoZWNrKTtcbiAgICAgIGlmIChyZXN1bHQuYXZhaWxhYmxlKSB7XG4gICAgICAgIHBvcnRTdGF0dXMuaW5uZXJIVE1MID0gYDxzcGFuIHN0eWxlPVwiY29sb3I6ICM0Y2FmNTA7XCI+UG9ydCAke2VzY2FwZUh0bWwoU3RyaW5nKHBvcnRUb0NoZWNrKSl9IGlzIGF2YWlsYWJsZTwvc3Bhbj5gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgc3VnZ2VzdGVkUG9ydCA9IGF3YWl0IGdldFN1Z2dlc3RlZFBvcnQoZGVmYXVsdFBvcnQpO1xuICAgICAgICBwb3J0U3RhdHVzLmlubmVySFRNTCA9IGBcbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiAjZTc0YzNjO1wiPlBvcnQgJHtlc2NhcGVIdG1sKHBvcnRUb0NoZWNrKX0gaW4gdXNlIGJ5ICR7ZXNjYXBlSHRtbChyZXN1bHQuY29uZmxpY3Q/LnVzZWRCeSB8fCAndW5rbm93bicpfTwvc3Bhbj5cbiAgICAgICAgYDtcbiAgICAgICAgY29uc3QgdXNlQnRuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7XG4gICAgICAgIHVzZUJ0bi50eXBlID0gJ2J1dHRvbic7XG4gICAgICAgIHVzZUJ0bi50ZXh0Q29udGVudCA9IGBVc2UgJHtzdWdnZXN0ZWRQb3J0fWA7XG4gICAgICAgIHVzZUJ0bi5zdHlsZS5jc3NUZXh0ID0gJ21hcmdpbi1sZWZ0OiA4cHg7IHBhZGRpbmc6IDJweCA4cHg7IGZvbnQtc2l6ZTogMC43NXJlbTsgY3Vyc29yOiBwb2ludGVyOyc7XG4gICAgICAgIHVzZUJ0bi5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktcG9ydCcpLnZhbHVlID0gc3VnZ2VzdGVkUG9ydDtcbiAgICAgICAgICBwb3J0U3RhdHVzLmlubmVySFRNTCA9IGA8c3BhbiBzdHlsZT1cImNvbG9yOiAjNGNhZjUwO1wiPlVzaW5nIHN1Z2dlc3RlZCBwb3J0ICR7ZXNjYXBlSHRtbChTdHJpbmcoc3VnZ2VzdGVkUG9ydCkpfTwvc3Bhbj5gO1xuICAgICAgICB9O1xuICAgICAgICBwb3J0U3RhdHVzLmFwcGVuZENoaWxkKHVzZUJ0bik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgcG9ydCBvbiBpbnB1dCBjaGFuZ2UgKGRlYm91bmNlZClcbiAgICBsZXQgcG9ydENoZWNrVGltZW91dDtcbiAgICBwb3J0SW5wdXQub25pbnB1dCA9IGZ1bmN0aW9uKCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHBvcnRDaGVja1RpbWVvdXQpO1xuICAgICAgcG9ydENoZWNrVGltZW91dCA9IHNldFRpbWVvdXQoY2hlY2tBbmRVcGRhdGVQb3J0U3RhdHVzLCA1MDApO1xuICAgIH07XG5cbiAgICAvLyBJbml0aWFsIHBvcnQgY2hlY2tcbiAgICBjaGVja0FuZFVwZGF0ZVBvcnRTdGF0dXMoKTtcblxuICAgIC8vIEZldGNoIFRhaWxzY2FsZSBzdGF0dXNcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS90YWlsc2NhbGUvc3RhdHVzJyk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2VzcyAmJiBkYXRhLmluc3RhbGxlZCAmJiBkYXRhLmNvbm5lY3RlZCkge1xuICAgICAgICB0YWlsc2NhbGVTdGF0dXMuaW5uZXJIVE1MID0gYFxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6ICM0Y2FmNTA7XCI+Q29ubmVjdGVkPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWxlZnQ6IDhweDtcIj4ke2RhdGEuc2VsZj8uaG9zdG5hbWV9ICgke2RhdGEuc2VsZj8uaXB9KTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1sZWZ0OiA4cHg7XCI+fCAke2RhdGEuZGV2aWNlQ291bnR9IGRldmljZXM8L3NwYW4+XG4gICAgICAgIGA7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEuaW5zdGFsbGVkKSB7XG4gICAgICAgIHRhaWxzY2FsZVN0YXR1cy5pbm5lckhUTUwgPSBgPHNwYW4gc3R5bGU9XCJjb2xvcjogI2ZmOTgwMDtcIj5Ob3QgY29ubmVjdGVkPC9zcGFuPmA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YWlsc2NhbGVTdGF0dXMuaW5uZXJIVE1MID0gYDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj5Ob3QgYXZhaWxhYmxlPC9zcGFuPmA7XG4gICAgICAgIHRhaWxzY2FsZUNoZWNrYm94LmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0YWlsc2NhbGVTdGF0dXMuaW5uZXJIVE1MID0gYDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj5Db3VsZCBub3QgY2hlY2sgc3RhdHVzPC9zcGFuPmA7XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIFVSTCBwcmV2aWV3IGluIHJlYWwtdGltZVxuICAgIGZ1bmN0aW9uIHVwZGF0ZVVybFByZXZpZXcoKSB7XG4gICAgICBjb25zdCBzdWJkb21haW4gPSBzdWJkb21haW5JbnB1dC52YWx1ZSB8fCAnc3ViZG9tYWluJztcbiAgICAgIGNvbnN0IGRuc1R5cGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPVwiZG5zLXR5cGVcIl06Y2hlY2tlZCcpLnZhbHVlO1xuICAgICAgY29uc3Qgc3NsVHlwZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9XCJzc2wtdHlwZVwiXTpjaGVja2VkJykudmFsdWU7XG5cbiAgICAgIGxldCB1cmwgPSAnJztcbiAgICAgIGlmIChTSVRFLnJvdXRpbmdNb2RlID09PSAnc3ViZGlyZWN0b3J5JyAmJiBTSVRFLmRvbWFpbikge1xuICAgICAgICAvLyBTdWJkaXJlY3RvcnkgbW9kZTogZG9tYWluLmNvbS9hcHBcbiAgICAgICAgdXJsID0gYGh0dHBzOi8vJHtTSVRFLmRvbWFpbn0vJHtzdWJkb21haW59YDtcbiAgICAgIH0gZWxzZSBpZiAoZG5zVHlwZSA9PT0gJ3ByaXZhdGUnKSB7XG4gICAgICAgIGNvbnN0IHByb3RvY29sID0gc3NsVHlwZSA9PT0gJ25vbmUnID8gJ2h0dHAnIDogJ2h0dHBzJztcbiAgICAgICAgdXJsID0gYCR7cHJvdG9jb2x9Oi8vJHtidWlsZERvbWFpbihzdWJkb21haW4pfWA7XG4gICAgICB9IGVsc2UgaWYgKGRuc1R5cGUgPT09ICdwdWJsaWMnKSB7XG4gICAgICAgIGNvbnN0IHByb3RvY29sID0gc3NsVHlwZSA9PT0gJ25vbmUnID8gJ2h0dHAnIDogJ2h0dHBzJztcbiAgICAgICAgY29uc3QgZG9tYWluID0gU0lURS5kb21haW4gfHwgc3ViZG9tYWluO1xuICAgICAgICB1cmwgPSBTSVRFLmRvbWFpbiA/IGAke3Byb3RvY29sfTovLyR7c3ViZG9tYWlufS4ke1NJVEUuZG9tYWlufWAgOiBgJHtwcm90b2NvbH06Ly8ke3N1YmRvbWFpbn1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgcG9ydCA9IHBvcnRJbnB1dC52YWx1ZSB8fCBhcHBUZW1wbGF0ZS5kZWZhdWx0UG9ydCB8fCBEQy5ERUZBVUxUUy5TRVJWSUNFX1BPUlQ7XG4gICAgICAgIHVybCA9IGBodHRwOi8vJHtpcElucHV0LnZhbHVlfToke3BvcnR9YDtcbiAgICAgIH1cbiAgICAgIHVybFByZXZpZXcudGV4dENvbnRlbnQgPSB1cmw7XG4gICAgfVxuXG4gICAgLy8gQXR0YWNoIGxpc3RlbmVyc1xuICAgIHN1YmRvbWFpbklucHV0Lm9uaW5wdXQgPSB1cGRhdGVVcmxQcmV2aWV3O1xuICAgIGlwSW5wdXQub25pbnB1dCA9IHVwZGF0ZVVybFByZXZpZXc7XG4gICAgcG9ydElucHV0Lm9uaW5wdXQgPSB1cGRhdGVVcmxQcmV2aWV3O1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W25hbWU9XCJkbnMtdHlwZVwiXScpLmZvckVhY2gocmFkaW8gPT4ge1xuICAgICAgcmFkaW8ub25jaGFuZ2UgPSB1cGRhdGVVcmxQcmV2aWV3O1xuICAgIH0pO1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W25hbWU9XCJzc2wtdHlwZVwiXScpLmZvckVhY2gocmFkaW8gPT4ge1xuICAgICAgcmFkaW8ub25jaGFuZ2UgPSB1cGRhdGVVcmxQcmV2aWV3O1xuICAgIH0pO1xuXG4gICAgdXBkYXRlVXJsUHJldmlldygpO1xuXG4gICAgLy8gQ2xvc2UgYXBwIHNlbGVjdG9yLCBvcGVuIGRlcGxveSBjb25maWdcbiAgICBtb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gICAgZGVwbG95TW9kYWwuY2xhc3NMaXN0LmFkZCgnc2hvdycpO1xuXG4gICAgLy8gU3RvcmUgYXBwIHRlbXBsYXRlIGZvciBkZXBsb3ltZW50XG4gICAgZGVwbG95TW9kYWwuZGF0YXNldC5hcHBUZW1wbGF0ZSA9IEpTT04uc3RyaW5naWZ5KGFwcFRlbXBsYXRlKTtcbiAgfVxuXG4gIC8vIEFkZCBhcHAgdG8gZ3JpZCB3aXRoIGZ1bGwgRG9ja2VyIGRlcGxveW1lbnRcbiAgYXN5bmMgZnVuY3Rpb24gYWRkQXBwVG9HcmlkKGRlcGxveUNvbmZpZykge1xuICAgIGNvbnN0IGFwcFRlbXBsYXRlID0gZGVwbG95Q29uZmlnLmFwcFRlbXBsYXRlO1xuICAgIGNvbnN0IGN1c3RvbUFwcHMgPSBzYWZlR2V0SlNPTihBUFBTX0tFWSwgW10pO1xuXG4gICAgLy8gQ2hlY2sgaWYgdXNpbmcgZXhpc3RpbmcgY29udGFpbmVyXG4gICAgY29uc3QgdXNpbmdFeGlzdGluZyA9IGFwcFRlbXBsYXRlLl91c2VFeGlzdGluZyAmJiBhcHBUZW1wbGF0ZS5fZXhpc3RpbmdDb250YWluZXI7XG5cbiAgICAvLyBDaGVjayBpZiBhcHAgYWxyZWFkeSBleGlzdHMgLSBza2lwIGlmIHVzaW5nIGV4aXN0aW5nIGNvbnRhaW5lciAodXNlciBhbHJlYWR5IGNvbmZpcm1lZClcbiAgICBjb25zdCBleGlzdGluZ0FwcCA9IGN1c3RvbUFwcHMuZmluZChhID0+IGEuaWQgPT09IGRlcGxveUNvbmZpZy5zdWJkb21haW4pO1xuICAgIGlmIChleGlzdGluZ0FwcCAmJiAhdXNpbmdFeGlzdGluZykge1xuICAgICAgY29uc3QgY29uZmlybWVkID0gY29uZmlybShgQW4gYXBwIHdpdGggc3ViZG9tYWluIFwiJHtkZXBsb3lDb25maWcuc3ViZG9tYWlufVwiIGFscmVhZHkgZXhpc3RzLiBSZWRlcGxveT9gKTtcbiAgICAgIGlmICghY29uZmlybWVkKSByZXR1cm47XG4gICAgfVxuICAgIC8vIFJlbW92ZSBmcm9tIGxvY2FsU3RvcmFnZSB0byBhbGxvdyByZWRlcGxveW1lbnQvdXBkYXRlXG4gICAgaWYgKGV4aXN0aW5nQXBwKSB7XG4gICAgICBjb25zdCBpbmRleCA9IGN1c3RvbUFwcHMuaW5kZXhPZihleGlzdGluZ0FwcCk7XG4gICAgICBjdXN0b21BcHBzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICBzYWZlU2V0KEFQUFNfS0VZLCBKU09OLnN0cmluZ2lmeShjdXN0b21BcHBzKSk7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgcG9ydCBhdmFpbGFiaWxpdHkgYmVmb3JlIGRlcGxveW1lbnQgKHNraXAgaWYgdXNpbmcgZXhpc3RpbmcgY29udGFpbmVyKVxuICAgIGlmICghdXNpbmdFeGlzdGluZykge1xuICAgICAgY29uc3QgcG9ydFRvVXNlID0gZGVwbG95Q29uZmlnLnBvcnQgfHwgYXBwVGVtcGxhdGUuZGVmYXVsdFBvcnQgfHwgODA4MDtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oYENoZWNraW5nIHBvcnQgJHtwb3J0VG9Vc2V9IGF2YWlsYWJpbGl0eS4uLmAsICdpbmZvJywgMCk7XG5cbiAgICAgIGNvbnN0IHBvcnRDaGVjayA9IGF3YWl0IGNoZWNrUG9ydEF2YWlsYWJpbGl0eShwb3J0VG9Vc2UpO1xuICAgICAgaWYgKCFwb3J0Q2hlY2suYXZhaWxhYmxlKSB7XG4gICAgICAgIGNvbnN0IHN1Z2dlc3RlZFBvcnQgPSBhd2FpdCBnZXRTdWdnZXN0ZWRQb3J0KGFwcFRlbXBsYXRlLmRlZmF1bHRQb3J0IHx8IDgwODApO1xuICAgICAgICBjb25zdCB1c2VBbHRlcm5hdGUgPSBjb25maXJtKFxuICAgICAgICAgIGBQb3J0ICR7cG9ydFRvVXNlfSBpcyBhbHJlYWR5IGluIHVzZSBieSAke3BvcnRDaGVjay5jb25mbGljdD8udXNlZEJ5IHx8ICdhbm90aGVyIGNvbnRhaW5lcid9LlxcblxcbmAgK1xuICAgICAgICAgIGBXb3VsZCB5b3UgbGlrZSB0byB1c2UgcG9ydCAke3N1Z2dlc3RlZFBvcnR9IGluc3RlYWQ/YFxuICAgICAgICApO1xuICAgICAgICBpZiAodXNlQWx0ZXJuYXRlKSB7XG4gICAgICAgICAgZGVwbG95Q29uZmlnLnBvcnQgPSBzdWdnZXN0ZWRQb3J0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNob3dOb3RpZmljYXRpb24oJ0RlcGxveW1lbnQgY2FuY2VsbGVkIC0gcG9ydCBjb25mbGljdCcsICdlcnJvcicsIDUwMDApO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBVc2UgZXhpc3RpbmcgY29udGFpbmVyJ3MgcG9ydFxuICAgICAgZGVwbG95Q29uZmlnLnBvcnQgPSBhcHBUZW1wbGF0ZS5fZXhpc3RpbmdDb250YWluZXIucHJpbWFyeVBvcnQ7XG4gICAgfVxuICAgIHNob3dOb3RpZmljYXRpb24oXG4gICAgICB1c2luZ0V4aXN0aW5nXG4gICAgICAgID8gYENvbmZpZ3VyaW5nICR7YXBwVGVtcGxhdGUubmFtZX0gd2l0aCBleGlzdGluZyBjb250YWluZXIuLi5gXG4gICAgICAgIDogYERlcGxveWluZyAke2FwcFRlbXBsYXRlLm5hbWV9Li4uYCxcbiAgICAgICdpbmZvJywgMFxuICAgICk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gUHJlcGFyZSBkZXBsb3ltZW50IGNvbmZpZyBmcm9tIHVzZXIncyBjaG9pY2VzXG4gICAgICBjb25zdCBhcGlEZXBsb3lDb25maWcgPSB7XG4gICAgICAgIGFwcElkOiBhcHBUZW1wbGF0ZS5pZCxcbiAgICAgICAgY29uZmlnOiB7XG4gICAgICAgICAgc3ViZG9tYWluOiBkZXBsb3lDb25maWcuc3ViZG9tYWluLFxuICAgICAgICAgIGlwOiBkZXBsb3lDb25maWcuaXAsXG4gICAgICAgICAgY3JlYXRlRG5zOiBkZXBsb3lDb25maWcuZG5zVHlwZSA9PT0gJ3ByaXZhdGUnLCAgLy8gT25seSBjcmVhdGUgRE5TIGZvciBwcml2YXRlXG4gICAgICAgICAgcG9ydDogZGVwbG95Q29uZmlnLnBvcnQgfHwgYXBwVGVtcGxhdGUuZGVmYXVsdFBvcnQgfHwgbnVsbCwgIC8vIFVzZSBjdXN0b20sIHRlbXBsYXRlIGRlZmF1bHQsIG9yIG51bGxcbiAgICAgICAgICBzc2xUeXBlOiBkZXBsb3lDb25maWcuc3NsVHlwZSxcbiAgICAgICAgICBkbnNUeXBlOiBkZXBsb3lDb25maWcuZG5zVHlwZSxcbiAgICAgICAgICB0YWlsc2NhbGVPbmx5OiBkZXBsb3lDb25maWcudGFpbHNjYWxlT25seSB8fCBmYWxzZSwgIC8vIFRhaWxzY2FsZS1vbmx5IGFjY2VzcyByZXN0cmljdGlvblxuICAgICAgICAgIG1lZGlhUGF0aDogZGVwbG95Q29uZmlnLm1lZGlhUGF0aCB8fCBudWxsLCAgLy8gTWVkaWEgZm9sZGVyIHBhdGggZm9yIG1lZGlhIGFwcHNcbiAgICAgICAgICBwbGV4Q2xhaW1Ub2tlbjogZGVwbG95Q29uZmlnLnBsZXhDbGFpbVRva2VuIHx8IG51bGwsICAvLyBQbGV4IGNsYWltIHRva2VuIGZvciBhdXRvLWNsYWltXG4gICAgICAgICAgY3VzdG9tVm9sdW1lczogZGVwbG95Q29uZmlnLmN1c3RvbVZvbHVtZXMgfHwgbnVsbCAgLy8gQ3VzdG9tIHZvbHVtZSBtb3VudCBvdmVycmlkZXNcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgLy8gQWRkIGV4aXN0aW5nIGNvbnRhaW5lciBpbmZvIGlmIHVzaW5nIGV4aXN0aW5nXG4gICAgICBpZiAodXNpbmdFeGlzdGluZykge1xuICAgICAgICBhcGlEZXBsb3lDb25maWcuY29uZmlnLnVzZUV4aXN0aW5nID0gdHJ1ZTtcbiAgICAgICAgYXBpRGVwbG95Q29uZmlnLmNvbmZpZy5leGlzdGluZ0NvbnRhaW5lcklkID0gYXBwVGVtcGxhdGUuX2V4aXN0aW5nQ29udGFpbmVyLmlkO1xuICAgICAgICBhcGlEZXBsb3lDb25maWcuY29uZmlnLmV4aXN0aW5nUG9ydCA9IGFwcFRlbXBsYXRlLl9leGlzdGluZ0NvbnRhaW5lci5wcmltYXJ5UG9ydDtcbiAgICAgICAgLy8gVXNlIGV4aXN0aW5nIGNvbnRhaW5lcidzIHBvcnQgaWYgbm8gY3VzdG9tIHBvcnQgc3BlY2lmaWVkXG4gICAgICAgIGlmICghZGVwbG95Q29uZmlnLnBvcnQgJiYgYXBwVGVtcGxhdGUuX2V4aXN0aW5nQ29udGFpbmVyLnByaW1hcnlQb3J0KSB7XG4gICAgICAgICAgYXBpRGVwbG95Q29uZmlnLmNvbmZpZy5wb3J0ID0gYXBwVGVtcGxhdGUuX2V4aXN0aW5nQ29udGFpbmVyLnByaW1hcnlQb3J0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIENhbGwgZGVwbG95bWVudCBBUElcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvYXBwcy9kZXBsb3knLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoYXBpRGVwbG95Q29uZmlnKVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIC8vIEFkZCB0byBzYXZlZCBhcHBzIChzdG9yZSBJUCBmb3IgbGF0ZXIgZGVsZXRpb24pXG4gICAgICAgIGNvbnN0IG5ld0FwcCA9IHtcbiAgICAgICAgICBpZDogZGVwbG95Q29uZmlnLnN1YmRvbWFpbiwgIC8vIFVzZSBzdWJkb21haW4gYXMgSURcbiAgICAgICAgICBuYW1lOiBhcHBUZW1wbGF0ZS5uYW1lLFxuICAgICAgICAgIGxvZ286IGAvYXNzZXRzLyR7YXBwVGVtcGxhdGUuaWR9LnBuZ2AsXG4gICAgICAgICAgY29udGFpbmVySWQ6IHJlc3VsdC5jb250YWluZXJJZCxcbiAgICAgICAgICB1cmw6IHJlc3VsdC51cmwsXG4gICAgICAgICAgaXA6IGRlcGxveUNvbmZpZy5pcCwgIC8vIFN0b3JlIElQIGZvciBETlMgcmVjb3JkIGRlbGV0aW9uXG4gICAgICAgICAgYXBwVGVtcGxhdGU6IGFwcFRlbXBsYXRlLmlkLCAgLy8gU3RvcmUgb3JpZ2luYWwgdGVtcGxhdGUgSURcbiAgICAgICAgICB0YWlsc2NhbGVPbmx5OiBkZXBsb3lDb25maWcudGFpbHNjYWxlT25seSB8fCBmYWxzZSAgLy8gVGFpbHNjYWxlIHByb3RlY3Rpb24gc3RhdHVzXG4gICAgICAgIH07XG4gICAgICAgIGN1c3RvbUFwcHMucHVzaChuZXdBcHApO1xuICAgICAgICBzYWZlU2V0KEFQUFNfS0VZLCBKU09OLnN0cmluZ2lmeShjdXN0b21BcHBzKSk7XG5cbiAgICAgICAgLy8gQWRkIHRvIEFQUFMgYXJyYXkgYW5kIHJlYnVpbGQgZ3JpZFxuICAgICAgICAvLyBBY2Nlc3MgQVBQUyBmcm9tIHBhcmVudCBzY29wZSB2aWEgd2luZG93XG4gICAgICAgIGlmICh3aW5kb3cuQVBQUyAmJiAhd2luZG93LkFQUFMuc29tZShhID0+IGEuaWQgPT09IGFwcFRlbXBsYXRlLmlkKSkge1xuICAgICAgICAgIHdpbmRvdy5BUFBTLnB1c2gobmV3QXBwKTtcbiAgICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5idWlsZEdyaWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHdpbmRvdy5idWlsZEdyaWQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cucmVmcmVzaEFsbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB3aW5kb3cucmVmcmVzaEFsbCgpLCA1MDApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNob3cgc3VjY2VzcyB3aXRoIFVSTCAoYW5kIHdhcm5pbmcgaWYgRE5TIGZhaWxlZClcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSByZXN1bHQudXNlZEV4aXN0aW5nXG4gICAgICAgICAgPyBgJHthcHBUZW1wbGF0ZS5uYW1lfSBjb25maWd1cmVkIHdpdGggZXhpc3RpbmcgY29udGFpbmVyIVxcblVSTDogJHtyZXN1bHQudXJsfWBcbiAgICAgICAgICA6IGAke2FwcFRlbXBsYXRlLm5hbWV9IGRlcGxveWVkIHN1Y2Nlc3NmdWxseSFcXG5VUkw6ICR7cmVzdWx0LnVybH1gO1xuICAgICAgICBpZiAocmVzdWx0Lndhcm5pbmcpIHtcbiAgICAgICAgICBtZXNzYWdlICs9IGBcXG5cXG5cdTI2QTAgV2FybmluZzogJHtyZXN1bHQud2FybmluZ31gO1xuICAgICAgICB9XG5cbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbihtZXNzYWdlLCAnc3VjY2VzcycsIDgwMDApO1xuXG4gICAgICAgIC8vIENsZWFuIHVwIHRlbXBvcmFyeSBwcm9wZXJ0aWVzXG4gICAgICAgIGRlbGV0ZSBhcHBUZW1wbGF0ZS5fdXNlRXhpc3Rpbmc7XG4gICAgICAgIGRlbGV0ZSBhcHBUZW1wbGF0ZS5fZXhpc3RpbmdDb250YWluZXI7XG4gICAgICAgIFxuICAgICAgICAvLyBGb3IgSFRUUFMgVVJMcywgY2hlY2sgU1NMIGNlcnRpZmljYXRlIHN0YXR1c1xuICAgICAgICBpZiAocmVzdWx0LnVybCAmJiByZXN1bHQudXJsLnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJykpIHtcbiAgICAgICAgICBjaGVja1NTTENlcnRpZmljYXRlKHJlc3VsdC51cmwsIGFwcFRlbXBsYXRlLm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2hvdyBzZXR1cCBpbnN0cnVjdGlvbnMgaWYgYXZhaWxhYmxlXG4gICAgICAgIGlmIChyZXN1bHQuc2V0dXBJbnN0cnVjdGlvbnMgJiYgcmVzdWx0LnNldHVwSW5zdHJ1Y3Rpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IHJlc3VsdC5zZXR1cEluc3RydWN0aW9ucy5qb2luKCdcXG4nKTtcbiAgICAgICAgICAgIHNob3dOb3RpZmljYXRpb24oYFNldHVwIEluc3RydWN0aW9ucyBmb3IgJHthcHBUZW1wbGF0ZS5uYW1lfTogJHtpbnN0cnVjdGlvbnN9YCwgJ2luZm8nLCAxMDAwMCk7XG4gICAgICAgICAgfSwgMTAwMCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihyZXN1bHQuZXJyb3IgfHwgJ0RlcGxveW1lbnQgZmFpbGVkJyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGVycm9ySGFuZGxlci5sb2dFcnJvcignW0FwcFNlbGVjdG9yXSBEZXBsb3ltZW50JywgZXJyb3IsIHsgZnVuY3Rpb246ICdkZXBsb3knIH0pO1xuICAgICAgc2hvd05vdGlmaWNhdGlvbihcbiAgICAgICAgYEZhaWxlZCB0byBkZXBsb3kgJHthcHBUZW1wbGF0ZS5uYW1lfTogJHtlcnJvci5tZXNzYWdlfWAsXG4gICAgICAgICdlcnJvcicsXG4gICAgICAgIDgwMDBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgU1NMIGNlcnRpZmljYXRlIHN0YXR1cyBhbmQgbm90aWZ5IHdoZW4gcmVhZHlcbiAgYXN5bmMgZnVuY3Rpb24gY2hlY2tTU0xDZXJ0aWZpY2F0ZSh1cmwsIGFwcE5hbWUpIHtcbiAgICBzaG93Tm90aWZpY2F0aW9uKGBcdTIzRjMgR2VuZXJhdGluZyBTU0wgY2VydGlmaWNhdGUgZm9yICR7YXBwTmFtZX0uLi5gLCAnd2FybmluZycsIDYwMDAwKTtcbiAgICBcbiAgICBsZXQgYXR0ZW1wdHMgPSAwO1xuICAgIGNvbnN0IG1heEF0dGVtcHRzID0gMTI7IC8vIDYwIHNlY29uZHMgdG90YWwgKDUgc2Vjb25kIGludGVydmFscylcbiAgICBcbiAgICBjb25zdCBjaGVja0NlcnQgPSBhc3luYyAoKSA9PiB7XG4gICAgICBhdHRlbXB0cysrO1xuICAgICAgXG4gICAgICB0cnkge1xuICAgICAgICAvLyBUcnkgdG8gZmV0Y2ggdGhlIFVSTCAtIGlmIFNTTCB3b3JrcywgdGhpcyB3aWxsIHN1Y2NlZWRcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIHsgXG4gICAgICAgICAgbWV0aG9kOiAnSEVBRCcsXG4gICAgICAgICAgbW9kZTogJ25vLWNvcnMnIC8vIEF2b2lkIENPUlMgaXNzdWVzXG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgLy8gSWYgd2UgZ2V0IGhlcmUsIFNTTCBpcyB3b3JraW5nXG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oYFx1MjcwNSAke2FwcE5hbWV9IGlzIHJlYWR5ISBTU0wgY2VydGlmaWNhdGUgZ2VuZXJhdGVkLmAsICdzdWNjZXNzJywgNTAwMCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gU1NMIG5vdCByZWFkeSB5ZXRcbiAgICAgICAgaWYgKGF0dGVtcHRzIDwgbWF4QXR0ZW1wdHMpIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KGNoZWNrQ2VydCwgNTAwMCk7IC8vIENoZWNrIGFnYWluIGluIDUgc2Vjb25kc1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNob3dOb3RpZmljYXRpb24oXG4gICAgICAgICAgICBgXHUyNkEwXHVGRTBGICR7YXBwTmFtZX0gZGVwbG95ZWQgYnV0IFNTTCBjZXJ0aWZpY2F0ZSBtYXkgc3RpbGwgYmUgZ2VuZXJhdGluZy5cXG5UcnkgcmVmcmVzaGluZyBpbiBhIG1vbWVudCBpZiB5b3Ugc2VlIGEgY2VydGlmaWNhdGUgZXJyb3IuYCxcbiAgICAgICAgICAgICd3YXJuaW5nJyxcbiAgICAgICAgICAgIDEwMDAwXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfTtcbiAgICBcbiAgICAvLyBTdGFydCBjaGVja2luZyBhZnRlciAzIHNlY29uZHMgKGdpdmUgQ2FkZHkgdGltZSB0byBzdGFydClcbiAgICBzZXRUaW1lb3V0KGNoZWNrQ2VydCwgMzAwMCk7XG4gIH1cblxuICAvLyBMb2FkIGN1c3RvbSBhcHBzIG9uIHN0YXJ0dXBcbiAgZnVuY3Rpb24gbG9hZEN1c3RvbUFwcHMoKSB7XG4gICAgY29uc3QgY3VzdG9tQXBwcyA9IHNhZmVHZXRKU09OKEFQUFNfS0VZLCBbXSk7XG4gICAgY3VzdG9tQXBwcy5mb3JFYWNoKGFwcCA9PiB7XG4gICAgICBpZiAoIXdpbmRvdy5BUFBTLnNvbWUoYSA9PiBhLmlkID09PSBhcHAuaWQpKSB7XG4gICAgICAgIHdpbmRvdy5BUFBTLnB1c2goYXBwKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIEV2ZW50IGxpc3RlbmVyc1xuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYWRkLXNlcnZpY2UtYnRuJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIGJ1aWxkQXBwU2VsZWN0b3IoKTtcbiAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gIH0pO1xuXG4gIHdpcmVNb2RhbChtb2RhbCwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcC1zZWxlY3Rvci1jYW5jZWwnKSk7XG5cbiAgLy8gRGVwbG95IG1vZGFsIGV2ZW50IGxpc3RlbmVyc1xuICBjb25zdCBkZXBsb3lNb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcHAtZGVwbG95LW1vZGFsJyk7XG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcC1kZXBsb3ktY2FuY2VsJyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIGRlcGxveU1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcbiAgfSk7XG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcC1kZXBsb3ktY29uZmlybScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAvLyBHZXQgdXNlciBjb25maWd1cmF0aW9uXG4gICAgY29uc3QgYXBwVGVtcGxhdGUgPSBKU09OLnBhcnNlKGRlcGxveU1vZGFsLmRhdGFzZXQuYXBwVGVtcGxhdGUpO1xuICAgIGNvbnN0IG1lZGlhUGF0aCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktbWVkaWEtcGF0aCcpLnZhbHVlLnRyaW0oKTtcblxuICAgIC8vIENvbGxlY3QgY3VzdG9tIHZvbHVtZSBvdmVycmlkZXNcbiAgICBjb25zdCBjdXN0b21Wb2x1bWVzID0gW107XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI3ZvbHVtZS1tb3VudHMtbGlzdCAudm9sLWhvc3QtcGF0aCcpLmZvckVhY2goaW5wdXQgPT4ge1xuICAgICAgY3VzdG9tVm9sdW1lcy5wdXNoKHsgaG9zdFBhdGg6IGlucHV0LnZhbHVlLnRyaW0oKSwgY29udGFpbmVyUGF0aDogaW5wdXQuZGF0YXNldC5jb250YWluZXJQYXRoIH0pO1xuICAgIH0pO1xuXG4gICAgY29uc3QgZGVwbG95Q29uZmlnID0ge1xuICAgICAgYXBwVGVtcGxhdGU6IGFwcFRlbXBsYXRlLFxuICAgICAgc3ViZG9tYWluOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGVwbG95LXN1YmRvbWFpbicpLnZhbHVlLnRyaW0oKSxcbiAgICAgIGRuc1R5cGU6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9XCJkbnMtdHlwZVwiXTpjaGVja2VkJykudmFsdWUsXG4gICAgICBzc2xUeXBlOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPVwic3NsLXR5cGVcIl06Y2hlY2tlZCcpLnZhbHVlLFxuICAgICAgaXA6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZXBsb3ktaXAnKS52YWx1ZS50cmltKCksXG4gICAgICBwb3J0OiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGVwbG95LXBvcnQnKS52YWx1ZS50cmltKCksXG4gICAgICB0YWlsc2NhbGVPbmx5OiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGVwbG95LXRhaWxzY2FsZS1vbmx5JykuY2hlY2tlZCxcbiAgICAgIG1lZGlhUGF0aDogbWVkaWFQYXRoIHx8IG51bGwsXG4gICAgICBwbGV4Q2xhaW1Ub2tlbjogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS1wbGV4LWNsYWltJyk/LnZhbHVlLnRyaW0oKSB8fCBudWxsLFxuICAgICAgY3VzdG9tVm9sdW1lczogY3VzdG9tVm9sdW1lcy5sZW5ndGggPiAwID8gY3VzdG9tVm9sdW1lcyA6IG51bGwsXG4gICAgICByZXNvdXJjZXM6IHtcbiAgICAgICAgY3B1czogcGFyc2VGbG9hdChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGVwbG95LWNwdS1saW1pdCcpLnZhbHVlKSB8fCAwLFxuICAgICAgICBtZW1vcnk6IHBhcnNlRmxvYXQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RlcGxveS1tZW1vcnktbGltaXQnKS52YWx1ZSkgfHwgMCxcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gVmFsaWRhdGUgc3ViZG9tYWluXG4gICAgaWYgKCFkZXBsb3lDb25maWcuc3ViZG9tYWluKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKCdQbGVhc2UgZW50ZXIgYSBzdWJkb21haW4gb3IgZG9tYWluIG5hbWUnLCAnd2FybmluZycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIG1lZGlhIHBhdGggZm9yIG1lZGlhIGFwcHNcbiAgICBpZiAoYXBwVGVtcGxhdGUubWVkaWFNb3VudD8ucmVxdWlyZWQgJiYgIW1lZGlhUGF0aCkge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbignUGxlYXNlIGVudGVyIGEgbWVkaWEgbGlicmFyeSBwYXRoIGZvciB0aGlzIGFwcGxpY2F0aW9uJywgJ3dhcm5pbmcnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDbG9zZSBkZXBsb3kgbW9kYWxcbiAgICBkZXBsb3lNb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG5cbiAgICAvLyBTdGFydCBkZXBsb3ltZW50XG4gICAgYWRkQXBwVG9HcmlkKGRlcGxveUNvbmZpZyk7XG4gIH0pO1xuXG4gIHdpcmVNb2RhbChkZXBsb3lNb2RhbCk7XG5cbiAgLy8gPT09PT0gRk9MREVSIEJST1dTRVIgRlVOQ1RJT05BTElUWSA9PT09PVxuICBjb25zdCBmb2xkZXJCcm93c2VyTW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZm9sZGVyLWJyb3dzZXItbW9kYWwnKTtcbiAgY29uc3QgZm9sZGVyQnJvd3NlclBhdGggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZm9sZGVyLWJyb3dzZXItcGF0aCcpO1xuICBjb25zdCBmb2xkZXJCcm93c2VyTGlzdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmb2xkZXItYnJvd3Nlci1saXN0Jyk7XG4gIGNvbnN0IGZvbGRlckJyb3dzZXJTZWxlY3RlZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmb2xkZXItYnJvd3Nlci1zZWxlY3RlZCcpO1xuICBjb25zdCBmb2xkZXJCcm93c2VyU2VsZWN0ZWRMaXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZvbGRlci1icm93c2VyLXNlbGVjdGVkLWxpc3QnKTtcbiAgbGV0IGN1cnJlbnRCcm93c2VyUGF0aCA9ICcnO1xuICBsZXQgc2VsZWN0ZWRGb2xkZXJzID0gW107XG4gIGxldCB0YXJnZXRNZWRpYUlucHV0ID0gbnVsbDtcblxuICB3aW5kb3cub3BlbkZvbGRlckJyb3dzZXIgPSBmdW5jdGlvbihtZWRpYUlucHV0KSB7XG4gICAgdGFyZ2V0TWVkaWFJbnB1dCA9IG1lZGlhSW5wdXQ7XG4gICAgc2VsZWN0ZWRGb2xkZXJzID0gbWVkaWFJbnB1dC52YWx1ZS5zcGxpdCgnLCcpLm1hcChwID0+IHAudHJpbSgpKS5maWx0ZXIocCA9PiBwKTtcbiAgICBjdXJyZW50QnJvd3NlclBhdGggPSAnJztcbiAgICB1cGRhdGVTZWxlY3RlZEZvbGRlcnNEaXNwbGF5KCk7XG4gICAgbG9hZEZvbGRlckNvbnRlbnRzKCcnKTtcbiAgICBmb2xkZXJCcm93c2VyTW9kYWwuY2xhc3NMaXN0LmFkZCgnc2hvdycpO1xuICB9O1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWRGb2xkZXJDb250ZW50cyhwYXRoKSB7XG4gICAgZm9sZGVyQnJvd3NlclBhdGgudGV4dENvbnRlbnQgPSBwYXRoIHx8ICdTZWxlY3QgYSBkcml2ZS4uLic7XG4gICAgZm9sZGVyQnJvd3Nlckxpc3QuaW5uZXJIVE1MID0gJzxkaXYgc3R5bGU9XCJwYWRkaW5nOiAyMHB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+TG9hZGluZy4uLjwvZGl2Pic7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgL2FwaS92MS9icm93c2UvZGlyZWN0b3JpZXM/cGF0aD0ke2VuY29kZVVSSUNvbXBvbmVudChwYXRoKX1gKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgaWYgKCFyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICBmb2xkZXJCcm93c2VyTGlzdC5pbm5lckhUTUwgPSBgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDIwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsgY29sb3I6IHZhcigtLWVycm9yKTtcIj5FcnJvcjogJHtlc2NhcGVIdG1sKHJlc3VsdC5lcnJvcil9PC9kaXY+YDtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50QnJvd3NlclBhdGggPSByZXN1bHQucGF0aCB8fCAnJztcbiAgICAgIGZvbGRlckJyb3dzZXJQYXRoLnRleHRDb250ZW50ID0gY3VycmVudEJyb3dzZXJQYXRoIHx8ICdTZWxlY3QgYSBkcml2ZS4uLic7XG5cbiAgICAgIGxldCBodG1sID0gJyc7XG5cbiAgICAgIC8vIEFkZCBwYXJlbnQgZm9sZGVyIG5hdmlnYXRpb25cbiAgICAgIGlmIChyZXN1bHQucGFyZW50ICYmIHJlc3VsdC5wYXJlbnQgIT09IHJlc3VsdC5wYXRoKSB7XG4gICAgICAgIGh0bWwgKz0gYDxkaXYgY2xhc3M9XCJmb2xkZXItaXRlbVwiIGRhdGEtcGF0aD1cIiR7ZXNjYXBlSHRtbChyZXN1bHQucGFyZW50KX1cIiBzdHlsZT1cInBhZGRpbmc6IDEycHggMTZweDsgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGN1cnNvcjogcG9pbnRlcjsgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiAxMHB4O1wiPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAxLjJyZW07XCI+XHUyQjA2XHVGRTBGPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj4uLiBQYXJlbnQgRGlyZWN0b3J5PC9zcGFuPlxuICAgICAgICA8L2Rpdj5gO1xuICAgICAgfVxuXG4gICAgICAvLyBBZGQgZm9sZGVyc1xuICAgICAgaWYgKHJlc3VsdC5pdGVtcy5sZW5ndGggPT09IDAgJiYgIXJlc3VsdC5wYXJlbnQpIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cInBhZGRpbmc6IDIwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5ObyBicm93c2VhYmxlIGRyaXZlcyBjb25maWd1cmVkLiBDaGVjayB5b3VyIGRvY2tlci1jb21wb3NlLnltbCB2b2x1bWUgbW91bnRzLjwvZGl2Pic7XG4gICAgICB9IGVsc2UgaWYgKHJlc3VsdC5pdGVtcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cInBhZGRpbmc6IDIwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5ObyBzdWJmb2xkZXJzIGZvdW5kPC9kaXY+JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdC5pdGVtcy5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgIGNvbnN0IGljb24gPSBpdGVtLnR5cGUgPT09ICdkcml2ZScgPyAnXHVEODNEXHVEQ0JFJyA6ICdcdUQ4M0RcdURDQzEnO1xuICAgICAgICAgIGNvbnN0IGlzU2VsZWN0ZWQgPSBzZWxlY3RlZEZvbGRlcnMuaW5jbHVkZXMoaXRlbS5wYXRoKTtcbiAgICAgICAgICBjb25zdCBzZWxlY3RlZFN0eWxlID0gaXNTZWxlY3RlZCA/ICdiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tc3VjY2VzcykgMjAlLCB0cmFuc3BhcmVudCk7JyA6ICcnO1xuICAgICAgICAgIGh0bWwgKz0gYDxkaXYgY2xhc3M9XCJmb2xkZXItaXRlbVwiIGRhdGEtcGF0aD1cIiR7ZXNjYXBlSHRtbChpdGVtLnBhdGgpfVwiIHN0eWxlPVwicGFkZGluZzogMTJweCAxNnB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgY3Vyc29yOiBwb2ludGVyOyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDEwcHg7ICR7c2VsZWN0ZWRTdHlsZX1cIj5cbiAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAxLjJyZW07XCI+JHtpY29ufTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZmxleDogMTtcIj4ke2VzY2FwZUh0bWwoaXRlbS5uYW1lKX08L3NwYW4+XG4gICAgICAgICAgICAke2lzU2VsZWN0ZWQgPyAnPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tc3VjY2Vzcyk7XCI+XHUyNzEzPC9zcGFuPicgOiAnJ31cbiAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgZm9sZGVyQnJvd3Nlckxpc3QuaW5uZXJIVE1MID0gaHRtbDtcblxuICAgICAgLy8gQWRkIGNsaWNrIGhhbmRsZXJzXG4gICAgICBmb2xkZXJCcm93c2VyTGlzdC5xdWVyeVNlbGVjdG9yQWxsKCcuZm9sZGVyLWl0ZW0nKS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICBpdGVtLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgIGxvYWRGb2xkZXJDb250ZW50cyhpdGVtLmRhdGFzZXQucGF0aCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdGVtLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCAoKSA9PiB7XG4gICAgICAgICAgaXRlbS5zdHlsZS5iYWNrZ3JvdW5kID0gJ3ZhcigtLWNhcmQtYmcpJztcbiAgICAgICAgfSk7XG4gICAgICAgIGl0ZW0uYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsICgpID0+IHtcbiAgICAgICAgICBjb25zdCBpc1NlbGVjdGVkID0gc2VsZWN0ZWRGb2xkZXJzLmluY2x1ZGVzKGl0ZW0uZGF0YXNldC5wYXRoKTtcbiAgICAgICAgICBpdGVtLnN0eWxlLmJhY2tncm91bmQgPSBpc1NlbGVjdGVkID8gJ2NvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1zdWNjZXNzKSAyMCUsIHRyYW5zcGFyZW50KScgOiAnJztcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBmb2xkZXJCcm93c2VyTGlzdC5pbm5lckhUTUwgPSBgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDIwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsgY29sb3I6IHZhcigtLWVycm9yKTtcIj5GYWlsZWQgdG8gbG9hZDogJHtlc2NhcGVIdG1sKGVycm9yLm1lc3NhZ2UpfTwvZGl2PmA7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlU2VsZWN0ZWRGb2xkZXJzRGlzcGxheSgpIHtcbiAgICBpZiAoc2VsZWN0ZWRGb2xkZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZm9sZGVyQnJvd3NlclNlbGVjdGVkLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvbGRlckJyb3dzZXJTZWxlY3RlZC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICBmb2xkZXJCcm93c2VyU2VsZWN0ZWRMaXN0LmlubmVySFRNTCA9IHNlbGVjdGVkRm9sZGVycy5tYXAocGF0aCA9PiBgXG4gICAgICA8c3BhbiBzdHlsZT1cInBhZGRpbmc6IDZweCAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tc3VjY2Vzcyk7IGJvcmRlci1yYWRpdXM6IDRweDsgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA2cHg7XCI+XG4gICAgICAgICR7ZXNjYXBlSHRtbChwYXRoKX1cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgb25jbGljaz1cInJlbW92ZVNlbGVjdGVkRm9sZGVyKCcke2VzY2FwZUh0bWwocGF0aCl9JylcIiBzdHlsZT1cImJhY2tncm91bmQ6IG5vbmU7IGJvcmRlcjogbm9uZTsgY3Vyc29yOiBwb2ludGVyOyBjb2xvcjogdmFyKC0tZXJyb3IpOyBmb250LXNpemU6IDFyZW07IHBhZGRpbmc6IDA7XCI+XHUwMEQ3PC9idXR0b24+XG4gICAgICA8L3NwYW4+XG4gICAgYCkuam9pbignJyk7XG4gIH1cblxuICB3aW5kb3cucmVtb3ZlU2VsZWN0ZWRGb2xkZXIgPSBmdW5jdGlvbihwYXRoKSB7XG4gICAgc2VsZWN0ZWRGb2xkZXJzID0gc2VsZWN0ZWRGb2xkZXJzLmZpbHRlcihwID0+IHAgIT09IHBhdGgpO1xuICAgIHVwZGF0ZVNlbGVjdGVkRm9sZGVyc0Rpc3BsYXkoKTtcbiAgICBsb2FkRm9sZGVyQ29udGVudHMoY3VycmVudEJyb3dzZXJQYXRoKTsgLy8gUmVmcmVzaCB0byB1cGRhdGUgY2hlY2ttYXJrc1xuICB9O1xuXG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmb2xkZXItYnJvd3Nlci1zZWxlY3QtY3VycmVudCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIGlmIChjdXJyZW50QnJvd3NlclBhdGggJiYgIXNlbGVjdGVkRm9sZGVycy5pbmNsdWRlcyhjdXJyZW50QnJvd3NlclBhdGgpKSB7XG4gICAgICBzZWxlY3RlZEZvbGRlcnMucHVzaChjdXJyZW50QnJvd3NlclBhdGgpO1xuICAgICAgdXBkYXRlU2VsZWN0ZWRGb2xkZXJzRGlzcGxheSgpO1xuICAgICAgbG9hZEZvbGRlckNvbnRlbnRzKGN1cnJlbnRCcm93c2VyUGF0aCk7IC8vIFJlZnJlc2ggdG8gc2hvdyBjaGVja21hcmtcbiAgICB9XG4gIH0pO1xuXG4gIHdpcmVNb2RhbChmb2xkZXJCcm93c2VyTW9kYWwsIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmb2xkZXItYnJvd3Nlci1jYW5jZWwnKSk7XG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZvbGRlci1icm93c2VyLWRvbmUnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBpZiAodGFyZ2V0TWVkaWFJbnB1dCkge1xuICAgICAgdGFyZ2V0TWVkaWFJbnB1dC52YWx1ZSA9IHNlbGVjdGVkRm9sZGVycy5qb2luKCcsICcpO1xuICAgIH1cbiAgICBmb2xkZXJCcm93c2VyTW9kYWwuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICB9KTtcblxuICAvLyBMb2FkIGN1c3RvbSBhcHBzIG9uIHBhZ2UgbG9hZFxuICBsb2FkQ3VzdG9tQXBwcygpO1xufSkoKTtcbjtcbi8vIFJlY2lwZSBTeXN0ZW0gXHUyMDE0IG11bHRpLWNvbnRhaW5lciBzdGFjayBkZXBsb3ltZW50XG4oZnVuY3Rpb24oKSB7XG4gIC8vID09PSBSRUNJUEUgREVQTE9ZIFdJWkFSRCBNT0RBTCA9PT1cbiAgaW5qZWN0TW9kYWwoJ3JlY2lwZS1kZXBsb3ktbW9kYWwnLCBgPGRpdiBpZD1cInJlY2lwZS1kZXBsb3ktbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1jb250ZW50XCIgc3R5bGU9XCJtaW4td2lkdGg6IDYyMHB4OyBtYXgtd2lkdGg6IDc0MHB4O1wiPlxuICAgICAgPGgzIGlkPVwicmVjaXBlLWRlcGxveS10aXRsZVwiPkRlcGxveSBSZWNpcGU8L2gzPlxuXG4gICAgICA8IS0tIFN0ZXAgaW5kaWNhdG9yIC0tPlxuICAgICAgPGRpdiBpZD1cInJlY2lwZS1zdGVwc1wiIHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiA0cHg7IG1hcmdpbjogMTZweCAwIDI0cHg7XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyZWNpcGUtc3RlcCBhY3RpdmVcIiBkYXRhLXN0ZXA9XCIxXCI+PHNwYW4+MTwvc3Bhbj4gQ29tcG9uZW50czwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwicmVjaXBlLXN0ZXBcIiBkYXRhLXN0ZXA9XCIyXCI+PHNwYW4+Mjwvc3Bhbj4gQ29uZmlndXJhdGlvbjwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwicmVjaXBlLXN0ZXBcIiBkYXRhLXN0ZXA9XCIzXCI+PHNwYW4+Mzwvc3Bhbj4gUmV2aWV3PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyZWNpcGUtc3RlcFwiIGRhdGEtc3RlcD1cIjRcIj48c3Bhbj40PC9zcGFuPiBQcm9ncmVzczwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gU3RlcCAxOiBDb21wb25lbnQgU2VsZWN0aW9uIC0tPlxuICAgICAgPGRpdiBpZD1cInJlY2lwZS1zdGVwLTFcIiBjbGFzcz1cInJlY2lwZS1zdGVwLXBhbmVsXCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwtYWNjZW50LXNtXCI+U2VsZWN0IENvbXBvbmVudHM6PC9sYWJlbD5cbiAgICAgICAgPGRpdiBpZD1cInJlY2lwZS1jb21wb25lbnQtbGlzdFwiIHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ2FwOiAxMHB4OyBtYXJnaW4tdG9wOiA4cHg7XCI+PC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBTdGVwIDI6IFNoYXJlZCBDb25maWd1cmF0aW9uIC0tPlxuICAgICAgPGRpdiBpZD1cInJlY2lwZS1zdGVwLTJcIiBjbGFzcz1cInJlY2lwZS1zdGVwLXBhbmVsXCIgc3R5bGU9XCJkaXNwbGF5Om5vbmU7XCI+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBnYXA6IDE2cHg7XCI+XG4gICAgICAgICAgPCEtLSBTaGFyZWQgdm9sdW1lcyAtLT5cbiAgICAgICAgICA8ZGl2IGlkPVwicmVjaXBlLXZvbHVtZXMtc2VjdGlvblwiIHN0eWxlPVwiZGlzcGxheTpub25lO1wiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbC1hY2NlbnQtc21cIj5TaGFyZWQgVm9sdW1lczo8L2xhYmVsPlxuICAgICAgICAgICAgPGRpdiBpZD1cInJlY2lwZS12b2x1bWUtbGlzdFwiIHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ2FwOiAxMHB4OyBtYXJnaW4tdG9wOiA4cHg7XCI+PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIFRpbWV6b25lIC0tPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsLWFjY2VudC1zbVwiPlRpbWV6b25lOjwvbGFiZWw+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cInJlY2lwZS10aW1lem9uZVwiIHZhbHVlPVwiVVRDXCIgcGxhY2Vob2xkZXI9XCJlLmcuIEFtZXJpY2EvTmV3X1lvcmtcIlxuICAgICAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxMDAlOyBwYWRkaW5nOiA4cHggMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDZweDtcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBUYXJnZXQgSVAgLS0+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwtYWNjZW50LXNtXCI+VGFyZ2V0IElQIEFkZHJlc3M6PC9sYWJlbD5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwicmVjaXBlLWlwXCIgdmFsdWU9XCJob3N0LmRvY2tlci5pbnRlcm5hbFwiIHBsYWNlaG9sZGVyPVwibG9jYWxob3N0IG9yIElQXCJcbiAgICAgICAgICAgICAgc3R5bGU9XCJ3aWR0aDogMTAwJTsgcGFkZGluZzogOHB4IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmcpOyBjb2xvcjogdmFyKC0tZmcpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA2cHg7XCIgLz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWhpbnQtc21cIj5JUCB3aGVyZSBjb250YWluZXJzIGV4cG9zZSBwb3J0czwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBUYWlsc2NhbGUgLS0+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2hlY2tib3gtbGFiZWxcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cInJlY2lwZS10YWlsc2NhbGVcIiAvPlxuICAgICAgICAgICAgPHNwYW4+UmVzdHJpY3QgdG8gVGFpbHNjYWxlIG5ldHdvcmsgb25seTwvc3Bhbj5cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFN0ZXAgMzogUmV2aWV3IC0tPlxuICAgICAgPGRpdiBpZD1cInJlY2lwZS1zdGVwLTNcIiBjbGFzcz1cInJlY2lwZS1zdGVwLXBhbmVsXCIgc3R5bGU9XCJkaXNwbGF5Om5vbmU7XCI+XG4gICAgICAgIDxkaXYgaWQ9XCJyZWNpcGUtcmV2aWV3LWNvbnRlbnRcIiBzdHlsZT1cImZvbnQtc2l6ZTogMC45cmVtOyBsaW5lLWhlaWdodDogMS43O1wiPjwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gU3RlcCA0OiBQcm9ncmVzcyAtLT5cbiAgICAgIDxkaXYgaWQ9XCJyZWNpcGUtc3RlcC00XCIgY2xhc3M9XCJyZWNpcGUtc3RlcC1wYW5lbFwiIHN0eWxlPVwiZGlzcGxheTpub25lO1wiPlxuICAgICAgICA8ZGl2IGlkPVwicmVjaXBlLXByb2dyZXNzLWxpc3RcIiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdhcDogOHB4O1wiPjwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwicmVjaXBlLWRlcGxveS1yZXN1bHRcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDE2cHg7IGRpc3BsYXk6bm9uZTtcIj48L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1idXR0b25zXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAyMHB4O1wiPlxuICAgICAgICA8YnV0dG9uIGlkPVwicmVjaXBlLWNhbmNlbFwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGlkPVwicmVjaXBlLXByZXZcIiBjbGFzcz1cImJ0bi1hY2NlbnRcIiBzdHlsZT1cImRpc3BsYXk6bm9uZTtcIj5CYWNrPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gaWQ9XCJyZWNpcGUtbmV4dFwiIGNsYXNzPVwiYnRuLWFjY2VudC1zb2xpZFwiPk5leHQ8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5gKTtcblxuICAvLyA9PT0gU1RBVEUgPT09XG4gIGxldCByZWNpcGVUZW1wbGF0ZXMgPSBudWxsO1xuICBsZXQgcmVjaXBlQ2F0ZWdvcmllcyA9IG51bGw7XG4gIGxldCBjdXJyZW50UmVjaXBlID0gbnVsbDtcbiAgbGV0IGN1cnJlbnRTdGVwID0gMTtcbiAgbGV0IGlzUHJlbWl1bSA9IGZhbHNlO1xuXG4gIGNvbnN0IGRlcGxveU1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS1kZXBsb3ktbW9kYWwnKTtcbiAgY29uc3QgY2FuY2VsQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS1jYW5jZWwnKTtcbiAgY29uc3QgcHJldkJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWNpcGUtcHJldicpO1xuICBjb25zdCBuZXh0QnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS1uZXh0Jyk7XG5cbiAgd2lyZU1vZGFsKGRlcGxveU1vZGFsLCBjYW5jZWxCdG4pO1xuXG4gIC8vID09PSBGRVRDSCBSRUNJUEUgVEVNUExBVEVTID09PVxuICBhc3luYyBmdW5jdGlvbiBmZXRjaFJlY2lwZVRlbXBsYXRlcygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL3JlY2lwZXMvdGVtcGxhdGVzJyk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcC5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIHJlY2lwZVRlbXBsYXRlcyA9IGRhdGEudGVtcGxhdGVzO1xuICAgICAgICByZWNpcGVDYXRlZ29yaWVzID0gZGF0YS5jYXRlZ29yaWVzO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIC8vIFByZW1pdW0gcmVxdWlyZWQgXHUyMDE0IHRlbXBsYXRlcyBBUEkgZ2F0ZWRcbiAgICAgIGlmIChyZXNwLnN0YXR1cyA9PT0gNDAzKSB7XG4gICAgICAgIGlzUHJlbWl1bSA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS53YXJuKCdGYWlsZWQgdG8gZmV0Y2ggcmVjaXBlIHRlbXBsYXRlczonLCBlLm1lc3NhZ2UpO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyA9PT0gQ0hFQ0sgUFJFTUlVTSA9PT1cbiAgYXN5bmMgZnVuY3Rpb24gY2hlY2tSZWNpcGVQcmVtaXVtKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvbGljZW5zZS9mZWF0dXJlL3JlY2lwZXMnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwLmpzb24oKTtcbiAgICAgIGlzUHJlbWl1bSA9IGRhdGEuYXZhaWxhYmxlO1xuICAgIH0gY2F0Y2gge1xuICAgICAgaXNQcmVtaXVtID0gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBpc1ByZW1pdW07XG4gIH1cblxuICAvLyA9PT0gUkVOREVSIFJFQ0lQRSBDQVJEUyBJTlRPIEFQUCBTRUxFQ1RPUiA9PT1cbiAgLy8gVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgdGhlIGFwcCBzZWxlY3RvciB0byBpbmplY3QgcmVjaXBlIGNhcmRzXG4gIHdpbmRvdy5yZW5kZXJSZWNpcGVDYXJkcyA9IGFzeW5jIGZ1bmN0aW9uKGdyaWQpIHtcbiAgICBhd2FpdCBjaGVja1JlY2lwZVByZW1pdW0oKTtcblxuICAgIC8vIEJ1aWxkIHJlY2lwZSBkYXRhIFx1MjAxNCB3ZSBjYW4gc2hvdyBjYXJkIG1ldGFkYXRhIGV2ZW4gd2l0aG91dCBwcmVtaXVtXG4gICAgLy8gKGNhcmRzIGp1c3Qgc2hvdyBhIGxvY2sgYW5kIHByb21wdCB0byB1cGdyYWRlKVxuICAgIGxldCByZWNpcGVzO1xuICAgIGlmIChpc1ByZW1pdW0gJiYgcmVjaXBlVGVtcGxhdGVzKSB7XG4gICAgICByZWNpcGVzID0gcmVjaXBlVGVtcGxhdGVzO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBTaG93IGhhcmRjb2RlZCBwcmV2aWV3IGNhcmRzIHdoZW4gbm90IHByZW1pdW1cbiAgICAgIHJlY2lwZXMgPSBnZXRQcmV2aWV3UmVjaXBlcygpO1xuICAgIH1cblxuICAgIGlmICghcmVjaXBlcyB8fCByZWNpcGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgLy8gQ2F0ZWdvcnkgaGVhZGVyXG4gICAgY29uc3QgaGVhZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgaGVhZGVyLmNsYXNzTmFtZSA9ICdhcHAtY2F0ZWdvcnktaGVhZGVyJztcbiAgICBoZWFkZXIuaW5uZXJIVE1MID0gYFxcdUQ4M0VcXHVEREVBIFJlY2lwZXNgO1xuICAgIGhlYWRlci5zdHlsZS5ib3JkZXJCb3R0b21Db2xvciA9ICcjOGU0NGFkJztcbiAgICBncmlkLmFwcGVuZENoaWxkKGhlYWRlcik7XG5cbiAgICBjb25zdCByZWNpcGVMaXN0ID0gQXJyYXkuaXNBcnJheShyZWNpcGVzKSA/IHJlY2lwZXMgOiBPYmplY3QudmFsdWVzKHJlY2lwZXMpO1xuICAgIHJlY2lwZUxpc3Quc29ydCgoYSwgYikgPT4gKGIucG9wdWxhcml0eSB8fCAwKSAtIChhLnBvcHVsYXJpdHkgfHwgMCkpO1xuXG4gICAgZm9yIChjb25zdCByZWNpcGUgb2YgcmVjaXBlTGlzdCkge1xuICAgICAgY29uc3Qgb3B0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBvcHRpb24uY2xhc3NOYW1lID0gJ2FwcC1vcHRpb24nO1xuICAgICAgb3B0aW9uLnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcblxuICAgICAgY29uc3QgY29tcG9uZW50QmFkZ2UgPSBgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC42NXJlbTsgcGFkZGluZzogMnB4IDZweDsgYm9yZGVyLXJhZGl1czogNHB4OyBtYXJnaW4tdG9wOiA0cHg7IGJhY2tncm91bmQ6IHJnYmEoMTQyLDY4LDE3MywwLjIpOyBjb2xvcjogI2E4NTVmNztcIj4ke3JlY2lwZS5jb21wb25lbnRDb3VudCB8fCByZWNpcGUuY29tcG9uZW50cz8ubGVuZ3RoIHx8ICc/J30gYXBwczwvZGl2PmA7XG5cbiAgICAgIGNvbnN0IGxvY2tPdmVybGF5ID0gIWlzUHJlbWl1bSA/IGA8ZGl2IHN0eWxlPVwicG9zaXRpb246IGFic29sdXRlOyB0b3A6IDZweDsgcmlnaHQ6IDZweDsgZm9udC1zaXplOiAwLjY1cmVtOyBwYWRkaW5nOiAycHggOHB4OyBib3JkZXItcmFkaXVzOiAxMHB4OyBiYWNrZ3JvdW5kOiByZ2JhKDI0MSwxOTYsMTUsMC4yKTsgY29sb3I6ICNmMWM0MGY7IGZvbnQtd2VpZ2h0OiA2MDA7XCI+UFJFTUlVTTwvZGl2PmAgOiAnJztcblxuICAgICAgb3B0aW9uLmlubmVySFRNTCA9IGBcbiAgICAgICAgJHtsb2NrT3ZlcmxheX1cbiAgICAgICAgPGRpdiBjbGFzcz1cImFwcC1vcHRpb24taWNvblwiPiR7ZXNjYXBlSHRtbChyZWNpcGUuaWNvbiB8fCAnXFx1RDgzRVxcdURERUEnKX08L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFwcC1vcHRpb24tbmFtZVwiPiR7ZXNjYXBlSHRtbChyZWNpcGUubmFtZSl9PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJhcHAtb3B0aW9uLWRlc2NcIj4ke2VzY2FwZUh0bWwocmVjaXBlLmRlc2NyaXB0aW9uIHx8ICcnKX08L2Rpdj5cbiAgICAgICAgJHtjb21wb25lbnRCYWRnZX1cbiAgICAgIGA7XG5cbiAgICAgIG9wdGlvbi5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICBpZiAoIWlzUHJlbWl1bSkge1xuICAgICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1JlY2lwZXMgcmVxdWlyZSBhIERhc2hDYWRkeSBQcmVtaXVtIGxpY2Vuc2UuIENsaWNrIHRoZSBMaWNlbnNlIGJ1dHRvbiB0byBhY3RpdmF0ZS4nLCAnd2FybmluZycsIDUwMDApO1xuICAgICAgICAgIGlmICh3aW5kb3cub3BlbkxpY2Vuc2VNb2RhbCkgd2luZG93Lm9wZW5MaWNlbnNlTW9kYWwoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgb3BlblJlY2lwZURlcGxveVdpemFyZChyZWNpcGUpO1xuICAgICAgfTtcblxuICAgICAgZ3JpZC5hcHBlbmRDaGlsZChvcHRpb24pO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBnZXRQcmV2aWV3UmVjaXBlcygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgeyBpZDogJ2h0cGMtc3VpdGUnLCBuYW1lOiAnSFRQQyBTdWl0ZScsIGljb246ICdcXHVEODNDXFx1REZBQycsIGRlc2NyaXB0aW9uOiAnQ29tcGxldGUgbWVkaWEgYXV0b21hdGlvbjogZmluZCwgZG93bmxvYWQsIG9yZ2FuaXplLCBhbmQgc3RyZWFtJywgY29tcG9uZW50Q291bnQ6IDYsIHBvcHVsYXJpdHk6IDk4IH0sXG4gICAgICB7IGlkOiAnbmV4dGNsb3VkLWNvbXBsZXRlJywgbmFtZTogJ05leHRjbG91ZCBDb21wbGV0ZScsIGljb246ICdcXHUyNjAxXFx1RkUwRicsIGRlc2NyaXB0aW9uOiAnRnVsbCBwcm9kdWN0aXZpdHkgc3VpdGU6IGNsb3VkIHN0b3JhZ2UsIG9mZmljZSBlZGl0aW5nLCBhbmQgY29sbGFib3JhdGlvbicsIGNvbXBvbmVudENvdW50OiA0LCBwb3B1bGFyaXR5OiA5MCB9LFxuICAgICAgeyBpZDogJ3NtYXJ0LWhvbWUnLCBuYW1lOiAnU21hcnQgSG9tZSBIdWInLCBpY29uOiAnXFx1RDgzQ1xcdURGRTAnLCBkZXNjcmlwdGlvbjogJ0hvbWUgYXV0b21hdGlvbjogY29udHJvbCwgYXV0b21hdGUsIGFuZCBtb25pdG9yIElvVCBkZXZpY2VzJywgY29tcG9uZW50Q291bnQ6IDQsIHBvcHVsYXJpdHk6IDg4IH0sXG4gICAgICB7IGlkOiAnZGV2LWVudmlyb25tZW50JywgbmFtZTogJ0RldiBFbnZpcm9ubWVudCcsIGljb246ICdcXHVEODNEXFx1RENCQicsIGRlc2NyaXB0aW9uOiAnU2VsZi1ob3N0ZWQgZGV2ZWxvcG1lbnQgd29ya2Zsb3c6IEdpdCwgQ0kvQ0QsIElERSwgYW5kIGRhdGFiYXNlJywgY29tcG9uZW50Q291bnQ6IDQsIHBvcHVsYXJpdHk6IDgyIH1cbiAgICBdO1xuICB9XG5cbiAgLy8gPT09IFJFQ0lQRSBERVBMT1kgV0laQVJEID09PVxuICBmdW5jdGlvbiBvcGVuUmVjaXBlRGVwbG95V2l6YXJkKHJlY2lwZSkge1xuICAgIGN1cnJlbnRSZWNpcGUgPSByZWNpcGU7XG4gICAgY3VycmVudFN0ZXAgPSAxO1xuXG4gICAgLy8gQ2xvc2UgYXBwIHNlbGVjdG9yXG4gICAgY29uc3QgYXBwU2VsZWN0b3JNb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcHAtc2VsZWN0b3ItbW9kYWwnKTtcbiAgICBpZiAoYXBwU2VsZWN0b3JNb2RhbCkgYXBwU2VsZWN0b3JNb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG5cbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVjaXBlLWRlcGxveS10aXRsZScpLnRleHRDb250ZW50ID0gYERlcGxveSAke3JlY2lwZS5uYW1lfWA7XG5cbiAgICAvLyBSZXNldCBzdGVwc1xuICAgIHVwZGF0ZVN0ZXBVSSgpO1xuICAgIHJlbmRlclN0ZXAxKCk7XG5cbiAgICBkZXBsb3lNb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVTdGVwVUkoKSB7XG4gICAgLy8gU3RlcCBpbmRpY2F0b3JzXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI3JlY2lwZS1zdGVwcyAucmVjaXBlLXN0ZXAnKS5mb3JFYWNoKGVsID0+IHtcbiAgICAgIGNvbnN0IHN0ZXAgPSBwYXJzZUludChlbC5kYXRhc2V0LnN0ZXApO1xuICAgICAgZWwuY2xhc3NMaXN0LnRvZ2dsZSgnYWN0aXZlJywgc3RlcCA9PT0gY3VycmVudFN0ZXApO1xuICAgICAgZWwuY2xhc3NMaXN0LnRvZ2dsZSgnY29tcGxldGVkJywgc3RlcCA8IGN1cnJlbnRTdGVwKTtcbiAgICB9KTtcblxuICAgIC8vIFN0ZXAgcGFuZWxzXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gNDsgaSsrKSB7XG4gICAgICBjb25zdCBwYW5lbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGByZWNpcGUtc3RlcC0ke2l9YCk7XG4gICAgICBpZiAocGFuZWwpIHBhbmVsLnN0eWxlLmRpc3BsYXkgPSBpID09PSBjdXJyZW50U3RlcCA/ICcnIDogJ25vbmUnO1xuICAgIH1cblxuICAgIC8vIE5hdmlnYXRpb24gYnV0dG9uc1xuICAgIHByZXZCdG4uc3R5bGUuZGlzcGxheSA9IGN1cnJlbnRTdGVwID4gMSAmJiBjdXJyZW50U3RlcCA8IDQgPyAnJyA6ICdub25lJztcbiAgICBpZiAoY3VycmVudFN0ZXAgPT09IDQpIHtcbiAgICAgIG5leHRCdG4uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIGNhbmNlbEJ0bi50ZXh0Q29udGVudCA9ICdDbG9zZSc7XG4gICAgfSBlbHNlIGlmIChjdXJyZW50U3RlcCA9PT0gMykge1xuICAgICAgbmV4dEJ0bi50ZXh0Q29udGVudCA9ICdcXHVEODNEXFx1REU4MCBEZXBsb3knO1xuICAgICAgbmV4dEJ0bi5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICBjYW5jZWxCdG4udGV4dENvbnRlbnQgPSAnQ2FuY2VsJztcbiAgICB9IGVsc2Uge1xuICAgICAgbmV4dEJ0bi50ZXh0Q29udGVudCA9ICdOZXh0JztcbiAgICAgIG5leHRCdG4uc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgICAgY2FuY2VsQnRuLnRleHRDb250ZW50ID0gJ0NhbmNlbCc7XG4gICAgfVxuICB9XG5cbiAgLy8gU3RlcCAxOiBDb21wb25lbnQgc2VsZWN0aW9uXG4gIGZ1bmN0aW9uIHJlbmRlclN0ZXAxKCkge1xuICAgIGNvbnN0IGxpc3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVjaXBlLWNvbXBvbmVudC1saXN0Jyk7XG4gICAgbGlzdC5pbm5lckhUTUwgPSAnJztcblxuICAgIGNvbnN0IGNvbXBvbmVudHMgPSBjdXJyZW50UmVjaXBlLmNvbXBvbmVudHMgfHwgW107XG4gICAgZm9yIChjb25zdCBjb21wIG9mIGNvbXBvbmVudHMpIHtcbiAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBlbC5zdHlsZS5jc3NUZXh0ID0gJ2Rpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogMTJweDsgcGFkZGluZzogMTJweDsgYm9yZGVyLXJhZGl1czogOHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJnKTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsnO1xuXG4gICAgICBjb25zdCBpc1JlcXVpcmVkID0gY29tcC5yZXF1aXJlZDtcbiAgICAgIGNvbnN0IGlzSW50ZXJuYWwgPSBjb21wLmludGVybmFsO1xuXG4gICAgICBlbC5pbm5lckhUTUwgPSBgXG4gICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiAke2lzUmVxdWlyZWQgPyAnY2hlY2tlZCBkaXNhYmxlZCcgOiAnY2hlY2tlZCd9IGRhdGEtY29tcG9uZW50LWlkPVwiJHtjb21wLmlkfVwiXG4gICAgICAgICAgc3R5bGU9XCJ3aWR0aDogMThweDsgaGVpZ2h0OiAxOHB4OyBhY2NlbnQtY29sb3I6IHZhcigtLWFjY2VudCk7XCIgLz5cbiAgICAgICAgPGRpdiBzdHlsZT1cImZsZXg6IDE7XCI+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IGZvbnQtc2l6ZTogMC45cmVtO1wiPiR7ZXNjYXBlSHRtbChjb21wLnJvbGUgfHwgY29tcC5pZCl9PC9kaXY+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43OHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5cbiAgICAgICAgICAgICR7Y29tcC50ZW1wbGF0ZVJlZiA/IGVzY2FwZUh0bWwoY29tcC50ZW1wbGF0ZVJlZikgOiAnQnVpbHQtaW4nfVxuICAgICAgICAgICAgJHtpc1JlcXVpcmVkID8gJzxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLWFjY2VudCk7IG1hcmdpbi1sZWZ0OiA2cHg7XCI+UmVxdWlyZWQ8L3NwYW4+JyA6ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1sZWZ0OiA2cHg7XCI+T3B0aW9uYWw8L3NwYW4+J31cbiAgICAgICAgICAgICR7aXNJbnRlcm5hbCA/ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1sZWZ0OiA2cHg7XCI+KEludGVybmFsKTwvc3Bhbj4nIDogJyd9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgJHtjb21wLm5vdGUgPyBgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLXdhcm4tZmcpOyBtYXJnaW4tdG9wOiA0cHg7XCI+XFx1MjZBMCAke2VzY2FwZUh0bWwoY29tcC5ub3RlKX08L2Rpdj5gIDogJyd9XG4gICAgICAgIDwvZGl2PlxuICAgICAgYDtcbiAgICAgIGxpc3QuYXBwZW5kQ2hpbGQoZWwpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN0ZXAgMjogU2hhcmVkIGNvbmZpZ3VyYXRpb25cbiAgZnVuY3Rpb24gcmVuZGVyU3RlcDIoKSB7XG4gICAgY29uc3Qgdm9sdW1lU2VjdGlvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWNpcGUtdm9sdW1lcy1zZWN0aW9uJyk7XG4gICAgY29uc3Qgdm9sdW1lTGlzdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWNpcGUtdm9sdW1lLWxpc3QnKTtcblxuICAgIGNvbnN0IHNoYXJlZFZvbHVtZXMgPSBjdXJyZW50UmVjaXBlLnNoYXJlZFZvbHVtZXM7XG4gICAgaWYgKHNoYXJlZFZvbHVtZXMgJiYgT2JqZWN0LmtleXMoc2hhcmVkVm9sdW1lcykubGVuZ3RoID4gMCkge1xuICAgICAgdm9sdW1lU2VjdGlvbi5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICB2b2x1bWVMaXN0LmlubmVySFRNTCA9ICcnO1xuXG4gICAgICBmb3IgKGNvbnN0IFtrZXksIHZvbF0gb2YgT2JqZWN0LmVudHJpZXMoc2hhcmVkVm9sdW1lcykpIHtcbiAgICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgZWwuc3R5bGUuY3NzVGV4dCA9ICdkaXNwbGF5OiBncmlkOyBnYXA6IDRweDsnO1xuICAgICAgICBlbC5pbm5lckhUTUwgPSBgXG4gICAgICAgICAgPGxhYmVsIHN0eWxlPVwiZm9udC13ZWlnaHQ6IDUwMDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPiR7ZXNjYXBlSHRtbCh2b2wubGFiZWwgfHwga2V5KX08L2xhYmVsPlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGRhdGEtdm9sdW1lLWtleT1cIiR7a2V5fVwiIHZhbHVlPVwiJHtlc2NhcGVIdG1sKHZvbC5kZWZhdWx0UGF0aCB8fCAnJyl9XCJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiJHtlc2NhcGVIdG1sKHZvbC5kZWZhdWx0UGF0aCB8fCAnL3BhdGgnKX1cIlxuICAgICAgICAgICAgc3R5bGU9XCJ3aWR0aDogMTAwJTsgcGFkZGluZzogOHB4IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmcpOyBjb2xvcjogdmFyKC0tZmcpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA2cHg7IGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7IGZvbnQtc2l6ZTogMC44NXJlbTtcIiAvPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWhpbnQtc21cIj4ke2VzY2FwZUh0bWwodm9sLmRlc2NyaXB0aW9uIHx8ICcnKX08L2Rpdj5cbiAgICAgICAgYDtcbiAgICAgICAgdm9sdW1lTGlzdC5hcHBlbmRDaGlsZChlbCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZvbHVtZVNlY3Rpb24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB9XG4gIH1cblxuICAvLyBTdGVwIDM6IFJldmlld1xuICBmdW5jdGlvbiByZW5kZXJTdGVwMygpIHtcbiAgICBjb25zdCBjb250ZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS1yZXZpZXctY29udGVudCcpO1xuICAgIGNvbnN0IHNlbGVjdGVkQ29tcG9uZW50cyA9IGdldFNlbGVjdGVkQ29tcG9uZW50cygpO1xuXG4gICAgY29uc3Qgdm9sdW1lSW5wdXRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI3JlY2lwZS12b2x1bWUtbGlzdCBpbnB1dFtkYXRhLXZvbHVtZS1rZXldJyk7XG4gICAgY29uc3Qgdm9sdW1lcyA9IHt9O1xuICAgIHZvbHVtZUlucHV0cy5mb3JFYWNoKGlucHV0ID0+IHtcbiAgICAgIHZvbHVtZXNbaW5wdXQuZGF0YXNldC52b2x1bWVLZXldID0gaW5wdXQudmFsdWU7XG4gICAgfSk7XG5cbiAgICBjb25zdCB0eiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWNpcGUtdGltZXpvbmUnKS52YWx1ZSB8fCAnVVRDJztcbiAgICBjb25zdCBpcCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWNpcGUtaXAnKS52YWx1ZSB8fCAnaG9zdC5kb2NrZXIuaW50ZXJuYWwnO1xuICAgIGNvbnN0IHRhaWxzY2FsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWNpcGUtdGFpbHNjYWxlJykuY2hlY2tlZDtcblxuICAgIGNvbnRlbnQuaW5uZXJIVE1MID0gYFxuICAgICAgPGRpdiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IGZvbnQtc2l6ZTogMXJlbTsgbWFyZ2luLWJvdHRvbTogMTJweDtcIj4ke2VzY2FwZUh0bWwoY3VycmVudFJlY2lwZS5uYW1lKX08L2Rpdj5cbiAgICAgIDxkaXYgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tYm90dG9tOiAxNnB4O1wiPiR7ZXNjYXBlSHRtbChjdXJyZW50UmVjaXBlLmRlc2NyaXB0aW9uIHx8ICcnKX08L2Rpdj5cblxuICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDEycHg7XCI+XG4gICAgICAgIDxzdHJvbmc+Q29tcG9uZW50cyAoJHtzZWxlY3RlZENvbXBvbmVudHMubGVuZ3RofSk6PC9zdHJvbmc+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBnYXA6IDRweDsgbWFyZ2luLXRvcDogNnB4O1wiPlxuICAgICAgICAgICR7c2VsZWN0ZWRDb21wb25lbnRzLm1hcChjID0+IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogNHB4IDA7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj5cbiAgICAgICAgICAgIFxcdTIwMjIgPHN0cm9uZz4ke2VzY2FwZUh0bWwoYy5yb2xlIHx8IGMuaWQpfTwvc3Ryb25nPiAke2MuaW50ZXJuYWwgPyAnPHNwYW4gc3R5bGU9XCJjb2xvcjp2YXIoLS1tdXRlZClcIj4oaW50ZXJuYWwpPC9zcGFuPicgOiAnJ31cbiAgICAgICAgICA8L2Rpdj5gKS5qb2luKCcnKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgJHtPYmplY3Qua2V5cyh2b2x1bWVzKS5sZW5ndGggPiAwID8gYDxkaXYgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAxMnB4O1wiPlxuICAgICAgICA8c3Ryb25nPlZvbHVtZXM6PC9zdHJvbmc+XG4gICAgICAgICR7T2JqZWN0LmVudHJpZXModm9sdW1lcykubWFwKChbaywgdl0pID0+IGA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtOyBmb250LWZhbWlseTogbW9ub3NwYWNlOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPiR7a306ICR7ZXNjYXBlSHRtbCh2KX08L2Rpdj5gKS5qb2luKCcnKX1cbiAgICAgIDwvZGl2PmAgOiAnJ31cblxuICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5cbiAgICAgICAgVGltZXpvbmU6ICR7ZXNjYXBlSHRtbCh0eil9ICZidWxsOyBJUDogJHtlc2NhcGVIdG1sKGlwKX0gJHt0YWlsc2NhbGUgPyAnJmJ1bGw7IFRhaWxzY2FsZSBvbmx5JyA6ICcnfVxuICAgICAgPC9kaXY+XG5cbiAgICAgICR7Y3VycmVudFJlY2lwZS5uZXR3b3JrID8gYDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi10b3A6IDRweDtcIj5Eb2NrZXIgbmV0d29yazogPGNvZGU+JHtlc2NhcGVIdG1sKGN1cnJlbnRSZWNpcGUubmV0d29yay5uYW1lKX08L2NvZGU+PC9kaXY+YCA6ICcnfVxuICAgIGA7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTZWxlY3RlZENvbXBvbmVudHMoKSB7XG4gICAgY29uc3QgY2hlY2tib3hlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyNyZWNpcGUtY29tcG9uZW50LWxpc3QgaW5wdXRbZGF0YS1jb21wb25lbnQtaWRdJyk7XG4gICAgY29uc3Qgc2VsZWN0ZWRJZHMgPSBuZXcgU2V0KCk7XG4gICAgY2hlY2tib3hlcy5mb3JFYWNoKGNiID0+IHtcbiAgICAgIGlmIChjYi5jaGVja2VkKSBzZWxlY3RlZElkcy5hZGQoY2IuZGF0YXNldC5jb21wb25lbnRJZCk7XG4gICAgfSk7XG5cbiAgICAvLyBBbHdheXMgaW5jbHVkZSByZXF1aXJlZCBjb21wb25lbnRzXG4gICAgY29uc3QgY29tcG9uZW50cyA9IGN1cnJlbnRSZWNpcGUuY29tcG9uZW50cyB8fCBbXTtcbiAgICBjb21wb25lbnRzLmZpbHRlcihjID0+IGMucmVxdWlyZWQpLmZvckVhY2goYyA9PiBzZWxlY3RlZElkcy5hZGQoYy5pZCkpO1xuXG4gICAgcmV0dXJuIGNvbXBvbmVudHMuZmlsdGVyKGMgPT4gc2VsZWN0ZWRJZHMuaGFzKGMuaWQpKTtcbiAgfVxuXG4gIC8vIFN0ZXAgNDogRGVwbG95XG4gIGFzeW5jIGZ1bmN0aW9uIGV4ZWN1dGVEZXBsb3koKSB7XG4gICAgY29uc3QgcHJvZ3Jlc3NMaXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS1wcm9ncmVzcy1saXN0Jyk7XG4gICAgY29uc3QgcmVzdWx0RWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVjaXBlLWRlcGxveS1yZXN1bHQnKTtcbiAgICByZXN1bHRFbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHByb2dyZXNzTGlzdC5pbm5lckhUTUwgPSAnJztcblxuICAgIGNvbnN0IHNlbGVjdGVkQ29tcG9uZW50cyA9IGdldFNlbGVjdGVkQ29tcG9uZW50cygpO1xuXG4gICAgLy8gU2hvdyBwcm9ncmVzcyBpdGVtc1xuICAgIGZvciAoY29uc3QgY29tcCBvZiBzZWxlY3RlZENvbXBvbmVudHMpIHtcbiAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBlbC5pZCA9IGByZWNpcGUtcHJvZ3Jlc3MtJHtjb21wLmlkfWA7XG4gICAgICBlbC5zdHlsZS5jc3NUZXh0ID0gJ2Rpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogMTBweDsgcGFkZGluZzogMTBweCAxMnB4OyBib3JkZXItcmFkaXVzOiA2cHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmcpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBmb250LXNpemU6IDAuODVyZW07JztcbiAgICAgIGVsLmlubmVySFRNTCA9IGBcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJyZWNpcGUtcHJvZ3Jlc3MtaWNvblwiIHN0eWxlPVwiZm9udC1zaXplOiAxLjFyZW07XCI+XFx1MjNGMzwvc3Bhbj5cbiAgICAgICAgPHNwYW4gc3R5bGU9XCJmbGV4OjE7IGZvbnQtd2VpZ2h0OiA1MDA7XCI+JHtlc2NhcGVIdG1sKGNvbXAucm9sZSB8fCBjb21wLmlkKX08L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwicmVjaXBlLXByb2dyZXNzLXN0YXR1c1wiIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj5RdWV1ZWQ8L3NwYW4+XG4gICAgICBgO1xuICAgICAgcHJvZ3Jlc3NMaXN0LmFwcGVuZENoaWxkKGVsKTtcbiAgICB9XG5cbiAgICAvLyBDb2xsZWN0IGNvbmZpZ1xuICAgIGNvbnN0IHZvbHVtZUlucHV0cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyNyZWNpcGUtdm9sdW1lLWxpc3QgaW5wdXRbZGF0YS12b2x1bWUta2V5XScpO1xuICAgIGNvbnN0IHZvbHVtZXMgPSB7fTtcbiAgICB2b2x1bWVJbnB1dHMuZm9yRWFjaChpbnB1dCA9PiB7XG4gICAgICB2b2x1bWVzW2lucHV0LmRhdGFzZXQudm9sdW1lS2V5XSA9IGlucHV0LnZhbHVlO1xuICAgIH0pO1xuXG4gICAgY29uc3QgY29uZmlnID0ge1xuICAgICAgc2VsZWN0ZWRDb21wb25lbnRzOiBzZWxlY3RlZENvbXBvbmVudHMubWFwKGMgPT4gYy5pZCksXG4gICAgICBzaGFyZWRDb25maWc6IHtcbiAgICAgICAgaXA6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZWNpcGUtaXAnKS52YWx1ZSB8fCAnaG9zdC5kb2NrZXIuaW50ZXJuYWwnLFxuICAgICAgICB0aW1lem9uZTogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlY2lwZS10aW1lem9uZScpLnZhbHVlIHx8ICdVVEMnLFxuICAgICAgICB0YWlsc2NhbGVPbmx5OiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVjaXBlLXRhaWxzY2FsZScpLmNoZWNrZWQsXG4gICAgICAgIHZvbHVtZXNcbiAgICAgIH0sXG4gICAgICBjb21wb25lbnRPdmVycmlkZXM6IHt9XG4gICAgfTtcblxuICAgIC8vIE1hcmsgYWxsIGFzIGRlcGxveWluZ1xuICAgIGZvciAoY29uc3QgY29tcCBvZiBzZWxlY3RlZENvbXBvbmVudHMpIHtcbiAgICAgIHVwZGF0ZVByb2dyZXNzSXRlbShjb21wLmlkLCAnZGVwbG95aW5nJywgJ0RlcGxveWluZy4uLicpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvcmVjaXBlcy9kZXBsb3knLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyByZWNpcGVJZDogY3VycmVudFJlY2lwZS5pZCwgY29uZmlnIH0pXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwLmpzb24oKTtcblxuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICAvLyBNYXJrIGRlcGxveWVkIGNvbXBvbmVudHNcbiAgICAgICAgZm9yIChjb25zdCBkZXBsb3llZCBvZiAoZGF0YS5kZXBsb3llZCB8fCBbXSkpIHtcbiAgICAgICAgICB1cGRhdGVQcm9ncmVzc0l0ZW0oZGVwbG95ZWQuaWQsICdzdWNjZXNzJywgZGVwbG95ZWQudXJsID8gYFJ1bm5pbmcgXFx1MjE5MiAke2RlcGxveWVkLnVybH1gIDogJ1J1bm5pbmcnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBNYXJrIGVycm9yc1xuICAgICAgICBmb3IgKGNvbnN0IGVyciBvZiAoZGF0YS5lcnJvcnMgfHwgW10pKSB7XG4gICAgICAgICAgdXBkYXRlUHJvZ3Jlc3NJdGVtKGVyci5jb21wb25lbnRJZCwgJ2Vycm9yJywgZXJyLmVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3VsdEVsLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgICAgcmVzdWx0RWwuaW5uZXJIVE1MID0gYFxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxNHB4OyBib3JkZXItcmFkaXVzOiA4cHg7IGJhY2tncm91bmQ6IHJnYmEoNDYsMjA0LDExMywwLjEpOyBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDQ2LDIwNCwxMTMsMC4zKTtcIj5cbiAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXdlaWdodDogNjAwOyBjb2xvcjogdmFyKC0tb2stZmcpOyBtYXJnaW4tYm90dG9tOiA2cHg7XCI+JHtlc2NhcGVIdG1sKGRhdGEubWVzc2FnZSB8fCAnRGVwbG95ZWQhJyl9PC9kaXY+XG4gICAgICAgICAgICAke2RhdGEuc2V0dXBJbnN0cnVjdGlvbnMgPyBgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tdG9wOiA4cHg7XCI+XG4gICAgICAgICAgICAgIDxzdHJvbmc+U2V0dXAgdGlwczo8L3N0cm9uZz5cbiAgICAgICAgICAgICAgPHVsIHN0eWxlPVwibWFyZ2luOiA0cHggMCAwIDE2cHg7IHBhZGRpbmc6IDA7XCI+JHtkYXRhLnNldHVwSW5zdHJ1Y3Rpb25zLm1hcChzID0+IGA8bGk+JHtlc2NhcGVIdG1sKHMpfTwvbGk+YCkuam9pbignJyl9PC91bD5cbiAgICAgICAgICAgIDwvZGl2PmAgOiAnJ31cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgYDtcblxuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKGAke2N1cnJlbnRSZWNpcGUubmFtZX0gcmVjaXBlIGRlcGxveWVkIHN1Y2Nlc3NmdWxseSFgLCAnc3VjY2VzcycsIDUwMDApO1xuXG4gICAgICAgIC8vIFJlZnJlc2ggZGFzaGJvYXJkXG4gICAgICAgIGlmICh3aW5kb3cubG9hZFNlcnZpY2VzKSB3aW5kb3cubG9hZFNlcnZpY2VzKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRFbC5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICAgIHJlc3VsdEVsLmlubmVySFRNTCA9IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogMTRweDsgYm9yZGVyLXJhZGl1czogOHB4OyBiYWNrZ3JvdW5kOiByZ2JhKDIzMSw3Niw2MCwwLjEpOyBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDIzMSw3Niw2MCwwLjMpOyBjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5cbiAgICAgICAgICA8c3Ryb25nPkRlcGxveW1lbnQgZmFpbGVkOjwvc3Ryb25nPiAke2VzY2FwZUh0bWwoZGF0YS5lcnJvciB8fCAnVW5rbm93biBlcnJvcicpfVxuICAgICAgICA8L2Rpdj5gO1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKGBSZWNpcGUgZGVwbG95bWVudCBmYWlsZWQ6ICR7ZGF0YS5lcnJvcn1gLCAnZXJyb3InLCA1MDAwKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXN1bHRFbC5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICByZXN1bHRFbC5pbm5lckhUTUwgPSBgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDE0cHg7IGJvcmRlci1yYWRpdXM6IDhweDsgYmFja2dyb3VuZDogcmdiYSgyMzEsNzYsNjAsMC4xKTsgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyMzEsNzYsNjAsMC4zKTsgY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+XG4gICAgICAgIDxzdHJvbmc+TmV0d29yayBlcnJvcjo8L3N0cm9uZz4gJHtlc2NhcGVIdG1sKGUubWVzc2FnZSl9XG4gICAgICA8L2Rpdj5gO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVByb2dyZXNzSXRlbShjb21wb25lbnRJZCwgc3RhdHVzLCB0ZXh0KSB7XG4gICAgY29uc3QgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgcmVjaXBlLXByb2dyZXNzLSR7Y29tcG9uZW50SWR9YCk7XG4gICAgaWYgKCFlbCkgcmV0dXJuO1xuICAgIGNvbnN0IGljb24gPSBlbC5xdWVyeVNlbGVjdG9yKCcucmVjaXBlLXByb2dyZXNzLWljb24nKTtcbiAgICBjb25zdCBzdGF0dXNFbCA9IGVsLnF1ZXJ5U2VsZWN0b3IoJy5yZWNpcGUtcHJvZ3Jlc3Mtc3RhdHVzJyk7XG5cbiAgICBpZiAoc3RhdHVzID09PSAnZGVwbG95aW5nJykge1xuICAgICAgaWNvbi50ZXh0Q29udGVudCA9ICdcXHUyM0YzJztcbiAgICAgIHN0YXR1c0VsLnN0eWxlLmNvbG9yID0gJ3ZhcigtLWFjY2VudCknO1xuICAgIH0gZWxzZSBpZiAoc3RhdHVzID09PSAnc3VjY2VzcycpIHtcbiAgICAgIGljb24udGV4dENvbnRlbnQgPSAnXFx1MjcwNSc7XG4gICAgICBzdGF0dXNFbC5zdHlsZS5jb2xvciA9ICd2YXIoLS1vay1mZyknO1xuICAgIH0gZWxzZSBpZiAoc3RhdHVzID09PSAnZXJyb3InKSB7XG4gICAgICBpY29uLnRleHRDb250ZW50ID0gJ1xcdTI3NEMnO1xuICAgICAgc3RhdHVzRWwuc3R5bGUuY29sb3IgPSAndmFyKC0tYmFkLWZnKSc7XG4gICAgfVxuICAgIHN0YXR1c0VsLnRleHRDb250ZW50ID0gdGV4dDtcbiAgfVxuXG4gIC8vID09PSBTVEVQIE5BVklHQVRJT04gPT09XG4gIG5leHRCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgaWYgKGN1cnJlbnRTdGVwID09PSAzKSB7XG4gICAgICBjdXJyZW50U3RlcCA9IDQ7XG4gICAgICB1cGRhdGVTdGVwVUkoKTtcbiAgICAgIGV4ZWN1dGVEZXBsb3koKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGN1cnJlbnRTdGVwIDwgMykge1xuICAgICAgY3VycmVudFN0ZXArKztcbiAgICAgIHVwZGF0ZVN0ZXBVSSgpO1xuICAgICAgaWYgKGN1cnJlbnRTdGVwID09PSAyKSByZW5kZXJTdGVwMigpO1xuICAgICAgaWYgKGN1cnJlbnRTdGVwID09PSAzKSByZW5kZXJTdGVwMygpO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJldkJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBpZiAoY3VycmVudFN0ZXAgPiAxICYmIGN1cnJlbnRTdGVwIDwgNCkge1xuICAgICAgY3VycmVudFN0ZXAtLTtcbiAgICAgIHVwZGF0ZVN0ZXBVSSgpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gPT09IFJFQ0lQRSBDQVJEIEdST1VQSU5HIE9OIERBU0hCT0FSRCA9PT1cbiAgLy8gQWZ0ZXIgZGFzaGJvYXJkIGxvYWRzLCBncm91cCBjYXJkcyB0aGF0IHNoYXJlIGEgcmVjaXBlSWRcbiAgd2luZG93Lmdyb3VwUmVjaXBlQ2FyZHMgPSBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBjYXJkcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5zZXJ2aWNlLWNhcmRbZGF0YS1yZWNpcGUtaWRdJyk7XG4gICAgaWYgKGNhcmRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgY29uc3QgZ3JvdXBzID0ge307XG4gICAgY2FyZHMuZm9yRWFjaChjYXJkID0+IHtcbiAgICAgIGNvbnN0IHJlY2lwZUlkID0gY2FyZC5kYXRhc2V0LnJlY2lwZUlkO1xuICAgICAgaWYgKCFncm91cHNbcmVjaXBlSWRdKSBncm91cHNbcmVjaXBlSWRdID0gW107XG4gICAgICBncm91cHNbcmVjaXBlSWRdLnB1c2goY2FyZCk7XG4gICAgfSk7XG5cbiAgICBmb3IgKGNvbnN0IFtyZWNpcGVJZCwgZ3JvdXBDYXJkc10gb2YgT2JqZWN0LmVudHJpZXMoZ3JvdXBzKSkge1xuICAgICAgaWYgKGdyb3VwQ2FyZHMubGVuZ3RoIDwgMikgY29udGludWU7XG5cbiAgICAgIC8vIEFwcGx5IHN1YnRsZSB2aXN1YWwgZ3JvdXBpbmdcbiAgICAgIGdyb3VwQ2FyZHMuZm9yRWFjaCgoY2FyZCwgaSkgPT4ge1xuICAgICAgICBjYXJkLnN0eWxlLmJvcmRlckxlZnQgPSAnM3B4IHNvbGlkIHJnYmEoMTQyLDY4LDE3MywwLjUpJztcbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAvLyBBZGQgYSByZWNpcGUgbGFiZWwgdG8gdGhlIGZpcnN0IGNhcmRcbiAgICAgICAgICBsZXQgbGFiZWwgPSBjYXJkLnF1ZXJ5U2VsZWN0b3IoJy5yZWNpcGUtZ3JvdXAtbGFiZWwnKTtcbiAgICAgICAgICBpZiAoIWxhYmVsKSB7XG4gICAgICAgICAgICBsYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgbGFiZWwuY2xhc3NOYW1lID0gJ3JlY2lwZS1ncm91cC1sYWJlbCc7XG4gICAgICAgICAgICBsYWJlbC5zdHlsZS5jc3NUZXh0ID0gJ3Bvc2l0aW9uOiBhYnNvbHV0ZTsgdG9wOiAtOHB4OyBsZWZ0OiAxMnB4OyBmb250LXNpemU6IDAuNnJlbTsgcGFkZGluZzogMXB4IDhweDsgYm9yZGVyLXJhZGl1czogOHB4OyBiYWNrZ3JvdW5kOiByZ2JhKDE0Miw2OCwxNzMsMC4zKTsgY29sb3I6ICNkNGE1ZmY7IGZvbnQtd2VpZ2h0OiA2MDA7IHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7IGxldHRlci1zcGFjaW5nOiAwLjVweDsnO1xuICAgICAgICAgICAgbGFiZWwudGV4dENvbnRlbnQgPSByZWNpcGVJZC5yZXBsYWNlKC8tL2csICcgJyk7XG4gICAgICAgICAgICBjYXJkLnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICAgICAgICAgIGNhcmQuYXBwZW5kQ2hpbGQobGFiZWwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8vID09PSBSRUNJUEUgTUFOQUdFTUVOVCBBQ1RJT05TID09PVxuICB3aW5kb3cubWFuYWdlUmVjaXBlID0gYXN5bmMgZnVuY3Rpb24ocmVjaXBlSWQsIGFjdGlvbikge1xuICAgIGNvbnN0IGVuZHBvaW50ID0gYC9hcGkvdjEvcmVjaXBlcy8ke3JlY2lwZUlkfS8ke2FjdGlvbn1gO1xuICAgIGNvbnN0IG1ldGhvZCA9IGFjdGlvbiA9PT0gJ3JlbW92ZScgPyAnREVMRVRFJyA6ICdQT1NUJztcbiAgICBjb25zdCB1cmwgPSBhY3Rpb24gPT09ICdyZW1vdmUnID8gYC9hcGkvdjEvcmVjaXBlcy8ke3JlY2lwZUlkfWAgOiBlbmRwb2ludDtcblxuICAgIGlmIChhY3Rpb24gPT09ICdyZW1vdmUnICYmICFjb25maXJtKGBSZW1vdmUgdGhlIGVudGlyZSAke3JlY2lwZUlkfSByZWNpcGU/IFRoaXMgd2lsbCBkZWxldGUgYWxsIGNvbnRhaW5lcnMgYW5kIGNvbmZpZ3VyYXRpb24uYCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHNlY3VyZUZldGNoKHVybCwgeyBtZXRob2QgfSk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcC5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oYFJlY2lwZSAke2FjdGlvbn06ICR7ZGF0YS5yZXN1bHRzPy5maWx0ZXIociA9PiByLnN0YXR1cyAhPT0gJ2ZhaWxlZCcpLmxlbmd0aCB8fCAwfSBjb21wb25lbnRzIHByb2Nlc3NlZGAsICdzdWNjZXNzJywgNDAwMCk7XG4gICAgICAgIGlmICh3aW5kb3cubG9hZFNlcnZpY2VzKSB3aW5kb3cubG9hZFNlcnZpY2VzKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKGBSZWNpcGUgJHthY3Rpb259IGZhaWxlZDogJHtkYXRhLmVycm9yfWAsICdlcnJvcicsIDUwMDApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oYE5ldHdvcmsgZXJyb3I6ICR7ZS5tZXNzYWdlfWAsICdlcnJvcicsIDUwMDApO1xuICAgIH1cbiAgfTtcblxuICAvLyA9PT0gSU5KRUNUIENTUyA9PT1cbiAgY29uc3Qgc3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuICBzdHlsZS50ZXh0Q29udGVudCA9IGBcbiAgICAucmVjaXBlLXN0ZXAge1xuICAgICAgZmxleDogMTtcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICAgIHBhZGRpbmc6IDhweCA0cHg7XG4gICAgICBmb250LXNpemU6IDAuNzhyZW07XG4gICAgICBjb2xvcjogdmFyKC0tbXV0ZWQpO1xuICAgICAgYm9yZGVyLWJvdHRvbTogMnB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG4gICAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycztcbiAgICB9XG4gICAgLnJlY2lwZS1zdGVwIHNwYW4ge1xuICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICB3aWR0aDogMjBweDtcbiAgICAgIGhlaWdodDogMjBweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLWJvcmRlcik7XG4gICAgICBjb2xvcjogdmFyKC0tbXV0ZWQpO1xuICAgICAgZm9udC1zaXplOiAwLjdyZW07XG4gICAgICBmb250LXdlaWdodDogNzAwO1xuICAgICAgbWFyZ2luLXJpZ2h0OiA0cHg7XG4gICAgfVxuICAgIC5yZWNpcGUtc3RlcC5hY3RpdmUge1xuICAgICAgY29sb3I6IHZhcigtLWFjY2VudCk7XG4gICAgICBib3JkZXItYm90dG9tLWNvbG9yOiB2YXIoLS1hY2NlbnQpO1xuICAgIH1cbiAgICAucmVjaXBlLXN0ZXAuYWN0aXZlIHNwYW4ge1xuICAgICAgYmFja2dyb3VuZDogdmFyKC0tYWNjZW50KTtcbiAgICAgIGNvbG9yOiAjZmZmO1xuICAgIH1cbiAgICAucmVjaXBlLXN0ZXAuY29tcGxldGVkIHtcbiAgICAgIGNvbG9yOiB2YXIoLS1vay1mZyk7XG4gICAgICBib3JkZXItYm90dG9tLWNvbG9yOiB2YXIoLS1vay1mZyk7XG4gICAgfVxuICAgIC5yZWNpcGUtc3RlcC5jb21wbGV0ZWQgc3BhbiB7XG4gICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1vay1mZyk7XG4gICAgICBjb2xvcjogI2ZmZjtcbiAgICB9XG4gICAgLnJlY2lwZS1zdGVwLXBhbmVsIHtcbiAgICAgIG1pbi1oZWlnaHQ6IDE4MHB4O1xuICAgIH1cbiAgYDtcbiAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG5cbiAgLy8gPT09IElOSVQgPT09XG4gIC8vIFByZS1mZXRjaCBwcmVtaXVtIHN0YXR1cyBvbiBsb2FkXG4gIGNoZWNrUmVjaXBlUHJlbWl1bSgpO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gQ0FERFkgUkVMT0FEIEJVVFRPTiA9PT09PT09PT09XG4oZnVuY3Rpb24oKSB7XG4gIC8vIFJlbG9hZCBDYWRkeSBidXR0b24gaGFuZGxlclxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVsb2FkLWNhZGR5LXRvcCcpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBidXR0b24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVsb2FkLWNhZGR5LXRvcCcpO1xuICAgIGNvbnN0IG9yaWdpbmFsVGV4dCA9IGJ1dHRvbi50ZXh0Q29udGVudDtcblxuICAgIHRyeSB7XG4gICAgICBidXR0b24udGV4dENvbnRlbnQgPSAnXHUyM0YzIFJlbG9hZGluZy4uLic7XG4gICAgICBidXR0b24uZGlzYWJsZWQgPSB0cnVlO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2NhZGR5L3JlbG9hZCcsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgICBpZiAocmVzcG9uc2Uub2sgJiYgcmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgYnV0dG9uLnRleHRDb250ZW50ID0gJ1x1MjcwNSBSZWxvYWRlZCEnO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBidXR0b24udGV4dENvbnRlbnQgPSBvcmlnaW5hbFRleHQ7XG4gICAgICAgICAgYnV0dG9uLmRpc2FibGVkID0gZmFsc2U7XG4gICAgICAgIH0sIDIwMDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHJlc3VsdC5lcnJvciB8fCAnUmVsb2FkIGZhaWxlZCcpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBidXR0b24udGV4dENvbnRlbnQgPSAnXHUyNzRDIEZhaWxlZCc7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKGBGYWlsZWQgdG8gcmVsb2FkIENhZGR5OiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJyk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgYnV0dG9uLnRleHRDb250ZW50ID0gb3JpZ2luYWxUZXh0O1xuICAgICAgICBidXR0b24uZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgIH0sIDIwMDApO1xuICAgIH1cbiAgfSk7XG59KSgpO1xuO1xuLy8gPT09PT09PT09PSBFUlJPUiBMT0cgVklFV0VSID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgLy8gSW5qZWN0IG1vZGFsIEhUTUxcbiAgaW5qZWN0TW9kYWwoJ2Vycm9yLWxvZy1tb2RhbCcsICc8ZGl2IGlkPVwiZXJyb3ItbG9nLW1vZGFsXCIgY2xhc3M9XCJsb2dzLW1vZGFsXCI+PGRpdiBjbGFzcz1cImxvZ3MtbW9kYWwtY29udGVudFwiPjxkaXYgY2xhc3M9XCJsb2dzLWhlYWRlclwiPjxoMz5cdUQ4M0RcdURDQ0IgRXJyb3IgTG9nczwvaDM+PGRpdiBjbGFzcz1cImxvZ3MtY29udHJvbHNcIj48YnV0dG9uIGlkPVwiZXJyb3ItbG9nLXJlZnJlc2hcIiBzdHlsZT1cInBhZGRpbmc6NHB4IDEycHghaW1wb3J0YW50O2ZvbnQtc2l6ZTouODVyZW0haW1wb3J0YW50XCI+XHVEODNEXHVERDA0IFJlZnJlc2g8L2J1dHRvbj48YnV0dG9uIGlkPVwiZXJyb3ItbG9nLWNsZWFyXCIgc3R5bGU9XCJwYWRkaW5nOjRweCAxMnB4IWltcG9ydGFudDtmb250LXNpemU6Ljg1cmVtIWltcG9ydGFudDtiYWNrZ3JvdW5kOmNvbG9yLW1peChpbiBzcmdiLHZhcigtLWJhZC1mZykgMTUlLHRyYW5zcGFyZW50KSFpbXBvcnRhbnQ7Ym9yZGVyLWNvbG9yOnZhcigtLWJhZC1mZykhaW1wb3J0YW50O2NvbG9yOnZhcigtLWJhZC1mZykhaW1wb3J0YW50XCI+XHVEODNEXHVEREQxXHVGRTBGIENsZWFyPC9idXR0b24+PGJ1dHRvbiBpZD1cImVycm9yLWxvZy1jbG9zZVwiIGNsYXNzPVwiY2xvc2UtYnRuXCI+XHUyNzE1PC9idXR0b24+PC9kaXY+PC9kaXY+PGRpdiBjbGFzcz1cImxvZ3MtY29udGFpbmVyXCI+PGRpdiBpZD1cImVycm9yLWxvZy1jb250ZW50XCIgY2xhc3M9XCJsb2dzLWNvbnRlbnRcIj48ZGl2IGNsYXNzPVwibG9ncy1sb2FkaW5nXCI+TG9hZGluZyBlcnJvciBsb2dzLi4uPC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+Jyk7XG5cbiAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXJyb3ItbG9nLW1vZGFsJyk7XG4gIGNvbnN0IGNvbnRlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXJyb3ItbG9nLWNvbnRlbnQnKTtcbiAgY29uc3Qgdmlld0J0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWV3LWVycm9yLWxvZ3MnKTtcbiAgY29uc3QgcmVmcmVzaEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlcnJvci1sb2ctcmVmcmVzaCcpO1xuICBjb25zdCBjbGVhckJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlcnJvci1sb2ctY2xlYXInKTtcbiAgY29uc3QgY2xvc2VCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXJyb3ItbG9nLWNsb3NlJyk7XG5cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZEVycm9yTG9ncygpIHtcbiAgICBjb250ZW50LmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwibG9ncy1sb2FkaW5nXCI+TG9hZGluZyBlcnJvciBsb2dzLi4uPC9kaXY+JztcbiAgICBcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9lcnJvci1sb2dzJyk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgXG4gICAgICBpZiAoZGF0YS5zdWNjZXNzICYmIGRhdGEubG9ncykge1xuICAgICAgICBpZiAoZGF0YS5sb2dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGNvbnRlbnQuaW5uZXJIVE1MID0gJzxkaXYgc3R5bGU9XCJwYWRkaW5nOiAyMHB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+XHUyNzA1IE5vIGVycm9ycyBsb2dnZWQhIEV2ZXJ5dGhpbmcgaXMgd29ya2luZyBzbW9vdGhseS48L2Rpdj4nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnRlbnQuaW5uZXJIVE1MID0gZGF0YS5sb2dzLm1hcChsb2cgPT4ge1xuICAgICAgICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKGxvZy50aW1lc3RhbXApLnRvTG9jYWxlU3RyaW5nKCk7XG4gICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9nLWVudHJ5IGVycm9yXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsb2ctdGltZXN0YW1wXCI+JHtkYXRlfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxvZy1sZXZlbFwiPkVSUk9SPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2ctbWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgICAgPHN0cm9uZz4ke2VzY2FwZUh0bWwobG9nLmNvbnRleHQpfTwvc3Ryb25nPjogJHtlc2NhcGVIdG1sKGxvZy5lcnJvcil9XG4gICAgICAgICAgICAgICAgICAke2xvZy5kZXRhaWxzID8gYDxicj48c21hbGwgc3R5bGU9XCJvcGFjaXR5OiAwLjc7XCI+JHtlc2NhcGVIdG1sKGxvZy5kZXRhaWxzKX08L3NtYWxsPmAgOiAnJ31cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBgO1xuICAgICAgICAgIH0pLmpvaW4oJycpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250ZW50LmlubmVySFRNTCA9ICc8ZGl2IHN0eWxlPVwicGFkZGluZzogMjBweDsgY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+XHUyNzRDIEZhaWxlZCB0byBsb2FkIGVycm9yIGxvZ3M8L2Rpdj4nO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb250ZW50LmlubmVySFRNTCA9IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogMjBweDsgY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+XHUyNzRDIEVycm9yIGxvYWRpbmcgbG9nczogJHtlc2NhcGVIdG1sKGVycm9yLm1lc3NhZ2UpfTwvZGl2PmA7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gY2xlYXJFcnJvckxvZ3MoKSB7XG4gICAgaWYgKCFjb25maXJtKCdDbGVhciBhbGwgZXJyb3IgbG9ncz8nKSkgcmV0dXJuO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvZXJyb3ItbG9ncycsIHsgbWV0aG9kOiAnREVMRVRFJyB9KTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICBcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignXHUyNzA1IEVycm9yIGxvZ3MgY2xlYXJlZCcsICdzdWNjZXNzJywgMzAwMCk7XG4gICAgICAgIGxvYWRFcnJvckxvZ3MoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1x1Mjc0QyBGYWlsZWQgdG8gY2xlYXIgbG9ncycsICdlcnJvcicsIDMwMDApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKGBcdTI3NEMgRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCAzMDAwKTtcbiAgICB9XG4gIH1cblxuICB2aWV3QnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgbG9hZEVycm9yTG9ncygpO1xuICB9KTtcblxuICByZWZyZXNoQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGxvYWRFcnJvckxvZ3MpO1xuICBjbGVhckJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBjbGVhckVycm9yTG9ncyk7XG4gIHdpcmVNb2RhbChtb2RhbCwgY2xvc2VCdG4pO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gQ09OVEFJTkVSIExPRyBWSUVXRVIgPT09PT09PT09PVxuKGZ1bmN0aW9uKCkge1xuICAvLyBJbmplY3QgbW9kYWwgSFRNTFxuICBpbmplY3RNb2RhbCgnY29udGFpbmVyLWxvZ3MtbW9kYWwnLCBgPGRpdiBpZD1cImNvbnRhaW5lci1sb2dzLW1vZGFsXCIgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsXCIgc3R5bGU9XCJ6LWluZGV4OiAxMDAxO1wiPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogOTAwcHg7IG1heC13aWR0aDogOTV2dzsgaGVpZ2h0OiA4MHZoOyBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1wiPlxuICAgICAgPGRpdiBjbGFzcz1cImxvZ3MtaGVhZGVyXCIgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IGFsaWduLWl0ZW1zOiBjZW50ZXI7IHBhZGRpbmctYm90dG9tOiAxMnB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgbWFyZ2luLWJvdHRvbTogMTJweDtcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8aDMgc3R5bGU9XCJtYXJnaW46IDA7XCI+XHVEODNEXHVEQ0RDIENvbnRhaW5lciBMb2dzPC9oMz5cbiAgICAgICAgICA8cCBjbGFzcz1cIm1vZGFsLXN1YnRpdGxlXCIgc3R5bGU9XCJtYXJnaW46IDRweCAwIDAgMDsgZm9udC1zaXplOiAwLjg1cmVtOyBvcGFjaXR5OiAwLjc7XCI+VmlldyBhbmQgc3RyZWFtIERvY2tlciBjb250YWluZXIgbG9nczwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJsb2dzLWNvbnRyb2xzXCIgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDhweDsgYWxpZ24taXRlbXM6IGNlbnRlcjtcIj5cbiAgICAgICAgICA8c2VsZWN0IGlkPVwiY2wtY29udGFpbmVyLXNlbGVjdFwiIHN0eWxlPVwicGFkZGluZzogNnB4IDEwcHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDZweDsgYmFja2dyb3VuZDogdmFyKC0tYmcpOyBjb2xvcjogdmFyKC0tZmcpOyBtaW4td2lkdGg6IDIwMHB4O1wiPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPlNlbGVjdCBhIGNvbnRhaW5lci4uLjwvb3B0aW9uPlxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwiY2wtbG9nLXNlYXJjaFwiIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGxvZ3MuLi5cIiBzdHlsZT1cInBhZGRpbmc6IDZweCAxMHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA2cHg7IGJhY2tncm91bmQ6IHZhcigtLWJnKTsgY29sb3I6IHZhcigtLWZnKTsgd2lkdGg6IDE1MHB4O1wiIC8+XG4gICAgICAgICAgPHNlbGVjdCBpZD1cImNsLWxvZy10YWlsXCIgc3R5bGU9XCJwYWRkaW5nOiA2cHggMTBweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogNnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iZyk7IGNvbG9yOiB2YXIoLS1mZyk7XCI+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiNTBcIj5MYXN0IDUwIGxpbmVzPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiMTAwXCIgc2VsZWN0ZWQ+TGFzdCAxMDAgbGluZXM8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI1MDBcIj5MYXN0IDUwMCBsaW5lczwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjEwMDBcIj5MYXN0IDEwMDAgbGluZXM8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJhbGxcIj5BbGwgbG9nczwvb3B0aW9uPlxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJjbC1yZWZyZXNoXCIgY2xhc3M9XCJidG4tYWNjZW50LXNvbGlkXCIgc3R5bGU9XCJwYWRkaW5nOiA2cHggMTRweDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPlx1RDgzRFx1REQwNCBSZWZyZXNoPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImNsLXN0cmVhbVwiIGNsYXNzPVwiYnRuLWFjY2VudC1zb2xpZFwiIHN0eWxlPVwicGFkZGluZzogNnB4IDE0cHg7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj5cdTI1QjYgU3RyZWFtPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImNsLWRvd25sb2FkXCIgc3R5bGU9XCJwYWRkaW5nOiA2cHggMTRweDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPlx1RDgzRFx1RENCRSBEb3dubG9hZDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJjbC1jbGVhci1zZWFyY2hcIiBzdHlsZT1cInBhZGRpbmc6IDZweCAxMHB4OyBmb250LXNpemU6IDAuODVyZW07XCIgdGl0bGU9XCJDbGVhciBzZWFyY2hcIj5cdTI3MTU8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwiY2wtY2xvc2VcIiBjbGFzcz1cImNsb3NlLWJ0blwiIHN0eWxlPVwicGFkZGluZzogNnB4IDEwcHg7XCI+XHUyNzE1PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICBcbiAgICAgIDxkaXYgaWQ9XCJjbC1jb250YWluZXItaW5mb1wiIHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiAxNnB4OyBtYXJnaW4tYm90dG9tOiAxMnB4OyBwYWRkaW5nOiA4cHggMTJweDsgYmFja2dyb3VuZDogdmFyKC0tYmctc2Vjb25kYXJ5LCB2YXIoLS1iZykpOyBib3JkZXItcmFkaXVzOiA2cHg7IGZvbnQtc2l6ZTogMC44MnJlbTtcIj5cbiAgICAgICAgPHNwYW4+PHN0cm9uZz5JbWFnZTo8L3N0cm9uZz4gPHNwYW4gaWQ9XCJjbC1pbWFnZVwiPi08L3NwYW4+PC9zcGFuPlxuICAgICAgICA8c3Bhbj48c3Ryb25nPlN0YXR1czo8L3N0cm9uZz4gPHNwYW4gaWQ9XCJjbC1zdGF0dXNcIj4tPC9zcGFuPjwvc3Bhbj5cbiAgICAgICAgPHNwYW4+PHN0cm9uZz5DcmVhdGVkOjwvc3Ryb25nPiA8c3BhbiBpZD1cImNsLWNyZWF0ZWRcIj4tPC9zcGFuPjwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgICAgXG4gICAgICA8ZGl2IGlkPVwiY2wtbG9nLWNvbnRlbnRcIiBjbGFzcz1cImxvZ3MtY29udGVudCBzY3JvbGwtY29udGFpbmVyXCIgc3R5bGU9XCJmbGV4OiAxOyBtaW4taGVpZ2h0OiAwOyBiYWNrZ3JvdW5kOiAjMWExYTFhOyBib3JkZXItcmFkaXVzOiA2cHg7IHBhZGRpbmc6IDEycHg7IGZvbnQtZmFtaWx5OiAnTW9uYWNvJywgJ01lbmxvJywgJ1VidW50dSBNb25vJywgbW9ub3NwYWNlOyBmb250LXNpemU6IDAuNzhyZW07IG92ZXJmbG93OiBhdXRvO1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibG9ncy1sb2FkaW5nXCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDQwcHg7XCI+U2VsZWN0IGEgY29udGFpbmVyIHRvIHZpZXcgbG9nczwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICBcbiAgICAgIDxkaXYgaWQ9XCJjbC1zdHJlYW0tc3RhdHVzXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lOyBwYWRkaW5nOiA4cHggMTJweDsgYmFja2dyb3VuZDogdmFyKC0tb2stYmcsICMxYTNhMWEpOyBjb2xvcjogdmFyKC0tb2stZmcsICM0YWRlODApOyBib3JkZXItcmFkaXVzOiA2cHg7IG1hcmdpbi10b3A6IDhweDsgZm9udC1zaXplOiAwLjgycmVtO1wiPlxuICAgICAgICA8c3BhbiBpZD1cImNsLXN0cmVhbS1pbmRpY2F0b3JcIj5cdUQ4M0RcdUREMzQ8L3NwYW4+IDxzcGFuIGlkPVwiY2wtc3RyZWFtLXRleHRcIj5EaXNjb25uZWN0ZWQ8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICAgIFxuICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxMnB4OyBwYWRkaW5nLXRvcDogMTJweDsgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDhweDsgZm9udC1zaXplOiAwLjc4cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlxuICAgICAgICAgIDxzcGFuIGlkPVwiY2wtbGluZS1jb3VudFwiPjAgbGluZXM8L3NwYW4+XG4gICAgICAgICAgPHNwYW4+fDwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBpZD1cImNsLWZpbHRlci1jb3VudFwiPjAgZmlsdGVyZWQ8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8YnV0dG9uIGlkPVwiY2wtY2xvc2UtYnRuXCIgY2xhc3M9XCJidG4tc2Vjb25kYXJ5XCI+Q2xvc2U8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5gKTtcblxuICBjb25zdCBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb250YWluZXItbG9ncy1tb2RhbCcpO1xuICBjb25zdCBjb250YWluZXJTZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2wtY29udGFpbmVyLXNlbGVjdCcpO1xuICBjb25zdCBsb2dDb250ZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NsLWxvZy1jb250ZW50Jyk7XG4gIGNvbnN0IGxvZ1NlYXJjaCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1sb2ctc2VhcmNoJyk7XG4gIGNvbnN0IGxvZ1RhaWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2wtbG9nLXRhaWwnKTtcbiAgY29uc3QgcmVmcmVzaEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1yZWZyZXNoJyk7XG4gIGNvbnN0IHN0cmVhbUJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1zdHJlYW0nKTtcbiAgY29uc3QgZG93bmxvYWRCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2wtZG93bmxvYWQnKTtcbiAgY29uc3QgY2xlYXJTZWFyY2hCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2wtY2xlYXItc2VhcmNoJyk7XG4gIGNvbnN0IGNsb3NlQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NsLWNsb3NlJyk7XG4gIGNvbnN0IGNsb3NlQnRuMiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1jbG9zZS1idG4nKTtcbiAgY29uc3Qgc3RyZWFtU3RhdHVzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NsLXN0cmVhbS1zdGF0dXMnKTtcbiAgY29uc3Qgc3RyZWFtSW5kaWNhdG9yID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NsLXN0cmVhbS1pbmRpY2F0b3InKTtcbiAgY29uc3Qgc3RyZWFtVGV4dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1zdHJlYW0tdGV4dCcpO1xuICBjb25zdCBsaW5lQ291bnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2wtbGluZS1jb3VudCcpO1xuICBjb25zdCBmaWx0ZXJDb3VudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1maWx0ZXItY291bnQnKTtcbiAgXG4gIC8vIENvbnRhaW5lciBpbmZvIGVsZW1lbnRzXG4gIGNvbnN0IGltYWdlRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2wtaW1hZ2UnKTtcbiAgY29uc3Qgc3RhdHVzRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2wtc3RhdHVzJyk7XG4gIGNvbnN0IGNyZWF0ZWRFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbC1jcmVhdGVkJyk7XG5cbiAgbGV0IGN1cnJlbnRDb250YWluZXJJZCA9IG51bGw7XG4gIGxldCBjdXJyZW50TG9ncyA9IFtdO1xuICBsZXQgZmlsdGVyZWRMb2dzID0gW107XG4gIGxldCBldmVudFNvdXJjZSA9IG51bGw7XG4gIGxldCBpc1N0cmVhbWluZyA9IGZhbHNlO1xuICBsZXQgc2VhcmNoVGltZW91dCA9IG51bGw7XG5cbiAgLy8gRm9ybWF0IGRhdGVcbiAgZnVuY3Rpb24gZm9ybWF0RGF0ZShkYXRlU3RyKSB7XG4gICAgaWYgKCFkYXRlU3RyKSByZXR1cm4gJy0nO1xuICAgIGNvbnN0IGQgPSBuZXcgRGF0ZShkYXRlU3RyKTtcbiAgICBpZiAoaXNOYU4oZC5nZXRUaW1lKCkpKSByZXR1cm4gZGF0ZVN0cjtcbiAgICByZXR1cm4gZC50b0xvY2FsZVN0cmluZygpO1xuICB9XG5cbiAgLy8gRXNjYXBlIEhUTUxcbiAgZnVuY3Rpb24gZXNjYXBlSHRtbChzdHIpIHtcbiAgICBpZiAoIXN0cikgcmV0dXJuICcnO1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi50ZXh0Q29udGVudCA9IHN0cjtcbiAgICByZXR1cm4gZGl2LmlubmVySFRNTDtcbiAgfVxuXG4gIC8vIEZvcm1hdCBsb2cgZW50cnkgZm9yIGRpc3BsYXlcbiAgZnVuY3Rpb24gZm9ybWF0TG9nRW50cnkobG9nLCBpbmRleCkge1xuICAgIGNvbnN0IHN0cmVhbUNsYXNzID0gbG9nLnN0cmVhbSA9PT0gJ3N0ZGVycicgPyAnbG9nLXN0ZGVycicgOiAnbG9nLXN0ZG91dCc7XG4gICAgY29uc3Qgc3RyZWFtSWNvbiA9IGxvZy5zdHJlYW0gPT09ICdzdGRlcnInID8gJ1x1MjZBMFx1RkUwRicgOiAnXHVEODNEXHVEQ0U0JztcbiAgICByZXR1cm4gYFxuICAgICAgPGRpdiBjbGFzcz1cImxvZy1lbnRyeSAke3N0cmVhbUNsYXNzfVwiIGRhdGEtaW5kZXg9XCIke2luZGV4fVwiIHN0eWxlPVwicGFkZGluZzogNHB4IDhweDsgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICMzMzM7IGRpc3BsYXk6IGZsZXg7IGdhcDogOHB4O1wiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImxvZy1saW5lLW51bVwiIHN0eWxlPVwiY29sb3I6ICM2NjY7IG1pbi13aWR0aDogNDBweDsgdGV4dC1hbGlnbjogcmlnaHQ7IHVzZXItc2VsZWN0OiBub25lO1wiPiR7aW5kZXggKyAxfTwvc3Bhbj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJsb2ctc3RyZWFtLWljb25cIiBzdHlsZT1cImNvbG9yOiAke2xvZy5zdHJlYW0gPT09ICdzdGRlcnInID8gJyNmNTllMGInIDogJyMyMmM1NWUnfTtcIj4ke3N0cmVhbUljb259PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImxvZy10ZXh0XCIgc3R5bGU9XCJmbGV4OiAxOyB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IHdvcmQtYnJlYWs6IGJyZWFrLWFsbDsgY29sb3I6ICNlNWU1ZTU7XCI+JHtlc2NhcGVIdG1sKGxvZy50ZXh0KX08L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICBgO1xuICB9XG5cbiAgLy8gUmVuZGVyIGxvZ3MgdG8gdGhlIGNvbnRlbnQgYXJlYVxuICBmdW5jdGlvbiByZW5kZXJMb2dzKGxvZ3MsIHNlYXJjaFRlcm0gPSAnJykge1xuICAgIGlmICghbG9ncyB8fCBsb2dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgbG9nQ29udGVudC5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cImxvZ3MtbG9hZGluZ1wiIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgdGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiA0MHB4O1wiPk5vIGxvZ3MgYXZhaWxhYmxlPC9kaXY+JztcbiAgICAgIGxpbmVDb3VudC50ZXh0Q29udGVudCA9ICcwIGxpbmVzJztcbiAgICAgIGZpbHRlckNvdW50LnRleHRDb250ZW50ID0gJzAgZmlsdGVyZWQnO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGN1cnJlbnRMb2dzID0gbG9ncztcbiAgICBmaWx0ZXJlZExvZ3MgPSBzZWFyY2hUZXJtID8gbG9ncy5maWx0ZXIobG9nID0+IFxuICAgICAgbG9nLnRleHQgJiYgbG9nLnRleHQudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhzZWFyY2hUZXJtLnRvTG93ZXJDYXNlKCkpXG4gICAgKSA6IGxvZ3M7XG5cbiAgICBsaW5lQ291bnQudGV4dENvbnRlbnQgPSBgJHtsb2dzLmxlbmd0aH0gbGluZXNgO1xuICAgIGZpbHRlckNvdW50LnRleHRDb250ZW50ID0gc2VhcmNoVGVybSA/IGAke2ZpbHRlcmVkTG9ncy5sZW5ndGh9IG9mICR7bG9ncy5sZW5ndGh9IHNob3duYCA6IGAke2xvZ3MubGVuZ3RofSBzaG93bmA7XG5cbiAgICBpZiAoZmlsdGVyZWRMb2dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgbG9nQ29udGVudC5pbm5lckhUTUwgPSBgPGRpdiBjbGFzcz1cImxvZ3MtbG9hZGluZ1wiIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgdGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiA0MHB4O1wiPk5vIGxvZ3MgbWF0Y2ggXCIke2VzY2FwZUh0bWwoc2VhcmNoVGVybSl9XCI8L2Rpdj5gO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxvZ0NvbnRlbnQuaW5uZXJIVE1MID0gZmlsdGVyZWRMb2dzLm1hcCgobG9nLCBpKSA9PiBmb3JtYXRMb2dFbnRyeShsb2csIGkpKS5qb2luKCcnKTtcbiAgICBcbiAgICAvLyBTY3JvbGwgdG8gYm90dG9tXG4gICAgbG9nQ29udGVudC5zY3JvbGxUb3AgPSBsb2dDb250ZW50LnNjcm9sbEhlaWdodDtcbiAgfVxuXG4gIC8vIExvYWQgY29udGFpbmVyIGxpc3RcbiAgYXN5bmMgZnVuY3Rpb24gbG9hZENvbnRhaW5lcnMoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBnZXRKU09OKCcvYXBpL3YxL2xvZ3MvY29udGFpbmVycycpO1xuICAgICAgY29uc3QgY29udGFpbmVycyA9IGRhdGEuY29udGFpbmVycyB8fCBbXTtcbiAgICAgIFxuICAgICAgLy8gU3RvcmUgY3VycmVudCBzZWxlY3Rpb25cbiAgICAgIGNvbnN0IGN1cnJlbnRWYWwgPSBjb250YWluZXJTZWxlY3QudmFsdWU7XG4gICAgICBcbiAgICAgIGNvbnRhaW5lclNlbGVjdC5pbm5lckhUTUwgPSAnPG9wdGlvbiB2YWx1ZT1cIlwiPlNlbGVjdCBhIGNvbnRhaW5lci4uLjwvb3B0aW9uPic7XG4gICAgICBcbiAgICAgIGNvbnRhaW5lcnMuZm9yRWFjaChjID0+IHtcbiAgICAgICAgY29uc3Qgb3B0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb3B0aW9uJyk7XG4gICAgICAgIG9wdGlvbi52YWx1ZSA9IGMuaWQ7XG4gICAgICAgIG9wdGlvbi50ZXh0Q29udGVudCA9IGAke2MubmFtZX0gKCR7Yy5pbWFnZS5zcGxpdCgnOicpWzBdfSkgLSAke2Muc3RhdHVzfWA7XG4gICAgICAgIG9wdGlvbi5kYXRhc2V0Lm5hbWUgPSBjLm5hbWU7XG4gICAgICAgIG9wdGlvbi5kYXRhc2V0LmltYWdlID0gYy5pbWFnZTtcbiAgICAgICAgb3B0aW9uLmRhdGFzZXQuc3RhdHVzID0gYy5zdGF0dXM7XG4gICAgICAgIG9wdGlvbi5kYXRhc2V0LmNyZWF0ZWQgPSBjLmNyZWF0ZWQ7XG4gICAgICAgIGNvbnRhaW5lclNlbGVjdC5hcHBlbmRDaGlsZChvcHRpb24pO1xuICAgICAgfSk7XG4gICAgICBcbiAgICAgIC8vIFJlc3RvcmUgc2VsZWN0aW9uIGlmIHN0aWxsIHZhbGlkXG4gICAgICBpZiAoY3VycmVudFZhbCAmJiBjb250YWluZXJTZWxlY3QucXVlcnlTZWxlY3Rvcihgb3B0aW9uW3ZhbHVlPVwiJHtjdXJyZW50VmFsfVwiXWApKSB7XG4gICAgICAgIGNvbnRhaW5lclNlbGVjdC52YWx1ZSA9IGN1cnJlbnRWYWw7XG4gICAgICAgIGxvYWRDb250YWluZXJJbmZvKGN1cnJlbnRWYWwpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGxvYWQgY29udGFpbmVyczonLCBlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIExvYWQgY29udGFpbmVyIGluZm9cbiAgZnVuY3Rpb24gbG9hZENvbnRhaW5lckluZm8oY29udGFpbmVySWQpIHtcbiAgICBjb25zdCBvcHRpb24gPSBjb250YWluZXJTZWxlY3QucXVlcnlTZWxlY3Rvcihgb3B0aW9uW3ZhbHVlPVwiJHtjb250YWluZXJJZH1cIl1gKTtcbiAgICBpZiAob3B0aW9uKSB7XG4gICAgICBpbWFnZUVsLnRleHRDb250ZW50ID0gb3B0aW9uLmRhdGFzZXQuaW1hZ2UgfHwgJy0nO1xuICAgICAgc3RhdHVzRWwudGV4dENvbnRlbnQgPSBvcHRpb24uZGF0YXNldC5zdGF0dXMgfHwgJy0nO1xuICAgICAgc3RhdHVzRWwuc3R5bGUuY29sb3IgPSBvcHRpb24uZGF0YXNldC5zdGF0dXMgPT09ICdydW5uaW5nJyA/ICd2YXIoLS1vay1mZywgIzRhZGU4MCknIDogJ3ZhcigtLWJhZC1mZywgI2VmNDQ0NCknO1xuICAgICAgY3JlYXRlZEVsLnRleHRDb250ZW50ID0gZm9ybWF0RGF0ZShvcHRpb24uZGF0YXNldC5jcmVhdGVkKTtcbiAgICB9XG4gIH1cblxuICAvLyBMb2FkIGxvZ3MgZm9yIHNlbGVjdGVkIGNvbnRhaW5lclxuICBhc3luYyBmdW5jdGlvbiBsb2FkTG9ncygpIHtcbiAgICBjb25zdCBjb250YWluZXJJZCA9IGNvbnRhaW5lclNlbGVjdC52YWx1ZTtcbiAgICBpZiAoIWNvbnRhaW5lcklkKSB7XG4gICAgICBsb2dDb250ZW50LmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwibG9ncy1sb2FkaW5nXCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDQwcHg7XCI+U2VsZWN0IGEgY29udGFpbmVyIHRvIHZpZXcgbG9nczwvZGl2Pic7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU3RvcCBhbnkgZXhpc3Rpbmcgc3RyZWFtXG4gICAgc3RvcFN0cmVhbSgpO1xuXG4gICAgY3VycmVudENvbnRhaW5lcklkID0gY29udGFpbmVySWQ7XG4gICAgbG9hZENvbnRhaW5lckluZm8oY29udGFpbmVySWQpO1xuXG4gICAgY29uc3QgdGFpbCA9IGxvZ1RhaWwudmFsdWU7XG4gICAgY29uc3Qgc2VhcmNoVGVybSA9IGxvZ1NlYXJjaC52YWx1ZS50cmltKCk7XG5cbiAgICBsb2dDb250ZW50LmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwibG9ncy1sb2FkaW5nXCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDQwcHg7XCI+TG9hZGluZyBsb2dzLi4uPC9kaXY+JztcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB1cmwgPSBgL2FwaS92MS9sb2dzL2NvbnRhaW5lci8ke2NvbnRhaW5lcklkfSR7dGFpbCAhPT0gJ2FsbCcgPyBgP3RhaWw9JHt0YWlsfWAgOiAnJ31gO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IGdldEpTT04odXJsKTtcblxuICAgICAgaWYgKGRhdGEubG9ncyAmJiBkYXRhLmxvZ3MubGVuZ3RoID4gMCkge1xuICAgICAgICByZW5kZXJMb2dzKGRhdGEubG9ncywgc2VhcmNoVGVybSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dDb250ZW50LmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwibG9ncy1sb2FkaW5nXCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDQwcHg7XCI+Tm8gbG9ncyBmb3VuZCBmb3IgdGhpcyBjb250YWluZXI8L2Rpdj4nO1xuICAgICAgICBsaW5lQ291bnQudGV4dENvbnRlbnQgPSAnMCBsaW5lcyc7XG4gICAgICAgIGZpbHRlckNvdW50LnRleHRDb250ZW50ID0gJzAgZmlsdGVyZWQnO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgbG9nQ29udGVudC5pbm5lckhUTUwgPSBgPGRpdiBjbGFzcz1cImxvZ3MtbG9hZGluZ1wiIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZywgI2VmNDQ0NCk7IHRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogNDBweDtcIj5FcnJvciBsb2FkaW5nIGxvZ3M6ICR7ZXNjYXBlSHRtbChlcnIubWVzc2FnZSl9PC9kaXY+YDtcbiAgICB9XG4gIH1cblxuICAvLyBTdGFydCBzdHJlYW1pbmcgbG9nc1xuICBmdW5jdGlvbiBzdGFydFN0cmVhbSgpIHtcbiAgICBjb25zdCBjb250YWluZXJJZCA9IGNvbnRhaW5lclNlbGVjdC52YWx1ZTtcbiAgICBpZiAoIWNvbnRhaW5lcklkKSByZXR1cm47XG5cbiAgICAvLyBTdG9wIGFueSBleGlzdGluZyBzdHJlYW1cbiAgICBzdG9wU3RyZWFtKCk7XG5cbiAgICBpc1N0cmVhbWluZyA9IHRydWU7XG4gICAgc3RyZWFtQnRuLnRleHRDb250ZW50ID0gJ1x1MjNGOSBTdG9wJztcbiAgICBzdHJlYW1TdGF0dXMuc3R5bGUuZGlzcGxheSA9ICdmbGV4JztcbiAgICBzdHJlYW1JbmRpY2F0b3IudGV4dENvbnRlbnQgPSAnXHVEODNEXHVERkUyJztcbiAgICBzdHJlYW1UZXh0LnRleHRDb250ZW50ID0gJ0Nvbm5lY3RpbmcuLi4nO1xuXG4gICAgY29uc3QgdXJsID0gYC9hcGkvdjEvbG9ncy9zdHJlYW0vJHtjb250YWluZXJJZH1gO1xuICAgIGV2ZW50U291cmNlID0gbmV3IEV2ZW50U291cmNlKHVybCk7XG5cbiAgICBldmVudFNvdXJjZS5vbm9wZW4gPSAoKSA9PiB7XG4gICAgICBzdHJlYW1JbmRpY2F0b3IudGV4dENvbnRlbnQgPSAnXHVEODNEXHVERkUyJztcbiAgICAgIHN0cmVhbVRleHQudGV4dENvbnRlbnQgPSAnQ29ubmVjdGVkIC0gc3RyZWFtaW5nIGxvZ3MnO1xuICAgIH07XG5cbiAgICBldmVudFNvdXJjZS5vbm1lc3NhZ2UgPSAoZXZlbnQpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGxvZyA9IEpTT04ucGFyc2UoZXZlbnQuZGF0YSk7XG4gICAgICAgIFxuICAgICAgICBpZiAobG9nLmVycm9yKSB7XG4gICAgICAgICAgc3RyZWFtSW5kaWNhdG9yLnRleHRDb250ZW50ID0gJ1x1RDgzRFx1REQzNCc7XG4gICAgICAgICAgc3RyZWFtVGV4dC50ZXh0Q29udGVudCA9IGBFcnJvcjogJHtsb2cuZXJyb3J9YDtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgdG8gY3VycmVudCBsb2dzXG4gICAgICAgIGN1cnJlbnRMb2dzLnB1c2gobG9nKTtcbiAgICAgICAgZmlsdGVyZWRMb2dzLnB1c2gobG9nKTtcbiAgICAgICAgXG4gICAgICAgIC8vIFVwZGF0ZSBjb3VudHNcbiAgICAgICAgbGluZUNvdW50LnRleHRDb250ZW50ID0gYCR7Y3VycmVudExvZ3MubGVuZ3RofSBsaW5lc2A7XG4gICAgICAgIGZpbHRlckNvdW50LnRleHRDb250ZW50ID0gYCR7ZmlsdGVyZWRMb2dzLmxlbmd0aH0gc2hvd25gO1xuICAgICAgICBcbiAgICAgICAgLy8gQXBwZW5kIG5ldyBsb2cgZW50cnlcbiAgICAgICAgY29uc3Qgc2VhcmNoVGVybSA9IGxvZ1NlYXJjaC52YWx1ZS50cmltKCk7XG4gICAgICAgIGlmICghc2VhcmNoVGVybSB8fCAobG9nLnRleHQgJiYgbG9nLnRleHQudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhzZWFyY2hUZXJtLnRvTG93ZXJDYXNlKCkpKSkge1xuICAgICAgICAgIGNvbnN0IGVudHJ5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgZW50cnkuaW5uZXJIVE1MID0gZm9ybWF0TG9nRW50cnkobG9nLCBmaWx0ZXJlZExvZ3MubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgY29uc3QgZW50cnlEaXYgPSBlbnRyeS5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICAgICAgICBlbnRyeURpdi5zdHlsZS5iYWNrZ3JvdW5kID0gJyMxYTNhMWEnO1xuICAgICAgICAgIGxvZ0NvbnRlbnQuYXBwZW5kQ2hpbGQoZW50cnlEaXYpO1xuICAgICAgICAgIFxuICAgICAgICAgIC8vIEF1dG8tc2Nyb2xsIHRvIGJvdHRvbVxuICAgICAgICAgIGxvZ0NvbnRlbnQuc2Nyb2xsVG9wID0gbG9nQ29udGVudC5zY3JvbGxIZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgcGFyc2luZyBsb2c6JywgZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGV2ZW50U291cmNlLm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICBzdHJlYW1JbmRpY2F0b3IudGV4dENvbnRlbnQgPSAnXHVEODNEXHVERDM0JztcbiAgICAgIHN0cmVhbVRleHQudGV4dENvbnRlbnQgPSAnRGlzY29ubmVjdGVkJztcbiAgICAgIGlzU3RyZWFtaW5nID0gZmFsc2U7XG4gICAgICBzdHJlYW1CdG4udGV4dENvbnRlbnQgPSAnXHUyNUI2IFN0cmVhbSc7XG4gICAgfTtcblxuICAgIC8vIFN0b3JlIHRoZSBFdmVudFNvdXJjZSBmb3IgY2xlYW51cFxuICAgIG1vZGFsLl9ldmVudFNvdXJjZSA9IGV2ZW50U291cmNlO1xuICB9XG5cbiAgLy8gU3RvcCBzdHJlYW1pbmcgbG9nc1xuICBmdW5jdGlvbiBzdG9wU3RyZWFtKCkge1xuICAgIGlmIChldmVudFNvdXJjZSkge1xuICAgICAgZXZlbnRTb3VyY2UuY2xvc2UoKTtcbiAgICAgIGV2ZW50U291cmNlID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKG1vZGFsLl9ldmVudFNvdXJjZSkge1xuICAgICAgbW9kYWwuX2V2ZW50U291cmNlLmNsb3NlKCk7XG4gICAgICBtb2RhbC5fZXZlbnRTb3VyY2UgPSBudWxsO1xuICAgIH1cbiAgICBpc1N0cmVhbWluZyA9IGZhbHNlO1xuICAgIHN0cmVhbUJ0bi50ZXh0Q29udGVudCA9ICdcdTI1QjYgU3RyZWFtJztcbiAgICBzdHJlYW1TdGF0dXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgfVxuXG4gIC8vIERvd25sb2FkIGxvZ3MgYXMgZmlsZVxuICBmdW5jdGlvbiBkb3dubG9hZExvZ3MoKSB7XG4gICAgaWYgKCFjdXJyZW50TG9ncyB8fCBjdXJyZW50TG9ncy5sZW5ndGggPT09IDApIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ05vIGxvZ3MgdG8gZG93bmxvYWQnLCAnZXJyb3InKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjb250YWluZXJOYW1lID0gY29udGFpbmVyU2VsZWN0LnF1ZXJ5U2VsZWN0b3IoYG9wdGlvblt2YWx1ZT1cIiR7Y3VycmVudENvbnRhaW5lcklkfVwiXWApPy5kYXRhc2V0Lm5hbWUgfHwgY3VycmVudENvbnRhaW5lcklkO1xuICAgIGNvbnN0IHRpbWVzdGFtcCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKS5yZXBsYWNlKC9bOi5dL2csICctJyk7XG4gICAgY29uc3QgZmlsZW5hbWUgPSBgJHtjb250YWluZXJOYW1lfS1sb2dzLSR7dGltZXN0YW1wfS50eHRgO1xuXG4gICAgY29uc3QgY29udGVudCA9IGN1cnJlbnRMb2dzLm1hcChsb2cgPT4ge1xuICAgICAgY29uc3QgdGltZXN0YW1wID0gbG9nLnRpbWVzdGFtcCB8fCAnJztcbiAgICAgIGNvbnN0IHN0cmVhbSA9IGxvZy5zdHJlYW0gPT09ICdzdGRlcnInID8gJ1tFUlJdJyA6ICdbT1VUXSc7XG4gICAgICByZXR1cm4gYCR7dGltZXN0YW1wID8gdGltZXN0YW1wICsgJyAnIDogJyd9JHtzdHJlYW19ICR7bG9nLnRleHR9YDtcbiAgICB9KS5qb2luKCdcXG4nKTtcblxuICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbY29udGVudF0sIHsgdHlwZTogJ3RleHQvcGxhaW4nIH0pO1xuICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgY29uc3QgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBhLmhyZWYgPSB1cmw7XG4gICAgYS5kb3dubG9hZCA9IGZpbGVuYW1lO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG4gICAgYS5jbGljaygpO1xuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoYSk7XG4gICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuXG4gICAgc2hvd05vdGlmaWNhdGlvbihgRG93bmxvYWRlZCAke2N1cnJlbnRMb2dzLmxlbmd0aH0gbG9nIGxpbmVzYCwgJ3N1Y2Nlc3MnKTtcbiAgfVxuXG4gIC8vIEV2ZW50IGxpc3RlbmVyc1xuICBjb250YWluZXJTZWxlY3Q/LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsICgpID0+IHtcbiAgICBsb2FkTG9ncygpO1xuICB9KTtcblxuICBsb2dUYWlsPy5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgbG9hZExvZ3MoKTtcbiAgfSk7XG5cbiAgcmVmcmVzaEJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgbG9hZExvZ3MoKTtcbiAgfSk7XG5cbiAgc3RyZWFtQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBpZiAoaXNTdHJlYW1pbmcpIHtcbiAgICAgIHN0b3BTdHJlYW0oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhcnRTdHJlYW0oKTtcbiAgICB9XG4gIH0pO1xuXG4gIGRvd25sb2FkQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBkb3dubG9hZExvZ3MoKTtcbiAgfSk7XG5cbiAgY2xlYXJTZWFyY2hCdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIGxvZ1NlYXJjaC52YWx1ZSA9ICcnO1xuICAgIHJlbmRlckxvZ3MoY3VycmVudExvZ3MsICcnKTtcbiAgfSk7XG5cbiAgbG9nU2VhcmNoPy5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsICgpID0+IHtcbiAgICAvLyBEZWJvdW5jZSBzZWFyY2hcbiAgICBjbGVhclRpbWVvdXQoc2VhcmNoVGltZW91dCk7XG4gICAgc2VhcmNoVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgcmVuZGVyTG9ncyhjdXJyZW50TG9ncywgbG9nU2VhcmNoLnZhbHVlLnRyaW0oKSk7XG4gICAgfSwgMzAwKTtcbiAgfSk7XG5cbiAgbG9nU2VhcmNoPy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgKGUpID0+IHtcbiAgICBpZiAoZS5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICBsb2dTZWFyY2gudmFsdWUgPSAnJztcbiAgICAgIHJlbmRlckxvZ3MoY3VycmVudExvZ3MsICcnKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIE9wZW4gbW9kYWxcbiAgY29uc3Qgb3BlbkJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWV3LWNvbnRhaW5lci1sb2dzJyk7XG4gIG9wZW5CdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTtcbiAgICBsb2FkQ29udGFpbmVycygpO1xuICB9KTtcblxuICAvLyBDbG9zZSBtb2RhbCBoYW5kbGVyc1xuICBmdW5jdGlvbiBjbG9zZU1vZGFsKCkge1xuICAgIHN0b3BTdHJlYW0oKTtcbiAgICBtb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gIH1cblxuICBjbG9zZUJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBjbG9zZU1vZGFsKTtcbiAgY2xvc2VCdG4yPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGNsb3NlTW9kYWwpO1xuXG4gIC8vIENsb3NlIG9uIGVzY2FwZSBrZXlcbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChlKSA9PiB7XG4gICAgaWYgKGUua2V5ID09PSAnRXNjYXBlJyAmJiBtb2RhbC5jbGFzc0xpc3QuY29udGFpbnMoJ3Nob3cnKSkge1xuICAgICAgY2xvc2VNb2RhbCgpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gV2lyZSBiYWNrZHJvcCBjbGljayB0byBjbG9zZU1vZGFsIHNvIHRoZSBsb2cgc3RyZWFtIHN0b3BzIHRvby5cbiAgLy8gKENhbid0IHVzZSB3aXJlTW9kYWwgaGVyZSBcdTIwMTQgaXQgb25seSBkb2VzIG1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKVxuICAvLyBvbiBiYWNrZHJvcCBjbGljaywgd2hpY2ggd291bGQgbGVhayB0aGUgU1NFL3N0cmVhbSBjb25uZWN0aW9uLilcbiAgbW9kYWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4geyBpZiAoZS50YXJnZXQgPT09IG1vZGFsKSBjbG9zZU1vZGFsKCk7IH0pO1xuXG4gIC8vIEV4cG9zZSBmb3IgdXNlIGJ5IHNlcnZpY2UgY2FyZCBidXR0b25zIChncmlkLmpzIGNhbGxzIG9wZW5Db250YWluZXJMb2dzTW9kYWwpXG4gIHdpbmRvdy5vcGVuQ29udGFpbmVyTG9nc01vZGFsID0gZnVuY3Rpb24oY29udGFpbmVySWQsIGNvbnRhaW5lck5hbWUpIHtcbiAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgbG9hZENvbnRhaW5lcnMoKS50aGVuKCgpID0+IHtcbiAgICAgIC8vIFRyeSB0byBmaW5kIGFuZCBzZWxlY3QgdGhlIGNvbnRhaW5lclxuICAgICAgY29uc3Qgb3B0aW9uID0gQXJyYXkuZnJvbShjb250YWluZXJTZWxlY3Qub3B0aW9ucykuZmluZChvcHQgPT4gXG4gICAgICAgIG9wdC52YWx1ZSA9PT0gY29udGFpbmVySWQgfHwgb3B0LmRhdGFzZXQubmFtZSA9PT0gY29udGFpbmVyTmFtZVxuICAgICAgKTtcbiAgICAgIGlmIChvcHRpb24pIHtcbiAgICAgICAgY29udGFpbmVyU2VsZWN0LnZhbHVlID0gb3B0aW9uLnZhbHVlO1xuICAgICAgICBsb2FkQ29udGFpbmVySW5mbyhvcHRpb24udmFsdWUpO1xuICAgICAgICBsb2FkTG9ncygpO1xuICAgICAgfSBlbHNlIGlmIChjb250YWluZXJJZCkge1xuICAgICAgICAvLyBJZiBjb250YWluZXIgbm90IGZvdW5kIGluIGxpc3QgYnV0IHdlIGhhdmUgYW4gSUQsIHRyeSBsb2FkaW5nIGRpcmVjdGx5XG4gICAgICAgIGN1cnJlbnRDb250YWluZXJJZCA9IGNvbnRhaW5lcklkO1xuICAgICAgICBpbWFnZUVsLnRleHRDb250ZW50ID0gY29udGFpbmVyTmFtZSB8fCBjb250YWluZXJJZDtcbiAgICAgICAgc3RhdHVzRWwudGV4dENvbnRlbnQgPSAnLSc7XG4gICAgICAgIGNyZWF0ZWRFbC50ZXh0Q29udGVudCA9ICctJztcbiAgICAgICAgbG9hZExvZ3MoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE5vIGNvbnRhaW5lciBJRCwganVzdCBzaG93IG1vZGFsIHdpdGggY29udGFpbmVyIGxpc3RcbiAgICAgICAgbG9nQ29udGVudC5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cImxvZ3MtbG9hZGluZ1wiIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgdGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiA0MHB4O1wiPlNlbGVjdCBhIGNvbnRhaW5lciB0byB2aWV3IGxvZ3M8L2Rpdj4nO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gQ09OVEFJTkVSIFNOQVBTSE9UIC8gQ0hFQ0tQT0lOVCA9PT09PT09PT09XG4oZnVuY3Rpb24oKSB7XG4gIC8vIEluamVjdCBtb2RhbCBIVE1MXG4gIGluamVjdE1vZGFsKCdzbmFwc2hvdC1tb2RhbCcsIGA8ZGl2IGlkPVwic25hcHNob3QtbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1jb250ZW50XCIgc3R5bGU9XCJtaW4td2lkdGg6IDcwMHB4OyBtYXgtd2lkdGg6IDg1MHB4O1wiPlxuICAgICAgPGgzPlx1RDgzRFx1RENCRSBDb250YWluZXIgU25hcHNob3RzPC9oMz5cbiAgICAgIDxwIGNsYXNzPVwibW9kYWwtc3VidGl0bGVcIj5cbiAgICAgICAgQ3JlYXRlIGFuZCBtYW5hZ2UgRG9ja2VyIGNvbnRhaW5lciBjaGVja3BvaW50cyBmb3IgaW5zdGFudCBzdGF0ZSByZWNvdmVyeS5cbiAgICAgIDwvcD5cblxuICAgICAgPGRpdiBpZD1cInNuYXBzaG90LWNvbnRhaW5lci1zZWxlY3Qtd3JhcHBlclwiIHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTZweDtcIj5cbiAgICAgICAgPGxhYmVsIHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlNlbGVjdCBDb250YWluZXI6PC9sYWJlbD5cbiAgICAgICAgPHNlbGVjdCBpZD1cInNuYXBzaG90LWNvbnRhaW5lci1zZWxlY3RcIiBzdHlsZT1cIndpZHRoOiAxMDAlOyBwYWRkaW5nOiA4cHggMTJweDsgbWFyZ2luLXRvcDogNHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1iZyk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDZweDsgY29sb3I6IHZhcigtLWZnKTsgZm9udC1zaXplOiAwLjlyZW07XCI+XG4gICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIFNlbGVjdCBhIGNvbnRhaW5lciAtLTwvb3B0aW9uPlxuICAgICAgICA8L3NlbGVjdD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGlkPVwic25hcHNob3QtZGV0YWlsc1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTsgbWFyZ2luLWJvdHRvbTogMTZweDsgcGFkZGluZzogMTJweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogOHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWhvdmVyKTtcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdyaWQtdGVtcGxhdGUtY29sdW1uczogMWZyIDFmcjsgZ2FwOiA4cHg7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj5cbiAgICAgICAgICA8ZGl2PjxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj5JbWFnZTo8L3NwYW4+IDxzcGFuIGlkPVwic25hcHNob3QtaW1hZ2VcIj48L3NwYW4+PC9kaXY+XG4gICAgICAgICAgPGRpdj48c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+U3RhdHVzOjwvc3Bhbj4gPHNwYW4gaWQ9XCJzbmFwc2hvdC1zdGF0dXNcIj48L3NwYW4+PC9kaXY+XG4gICAgICAgICAgPGRpdj48c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+Q3JlYXRlZDo8L3NwYW4+IDxzcGFuIGlkPVwic25hcHNob3QtY3JlYXRlZFwiPjwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICA8ZGl2PjxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj5Db250YWluZXIgSUQ6PC9zcGFuPiA8c3BhbiBpZD1cInNuYXBzaG90LWlkXCIgc3R5bGU9XCJmb250LWZhbWlseTogbW9ub3NwYWNlO1wiPjwvc3Bhbj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLXRhYnNcIiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDEycHg7XCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWIgYWN0aXZlXCIgZGF0YS1wYW5lbD1cInNuYXBzaG90LWNyZWF0ZVwiPkNyZWF0ZSBTbmFwc2hvdDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwicGFuZWwtdGFiXCIgZGF0YS1wYW5lbD1cInNuYXBzaG90LWxpc3RcIj5NYW5hZ2UgU25hcHNob3RzPC9idXR0b24+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBpZD1cInNuYXBzaG90LWNyZWF0ZVwiIGNsYXNzPVwicGFuZWwtc2VjdGlvbiBhY3RpdmVcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDEycHg7XCI+XG4gICAgICAgICAgPGxhYmVsIHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlNuYXBzaG90IE5hbWU6PC9sYWJlbD5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cInNuYXBzaG90LW5hbWVcIiBwbGFjZWhvbGRlcj1cImUuZy4sIGJlZm9yZS11cGRhdGUtMjAyNFwiIFxuICAgICAgICAgICAgc3R5bGU9XCJ3aWR0aDogMTAwJTsgcGFkZGluZzogOHB4IDEycHg7IG1hcmdpbi10b3A6IDRweDsgYmFja2dyb3VuZDogdmFyKC0tYmcpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA2cHg7IGNvbG9yOiB2YXIoLS1mZyk7IGZvbnQtc2l6ZTogMC45cmVtOyBib3gtc2l6aW5nOiBib3JkZXItYm94O1wiIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTJweDtcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjaGVja2JveC1sYWJlbFwiIHN0eWxlPVwiZm9udC1zaXplOiAwLjg1cmVtO1wiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwic25hcHNob3QtbGVhdmUtcnVubmluZ1wiIGNoZWNrZWQgLz5cbiAgICAgICAgICAgIExlYXZlIGNvbnRhaW5lciBydW5uaW5nIGFmdGVyIGNoZWNrcG9pbnQgKHJlc3VtZSB3aXRob3V0IHJlc3RhcnQpXG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxidXR0b24gaWQ9XCJzbmFwc2hvdC1jcmVhdGUtYnRuXCIgY2xhc3M9XCJidG4tYWNjZW50LXNvbGlkXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTtcIj5cdUQ4M0RcdURDQkUgQ3JlYXRlIFNuYXBzaG90PC9idXR0b24+XG4gICAgICAgIDxkaXYgaWQ9XCJzbmFwc2hvdC1jcmVhdGUtc3RhdHVzXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxMnB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj48L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGlkPVwic25hcHNob3QtbGlzdFwiIGNsYXNzPVwicGFuZWwtc2VjdGlvblwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgPGRpdiBpZD1cInNuYXBzaG90LWxpc3QtY29udGFpbmVyXCIgY2xhc3M9XCJzY3JvbGwtY29udGFpbmVyXCIgc3R5bGU9XCJtYXgtaGVpZ2h0OiAzMDBweDtcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0RcdURDQkU8L3NwYW4+U2VsZWN0IGEgY29udGFpbmVyIHRvIHZpZXcgaXRzIHNuYXBzaG90czwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1idXR0b25zIG1vZGFsLWZvb3Rlci1iYXJcIj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cInNuYXBzaG90LWNsb3NlXCI+Q2xvc2U8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5gKTtcblxuICBjb25zdCBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbmFwc2hvdC1tb2RhbCcpO1xuICBjb25zdCBvcGVuQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuYXBzaG90LWJ0bicpO1xuICBjb25zdCBjbG9zZUJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbmFwc2hvdC1jbG9zZScpO1xuICBjb25zdCBjb250YWluZXJTZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25hcHNob3QtY29udGFpbmVyLXNlbGVjdCcpO1xuICBjb25zdCBkZXRhaWxzRGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuYXBzaG90LWRldGFpbHMnKTtcbiAgY29uc3QgY3JlYXRlQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuYXBzaG90LWNyZWF0ZS1idG4nKTtcbiAgY29uc3QgY3JlYXRlU3RhdHVzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuYXBzaG90LWNyZWF0ZS1zdGF0dXMnKTtcblxuICBsZXQgY3VycmVudENvbnRhaW5lcklkID0gbnVsbDtcblxuICBhc3luYyBmdW5jdGlvbiBsb2FkQ29udGFpbmVycygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvY29udGFpbmVycycpO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBpZiAoIWRhdGEuc3VjY2VzcyB8fCAhZGF0YS5jb250YWluZXJzKSByZXR1cm47XG4gICAgICBcbiAgICAgIGNvbnRhaW5lclNlbGVjdC5pbm5lckhUTUwgPSAnPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIFNlbGVjdCBhIGNvbnRhaW5lciAtLTwvb3B0aW9uPic7XG4gICAgICBmb3IgKGNvbnN0IGMgb2YgZGF0YS5jb250YWluZXJzKSB7XG4gICAgICAgIGNvbnN0IG9wdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ29wdGlvbicpO1xuICAgICAgICBvcHQudmFsdWUgPSBjLmlkO1xuICAgICAgICBvcHQudGV4dENvbnRlbnQgPSBgJHtjLm5hbWUgfHwgYy5pZH0gKCR7Yy5pbWFnZSB8fCAndW5rbm93bid9KWA7XG4gICAgICAgIG9wdC5kYXRhc2V0Lm5hbWUgPSBjLm5hbWU7XG4gICAgICAgIG9wdC5kYXRhc2V0LmltYWdlID0gYy5pbWFnZTtcbiAgICAgICAgb3B0LmRhdGFzZXQuc3RhdHVzID0gYy5zdGF0dXM7XG4gICAgICAgIG9wdC5kYXRhc2V0LmNyZWF0ZWQgPSBjLmNyZWF0ZWQ7XG4gICAgICAgIGNvbnRhaW5lclNlbGVjdC5hcHBlbmRDaGlsZChvcHQpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIGNvbnRhaW5lcnM6JywgZSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2hvd0NvbnRhaW5lckRldGFpbHMob3B0KSB7XG4gICAgaWYgKCFvcHQgfHwgIW9wdC52YWx1ZSkge1xuICAgICAgZGV0YWlsc0Rpdi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgY3VycmVudENvbnRhaW5lcklkID0gbnVsbDtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY3VycmVudENvbnRhaW5lcklkID0gb3B0LnZhbHVlO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbmFwc2hvdC1pbWFnZScpLnRleHRDb250ZW50ID0gb3B0LmRhdGFzZXQuaW1hZ2UgfHwgJy0nO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbmFwc2hvdC1zdGF0dXMnKS50ZXh0Q29udGVudCA9IG9wdC5kYXRhc2V0LnN0YXR1cyB8fCAnLSc7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuYXBzaG90LWNyZWF0ZWQnKS50ZXh0Q29udGVudCA9IG9wdC5kYXRhc2V0LmNyZWF0ZWQgPyBuZXcgRGF0ZShvcHQuZGF0YXNldC5jcmVhdGVkICogMTAwMCkudG9Mb2NhbGVTdHJpbmcoKSA6ICctJztcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25hcHNob3QtaWQnKS50ZXh0Q29udGVudCA9IG9wdC52YWx1ZS5zdWJzdHJpbmcoMCwgMTIpO1xuICAgIGRldGFpbHNEaXYuc3R5bGUuZGlzcGxheSA9ICcnO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlU25hcHNob3QoKSB7XG4gICAgaWYgKCFjdXJyZW50Q29udGFpbmVySWQpIHtcbiAgICAgIGNyZWF0ZVN0YXR1cy50ZXh0Q29udGVudCA9ICdQbGVhc2Ugc2VsZWN0IGEgY29udGFpbmVyIGZpcnN0JztcbiAgICAgIGNyZWF0ZVN0YXR1cy5zdHlsZS5jb2xvciA9ICd2YXIoLS1iYWQtZmcpJztcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbmFtZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbmFwc2hvdC1uYW1lJykudmFsdWUudHJpbSgpO1xuICAgIGlmICghbmFtZSkge1xuICAgICAgY3JlYXRlU3RhdHVzLnRleHRDb250ZW50ID0gJ1BsZWFzZSBlbnRlciBhIHNuYXBzaG90IG5hbWUnO1xuICAgICAgY3JlYXRlU3RhdHVzLnN0eWxlLmNvbG9yID0gJ3ZhcigtLWJhZC1mZyknO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBsZWF2ZVJ1bm5pbmcgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25hcHNob3QtbGVhdmUtcnVubmluZycpLmNoZWNrZWQ7XG4gICAgXG4gICAgY3JlYXRlQnRuLmRpc2FibGVkID0gdHJ1ZTtcbiAgICBjcmVhdGVCdG4udGV4dENvbnRlbnQgPSAnQ3JlYXRpbmcuLi4nO1xuICAgIGNyZWF0ZVN0YXR1cy50ZXh0Q29udGVudCA9ICcnO1xuICAgIFxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaChgL2FwaS92MS9jb250YWluZXJzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGN1cnJlbnRDb250YWluZXJJZCl9L2NoZWNrcG9pbnRgLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBuYW1lLCBsZWF2ZVJ1bm5pbmcgfSlcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIGNyZWF0ZVN0YXR1cy50ZXh0Q29udGVudCA9IGBcdTI3MTMgU25hcHNob3QgXCIke25hbWV9XCIgY3JlYXRlZCBzdWNjZXNzZnVsbHlgO1xuICAgICAgICBjcmVhdGVTdGF0dXMuc3R5bGUuY29sb3IgPSAndmFyKC0tb2stZmcpJztcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuYXBzaG90LW5hbWUnKS52YWx1ZSA9ICcnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3JlYXRlU3RhdHVzLnRleHRDb250ZW50ID0gYFx1MjcxNyBGYWlsZWQ6ICR7ZGF0YS5lcnJvciB8fCAnVW5rbm93biBlcnJvcid9YDtcbiAgICAgICAgY3JlYXRlU3RhdHVzLnN0eWxlLmNvbG9yID0gJ3ZhcigtLWJhZC1mZyknO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNyZWF0ZVN0YXR1cy50ZXh0Q29udGVudCA9IGBcdTI3MTcgRXJyb3I6ICR7ZS5tZXNzYWdlfWA7XG4gICAgICBjcmVhdGVTdGF0dXMuc3R5bGUuY29sb3IgPSAndmFyKC0tYmFkLWZnKSc7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGNyZWF0ZUJ0bi5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgY3JlYXRlQnRuLnRleHRDb250ZW50ID0gJ1x1RDgzRFx1RENCRSBDcmVhdGUgU25hcHNob3QnO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG9wZW5Nb2RhbCgpIHtcbiAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgbG9hZENvbnRhaW5lcnMoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsb3NlTW9kYWwoKSB7XG4gICAgbW9kYWwuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICAgIGRldGFpbHNEaXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBjdXJyZW50Q29udGFpbmVySWQgPSBudWxsO1xuICAgIGNvbnRhaW5lclNlbGVjdC5zZWxlY3RlZEluZGV4ID0gMDtcbiAgfVxuXG4gIG9wZW5CdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgb3Blbk1vZGFsKTtcbiAgY2xvc2VCdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgY2xvc2VNb2RhbCk7XG4gIHdpcmVNb2RhbChtb2RhbCwgY2xvc2VCdG4pO1xuICBcbiAgY29udGFpbmVyU2VsZWN0Py5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgIGNvbnN0IG9wdCA9IGNvbnRhaW5lclNlbGVjdC5vcHRpb25zW2NvbnRhaW5lclNlbGVjdC5zZWxlY3RlZEluZGV4XTtcbiAgICBzaG93Q29udGFpbmVyRGV0YWlscyhvcHQpO1xuICB9KTtcbiAgXG4gIGNyZWF0ZUJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBjcmVhdGVTbmFwc2hvdCk7XG4gIFxuICAvLyBUYWIgc3dpdGNoaW5nXG4gIG1vZGFsPy5xdWVyeVNlbGVjdG9yQWxsKCcucGFuZWwtdGFiJykuZm9yRWFjaCh0YWIgPT4ge1xuICAgIHRhYi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgIG1vZGFsLnF1ZXJ5U2VsZWN0b3JBbGwoJy5wYW5lbC10YWInKS5mb3JFYWNoKHQgPT4gdC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKSk7XG4gICAgICBtb2RhbC5xdWVyeVNlbGVjdG9yQWxsKCcucGFuZWwtc2VjdGlvbicpLmZvckVhY2gocyA9PiBzLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpKTtcbiAgICAgIHRhYi5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICAgIG1vZGFsLnF1ZXJ5U2VsZWN0b3IoYCMke3RhYi5kYXRhc2V0LnBhbmVsfWApLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgIH0pO1xuICB9KTtcbn0pKCk7XG47XG4vLyA9PT09PT09PT09IFNNQVJUIEFSUiBDT05ORUNUID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgaW5qZWN0TW9kYWwoJ2Fyci1zZXR1cC1tb2RhbCcsIGA8ZGl2IGlkPVwiYXJyLXNldHVwLW1vZGFsXCIgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsXCI+XG4gICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtY29udGVudFwiIHN0eWxlPVwibWluLXdpZHRoOiA2MDBweDsgbWF4LXdpZHRoOiA3MjBweDtcIj5cbiAgICAgIDxoMz5cdUQ4M0NcdURGQUMgU21hcnQgQXJyIENvbm5lY3Q8L2gzPlxuICAgICAgPHAgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW46IDAgMCAxNnB4OyBmb250LXNpemU6IDAuOXJlbTtcIj5cbiAgICAgICAgQXV0by1kaXNjb3ZlciBhbmQgY29ubmVjdCB5b3VyIGVudGlyZSBtZWRpYSBzdGFjay5cbiAgICAgIDwvcD5cblxuICAgICAgPCEtLSBQaGFzZSAxOiBEZXRlY3Rpb24gLS0+XG4gICAgICA8ZGl2IGlkPVwic21hcnQtcGhhc2UtZGV0ZWN0XCI+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDIwcHg7XCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAxMnB4OyBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XCI+PC9zcGFuPlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyBmb250LXNpemU6IDAuOXJlbTtcIj5TY2FubmluZyBmb3Igc2VydmljZXMuLi48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJzbWFydC1kZXRlY3QtcmVzdWx0c1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj48L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFBoYXNlIDI6IENyZWRlbnRpYWwgSW5wdXQgKG9ubHkgZm9yIHNlcnZpY2VzIG5lZWRpbmcga2V5cykgLS0+XG4gICAgICA8ZGl2IGlkPVwic21hcnQtcGhhc2UtY3JlZGVudGlhbHNcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgIDxoNCBjbGFzcz1cImhlYWRpbmctYWNjZW50LXNlY3Rpb25cIj5FbnRlciBNaXNzaW5nIEFQSSBLZXlzPC9oND5cbiAgICAgICAgPGRpdiBpZD1cInNtYXJ0LWNyZWRlbnRpYWwtaW5wdXRzXCI+PC9kaXY+XG5cbiAgICAgICAgPCEtLSBDb25uZWN0aW9uIE9wdGlvbnMgLS0+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tdG9wOiAxNnB4OyBwYWRkaW5nOiAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+XG4gICAgICAgICAgPGg0IHN0eWxlPVwibWFyZ2luOiAwIDAgMTBweDsgZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tYWNjZW50KTtcIj5Db25uZWN0aW9uIE9wdGlvbnM8L2g0PlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm9wdGlvbi1sYWJlbFwiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwic21hcnQtb3B0LXNlZXJyXCIgY2hlY2tlZCBjbGFzcz1cImNoZWNrYm94LXNtXCIgLz5cbiAgICAgICAgICAgIENvbmZpZ3VyZSBTZWVyciB3aXRoIFJhZGFyciArIFNvbmFyclxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwib3B0aW9uLWxhYmVsXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJzbWFydC1vcHQtcGxleFwiIGNoZWNrZWQgY2xhc3M9XCJjaGVja2JveC1zbVwiIC8+XG4gICAgICAgICAgICBDb25uZWN0IFBsZXggdG8gU2VlcnJcbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm9wdGlvbi1sYWJlbFwiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwic21hcnQtb3B0LXByb3dsYXJyXCIgY2hlY2tlZCBjbGFzcz1cImNoZWNrYm94LXNtXCIgLz5cbiAgICAgICAgICAgIENvbm5lY3QgUHJvd2xhcnIgdG8gUmFkYXJyICsgU29uYXJyXG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8bGFiZWwgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDsgY3Vyc29yOiBwb2ludGVyOyBmb250LXNpemU6IDAuODVyZW07XCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJzbWFydC1vcHQtc2F2ZVwiIGNoZWNrZWQgY2xhc3M9XCJjaGVja2JveC1zbVwiIC8+XG4gICAgICAgICAgICBTYXZlIEFQSSBrZXlzIGZvciBvbmUtY2xpY2sgcmVjb25uZWN0XG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGJ1dHRvbiBpZD1cInNtYXJ0LWNvbm5lY3QtYnRuXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTsgbWFyZ2luLXRvcDogMTZweDsgcGFkZGluZzogMTJweDsgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgI2U3NGMzYyAwJSwgIzliNTliNiAxMDAlKTsgYm9yZGVyOiBub25lOyBjb2xvcjogd2hpdGU7IGZvbnQtd2VpZ2h0OiA2MDA7IGZvbnQtc2l6ZTogMXJlbTsgYm9yZGVyLXJhZGl1czogOHB4OyBjdXJzb3I6IHBvaW50ZXI7XCI+XG4gICAgICAgICAgU21hcnQgQ29ubmVjdFxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFBoYXNlIDM6IENvbm5lY3Rpb24gUHJvZ3Jlc3MgLS0+XG4gICAgICA8ZGl2IGlkPVwic21hcnQtcGhhc2UtcHJvZ3Jlc3NcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgIDxoNCBjbGFzcz1cImhlYWRpbmctYWNjZW50LXNlY3Rpb25cIj5Db25uZWN0aW5nIEV2ZXJ5dGhpbmcuLi48L2g0PlxuICAgICAgICA8ZGl2IGlkPVwic21hcnQtcHJvZ3Jlc3Mtc3RlcHNcIiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGdhcDogNnB4O1wiPjwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gUGhhc2UgNDogUmVzdWx0cyAtLT5cbiAgICAgIDxkaXYgaWQ9XCJzbWFydC1waGFzZS1yZXN1bHRzXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgICAgICA8ZGl2IGlkPVwic21hcnQtcmVzdWx0cy1jb250ZW50XCI+PC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJzbWFydC1wbGV4LWxpYnJhcmllc1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTsgbWFyZ2luLXRvcDogMTJweDtcIj48L2Rpdj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyBtYXJnaW4tdG9wOiAxNnB4O1wiPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJzbWFydC1yZXRyeS1idG5cIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7IGZsZXg6IDE7IHBhZGRpbmc6IDEwcHg7IGJhY2tncm91bmQ6ICNmMzljMTI7IGJvcmRlcjogbm9uZTsgY29sb3I6IHdoaXRlOyBmb250LXdlaWdodDogNTAwOyBib3JkZXItcmFkaXVzOiA4cHg7IGN1cnNvcjogcG9pbnRlcjtcIj5cbiAgICAgICAgICAgIFJldHJ5IEZhaWxlZCBTdGVwc1xuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxhIGlkPVwic21hcnQtb3Blbi1zZWVyclwiIGhyZWY9XCIjXCIgdGFyZ2V0PVwiX2JsYW5rXCIgcmVsPVwibm9vcGVuZXIgbm9yZWZlcnJlclwiXG4gICAgICAgICAgICAgc3R5bGU9XCJmbGV4OiAxOyBwYWRkaW5nOiAxMHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1hY2NlbnQpOyBjb2xvcjogd2hpdGU7IGJvcmRlcjogbm9uZTsgYm9yZGVyLXJhZGl1czogOHB4OyBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtd2VpZ2h0OiA1MDA7IHRleHQtZGVjb3JhdGlvbjogbm9uZTsgdGV4dC1hbGlnbjogY2VudGVyO1wiPlxuICAgICAgICAgICAgT3BlbiBTZWVyclxuICAgICAgICAgIDwvYT5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBIZWxwIFRleHQgLS0+XG4gICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tdG9wOiAxMnB4OyBwYWRkaW5nOiAxMHB4OyBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tYWNjZW50KSA1JSwgdHJhbnNwYXJlbnQpOyBib3JkZXItcmFkaXVzOiA2cHg7XCI+XG4gICAgICAgIDxzdHJvbmc+V2hlcmUgdG8gZmluZCBBUEkga2V5czo8L3N0cm9uZz48YnI+XG4gICAgICAgIFJhZGFyci9Tb25hcnIvUHJvd2xhcnI6IFNldHRpbmdzIC0+IEdlbmVyYWwgLT4gU2VjdXJpdHkgLT4gQVBJIEtleVxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQ2xvc2UgQnV0dG9uIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJhcnItc2V0dXAtY2FuY2VsXCI+Q2xvc2U8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5gKTtcblxuICBjb25zdCBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcnItc2V0dXAtbW9kYWwnKTtcbiAgY29uc3Qgb3BlbkJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcnItc2V0dXAtYnRuJyk7XG4gIGNvbnN0IGNhbmNlbEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcnItc2V0dXAtY2FuY2VsJyk7XG4gIGNvbnN0IGNvbm5lY3RCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc21hcnQtY29ubmVjdC1idG4nKTtcblxuICAvLyBQaGFzZSBlbGVtZW50c1xuICBjb25zdCBwaGFzZURldGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1waGFzZS1kZXRlY3QnKTtcbiAgY29uc3QgcGhhc2VDcmVkZW50aWFscyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1waGFzZS1jcmVkZW50aWFscycpO1xuICBjb25zdCBwaGFzZVByb2dyZXNzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NtYXJ0LXBoYXNlLXByb2dyZXNzJyk7XG4gIGNvbnN0IHBoYXNlUmVzdWx0cyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1waGFzZS1yZXN1bHRzJyk7XG5cbiAgY29uc3QgZGV0ZWN0UmVzdWx0cyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbWFydC1kZXRlY3QtcmVzdWx0cycpO1xuICBjb25zdCBjcmVkZW50aWFsSW5wdXRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NtYXJ0LWNyZWRlbnRpYWwtaW5wdXRzJyk7XG4gIGNvbnN0IHByb2dyZXNzU3RlcHMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc21hcnQtcHJvZ3Jlc3Mtc3RlcHMnKTtcbiAgY29uc3QgcmVzdWx0c0NvbnRlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc21hcnQtcmVzdWx0cy1jb250ZW50Jyk7XG4gIGNvbnN0IHBsZXhMaWJyYXJpZXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc21hcnQtcGxleC1saWJyYXJpZXMnKTtcbiAgY29uc3QgcmV0cnlCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc21hcnQtcmV0cnktYnRuJyk7XG5cbiAgbGV0IGRldGVjdGVkRGF0YSA9IG51bGw7IC8vIFN0b3JlIGRldGVjdGlvbiByZXN1bHRzIGZvciBzbWFydC1jb25uZWN0XG5cbiAgY29uc3Qgc2VydmljZUljb25zID0geyBwbGV4OiAnXHVEODNDXHVERkFDJywgcmFkYXJyOiAnXHVEODNDXHVERkFDJywgc29uYXJyOiAnXHVEODNEXHVEQ0ZBJywgcHJvd2xhcnI6ICdcdUQ4M0RcdUREMEQnLCBzZWVycjogJ1x1RDgzRFx1RENDQicgfTtcbiAgY29uc3Qgc2VydmljZUxhYmVscyA9IHsgcGxleDogJ1BsZXgnLCByYWRhcnI6ICdSYWRhcnIgKE1vdmllcyknLCBzb25hcnI6ICdTb25hcnIgKFRWKScsIHByb3dsYXJyOiAnUHJvd2xhcnIgKEluZGV4ZXJzKScsIHNlZXJyOiAnU2VlcnInIH07XG5cbiAgZnVuY3Rpb24gc2hvd1BoYXNlKHBoYXNlKSB7XG4gICAgcGhhc2VEZXRlY3Quc3R5bGUuZGlzcGxheSA9IHBoYXNlID09PSAnZGV0ZWN0JyA/ICdibG9jaycgOiAnbm9uZSc7XG4gICAgcGhhc2VDcmVkZW50aWFscy5zdHlsZS5kaXNwbGF5ID0gcGhhc2UgPT09ICdjcmVkZW50aWFscycgPyAnYmxvY2snIDogJ25vbmUnO1xuICAgIHBoYXNlUHJvZ3Jlc3Muc3R5bGUuZGlzcGxheSA9IHBoYXNlID09PSAncHJvZ3Jlc3MnID8gJ2Jsb2NrJyA6ICdub25lJztcbiAgICBwaGFzZVJlc3VsdHMuc3R5bGUuZGlzcGxheSA9IHBoYXNlID09PSAncmVzdWx0cycgPyAnYmxvY2snIDogJ25vbmUnO1xuICB9XG5cbiAgZnVuY3Rpb24gc3RhdHVzQmFkZ2Uoc3RhdHVzKSB7XG4gICAgY29uc3QgY29sb3JzID0ge1xuICAgICAgY29ubmVjdGVkOiB7IGJnOiAndmFyKC0tb2stZmcpJywgaWNvbjogJyYjMTAwMDM7JywgdGV4dDogJ0Nvbm5lY3RlZCcgfSxcbiAgICAgIG5lZWRzX2tleTogeyBiZzogJyNmMzljMTInLCBpY29uOiAnJiMxMjgyNzM7JywgdGV4dDogJ05lZWRzIEFQSSBLZXknIH0sXG4gICAgICBub3RfZm91bmQ6IHsgYmc6ICd2YXIoLS1tdXRlZCknLCBpY29uOiAnJm1kYXNoOycsIHRleHQ6ICdOb3QgRm91bmQnIH0sXG4gICAgICBlcnJvcjogeyBiZzogJ3ZhcigtLWJhZC1mZyknLCBpY29uOiAnJiMxMDAwNzsnLCB0ZXh0OiAnRXJyb3InIH1cbiAgICB9O1xuICAgIGNvbnN0IGMgPSBjb2xvcnNbc3RhdHVzXSB8fCBjb2xvcnMubm90X2ZvdW5kO1xuICAgIHJldHVybiBgPHNwYW4gc3R5bGU9XCJkaXNwbGF5OiBpbmxpbmUtZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA0cHg7IHBhZGRpbmc6IDJweCA4cHg7IGJvcmRlci1yYWRpdXM6IDRweDsgZm9udC1zaXplOiAwLjc1cmVtOyBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgJHtjLmJnfSAyMCUsIHRyYW5zcGFyZW50KTsgY29sb3I6ICR7Yy5iZ307XCI+JHtjLmljb259ICR7Yy50ZXh0fTwvc3Bhbj5gO1xuICB9XG5cbiAgLy8gUGhhc2UgMTogU21hcnQgRGV0ZWN0aW9uXG4gIGFzeW5jIGZ1bmN0aW9uIHNtYXJ0RGV0ZWN0KCkge1xuICAgIHNob3dQaGFzZSgnZGV0ZWN0Jyk7XG4gICAgZGV0ZWN0UmVzdWx0cy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvYXJyL3NtYXJ0LWRldGVjdCcpO1xuICAgICAgZGV0ZWN0ZWREYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgICBpZiAoIWRldGVjdGVkRGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIGRldGVjdFJlc3VsdHMuaW5uZXJIVE1MID0gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxMnB4OyBjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5EZXRlY3Rpb24gZmFpbGVkOiAke2VzY2FwZUh0bWwoZGV0ZWN0ZWREYXRhLmVycm9yKX08L2Rpdj5gO1xuICAgICAgICBkZXRlY3RSZXN1bHRzLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbmRlciBkZXRlY3Rpb24gcmVzdWx0c1xuICAgICAgbGV0IGh0bWwgPSAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGdhcDogOHB4O1wiPic7XG5cbiAgICAgIGZvciAoY29uc3QgW3N2YywgaW5mb10gb2YgT2JqZWN0LmVudHJpZXMoZGV0ZWN0ZWREYXRhLnNlcnZpY2VzKSkge1xuICAgICAgICBjb25zdCBpY29uID0gc2VydmljZUljb25zW3N2Y10gfHwgJ1x1RDgzRFx1RENFNic7XG4gICAgICAgIGNvbnN0IGxhYmVsID0gc2VydmljZUxhYmVsc1tzdmNdIHx8IHN2YztcbiAgICAgICAgY29uc3Qgc291cmNlID0gaW5mby5zb3VyY2UgPyBgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDAuN3JlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgcGFkZGluZzogMXB4IDZweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iZyk7IGJvcmRlci1yYWRpdXM6IDNweDtcIj4ke2VzY2FwZUh0bWwoaW5mby5zb3VyY2UpfTwvc3Bhbj5gIDogJyc7XG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSBpbmZvLnZlcnNpb24gPyBgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDAuN3JlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj52JHtlc2NhcGVIdG1sKGluZm8udmVyc2lvbil9PC9zcGFuPmAgOiAnJztcbiAgICAgICAgY29uc3Qga2V5U2F2ZWQgPSAoaW5mby5oYXNBcGlLZXkgfHwgaW5mby5oYXNUb2tlbikgJiYgaW5mby5zdGF0dXMgPT09ICdjb25uZWN0ZWQnXG4gICAgICAgICAgPyAnPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDAuN3JlbTsgY29sb3I6IHZhcigtLW9rLWZnKTtcIj5LZXkgc2F2ZWQ8L3NwYW4+JyA6ICcnO1xuXG4gICAgICAgIGh0bWwgKz0gYDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDEwcHg7IHBhZGRpbmc6IDEwcHggMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogOHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAxLjFyZW07XCI+JHtpY29ufTwvc3Bhbj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZmxleDogMTtcIj5cbiAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXdlaWdodDogNTAwOyBmb250LXNpemU6IDAuOXJlbTtcIj4ke2xhYmVsfTwvZGl2PlxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogNnB4OyBhbGlnbi1pdGVtczogY2VudGVyOyBmbGV4LXdyYXA6IHdyYXA7XCI+XG4gICAgICAgICAgICAgICR7c291cmNlfSAke3ZlcnNpb259ICR7a2V5U2F2ZWR9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAke3N0YXR1c0JhZGdlKGluZm8uc3RhdHVzKX1cbiAgICAgICAgPC9kaXY+YDtcbiAgICAgIH1cblxuICAgICAgaHRtbCArPSAnPC9kaXY+JztcblxuICAgICAgLy8gU3VtbWFyeVxuICAgICAgY29uc3QgcyA9IGRldGVjdGVkRGF0YS5zdW1tYXJ5O1xuICAgICAgaHRtbCArPSBgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDEycHg7IHBhZGRpbmc6IDEwcHg7IGJhY2tncm91bmQ6IGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1hY2NlbnQpIDglLCB0cmFuc3BhcmVudCk7IGJvcmRlci1yYWRpdXM6IDhweDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPlxuICAgICAgICAke2VzY2FwZUh0bWwoU3RyaW5nKHMuZnVsbHlDb25uZWN0ZWQpKX0vJHtlc2NhcGVIdG1sKFN0cmluZyhzLnRvdGFsRGV0ZWN0ZWQgKyAoNSAtIHMudG90YWxEZXRlY3RlZCkpKX0gc2VydmljZXMgZGV0ZWN0ZWQgJm1pZGRvdDtcbiAgICAgICAgJHtlc2NhcGVIdG1sKFN0cmluZyhzLmZ1bGx5Q29ubmVjdGVkKSl9IGNvbm5lY3RlZCR7cy5uZWVkc0FwaUtleSA+IDAgPyBgICZtaWRkb3Q7IDxzdHJvbmc+JHtlc2NhcGVIdG1sKFN0cmluZyhzLm5lZWRzQXBpS2V5KSl9IG5lZWRzIEFQSSBrZXk8L3N0cm9uZz5gIDogJyd9XG4gICAgICA8L2Rpdj5gO1xuXG4gICAgICBkZXRlY3RSZXN1bHRzLmlubmVySFRNTCA9IGh0bWw7XG4gICAgICBkZXRlY3RSZXN1bHRzLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXG4gICAgICAvLyBCdWlsZCBjcmVkZW50aWFsIGlucHV0cyBmb3Igc2VydmljZXMgdGhhdCBuZWVkIGtleXNcbiAgICAgIGJ1aWxkQ3JlZGVudGlhbElucHV0cyhkZXRlY3RlZERhdGEpO1xuXG4gICAgICAvLyBBdXRvLWFkdmFuY2UgYWZ0ZXIgYSBzaG9ydCBkZWxheVxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHNob3dQaGFzZSgnY3JlZGVudGlhbHMnKTtcbiAgICAgIH0sIDgwMCk7XG5cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBkZXRlY3RSZXN1bHRzLmlubmVySFRNTCA9IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogMTJweDsgY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+RXJyb3I6ICR7ZXNjYXBlSHRtbChlLm1lc3NhZ2UpfTwvZGl2PmA7XG4gICAgICBkZXRlY3RSZXN1bHRzLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJ1aWxkIGNyZWRlbnRpYWwgaW5wdXQgZmllbGRzXG4gIGZ1bmN0aW9uIGJ1aWxkQ3JlZGVudGlhbElucHV0cyhkYXRhKSB7XG4gICAgbGV0IGh0bWwgPSAnJztcbiAgICBjb25zdCBzZXJ2aWNlcyA9IGRhdGEuc2VydmljZXM7XG4gICAgY29uc3QgYXJyU2VydmljZXMgPSBbJ3JhZGFycicsICdzb25hcnInLCAncHJvd2xhcnInXTtcblxuICAgIGZvciAoY29uc3Qgc3ZjIG9mIGFyclNlcnZpY2VzKSB7XG4gICAgICBjb25zdCBpbmZvID0gc2VydmljZXNbc3ZjXTtcbiAgICAgIGlmICghaW5mbyB8fCBpbmZvLnN0YXR1cyA9PT0gJ25vdF9mb3VuZCcgJiYgIWluZm8udXJsKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgaWNvbiA9IHNlcnZpY2VJY29uc1tzdmNdO1xuICAgICAgY29uc3QgbGFiZWwgPSBzZXJ2aWNlTGFiZWxzW3N2Y107XG4gICAgICBjb25zdCBpc0Nvbm5lY3RlZCA9IGluZm8uc3RhdHVzID09PSAnY29ubmVjdGVkJztcbiAgICAgIGNvbnN0IGJvcmRlckNvbG9yID0gaXNDb25uZWN0ZWQgPyAndmFyKC0tb2stZmcpJyA6ICd2YXIoLS1ib3JkZXIpJztcblxuICAgICAgaHRtbCArPSBgPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDEwcHg7IHBhZGRpbmc6IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgJHtib3JkZXJDb2xvcn07XCI+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDsgbWFyZ2luLWJvdHRvbTogOHB4O1wiPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAxLjFyZW07XCI+JHtpY29ufTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA1MDA7XCI+JHtsYWJlbH08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gaWQ9XCJzbWFydC0ke3N2Y30tc3RhdHVzXCIgc3R5bGU9XCJtYXJnaW4tbGVmdDogYXV0bzsgZm9udC1zaXplOiAwLjc1cmVtO1wiPlxuICAgICAgICAgICAgJHtpc0Nvbm5lY3RlZCA/ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1vay1mZyk7XCI+JiMxMDAwMzsgQ29ubmVjdGVkPC9zcGFuPicgOiAnJ31cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAyZnIgMWZyOyBnYXA6IDhweDtcIj5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGxhYmVsIHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlVSTDo8L2xhYmVsPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJzbWFydC0ke3N2Y30tdXJsXCIgdmFsdWU9XCIke2VzY2FwZUh0bWwoaW5mby51cmwgfHwgJycpfVwiIHBsYWNlaG9sZGVyPVwiaHR0cHM6Ly9zZWVkYm94LmNvbS8ke3N2Y30vXCJcbiAgICAgICAgICAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxMDAlOyBmb250LXNpemU6IDAuODVyZW07IHBhZGRpbmc6IDZweCA4cHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmcpOyBjb2xvcjogdmFyKC0tZmcpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA0cHg7XCIgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGxhYmVsIHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkFQSSBLZXk6PC9sYWJlbD5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicGFzc3dvcmRcIiBpZD1cInNtYXJ0LSR7c3ZjfS1rZXlcIiBwbGFjZWhvbGRlcj1cIiR7aXNDb25uZWN0ZWQgPyAnKHNhdmVkKScgOiAnUGFzdGUgQVBJIGtleSd9XCJcbiAgICAgICAgICAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxMDAlOyBmb250LXNpemU6IDAuODVyZW07IHBhZGRpbmc6IDZweCA4cHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmcpOyBjb2xvcjogdmFyKC0tZmcpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA0cHg7XCIgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxidXR0b24gb25jbGljaz1cInNtYXJ0VGVzdENvbm5lY3Rpb24oJyR7c3ZjfScpXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiA4cHg7IHBhZGRpbmc6IDRweCAxMnB4OyBmb250LXNpemU6IDAuNzVyZW07IGN1cnNvcjogcG9pbnRlcjtcIj5UZXN0PC9idXR0b24+XG4gICAgICA8L2Rpdj5gO1xuICAgIH1cblxuICAgIC8vIFBsZXggc3RhdHVzIChub24tZWRpdGFibGUsIGp1c3Qgc2hvd3Mgc3RhdHVzKVxuICAgIGNvbnN0IHBsZXggPSBzZXJ2aWNlcy5wbGV4O1xuICAgIGlmIChwbGV4KSB7XG4gICAgICBjb25zdCBwbGV4Q29ubmVjdGVkID0gcGxleC5zdGF0dXMgPT09ICdjb25uZWN0ZWQnO1xuICAgICAgaHRtbCArPSBgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDEwcHggMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogOHB4OyBib3JkZXI6IDFweCBzb2xpZCAke3BsZXhDb25uZWN0ZWQgPyAndmFyKC0tb2stZmcpJyA6ICd2YXIoLS1ib3JkZXIpJ307IG1hcmdpbi1ib3R0b206IDEwcHg7XCI+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDtcIj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMS4xcmVtO1wiPlx1RDgzQ1x1REZBQzwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA1MDA7XCI+UGxleDwvc3Bhbj5cbiAgICAgICAgICAke3N0YXR1c0JhZGdlKHBsZXguc3RhdHVzKX1cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiBhdXRvOyBmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JHtlc2NhcGVIdG1sKHBsZXguc291cmNlIHx8ICcnKX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+YDtcbiAgICB9XG5cbiAgICAvLyBTZWVyciBzdGF0dXNcbiAgICBjb25zdCBzZWVyciA9IHNlcnZpY2VzLnNlZXJyO1xuICAgIGlmIChzZWVycikge1xuICAgICAgY29uc3Qgc2VlcnJPayA9IHNlZXJyLnN0YXR1cyA9PT0gJ2Nvbm5lY3RlZCc7XG4gICAgICBsZXQgY29uZmlndXJlZEh0bWwgPSAnJztcbiAgICAgIGlmIChzZWVyci5jb25maWd1cmVkU2VydmljZXMpIHtcbiAgICAgICAgY29uc3QgY3MgPSBzZWVyci5jb25maWd1cmVkU2VydmljZXM7XG4gICAgICAgIGNvbmZpZ3VyZWRIdG1sID0gYDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi10b3A6IDRweDtcIj5cbiAgICAgICAgICBDb25maWd1cmVkOiAke2NzLnJhZGFyciA/ICcmIzEwMDAzOyBSYWRhcnInIDogJyYjMTAwMDc7IFJhZGFycid9ICZtaWRkb3Q7XG4gICAgICAgICAgJHtjcy5zb25hcnIgPyAnJiMxMDAwMzsgU29uYXJyJyA6ICcmIzEwMDA3OyBTb25hcnInfSAmbWlkZG90O1xuICAgICAgICAgICR7Y3MucGxleCA/ICcmIzEwMDAzOyBQbGV4JyA6ICcmIzEwMDA3OyBQbGV4J31cbiAgICAgICAgPC9kaXY+YDtcbiAgICAgIH1cbiAgICAgIGh0bWwgKz0gYDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxMHB4IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgJHtzZWVyck9rID8gJ3ZhcigtLW9rLWZnKScgOiAndmFyKC0tYm9yZGVyKSd9O1wiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7XCI+XG4gICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDEuMXJlbTtcIj5cdUQ4M0RcdURDQ0I8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXdlaWdodDogNTAwO1wiPlNlZXJyPC9zcGFuPlxuICAgICAgICAgICR7c3RhdHVzQmFkZ2Uoc2VlcnIuc3RhdHVzKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgICR7Y29uZmlndXJlZEh0bWx9XG4gICAgICA8L2Rpdj5gO1xuICAgIH1cblxuICAgIGNyZWRlbnRpYWxJbnB1dHMuaW5uZXJIVE1MID0gaHRtbDtcbiAgfVxuXG4gIC8vIFRlc3QgY29ubmVjdGlvbiAoZ2xvYmFsIGZvciBvbmNsaWNrKVxuICB3aW5kb3cuc21hcnRUZXN0Q29ubmVjdGlvbiA9IGFzeW5jIGZ1bmN0aW9uKHNlcnZpY2UpIHtcbiAgICBjb25zdCB1cmxJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBzbWFydC0ke3NlcnZpY2V9LXVybGApO1xuICAgIGNvbnN0IGtleUlucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYHNtYXJ0LSR7c2VydmljZX0ta2V5YCk7XG4gICAgY29uc3Qgc3RhdHVzU3BhbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBzbWFydC0ke3NlcnZpY2V9LXN0YXR1c2ApO1xuXG4gICAgY29uc3QgdXJsID0gdXJsSW5wdXQ/LnZhbHVlLnRyaW0oKTtcbiAgICBjb25zdCBhcGlLZXkgPSBrZXlJbnB1dD8udmFsdWUudHJpbSgpO1xuXG4gICAgaWYgKCF1cmwgfHwgIWFwaUtleSkge1xuICAgICAgc3RhdHVzU3Bhbi5pbm5lckhUTUwgPSAnPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5FbnRlciBVUkwgYW5kIEFQSSBrZXk8L3NwYW4+JztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzdGF0dXNTcGFuLmlubmVySFRNTCA9ICc8c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+JztcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2Fyci90ZXN0LWNvbm5lY3Rpb24nLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBzZXJ2aWNlLCB1cmwsIGFwaUtleSB9KVxuICAgICAgfSk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBzdGF0dXNTcGFuLmlubmVySFRNTCA9IGA8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1vay1mZyk7XCI+JiMxMDAwMzsgJHtlc2NhcGVIdG1sKGRhdGEuYXBwTmFtZSB8fCAnQ29ubmVjdGVkJyl9IHYke2VzY2FwZUh0bWwoZGF0YS52ZXJzaW9uIHx8ICcnKX08L3NwYW4+YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXR1c1NwYW4uaW5uZXJIVE1MID0gYDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+JiMxMDAwNzsgJHtlc2NhcGVIdG1sKGRhdGEuZXJyb3IpfTwvc3Bhbj5gO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHN0YXR1c1NwYW4uaW5uZXJIVE1MID0gYDxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+JiMxMDAwNzsgJHtlc2NhcGVIdG1sKGUubWVzc2FnZSl9PC9zcGFuPmA7XG4gICAgfVxuICB9O1xuXG4gIC8vIFBoYXNlIDM6IFNtYXJ0IENvbm5lY3RcbiAgYXN5bmMgZnVuY3Rpb24gc21hcnRDb25uZWN0KCkge1xuICAgIHNob3dQaGFzZSgncHJvZ3Jlc3MnKTtcbiAgICBwcm9ncmVzc1N0ZXBzLmlubmVySFRNTCA9ICc8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiAyMHB4O1wiPjxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj48ZGl2IHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogOHB4O1wiPkNvbm5lY3Rpbmcgc2VydmljZXMuLi48L2Rpdj48L2Rpdj4nO1xuXG4gICAgLy8gR2F0aGVyIGlucHV0XG4gICAgY29uc3Qgc2VydmljZXMgPSB7fTtcbiAgICBmb3IgKGNvbnN0IHN2YyBvZiBbJ3JhZGFycicsICdzb25hcnInLCAncHJvd2xhcnInXSkge1xuICAgICAgY29uc3QgdXJsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYHNtYXJ0LSR7c3ZjfS11cmxgKT8udmFsdWUudHJpbSgpO1xuICAgICAgY29uc3QgYXBpS2V5ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYHNtYXJ0LSR7c3ZjfS1rZXlgKT8udmFsdWUudHJpbSgpO1xuICAgICAgaWYgKGFwaUtleSAmJiB1cmwpIHtcbiAgICAgICAgc2VydmljZXNbc3ZjXSA9IHsgYXBpS2V5LCB1cmwgfTtcbiAgICAgIH0gZWxzZSBpZiAoYXBpS2V5KSB7XG4gICAgICAgIC8vIEtleSBwcm92aWRlZCB3aXRob3V0IFVSTCAtIGxldCBiYWNrZW5kIHJlc29sdmVcbiAgICAgICAgc2VydmljZXNbc3ZjXSA9IHsgYXBpS2V5IH07XG4gICAgICB9XG4gICAgICAvLyBJZiBubyBrZXkgZW50ZXJlZCBidXQgc2VydmljZSB3YXMgYWxyZWFkeSBjb25uZWN0ZWQsIGJhY2tlbmQgdXNlcyBzdG9yZWQgY3JlZGVudGlhbHNcbiAgICB9XG5cbiAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgc2VydmljZXM6IE9iamVjdC5rZXlzKHNlcnZpY2VzKS5sZW5ndGggPiAwID8gc2VydmljZXMgOiB1bmRlZmluZWQsXG4gICAgICBjb25maWd1cmVQbGV4OiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc21hcnQtb3B0LXBsZXgnKT8uY2hlY2tlZCxcbiAgICAgIGNvbmZpZ3VyZVByb3dsYXJyOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc21hcnQtb3B0LXByb3dsYXJyJyk/LmNoZWNrZWQsXG4gICAgICBjb25maWd1cmVTZWVycjogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NtYXJ0LW9wdC1zZWVycicpPy5jaGVja2VkLFxuICAgICAgc2F2ZUNyZWRlbnRpYWxzOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc21hcnQtb3B0LXNhdmUnKT8uY2hlY2tlZFxuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9hcnIvc21hcnQtY29ubmVjdCcsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShwYXlsb2FkKVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICAgIC8vIFJlbmRlciBwcm9ncmVzcyBzdGVwc1xuICAgICAgbGV0IHN0ZXBzSHRtbCA9ICcnO1xuICAgICAgZm9yIChjb25zdCBzdGVwIG9mIChkYXRhLnN0ZXBzIHx8IFtdKSkge1xuICAgICAgICBjb25zdCBpY29uID0gc3RlcC5zdGF0dXMgPT09ICdzdWNjZXNzJyA/ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1vay1mZyk7XCI+JiMxMDAwMzs8L3NwYW4+J1xuICAgICAgICAgICAgICAgICAgIDogJzxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+JiMxMDAwNzs8L3NwYW4+JztcbiAgICAgICAgY29uc3QgZGV0YWlsQ29sb3IgPSBzdGVwLnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnID8gJ3ZhcigtLW11dGVkKScgOiAndmFyKC0tYmFkLWZnKSc7XG4gICAgICAgIHN0ZXBzSHRtbCArPSBgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyBwYWRkaW5nOiA2cHggMTBweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogNnB4OyBmb250LXNpemU6IDAuODVyZW07XCI+XG4gICAgICAgICAgJHtpY29ufVxuICAgICAgICAgIDxzcGFuPiR7ZXNjYXBlSHRtbChzdGVwLnN0ZXApfTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiBhdXRvOyBmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiAke2RldGFpbENvbG9yfTtcIj4ke2VzY2FwZUh0bWwoc3RlcC5kZXRhaWxzIHx8ICcnKX08L3NwYW4+XG4gICAgICAgIDwvZGl2PmA7XG4gICAgICB9XG4gICAgICBwcm9ncmVzc1N0ZXBzLmlubmVySFRNTCA9IHN0ZXBzSHRtbDtcblxuICAgICAgLy8gU2hvdyByZXN1bHRzIGFmdGVyIGJyaWVmIGRlbGF5XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHNob3dSZXN1bHRzKGRhdGEpLCA1MDApO1xuXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcHJvZ3Jlc3NTdGVwcy5pbm5lckhUTUwgPSBgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDEycHg7IGNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkNvbm5lY3Rpb24gZXJyb3I6ICR7ZXNjYXBlSHRtbChlLm1lc3NhZ2UpfTwvZGl2PmA7XG4gICAgfVxuICB9XG5cbiAgLy8gUGhhc2UgNDogUmVzdWx0c1xuICBmdW5jdGlvbiBzaG93UmVzdWx0cyhkYXRhKSB7XG4gICAgc2hvd1BoYXNlKCdyZXN1bHRzJyk7XG5cbiAgICBjb25zdCBzID0gZGF0YS5zdW1tYXJ5IHx8IHt9O1xuICAgIGNvbnN0IGFsbEdvb2QgPSBzLmZhaWxlZCA9PT0gMCAmJiBzLnN1Y2NlZWRlZCA+IDA7XG4gICAgY29uc3QgaGVhZGVyQ29sb3IgPSBhbGxHb29kID8gJ3ZhcigtLW9rLWZnKScgOiAnI2YzOWMxMic7XG4gICAgY29uc3QgaGVhZGVySWNvbiA9IGFsbEdvb2QgPyAnJiMxMDAwMzsnIDogJyYjOTg4ODsnO1xuICAgIGNvbnN0IGhlYWRlclRleHQgPSBhbGxHb29kID8gJ0FsbCBDb25uZWN0ZWQhJyA6IGAke2VzY2FwZUh0bWwoU3RyaW5nKHMuc3VjY2VlZGVkKSl9LyR7ZXNjYXBlSHRtbChTdHJpbmcocy50b3RhbFN0ZXBzKSl9IFN0ZXBzIFN1Y2NlZWRlZGA7XG5cbiAgICBsZXQgaHRtbCA9IGA8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiAxNnB4OyBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgJHtoZWFkZXJDb2xvcn0gMTIlLCB0cmFuc3BhcmVudCk7IGJvcmRlci1yYWRpdXM6IDEwcHg7IGJvcmRlcjogMXB4IHNvbGlkICR7aGVhZGVyQ29sb3J9OyBtYXJnaW4tYm90dG9tOiAxMnB4O1wiPlxuICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMS41cmVtOyBjb2xvcjogJHtoZWFkZXJDb2xvcn07XCI+JHtoZWFkZXJJY29ufTwvZGl2PlxuICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMS4xcmVtOyBmb250LXdlaWdodDogNjAwOyBjb2xvcjogJHtoZWFkZXJDb2xvcn07XCI+JHtoZWFkZXJUZXh0fTwvZGl2PlxuICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogNHB4O1wiPiR7ZXNjYXBlSHRtbChTdHJpbmcocy5zdWNjZWVkZWQpKX0gc3VjY2VlZGVkLCAke2VzY2FwZUh0bWwoU3RyaW5nKHMuZmFpbGVkKSl9IGZhaWxlZDwvZGl2PlxuICAgIDwvZGl2PmA7XG5cbiAgICAvLyBTdGVwcyBkZXRhaWxcbiAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgZ2FwOiA0cHg7XCI+JztcbiAgICBmb3IgKGNvbnN0IHN0ZXAgb2YgKGRhdGEuc3RlcHMgfHwgW10pKSB7XG4gICAgICBjb25zdCBpY29uID0gc3RlcC5zdGF0dXMgPT09ICdzdWNjZXNzJyA/ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1vay1mZyk7XCI+JiMxMDAwMzs8L3NwYW4+J1xuICAgICAgICAgICAgICAgICA6ICc8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPiYjMTAwMDc7PC9zcGFuPic7XG4gICAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7IHBhZGRpbmc6IDRweCA4cHg7IGZvbnQtc2l6ZTogMC44cmVtO1wiPlxuICAgICAgICAke2ljb259ICR7ZXNjYXBlSHRtbChzdGVwLnN0ZXApfSA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiBhdXRvOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBmb250LXNpemU6IDAuNzVyZW07XCI+JHtlc2NhcGVIdG1sKHN0ZXAuZGV0YWlscyB8fCAnJyl9PC9zcGFuPlxuICAgICAgPC9kaXY+YDtcbiAgICB9XG4gICAgaHRtbCArPSAnPC9kaXY+JztcblxuICAgIHJlc3VsdHNDb250ZW50LmlubmVySFRNTCA9IGh0bWw7XG5cbiAgICAvLyBTaG93IHJldHJ5IGJ1dHRvbiBpZiBhbnkgZmFpbHVyZXNcbiAgICByZXRyeUJ0bi5zdHlsZS5kaXNwbGF5ID0gcy5mYWlsZWQgPiAwID8gJ2Jsb2NrJyA6ICdub25lJztcblxuICAgIC8vIEZldGNoIFBsZXggbGlicmFyaWVzIGlmIFBsZXggd2FzIGNvbm5lY3RlZFxuICAgIGlmIChkYXRhLnN0ZXBzPy5zb21lKHN0ID0+IHN0LnN0ZXAuaW5jbHVkZXMoJ1BsZXgnKSAmJiBzdC5zdGF0dXMgPT09ICdzdWNjZXNzJykpIHtcbiAgICAgIGZldGNoUGxleExpYnJhcmllcygpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGZldGNoUGxleExpYnJhcmllcygpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvcGxleC9saWJyYXJpZXMnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2VzcyAmJiBkYXRhLmxpYnJhcmllcz8ubGVuZ3RoID4gMCkge1xuICAgICAgICBsZXQgaHRtbCA9IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogOHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPlxuICAgICAgICAgIDxoNCBzdHlsZT1cIm1hcmdpbjogMCAwIDhweDsgZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tYWNjZW50KTtcIj5cdUQ4M0NcdURGQUMgJHtlc2NhcGVIdG1sKGRhdGEuc2VydmVyTmFtZSl9IExpYnJhcmllczwvaDQ+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGZsZXgtd3JhcDogd3JhcDsgZ2FwOiA4cHg7XCI+YDtcbiAgICAgICAgZm9yIChjb25zdCBsaWIgb2YgZGF0YS5saWJyYXJpZXMpIHtcbiAgICAgICAgICBjb25zdCB0eXBlSWNvbiA9IGxpYi50eXBlID09PSAnbW92aWUnID8gJ1x1RDgzQ1x1REZBQycgOiBsaWIudHlwZSA9PT0gJ3Nob3cnID8gJ1x1RDgzRFx1RENGQScgOiAnXHVEODNDXHVERkI1JztcbiAgICAgICAgICBodG1sICs9IGA8ZGl2IHN0eWxlPVwicGFkZGluZzogOHB4IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmcpOyBib3JkZXItcmFkaXVzOiA2cHg7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj5cbiAgICAgICAgICAgICR7dHlwZUljb259IDxzdHJvbmc+JHtlc2NhcGVIdG1sKGxpYi50aXRsZSl9PC9zdHJvbmc+XG4gICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7IGZvbnQtc2l6ZTogMC43NXJlbTtcIj4ke2VzY2FwZUh0bWwoU3RyaW5nKGxpYi5jb3VudCkpfSBpdGVtczwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9XG4gICAgICAgIGh0bWwgKz0gJzwvZGl2PjwvZGl2Pic7XG4gICAgICAgIHBsZXhMaWJyYXJpZXMuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgcGxleExpYnJhcmllcy5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBJZ25vcmUgUGxleCBsaWJyYXJ5IGZldGNoIGVycm9yc1xuICAgIH1cbiAgfVxuXG4gIC8vIEV2ZW50IGxpc3RlbmVyc1xuICBvcGVuQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgcGxleExpYnJhcmllcy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHNtYXJ0RGV0ZWN0KCk7XG4gIH0pO1xuXG4gIHdpcmVNb2RhbChtb2RhbCwgY2FuY2VsQnRuKTtcbiAgY29ubmVjdEJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzbWFydENvbm5lY3QpO1xuICByZXRyeUJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzbWFydENvbm5lY3QpO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gTk9USUZJQ0FUSU9OIFNFVFRJTkdTID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgY29uc3QgZXJyb3JIYW5kbGVyID0gbmV3IEVycm9ySGFuZGxlcigpO1xuICAvLyBJbmplY3QgbW9kYWwgSFRNTFxuICBpbmplY3RNb2RhbCgnbm90aWZpY2F0aW9ucy1tb2RhbCcsIGA8ZGl2IGlkPVwibm90aWZpY2F0aW9ucy1tb2RhbFwiIGNsYXNzPVwid2VhdGhlci1tb2RhbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogNTUwcHg7IG1heC13aWR0aDogNjUwcHg7XCI+XG4gICAgICA8aDM+XHVEODNEXHVERDE0IE5vdGlmaWNhdGlvbiBTZXR0aW5nczwvaDM+XG5cbiAgICAgIDwhLS0gTWFzdGVyIFRvZ2dsZSAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJhY2NlbnQtaW5mby1ib3hcIj5cbiAgICAgICAgPGxhYmVsIHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiAxMHB4OyBjdXJzb3I6IHBvaW50ZXI7XCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwibm90aWZpY2F0aW9ucy1lbmFibGVkXCIgLz5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXdlaWdodDogNjAwOyBjb2xvcjogdmFyKC0tYWNjZW50KTtcIj5FbmFibGUgTm90aWZpY2F0aW9uczwvc3Bhbj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXRpbnktbXV0ZWRcIj5SZWNlaXZlIGFsZXJ0cyB3aGVuIGNvbnRhaW5lcnMgZ28gdXAvZG93bjwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2xhYmVsPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gUHJvdmlkZXJzIFNlY3Rpb24gLS0+XG4gICAgICA8aDQgY2xhc3M9XCJzZWN0aW9uLWhlYWRpbmdcIj5Ob3RpZmljYXRpb24gUHJvdmlkZXJzPC9oND5cblxuICAgICAgPCEtLSBEaXNjb3JkIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cIm5vdGlmaWNhdGlvbi1wcm92aWRlciBwcm92aWRlci1jYXJkXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJwcm92aWRlci1oZWFkZXJcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjaGVja2JveC1sYWJlbFwiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwiZGlzY29yZC1lbmFibGVkXCIgLz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZnctNTAwXCI+RGlzY29yZDwvc3Bhbj5cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJkaXNjb3JkLXRlc3RcIiBjbGFzcz1cInRlc3QtYnRuIGJ0bi14c1wiPlRlc3Q8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJkaXNjb3JkLWNvbmZpZ1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbC1zbVwiPldlYmhvb2sgVVJMOjwvbGFiZWw+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJkaXNjb3JkLXdlYmhvb2tcIiBwbGFjZWhvbGRlcj1cImh0dHBzOi8vZGlzY29yZC5jb20vYXBpL3YxL3dlYmhvb2tzLy4uLlwiIHN0eWxlPVwid2lkdGg6IDEwMCU7XCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUZWxlZ3JhbSAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJub3RpZmljYXRpb24tcHJvdmlkZXIgcHJvdmlkZXItY2FyZFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicHJvdmlkZXItaGVhZGVyXCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2hlY2tib3gtbGFiZWxcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cInRlbGVncmFtLWVuYWJsZWRcIiAvPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmdy01MDBcIj5UZWxlZ3JhbTwvc3Bhbj5cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJ0ZWxlZ3JhbS10ZXN0XCIgY2xhc3M9XCJ0ZXN0LWJ0biBidG4teHNcIj5UZXN0PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwidGVsZWdyYW0tY29uZmlnXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkLTJjb2xcIj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsLXNtXCI+Qm90IFRva2VuOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwidGVsZWdyYW0tYm90LXRva2VuXCIgcGxhY2Vob2xkZXI9XCIxMjM0NTY6QUJDLi4uXCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWwtc21cIj5DaGF0IElEOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwidGVsZWdyYW0tY2hhdC1pZFwiIHBsYWNlaG9sZGVyPVwiLTEwMDEyMzQ1Njc4OTBcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gbnRmeS5zaCAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJub3RpZmljYXRpb24tcHJvdmlkZXIgcHJvdmlkZXItY2FyZFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicHJvdmlkZXItaGVhZGVyXCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2hlY2tib3gtbGFiZWxcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cIm50ZnktZW5hYmxlZFwiIC8+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZ3LTUwMFwiPm50Znkuc2g8L3NwYW4+XG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwibnRmeS10ZXN0XCIgY2xhc3M9XCJ0ZXN0LWJ0biBidG4teHNcIj5UZXN0PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwibnRmeS1jb25maWdcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdyaWQtdGVtcGxhdGUtY29sdW1uczogMmZyIDFmcjsgZ2FwOiA4cHg7XCI+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbC1zbVwiPlNlcnZlciBVUkw6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJudGZ5LXNlcnZlclwiIHBsYWNlaG9sZGVyPVwiaHR0cHM6Ly9udGZ5LnNoXCIgdmFsdWU9XCJodHRwczovL250Znkuc2hcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbC1zbVwiPlRvcGljOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwibnRmeS10b3BpY1wiIHBsYWNlaG9sZGVyPVwiZGFzaGNhZGR5LWFsZXJ0c1wiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBFbWFpbCAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJub3RpZmljYXRpb24tcHJvdmlkZXIgcHJvdmlkZXItY2FyZFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicHJvdmlkZXItaGVhZGVyXCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2hlY2tib3gtbGFiZWxcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImVtYWlsLWVuYWJsZWRcIiAvPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmdy01MDBcIj5FbWFpbCAoU01UUCk8L3NwYW4+XG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwiZW1haWwtdGVzdFwiIGNsYXNzPVwidGVzdC1idG4gYnRuLXhzXCI+VGVzdDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cImVtYWlsLWNvbmZpZ1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAyZnIgMWZyOyBnYXA6IDhweDsgbWFyZ2luLWJvdHRvbTogOHB4O1wiPlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWwtc21cIj5TTVRQIEhvc3Q6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJlbWFpbC1ob3N0XCIgcGxhY2Vob2xkZXI9XCJzbXRwLmdtYWlsLmNvbVwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsLXNtXCI+UG9ydDo8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGlkPVwiZW1haWwtcG9ydFwiIHZhbHVlPVwiNTg3XCIgcGxhY2Vob2xkZXI9XCI1ODdcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdyaWQtdGVtcGxhdGUtY29sdW1uczogMWZyIDFmcjsgZ2FwOiA4cHg7IG1hcmdpbi1ib3R0b206IDhweDtcIj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsLXNtXCI+VXNlcm5hbWU6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJlbWFpbC11c2VyXCIgcGxhY2Vob2xkZXI9XCJ1c2VyQGdtYWlsLmNvbVwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsLXNtXCI+UGFzc3dvcmQ6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJwYXNzd29yZFwiIGlkPVwiZW1haWwtcGFzc1wiIHBsYWNlaG9sZGVyPVwiYXBwIHBhc3N3b3JkXCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDFmciAxZnI7IGdhcDogOHB4O1wiPlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWwtc21cIj5Gcm9tOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwiZW1haWwtZnJvbVwiIHBsYWNlaG9sZGVyPVwiRGFzaENhZGR5ICZsdDtub3JlcGx5QGV4YW1wbGUuY29tJmd0O1wiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsLXNtXCI+VG86PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJlbWFpbC10b1wiIHBsYWNlaG9sZGVyPVwiYWRtaW5AZXhhbXBsZS5jb21cIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGxhYmVsIHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA2cHg7IG1hcmdpbi10b3A6IDhweDsgZm9udC1zaXplOiAwLjhyZW07XCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJlbWFpbC1zZWN1cmVcIiAvPiBVc2UgVExTIChwb3J0IDQ2NSlcbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEhlYWx0aCBDaGVjayBTZXR0aW5ncyAtLT5cbiAgICAgIDxoNCBjbGFzcz1cInNlY3Rpb24taGVhZGluZ1wiPkhlYWx0aCBNb25pdG9yaW5nPC9oND5cbiAgICAgIDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+XG4gICAgICAgIDxsYWJlbCBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogMTBweDsgY3Vyc29yOiBwb2ludGVyOyBtYXJnaW4tYm90dG9tOiAxMHB4O1wiPlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImhlYWx0aC1jaGVjay1lbmFibGVkXCIgLz5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmdy01MDBcIj5FbmFibGUgSGVhbHRoIE1vbml0b3Jpbmc8L3NwYW4+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC10aW55LW11dGVkXCI+UGVyaW9kaWNhbGx5IGNoZWNrIGNvbnRhaW5lciBzdGF0dXM8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGRpdiBpZD1cImhlYWx0aC1jaGVjay1jb25maWdcIiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogMTBweDtcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbC1zbVwiPkNoZWNrIGludGVydmFsOjwvbGFiZWw+XG4gICAgICAgICAgPHNlbGVjdCBpZD1cImhlYWx0aC1jaGVjay1pbnRlcnZhbFwiIHN0eWxlPVwid2lkdGg6IGF1dG87XCI+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiMVwiPjEgbWludXRlPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiNVwiIHNlbGVjdGVkPjUgbWludXRlczwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjE1XCI+MTUgbWludXRlczwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjMwXCI+MzAgbWludXRlczwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjYwXCI+MSBob3VyPC9vcHRpb24+XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImhlYWx0aC1jaGVjay1ub3dcIiBzdHlsZT1cInBhZGRpbmc6IDRweCAxMHB4OyBmb250LXNpemU6IDAuNzVyZW07IG1hcmdpbi1sZWZ0OiBhdXRvO1wiPkNoZWNrIE5vdzwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cImhlYWx0aC1jaGVjay1zdGF0dXNcIiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogOHB4O1wiPlxuICAgICAgICAgIExhc3QgY2hlY2s6IE5ldmVyXG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gRXZlbnQgVHlwZXMgLS0+XG4gICAgICA8aDQgY2xhc3M9XCJzZWN0aW9uLWhlYWRpbmdcIj5FdmVudHMgdG8gTm90aWZ5PC9oND5cbiAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDFmciAxZnI7IGdhcDogNnB4OyBwYWRkaW5nOiAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImNoZWNrYm94LWxhYmVsLXNtXCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwiZXZlbnQtY29udGFpbmVyLWRvd25cIiBjaGVja2VkIC8+IENvbnRhaW5lciBEb3duXG4gICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImNoZWNrYm94LWxhYmVsLXNtXCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwiZXZlbnQtY29udGFpbmVyLXVwXCIgY2hlY2tlZCAvPiBDb250YWluZXIgUmVjb3ZlcmVkXG4gICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImNoZWNrYm94LWxhYmVsLXNtXCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwiZXZlbnQtZGVwbG95LXN1Y2Nlc3NcIiBjaGVja2VkIC8+IERlcGxveW1lbnQgU3VjY2Vzc1xuICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJjaGVja2JveC1sYWJlbC1zbVwiPlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImV2ZW50LWRlcGxveS1mYWlsZWRcIiBjaGVja2VkIC8+IERlcGxveW1lbnQgRmFpbGVkXG4gICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImNoZWNrYm94LWxhYmVsLXNtXCIgc3R5bGU9XCJncmlkLWNvbHVtbjogMSAvIC0xO1wiPlxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImV2ZW50LXJlc291cmNlLWFsZXJ0XCIgY2hlY2tlZCAvPiBSZXNvdXJjZSBBbGVydHNcbiAgICAgICAgPC9sYWJlbD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEhpc3RvcnkgLS0+XG4gICAgICA8aDQgY2xhc3M9XCJzZWN0aW9uLWhlYWRpbmdcIj5Ob3RpZmljYXRpb24gSGlzdG9yeTwvaDQ+XG4gICAgICA8ZGl2IGlkPVwibm90aWZpY2F0aW9uLWhpc3RvcnlcIiBzdHlsZT1cIm1heC1oZWlnaHQ6IDE1MHB4OyBvdmVyZmxvdy15OiBhdXRvOyBwYWRkaW5nOiA4cHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgZm9udC1zaXplOiAwLjhyZW07XCI+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDIwcHg7XCI+Tm8gbm90aWZpY2F0aW9ucyB5ZXQ8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBpZD1cImxhc3Qtbm90aWZpY2F0aW9uLXNlbnRcIiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgdGV4dC1hbGlnbjogY2VudGVyOyBtYXJnaW4tdG9wOiA2cHg7XCI+PC9kaXY+XG5cbiAgICAgIDwhLS0gQnV0dG9ucyAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWJ1dHRvbnMgbW9kYWwtZm9vdGVyLWJhclwiPlxuICAgICAgICA8YnV0dG9uIGlkPVwibm90aWZpY2F0aW9ucy1zZW5kLXRlc3RcIiBjbGFzcz1cImJ0bi1zZWNvbmRhcnlcIiBzdHlsZT1cIm1hcmdpbi1yaWdodDogYXV0bztcIj5TZW5kIFRlc3Q8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBpZD1cIm5vdGlmaWNhdGlvbnMtY2FuY2VsXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gaWQ9XCJub3RpZmljYXRpb25zLXNhdmVcIiBjbGFzcz1cImJ0bi1hY2NlbnRcIj5TYXZlIFNldHRpbmdzPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+YCk7XG5cbiAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbm90aWZpY2F0aW9ucy1tb2RhbCcpO1xuICBjb25zdCBvcGVuQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21hbmFnZS1ub3RpZmljYXRpb25zJyk7XG4gIGNvbnN0IHNhdmVCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbm90aWZpY2F0aW9ucy1zYXZlJyk7XG4gIGNvbnN0IGNhbmNlbEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdub3RpZmljYXRpb25zLWNhbmNlbCcpO1xuXG4gIC8vIFByb3ZpZGVyIHRvZ2dsZSBoYW5kbGVyc1xuICBbJ2Rpc2NvcmQnLCAndGVsZWdyYW0nLCAnbnRmeScsICdlbWFpbCddLmZvckVhY2gocHJvdmlkZXIgPT4ge1xuICAgIGNvbnN0IGNoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYCR7cHJvdmlkZXJ9LWVuYWJsZWRgKTtcbiAgICBjb25zdCBjb25maWcgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgJHtwcm92aWRlcn0tY29uZmlnYCk7XG5cbiAgICBjaGVja2JveD8uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKCkgPT4ge1xuICAgICAgY29uZmlnLnN0eWxlLmRpc3BsYXkgPSBjaGVja2JveC5jaGVja2VkID8gJ2Jsb2NrJyA6ICdub25lJztcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gSGVhbHRoIGNoZWNrIHRvZ2dsZVxuICBjb25zdCBoZWFsdGhDaGVja0VuYWJsZWQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWNoZWNrLWVuYWJsZWQnKTtcbiAgY29uc3QgaGVhbHRoQ2hlY2tDb25maWcgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWNoZWNrLWNvbmZpZycpO1xuICBoZWFsdGhDaGVja0VuYWJsZWQ/LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsICgpID0+IHtcbiAgICBoZWFsdGhDaGVja0NvbmZpZy5zdHlsZS5vcGFjaXR5ID0gaGVhbHRoQ2hlY2tFbmFibGVkLmNoZWNrZWQgPyAnMScgOiAnMC41JztcbiAgfSk7XG5cbiAgLy8gTG9hZCBub3RpZmljYXRpb24gY29uZmlnIGZyb20gQVBJXG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWROb3RpZmljYXRpb25Db25maWcoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvbm90aWZpY2F0aW9ucy9jb25maWcnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0gZGF0YS5jb25maWc7XG5cbiAgICAgICAgLy8gTWFzdGVyIHRvZ2dsZVxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbm90aWZpY2F0aW9ucy1lbmFibGVkJykuY2hlY2tlZCA9IGNvbmZpZy5lbmFibGVkO1xuXG4gICAgICAgIC8vIFByb3ZpZGVyc1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGlzY29yZC1lbmFibGVkJykuY2hlY2tlZCA9IGNvbmZpZy5wcm92aWRlcnM/LmRpc2NvcmQ/LmVuYWJsZWQgfHwgZmFsc2U7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZWxlZ3JhbS1lbmFibGVkJykuY2hlY2tlZCA9IGNvbmZpZy5wcm92aWRlcnM/LnRlbGVncmFtPy5lbmFibGVkIHx8IGZhbHNlO1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbnRmeS1lbmFibGVkJykuY2hlY2tlZCA9IGNvbmZpZy5wcm92aWRlcnM/Lm50Znk/LmVuYWJsZWQgfHwgZmFsc2U7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlbWFpbC1lbmFibGVkJykuY2hlY2tlZCA9IGNvbmZpZy5wcm92aWRlcnM/LmVtYWlsPy5lbmFibGVkIHx8IGZhbHNlO1xuXG4gICAgICAgIC8vIFNob3cvaGlkZSBjb25maWcgc2VjdGlvbnNcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Rpc2NvcmQtY29uZmlnJykuc3R5bGUuZGlzcGxheSA9IGNvbmZpZy5wcm92aWRlcnM/LmRpc2NvcmQ/LmVuYWJsZWQgPyAnYmxvY2snIDogJ25vbmUnO1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVsZWdyYW0tY29uZmlnJykuc3R5bGUuZGlzcGxheSA9IGNvbmZpZy5wcm92aWRlcnM/LnRlbGVncmFtPy5lbmFibGVkID8gJ2Jsb2NrJyA6ICdub25lJztcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ250ZnktY29uZmlnJykuc3R5bGUuZGlzcGxheSA9IGNvbmZpZy5wcm92aWRlcnM/Lm50Znk/LmVuYWJsZWQgPyAnYmxvY2snIDogJ25vbmUnO1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZW1haWwtY29uZmlnJykuc3R5bGUuZGlzcGxheSA9IGNvbmZpZy5wcm92aWRlcnM/LmVtYWlsPy5lbmFibGVkID8gJ2Jsb2NrJyA6ICdub25lJztcblxuICAgICAgICAvLyBudGZ5IHNlcnZlciBVUkxcbiAgICAgICAgaWYgKGNvbmZpZy5wcm92aWRlcnM/Lm50Znk/LnNlcnZlclVybCkge1xuICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdudGZ5LXNlcnZlcicpLnZhbHVlID0gY29uZmlnLnByb3ZpZGVycy5udGZ5LnNlcnZlclVybDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGVtYWlsIGZpZWxkc1xuICAgICAgICBpZiAoY29uZmlnLnByb3ZpZGVycz8uZW1haWw/Lmhvc3QpIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlbWFpbC1ob3N0JykudmFsdWUgPSBjb25maWcucHJvdmlkZXJzLmVtYWlsLmhvc3Q7XG4gICAgICAgIGlmIChjb25maWcucHJvdmlkZXJzPy5lbWFpbD8uZnJvbSkgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2VtYWlsLWZyb20nKS52YWx1ZSA9IGNvbmZpZy5wcm92aWRlcnMuZW1haWwuZnJvbTtcblxuICAgICAgICAvLyBIZWFsdGggY2hlY2tcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1jaGVjay1lbmFibGVkJykuY2hlY2tlZCA9IGNvbmZpZy5oZWFsdGhDaGVjaz8uZW5hYmxlZCB8fCBmYWxzZTtcbiAgICAgICAgaWYgKGNvbmZpZy5oZWFsdGhDaGVjaz8uaW50ZXJ2YWxNaW51dGVzKSB7XG4gICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1jaGVjay1pbnRlcnZhbCcpLnZhbHVlID0gY29uZmlnLmhlYWx0aENoZWNrLmludGVydmFsTWludXRlcztcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29uZmlnLmhlYWx0aENoZWNrPy5sYXN0Q2hlY2spIHtcbiAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWNoZWNrLXN0YXR1cycpLnRleHRDb250ZW50ID1cbiAgICAgICAgICAgIGBMYXN0IGNoZWNrOiAke25ldyBEYXRlKGNvbmZpZy5oZWFsdGhDaGVjay5sYXN0Q2hlY2spLnRvTG9jYWxlU3RyaW5nKCl9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEV2ZW50c1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXZlbnQtY29udGFpbmVyLWRvd24nKS5jaGVja2VkID0gY29uZmlnLmV2ZW50cz8uY29udGFpbmVyRG93biAhPT0gZmFsc2U7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdldmVudC1jb250YWluZXItdXAnKS5jaGVja2VkID0gY29uZmlnLmV2ZW50cz8uY29udGFpbmVyVXAgIT09IGZhbHNlO1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXZlbnQtZGVwbG95LXN1Y2Nlc3MnKS5jaGVja2VkID0gY29uZmlnLmV2ZW50cz8uZGVwbG95bWVudFN1Y2Nlc3MgIT09IGZhbHNlO1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXZlbnQtZGVwbG95LWZhaWxlZCcpLmNoZWNrZWQgPSBjb25maWcuZXZlbnRzPy5kZXBsb3ltZW50RmFpbGVkICE9PSBmYWxzZTtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2V2ZW50LXJlc291cmNlLWFsZXJ0JykuY2hlY2tlZCA9IGNvbmZpZy5ldmVudHM/LnJlc291cmNlQWxlcnQgIT09IGZhbHNlO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBlcnJvckhhbmRsZXIubG9nRXJyb3IoJ1tOb3RpZmljYXRpb25zXSBMb2FkIENvbmZpZycsIGVycm9yLCB7IGZ1bmN0aW9uOiAnbG9hZENvbmZpZycgfSk7XG4gICAgfVxuICB9XG5cbiAgLy8gTG9hZCBub3RpZmljYXRpb24gaGlzdG9yeVxuICBhc3luYyBmdW5jdGlvbiBsb2FkTm90aWZpY2F0aW9uSGlzdG9yeSgpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9ub3RpZmljYXRpb25zL2hpc3Rvcnk/bGltaXQ9MTAnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdub3RpZmljYXRpb24taGlzdG9yeScpO1xuICAgICAgaWYgKGRhdGEuc3VjY2VzcyAmJiBkYXRhLmhpc3Rvcnk/Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9IGRhdGEuaGlzdG9yeS5tYXAoaXRlbSA9PiB7XG4gICAgICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKGl0ZW0udGltZXN0YW1wKS50b0xvY2FsZVN0cmluZygpO1xuICAgICAgICAgIGNvbnN0IHR5cGVDb2xvcnMgPSB7XG4gICAgICAgICAgICBzdWNjZXNzOiAndmFyKC0tb2stZmcpJyxcbiAgICAgICAgICAgIGVycm9yOiAndmFyKC0tYmFkLWZnKScsXG4gICAgICAgICAgICB3YXJuaW5nOiAnI2YzOWMxMicsXG4gICAgICAgICAgICBpbmZvOiAndmFyKC0tYWNjZW50KSdcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwicGFkZGluZzogNnB4IDhweDsgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyBhbGlnbi1pdGVtczogZmxleC1zdGFydDtcIj5cbiAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJjb2xvcjogJHt0eXBlQ29sb3JzW2l0ZW0udHlwZV0gfHwgJ3ZhcigtLW11dGVkKSd9XCI+JHtpdGVtLnR5cGUgPT09ICdzdWNjZXNzJyA/ICdcdTI3MTMnIDogaXRlbS50eXBlID09PSAnZXJyb3InID8gJ1x1MjcxNycgOiAnXHUyMTM5J308L3NwYW4+XG4gICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmbGV4OiAxOyBtaW4td2lkdGg6IDA7XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA1MDA7IHdoaXRlLXNwYWNlOiBub3dyYXA7IG92ZXJmbG93OiBoaWRkZW47IHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1wiPiR7ZXNjYXBlSHRtbChpdGVtLnRpdGxlKX08L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjdyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JHtkYXRlfTwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIGA7XG4gICAgICAgIH0pLmpvaW4oJycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgdGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiAyMHB4O1wiPk5vIG5vdGlmaWNhdGlvbnMgeWV0PC9kaXY+JztcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZXJyb3JIYW5kbGVyLmxvZ0Vycm9yKCdbTm90aWZpY2F0aW9uc10gTG9hZCBIaXN0b3J5JywgZXJyb3IsIHsgZnVuY3Rpb246ICdsb2FkSGlzdG9yeScgfSk7XG4gICAgfVxuICB9XG5cbiAgLy8gU2F2ZSBub3RpZmljYXRpb24gY29uZmlnXG4gIGFzeW5jIGZ1bmN0aW9uIHNhdmVOb3RpZmljYXRpb25Db25maWcoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgICAgZW5hYmxlZDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25vdGlmaWNhdGlvbnMtZW5hYmxlZCcpLmNoZWNrZWQsXG4gICAgICAgIHByb3ZpZGVyczoge1xuICAgICAgICAgIGRpc2NvcmQ6IHtcbiAgICAgICAgICAgIGVuYWJsZWQ6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkaXNjb3JkLWVuYWJsZWQnKS5jaGVja2VkLFxuICAgICAgICAgICAgd2ViaG9va1VybDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Rpc2NvcmQtd2ViaG9vaycpLnZhbHVlLnRyaW0oKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGVsZWdyYW06IHtcbiAgICAgICAgICAgIGVuYWJsZWQ6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZWxlZ3JhbS1lbmFibGVkJykuY2hlY2tlZCxcbiAgICAgICAgICAgIGJvdFRva2VuOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVsZWdyYW0tYm90LXRva2VuJykudmFsdWUudHJpbSgpLFxuICAgICAgICAgICAgY2hhdElkOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVsZWdyYW0tY2hhdC1pZCcpLnZhbHVlLnRyaW0oKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgbnRmeToge1xuICAgICAgICAgICAgZW5hYmxlZDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ250ZnktZW5hYmxlZCcpLmNoZWNrZWQsXG4gICAgICAgICAgICBzZXJ2ZXJVcmw6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdudGZ5LXNlcnZlcicpLnZhbHVlLnRyaW0oKSB8fCAnaHR0cHM6Ly9udGZ5LnNoJyxcbiAgICAgICAgICAgIHRvcGljOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbnRmeS10b3BpYycpLnZhbHVlLnRyaW0oKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgZW1haWw6IHtcbiAgICAgICAgICAgIGVuYWJsZWQ6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlbWFpbC1lbmFibGVkJykuY2hlY2tlZCxcbiAgICAgICAgICAgIGhvc3Q6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlbWFpbC1ob3N0JykudmFsdWUudHJpbSgpLFxuICAgICAgICAgICAgcG9ydDogcGFyc2VJbnQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2VtYWlsLXBvcnQnKS52YWx1ZSkgfHwgNTg3LFxuICAgICAgICAgICAgc2VjdXJlOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZW1haWwtc2VjdXJlJykuY2hlY2tlZCxcbiAgICAgICAgICAgIHVzZXI6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlbWFpbC11c2VyJykudmFsdWUudHJpbSgpLFxuICAgICAgICAgICAgcGFzczogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2VtYWlsLXBhc3MnKS52YWx1ZS50cmltKCksXG4gICAgICAgICAgICBmcm9tOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZW1haWwtZnJvbScpLnZhbHVlLnRyaW0oKSxcbiAgICAgICAgICAgIHRvOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZW1haWwtdG8nKS52YWx1ZS50cmltKClcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGV2ZW50czoge1xuICAgICAgICAgIGNvbnRhaW5lckRvd246IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdldmVudC1jb250YWluZXItZG93bicpLmNoZWNrZWQsXG4gICAgICAgICAgY29udGFpbmVyVXA6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdldmVudC1jb250YWluZXItdXAnKS5jaGVja2VkLFxuICAgICAgICAgIGRlcGxveW1lbnRTdWNjZXNzOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXZlbnQtZGVwbG95LXN1Y2Nlc3MnKS5jaGVja2VkLFxuICAgICAgICAgIGRlcGxveW1lbnRGYWlsZWQ6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdldmVudC1kZXBsb3ktZmFpbGVkJykuY2hlY2tlZCxcbiAgICAgICAgICByZXNvdXJjZUFsZXJ0OiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXZlbnQtcmVzb3VyY2UtYWxlcnQnKS5jaGVja2VkXG4gICAgICAgIH0sXG4gICAgICAgIGhlYWx0aENoZWNrOiB7XG4gICAgICAgICAgZW5hYmxlZDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1jaGVjay1lbmFibGVkJykuY2hlY2tlZCxcbiAgICAgICAgICBpbnRlcnZhbE1pbnV0ZXM6IHBhcnNlSW50KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtY2hlY2staW50ZXJ2YWwnKS52YWx1ZSkgfHwgNVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL25vdGlmaWNhdGlvbnMvY29uZmlnJywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGNvbmZpZylcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdOb3RpZmljYXRpb24gc2V0dGluZ3Mgc2F2ZWQnLCAnc3VjY2VzcycsIDMwMDApO1xuICAgICAgICBtb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKGBGYWlsZWQgdG8gc2F2ZTogJHtkYXRhLmVycm9yfWAsICdlcnJvcicsIDMwMDApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKGBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIDMwMDApO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRlc3Qgbm90aWZpY2F0aW9uIGhhbmRsZXJzXG4gIGFzeW5jIGZ1bmN0aW9uIHRlc3RQcm92aWRlcihwcm92aWRlcikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL25vdGlmaWNhdGlvbnMvdGVzdCcsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHByb3ZpZGVyIH0pXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbihgVGVzdCAke3Byb3ZpZGVyfSBub3RpZmljYXRpb24gc2VudCFgLCAnc3VjY2VzcycsIDMwMDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbihgVGVzdCBmYWlsZWQ6ICR7ZGF0YS5lcnJvcn1gLCAnZXJyb3InLCAzMDAwKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbihgRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCAzMDAwKTtcbiAgICB9XG4gIH1cblxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGlzY29yZC10ZXN0Jyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gdGVzdFByb3ZpZGVyKCdkaXNjb3JkJykpO1xuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVsZWdyYW0tdGVzdCcpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHRlc3RQcm92aWRlcigndGVsZWdyYW0nKSk7XG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdudGZ5LXRlc3QnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0ZXN0UHJvdmlkZXIoJ250ZnknKSk7XG4gIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdlbWFpbC10ZXN0Jyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gdGVzdFByb3ZpZGVyKCdlbWFpbCcpKTtcblxuICAvLyBIZWFsdGggY2hlY2sgbm93IGJ1dHRvblxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWNoZWNrLW5vdycpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9ub3RpZmljYXRpb25zL2hlYWx0aC1jaGVjaycsIHsgbWV0aG9kOiAnUE9TVCcgfSk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtY2hlY2stc3RhdHVzJykudGV4dENvbnRlbnQgPVxuICAgICAgICAgIGBMYXN0IGNoZWNrOiAke25ldyBEYXRlKGRhdGEubGFzdENoZWNrKS50b0xvY2FsZVN0cmluZygpfSAoJHtkYXRhLmNvbnRhaW5lcnNNb25pdG9yZWR9IGNvbnRhaW5lcnMpYDtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignSGVhbHRoIGNoZWNrIGNvbXBsZXRlZCcsICdzdWNjZXNzJywgMjAwMCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oYEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgMzAwMCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBNb2RhbCBoYW5kbGVyc1xuICBvcGVuQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgbG9hZE5vdGlmaWNhdGlvbkNvbmZpZygpO1xuICAgIGxvYWROb3RpZmljYXRpb25IaXN0b3J5KCk7XG4gIH0pO1xuXG4gIHNhdmVCdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgc2F2ZU5vdGlmaWNhdGlvbkNvbmZpZyk7XG5cbiAgLy8gU2VuZCBUZXN0IGJ1dHRvbiAtIHNlbmRzIHRlc3Qgbm90aWZpY2F0aW9uIHRvIGFsbCBlbmFibGVkIHByb3ZpZGVyc1xuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbm90aWZpY2F0aW9ucy1zZW5kLXRlc3QnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25vdGlmaWNhdGlvbnMtc2VuZC10ZXN0Jyk7XG4gICAgY29uc3Qgb3JpZ2luYWxUZXh0ID0gYnRuLnRleHRDb250ZW50O1xuICAgIGJ0bi50ZXh0Q29udGVudCA9ICdTZW5kaW5nLi4uJztcbiAgICBidG4uZGlzYWJsZWQgPSB0cnVlO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvbm90aWZpY2F0aW9ucy9zZW5kJywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgXG4gICAgICAgICAgZXZlbnQ6ICd0ZXN0JyxcbiAgICAgICAgICBkYXRhOiB7IG1lc3NhZ2U6ICdUaGlzIGlzIGEgdGVzdCBub3RpZmljYXRpb24gZnJvbSBEYXNoQ2FkZHkuJyB9LFxuICAgICAgICAgIHR5cGU6ICdpbmZvJ1xuICAgICAgICB9KVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1Rlc3Qgbm90aWZpY2F0aW9uIHNlbnQhJywgJ3N1Y2Nlc3MnLCAzMDAwKTtcbiAgICAgICAgLy8gVXBkYXRlIGxhc3Qgc2VudCB0aW1lc3RhbXBcbiAgICAgICAgbG9hZE5vdGlmaWNhdGlvblN0YXR1cygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbihgVGVzdCBmYWlsZWQ6ICR7ZGF0YS5yZXN1bHRzPy5tYXAociA9PiBgJHtyLnByb3ZpZGVyfTogJHtyLmVycm9yIHx8ICdvayd9YCkuam9pbignLCAnKX1gLCAnZXJyb3InLCA1MDAwKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgc2hvd05vdGlmaWNhdGlvbihgRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCAzMDAwKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYnRuLnRleHRDb250ZW50ID0gb3JpZ2luYWxUZXh0O1xuICAgICAgYnRuLmRpc2FibGVkID0gZmFsc2U7XG4gICAgfVxuICB9KTtcblxuICAvLyBMb2FkIG5vdGlmaWNhdGlvbiBzdGF0dXMgKGxhc3Qgc2VudCB0aW1lc3RhbXApXG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWROb3RpZmljYXRpb25TdGF0dXMoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvbm90aWZpY2F0aW9ucy9zdGF0dXMnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzICYmIGRhdGEubGFzdFNlbnQpIHtcbiAgICAgICAgY29uc3QgbGFzdFNlbnRFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsYXN0LW5vdGlmaWNhdGlvbi1zZW50Jyk7XG4gICAgICAgIGlmIChsYXN0U2VudEVsKSB7XG4gICAgICAgICAgbGFzdFNlbnRFbC50ZXh0Q29udGVudCA9IGBMYXN0IHNlbnQ6ICR7bmV3IERhdGUoZGF0YS5sYXN0U2VudCkudG9Mb2NhbGVTdHJpbmcoKX1gO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIFNpbGVudGx5IGZhaWwgLSBzdGF0dXMgaXMgbm90IGNyaXRpY2FsXG4gICAgfVxuICB9XG5cbiAgd2lyZU1vZGFsKG1vZGFsLCBjYW5jZWxCdG4pO1xufSkoKTtcbjtcbi8vID09PT09PT09PT0gUEFORUwgVEFCIFNXSVRDSElORyAoc2hhcmVkIHV0aWxpdHkpID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4ge1xuICAgIGNvbnN0IHRhYiA9IGUudGFyZ2V0LmNsb3Nlc3QoJy5wYW5lbC10YWInKTtcbiAgICBpZiAoIXRhYikgcmV0dXJuO1xuICAgIGNvbnN0IHBhbmVsSWQgPSB0YWIuZGF0YXNldC5wYW5lbDtcbiAgICBpZiAoIXBhbmVsSWQpIHJldHVybjtcbiAgICBjb25zdCB0YWJCYXIgPSB0YWIuY2xvc2VzdCgnLnBhbmVsLXRhYnMnKTtcbiAgICBjb25zdCBtb2RhbENvbnRlbnQgPSB0YWJCYXIuY2xvc2VzdCgnLndlYXRoZXItbW9kYWwtY29udGVudCcpO1xuICAgIHRhYkJhci5xdWVyeVNlbGVjdG9yQWxsKCcucGFuZWwtdGFiJykuZm9yRWFjaCh0ID0+IHQuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJykpO1xuICAgIHRhYi5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICBtb2RhbENvbnRlbnQucXVlcnlTZWxlY3RvckFsbCgnLnBhbmVsLXNlY3Rpb24nKS5mb3JFYWNoKHMgPT4gcy5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKSk7XG4gICAgY29uc3QgdGFyZ2V0ID0gbW9kYWxDb250ZW50LnF1ZXJ5U2VsZWN0b3IoJyMnICsgcGFuZWxJZCk7XG4gICAgaWYgKHRhcmdldCkgdGFyZ2V0LmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICB9KTtcbn0pKCk7XG47XG4vLyA9PT09PT09PT09IFVOSUZJRUQgQkFDS1VQL1JFU1RPUkUgdjIuMCA9PT09PT09PT09XG4vLyBTaW5nbGUgZmlsZSBjYXB0dXJlcyBldmVyeXRoaW5nOiBzZXJ2ZXIgY29uZmlnICsgYnJvd3NlciBzdGF0ZSArIHRoZW1lcyArIGVuY3J5cHRpb24ga2V5XG4oZnVuY3Rpb24oKSB7XG4gIC8vIEFsbCBEYXNoQ2FkZHkgbG9jYWxTdG9yYWdlIGtleXMgdG8gaW5jbHVkZSBpbiBiYWNrdXBcbiAgdmFyIEJST1dTRVJfU1RBVEVfS0VZUyA9IFtcbiAgICAnZGFzaGNhZGR5X3NpdGVfY29uZmlnJywgJ2Rhc2hjYWRkeV9vbmJvYXJkaW5nJywgJ2Rhc2hjYWRkeS1lbmNyeXB0aW9uLWtleScsXG4gICAgJ2Rhc2hjYWRkeS1zZXR1cCcsICdkYXNoY2FkZHktY29uZmlnJyxcbiAgICAndGhlbWUnLCAndXNlci10aGVtZXMnLCAnY3VzdG9tLXRoZW1lJyxcbiAgICAnY3VzdG9tLWFwcHMnLCAnY3VzdG9tLXNlcnZpY2VzJywgJ3Rvb2xiYXItc2VjdGlvbnMnLFxuICAgICd3ZWF0aGVyLWxvY2F0aW9uJywgJ3dlYXRoZXItemlwJywgJ3dlYXRoZXItZ2VvJywgJ3dlYXRoZXItdW5pdCcsXG4gICAgJ2Nsb2NrLXN0eWxlJywgJ2Nsb2NrLWNoaW1lcycsICdjbG9jay1jaGltZS12b2x1bWUnXG4gIF07XG5cbiAgLy8gQ29sbGVjdCBhbGwgRGFzaENhZGR5IGJyb3dzZXIgc3RhdGUgZnJvbSBsb2NhbFN0b3JhZ2VcbiAgZnVuY3Rpb24gY29sbGVjdEJyb3dzZXJTdGF0ZSgpIHtcbiAgICB2YXIgc3RhdGUgPSB7fTtcbiAgICAvLyBHcmFiIGFsbCB3aGl0ZWxpc3RlZCBrZXlzXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBCUk9XU0VSX1NUQVRFX0tFWVMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBrZXkgPSBCUk9XU0VSX1NUQVRFX0tFWVNbaV07XG4gICAgICB2YXIgdmFsID0gc2FmZUdldChrZXkpO1xuICAgICAgaWYgKHZhbCAhPT0gbnVsbCAmJiB2YWwgIT09IHVuZGVmaW5lZCkgc3RhdGVba2V5XSA9IHZhbDtcbiAgICB9XG4gICAgLy8gR3JhYiBkeW5hbWljIHdpZGdldC0qLWVuYWJsZWQga2V5c1xuICAgIHRyeSB7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxvY2FsU3RvcmFnZS5sZW5ndGg7IGorKykge1xuICAgICAgICB2YXIgayA9IGxvY2FsU3RvcmFnZS5rZXkoaik7XG4gICAgICAgIGlmICgvXndpZGdldC0uKy1lbmFibGVkJC8udGVzdChrKSkge1xuICAgICAgICAgIHN0YXRlW2tdID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oayk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7IC8qIHByaXZhdGUgYnJvd3NpbmcgKi8gfVxuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIC8vIFJlc3RvcmUgYnJvd3NlciBzdGF0ZSBmcm9tIGJhY2t1cCBpbnRvIGxvY2FsU3RvcmFnZVxuICBmdW5jdGlvbiByZXN0b3JlQnJvd3NlclN0YXRlKGJyb3dzZXJTdGF0ZSkge1xuICAgIGlmICghYnJvd3NlclN0YXRlIHx8IHR5cGVvZiBicm93c2VyU3RhdGUgIT09ICdvYmplY3QnKSByZXR1cm4gMDtcbiAgICB2YXIgY291bnQgPSAwO1xuICAgIGZvciAodmFyIGtleSBpbiBicm93c2VyU3RhdGUpIHtcbiAgICAgIGlmICghYnJvd3NlclN0YXRlLmhhc093blByb3BlcnR5KGtleSkpIGNvbnRpbnVlO1xuICAgICAgc2FmZVNldChrZXksIGJyb3dzZXJTdGF0ZVtrZXldKTtcbiAgICAgIGNvdW50Kys7XG4gICAgfVxuICAgIHJldHVybiBjb3VudDtcbiAgfVxuXG4gIC8vIEhhbmRsZSBsZWdhY3kgdjEuMC4wIGltcG9ydC1leHBvcnQgZm9ybWF0IChwcmUtYmFja3VwIG1vZGFsKVxuICBmdW5jdGlvbiBpc0xlZ2FjeUZvcm1hdChkYXRhKSB7XG4gICAgcmV0dXJuIGRhdGEudmVyc2lvbiAmJiAhZGF0YS5maWxlcyAmJiBkYXRhLnNlcnZpY2VzO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzdG9yZUxlZ2FjeUZvcm1hdChkYXRhKSB7XG4gICAgLy8gTWFwIHRoZSBvbGQgZmxhdCBrZXlzIGludG8gYnJvd3NlclN0YXRlIGZvciBsb2NhbFN0b3JhZ2UgcmVzdG9yZVxuICAgIHZhciBicm93c2VyU3RhdGUgPSB7fTtcbiAgICBpZiAoZGF0YS5jdXN0b21TZXJ2aWNlcykgYnJvd3NlclN0YXRlWydjdXN0b20tc2VydmljZXMnXSA9IEpTT04uc3RyaW5naWZ5KGRhdGEuY3VzdG9tU2VydmljZXMpO1xuICAgIGlmIChkYXRhLmN1c3RvbUFwcHMpIGJyb3dzZXJTdGF0ZVsnY3VzdG9tLWFwcHMnXSA9IEpTT04uc3RyaW5naWZ5KGRhdGEuY3VzdG9tQXBwcyk7XG4gICAgaWYgKGRhdGEud2VhdGhlclppcCkgYnJvd3NlclN0YXRlWyd3ZWF0aGVyLXppcCddID0gZGF0YS53ZWF0aGVyWmlwO1xuICAgIGlmIChkYXRhLnRoZW1lKSBicm93c2VyU3RhdGVbJ3RoZW1lJ10gPSBkYXRhLnRoZW1lO1xuICAgIGlmIChkYXRhLnVzZXJUaGVtZXMgJiYgT2JqZWN0LmtleXMoZGF0YS51c2VyVGhlbWVzKS5sZW5ndGgpIGJyb3dzZXJTdGF0ZVsndXNlci10aGVtZXMnXSA9IEpTT04uc3RyaW5naWZ5KGRhdGEudXNlclRoZW1lcyk7XG4gICAgcmVzdG9yZUJyb3dzZXJTdGF0ZShicm93c2VyU3RhdGUpO1xuXG4gICAgLy8gUHVzaCBzZXJ2aWNlcyB0byBzZXJ2ZXIgaWYgYXZhaWxhYmxlXG4gICAgaWYgKGRhdGEuc2VydmljZXMgJiYgQXJyYXkuaXNBcnJheShkYXRhLnNlcnZpY2VzKSkge1xuICAgICAgc2VjdXJlRmV0Y2goJy9hcGkvdjEvc2VydmljZXMnLCB7XG4gICAgICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShkYXRhLnNlcnZpY2VzKVxuICAgICAgfSkuY2F0Y2goZnVuY3Rpb24oKSB7fSk7XG4gICAgfVxuXG4gICAgLy8gUHVzaCB0aGVtZXMgdG8gc2VydmVyIGlmIGF2YWlsYWJsZVxuICAgIGlmIChkYXRhLnVzZXJUaGVtZXMpIHtcbiAgICAgIE9iamVjdC5rZXlzKGRhdGEudXNlclRoZW1lcykuZm9yRWFjaChmdW5jdGlvbihzbHVnKSB7XG4gICAgICAgIHZhciB0ID0gZGF0YS51c2VyVGhlbWVzW3NsdWddO1xuICAgICAgICB2YXIgY29sb3JzID0ge307XG4gICAgICAgICh3aW5kb3cuVEhFTUVfUFJPUFMgfHwgW10pLmZvckVhY2goZnVuY3Rpb24ocCkgeyBpZiAodFtwXSkgY29sb3JzW3BdID0gdFtwXTsgfSk7XG4gICAgICAgIHNlY3VyZUZldGNoKCcvYXBpL3YxL3RoZW1lcy8nICsgc2x1Zywge1xuICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgbmFtZTogdC5uYW1lIHx8IHNsdWcsIGNvbG9yczogY29sb3JzIH0pXG4gICAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uKCkge30pO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLy8gSW5qZWN0IG1vZGFsIEhUTUxcbiAgaW5qZWN0TW9kYWwoJ2JhY2t1cC1tb2RhbCcsIGA8ZGl2IGlkPVwiYmFja3VwLW1vZGFsXCIgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsXCI+XG4gICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtY29udGVudFwiIHN0eWxlPVwibWluLXdpZHRoOiA1NTBweDsgbWF4LXdpZHRoOiA2NTBweDtcIj5cbiAgICAgIDxoMz5cdUQ4M0RcdURDQkUgQmFja3VwICYgUmVzdG9yZTwvaDM+XG4gICAgICA8cCBjbGFzcz1cIm1vZGFsLXN1YnRpdGxlXCI+XG4gICAgICAgIEZ1bGwgYmFja3VwIG9mIHlvdXIgZW50aXJlIERhc2hDYWRkeSBzZXR1cCBcdTIwMTQgc2VydmVyIGNvbmZpZywgY3JlZGVudGlhbHMsIHRoZW1lcywgYW5kIGJyb3dzZXIgcHJlZmVyZW5jZXMgaW4gb25lIGZpbGUuXG4gICAgICA8L3A+XG5cbiAgICAgIDwhLS0gVGFiIGJhciAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC10YWJzXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWIgYWN0aXZlXCIgZGF0YS1wYW5lbD1cImJhY2t1cC1tYW51YWxcIj5NYW51YWw8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYlwiIGRhdGEtcGFuZWw9XCJiYWNrdXAtc2NoZWR1bGVzLXRhYlwiPlNjaGVkdWxlczwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwicGFuZWwtdGFiXCIgZGF0YS1wYW5lbD1cImJhY2t1cC1kaXNrLXRhYlwiPkJhY2t1cHMgb24gRGlzazwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwicGFuZWwtdGFiXCIgZGF0YS1wYW5lbD1cImJhY2t1cC1wb2ludGludGltZS10YWJcIj5Qb2ludC1pbi1UaW1lPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWJcIiBkYXRhLXBhbmVsPVwiYmFja3VwLWhpc3RvcnktdGFiXCI+SGlzdG9yeTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gVGFiOiBNYW51YWwgLS0+XG4gICAgICA8ZGl2IGlkPVwiYmFja3VwLW1hbnVhbFwiIGNsYXNzPVwicGFuZWwtc2VjdGlvbiBhY3RpdmVcIj5cbiAgICAgICAgPCEtLSBFeHBvcnQgU2VjdGlvbiAtLT5cbiAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDIwcHg7IHBhZGRpbmc6IDE2cHg7IGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsIGNvbG9yLW1peChpbiBzcmdiLCAjMjdhZTYwIDE1JSwgdHJhbnNwYXJlbnQpLCBjb2xvci1taXgoaW4gc3JnYiwgIzJlY2M3MSAxMCUsIHRyYW5zcGFyZW50KSk7IGJvcmRlci1yYWRpdXM6IDEwcHg7IGJvcmRlcjogMXB4IHNvbGlkICMyN2FlNjA7XCI+XG4gICAgICAgICAgPGg0IHN0eWxlPVwibWFyZ2luOiAwIDAgOHB4OyBjb2xvcjogIzJlY2M3MTsgZm9udC1zaXplOiAwLjk1cmVtO1wiPlx1RDgzRFx1RENFNCBFeHBvcnQgQmFja3VwPC9oND5cbiAgICAgICAgICA8cCBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW46IDAgMCAxMnB4O1wiPlxuICAgICAgICAgICAgRG93bmxvYWRzIGV2ZXJ5dGhpbmcgXHUyMDE0IHNlcnZpY2VzLCBDYWRkeWZpbGUsIGNyZWRlbnRpYWxzLCBlbmNyeXB0aW9uIGtleSwgdGhlbWVzLCBhbmQgYWxsIGJyb3dzZXIgcHJlZmVyZW5jZXMuXG4gICAgICAgICAgPC9wPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJiYWNrdXAtZXhwb3J0LWJ0blwiIHN0eWxlPVwid2lkdGg6IDEwMCU7IHBhZGRpbmc6IDEwcHg7IGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICMyN2FlNjAgMCUsICMyZWNjNzEgMTAwJSk7IGJvcmRlcjogbm9uZTsgY29sb3I6IHdoaXRlOyBmb250LXdlaWdodDogNjAwOyBib3JkZXItcmFkaXVzOiA4cHg7IGN1cnNvcjogcG9pbnRlcjtcIj5cbiAgICAgICAgICAgIFx1MkIwN1x1RkUwRiBEb3dubG9hZCBGdWxsIEJhY2t1cFxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIEltcG9ydCBTZWN0aW9uIC0tPlxuICAgICAgICA8ZGl2IHN0eWxlPVwicGFkZGluZzogMTZweDsgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgY29sb3ItbWl4KGluIHNyZ2IsICMzNDk4ZGIgMTUlLCB0cmFuc3BhcmVudCksIGNvbG9yLW1peChpbiBzcmdiLCAjMjk4MGI5IDEwJSwgdHJhbnNwYXJlbnQpKTsgYm9yZGVyLXJhZGl1czogMTBweDsgYm9yZGVyOiAxcHggc29saWQgIzM0OThkYjtcIj5cbiAgICAgICAgICA8aDQgc3R5bGU9XCJtYXJnaW46IDAgMCA4cHg7IGNvbG9yOiAjMzQ5OGRiOyBmb250LXNpemU6IDAuOTVyZW07XCI+XHVEODNEXHVEQ0U1IFJlc3RvcmUgQmFja3VwPC9oND5cbiAgICAgICAgICA8cCBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW46IDAgMCAxMnB4O1wiPlxuICAgICAgICAgICAgVXBsb2FkIGEgYmFja3VwIGZpbGUgdG8gcmVzdG9yZSB5b3VyIGVudGlyZSBjb25maWd1cmF0aW9uIFx1MjAxNCBkcmFnIGFuZCBkcm9wIHJlYWR5LlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cImZpbGVcIiBpZD1cImJhY2t1cC1maWxlLWlucHV0XCIgYWNjZXB0PVwiLmpzb25cIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCIgLz5cbiAgICAgICAgICA8YnV0dG9uIGlkPVwiYmFja3VwLXNlbGVjdC1maWxlXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTsgcGFkZGluZzogMTBweDsgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgIzM0OThkYiAwJSwgIzI5ODBiOSAxMDAlKTsgYm9yZGVyOiBub25lOyBjb2xvcjogd2hpdGU7IGZvbnQtd2VpZ2h0OiA2MDA7IGJvcmRlci1yYWRpdXM6IDhweDsgY3Vyc29yOiBwb2ludGVyO1wiPlxuICAgICAgICAgICAgXHVEODNEXHVEQ0MxIFNlbGVjdCBCYWNrdXAgRmlsZVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxkaXYgaWQ9XCJiYWNrdXAtZmlsZS1uYW1lXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lOyBtYXJnaW4tdG9wOiA4cHg7IHBhZGRpbmc6IDhweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogNnB4OyBmb250LXNpemU6IDAuODVyZW07XCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gUHJldmlldyBTZWN0aW9uIChzaG93biBhZnRlciBmaWxlIHNlbGVjdGVkKSAtLT5cbiAgICAgICAgPGRpdiBpZD1cImJhY2t1cC1wcmV2aWV3XCIgc3R5bGU9XCJkaXNwbGF5OiBub25lOyBtYXJnaW4tdG9wOiAxNnB4OyBwYWRkaW5nOiAxNnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiAxMHB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPlxuICAgICAgICAgIDxoNCBzdHlsZT1cIm1hcmdpbjogMCAwIDEycHg7IGZvbnQtc2l6ZTogMC45cmVtO1wiPlx1RDgzRFx1RENDQiBCYWNrdXAgQ29udGVudHM8L2g0PlxuICAgICAgICAgIDxkaXYgaWQ9XCJiYWNrdXAtcHJldmlldy1jb250ZW50XCIgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07XCI+PC9kaXY+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDEycHg7IHBhZGRpbmctdG9wOiAxMnB4OyBib3JkZXItdG9wOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNoZWNrYm94LWxhYmVsXCIgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07XCI+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImJhY2t1cC1yZWxvYWQtY2FkZHlcIiBjaGVja2VkIC8+XG4gICAgICAgICAgICAgIFJlbG9hZCBDYWRkeSBhZnRlciByZXN0b3JlXG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJiYWNrdXAtZG8tcmVzdG9yZS1idG5cIiBzdHlsZT1cIndpZHRoOiAxMDAlOyBtYXJnaW4tdG9wOiAxMnB4OyBwYWRkaW5nOiAxMHB4OyBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjZTc0YzNjIDAlLCAjYzAzOTJiIDEwMCUpOyBib3JkZXI6IG5vbmU7IGNvbG9yOiB3aGl0ZTsgZm9udC13ZWlnaHQ6IDYwMDsgYm9yZGVyLXJhZGl1czogOHB4OyBjdXJzb3I6IHBvaW50ZXI7XCI+XG4gICAgICAgICAgICBcdTI2QTEgUmVzdG9yZSBFdmVyeXRoaW5nXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gUmVzdWx0IE1lc3NhZ2UgLS0+XG4gICAgICAgIDxkaXYgaWQ9XCJiYWNrdXAtcmVzdWx0XCIgc3R5bGU9XCJkaXNwbGF5OiBub25lOyBtYXJnaW4tdG9wOiAxNnB4OyBwYWRkaW5nOiAxMnB4OyBib3JkZXItcmFkaXVzOiA4cHg7XCI+PC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IFNjaGVkdWxlcyAoUHJlbWl1bSkgLS0+XG4gICAgICA8ZGl2IGlkPVwiYmFja3VwLXNjaGVkdWxlcy10YWJcIiBjbGFzcz1cInBhbmVsLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBpZD1cImJhY2t1cC1zY2hlZHVsZXMtY29udGFpbmVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdTIzRjA8L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcgc2NoZWR1bGVzLi4uXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gVGFiOiBCYWNrdXBzIG9uIERpc2sgLS0+XG4gICAgICA8ZGl2IGlkPVwiYmFja3VwLWRpc2stdGFiXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJiYWNrdXAtZGlzay1jb250YWluZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1RENCRTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZyBiYWNrdXAgZmlsZXMuLi5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IFBvaW50LWluLVRpbWUgUmVzdG9yZSAtLT5cbiAgICAgIDxkaXYgaWQ9XCJiYWNrdXAtcG9pbnRpbnRpbWUtdGFiXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJwb2ludGludGltZS1jb250YWluZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1MjNFQTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZy4uLlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRhYjogQmFja3VwIEhpc3RvcnkgLS0+XG4gICAgICA8ZGl2IGlkPVwiYmFja3VwLWhpc3RvcnktdGFiXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJiYWNrdXAtaGlzdG9yeS1jb250YWluZXJcIiBzdHlsZT1cIm1heC1oZWlnaHQ6IDQwMHB4OyBvdmVyZmxvdy15OiBhdXRvO1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVEQ0NCPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPiBMb2FkaW5nIGJhY2t1cCBoaXN0b3J5Li4uXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQ2xvc2UgQnV0dG9uIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJiYWNrdXAtY2FuY2VsXCI+Q2xvc2U8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5gKTtcblxuICB2YXIgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmFja3VwLW1vZGFsJyk7XG4gIHZhciBvcGVuQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JhY2t1cC1yZXN0b3JlLWJ0bicpO1xuICB2YXIgY2FuY2VsQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JhY2t1cC1jYW5jZWwnKTtcbiAgdmFyIGV4cG9ydEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtZXhwb3J0LWJ0bicpO1xuICB2YXIgc2VsZWN0RmlsZUJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtc2VsZWN0LWZpbGUnKTtcbiAgdmFyIGZpbGVJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtZmlsZS1pbnB1dCcpO1xuICB2YXIgZmlsZU5hbWVEaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmFja3VwLWZpbGUtbmFtZScpO1xuICB2YXIgcHJldmlld0RpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtcHJldmlldycpO1xuICB2YXIgcHJldmlld0NvbnRlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmFja3VwLXByZXZpZXctY29udGVudCcpO1xuICB2YXIgcmVzdG9yZUJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtZG8tcmVzdG9yZS1idG4nKTtcbiAgdmFyIHJlc3VsdERpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtcmVzdWx0Jyk7XG4gIHZhciBzY2hlZHVsZUNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtc2NoZWR1bGVzLWNvbnRhaW5lcicpO1xuICB2YXIgaGlzdG9yeUNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtaGlzdG9yeS1jb250YWluZXInKTtcbiAgdmFyIGRpc2tDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmFja3VwLWRpc2stY29udGFpbmVyJyk7XG4gIHZhciBwb2ludGludGltZUNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwb2ludGludGltZS1jb250YWluZXInKTtcblxuICB2YXIgc2VsZWN0ZWRCYWNrdXAgPSBudWxsO1xuXG4gIC8vIE9wZW4gbW9kYWxcbiAgb3BlbkJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgaWYgKHJlc3VsdERpdikgcmVzdWx0RGl2LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgaWYgKHByZXZpZXdEaXYpIHByZXZpZXdEaXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBpZiAoZmlsZU5hbWVEaXYpIGZpbGVOYW1lRGl2LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgc2VsZWN0ZWRCYWNrdXAgPSBudWxsO1xuICB9KTtcblxuICB3aXJlTW9kYWwobW9kYWwsIGNhbmNlbEJ0bik7XG5cbiAgLy8gPT09IEVYUE9SVDogU2VydmVyIGJhY2t1cCArIGJyb3dzZXIgc3RhdGUgaW4gb25lIGZpbGUgPT09XG4gIGV4cG9ydEJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyBmdW5jdGlvbigpIHtcbiAgICBleHBvcnRCdG4uZGlzYWJsZWQgPSB0cnVlO1xuICAgIGV4cG9ydEJ0bi5pbm5lckhUTUwgPSAnPHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPiBFeHBvcnRpbmcuLi4nO1xuICAgIHRyeSB7XG4gICAgICAvLyBGZXRjaCBzZXJ2ZXItc2lkZSBiYWNrdXAgKGNvbmZpZywgc2VydmljZXMsIGNhZGR5ZmlsZSwgY3JlZGVudGlhbHMsIGVuY3J5cHRpb24ga2V5LCB0aGVtZXMsIGV0Yy4pXG4gICAgICB2YXIgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9iYWNrdXAvZXhwb3J0Jyk7XG4gICAgICB2YXIgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgLy8gQWRkIGFsbCBicm93c2VyIGxvY2FsU3RvcmFnZSBzdGF0ZVxuICAgICAgZGF0YS5icm93c2VyU3RhdGUgPSBjb2xsZWN0QnJvd3NlclN0YXRlKCk7XG5cbiAgICAgIC8vIERvd25sb2FkIHVuaWZpZWQgYmFja3VwXG4gICAgICB2YXIgYmxvYiA9IG5ldyBCbG9iKFtKU09OLnN0cmluZ2lmeShkYXRhLCBudWxsLCAyKV0sIHsgdHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nIH0pO1xuICAgICAgdmFyIHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICB2YXIgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgIGEuaHJlZiA9IHVybDtcbiAgICAgIGEuZG93bmxvYWQgPSAnZGFzaGNhZGR5LWJhY2t1cC0nICsgbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF0gKyAnLmpzb24nO1xuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChhKTtcbiAgICAgIGEuY2xpY2soKTtcbiAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoYSk7XG4gICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG5cbiAgICAgIHZhciBzdGF0ZUNvdW50ID0gT2JqZWN0LmtleXMoZGF0YS5icm93c2VyU3RhdGUpLmxlbmd0aDtcbiAgICAgIHZhciB0aGVtZUNvdW50ID0gZGF0YS50aGVtZXMgPyBPYmplY3Qua2V5cyhkYXRhLnRoZW1lcykubGVuZ3RoIDogMDtcbiAgICAgIHJlc3VsdERpdi5pbm5lckhUTUwgPSAnXHUyNzA1IEZ1bGwgYmFja3VwIGRvd25sb2FkZWQgXHUyMDE0IHNlcnZlciBjb25maWcgKyAnICsgc3RhdGVDb3VudCArICcgYnJvd3NlciBzZXR0aW5ncycgKyAodGhlbWVDb3VudCA/ICcgKyAnICsgdGhlbWVDb3VudCArICcgdGhlbWVzJyA6ICcnKTtcbiAgICAgIHJlc3VsdERpdi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgIHJlc3VsdERpdi5zdHlsZS5iYWNrZ3JvdW5kID0gJ2NvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1vay1mZykgMTUlLCB0cmFuc3BhcmVudCknO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmJvcmRlciA9ICcxcHggc29saWQgdmFyKC0tb2stZmcpJztcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXN1bHREaXYuaW5uZXJIVE1MID0gJ1x1Mjc0QyBFeHBvcnQgZmFpbGVkOiAnICsgZXNjYXBlSHRtbChlLm1lc3NhZ2UpO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmJhY2tncm91bmQgPSAnY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWJhZC1mZykgMTUlLCB0cmFuc3BhcmVudCknO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmJvcmRlciA9ICcxcHggc29saWQgdmFyKC0tYmFkLWZnKSc7XG4gICAgfVxuICAgIGV4cG9ydEJ0bi5kaXNhYmxlZCA9IGZhbHNlO1xuICAgIGV4cG9ydEJ0bi5pbm5lckhUTUwgPSAnXHUyQjA3XHVGRTBGIERvd25sb2FkIEZ1bGwgQmFja3VwJztcbiAgfSk7XG5cbiAgLy8gU2VsZWN0IGZpbGUgYnV0dG9uXG4gIHNlbGVjdEZpbGVCdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7IGZpbGVJbnB1dC5jbGljaygpOyB9KTtcblxuICAvLyA9PT0gRklMRSBTRUxFQ1RFRDogUHJldmlldyBjb250ZW50cyA9PT1cbiAgZmlsZUlucHV0Py5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBhc3luYyBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGZpbGUgPSBlLnRhcmdldC5maWxlc1swXTtcbiAgICBpZiAoIWZpbGUpIHJldHVybjtcbiAgICBmaWxlTmFtZURpdi50ZXh0Q29udGVudCA9ICdcdUQ4M0RcdURDQzQgJyArIGZpbGUubmFtZTtcbiAgICBmaWxlTmFtZURpdi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICByZXN1bHREaXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB0cnkge1xuICAgICAgdmFyIHRleHQgPSBhd2FpdCBmaWxlLnRleHQoKTtcbiAgICAgIHZhciBiYWNrdXAgPSBKU09OLnBhcnNlKHRleHQpO1xuXG4gICAgICAvLyBIYW5kbGUgbGVnYWN5IHYxLjAuMCBmb3JtYXQgKGZyb20gb2xkIGltcG9ydC1leHBvcnQuanMpXG4gICAgICBpZiAoaXNMZWdhY3lGb3JtYXQoYmFja3VwKSkge1xuICAgICAgICBzZWxlY3RlZEJhY2t1cCA9IGJhY2t1cDtcbiAgICAgICAgdmFyIGh0bWwgPSAnPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDhweDsgY29sb3I6IHZhcigtLW11dGVkKTsgZm9udC1zaXplOiAwLjhyZW07XCI+TGVnYWN5IGZvcm1hdCAodicgKyBlc2NhcGVIdG1sKGJhY2t1cC52ZXJzaW9uKSArICcpPC9kaXY+JztcbiAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGZsZXgtd3JhcDogd3JhcDsgZ2FwOiA2cHg7XCI+JztcbiAgICAgICAgaWYgKGJhY2t1cC5zZXJ2aWNlcz8ubGVuZ3RoKSBodG1sICs9ICc8c3BhbiBzdHlsZT1cInBhZGRpbmc6IDRweCA4cHg7IGJhY2tncm91bmQ6IHZhcigtLWJhc2UpOyBib3JkZXItcmFkaXVzOiA0cHg7IGZvbnQtc2l6ZTogMC44cmVtO1wiPlx1RDgzRFx1RENDQiAnICsgYmFja3VwLnNlcnZpY2VzLmxlbmd0aCArICcgc2VydmljZXM8L3NwYW4+JztcbiAgICAgICAgaWYgKGJhY2t1cC5jdXN0b21BcHBzPy5sZW5ndGgpIGh0bWwgKz0gJzxzcGFuIHN0eWxlPVwicGFkZGluZzogNHB4IDhweDsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IGJvcmRlci1yYWRpdXM6IDRweDsgZm9udC1zaXplOiAwLjhyZW07XCI+XHVEODNEXHVEQ0U2ICcgKyBiYWNrdXAuY3VzdG9tQXBwcy5sZW5ndGggKyAnIGN1c3RvbSBhcHBzPC9zcGFuPic7XG4gICAgICAgIGlmIChiYWNrdXAudGhlbWUpIGh0bWwgKz0gJzxzcGFuIHN0eWxlPVwicGFkZGluZzogNHB4IDhweDsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IGJvcmRlci1yYWRpdXM6IDRweDsgZm9udC1zaXplOiAwLjhyZW07XCI+XHVEODNDXHVERkE4IFRoZW1lOiAnICsgZXNjYXBlSHRtbChiYWNrdXAudGhlbWUpICsgJzwvc3Bhbj4nO1xuICAgICAgICBpZiAoYmFja3VwLnVzZXJUaGVtZXMpIGh0bWwgKz0gJzxzcGFuIHN0eWxlPVwicGFkZGluZzogNHB4IDhweDsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IGJvcmRlci1yYWRpdXM6IDRweDsgZm9udC1zaXplOiAwLjhyZW07XCI+XHVEODNDXHVERkE4ICcgKyBPYmplY3Qua2V5cyhiYWNrdXAudXNlclRoZW1lcykubGVuZ3RoICsgJyBjdXN0b20gdGhlbWVzPC9zcGFuPic7XG4gICAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgICAgIHByZXZpZXdDb250ZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgICAgIHByZXZpZXdEaXYuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gdjEuMSsgLyB2Mi4wIGZvcm1hdCBcdTIwMTQgc2VuZCB0byBzZXJ2ZXIgZm9yIHByZXZpZXdcbiAgICAgIHZhciByZXNwb25zZSA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2JhY2t1cC9wcmV2aWV3Jywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJhY2t1cClcbiAgICAgIH0pO1xuICAgICAgdmFyIHByZXZpZXcgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICBpZiAocHJldmlldy5zdWNjZXNzKSB7XG4gICAgICAgIHNlbGVjdGVkQmFja3VwID0gYmFja3VwO1xuICAgICAgICB2YXIgaHRtbCA9ICc8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogOHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBmb250LXNpemU6IDAuOHJlbTtcIj5FeHBvcnRlZDogJyArIG5ldyBEYXRlKGJhY2t1cC5leHBvcnRlZEF0KS50b0xvY2FsZVN0cmluZygpICsgJyAodicgKyBlc2NhcGVIdG1sKGJhY2t1cC52ZXJzaW9uKSArICcpPC9kaXY+JztcblxuICAgICAgICAvLyBTZXJ2ZXIgZmlsZXNcbiAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDZweDsgZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOyBsZXR0ZXItc3BhY2luZzogMC41cHg7XCI+U2VydmVyIENvbmZpZzwvZGl2Pic7XG4gICAgICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBmbGV4LXdyYXA6IHdyYXA7IGdhcDogNnB4OyBtYXJnaW4tYm90dG9tOiAxMHB4O1wiPic7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBwcmV2aWV3LnByZXZpZXcuZmlsZXMpIHtcbiAgICAgICAgICB2YXIgaW5mbyA9IHByZXZpZXcucHJldmlldy5maWxlc1trZXldO1xuICAgICAgICAgIHZhciBpY29uID0gaW5mby5hY3Rpb24gPT09ICdjcmVhdGUnID8gJ1x1RDgzQ1x1REQ5NScgOiAnXHVEODNEXHVEQ0REJztcbiAgICAgICAgICBodG1sICs9ICc8c3BhbiBzdHlsZT1cInBhZGRpbmc6IDRweCA4cHg7IGJhY2tncm91bmQ6IHZhcigtLWJhc2UpOyBib3JkZXItcmFkaXVzOiA0cHg7IGZvbnQtc2l6ZTogMC44cmVtO1wiPicgKyBpY29uICsgJyAnICsgZXNjYXBlSHRtbChpbmZvLmRlc2NyaXB0aW9uKSArICc8L3NwYW4+JztcbiAgICAgICAgfVxuICAgICAgICBodG1sICs9ICc8L2Rpdj4nO1xuXG4gICAgICAgIC8vIFNlcnZpY2VzIGNvdW50XG4gICAgICAgIGlmIChwcmV2aWV3LnByZXZpZXcuc2VydmljZUNvdW50KSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tYWNjZW50KTsgbWFyZ2luLWJvdHRvbTogNnB4O1wiPicgKyBwcmV2aWV3LnByZXZpZXcuc2VydmljZUNvdW50ICsgJyBzZXJ2aWNlczwvZGl2Pic7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUaGVtZXNcbiAgICAgICAgaWYgKHByZXZpZXcucHJldmlldy50aGVtZUNvdW50KSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tYWNjZW50KTsgbWFyZ2luLWJvdHRvbTogNnB4O1wiPlx1RDgzQ1x1REZBOCAnICsgcHJldmlldy5wcmV2aWV3LnRoZW1lQ291bnQgKyAnIGN1c3RvbSB0aGVtZXM8L2Rpdj4nO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQnJvd3NlciBzdGF0ZVxuICAgICAgICBpZiAocHJldmlldy5wcmV2aWV3LmJyb3dzZXJTdGF0ZUNvdW50KSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDZweDsgZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOyBsZXR0ZXItc3BhY2luZzogMC41cHg7XCI+QnJvd3NlciBQcmVmZXJlbmNlczwvZGl2Pic7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tYWNjZW50KTtcIj5cdUQ4M0RcdUREQTVcdUZFMEYgJyArIHByZXZpZXcucHJldmlldy5icm93c2VyU3RhdGVDb3VudCArICcgc2F2ZWQgc2V0dGluZ3MgKHRoZW1lLCB3ZWF0aGVyLCBjbG9jaywgd2lkZ2V0cywgZXRjLik8L2Rpdj4nO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJldmlld0NvbnRlbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgcHJldmlld0Rpdi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdERpdi5pbm5lckhUTUwgPSAnXHUyNkEwXHVGRTBGIEludmFsaWQgYmFja3VwIGZpbGU6ICcgKyBlc2NhcGVIdG1sKHByZXZpZXcuZXJyb3IpO1xuICAgICAgICByZXN1bHREaXYuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgIHJlc3VsdERpdi5zdHlsZS5iYWNrZ3JvdW5kID0gJ2NvbG9yLW1peChpbiBzcmdiLCAjZjM5YzEyIDE1JSwgdHJhbnNwYXJlbnQpJztcbiAgICAgICAgcmVzdWx0RGl2LnN0eWxlLmJvcmRlciA9ICcxcHggc29saWQgI2YzOWMxMic7XG4gICAgICAgIHByZXZpZXdEaXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXN1bHREaXYuaW5uZXJIVE1MID0gJ1x1Mjc0QyBDb3VsZCBub3QgcmVhZCBmaWxlOiAnICsgZXNjYXBlSHRtbChlLm1lc3NhZ2UpO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmJhY2tncm91bmQgPSAnY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWJhZC1mZykgMTUlLCB0cmFuc3BhcmVudCknO1xuICAgICAgcmVzdWx0RGl2LnN0eWxlLmJvcmRlciA9ICcxcHggc29saWQgdmFyKC0tYmFkLWZnKSc7XG4gICAgICBwcmV2aWV3RGl2LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgfVxuICB9KTtcblxuICAvLyA9PT0gUkVTVE9SRTogU2VydmVyICsgYnJvd3NlciBzdGF0ZSA9PT1cbiAgcmVzdG9yZUJ0bj8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXNlbGVjdGVkQmFja3VwKSByZXR1cm47XG4gICAgaWYgKCFjb25maXJtKCdUaGlzIHdpbGwgb3ZlcndyaXRlIHlvdXIgY3VycmVudCBjb25maWd1cmF0aW9uIGFuZCBicm93c2VyIHByZWZlcmVuY2VzLiBDb250aW51ZT8nKSkgcmV0dXJuO1xuICAgIHJlc3RvcmVCdG4uZGlzYWJsZWQgPSB0cnVlO1xuICAgIHJlc3RvcmVCdG4uaW5uZXJIVE1MID0gJzxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gUmVzdG9yaW5nLi4uJztcbiAgICB0cnkge1xuICAgICAgLy8gSGFuZGxlIGxlZ2FjeSBmb3JtYXRcbiAgICAgIGlmIChpc0xlZ2FjeUZvcm1hdChzZWxlY3RlZEJhY2t1cCkpIHtcbiAgICAgICAgcmVzdG9yZUxlZ2FjeUZvcm1hdChzZWxlY3RlZEJhY2t1cCk7XG4gICAgICAgIHJlc3VsdERpdi5pbm5lckhUTUwgPSAnXHUyNzA1IExlZ2FjeSBiYWNrdXAgcmVzdG9yZWQgXHUyMDE0IGJyb3dzZXIgc2V0dGluZ3MgYW5kIHNlcnZpY2VzIGltcG9ydGVkLic7XG4gICAgICAgIHJlc3VsdERpdi5zdHlsZS5iYWNrZ3JvdW5kID0gJ2NvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1vay1mZykgMTUlLCB0cmFuc3BhcmVudCknO1xuICAgICAgICByZXN1bHREaXYuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCB2YXIoLS1vay1mZyknO1xuICAgICAgICByZXN1bHREaXYuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGxvY2F0aW9uLnJlbG9hZCgpOyB9LCAyMDAwKTtcbiAgICAgICAgcmVzdG9yZUJ0bi5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgICByZXN0b3JlQnRuLmlubmVySFRNTCA9ICdcdTI2QTEgUmVzdG9yZSBFdmVyeXRoaW5nJztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyB2MS4xKyAvIHYyLjAgXHUyMDE0IHJlc3RvcmUgc2VydmVyLXNpZGUgZmlyc3RcbiAgICAgIHZhciByZWxvYWRDYWRkeSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrdXAtcmVsb2FkLWNhZGR5Jyk/LmNoZWNrZWQgPz8gdHJ1ZTtcbiAgICAgIHZhciByZXNwb25zZSA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2JhY2t1cC9yZXN0b3JlJywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgYmFja3VwOiBzZWxlY3RlZEJhY2t1cCwgb3B0aW9uczogeyByZWxvYWRDYWRkeTogcmVsb2FkQ2FkZHkgfSB9KVxuICAgICAgfSk7XG4gICAgICB2YXIgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgLy8gVGhlbiByZXN0b3JlIGJyb3dzZXIgc3RhdGVcbiAgICAgIHZhciBicm93c2VyQ291bnQgPSAwO1xuICAgICAgaWYgKHNlbGVjdGVkQmFja3VwLmJyb3dzZXJTdGF0ZSkge1xuICAgICAgICBicm93c2VyQ291bnQgPSByZXN0b3JlQnJvd3NlclN0YXRlKHNlbGVjdGVkQmFja3VwLmJyb3dzZXJTdGF0ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgdmFyIG1zZyA9ICdcdTI3MDUgJyArIGRhdGEubWVzc2FnZTtcbiAgICAgICAgaWYgKGJyb3dzZXJDb3VudCA+IDApIG1zZyArPSAnPGJyPjxzbWFsbCBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JyArIGJyb3dzZXJDb3VudCArICcgYnJvd3NlciBzZXR0aW5ncyByZXN0b3JlZDwvc21hbGw+JztcbiAgICAgICAgaWYgKGRhdGEucmVzdWx0cy5jYWRkeVJlbG9hZGVkKSBtc2cgKz0gJzxicj48c21hbGwgc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkNhZGR5IGNvbmZpZ3VyYXRpb24gcmVsb2FkZWQ8L3NtYWxsPic7XG4gICAgICAgIHJlc3VsdERpdi5pbm5lckhUTUwgPSBtc2c7XG4gICAgICAgIHJlc3VsdERpdi5zdHlsZS5iYWNrZ3JvdW5kID0gJ2NvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1vay1mZykgMTUlLCB0cmFuc3BhcmVudCknO1xuICAgICAgICByZXN1bHREaXYuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCB2YXIoLS1vay1mZyknO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBsb2NhdGlvbi5yZWxvYWQoKTsgfSwgMjAwMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHREaXYuaW5uZXJIVE1MID0gJ1x1MjZBMFx1RkUwRiAnICsgZXNjYXBlSHRtbChkYXRhLm1lc3NhZ2UpO1xuICAgICAgICBpZiAoYnJvd3NlckNvdW50ID4gMCkgcmVzdWx0RGl2LmlubmVySFRNTCArPSAnPGJyPjxzbWFsbCBzdHlsZT1cImNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+JyArIGJyb3dzZXJDb3VudCArICcgYnJvd3NlciBzZXR0aW5ncyB3ZXJlIHJlc3RvcmVkPC9zbWFsbD4nO1xuICAgICAgICBpZiAoZGF0YS5yZXN1bHRzPy5lcnJvcnM/Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICByZXN1bHREaXYuaW5uZXJIVE1MICs9ICc8YnI+PHNtYWxsPicgKyBkYXRhLnJlc3VsdHMuZXJyb3JzLm1hcChmdW5jdGlvbihlKSB7IHJldHVybiBlc2NhcGVIdG1sKGUuZmlsZSkgKyAnOiAnICsgZXNjYXBlSHRtbChlLmVycm9yKTsgfSkuam9pbignLCAnKSArICc8L3NtYWxsPic7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0RGl2LnN0eWxlLmJhY2tncm91bmQgPSAnY29sb3ItbWl4KGluIHNyZ2IsICNmMzljMTIgMTUlLCB0cmFuc3BhcmVudCknO1xuICAgICAgICByZXN1bHREaXYuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCAjZjM5YzEyJztcbiAgICAgIH1cbiAgICAgIHJlc3VsdERpdi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXN1bHREaXYuaW5uZXJIVE1MID0gJ1x1Mjc0QyBSZXN0b3JlIGZhaWxlZDogJyArIGVzY2FwZUh0bWwoZS5tZXNzYWdlKTtcbiAgICAgIHJlc3VsdERpdi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgIHJlc3VsdERpdi5zdHlsZS5iYWNrZ3JvdW5kID0gJ2NvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1iYWQtZmcpIDE1JSwgdHJhbnNwYXJlbnQpJztcbiAgICAgIHJlc3VsdERpdi5zdHlsZS5ib3JkZXIgPSAnMXB4IHNvbGlkIHZhcigtLWJhZC1mZyknO1xuICAgIH1cbiAgICByZXN0b3JlQnRuLmRpc2FibGVkID0gZmFsc2U7XG4gICAgcmVzdG9yZUJ0bi5pbm5lckhUTUwgPSAnXHUyNkExIFJlc3RvcmUgRXZlcnl0aGluZyc7XG4gIH0pO1xuXG4gIC8vID09PSBTY2hlZHVsZXMgVGFiIChQcmVtaXVtKSA9PT1cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZFNjaGVkdWxlc1RhYigpIHtcbiAgICBpZiAoIXNjaGVkdWxlQ29udGFpbmVyKSByZXR1cm47XG4gICAgc2NoZWR1bGVDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiYnJhbmQtc3Bpbm5lclwiPjwvc3Bhbj4gTG9hZGluZy4uLjwvZGl2Pic7XG4gICAgdHJ5IHtcbiAgICAgIHZhciByZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9iYWNrdXBzL3NjaGVkdWxlJyk7XG4gICAgICB2YXIgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBcbiAgICAgIGlmIChkYXRhLnByZW1pdW1SZXF1aXJlZCkge1xuICAgICAgICBzY2hlZHVsZUNvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCIgc3R5bGU9XCJwYWRkaW5nOiAyNHB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7XCI+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJmb250LXNpemU6IDJyZW07IG1hcmdpbi1ib3R0b206IDEycHg7XCI+XHUyQjUwPC9kaXY+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJmb250LXdlaWdodDogNjAwOyBtYXJnaW4tYm90dG9tOiA4cHg7XCI+UHJlbWl1bSBGZWF0dXJlPC9kaXY+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+QXV0by1iYWNrdXAgc2NoZWR1bGluZyByZXF1aXJlcyBhIERhc2hDYWRkeSBQcmVtaXVtIHN1YnNjcmlwdGlvbi48L2Rpdj4nICtcbiAgICAgICAgICAnPGJ1dHRvbiBvbmNsaWNrPVwic2hvd05vdGlmaWNhdGlvbihcXCdVcGdyYWRlIHRvIFByZW1pdW0gdG8gZW5hYmxlIGF1dG8tYmFja3VwcyFcXCcsIFxcJ2luZm9cXCcpOyBzY3JvbGxUb1NlY3Rpb24oXFwnbGljZW5zZVxcJyk7XCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxNnB4OyBwYWRkaW5nOiA4cHggMjBweDsgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgI2YzOWMxMiwgI2U2N2UyMik7IGJvcmRlcjogbm9uZTsgY29sb3I6IHdoaXRlOyBib3JkZXItcmFkaXVzOiA4cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDYwMDtcIj5VcGdyYWRlIHRvIFByZW1pdW08L2J1dHRvbj4nICtcbiAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgXG4gICAgICBpZiAoIWRhdGEuc3VjY2VzcykgdGhyb3cgbmV3IEVycm9yKGRhdGEuZXJyb3IgfHwgJ0ZhaWxlZCB0byBsb2FkIHNjaGVkdWxlcycpO1xuICAgICAgXG4gICAgICB2YXIgc2NoZWR1bGVzID0gZGF0YS5zY2hlZHVsZXMgfHwgW107XG4gICAgICBcbiAgICAgIGlmIChzY2hlZHVsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHNjaGVkdWxlQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj4nICtcbiAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHUyM0YwPC9zcGFuPicgK1xuICAgICAgICAgICc8ZGl2Pk5vIGJhY2t1cCBzY2hlZHVsZXMgY29uZmlndXJlZDwvZGl2PicgK1xuICAgICAgICAgICc8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi10b3A6IDRweDtcIj5TZWxlY3QgYXBwcyBiZWxvdyB0byBlbmFibGUgYXV0by1iYWNrdXA8L2Rpdj4nICtcbiAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgXG4gICAgICB2YXIgaHRtbCA9ICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgZ2FwOiA4cHg7XCI+JztcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2NoZWR1bGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBzY2ggPSBzY2hlZHVsZXNbaV07XG4gICAgICAgIHZhciBuZXh0UnVuU3RyID0gc2NoLm5leHRSdW4gPyBuZXcgRGF0ZShzY2gubmV4dFJ1bikudG9Mb2NhbGVTdHJpbmcoKSA6ICdOb3Qgc2NoZWR1bGVkJztcbiAgICAgICAgdmFyIGxhc3RSdW5TdHIgPSBzY2gubGFzdFJ1biA/IG5ldyBEYXRlKHNjaC5sYXN0UnVuKS50b0xvY2FsZVN0cmluZygpIDogJ05ldmVyJztcbiAgICAgICAgXG4gICAgICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxMnB4IDE0cHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgYWxpZ24taXRlbXM6IGNlbnRlcjsgbWFyZ2luLWJvdHRvbTogOHB4O1wiPicgK1xuICAgICAgICAgICcgIDxkaXYgc3R5bGU9XCJmb250LXdlaWdodDogNjAwOyBmb250LXNpemU6IDAuOXJlbTtcIj4nICsgZXNjYXBlSHRtbChzY2guYXBwSWQpICsgJzwvZGl2PicgK1xuICAgICAgICAgICcgIDxsYWJlbCBjbGFzcz1cInRvZ2dsZS1zd2l0Y2hcIiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogNnB4O1wiPicgK1xuICAgICAgICAgICcgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwic2NoZWR1bGUtdG9nZ2xlXCIgZGF0YS1hcHBpZD1cIicgKyBlc2NhcGVIdG1sKHNjaC5hcHBJZCkgKyAnXCInICsgKHNjaC5lbmFibGVkID8gJyBjaGVja2VkJyA6ICcnKSArICcgLz4nICtcbiAgICAgICAgICAnICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPicgKyAoc2NoLmVuYWJsZWQgPyAnT04nIDogJ09GRicpICsgJzwvc3Bhbj4nICtcbiAgICAgICAgICAnICA8L2xhYmVsPicgK1xuICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdyaWQtdGVtcGxhdGUtY29sdW1uczogMWZyIDFmcjsgZ2FwOiA4cHg7IGZvbnQtc2l6ZTogMC44cmVtOyBtYXJnaW4tYm90dG9tOiAxMHB4O1wiPicgK1xuICAgICAgICAgICcgIDxkaXY+PHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlNjaGVkdWxlOjwvc3Bhbj4gPHNlbGVjdCBjbGFzcz1cInNjaGVkdWxlLXNlbGVjdFwiIGRhdGEtYXBwaWQ9XCInICsgZXNjYXBlSHRtbChzY2guYXBwSWQpICsgJ1wiIHN0eWxlPVwiYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IDRweDsgcGFkZGluZzogMnB4IDZweDtcIj4nICtcbiAgICAgICAgICAnICAgIDxvcHRpb24gdmFsdWU9XCJob3VybHlcIicgKyAoc2NoLnNjaGVkdWxlID09PSAnaG91cmx5JyA/ICcgc2VsZWN0ZWQnIDogJycpICsgJz5Ib3VybHk8L29wdGlvbj4nICtcbiAgICAgICAgICAnICAgIDxvcHRpb24gdmFsdWU9XCJkYWlseVwiJyArIChzY2guc2NoZWR1bGUgPT09ICdkYWlseScgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+RGFpbHk8L29wdGlvbj4nICtcbiAgICAgICAgICAnICAgIDxvcHRpb24gdmFsdWU9XCJ3ZWVrbHlcIicgKyAoc2NoLnNjaGVkdWxlID09PSAnd2Vla2x5JyA/ICcgc2VsZWN0ZWQnIDogJycpICsgJz5XZWVrbHk8L29wdGlvbj4nICtcbiAgICAgICAgICAnICAgIDxvcHRpb24gdmFsdWU9XCJtb250aGx5XCInICsgKHNjaC5zY2hlZHVsZSA9PT0gJ21vbnRobHknID8gJyBzZWxlY3RlZCcgOiAnJykgKyAnPk1vbnRobHk8L29wdGlvbj4nICtcbiAgICAgICAgICAnICA8L3NlbGVjdD48L2Rpdj4nICtcbiAgICAgICAgICAnICA8ZGl2PjxzcGFuIHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTtcIj5LZWVwIGxhc3Q6PC9zcGFuPiA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGNsYXNzPVwicmV0ZW50aW9uLWlucHV0XCIgZGF0YS1hcHBpZD1cIicgKyBlc2NhcGVIdG1sKHNjaC5hcHBJZCkgKyAnXCIgdmFsdWU9XCInICsgKHNjaC5yZXRlbnRpb24/LmtlZXAgfHwgNykgKyAnXCIgbWluPVwiMVwiIG1heD1cIjEwMFwiIHN0eWxlPVwid2lkdGg6IDUwcHg7IGJhY2tncm91bmQ6IHZhcigtLWJhc2UpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA0cHg7IHBhZGRpbmc6IDJweCA2cHg7XCIgLz48L2Rpdj4nICtcbiAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDEwcHg7XCI+JyArXG4gICAgICAgICAgJyAgPGRpdj5OZXh0IHJ1bjogJyArIGVzY2FwZUh0bWwobmV4dFJ1blN0cikgKyAnPC9kaXY+JyArXG4gICAgICAgICAgJyAgPGRpdj5MYXN0IHJ1bjogJyArIGVzY2FwZUh0bWwobGFzdFJ1blN0cikgKyAnPC9kaXY+JyArXG4gICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiA2cHg7XCI+JyArXG4gICAgICAgICAgJyAgPGJ1dHRvbiBjbGFzcz1cInNjaGVkdWxlLXJ1bi1ub3dcIiBkYXRhLWFwcGlkPVwiJyArIGVzY2FwZUh0bWwoc2NoLmFwcElkKSArICdcIiBzdHlsZT1cInBhZGRpbmc6IDVweCAxMnB4OyBmb250LXNpemU6IDAuOHJlbTsgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLW9rLWZnKSAyMCUsIHRyYW5zcGFyZW50KTsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tb2stZmcpOyBjb2xvcjogdmFyKC0tb2stZmcpOyBib3JkZXItcmFkaXVzOiA2cHg7IGN1cnNvcjogcG9pbnRlcjtcIj5cdTI1QjZcdUZFMEYgUnVuIE5vdzwvYnV0dG9uPicgK1xuICAgICAgICAgICcgIDxidXR0b24gY2xhc3M9XCJzY2hlZHVsZS1kZWxldGVcIiBkYXRhLWFwcGlkPVwiJyArIGVzY2FwZUh0bWwoc2NoLmFwcElkKSArICdcIiBzdHlsZT1cInBhZGRpbmc6IDVweCAxMnB4OyBmb250LXNpemU6IDAuOHJlbTsgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJhZC1mZyk7IGNvbG9yOiB2YXIoLS1iYWQtZmcpOyBib3JkZXItcmFkaXVzOiA2cHg7IGN1cnNvcjogcG9pbnRlcjtcIj5cdUQ4M0RcdURERDFcdUZFMEYgUmVtb3ZlPC9idXR0b24+JyArXG4gICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgfVxuICAgICAgaHRtbCArPSAnPC9kaXY+JztcbiAgICAgIFxuICAgICAgLy8gQWRkIFwiQWRkIFNjaGVkdWxlXCIgc2VjdGlvbiBhdCBib3R0b21cbiAgICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJtYXJnaW4tdG9wOiAxNnB4OyBwYWRkaW5nOiAxNnB4OyBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tYWNjZW50KSA1JSwgdHJhbnNwYXJlbnQpOyBib3JkZXItcmFkaXVzOiAxMHB4OyBib3JkZXI6IDFweCBkYXNoZWQgdmFyKC0tYm9yZGVyKTtcIj4nICtcbiAgICAgICAgJzxoNCBzdHlsZT1cIm1hcmdpbjogMCAwIDEycHg7IGZvbnQtc2l6ZTogMC44NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5cdTI3OTUgQWRkIE5ldyBTY2hlZHVsZTwvaDQ+JyArXG4gICAgICAgICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7IGZsZXgtd3JhcDogd3JhcDtcIj4nICtcbiAgICAgICAgJyAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJuZXctc2NoZWR1bGUtYXBwaWRcIiBwbGFjZWhvbGRlcj1cIkFwcCBJRCAoZS5nLiwgcGxleCwgc29uYXJyKVwiIHN0eWxlPVwiZmxleDogMTsgbWluLXdpZHRoOiAxNTBweDsgcGFkZGluZzogOHB4OyBib3JkZXItcmFkaXVzOiA2cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJhY2tncm91bmQ6IHZhcigtLWJhc2UpO1wiIC8+JyArXG4gICAgICAgICcgIDxzZWxlY3QgaWQ9XCJuZXctc2NoZWR1bGUtaW50ZXJ2YWxcIiBzdHlsZT1cInBhZGRpbmc6IDhweDsgYm9yZGVyLXJhZGl1czogNnB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBiYWNrZ3JvdW5kOiB2YXIoLS1iYXNlKTtcIj4nICtcbiAgICAgICAgJyAgICA8b3B0aW9uIHZhbHVlPVwiaG91cmx5XCI+SG91cmx5PC9vcHRpb24+JyArXG4gICAgICAgICcgICAgPG9wdGlvbiB2YWx1ZT1cImRhaWx5XCIgc2VsZWN0ZWQ+RGFpbHk8L29wdGlvbj4nICtcbiAgICAgICAgJyAgICA8b3B0aW9uIHZhbHVlPVwid2Vla2x5XCI+V2Vla2x5PC9vcHRpb24+JyArXG4gICAgICAgICcgICAgPG9wdGlvbiB2YWx1ZT1cIm1vbnRobHlcIj5Nb250aGx5PC9vcHRpb24+JyArXG4gICAgICAgICcgICAgPG9wdGlvbiB2YWx1ZT1cIjZoXCI+RXZlcnkgNiBob3Vyczwvb3B0aW9uPicgK1xuICAgICAgICAnICAgIDxvcHRpb24gdmFsdWU9XCIzMG1cIj5FdmVyeSAzMCBtaW51dGVzPC9vcHRpb24+JyArXG4gICAgICAgICcgIDwvc2VsZWN0PicgK1xuICAgICAgICAnICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGlkPVwibmV3LXNjaGVkdWxlLXJldGVudGlvblwiIHZhbHVlPVwiN1wiIG1pbj1cIjFcIiBtYXg9XCIxMDBcIiBwbGFjZWhvbGRlcj1cIktlZXBcIiBzdHlsZT1cIndpZHRoOiA3MHB4OyBwYWRkaW5nOiA4cHg7IGJvcmRlci1yYWRpdXM6IDZweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7XCIgLz4nICtcbiAgICAgICAgJyAgPGJ1dHRvbiBpZD1cImFkZC1zY2hlZHVsZS1idG5cIiBzdHlsZT1cInBhZGRpbmc6IDhweCAxNnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1hY2NlbnQpOyBib3JkZXI6IG5vbmU7IGNvbG9yOiB3aGl0ZTsgYm9yZGVyLXJhZGl1czogNnB4OyBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtd2VpZ2h0OiA1MDA7XCI+QWRkIFNjaGVkdWxlPC9idXR0b24+JyArXG4gICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgJzwvZGl2Pic7XG4gICAgICBcbiAgICAgIHNjaGVkdWxlQ29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7XG4gICAgICBcbiAgICAgIC8vIFdpcmUgdXAgZXZlbnQgbGlzdGVuZXJzXG4gICAgICBzY2hlZHVsZUNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuc2NoZWR1bGUtdG9nZ2xlJykuZm9yRWFjaChmdW5jdGlvbih0b2dnbGUpIHtcbiAgICAgICAgdG9nZ2xlLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGZ1bmN0aW9uKCkgeyB1cGRhdGVTY2hlZHVsZSh0b2dnbGUuZGF0YXNldC5hcHBpZCwgeyBlbmFibGVkOiB0b2dnbGUuY2hlY2tlZCB9KTsgfSk7XG4gICAgICB9KTtcbiAgICAgIHNjaGVkdWxlQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zY2hlZHVsZS1zZWxlY3QnKS5mb3JFYWNoKGZ1bmN0aW9uKHNlbCkge1xuICAgICAgICBzZWwuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24oKSB7IHVwZGF0ZVNjaGVkdWxlKHNlbC5kYXRhc2V0LmFwcGlkLCB7IHNjaGVkdWxlOiBzZWwudmFsdWUgfSk7IH0pO1xuICAgICAgfSk7XG4gICAgICBzY2hlZHVsZUNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcucmV0ZW50aW9uLWlucHV0JykuZm9yRWFjaChmdW5jdGlvbihpbnApIHtcbiAgICAgICAgaW5wLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGZ1bmN0aW9uKCkgeyB1cGRhdGVTY2hlZHVsZShpbnAuZGF0YXNldC5hcHBpZCwgeyByZXRlbnRpb246IHsga2VlcDogcGFyc2VJbnQoaW5wLnZhbHVlKSB8fCA3IH0gfSk7IH0pO1xuICAgICAgfSk7XG4gICAgICBzY2hlZHVsZUNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuc2NoZWR1bGUtcnVuLW5vdycpLmZvckVhY2goZnVuY3Rpb24oYnRuKSB7XG4gICAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkgeyBydW5CYWNrdXBOb3coYnRuLmRhdGFzZXQuYXBwaWQpOyB9KTtcbiAgICAgIH0pO1xuICAgICAgc2NoZWR1bGVDb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgnLnNjaGVkdWxlLWRlbGV0ZScpLmZvckVhY2goZnVuY3Rpb24oYnRuKSB7XG4gICAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkgeyBkZWxldGVTY2hlZHVsZShidG4uZGF0YXNldC5hcHBpZCk7IH0pO1xuICAgICAgfSk7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYWRkLXNjaGVkdWxlLWJ0bicpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFkZE5ld1NjaGVkdWxlKTtcbiAgICAgIFxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHNjaGVkdWxlQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkZhaWxlZCB0byBsb2FkOiAnICsgZXNjYXBlSHRtbChlLm1lc3NhZ2UpICsgJzwvZGl2Pic7XG4gICAgfVxuICB9XG4gIFxuICBhc3luYyBmdW5jdGlvbiB1cGRhdGVTY2hlZHVsZShhcHBJZCwgdXBkYXRlcykge1xuICAgIHRyeSB7XG4gICAgICB2YXIgcmVzID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvYmFja3Vwcy9zY2hlZHVsZScsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IGFwcElkLCAuLi51cGRhdGVzIH0pXG4gICAgICB9KTtcbiAgICAgIHZhciBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignU2NoZWR1bGUgdXBkYXRlZCBmb3IgJyArIGFwcElkLCAnc3VjY2VzcycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignVXBkYXRlIGZhaWxlZDogJyArIChkYXRhLmVycm9yIHx8ICdVbmtub3duJyksICdlcnJvcicpO1xuICAgICAgICBsb2FkU2NoZWR1bGVzVGFiKCk7IC8vIFJlZnJlc2ggb24gZmFpbHVyZVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ0Vycm9yOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICB9XG4gIH1cbiAgXG4gIGFzeW5jIGZ1bmN0aW9uIHJ1bkJhY2t1cE5vdyhhcHBJZCkge1xuICAgIHRyeSB7XG4gICAgICB2YXIgcmVzID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvYmFja3Vwcy9iYWNrdXAvJyArIGVuY29kZVVSSUNvbXBvbmVudChhcHBJZCksIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9XG4gICAgICB9KTtcbiAgICAgIHZhciBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignQmFja3VwIHN0YXJ0ZWQgZm9yICcgKyBhcHBJZCArICchJywgJ3N1Y2Nlc3MnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ0JhY2t1cCBmYWlsZWQ6ICcgKyAoZGF0YS5lcnJvciB8fCAnVW5rbm93bicpLCAnZXJyb3InKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKCdFcnJvcjogJyArIGUubWVzc2FnZSwgJ2Vycm9yJyk7XG4gICAgfVxuICB9XG4gIFxuICBhc3luYyBmdW5jdGlvbiBkZWxldGVTY2hlZHVsZShhcHBJZCkge1xuICAgIGlmICghY29uZmlybSgnUmVtb3ZlIGJhY2t1cCBzY2hlZHVsZSBmb3IgJyArIGFwcElkICsgJz8nKSkgcmV0dXJuO1xuICAgIHRyeSB7XG4gICAgICB2YXIgcmVzID0gYXdhaXQgc2VjdXJlRmV0Y2goJy9hcGkvdjEvYmFja3Vwcy9zY2hlZHVsZS8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGFwcElkKSwgeyBtZXRob2Q6ICdERUxFVEUnIH0pO1xuICAgICAgdmFyIGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdTY2hlZHVsZSByZW1vdmVkIGZvciAnICsgYXBwSWQsICdzdWNjZXNzJyk7XG4gICAgICAgIGxvYWRTY2hlZHVsZXNUYWIoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ0RlbGV0ZSBmYWlsZWQ6ICcgKyAoZGF0YS5lcnJvciB8fCAnVW5rbm93bicpLCAnZXJyb3InKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKCdFcnJvcjogJyArIGUubWVzc2FnZSwgJ2Vycm9yJyk7XG4gICAgfVxuICB9XG4gIFxuICBhc3luYyBmdW5jdGlvbiBhZGROZXdTY2hlZHVsZSgpIHtcbiAgICB2YXIgYXBwSWQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbmV3LXNjaGVkdWxlLWFwcGlkJyk/LnZhbHVlPy50cmltKCk7XG4gICAgdmFyIGludGVydmFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25ldy1zY2hlZHVsZS1pbnRlcnZhbCcpPy52YWx1ZSB8fCAnZGFpbHknO1xuICAgIHZhciByZXRlbnRpb24gPSBwYXJzZUludChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbmV3LXNjaGVkdWxlLXJldGVudGlvbicpPy52YWx1ZSkgfHwgNztcbiAgICBcbiAgICBpZiAoIWFwcElkKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKCdQbGVhc2UgZW50ZXIgYW4gQXBwIElEJywgJ3dhcm5pbmcnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgXG4gICAgdHJ5IHtcbiAgICAgIHZhciByZXMgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9iYWNrdXBzL3NjaGVkdWxlJywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgYXBwSWQsIHNjaGVkdWxlOiBpbnRlcnZhbCwgcmV0ZW50aW9uOiB7IGtlZXA6IHJldGVudGlvbiB9LCBlbmFibGVkOiB0cnVlIH0pXG4gICAgICB9KTtcbiAgICAgIHZhciBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbignU2NoZWR1bGUgY3JlYXRlZCBmb3IgJyArIGFwcElkLCAnc3VjY2VzcycpO1xuICAgICAgICBsb2FkU2NoZWR1bGVzVGFiKCk7XG4gICAgICAgIC8vIENsZWFyIGlucHV0c1xuICAgICAgICB2YXIgYXBwSWRJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduZXctc2NoZWR1bGUtYXBwaWQnKTtcbiAgICAgICAgaWYgKGFwcElkSW5wdXQpIGFwcElkSW5wdXQudmFsdWUgPSAnJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ0ZhaWxlZDogJyArIChkYXRhLmVycm9yIHx8ICdVbmtub3duJyksICdlcnJvcicpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ0Vycm9yOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICB9XG4gIH1cbiAgXG4gIC8vID09PSBCYWNrdXBzIG9uIERpc2sgVGFiID09PVxuICBhc3luYyBmdW5jdGlvbiBsb2FkRGlza0JhY2t1cHMoKSB7XG4gICAgaWYgKCFkaXNrQ29udGFpbmVyKSByZXR1cm47XG4gICAgZGlza0NvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPiBMb2FkaW5nLi4uPC9kaXY+JztcbiAgICB0cnkge1xuICAgICAgdmFyIHJlcyA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2JhY2t1cHMvZmlsZXMnKTtcbiAgICAgIHZhciBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB0aHJvdyBuZXcgRXJyb3IoZGF0YS5lcnJvciB8fCAnRmFpbGVkIHRvIGxvYWQnKTtcblxuICAgICAgdmFyIGZpbGVzID0gZGF0YS5maWxlcyB8fCBbXTtcblxuICAgICAgaWYgKGZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBkaXNrQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj4nICtcbiAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVEQ0JFPC9zcGFuPicgK1xuICAgICAgICAgICc8ZGl2Pk5vIGJhY2t1cCBmaWxlcyBvbiBkaXNrPC9kaXY+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuOHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogNHB4O1wiPlJ1biBhIGJhY2t1cCB0byBjcmVhdGUgYmFja3VwIGZpbGVzPC9kaXY+JyArXG4gICAgICAgICAgJzwvZGl2Pic7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gR3JvdXAgYnkgYXBwSWRcbiAgICAgIHZhciBieUFwcCA9IHt9O1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgZiA9IGZpbGVzW2ldO1xuICAgICAgICB2YXIgYXBwSWQgPSBmLmFwcElkIHx8ICd1bmtub3duJztcbiAgICAgICAgaWYgKCFieUFwcFthcHBJZF0pIGJ5QXBwW2FwcElkXSA9IFtdO1xuICAgICAgICBieUFwcFthcHBJZF0ucHVzaChmKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGh0bWwgPSAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWJvdHRvbTogMTJweDtcIj4nICsgZmlsZXMubGVuZ3RoICsgJyBiYWNrdXAgZmlsZShzKSBhY3Jvc3MgJyArIE9iamVjdC5rZXlzKGJ5QXBwKS5sZW5ndGggKyAnIGFwcChzKTwvZGl2Pic7XG4gICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgZ2FwOiAxMnB4O1wiPic7XG5cbiAgICAgIHZhciBhcHBJZHMgPSBPYmplY3Qua2V5cyhieUFwcCkuc29ydCgpO1xuICAgICAgZm9yICh2YXIgYSA9IDA7IGEgPCBhcHBJZHMubGVuZ3RoOyBhKyspIHtcbiAgICAgICAgdmFyIGFwcElkID0gYXBwSWRzW2FdO1xuICAgICAgICB2YXIgYXBwRmlsZXMgPSBieUFwcFthcHBJZF07XG4gICAgICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IG92ZXJmbG93OiBoaWRkZW47XCI+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJwYWRkaW5nOiA4cHggMTJweDsgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWFjY2VudCkgOCUsIHRyYW5zcGFyZW50KTsgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGZvbnQtd2VpZ2h0OiA2MDA7IGZvbnQtc2l6ZTogMC44NXJlbTtcIj4nICtcbiAgICAgICAgICBlc2NhcGVIdG1sKGFwcElkKSArICcgPHNwYW4gc3R5bGU9XCJmb250LXdlaWdodDogbm9ybWFsOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBmb250LXNpemU6IDAuNzVyZW07XCI+KCcgKyBhcHBGaWxlcy5sZW5ndGggKyAnIGJhY2t1cChzKSk8L3NwYW4+JyArXG4gICAgICAgICAgJzwvZGl2Pic7XG5cbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBhcHBGaWxlcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgIHZhciBmID0gYXBwRmlsZXNbal07XG4gICAgICAgICAgdmFyIGRhdGVTdHIgPSBuZXcgRGF0ZShmLnRpbWVzdGFtcCkudG9Mb2NhbGVTdHJpbmcoKTtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwicGFkZGluZzogMTBweCAxMnB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj4nICtcbiAgICAgICAgICAgICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOyBhbGlnbi1pdGVtczogY2VudGVyOyBtYXJnaW4tYm90dG9tOiA0cHg7XCI+JyArXG4gICAgICAgICAgICAnICA8ZGl2IHN0eWxlPVwiZm9udC13ZWlnaHQ6IDUwMDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPicgKyBlc2NhcGVIdG1sKGYubmFtZSkgKyAnPC9kaXY+JyArXG4gICAgICAgICAgICAnICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPicgKyBmLnNpemVGb3JtYXR0ZWQgKyAnPC9kaXY+JyArXG4gICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWJvdHRvbTogOHB4O1wiPicgKyBkYXRlU3RyICsgJzwvZGl2PicgK1xuICAgICAgICAgICAgJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDZweDtcIj4nICtcbiAgICAgICAgICAgICcgIDxidXR0b24gY2xhc3M9XCJkaXNrLWNvbXBhcmUtYnRuXCIgZGF0YS1hcHBpZD1cIicgKyBlc2NhcGVIdG1sKGFwcElkKSArICdcIiBkYXRhLWZpbGVuYW1lPVwiJyArIGVzY2FwZUh0bWwoZi5uYW1lKSArICdcIiBzdHlsZT1cInBhZGRpbmc6IDNweCA4cHg7IGZvbnQtc2l6ZTogMC43NXJlbTsgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWFjY2VudCk7IGNvbG9yOiB2YXIoLS1hY2NlbnQpOyBib3JkZXItcmFkaXVzOiA1cHg7IGN1cnNvcjogcG9pbnRlcjtcIj5Db21wYXJlPC9idXR0b24+JyArXG4gICAgICAgICAgICAnICA8YnV0dG9uIGNsYXNzPVwiZGlzay1yZXN0b3JlLWJ0blwiIGRhdGEtYXBwaWQ9XCInICsgZXNjYXBlSHRtbChhcHBJZCkgKyAnXCIgZGF0YS1maWxlbmFtZT1cIicgKyBlc2NhcGVIdG1sKGYubmFtZSkgKyAnXCIgc3R5bGU9XCJwYWRkaW5nOiAzcHggOHB4OyBmb250LXNpemU6IDAuNzVyZW07IGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsIHZhcigtLW9rLWZnKSwgIzI3YWU2MCk7IGJvcmRlcjogbm9uZTsgY29sb3I6IHdoaXRlOyBib3JkZXItcmFkaXVzOiA1cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDUwMDtcIj5SZXN0b3JlPC9idXR0b24+JyArXG4gICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgfVxuICAgICAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgICAgfVxuICAgICAgaHRtbCArPSAnPC9kaXY+JztcblxuICAgICAgZGlza0NvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgICAvLyBXaXJlIHVwIGJ1dHRvbnNcbiAgICAgIGRpc2tDb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgnLmRpc2stY29tcGFyZS1idG4nKS5mb3JFYWNoKGZ1bmN0aW9uKGJ0bikge1xuICAgICAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpIHsgY29tcGFyZUJhY2t1cEZpbGUoYnRuLmRhdGFzZXQuYXBwaWQsIGJ0bi5kYXRhc2V0LmZpbGVuYW1lKTsgfSk7XG4gICAgICB9KTtcbiAgICAgIGRpc2tDb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgnLmRpc2stcmVzdG9yZS1idG4nKS5mb3JFYWNoKGZ1bmN0aW9uKGJ0bikge1xuICAgICAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpIHsgcmVzdG9yZUJhY2t1cEZpbGUoYnRuLmRhdGFzZXQuYXBwaWQsIGJ0bi5kYXRhc2V0LmZpbGVuYW1lKTsgfSk7XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBkaXNrQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkZhaWxlZDogJyArIGVzY2FwZUh0bWwoZS5tZXNzYWdlKSArICc8L2Rpdj4nO1xuICAgIH1cbiAgfVxuICBcbiAgLy8gPT09IEJhY2t1cCBIaXN0b3J5IFRhYiA9PT1cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZEJhY2t1cEhpc3RvcnkoKSB7XG4gICAgaWYgKCFoaXN0b3J5Q29udGFpbmVyKSByZXR1cm47XG4gICAgaGlzdG9yeUNvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPiBMb2FkaW5nLi4uPC9kaXY+JztcbiAgICB0cnkge1xuICAgICAgdmFyIHJlcyA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2JhY2t1cHMvaGlzdG9yeT9saW1pdD01MCcpO1xuICAgICAgdmFyIGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MgfHwgIWRhdGEuaGlzdG9yeT8ubGVuZ3RoKSB7XG4gICAgICAgIGhpc3RvcnlDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1RENDQjwvc3Bhbj4gTm8gYmFja3VwIGhpc3RvcnkgeWV0PC9kaXY+JztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdmFyIGh0bWwgPSAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGdhcDogNnB4O1wiPic7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEuaGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgYmsgPSBkYXRhLmhpc3RvcnlbaV07XG4gICAgICAgIHZhciBzaXplTUIgPSBiay5zaXplID8gKGJrLnNpemUgLyAxMDI0IC8gMTAyNCkudG9GaXhlZCgyKSA6ICc/JztcbiAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cInBhZGRpbmc6IDEwcHggMTJweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogNnB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBmb250LXNpemU6IDAuODVyZW07XCI+JztcbiAgICAgICAgaHRtbCArPSAnICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOyBhbGlnbi1pdGVtczogY2VudGVyOyBtYXJnaW4tYm90dG9tOiA0cHg7XCI+JztcbiAgICAgICAgaHRtbCArPSAnICAgIDxzcGFuIHN0eWxlPVwiZm9udC13ZWlnaHQ6IDUwMDtcIj4nICsgZXNjYXBlSHRtbChiay5uYW1lIHx8ICdiYWNrdXAnKSArICc8L3NwYW4+JztcbiAgICAgICAgaHRtbCArPSAnICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDtcIj4nO1xuICAgICAgICBodG1sICs9ICcgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1iYWRnZSAnICsgKGJrLnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnID8gJ3N1Y2Nlc3MnIDogJ2Rvd24nKSArICdcIj4nICsgZXNjYXBlSHRtbChiay5zdGF0dXMpICsgJzwvc3Bhbj4nO1xuICAgICAgICBpZiAoYmsuc3RhdHVzID09PSAnc3VjY2VzcycpIGh0bWwgKz0gJyAgICAgIDxidXR0b24gY2xhc3M9XCJiYWNrdXAtcmVzdG9yZS1idG5cIiBkYXRhLWJhY2t1cC1pZD1cIicgKyBlc2NhcGVIdG1sKGJrLmlkKSArICdcIiBzdHlsZT1cInBhZGRpbmc6IDNweCA4cHg7IGZvbnQtc2l6ZTogMC43NXJlbTtcIj5SZXN0b3JlPC9idXR0b24+JztcbiAgICAgICAgaHRtbCArPSAnICAgIDwvZGl2Pic7XG4gICAgICAgIGh0bWwgKz0gJyAgPC9kaXY+JztcbiAgICAgICAgaHRtbCArPSAnICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPic7XG4gICAgICAgIGh0bWwgKz0gJyAgICAnICsgbmV3IERhdGUoYmsudGltZXN0YW1wKS50b0xvY2FsZVN0cmluZygpICsgJyB8ICcgKyBzaXplTUIgKyAnIE1CIHwgJyArIChiay5kdXJhdGlvbiA/IChiay5kdXJhdGlvbiAvIDEwMDApLnRvRml4ZWQoMSkgKyAncycgOiAnLS0nKTtcbiAgICAgICAgaWYgKGJrLmVuY3J5cHRlZCkgaHRtbCArPSAnIHwgXHVEODNEXHVERDEyJztcbiAgICAgICAgaHRtbCArPSAnICA8L2Rpdj4nO1xuICAgICAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgICAgfVxuICAgICAgaHRtbCArPSAnPC9kaXY+JztcbiAgICAgIGhpc3RvcnlDb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgIGhpc3RvcnlDb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgnLmJhY2t1cC1yZXN0b3JlLWJ0bicpLmZvckVhY2goZnVuY3Rpb24oYnRuKSB7XG4gICAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkgeyB3aW5kb3cuX19yZXN0b3JlU2VydmVyQmFja3VwKGJ0bi5kYXRhc2V0LmJhY2t1cElkKTsgfSk7XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBoaXN0b3J5Q29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIiBzdHlsZT1cImNvbG9yOiB2YXIoLS1iYWQtZmcpO1wiPkZhaWxlZDogJyArIGVzY2FwZUh0bWwoZS5tZXNzYWdlKSArICc8L2Rpdj4nO1xuICAgIH1cbiAgfVxuXG4gIHdpbmRvdy5fX3Jlc3RvcmVTZXJ2ZXJCYWNrdXAgPSBhc3luYyBmdW5jdGlvbihiYWNrdXBJZCkge1xuICAgIGlmICghY29uZmlybSgnUmVzdG9yZSBmcm9tIHRoaXMgc2VydmVyIGJhY2t1cD8gVGhpcyB3aWxsIG92ZXJ3cml0ZSBjdXJyZW50IGNvbmZpZ3VyYXRpb24uJykpIHJldHVybjtcbiAgICB0cnkge1xuICAgICAgdmFyIHJlcyA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2JhY2t1cHMvcmVzdG9yZS8nICsgYmFja3VwSWQsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHJlc3RvcmVTZXJ2aWNlczogdHJ1ZSwgcmVzdG9yZUNvbmZpZzogdHJ1ZSB9KVxuICAgICAgfSk7XG4gICAgICB2YXIgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1Jlc3RvcmUgY29tcGxldGVkIHN1Y2Nlc3NmdWxseSEnLCAnc3VjY2VzcycpO1xuICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNob3dOb3RpZmljYXRpb24oJ1Jlc3RvcmUgZmFpbGVkOiAnICsgKGRhdGEuZXJyb3IgfHwgJ1Vua25vd24gZXJyb3InKSwgJ2Vycm9yJyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkgeyBzaG93Tm90aWZpY2F0aW9uKCdSZXN0b3JlIGVycm9yOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTsgfVxuICB9O1xuXG4gIC8vIExhenktbG9hZCB0YWJzXG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXBhbmVsPVwiYmFja3VwLXNjaGVkdWxlcy10YWJcIl0nKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBsb2FkU2NoZWR1bGVzVGFiKTtcbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtcGFuZWw9XCJiYWNrdXAtZGlzay10YWJcIl0nKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBsb2FkRGlza0JhY2t1cHMpO1xuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1wYW5lbD1cImJhY2t1cC1wb2ludGludGltZS10YWJcIl0nKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBsb2FkUG9pbnRJblRpbWVUYWIpO1xuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1wYW5lbD1cImJhY2t1cC1oaXN0b3J5LXRhYlwiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGxvYWRCYWNrdXBIaXN0b3J5KTtcblxuICAvLyA9PT09PSBQb2ludC1pbi1UaW1lIFJlc3RvcmUgVGFiID09PT09XG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWRQb2ludEluVGltZVRhYigpIHtcbiAgICBpZiAoIXBvaW50aW50aW1lQ29udGFpbmVyKSByZXR1cm47XG5cbiAgICAvLyBDaGVjayBwcmVtaXVtXG4gICAgdHJ5IHtcbiAgICAgIHZhciBsaWNlbnNlUmVzID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvbGljZW5zZS9zdGF0dXMnKTtcbiAgICAgIHZhciBsaWNlbnNlRGF0YSA9IGF3YWl0IGxpY2Vuc2VSZXMuanNvbigpO1xuICAgICAgaWYgKGxpY2Vuc2VEYXRhLnRpZXIgIT09ICdwcmVtaXVtJykge1xuICAgICAgICBwb2ludGludGltZUNvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCIgc3R5bGU9XCJwYWRkaW5nOiAyNHB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7XCI+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJmb250LXNpemU6IDJyZW07IG1hcmdpbi1ib3R0b206IDEycHg7XCI+XHUyQjUwPC9kaXY+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJmb250LXdlaWdodDogNjAwOyBtYXJnaW4tYm90dG9tOiA4cHg7XCI+UHJlbWl1bSBGZWF0dXJlPC9kaXY+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+UG9pbnQtaW4tdGltZSByZXN0b3JlIHJlcXVpcmVzIERhc2hDYWRkeSBQcmVtaXVtIHdpdGggYXV0by1iYWNrdXAgZW5hYmxlZC48L2Rpdj4nICtcbiAgICAgICAgICAnPGJ1dHRvbiBvbmNsaWNrPVwic2hvd05vdGlmaWNhdGlvbihcXCdVcGdyYWRlIHRvIFByZW1pdW0gZm9yIHBvaW50LWluLXRpbWUgcmVzdG9yZSFcXCcsIFxcJ2luZm9cXCcpOyBzY3JvbGxUb1NlY3Rpb24oXFwnbGljZW5zZVxcJyk7XCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxNnB4OyBwYWRkaW5nOiA4cHggMjBweDsgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgI2YzOWMxMiwgI2U2N2UyMik7IGJvcmRlcjogbm9uZTsgY29sb3I6IHdoaXRlOyBib3JkZXItcmFkaXVzOiA4cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDYwMDtcIj5VcGdyYWRlIHRvIFByZW1pdW08L2J1dHRvbj4nICtcbiAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHsgLyogaWdub3JlICovIH1cblxuICAgIHBvaW50aW50aW1lQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcuLi48L2Rpdj4nO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIEZldGNoIHNlcnZpY2VzIGZvciBkcm9wZG93blxuICAgICAgdmFyIHNlcnZpY2VzUmVzID0gYXdhaXQgZmV0Y2goJy9hcGkvdjEvc2VydmljZXMnKTtcbiAgICAgIHZhciBzZXJ2aWNlc0RhdGEgPSBhd2FpdCBzZXJ2aWNlc1Jlcy5qc29uKCk7XG4gICAgICB2YXIgc2VydmljZXMgPSBzZXJ2aWNlc0RhdGEuc2VydmljZXMgfHwgW107XG5cbiAgICAgIGlmIChzZXJ2aWNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcG9pbnRpbnRpbWVDb250YWluZXIuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1RENFNjwvc3Bhbj4gTm8gYXBwcyBkZXBsb3llZCB5ZXQ8L2Rpdj4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBodG1sID0gJzxkaXYgc3R5bGU9XCJwYWRkaW5nOiA4cHggMCAxMnB4O1wiPicgK1xuICAgICAgICAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyBhbGlnbi1pdGVtczogY2VudGVyOyBtYXJnaW4tYm90dG9tOiAxMnB4O1wiPicgK1xuICAgICAgICAnICA8bGFiZWwgc3R5bGU9XCJmb250LXNpemU6IDAuODVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IHdoaXRlLXNwYWNlOiBub3dyYXA7XCI+QXBwOjwvbGFiZWw+JyArXG4gICAgICAgICcgIDxzZWxlY3QgaWQ9XCJwaXQtYXBwLXNlbGVjdFwiIHN0eWxlPVwiZmxleDogMTsgcGFkZGluZzogOHB4OyBib3JkZXItcmFkaXVzOiA2cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJhY2tncm91bmQ6IHZhcigtLWJhc2UpOyBtYXgtd2lkdGg6IDI0MHB4O1wiPic7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlcnZpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGh0bWwgKz0gJzxvcHRpb24gdmFsdWU9XCInICsgZXNjYXBlSHRtbChzZXJ2aWNlc1tpXS5pZCB8fCBzZXJ2aWNlc1tpXS5uYW1lIHx8ICcnKSArICdcIj4nICtcbiAgICAgICAgICBlc2NhcGVIdG1sKHNlcnZpY2VzW2ldLm5hbWUgfHwgc2VydmljZXNbaV0uaWQgfHwgJycpICsgJzwvb3B0aW9uPic7XG4gICAgICB9XG4gICAgICBodG1sICs9ICc8L3NlbGVjdD4nICtcbiAgICAgICAgJyAgPGJ1dHRvbiBpZD1cInBpdC1sb2FkLWJ0blwiIHN0eWxlPVwicGFkZGluZzogOHB4IDE2cHg7IGJhY2tncm91bmQ6IHZhcigtLWFjY2VudCk7IGJvcmRlcjogbm9uZTsgY29sb3I6IHdoaXRlOyBib3JkZXItcmFkaXVzOiA2cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDUwMDtcIj5Mb2FkIEJhY2t1cHM8L2J1dHRvbj4nICtcbiAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAnPGRpdiBpZD1cInBpdC1iYWNrdXBzLWxpc3RcIiBzdHlsZT1cIm1heC1oZWlnaHQ6IDMyMHB4OyBvdmVyZmxvdy15OiBhdXRvO1wiPjwvZGl2PicgK1xuICAgICAgICAnPC9kaXY+JztcblxuICAgICAgcG9pbnRpbnRpbWVDb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDtcblxuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BpdC1sb2FkLWJ0bicpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYXBwSWQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGl0LWFwcC1zZWxlY3QnKT8udmFsdWU7XG4gICAgICAgIGlmIChhcHBJZCkgbG9hZFBvaW50SW5UaW1lQmFja3VwcyhhcHBJZCk7XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBwb2ludGludGltZUNvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5GYWlsZWQ6ICcgKyBlc2NhcGVIdG1sKGUubWVzc2FnZSkgKyAnPC9kaXY+JztcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBsb2FkUG9pbnRJblRpbWVCYWNrdXBzKGFwcElkKSB7XG4gICAgdmFyIGxpc3RFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwaXQtYmFja3Vwcy1saXN0Jyk7XG4gICAgaWYgKCFsaXN0RWwpIHJldHVybjtcblxuICAgIGxpc3RFbC5pbm5lckhUTUwgPSAnPGRpdiBzdHlsZT1cInBhZGRpbmc6IDIwcHg7IHRleHQtYWxpZ246IGNlbnRlcjtcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcgYmFja3Vwcy4uLjwvZGl2Pic7XG5cbiAgICB0cnkge1xuICAgICAgdmFyIHJlcyA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2JhY2t1cHMvZmlsZXMvJyArIGVuY29kZVVSSUNvbXBvbmVudChhcHBJZCkpO1xuICAgICAgdmFyIGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuXG4gICAgICBpZiAoIWRhdGEuc3VjY2VzcyB8fCAhZGF0YS5maWxlcyB8fCBkYXRhLmZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBsaXN0RWwuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1RENCRTwvc3Bhbj4gTm8gYmFja3VwIGZpbGVzIGZvciAnICsgZXNjYXBlSHRtbChhcHBJZCkgKyAnPC9kaXY+JztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgaHRtbCA9ICc8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tYm90dG9tOiA4cHg7XCI+JyArIGRhdGEuZmlsZXMubGVuZ3RoICsgJyBiYWNrdXAocyk8L2Rpdj4nICtcbiAgICAgICAgJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDZweDtcIj4nO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEuZmlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGYgPSBkYXRhLmZpbGVzW2ldO1xuICAgICAgICB2YXIgZGF0ZVN0ciA9IG5ldyBEYXRlKGYudGltZXN0YW1wKS50b0xvY2FsZVN0cmluZygpO1xuICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwicGFkZGluZzogMTBweCAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IGFsaWduLWl0ZW1zOiBjZW50ZXI7IG1hcmdpbi1ib3R0b206IDRweDtcIj4nICtcbiAgICAgICAgICAnICA8ZGl2IHN0eWxlPVwiZm9udC13ZWlnaHQ6IDUwMDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPicgKyBlc2NhcGVIdG1sKGYubmFtZSkgKyAnPC9kaXY+JyArXG4gICAgICAgICAgJyAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj4nICsgZi5zaXplRm9ybWF0dGVkICsgJzwvZGl2PicgK1xuICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLWJvdHRvbTogOHB4O1wiPicgKyBkYXRlU3RyICsgJzwvZGl2PicgK1xuICAgICAgICAgICc8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiA2cHg7XCI+JyArXG4gICAgICAgICAgJyAgPGJ1dHRvbiBjbGFzcz1cInBpdC1jb21wYXJlLWJ0blwiIGRhdGEtYXBwaWQ9XCInICsgZXNjYXBlSHRtbChhcHBJZCkgKyAnXCIgZGF0YS1maWxlbmFtZT1cIicgKyBlc2NhcGVIdG1sKGYubmFtZSkgKyAnXCIgc3R5bGU9XCJwYWRkaW5nOiA0cHggMTBweDsgZm9udC1zaXplOiAwLjc1cmVtOyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYWNjZW50KTsgY29sb3I6IHZhcigtLWFjY2VudCk7IGJvcmRlci1yYWRpdXM6IDVweDsgY3Vyc29yOiBwb2ludGVyO1wiPkNvbXBhcmU8L2J1dHRvbj4nICtcbiAgICAgICAgICAnICA8YnV0dG9uIGNsYXNzPVwicGl0LXJlc3RvcmUtYnRuXCIgZGF0YS1hcHBpZD1cIicgKyBlc2NhcGVIdG1sKGFwcElkKSArICdcIiBkYXRhLWZpbGVuYW1lPVwiJyArIGVzY2FwZUh0bWwoZi5uYW1lKSArICdcIiBzdHlsZT1cInBhZGRpbmc6IDRweCAxMHB4OyBmb250LXNpemU6IDAuNzVyZW07IGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsIHZhcigtLW9rLWZnKSwgIzI3YWU2MCk7IGJvcmRlcjogbm9uZTsgY29sb3I6IHdoaXRlOyBib3JkZXItcmFkaXVzOiA1cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDUwMDtcIj5SZXN0b3JlPC9idXR0b24+JyArXG4gICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgfVxuICAgICAgaHRtbCArPSAnPC9kaXY+JztcbiAgICAgIGxpc3RFbC5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgICAvLyBXaXJlIHVwIGJ1dHRvbnNcbiAgICAgIGxpc3RFbC5xdWVyeVNlbGVjdG9yQWxsKCcucGl0LWNvbXBhcmUtYnRuJykuZm9yRWFjaChmdW5jdGlvbihidG4pIHtcbiAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7IGNvbXBhcmVCYWNrdXBGaWxlKGJ0bi5kYXRhc2V0LmFwcGlkLCBidG4uZGF0YXNldC5maWxlbmFtZSk7IH0pO1xuICAgICAgfSk7XG4gICAgICBsaXN0RWwucXVlcnlTZWxlY3RvckFsbCgnLnBpdC1yZXN0b3JlLWJ0bicpLmZvckVhY2goZnVuY3Rpb24oYnRuKSB7XG4gICAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkgeyByZXN0b3JlQmFja3VwRmlsZShidG4uZGF0YXNldC5hcHBpZCwgYnRuLmRhdGFzZXQuZmlsZW5hbWUpOyB9KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxpc3RFbC5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCIgc3R5bGU9XCJjb2xvcjogdmFyKC0tYmFkLWZnKTtcIj5GYWlsZWQ6ICcgKyBlc2NhcGVIdG1sKGUubWVzc2FnZSkgKyAnPC9kaXY+JztcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBjb21wYXJlQmFja3VwRmlsZShhcHBJZCwgZmlsZW5hbWUpIHtcbiAgICB0cnkge1xuICAgICAgdmFyIHJlcyA9IGF3YWl0IHNlY3VyZUZldGNoKCcvYXBpL3YxL2JhY2t1cHMvY29tcGFyZS8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKSwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHt9KVxuICAgICAgfSk7XG4gICAgICB2YXIgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdDb21wYXJlIGZhaWxlZDogJyArIChkYXRhLmVycm9yIHx8ICdVbmtub3duJyksICdlcnJvcicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBkaWZmID0gZGF0YS5kaWZmO1xuICAgICAgdmFyIGh0bWwgPSAnPGRpdiBzdHlsZT1cInBvc2l0aW9uOiBmaXhlZDsgdG9wOiAwOyBsZWZ0OiAwOyByaWdodDogMDsgYm90dG9tOiAwOyBiYWNrZ3JvdW5kOiByZ2JhKDAsMCwwLDAuNSk7IHotaW5kZXg6IDEwMDAwOyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcIiBpZD1cImNvbXBhcmUtb3ZlcmxheVwiPicgK1xuICAgICAgICAnPGRpdiBzdHlsZT1cImJhY2tncm91bmQ6IHZhcigtLWJhc2UpOyBib3JkZXItcmFkaXVzOiAxMnB4OyBtYXgtd2lkdGg6IDYwMHB4OyB3aWR0aDogOTAlOyBtYXgtaGVpZ2h0OiA4MHZoOyBvdmVyZmxvdzogYXV0bzsgcGFkZGluZzogMjBweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj4nICtcbiAgICAgICAgJzxoNCBzdHlsZT1cIm1hcmdpbjogMCAwIDE2cHg7XCI+XHVEODNEXHVEQ0NBIENvbXBhcmU6ICcgKyBlc2NhcGVIdG1sKGZpbGVuYW1lKSArICc8L2g0PicgK1xuICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tYm90dG9tOiAxNnB4O1wiPlNpemU6ICcgKyAoZGlmZi5zaXplRm9ybWF0dGVkIHx8ICc/JykgKyAnIHwgQ3JlYXRlZDogJyArIG5ldyBEYXRlKGRpZmYudGltZXN0YW1wKS50b0xvY2FsZVN0cmluZygpICsgJzwvZGl2Pic7XG5cbiAgICAgIGlmIChkaWZmLnNlcnZpY2VzKSB7XG4gICAgICAgIHZhciBzdmNDaGFuZ2VkID0gZGlmZi5zZXJ2aWNlcy5oYXNDaGFuZ2VzID8gJ1x1RDgzRFx1REQzNCcgOiAnXHVEODNEXHVERkUyJztcbiAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDEycHg7IHBhZGRpbmc6IDEwcHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDZweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj4nICtcbiAgICAgICAgICAnPGRpdiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IGZvbnQtc2l6ZTogMC44NXJlbTsgbWFyZ2luLWJvdHRvbTogNHB4O1wiPicgKyBzdmNDaGFuZ2VkICsgJyBTZXJ2aWNlcyAoYmFja3VwIHZzIGN1cnJlbnQpPC9kaXY+JyArXG4gICAgICAgICAgJzxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuOHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5CYWNrdXA6ICcgKyBkaWZmLnNlcnZpY2VzLmJhY2t1cENvdW50ICsgJyBzZXJ2aWNlcyB8IEN1cnJlbnQ6ICcgKyBkaWZmLnNlcnZpY2VzLmN1cnJlbnRDb3VudCArICcgc2VydmljZXM8L2Rpdj4nO1xuICAgICAgICBpZiAoZGlmZi5zZXJ2aWNlcy5oYXNDaGFuZ2VzKSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDZweDsgZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiAjZjM5YzEyO1wiPlNlcnZpY2VzIGRpZmZlciBcdTIwMTQgcmVzdG9yaW5nIHdpbGwgcmVwbGFjZSBjdXJyZW50IGNvbmZpZ3VyYXRpb248L2Rpdj4nO1xuICAgICAgICB9XG4gICAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgICB9XG5cbiAgICAgIGlmIChkaWZmLmNvbmZpZykge1xuICAgICAgICB2YXIgY2ZnQ2hhbmdlZCA9IGRpZmYuY29uZmlnLmhhc0NoYW5nZXMgPyAnXHVEODNEXHVERDM0JyA6ICdcdUQ4M0RcdURGRTInO1xuICAgICAgICBodG1sICs9ICc8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTJweDsgcGFkZGluZzogMTBweDsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTsgYm9yZGVyLXJhZGl1czogNnB4OyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPicgK1xuICAgICAgICAgICc8ZGl2IHN0eWxlPVwiZm9udC13ZWlnaHQ6IDYwMDsgZm9udC1zaXplOiAwLjg1cmVtOyBtYXJnaW4tYm90dG9tOiA0cHg7XCI+JyArIGNmZ0NoYW5nZWQgKyAnIENvbmZpZ3VyYXRpb248L2Rpdj4nO1xuICAgICAgICBpZiAoZGlmZi5jb25maWcuaGFzQ2hhbmdlcykge1xuICAgICAgICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuOHJlbTsgY29sb3I6ICNmMzljMTI7XCI+Q29uZmlndXJhdGlvbiBkaWZmZXJzIFx1MjAxNCByZXN0b3Jpbmcgd2lsbCByZXBsYWNlIGN1cnJlbnQgc2V0dGluZ3M8L2Rpdj4nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGh0bWwgKz0gJzxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuOHJlbTsgY29sb3I6IHZhcigtLW9rLWZnKTtcIj5ObyBjaGFuZ2VzPC9kaXY+JztcbiAgICAgICAgfVxuICAgICAgICBodG1sICs9ICc8L2Rpdj4nO1xuICAgICAgfVxuXG4gICAgICBodG1sICs9ICc8YnV0dG9uIGlkPVwiY29tcGFyZS1jbG9zZS1idG5cIiBzdHlsZT1cInBhZGRpbmc6IDhweCAyMHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1hY2NlbnQpOyBib3JkZXI6IG5vbmU7IGNvbG9yOiB3aGl0ZTsgYm9yZGVyLXJhZGl1czogNnB4OyBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtd2VpZ2h0OiA1MDA7XCI+Q2xvc2U8L2J1dHRvbj4nICtcbiAgICAgICAgJzwvZGl2PjwvZGl2Pic7XG5cbiAgICAgIGRvY3VtZW50LmJvZHkuaW5zZXJ0QWRqYWNlbnRIVE1MKCdiZWZvcmVlbmQnLCBodG1sKTtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb21wYXJlLWNsb3NlLWJ0bicpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcGFyZS1vdmVybGF5Jyk/LnJlbW92ZSgpO1xuICAgICAgfSk7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcGFyZS1vdmVybGF5Jyk/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZSkge1xuICAgICAgICBpZiAoZS50YXJnZXQgPT09IHRoaXMpIHRoaXMucmVtb3ZlKCk7XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzaG93Tm90aWZpY2F0aW9uKCdDb21wYXJlIGVycm9yOiAnICsgZS5tZXNzYWdlLCAnZXJyb3InKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiByZXN0b3JlQmFja3VwRmlsZShhcHBJZCwgZmlsZW5hbWUpIHtcbiAgICBpZiAoIWNvbmZpcm0oJ1Jlc3RvcmUgJyArIGZpbGVuYW1lICsgJyBmb3IgJyArIGFwcElkICsgJz9cXG5cXG5UaGlzIHdpbGwgcmVwbGFjZSBjdXJyZW50IGNvbmZpZ3VyYXRpb24sIGNyZWRlbnRpYWxzLCBhbmQgZGF0YS4gQ29udGFpbmVycyB3aWxsIGJlIHJlc3RhcnRlZC4nKSkgcmV0dXJuO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciByZXMgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9hcHBzLycgKyBlbmNvZGVVUklDb21wb25lbnQoYXBwSWQpICsgJy9yZXZlcnQvJyArIGVuY29kZVVSSUNvbXBvbmVudChmaWxlbmFtZSksIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHJlc3RhcnRDb250YWluZXJzOiB0cnVlIH0pXG4gICAgICB9KTtcbiAgICAgIHZhciBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGlmIChkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgc2hvd05vdGlmaWNhdGlvbihhcHBJZCArICcgcmVzdG9yZWQgdG8gJyArIGZpbGVuYW1lLCAnc3VjY2VzcycpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBsb2NhdGlvbi5yZWxvYWQoKTsgfSwgMTUwMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzaG93Tm90aWZpY2F0aW9uKCdSZXN0b3JlIGZhaWxlZDogJyArIChkYXRhLmVycm9yIHx8ICdVbmtub3duJyksICdlcnJvcicpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHNob3dOb3RpZmljYXRpb24oJ1Jlc3RvcmUgZXJyb3I6ICcgKyBlLm1lc3NhZ2UsICdlcnJvcicpO1xuICAgIH1cbiAgfVxufSkoKTtcbjtcbi8vID09PT09PT09PT0gUkVTT1VSQ0UgTU9OSVRPUiAoRW5oYW5jZWQpID09PT09PT09PT1cbihmdW5jdGlvbigpIHtcbiAgLy8gSW5qZWN0IG1vZGFsIEhUTUxcbiAgaW5qZWN0TW9kYWwoJ3N0YXRzLW1vZGFsJywgYDxkaXYgaWQ9XCJzdGF0cy1tb2RhbFwiIGNsYXNzPVwid2VhdGhlci1tb2RhbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWNvbnRlbnRcIiBzdHlsZT1cIm1pbi13aWR0aDogNzUwcHg7IG1heC13aWR0aDogOTUwcHg7XCI+XG4gICAgICA8aDM+XHVEODNEXHVEQ0NBIFJlc291cmNlIE1vbml0b3I8L2gzPlxuICAgICAgPHAgY2xhc3M9XCJtb2RhbC1zdWJ0aXRsZVwiPlxuICAgICAgICBSZWFsLXRpbWUgYW5kIGhpc3RvcmljYWwgQ1BVLCBtZW1vcnksIG5ldHdvcmssIGFuZCBkaXNrIHVzYWdlIGZvciBjb250YWluZXJzLlxuICAgICAgPC9wPlxuXG4gICAgICA8IS0tIFRhYiBiYXIgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtdGFic1wiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwicGFuZWwtdGFiIGFjdGl2ZVwiIGRhdGEtcGFuZWw9XCJzdGF0cy1saXZlXCI+TGl2ZSBTdGF0czwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwicGFuZWwtdGFiXCIgZGF0YS1wYW5lbD1cInN0YXRzLWFnZ3JlZ2F0ZWRcIj4yNGggU3VtbWFyeTwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwicGFuZWwtdGFiXCIgZGF0YS1wYW5lbD1cInN0YXRzLWhpc3RvcnlcIj5IaXN0b3J5PC9idXR0b24+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWJcIiBkYXRhLXBhbmVsPVwic3RhdHMtYWxlcnRzXCI+QWxlcnRzPC9idXR0b24+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IExpdmUgU3RhdHMgLS0+XG4gICAgICA8ZGl2IGlkPVwic3RhdHMtbGl2ZVwiIGNsYXNzPVwicGFuZWwtc2VjdGlvbiBhY3RpdmVcIj5cbiAgICAgICAgPGRpdiBpZD1cInN0YXRzLWNvbnRhaW5lclwiIGNsYXNzPVwic2Nyb2xsLWNvbnRhaW5lclwiPlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDQwcHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcgY29udGFpbmVyIHN0YXRzLi4uXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gVGFiOiAyNGggQWdncmVnYXRlZCBTdW1tYXJ5IC0tPlxuICAgICAgPGRpdiBpZD1cInN0YXRzLWFnZ3JlZ2F0ZWRcIiBjbGFzcz1cInBhbmVsLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBpZD1cInN0YXRzLWFnZ3JlZ2F0ZWQtY29udGFpbmVyXCIgY2xhc3M9XCJzY3JvbGwtY29udGFpbmVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0RcdURDQzg8L3NwYW4+XG4gICAgICAgICAgICBMb2FkaW5nIDI0LWhvdXIgYWdncmVnYXRlZCBtZXRyaWNzLi4uXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gVGFiOiBMb25nLXRlcm0gSGlzdG9yeSAtLT5cbiAgICAgIDxkaXYgaWQ9XCJzdGF0cy1oaXN0b3J5XCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDhweDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgbWFyZ2luLWJvdHRvbTogMTJweDsgZmxleC13cmFwOiB3cmFwO1wiPlxuICAgICAgICAgIDxsYWJlbCBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5Db250YWluZXI6PC9sYWJlbD5cbiAgICAgICAgICA8c2VsZWN0IGlkPVwic3RhdHMtaGlzdG9yeS1jb250YWluZXJcIiBzdHlsZT1cInBhZGRpbmc6IDRweCA4cHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGNvbG9yOiB2YXIoLS1mZyk7IGJvcmRlci1yYWRpdXM6IDRweDsgZm9udC1zaXplOiAwLjg1cmVtOyBmbGV4OiAxOyBtaW4td2lkdGg6IDE4MHB4O1wiPjwvc2VsZWN0PlxuICAgICAgICAgIDxkaXYgaWQ9XCJzdGF0cy1oaXN0b3J5LXJhbmdlLWJ1dHRvbnNcIiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogNHB4O1wiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInN0YXRzLXJhbmdlLWJ0biBhY3RpdmVcIiBkYXRhLXJhbmdlPVwiMWhcIj4xaDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInN0YXRzLXJhbmdlLWJ0blwiIGRhdGEtcmFuZ2U9XCIyNGhcIj4yNGg8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJzdGF0cy1yYW5nZS1idG5cIiBkYXRhLXJhbmdlPVwiN2RcIj43ZDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInN0YXRzLXJhbmdlLWJ0blwiIGRhdGEtcmFuZ2U9XCIzMGRcIj4zMGQ8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJzdGF0cy1yYW5nZS1idG5cIiBkYXRhLXJhbmdlPVwiMXlcIj4xeTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cInN0YXRzLWhpc3RvcnktY29udGFpbmVyLWFyZWFcIiBjbGFzcz1cInNjcm9sbC1jb250YWluZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1RENDQTwvc3Bhbj5cbiAgICAgICAgICAgIENob29zZSBhIGNvbnRhaW5lciBhbmQgdGltZSByYW5nZSB0byB2aWV3IGhpc3RvcnkuXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gVGFiOiBBbGVydCBDb25maWd1cmF0aW9uIC0tPlxuICAgICAgPGRpdiBpZD1cInN0YXRzLWFsZXJ0c1wiIGNsYXNzPVwicGFuZWwtc2VjdGlvblwiPlxuICAgICAgICA8ZGl2IGlkPVwic3RhdHMtYWxlcnRzLWNvbnRhaW5lclwiIGNsYXNzPVwic2Nyb2xsLWNvbnRhaW5lclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJlbXB0eS1pY29uXCI+XHVEODNEXHVERDE0PC9zcGFuPlxuICAgICAgICAgICAgTG9hZGluZyBhbGVydCBjb25maWd1cmF0aW9ucy4uLlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEF1dG8tcmVmcmVzaCB0b2dnbGUgKGJvdHRvbSBiYXIpIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWJvdHRvbS1iYXJcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2hlY2tib3gtbGFiZWxcIiBzdHlsZT1cImZvbnQtc2l6ZTogMC44NXJlbTtcIj5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJzdGF0cy1hdXRvLXJlZnJlc2hcIiBjaGVja2VkIC8+XG4gICAgICAgICAgQXV0by1yZWZyZXNoIGV2ZXJ5IDVzXG4gICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDxidXR0b24gaWQ9XCJzdGF0cy1yZWZyZXNoLWJ0blwiIGNsYXNzPVwiYnRuLXNtXCI+XHVEODNEXHVERDA0IFJlZnJlc2ggTm93PC9idXR0b24+XG4gICAgICAgIDxzcGFuIGlkPVwic3RhdHMtbGFzdC11cGRhdGVcIiBjbGFzcz1cInRleHQtYXV0by1yaWdodFwiPjwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIENsb3NlIEJ1dHRvbiAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJ3ZWF0aGVyLW1vZGFsLWJ1dHRvbnMgbW9kYWwtZm9vdGVyLWJhclwiPlxuICAgICAgICA8YnV0dG9uIGlkPVwic3RhdHMtY2FuY2VsXCI+Q2xvc2U8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5gKTtcblxuICBjb25zdCBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGF0cy1tb2RhbCcpO1xuICBjb25zdCBvcGVuQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbnRhaW5lci1zdGF0cy1idG4nKTtcbiAgY29uc3QgY2FuY2VsQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0YXRzLWNhbmNlbCcpO1xuICBjb25zdCByZWZyZXNoQnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0YXRzLXJlZnJlc2gtYnRuJyk7XG4gIGNvbnN0IGF1dG9SZWZyZXNoQ2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RhdHMtYXV0by1yZWZyZXNoJyk7XG4gIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGF0cy1jb250YWluZXInKTtcbiAgY29uc3QgYWdncmVnYXRlZENvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGF0cy1hZ2dyZWdhdGVkLWNvbnRhaW5lcicpO1xuICBjb25zdCBhbGVydHNDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RhdHMtYWxlcnRzLWNvbnRhaW5lcicpO1xuICBjb25zdCBsYXN0VXBkYXRlU3BhbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGF0cy1sYXN0LXVwZGF0ZScpO1xuXG4gIGxldCByZWZyZXNoSW50ZXJ2YWwgPSBudWxsO1xuICBsZXQgY2FjaGVkTW9uaXRvcmluZ0RhdGEgPSBudWxsO1xuXG4gIGZ1bmN0aW9uIGZvcm1hdEJ5dGVzKGJ5dGVzKSB7XG4gICAgaWYgKGJ5dGVzID09PSAwIHx8ICFieXRlcykgcmV0dXJuICcwIEInO1xuICAgIGNvbnN0IGsgPSAxMDI0O1xuICAgIGNvbnN0IHNpemVzID0gWydCJywgJ0tCJywgJ01CJywgJ0dCJ107XG4gICAgY29uc3QgaSA9IE1hdGguZmxvb3IoTWF0aC5sb2coYnl0ZXMpIC8gTWF0aC5sb2coaykpO1xuICAgIHJldHVybiBwYXJzZUZsb2F0KChieXRlcyAvIE1hdGgucG93KGssIGkpKS50b0ZpeGVkKDEpKSArICcgJyArIHNpemVzW2ldO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0Q3B1Q29sb3IocGVyY2VudCkge1xuICAgIGlmIChwZXJjZW50IDwgMzApIHJldHVybiAnIzJlY2M3MSc7XG4gICAgaWYgKHBlcmNlbnQgPCA3MCkgcmV0dXJuICcjZjM5YzEyJztcbiAgICByZXR1cm4gJyNlNzRjM2MnO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0TWVtQ29sb3IocGVyY2VudCkge1xuICAgIGlmIChwZXJjZW50IDwgNTApIHJldHVybiAnIzJlY2M3MSc7XG4gICAgaWYgKHBlcmNlbnQgPCA4MCkgcmV0dXJuICcjZjM5YzEyJztcbiAgICByZXR1cm4gJyNlNzRjM2MnO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZFN0YXRzKCkge1xuICAgIHRyeSB7XG4gICAgICAvLyBUcnkgbmV3IG1vbml0b3JpbmcgQVBJIGZpcnN0LCBmYWxsIGJhY2sgdG8gb2xkXG4gICAgICBsZXQgc3RhdHMgPSBudWxsO1xuICAgICAgbGV0IGlzTmV3QXBpID0gZmFsc2U7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9tb25pdG9yaW5nL3N0YXRzJyk7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgICBpZiAoZGF0YS5zdWNjZXNzICYmIGRhdGEuc3RhdHMpIHsgc3RhdHMgPSBkYXRhLnN0YXRzOyBpc05ld0FwaSA9IHRydWU7IGNhY2hlZE1vbml0b3JpbmdEYXRhID0gZGF0YS5zdGF0czsgfVxuICAgICAgfSBjYXRjaCAoXykge31cblxuICAgICAgaWYgKCFpc05ld0FwaSkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL3N0YXRzL2NvbnRhaW5lcnMnKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgaWYgKGRhdGEuc3VjY2VzcyAmJiBkYXRhLnN0YXRzKSB7XG4gICAgICAgICAgLy8gQ29udmVydCBhcnJheSBmb3JtYXQgdG8gb2JqZWN0IGZvcm1hdFxuICAgICAgICAgIHN0YXRzID0ge307XG4gICAgICAgICAgZm9yIChjb25zdCBzIG9mIGRhdGEuc3RhdHMpIHtcbiAgICAgICAgICAgIHN0YXRzW3MubmFtZV0gPSB7IG5hbWU6IHMubmFtZSwgY3VycmVudDogeyBjcHU6IHMuY3B1LCBtZW1vcnk6IHsgcGVyY2VudDogcy5tZW1vcnkucGVyY2VudCwgdXNhZ2U6IHMubWVtb3J5LnVzZWQsIGxpbWl0OiBzLm1lbW9yeS5saW1pdCwgdXNhZ2VNQjogTWF0aC5yb3VuZChzLm1lbW9yeS51c2VkIC8gMTA0ODU3NiksIGxpbWl0TUI6IE1hdGgucm91bmQocy5tZW1vcnkubGltaXQgLyAxMDQ4NTc2KSB9LCBuZXR3b3JrOiB7IHJ4Qnl0ZXM6IHMubmV0d29yay5yeCwgdHhCeXRlczogcy5uZXR3b3JrLnR4LCByeE1COiAocy5uZXR3b3JrLnJ4IC8gMTA0ODU3NikudG9GaXhlZCgxKSwgdHhNQjogKHMubmV0d29yay50eCAvIDEwNDg1NzYpLnRvRml4ZWQoMSkgfSwgZGlzazogeyByZWFkTUI6IDAsIHdyaXRlTUI6IDAgfSB9LCBzdGF0dXM6IHMuc3RhdHVzIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhY2hlZE1vbml0b3JpbmdEYXRhID0gc3RhdHM7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFzdGF0cyB8fCBPYmplY3Qua2V5cyhzdGF0cykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBzdHlsZT1cInRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogNDBweDsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5ObyBydW5uaW5nIGNvbnRhaW5lcnMgZm91bmQ8L2Rpdj4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxldCBodG1sID0gJzxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDhweDtcIj4nO1xuXG4gICAgICBmb3IgKGNvbnN0IFtpZCwgaW5mb10gb2YgT2JqZWN0LmVudHJpZXMoc3RhdHMpKSB7XG4gICAgICAgIGNvbnN0IGN1ciA9IGluZm8uY3VycmVudCB8fCBpbmZvO1xuICAgICAgICBjb25zdCBjcHUgPSBjdXIuY3B1Py5wZXJjZW50IHx8IDA7XG4gICAgICAgIGNvbnN0IG1lbSA9IGN1ci5tZW1vcnk/LnBlcmNlbnQgfHwgMDtcbiAgICAgICAgY29uc3QgY3B1Q29sb3IgPSBnZXRDcHVDb2xvcihjcHUpO1xuICAgICAgICBjb25zdCBtZW1Db2xvciA9IGdldE1lbUNvbG9yKG1lbSk7XG4gICAgICAgIGNvbnN0IG1lbVVzZWQgPSBjdXIubWVtb3J5Py51c2FnZSB8fCBjdXIubWVtb3J5Py51c2VkIHx8IDA7XG4gICAgICAgIGNvbnN0IG1lbUxpbWl0ID0gY3VyLm1lbW9yeT8ubGltaXQgfHwgMDtcbiAgICAgICAgY29uc3QgbmV0UnggPSBjdXIubmV0d29yaz8ucnhCeXRlcyB8fCBjdXIubmV0d29yaz8ucnggfHwgMDtcbiAgICAgICAgY29uc3QgbmV0VHggPSBjdXIubmV0d29yaz8udHhCeXRlcyB8fCBjdXIubmV0d29yaz8udHggfHwgMDtcbiAgICAgICAgY29uc3QgYWdnID0gaW5mby5hZ2dyZWdhdGVkO1xuXG4gICAgICAgIGh0bWwgKz0gYFxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAxMnB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XCI+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiAxMnB4OyBtYXJnaW4tYm90dG9tOiAxMHB4O1wiPlxuICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IGZsZXg6IDE7XCI+JHtpbmZvLm5hbWUgfHwgaWR9PC9zcGFuPlxuICAgICAgICAgICAgICAke2FnZyA/IGA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMC42NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgcGFkZGluZzogMnB4IDZweDsgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWFjY2VudCkgMTAlLCB0cmFuc3BhcmVudCk7IGJvcmRlci1yYWRpdXM6IDRweDtcIj5hdmcgJHthZ2cuY3B1Py5hdmc/LnRvRml4ZWQoMCkgfHwgMH0lIGNwdTwvc3Bhbj5gIDogJyd9XG4gICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAwLjc1cmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBiYWNrZ3JvdW5kOiB2YXIoLS1iYXNlKTsgcGFkZGluZzogMnB4IDhweDsgYm9yZGVyLXJhZGl1czogNHB4O1wiPiR7aW5mby5zdGF0dXMgfHwgJ3J1bm5pbmcnfTwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdyaWQtdGVtcGxhdGUtY29sdW1uczogcmVwZWF0KDMsIDFmcik7IGdhcDogMTJweDtcIj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjdyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDRweDtcIj5DUFU8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZmxleDogMTsgaGVpZ2h0OiA2cHg7IGJhY2tncm91bmQ6IHZhcigtLWJhc2UpOyBib3JkZXItcmFkaXVzOiAzcHg7IG92ZXJmbG93OiBoaWRkZW47XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJoZWlnaHQ6IDEwMCU7IHdpZHRoOiAke01hdGgubWluKGNwdSwgMTAwKX0lOyBiYWNrZ3JvdW5kOiAke2NwdUNvbG9yfTsgYm9yZGVyLXJhZGl1czogM3B4OyB0cmFuc2l0aW9uOiB3aWR0aCAwLjNzO1wiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBmb250LXdlaWdodDogNTAwOyBjb2xvcjogJHtjcHVDb2xvcn07IG1pbi13aWR0aDogNDVweDsgdGV4dC1hbGlnbjogcmlnaHQ7XCI+JHtjcHUudG9GaXhlZCgxKX0lPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjdyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDRweDtcIj5NZW1vcnk8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZmxleDogMTsgaGVpZ2h0OiA2cHg7IGJhY2tncm91bmQ6IHZhcigtLWJhc2UpOyBib3JkZXItcmFkaXVzOiAzcHg7IG92ZXJmbG93OiBoaWRkZW47XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJoZWlnaHQ6IDEwMCU7IHdpZHRoOiAke01hdGgubWluKG1lbSwgMTAwKX0lOyBiYWNrZ3JvdW5kOiAke21lbUNvbG9yfTsgYm9yZGVyLXJhZGl1czogM3B4OyB0cmFuc2l0aW9uOiB3aWR0aCAwLjNzO1wiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBmb250LXdlaWdodDogNTAwOyBjb2xvcjogJHttZW1Db2xvcn07IG1pbi13aWR0aDogNDVweDsgdGV4dC1hbGlnbjogcmlnaHQ7XCI+JHttZW0udG9GaXhlZCgxKX0lPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNjVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi10b3A6IDJweDtcIj4ke2Zvcm1hdEJ5dGVzKG1lbVVzZWQpfSAvICR7Zm9ybWF0Qnl0ZXMobWVtTGltaXQpfTwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjdyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDRweDtcIj5OZXR3b3JrPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtO1wiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJjb2xvcjogIzM0OThkYjtcIj5cdTIxOTMgJHtmb3JtYXRCeXRlcyhuZXRSeCl9PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW46IDAgNHB4O1wiPi88L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiAjZTc0YzNjO1wiPlx1MjE5MSAke2Zvcm1hdEJ5dGVzKG5ldFR4KX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+YDtcbiAgICAgIH1cbiAgICAgIGh0bWwgKz0gJzwvZGl2Pic7XG4gICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgIGxhc3RVcGRhdGVTcGFuLnRleHRDb250ZW50ID0gJ1VwZGF0ZWQ6ICcgKyBuZXcgRGF0ZSgpLnRvTG9jYWxlVGltZVN0cmluZygpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSBgPGRpdiBzdHlsZT1cInRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogNDBweDsgY29sb3I6IHZhcigtLWJhZC1mZyk7XCI+XHUyNzRDIEZhaWxlZCB0byBsb2FkIHN0YXRzOiAke2VzY2FwZUh0bWwoZS5tZXNzYWdlKX08L2Rpdj5gO1xuICAgIH1cbiAgfVxuXG4gIC8vID09PSAyNGggQWdncmVnYXRlZCBUYWIgPT09XG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWRBZ2dyZWdhdGVkKCkge1xuICAgIGlmICghYWdncmVnYXRlZENvbnRhaW5lcikgcmV0dXJuO1xuICAgIGNvbnN0IGRhdGEgPSBjYWNoZWRNb25pdG9yaW5nRGF0YTtcbiAgICBpZiAoIWRhdGEgfHwgT2JqZWN0LmtleXMoZGF0YSkubGVuZ3RoID09PSAwKSB7XG4gICAgICBhZ2dyZWdhdGVkQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0RcdURDQzg8L3NwYW4+Tm8gbW9uaXRvcmluZyBkYXRhIGF2YWlsYWJsZS4gT3BlbiB0aGUgTGl2ZSBTdGF0cyB0YWIgZmlyc3QuPC9kaXY+JztcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IGh0bWwgPSAnPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGdhcDogMTJweDtcIj4nO1xuICAgIGZvciAoY29uc3QgW2lkLCBpbmZvXSBvZiBPYmplY3QuZW50cmllcyhkYXRhKSkge1xuICAgICAgY29uc3QgYWdnID0gaW5mby5hZ2dyZWdhdGVkO1xuICAgICAgaWYgKCFhZ2cpIGNvbnRpbnVlO1xuICAgICAgaHRtbCArPSBgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDEycHg7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7IGJvcmRlci1yYWRpdXM6IDhweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtd2VpZ2h0OiA2MDA7IG1hcmdpbi1ib3R0b206IDEwcHg7XCI+JHtpbmZvLm5hbWUgfHwgaWR9PC9kaXY+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IHJlcGVhdCg0LCAxZnIpOyBnYXA6IDhweDtcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdC1taW5pLWNhcmRcIj48c3BhbiBjbGFzcz1cInN0YXQtdmFsXCI+JHthZ2cuY3B1Py5hdmc/LnRvRml4ZWQoMSkgfHwgMH0lPC9zcGFuPjxzcGFuIGNsYXNzPVwic3RhdC1sYmxcIj5BdmcgQ1BVPC9zcGFuPjwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0LW1pbmktY2FyZFwiPjxzcGFuIGNsYXNzPVwic3RhdC12YWxcIj4ke2FnZy5jcHU/Lm1heD8udG9GaXhlZCgxKSB8fCAwfSU8L3NwYW4+PHNwYW4gY2xhc3M9XCJzdGF0LWxibFwiPk1heCBDUFU8L3NwYW4+PC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInN0YXQtbWluaS1jYXJkXCI+PHNwYW4gY2xhc3M9XCJzdGF0LXZhbFwiPiR7YWdnLm1lbW9yeT8uYXZnPy50b0ZpeGVkKDEpIHx8IDB9JTwvc3Bhbj48c3BhbiBjbGFzcz1cInN0YXQtbGJsXCI+QXZnIE1lbTwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdC1taW5pLWNhcmRcIj48c3BhbiBjbGFzcz1cInN0YXQtdmFsXCI+JHthZ2cubWVtb3J5Py5tYXg/LnRvRml4ZWQoMSkgfHwgMH0lPC9zcGFuPjxzcGFuIGNsYXNzPVwic3RhdC1sYmxcIj5NYXggTWVtPC9zcGFuPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgJHthZ2cuZGF0YVBvaW50cyA/IGA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjdyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi10b3A6IDZweDtcIj4ke2FnZy5kYXRhUG9pbnRzfSBkYXRhIHBvaW50cyBvdmVyICR7YWdnLnRpbWVSYW5nZSB8fCAyNH1oPC9kaXY+YCA6ICcnfVxuICAgICAgPC9kaXY+YDtcbiAgICB9XG4gICAgaHRtbCArPSAnPC9kaXY+JztcbiAgICBhZ2dyZWdhdGVkQ29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7XG4gIH1cblxuICAvLyA9PT0gQWxlcnRzIFRhYiA9PT1cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZEFsZXJ0cygpIHtcbiAgICBpZiAoIWFsZXJ0c0NvbnRhaW5lcikgcmV0dXJuO1xuICAgIGFsZXJ0c0NvbnRhaW5lci5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPiBMb2FkaW5nIGFsZXJ0cy4uLjwvZGl2Pic7XG5cbiAgICBjb25zdCBkYXRhID0gY2FjaGVkTW9uaXRvcmluZ0RhdGE7XG4gICAgaWYgKCFkYXRhIHx8IE9iamVjdC5rZXlzKGRhdGEpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgYWxlcnRzQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImVtcHR5LWljb25cIj5cdUQ4M0RcdUREMTQ8L3NwYW4+Tm8gY29udGFpbmVycyBmb3VuZC4gT3BlbiB0aGUgTGl2ZSBTdGF0cyB0YWIgZmlyc3QuPC9kaXY+JztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBwcmVtaXVtIHN0YXR1cyBmb3IgY29uZmlnIHNlY3Rpb24gdmlzaWJpbGl0eVxuICAgIGxldCBpc1ByZW1pdW0gPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL2xpY2Vuc2UvZmVhdHVyZS9yZXNvdXJjZS1hbGVydHMnKTtcbiAgICAgIGNvbnN0IGxkID0gYXdhaXQgcmVzcC5qc29uKCk7XG4gICAgICBpc1ByZW1pdW0gPSBsZC5hdmFpbGFibGU7XG4gICAgfSBjYXRjaCAoXykgeyBpc1ByZW1pdW0gPSBmYWxzZTsgfVxuXG4gICAgLy8gRmV0Y2ggYWxlcnQgaGlzdG9yeVxuICAgIGxldCBhbGVydEhpc3RvcnkgPSBbXTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgaHIgPSBhd2FpdCBmZXRjaCgnL2FwaS92MS9tb25pdG9yaW5nL2FsZXJ0cz9saW1pdD01MCcpO1xuICAgICAgY29uc3QgaGQgPSBhd2FpdCBoci5qc29uKCk7XG4gICAgICBpZiAoaGQuc3VjY2VzcykgYWxlcnRIaXN0b3J5ID0gaGQuaGlzdG9yeSB8fCBbXTtcbiAgICB9IGNhdGNoIChfKSB7fVxuXG4gICAgLy8gRmV0Y2ggYWxsIGFsZXJ0IGNvbmZpZ3NcbiAgICBsZXQgYWxsQ29uZmlncyA9IHt9O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjciA9IGF3YWl0IGZldGNoKCcvYXBpL3YxL21vbml0b3JpbmcvYWxlcnRzL2NvbmZpZycpO1xuICAgICAgY29uc3QgY2QgPSBhd2FpdCBjci5qc29uKCk7XG4gICAgICBpZiAoY2Quc3VjY2VzcykgYWxsQ29uZmlncyA9IGNkLmNvbmZpZ3MgfHwge307XG4gICAgfSBjYXRjaCAoXykge31cblxuICAgIGNvbnN0IGNvbnRhaW5lcnMgPSBPYmplY3QuZW50cmllcyhkYXRhKTtcbiAgICBjb25zdCBjb250YWluZXJSb3dzID0gY29udGFpbmVycy5tYXAoKFtpZCwgaW5mb10pID0+IHtcbiAgICAgIGNvbnN0IGNmZyA9IGFsbENvbmZpZ3NbaWRdIHx8IHsgY3B1VGhyZXNob2xkOiA4MCwgbWVtb3J5VGhyZXNob2xkOiA5MCwgZGlza0lPVGhyZXNob2xkOiA1MCwgYXV0b1Jlc3RhcnQ6IGZhbHNlLCBlbmFibGVkOiBmYWxzZSB9O1xuICAgICAgcmV0dXJuIGBcbiAgICAgICAgPHRyIGRhdGEtY29udGFpbmVyPVwiJHtpZH1cIj5cbiAgICAgICAgICA8dGQgc3R5bGU9XCJmb250LXdlaWdodDogNjAwOyBwYWRkaW5nOiA4cHg7XCI+JHtpbmZvLm5hbWUgfHwgaWR9PC90ZD5cbiAgICAgICAgICA8dGQgc3R5bGU9XCJwYWRkaW5nOiA0cHggOHB4O1wiPjxpbnB1dCB0eXBlPVwibnVtYmVyXCIgY2xhc3M9XCJhbGVydC1jcHVcIiB2YWx1ZT1cIiR7Y2ZnLmNwdVRocmVzaG9sZCA/PyA4MH1cIiBtaW49XCIwXCIgbWF4PVwiMTAwXCIgc3R5bGU9XCJ3aWR0aDogNjBweDsgZm9udC1zaXplOiAwLjhyZW07IHBhZGRpbmc6IDJweCA0cHg7XCIgJHtpc1ByZW1pdW0gPyAnJyA6ICdkaXNhYmxlZCd9IC8+PC90ZD5cbiAgICAgICAgICA8dGQgc3R5bGU9XCJwYWRkaW5nOiA0cHggOHB4O1wiPjxpbnB1dCB0eXBlPVwibnVtYmVyXCIgY2xhc3M9XCJhbGVydC1tZW1cIiB2YWx1ZT1cIiR7Y2ZnLm1lbW9yeVRocmVzaG9sZCA/PyA5MH1cIiBtaW49XCIwXCIgbWF4PVwiMTAwXCIgc3R5bGU9XCJ3aWR0aDogNjBweDsgZm9udC1zaXplOiAwLjhyZW07IHBhZGRpbmc6IDJweCA0cHg7XCIgJHtpc1ByZW1pdW0gPyAnJyA6ICdkaXNhYmxlZCd9IC8+PC90ZD5cbiAgICAgICAgICA8dGQgc3R5bGU9XCJwYWRkaW5nOiA0cHggOHB4O1wiPjxpbnB1dCB0eXBlPVwibnVtYmVyXCIgY2xhc3M9XCJhbGVydC1kaXNrXCIgdmFsdWU9XCIke2NmZy5kaXNrSU9UaHJlc2hvbGQgPz8gNTB9XCIgbWluPVwiMFwiIG1heD1cIjEwMDBcIiBzdHlsZT1cIndpZHRoOiA3MHB4OyBmb250LXNpemU6IDAuOHJlbTsgcGFkZGluZzogMnB4IDRweDtcIiAke2lzUHJlbWl1bSA/ICcnIDogJ2Rpc2FibGVkJ30gLz48L3RkPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cInBhZGRpbmc6IDRweCA4cHg7XCI+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiYWxlcnQtYXV0b3Jlc3RhcnRcIiAke2NmZy5hdXRvUmVzdGFydCA/ICdjaGVja2VkJyA6ICcnfSAke2lzUHJlbWl1bSA/ICcnIDogJ2Rpc2FibGVkJ30gLz48L3RkPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cInBhZGRpbmc6IDRweCA4cHg7XCI+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYWxlcnQtdGVzdC1idG4gYnRuLXhzXCIgZGF0YS1jb250YWluZXI9XCIke2lkfVwiIGRhdGEtbmFtZT1cIiR7aW5mby5uYW1lIHx8IGlkfVwiIHN0eWxlPVwicGFkZGluZzogMnB4IDhweDsgZm9udC1zaXplOiAwLjc1cmVtOyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpOyBib3JkZXItcmFkaXVzOiA0cHg7IGN1cnNvcjogcG9pbnRlcjtcIj5UZXN0PC9idXR0b24+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgIGA7XG4gICAgfSkuam9pbignJyk7XG5cbiAgICBjb25zdCBoaXN0b3J5Um93cyA9IGFsZXJ0SGlzdG9yeS5tYXAoZW50cnkgPT4ge1xuICAgICAgY29uc3QgdGltZSA9IG5ldyBEYXRlKGVudHJ5LnRpbWVzdGFtcCkudG9Mb2NhbGVTdHJpbmcoKTtcbiAgICAgIGNvbnN0IG5vdGlmaWVkTWFyayA9IGVudHJ5Lm5vdGlmaWVkID8gJ1x1MjcxMycgOiAnXHUyMDE0JztcbiAgICAgIHJldHVybiBgXG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHggOHB4OyBmb250LXNpemU6IDAuOHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj4ke3RpbWV9PC90ZD5cbiAgICAgICAgICA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHggOHB4OyBmb250LXdlaWdodDogNTAwO1wiPiR7ZW50cnkuY29udGFpbmVyTmFtZSB8fCBlbnRyeS5jb250YWluZXJJZH08L3RkPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweCA4cHg7IHRleHQtdHJhbnNmb3JtOiBjYXBpdGFsaXplO1wiPiR7ZW50cnkubWV0cmljIHx8IGVudHJ5LnR5cGV9PC90ZD5cbiAgICAgICAgICA8dGQgc3R5bGU9XCJwYWRkaW5nOiA2cHggOHB4O1wiPiR7dHlwZW9mIGVudHJ5LnZhbHVlID09PSAnbnVtYmVyJyA/IGVudHJ5LnZhbHVlLnRvRml4ZWQoMSkgOiBlbnRyeS52YWx1ZX0ke2VudHJ5Lm1ldHJpYyA9PT0gJ2Rpc2snID8gJyBNQi9zJyA6ICclJ308L3RkPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweCA4cHg7IHRleHQtYWxpZ246IGNlbnRlcjtcIj4ke25vdGlmaWVkTWFya308L3RkPlxuICAgICAgICAgIDx0ZCBzdHlsZT1cInBhZGRpbmc6IDZweCA4cHg7IGZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6ICR7ZW50cnkuYXV0b1Jlc3RhcnRUcmlnZ2VyZWQgPyAnI2YzOWMxMicgOiAndmFyKC0tbXV0ZWQpJ307XCI+JHtlbnRyeS5hdXRvUmVzdGFydFRyaWdnZXJlZCA/ICdcdTIxQkInIDogJyd9PC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgIGA7XG4gICAgfSkuam9pbignJyk7XG5cbiAgICBjb25zdCBjb25maWdTZWN0aW9uID0gaXNQcmVtaXVtID8gYFxuICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDIwcHg7XCI+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IG1hcmdpbi1ib3R0b206IDEwcHg7XCI+XG4gICAgICAgICAgPGg0IHN0eWxlPVwibWFyZ2luOiAwOyBmb250LXNpemU6IDAuOXJlbTtcIj5cdTI2OTlcdUZFMEYgQWxlcnQgQ29uZmlndXJhdGlvbjwvaDQ+XG4gICAgICAgICAgPGEgaHJlZj1cIiNcIiBpZD1cImdvLXRvLW5vdGlmaWNhdGlvbnNcIiBzdHlsZT1cImZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogdmFyKC0tYWNjZW50KTsgdGV4dC1kZWNvcmF0aW9uOiBub25lO1wiPkNvbmZpZ3VyZSBub3RpZmljYXRpb25zIFx1MjE5MjwvYT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJvdmVyZmxvdy14OiBhdXRvO1wiPlxuICAgICAgICAgIDx0YWJsZSBzdHlsZT1cIndpZHRoOiAxMDAlOyBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyBmb250LXNpemU6IDAuODVyZW07XCI+XG4gICAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICAgIDx0ciBzdHlsZT1cImJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1wiPlxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInRleHQtYWxpZ246IGxlZnQ7IHBhZGRpbmc6IDZweCA4cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+Q29udGFpbmVyPC90aD5cbiAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJ0ZXh0LWFsaWduOiBsZWZ0OyBwYWRkaW5nOiA2cHggOHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkNQVSAlPC90aD5cbiAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJ0ZXh0LWFsaWduOiBsZWZ0OyBwYWRkaW5nOiA2cHggOHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPk1lbSAlPC90aD5cbiAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJ0ZXh0LWFsaWduOiBsZWZ0OyBwYWRkaW5nOiA2cHggOHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkRpc2sgSS9PIE1CL3M8L3RoPlxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogNnB4IDhweDsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5BdXRvLVJlc3RhcnQ8L3RoPlxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInBhZGRpbmc6IDZweCA4cHg7XCI+PC90aD5cbiAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICA8dGJvZHk+JHtjb250YWluZXJSb3dzfTwvdGJvZHk+XG4gICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tdG9wOiAxMnB4OyBkaXNwbGF5OiBmbGV4OyBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1wiPlxuICAgICAgICAgIDxidXR0b24gaWQ9XCJzYXZlLWFsbC1hbGVydHNcIiBzdHlsZT1cInBhZGRpbmc6IDZweCAxNnB4OyBmb250LXNpemU6IDAuODVyZW07IGJhY2tncm91bmQ6IHZhcigtLWFjY2VudCk7IGNvbG9yOiB2YXIoLS1iYXNlKTsgYm9yZGVyOiBub25lOyBib3JkZXItcmFkaXVzOiA0cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDYwMDtcIj5TYXZlIEFsbDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIGAgOiBgXG4gICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMjBweDsgcGFkZGluZzogMTJweDsgYmFja2dyb3VuZDogcmdiYSgyNDEsMTk2LDE1LDAuMSk7IGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjQxLDE5NiwxNSwwLjMpOyBib3JkZXItcmFkaXVzOiA4cHg7IHRleHQtYWxpZ246IGNlbnRlcjtcIj5cbiAgICAgICAgPHNwYW4gc3R5bGU9XCJjb2xvcjogI2YxYzQwZjsgZm9udC13ZWlnaHQ6IDYwMDsgZm9udC1zaXplOiAwLjg1cmVtO1wiPlx1MkI1MCBQcmVtaXVtIEZlYXR1cmU8L3NwYW4+XG4gICAgICAgIDxwIHN0eWxlPVwibWFyZ2luOiA2cHggMCAwOyBmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+VXBncmFkZSB0byBjb25maWd1cmUgcmVzb3VyY2UgYWxlcnQgdGhyZXNob2xkcyBwZXIgY29udGFpbmVyLjwvcD5cbiAgICAgICAgPGJ1dHRvbiBpZD1cInVwZ3JhZGUtZm9yLWFsZXJ0c1wiIHN0eWxlPVwibWFyZ2luLXRvcDogOHB4OyBwYWRkaW5nOiA0cHggMTJweDsgZm9udC1zaXplOiAwLjc1cmVtOyBiYWNrZ3JvdW5kOiAjZjFjNDBmOyBjb2xvcjogIzAwMDsgYm9yZGVyOiBub25lOyBib3JkZXItcmFkaXVzOiA0cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IDYwMDtcIj5VcGdyYWRlIE5vdzwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgYDtcblxuICAgIGFsZXJ0c0NvbnRhaW5lci5pbm5lckhUTUwgPSBgXG4gICAgICAke2NvbmZpZ1NlY3Rpb259XG4gICAgICA8ZGl2PlxuICAgICAgICA8aDQgc3R5bGU9XCJtYXJnaW46IDAgMCAxMHB4OyBmb250LXNpemU6IDAuOXJlbTtcIj5cdUQ4M0RcdURDQ0IgUmVjZW50IEFsZXJ0czwvaDQ+XG4gICAgICAgICR7aGlzdG9yeVJvd3MgPyBgXG4gICAgICAgICAgPGRpdiBzdHlsZT1cIm92ZXJmbG93LXg6IGF1dG87XCI+XG4gICAgICAgICAgICA8dGFibGUgc3R5bGU9XCJ3aWR0aDogMTAwJTsgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsgZm9udC1zaXplOiAwLjhyZW07XCI+XG4gICAgICAgICAgICAgIDx0aGVhZD5cbiAgICAgICAgICAgICAgICA8dHIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcIj5cbiAgICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInRleHQtYWxpZ246IGxlZnQ7IHBhZGRpbmc6IDZweCA4cHg7IGNvbG9yOiB2YXIoLS1tdXRlZCk7XCI+VGltZTwvdGg+XG4gICAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJ0ZXh0LWFsaWduOiBsZWZ0OyBwYWRkaW5nOiA2cHggOHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPkNvbnRhaW5lcjwvdGg+XG4gICAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJ0ZXh0LWFsaWduOiBsZWZ0OyBwYWRkaW5nOiA2cHggOHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPk1ldHJpYzwvdGg+XG4gICAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJ0ZXh0LWFsaWduOiBsZWZ0OyBwYWRkaW5nOiA2cHggOHB4OyBjb2xvcjogdmFyKC0tbXV0ZWQpO1wiPlZhbHVlPC90aD5cbiAgICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogNnB4IDhweDsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5cdTI3MTM/PC90aD5cbiAgICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cInBhZGRpbmc6IDZweCA4cHg7XCI+PC90aD5cbiAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgICAgICA8dGJvZHk+JHtoaXN0b3J5Um93c308L3Rib2R5PlxuICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgYCA6ICc8ZGl2IHN0eWxlPVwiY29sb3I6IHZhcigtLW11dGVkKTsgdGV4dC1hbGlnbjogY2VudGVyOyBwYWRkaW5nOiAyMHB4O1wiPk5vIGFsZXJ0cyByZWNvcmRlZCB5ZXQuPC9kaXY+J31cbiAgICAgIDwvZGl2PlxuICAgIGA7XG5cbiAgICAvLyBXaXJlIHVwIHNhdmUtYWxsIGJ1dHRvblxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzYXZlLWFsbC1hbGVydHMnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjb25maWdzID0ge307XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjc3RhdHMtYWxlcnRzLWNvbnRhaW5lciB0cltkYXRhLWNvbnRhaW5lcl0nKS5mb3JFYWNoKHJvdyA9PiB7XG4gICAgICAgIGNvbnN0IGNJZCA9IHJvdy5kYXRhc2V0LmNvbnRhaW5lcjtcbiAgICAgICAgY29uZmlnc1tjSWRdID0ge1xuICAgICAgICAgIGNwdVRocmVzaG9sZDogcGFyc2VJbnQocm93LnF1ZXJ5U2VsZWN0b3IoJy5hbGVydC1jcHUnKT8udmFsdWUpIHx8IDgwLFxuICAgICAgICAgIG1lbW9yeVRocmVzaG9sZDogcGFyc2VJbnQocm93LnF1ZXJ5U2VsZWN0b3IoJy5hbGVydC1tZW0nKT8udmFsdWUpIHx8IDkwLFxuICAgICAgICAgIGRpc2tJT1RocmVzaG9sZDogcGFyc2VJbnQocm93LnF1ZXJ5U2VsZWN0b3IoJy5hbGVydC1kaXNrJyk/LnZhbHVlKSB8fCA1MCxcbiAgICAgICAgICBhdXRvUmVzdGFydDogISFyb3cucXVlcnlTZWxlY3RvcignLmFsZXJ0LWF1dG9yZXN0YXJ0Jyk/LmNoZWNrZWQsXG4gICAgICAgICAgZW5hYmxlZDogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBzZWN1cmVGZXRjaCgnL2FwaS92MS9tb25pdG9yaW5nL2FsZXJ0cy9jb25maWcnLCB7XG4gICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBjb25maWdzIH0pXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBkID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgICAgY29uc3QgYnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NhdmUtYWxsLWFsZXJ0cycpO1xuICAgICAgICBidG4udGV4dENvbnRlbnQgPSBkLnN1Y2Nlc3MgPyAnXHUyNzA1IFNhdmVkJyA6ICdcdTI3NEMgRmFpbGVkJztcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IGJ0bi50ZXh0Q29udGVudCA9ICdTYXZlIEFsbCc7IH0sIDIwMDApO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zdCBidG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2F2ZS1hbGwtYWxlcnRzJyk7XG4gICAgICAgIGJ0bi50ZXh0Q29udGVudCA9ICdcdTI3NEMgRXJyb3InO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgYnRuLnRleHRDb250ZW50ID0gJ1NhdmUgQWxsJzsgfSwgMjAwMCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBXaXJlIHVwIG5vdGlmaWNhdGlvbiBzZXR0aW5ncyBsaW5rXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2dvLXRvLW5vdGlmaWNhdGlvbnMnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgbW9kYWwuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO1xuICAgICAgc3RvcEF1dG9SZWZyZXNoKCk7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFuYWdlLW5vdGlmaWNhdGlvbnMnKT8uY2xpY2soKTtcbiAgICB9KTtcblxuICAgIC8vIFdpcmUgdXAgdGVzdCBidXR0b25zXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmFsZXJ0LXRlc3QtYnRuJykuZm9yRWFjaChidG4gPT4ge1xuICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBvcmlnID0gYnRuLnRleHRDb250ZW50O1xuICAgICAgICBidG4udGV4dENvbnRlbnQgPSAnLi4uJztcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBzZWN1cmVGZXRjaChgL2FwaS92MS9tb25pdG9yaW5nL2FsZXJ0cy8ke2J0bi5kYXRhc2V0LmNvbnRhaW5lcn0vdGVzdGAsIHsgbWV0aG9kOiAnUE9TVCcgfSk7XG4gICAgICAgICAgYnRuLnRleHRDb250ZW50ID0gJ1x1MjcwNSc7XG4gICAgICAgICAgc2hvd05vdGlmaWNhdGlvbignVGVzdCBhbGVydCBzZW50IGZvciAnICsgYnRuLmRhdGFzZXQubmFtZSwgJ3N1Y2Nlc3MnLCAzMDAwKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGJ0bi50ZXh0Q29udGVudCA9ICdcdTI3NEMnO1xuICAgICAgICB9XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4geyBidG4udGV4dENvbnRlbnQgPSBvcmlnOyB9LCAyMDAwKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gV2lyZSB1cCB1cGdyYWRlIGJ1dHRvblxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cGdyYWRlLWZvci1hbGVydHMnKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICBtb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gICAgICBzdG9wQXV0b1JlZnJlc2goKTtcbiAgICAgIGlmICh0eXBlb2Ygb3BlbkxpY2Vuc2VNb2RhbCA9PT0gJ2Z1bmN0aW9uJykgb3BlbkxpY2Vuc2VNb2RhbCgpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gc3RhcnRBdXRvUmVmcmVzaCgpIHtcbiAgICBpZiAocmVmcmVzaEludGVydmFsKSBjbGVhckludGVydmFsKHJlZnJlc2hJbnRlcnZhbCk7XG4gICAgaWYgKGF1dG9SZWZyZXNoQ2hlY2tib3g/LmNoZWNrZWQpIHtcbiAgICAgIHJlZnJlc2hJbnRlcnZhbCA9IHNldEludGVydmFsKGxvYWRTdGF0cywgREMuUE9MTC5TVEFUUyk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc3RvcEF1dG9SZWZyZXNoKCkge1xuICAgIGlmIChyZWZyZXNoSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwocmVmcmVzaEludGVydmFsKTtcbiAgICAgIHJlZnJlc2hJbnRlcnZhbCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLy8gT3BlbiBtb2RhbFxuICBvcGVuQnRuPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBtb2RhbC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgbG9hZFN0YXRzKCk7XG4gICAgc3RhcnRBdXRvUmVmcmVzaCgpO1xuICB9KTtcblxuICAvLyBDbG9zZSBtb2RhbFxuICBjYW5jZWxCdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIG1vZGFsLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcbiAgICBzdG9wQXV0b1JlZnJlc2goKTtcbiAgfSk7XG5cbiAgbW9kYWw/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGUpID0+IHtcbiAgICBpZiAoZS50YXJnZXQgPT09IG1vZGFsKSB7XG4gICAgICBtb2RhbC5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gICAgICBzdG9wQXV0b1JlZnJlc2goKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJlZnJlc2hCdG4/LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgbG9hZFN0YXRzKTtcblxuICBhdXRvUmVmcmVzaENoZWNrYm94Py5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgaWYgKGF1dG9SZWZyZXNoQ2hlY2tib3guY2hlY2tlZCkgc3RhcnRBdXRvUmVmcmVzaCgpO1xuICAgIGVsc2Ugc3RvcEF1dG9SZWZyZXNoKCk7XG4gIH0pO1xuXG4gIC8vIExhenktbG9hZCB0YWJzXG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXBhbmVsPVwic3RhdHMtYWdncmVnYXRlZFwiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGxvYWRBZ2dyZWdhdGVkKTtcbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtcGFuZWw9XCJzdGF0cy1hbGVydHNcIl0nKT8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBsb2FkQWxlcnRzKTtcblxuICAvLyA9PT0gSGlzdG9yeSBUYWIgPT09XG4gIGNvbnN0IGhpc3RvcnlDb250YWluZXJTZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RhdHMtaGlzdG9yeS1jb250YWluZXInKTtcbiAgY29uc3QgaGlzdG9yeUFyZWEgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RhdHMtaGlzdG9yeS1jb250YWluZXItYXJlYScpO1xuICBjb25zdCByYW5nZUJ1dHRvbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuc3RhdHMtcmFuZ2UtYnRuJyk7XG5cbiAgbGV0IGN1cnJlbnRSYW5nZSA9ICcxaCc7XG5cbiAgZnVuY3Rpb24gcmFuZ2VUb01zKHJhbmdlKSB7XG4gICAgc3dpdGNoIChyYW5nZSkge1xuICAgICAgY2FzZSAnMWgnOiAgcmV0dXJuIDYwICogNjAgKiAxMDAwO1xuICAgICAgY2FzZSAnMjRoJzogcmV0dXJuIDI0ICogNjAgKiA2MCAqIDEwMDA7XG4gICAgICBjYXNlICc3ZCc6ICByZXR1cm4gNyAqIDI0ICogNjAgKiA2MCAqIDEwMDA7XG4gICAgICBjYXNlICczMGQnOiByZXR1cm4gMzAgKiAyNCAqIDYwICogNjAgKiAxMDAwO1xuICAgICAgY2FzZSAnMXknOiAgcmV0dXJuIDM2NSAqIDI0ICogNjAgKiA2MCAqIDEwMDA7XG4gICAgICBkZWZhdWx0OiAgICByZXR1cm4gNjAgKiA2MCAqIDEwMDA7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdGllckxhYmVsKHRpZXIpIHtcbiAgICBpZiAodGllciA9PT0gJ3JhdycpIHJldHVybiAnbGl2ZSAoMTBzIHNhbXBsZXMpJztcbiAgICBpZiAodGllciA9PT0gJ2hvdXJseScpIHJldHVybiAnaG91cmx5IGF2ZXJhZ2UnO1xuICAgIGlmICh0aWVyID09PSAnZGFpbHknKSByZXR1cm4gJ2RhaWx5IGF2ZXJhZ2UnO1xuICAgIHJldHVybiB0aWVyO1xuICB9XG5cbiAgLy8gU2ltcGxlIFNWRyBzcGFya2xpbmUgXHUyMDE0IG5vIGV4dGVybmFsIGxpYlxuICBmdW5jdGlvbiByZW5kZXJTcGFya2xpbmUoc2FtcGxlcywgYWNjZXNzb3IsIGNvbG9yLCBsYWJlbCwgdW5pdCkge1xuICAgIGlmICghc2FtcGxlcyB8fCBzYW1wbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGA8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBwYWRkaW5nOiAyMHB4O1wiPk5vIGRhdGEgZm9yICR7ZXNjYXBlSHRtbChsYWJlbCl9PC9kaXY+YDtcbiAgICB9XG4gICAgY29uc3QgdmFsdWVzID0gc2FtcGxlcy5tYXAoYWNjZXNzb3IpLmZpbHRlcih2ID0+IHYgIT0gbnVsbCk7XG4gICAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBgPGRpdiBzdHlsZT1cInRleHQtYWxpZ246IGNlbnRlcjsgY29sb3I6IHZhcigtLW11dGVkKTsgcGFkZGluZzogMjBweDtcIj5ObyBkYXRhIGZvciAke2VzY2FwZUh0bWwobGFiZWwpfTwvZGl2PmA7XG4gICAgfVxuICAgIGNvbnN0IG1heCA9IE1hdGgubWF4KC4uLnZhbHVlcywgMSk7XG4gICAgY29uc3QgbWluID0gTWF0aC5taW4oLi4udmFsdWVzLCAwKTtcbiAgICBjb25zdCByYW5nZSA9IG1heCAtIG1pbiB8fCAxO1xuICAgIGNvbnN0IHcgPSA2MDAsIGggPSA4MCwgcGFkID0gNDtcbiAgICBjb25zdCBzdGVwWCA9ICh3IC0gcGFkICogMikgLyBNYXRoLm1heCh2YWx1ZXMubGVuZ3RoIC0gMSwgMSk7XG4gICAgY29uc3QgcG9pbnRzID0gdmFsdWVzLm1hcCgodiwgaSkgPT4ge1xuICAgICAgY29uc3QgeCA9IHBhZCArIGkgKiBzdGVwWDtcbiAgICAgIGNvbnN0IHkgPSBoIC0gcGFkIC0gKCh2IC0gbWluKSAvIHJhbmdlKSAqIChoIC0gcGFkICogMik7XG4gICAgICByZXR1cm4gYCR7eC50b0ZpeGVkKDEpfSwke3kudG9GaXhlZCgxKX1gO1xuICAgIH0pLmpvaW4oJyAnKTtcbiAgICBjb25zdCBsYXN0ID0gdmFsdWVzW3ZhbHVlcy5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBhdmcgPSB2YWx1ZXMucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCkgLyB2YWx1ZXMubGVuZ3RoO1xuICAgIHJldHVybiBgXG4gICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTRweDtcIj5cbiAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBiYXNlbGluZTsgZ2FwOiAxMnB4OyBtYXJnaW4tYm90dG9tOiA0cHg7XCI+XG4gICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXdlaWdodDogNjAwOyBmb250LXNpemU6IDAuOXJlbTtcIj4ke2VzY2FwZUh0bWwobGFiZWwpfTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMC43NXJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj5sYXN0ICR7bGFzdC50b0ZpeGVkKDEpfSR7dW5pdH0gXHUwMEI3IGF2ZyAke2F2Zy50b0ZpeGVkKDEpfSR7dW5pdH0gXHUwMEI3IG1heCAke21heC50b0ZpeGVkKDEpfSR7dW5pdH08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8c3ZnIHZpZXdCb3g9XCIwIDAgJHt3fSAke2h9XCIgcHJlc2VydmVBc3BlY3RSYXRpbz1cIm5vbmVcIiBzdHlsZT1cIndpZHRoOiAxMDAlOyBoZWlnaHQ6ICR7aH1weDsgYmFja2dyb3VuZDogdmFyKC0tYmFzZSk7IGJvcmRlci1yYWRpdXM6IDRweDtcIj5cbiAgICAgICAgICA8cG9seWxpbmUgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIke2NvbG9yfVwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHBvaW50cz1cIiR7cG9pbnRzfVwiIC8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9kaXY+XG4gICAgYDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBvcHVsYXRlSGlzdG9yeUNvbnRhaW5lclNlbGVjdCgpIHtcbiAgICBpZiAoIWhpc3RvcnlDb250YWluZXJTZWxlY3QpIHJldHVybjtcbiAgICBjb25zdCBkYXRhID0gY2FjaGVkTW9uaXRvcmluZ0RhdGEgfHwge307XG4gICAgY29uc3QgcHJldmlvdXMgPSBoaXN0b3J5Q29udGFpbmVyU2VsZWN0LnZhbHVlO1xuICAgIGNvbnN0IGVudHJpZXMgPSBPYmplY3QuZW50cmllcyhkYXRhKTtcbiAgICBpZiAoZW50cmllcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGhpc3RvcnlDb250YWluZXJTZWxlY3QuaW5uZXJIVE1MID0gJzxvcHRpb24gdmFsdWU9XCJcIj5ObyBjb250YWluZXJzPC9vcHRpb24+JztcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaGlzdG9yeUNvbnRhaW5lclNlbGVjdC5pbm5lckhUTUwgPSBlbnRyaWVzXG4gICAgICAubWFwKChbaWQsIGluZm9dKSA9PiBgPG9wdGlvbiB2YWx1ZT1cIiR7ZXNjYXBlSHRtbChpZCl9XCI+JHtlc2NhcGVIdG1sKGluZm8ubmFtZSB8fCBpZCl9PC9vcHRpb24+YClcbiAgICAgIC5qb2luKCcnKTtcbiAgICBpZiAocHJldmlvdXMgJiYgZGF0YVtwcmV2aW91c10pIGhpc3RvcnlDb250YWluZXJTZWxlY3QudmFsdWUgPSBwcmV2aW91cztcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGxvYWRIaXN0b3J5KCkge1xuICAgIGlmICghaGlzdG9yeUFyZWEgfHwgIWhpc3RvcnlDb250YWluZXJTZWxlY3QpIHJldHVybjtcbiAgICBjb25zdCBjb250YWluZXJJZCA9IGhpc3RvcnlDb250YWluZXJTZWxlY3QudmFsdWU7XG4gICAgaWYgKCFjb250YWluZXJJZCkge1xuICAgICAgaGlzdG9yeUFyZWEuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1RENDQTwvc3Bhbj5ObyBjb250YWluZXIgc2VsZWN0ZWQuPC9kaXY+JztcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZW5kVGltZSA9IERhdGUubm93KCk7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gZW5kVGltZSAtIHJhbmdlVG9NcyhjdXJyZW50UmFuZ2UpO1xuICAgIGhpc3RvcnlBcmVhLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwicGFuZWwtZW1wdHlcIj48c3BhbiBjbGFzcz1cImJyYW5kLXNwaW5uZXJcIj48L3NwYW4+IExvYWRpbmcgaGlzdG9yeS4uLjwvZGl2Pic7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goYC9hcGkvdjEvbW9uaXRvcmluZy9oaXN0b3J5LyR7ZW5jb2RlVVJJQ29tcG9uZW50KGNvbnRhaW5lcklkKX0/c3RhcnRUaW1lPSR7c3RhcnRUaW1lfSZlbmRUaW1lPSR7ZW5kVGltZX1gKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHRocm93IG5ldyBFcnJvcihkYXRhLmVycm9yIHx8ICdGYWlsZWQgdG8gbG9hZCBoaXN0b3J5Jyk7XG5cbiAgICAgIGNvbnN0IHNhbXBsZXMgPSBkYXRhLnNhbXBsZXMgfHwgW107XG4gICAgICBjb25zdCB0aWVyID0gZGF0YS50aWVyIHx8ICdyYXcnO1xuXG4gICAgICBpZiAoc2FtcGxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaGlzdG9yeUFyZWEuaW5uZXJIVE1MID0gYDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1RENDQTwvc3Bhbj5ObyBkYXRhIGZvciB0aGUgbGFzdCAke2N1cnJlbnRSYW5nZX0uIFRpZXI6ICR7dGllckxhYmVsKHRpZXIpfS48L2Rpdj5gO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIERpZmZlcmVudCBzaGFwZSBiZXR3ZWVuIHJhdyB2cyByb2xsZWQtdXAgc2FtcGxlc1xuICAgICAgY29uc3QgaXNSYXcgPSB0aWVyID09PSAncmF3JztcbiAgICAgIGNvbnN0IGNwdUFjY2Vzc29yID0gaXNSYXcgPyAocykgPT4gcy5jcHU/LnBlcmNlbnQgOiAocykgPT4gcy5jcHU/LmF2ZztcbiAgICAgIGNvbnN0IG1lbUFjY2Vzc29yID0gaXNSYXcgPyAocykgPT4gcy5tZW1vcnk/LnBlcmNlbnQgOiAocykgPT4gcy5tZW1vcnk/LmF2Z1BlcmNlbnQ7XG4gICAgICBjb25zdCBuZXRSeEFjY2Vzc29yID0gaXNSYXcgPyAocykgPT4gKHMubmV0d29yaz8ucnhNQiB8fCAwKSA6IChzKSA9PiAocy5uZXR3b3JrPy5yeE1CIHx8IDApO1xuICAgICAgY29uc3QgbmV0VHhBY2Nlc3NvciA9IGlzUmF3ID8gKHMpID0+IChzLm5ldHdvcms/LnR4TUIgfHwgMCkgOiAocykgPT4gKHMubmV0d29yaz8udHhNQiB8fCAwKTtcblxuICAgICAgbGV0IGh0bWwgPSBgXG4gICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNzVyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi1ib3R0b206IDhweDtcIj5cbiAgICAgICAgICAke3NhbXBsZXMubGVuZ3RofSBzYW1wbGVzIFx1MDBCNyAke2VzY2FwZUh0bWwodGllckxhYmVsKHRpZXIpKX0gXHUwMEI3ICR7bmV3IERhdGUoc3RhcnRUaW1lKS50b0xvY2FsZVN0cmluZygpfSBcdTIxOTIgJHtuZXcgRGF0ZShlbmRUaW1lKS50b0xvY2FsZVN0cmluZygpfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIGA7XG4gICAgICBodG1sICs9IHJlbmRlclNwYXJrbGluZShzYW1wbGVzLCBjcHVBY2Nlc3NvciwgJyMyZWNjNzEnLCAnQ1BVJywgJyUnKTtcbiAgICAgIGh0bWwgKz0gcmVuZGVyU3BhcmtsaW5lKHNhbXBsZXMsIG1lbUFjY2Vzc29yLCAnIzM0OThkYicsICdNZW1vcnknLCAnJScpO1xuICAgICAgaHRtbCArPSByZW5kZXJTcGFya2xpbmUoc2FtcGxlcywgbmV0UnhBY2Nlc3NvciwgJyM5YjU5YjYnLCAnTmV0d29yayBSWCcsICcgTUInKTtcbiAgICAgIGh0bWwgKz0gcmVuZGVyU3BhcmtsaW5lKHNhbXBsZXMsIG5ldFR4QWNjZXNzb3IsICcjZTY3ZTIyJywgJ05ldHdvcmsgVFgnLCAnIE1CJyk7XG5cbiAgICAgIGhpc3RvcnlBcmVhLmlubmVySFRNTCA9IGh0bWw7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaGlzdG9yeUFyZWEuaW5uZXJIVE1MID0gYDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1MjZBMFx1RkUwRjwvc3Bhbj5GYWlsZWQgdG8gbG9hZCBoaXN0b3J5OiAke2VzY2FwZUh0bWwoZS5tZXNzYWdlKX08L2Rpdj5gO1xuICAgIH1cbiAgfVxuXG4gIHJhbmdlQnV0dG9ucy5mb3JFYWNoKGJ0biA9PiB7XG4gICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgcmFuZ2VCdXR0b25zLmZvckVhY2goYiA9PiBiLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpKTtcbiAgICAgIGJ0bi5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICAgIGN1cnJlbnRSYW5nZSA9IGJ0bi5kYXRhc2V0LnJhbmdlO1xuICAgICAgbG9hZEhpc3RvcnkoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaGlzdG9yeUNvbnRhaW5lclNlbGVjdD8uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgbG9hZEhpc3RvcnkpO1xuXG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXBhbmVsPVwic3RhdHMtaGlzdG9yeVwiXScpPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICBwb3B1bGF0ZUhpc3RvcnlDb250YWluZXJTZWxlY3QoKTtcbiAgICBsb2FkSGlzdG9yeSgpO1xuICB9KTtcbn0pKCk7XG47XG4vLyA9PT09PT09PT09IEhFQUxUSCBDSEVDSyBEQVNIQk9BUkQgPT09PT09PT09PVxuKGZ1bmN0aW9uKCkge1xuICAvLyBJbmplY3QgbW9kYWwgSFRNTFxuICBpbmplY3RNb2RhbCgnaGVhbHRoLW1vZGFsJywgYDxkaXYgaWQ9XCJoZWFsdGgtbW9kYWxcIiBjbGFzcz1cIndlYXRoZXItbW9kYWxcIj5cbiAgICA8ZGl2IGNsYXNzPVwid2VhdGhlci1tb2RhbC1jb250ZW50XCIgc3R5bGU9XCJtaW4td2lkdGg6IDgwMHB4OyBtYXgtd2lkdGg6IDEwMDBweDtcIj5cbiAgICAgIDxoMz5cdUQ4M0NcdURGRTUgSGVhbHRoIENoZWNrIERhc2hib2FyZDwvaDM+XG4gICAgICA8cCBjbGFzcz1cIm1vZGFsLXN1YnRpdGxlXCI+XG4gICAgICAgIFNlcnZpY2UgdXB0aW1lIHRyYWNraW5nLCBTTEEgbW9uaXRvcmluZywgYW5kIGluY2lkZW50IG1hbmFnZW1lbnQuXG4gICAgICA8L3A+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC10YWJzXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWIgYWN0aXZlXCIgZGF0YS1wYW5lbD1cImhlYWx0aC1zdGF0dXNcIj5TdGF0dXM8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInBhbmVsLXRhYlwiIGRhdGEtcGFuZWw9XCJoZWFsdGgtaW5jaWRlbnRzXCI+SW5jaWRlbnRzPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJwYW5lbC10YWJcIiBkYXRhLXBhbmVsPVwiaGVhbHRoLWNvbmZpZ1wiPkNvbmZpZ3VyZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gVGFiOiBTdGF0dXMgLS0+XG4gICAgICA8ZGl2IGlkPVwiaGVhbHRoLXN0YXR1c1wiIGNsYXNzPVwicGFuZWwtc2VjdGlvbiBhY3RpdmVcIj5cbiAgICAgICAgPGRpdiBpZD1cImhlYWx0aC1zdGF0dXMtY29udGFpbmVyXCIgY2xhc3M9XCJzY3JvbGwtY29udGFpbmVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWVtcHR5XCI+PHNwYW4gY2xhc3M9XCJicmFuZC1zcGlubmVyXCI+PC9zcGFuPiBMb2FkaW5nIGhlYWx0aCBzdGF0dXMuLi48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IEluY2lkZW50cyAtLT5cbiAgICAgIDxkaXYgaWQ9XCJoZWFsdGgtaW5jaWRlbnRzXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJoZWFsdGgtaW5jaWRlbnRzLWNvbnRhaW5lclwiIGNsYXNzPVwic2Nyb2xsLWNvbnRhaW5lclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1RDgzRFx1REVBODwvc3Bhbj4gTG9hZGluZyBpbmNpZGVudHMuLi48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUYWI6IENvbmZpZ3VyZSAtLT5cbiAgICAgIDxkaXYgaWQ9XCJoZWFsdGgtY29uZmlnXCIgY2xhc3M9XCJwYW5lbC1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJoZWFsdGgtY29uZmlnLWNvbnRhaW5lclwiIGNsYXNzPVwic2Nyb2xsLWNvbnRhaW5lclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1lbXB0eVwiPjxzcGFuIGNsYXNzPVwiZW1wdHktaWNvblwiPlx1MjY5OVx1RkUwRjwvc3Bhbj4gTG9hZGluZyBjb25maWd1cmF0aW9uLi4uPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gR2xvYmFsIFNldHRpbmdzOiByZXRlbnRpb24sIHBvbGxpbmcgaW50ZXJ2YWwsIGRpc2stdXNhZ2UgdGhyZXNob2xkIC0tPlxuICAgICAgICA8ZGl2IGlkPVwiaGVhbHRoLWdsb2JhbC1zZXR0aW5nc1wiIHN0eWxlPVwibWFyZ2luLXRvcDogMTZweDsgcGFkZGluZzogMTZweDsgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTsgYm9yZGVyLXJhZGl1czogdmFyKC0tcmFkaXVzKTsgYmFja2dyb3VuZDogdmFyKC0tY2FyZC1iYXNlKTtcIj5cbiAgICAgICAgICA8aDQgc3R5bGU9XCJtYXJnaW46IDAgMCA0cHg7XCI+XHVEODNDXHVERjBEIEdsb2JhbCBTZXR0aW5nczwvaDQ+XG4gICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LW11dGVkLXNtXCIgc3R5bGU9XCJtYXJnaW46IDAgMCAxMnB4O1wiPkFwcGxpZXMgdG8gYWxsIGhlYWx0aCBjaGVja3MuIFNldHRpbmdzIGFyZSBzdG9yZWQgbG9jYWxseSBpbiB0aGlzIGJyb3dzZXIuPC9wPlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBncmlkOyBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDFmciAxZnIgMWZyOyBnYXA6IDEycHg7XCI+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LW11dGVkLXNtXCI+RGF0YSBSZXRlbnRpb24gKGRheXMpPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBpZD1cImhlYWx0aC1zZXR0aW5nLXJldGVudGlvblwiIHZhbHVlPVwiMzBcIiBtaW49XCIxXCIgbWF4PVwiMzY1MFwiIGNsYXNzPVwiZm9ybS1pbnB1dFwiIC8+XG4gICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDAuNzJyZW07IGNvbG9yOiB2YXIoLS1tdXRlZCk7IG1hcmdpbi10b3A6IDJweDtcIj5IZWFsdGggaGlzdG9yeSBvbGRlciB0aGFuIHRoaXMgaXMgcHJ1bmVkLjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LW11dGVkLXNtXCI+UG9sbGluZyBJbnRlcnZhbCAoc2Vjb25kcyk8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGlkPVwiaGVhbHRoLXNldHRpbmctaW50ZXJ2YWxcIiB2YWx1ZT1cIjMwXCIgbWluPVwiNVwiIG1heD1cIjM2MDBcIiBjbGFzcz1cImZvcm0taW5wdXRcIiAvPlxuICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAwLjcycmVtOyBjb2xvcjogdmFyKC0tbXV0ZWQpOyBtYXJnaW4tdG9wOiAycHg7XCI+SG93IG9mdGVuIGVhY2ggc2VydmljZSBpcyBjaGVja2VkLjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LW11dGVkLXNtXCI+RGlzay1Vc2FnZSBXYXJuaW5nICglKTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgaWQ9XCJoZWFsdGgtc2V0dGluZy1kaXNrLXRocmVzaG9sZFwiIHZhbHVlPVwiODBcIiBtaW49XCI1MFwiIG1heD1cIjk5XCIgY2xhc3M9XCJmb3JtLWlucHV0XCIgLz5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZTogMC43MnJlbTsgY29sb3I6IHZhcigtLW11dGVkKTsgbWFyZ2luLXRvcDogMnB4O1wiPldhcm4gd2hlbiBkaXNrIHVzYWdlIGV4Y2VlZHMgdGhpcyBsZXZlbC48L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tdG9wOiAxMnB4OyBkaXNwbGF5OiBmbGV4OyBnYXA6IDhweDsgYWxpZ24taXRlbXM6IGNlbnRlcjtcIj5cbiAgICAgICAgICAgIDxidXR0b24gaWQ9XCJoZWFsdGgtZ2xvYmFsLXNhdmVcIiBjbGFzcz1cImJ0bi1hY2NlbnQtc29saWRcIj5TYXZlIEdsb2JhbCBTZXR0aW5nczwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBpZD1cImhlYWx0aC1nbG9iYWwtcmVzZXRcIiBjbGFzcz1cImJ0bi1zbVwiPlJlc2V0IHRvIERlZmF1bHRzPC9idXR0b24+XG4gICAgICAgICAgICA8c3BhbiBpZD1cImhlYWx0aC1nbG9iYWwtc3RhdHVzXCIgc3R5bGU9XCJmb250LXNpemU6IDAuOHJlbTsgY29sb3I6IHZhcigtLW11dGVkKTtcIj48L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gQWRkL0VkaXQgSGVhbHRoIENoZWNrIEZvcm0gLS0+XG4gICAgICAgIDxkaXYgaWQ9XCJoZWFsdGgtY29uZmlnLWZvcm1cIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7IG1hcmdpbi10b3A6IDE2cHg7IHBhZGRpbmc6IDE2cHg7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7IGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cyk7IGJhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSk7XCI+XG4gICAgICAgICAgPGg0IGlkPVwiaGVhbHRoLWZvcm0tdGl0bGVcIiBzdHlsZT1cIm1hcmdpbjogMCAwIDEycHg7XCI+QWRkIEhlYWx0aCBDaGVjazwvaDQ+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGdyaWQ7IGdyaWQtdGVtcGxhdGUtY29sdW1uczogMWZyIDFmcjsgZ2FwOiAxMnB4O1wiPlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1tdXRlZC1zbVwiPlNlcnZpY2UgSUQ8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cImhlYWx0aC1mb3JtLWlkXCIgcGxhY2Vob2xkZXI9XCJlLmcuIHBsZXhcIiBjbGFzcz1cImZvcm0taW5wdXRcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LW11dGVkLXNtXCI+RGlzcGxheSBOYW1lPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJoZWFsdGgtZm9ybS1uYW1lXCIgcGxhY2Vob2xkZXI9XCJlLmcuIFBsZXggTWVkaWEgU2VydmVyXCIgY2xhc3M9XCJmb3JtLWlucHV0XCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cImdyaWQtY29sdW1uOiBzcGFuIDI7XCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtbXV0ZWQtc21cIj5VUkw8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBpZD1cImhlYWx0aC1mb3JtLXVybFwiIHBsYWNlaG9sZGVyPVwiaHR0cHM6Ly9wbGV4LmhvbWVcIiBjbGFzcz1cImZvcm0taW5wdXRcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LW11dGVkLXNtXCI+VGltZW91dCAobXMpPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBpZD1cImhlYWx0aC1mb3JtLXRpbWVvdXRcIiB2YWx1ZT1cIjEwMDAwXCIgY2xhc3M9XCJmb3JtLWlucHV0XCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1tdXRlZC1zbVwiPkV4cGVjdGVkIFN0YXR1cyBDb2RlczwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwiaGVhbHRoLWZvcm0tY29kZXNcIiB2YWx1ZT1cIjIwMFwiIHBsYWNlaG9sZGVyPVwiMjAwLCAzMDEsIDMwMlwiIGNsYXNzPVwiZm9ybS1pbnB1dFwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtbXV0ZWQtc21cIj5TTEEgVGFyZ2V0ICglKTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgaWQ9XCJoZWFsdGgtZm9ybS1zbGFcIiB2YWx1ZT1cIjk5LjlcIiBzdGVwPVwiMC4xXCIgY2xhc3M9XCJmb3JtLWlucHV0XCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1tdXRlZC1zbVwiPlNsb3cgUmVzcG9uc2UgVGhyZXNob2xkIChtcyk8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGlkPVwiaGVhbHRoLWZvcm0tc2xvd1wiIHZhbHVlPVwiNTAwMFwiIGNsYXNzPVwiZm9ybS1pbnB1dFwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogMTJweDsgZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7IGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XCI+XG4gICAgICAgICAgICA8YnV0dG9uIGlkPVwiaGVhbHRoLWZvcm0tY2FuY2VsXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGlkPVwiaGVhbHRoLWZvcm0tc2F2ZVwiIGNsYXNzPVwiYnRuLWFjY2VudC1zb2xpZFwiPlNhdmU8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDEycHg7XCI+XG4gICAgICAgICAgPGJ1dHRvbiBpZD1cImhlYWx0aC1hZGQtYnRuXCIgY2xhc3M9XCJidG4tYWNjZW50LXNvbGlkXCI+KyBBZGQgSGVhbHRoIENoZWNrPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1ib3R0b20tYmFyXCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJoZWFsdGgtcmVmcmVzaC1idG5cIiBjbGFzcz1cImJ0bi1zbVwiPlx1RDgzRFx1REQwNCBSZWZyZXNoPC9idXR0b24+XG4gICAgICAgIDxzcGFuIGlkPVwiaGVhbHRoLWxhc3QtdXBkYXRlXCIgY2xhc3M9XCJ0ZXh0LWF1dG8tcmlnaHRcIj48L3NwYW4+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cIndlYXRoZXItbW9kYWwtYnV0dG9ucyBtb2RhbC1mb290ZXItYmFyXCI+XG4gICAgICAgIDxidXR0b24gaWQ9XCJoZWFsdGgtY2FuY2VsXCI+Q2xvc2U8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5gKTtcblxuICBjb25zdCBtb2RhbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtbW9kYWwnKTtcbiAgY29uc3Qgb3BlbkJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtY2hlY2stYnRuJyk7XG4gIGNvbnN0IGNhbmNlbEJ0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtY2FuY2VsJyk7XG4gIGNvbnN0IHJlZnJlc2hCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLXJlZnJlc2gtYnRuJyk7XG4gIGNvbnN0IHN0YXR1c0NvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtc3RhdHVzLWNvbnRhaW5lcicpO1xuICBjb25zdCBpbmNpZGVudHNDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWluY2lkZW50cy1jb250YWluZXInKTtcbiAgY29uc3QgY29uZmlnQ29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1jb25maWctY29udGFpbmVyJyk7XG4gIGNvbnN0IGxhc3RVcGRhdGVTcGFuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1sYXN0LXVwZGF0ZScpO1xuICBjb25zdCBhZGRCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWFkZC1idG4nKTtcbiAgY29uc3QgZm9ybUVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1jb25maWctZm9ybScpO1xuICBjb25zdCBmb3JtVGl0bGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWZvcm0tdGl0bGUnKTtcbiAgY29uc3QgZm9ybUNhbmNlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtZm9ybS1jYW5jZWwnKTtcbiAgY29uc3QgZm9ybVNhdmUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWZvcm0tc2F2ZScpO1xuXG4gIC8vIC0tLS0gR2xvYmFsIGhlYWx0aCBzZXR0aW5ncyAocmV0ZW50aW9uLCBwb2xsaW5nIGludGVydmFsLCBkaXNrIHRocmVzaG9sZCkgLS0tLVxuICBjb25zdCBIRUFMVEhfU0VUVElOR1NfS0VZID0gJ2Rhc2hjYWRkeS1oZWFsdGgtc2V0dGluZ3MnO1xuICBjb25zdCBIRUFMVEhfREVGQVVMVFMgPSB7IHJldGVudGlvbkRheXM6IDMwLCBwb2xsaW5nSW50ZXJ2YWw6IDMwLCBkaXNrVXNhZ2VUaHJlc2hvbGQ6IDgwIH07XG4gIGNvbnN0IGdsb2JhbFNhdmVCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLWdsb2JhbC1zYXZlJyk7XG4gIGNvbnN0IGdsb2JhbFJlc2V0QnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hlYWx0aC1nbG9iYWwtcmVzZXQnKTtcbiAgY29uc3QgZ2xvYmFsU3RhdHVzU3BhbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtZ2xvYmFsLXN0YXR1cycpO1xuICBjb25zdCByZXRlbnRpb25JbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtc2V0dGluZy1yZXRlbnRpb24nKTtcbiAgY29uc3QgaW50ZXJ2YWxJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFsdGgtc2V0dGluZy1pbnRlcnZhbCcpO1xuICBjb25zdCBkaXNrVGhyZXNob2xkSW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhbHRoLXNldHRpbmctZGlzay10aHJlc2hvbGQnKTtcblxuICBmdW5jdGlvbiBsb2FkSGVhbHRoU2V0dGluZ3MoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhdyA9IHNhZmVHZXQoSEVBTFRIX1NFVFRJTkdTX0tFWSk7XG4gICAgICBjb25zdCBzYXZlZCA9IHJhdyA/IEpTT04ucGFyc2UocmF3KSA6IHt9O1xuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIEhFQUxUSF9ERUZBVUxUUywgc2F2ZWQpO1xuICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBIRUFMVEhfREVGQVVMVFMpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGFwcGx5SGVhbHRoU2V0dGluZ3NUb1VJKCkge1xuICAgIGNvbnN0IHMgPSBsb2FkSGVhbHRoU2V0dGluZ3MoKTtcbiAgICBpZiAocmV0ZW50aW9uSW5wdXQpIHJldGVudGlvbklucHV0LnZhbHVlID0gcy5yZXRlbnRpb25EYXlzO1xuICAgIGlmIChpbnRlcnZhbElucHV0KSBpbnRlcnZhbElucHV0LnZhbHVlID0gcy5wb2xsaW5nSW50ZXJ2YWw7XG4gICAgaWYgKGRpc2tUaHJlc2hvbGRJbnB1dCkgZGlza1RocmVzaG9sZElucHV0LnZhbHVlID0gcy5kaXNrVXNhZ2VUaHJlc2hvbGQ7XG4gIH1cblxuICBmdW5jdGlvbiBzYXZlSGVhbHRoU2V0dGluZ3MoKSB7XG4gICAgY29uc3Qgc2V0dGluZ3MgPSB7XG4gICAgICByZXRlbnRpb25EYXlzOiBNYXRoLm1heCgxLCBNYXRoLm1pbigzNjUwLCBwYXJzZUludChyZXRlbnRpb25JbnB1dD8udmFsdWUpIHx8IEhFQUxUSF9ERUZBVUxUUy5yZXRlbnRpb25EYXlzKSksXG4gICAgICBwb2xsaW5nSW50ZXJ2YWw6IE1hdGgubWF4KDUsIE1hdGgubWluKDM2MDAsIHBhcnNlSW50KGludGVydmFsSW5wdXQ/LnZhbHVlKSB8fCBIRUFMVEhfREVGQVVMVFMucG9sbGluZ0ludGVydmFsKSksXG4gICAgICBkaXNrVXNhZ2VUaHJlc2hvbGQ6IE1hdGgubWF4KDUwLCBNYXRoLm1pbig5OSwgcGFyc2VJbnQoZGlza1RocmVzaG9sZElucHV0Py52YWx1ZSkgfHwgSEVBTFRIX0RFRkFVTFRTLmRpc2tVc2FnZVRocmVzaG9sZCkpXG4gICAgfTtcbiAgICB0cnkge1xuICAgICAgc2FmZVNldChIRUFMVEhfU0VUVElOR1NfS0VZLCBKU09OLnN0cmluZ2lmeShzZXR0aW5ncykpO1xuICAgICAgYXBwbHlIZWFsdGhTZXR0aW5nc1RvVUkoKTtcbiAgICAgIGlmIChnbG9iYWxTdGF0dXNTcGFuKSB7XG4gICAgICAgIGdsb2JhbFN0YXR1c1NwYW4udGV4dENvbnRlbnQgPSAnU2F2ZWQgXHUyNzEzJztcbiAgICAgICAgZ2xvYmFsU3RhdHVzU3Bhbi5zdHlsZS5jb2xvciA9ICd2YXIoLS1vay1mZyknO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+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+IHsgaXNzdWVkQ29weUJ0bi50ZXh0Q29udGVudCA9IG9yaWdpbmFsOyB9LCAxMjAwKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzaG93RXJyb3IoJ0NvdWxkIG5vdCBjb3B5IHRvIGNsaXBib2FyZC4gU2VsZWN0IHRoZSBVUkwgbWFudWFsbHkuJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBFeHBvc2UgZm9yIG90aGVyIG1vZHVsZXMgdG8gb3BlblxuICB3aW5kb3cub3BlblNoYXJlTW9kYWwgPSBvcGVuU2hhcmVNb2RhbDtcbn0pKCk7XG47XG4vKipcbiAqIERDLTA3NzogaTE4biBGcm9udGVuZCBcdTIwMTQgTGFuZ3VhZ2Ugc2VsZWN0b3IgYW5kIHRyYW5zbGF0aW9uIHN5c3RlbVxuICogXG4gKiBQcm92aWRlcyB3aW5kb3cuRENJMThuLnQoa2V5KSBmb3IgdGhlIGRhc2hib2FyZCBmcm9udGVuZC5cbiAqIExvYWRzIHRyYW5zbGF0aW9ucyBmcm9tIC9hcGkvdjEvaTE4bi90cmFuc2xhdGlvbnMvOmxhbmdcbiAqIExhbmd1YWdlIHByZWZlcmVuY2Ugc3RvcmVkIGluIGxvY2FsU3RvcmFnZS5cbiAqIEhhbmRsZXMgUlRMIGZvciBBcmFiaWMuXG4gKi9cbihmdW5jdGlvbiAoKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICBjb25zdCBTVE9SQUdFX0tFWSA9ICdkYXNoY2FkZHktbGFuZ3VhZ2UnO1xuICBjb25zdCBERUZBVUxUX0xBTkcgPSAnZW4nO1xuICBjb25zdCBTVVBQT1JURURfTEFOR1MgPSBbJ2VuJywgJ2VzJywgJ2ZyJywgJ2RlJywgJ2FyJ107XG4gIGNvbnN0IExBTkdfTkFNRVMgPSB7XG4gICAgZW46ICdFbmdsaXNoJywgZXM6ICdFc3BhXHUwMEYxb2wnLCBmcjogJ0ZyYW5cdTAwRTdhaXMnLCBkZTogJ0RldXRzY2gnLCBhcjogJ1x1MDYyN1x1MDY0NFx1MDYzOVx1MDYzMVx1MDYyOFx1MDY0QVx1MDYyOScsXG4gIH07XG5cbiAgbGV0IGN1cnJlbnRMYW5nID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oU1RPUkFHRV9LRVkpIHx8IERFRkFVTFRfTEFORztcbiAgbGV0IHRyYW5zbGF0aW9ucyA9IHt9O1xuICBsZXQgbG9hZGVkID0gZmFsc2U7XG5cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZFRyYW5zbGF0aW9ucyhsYW5nKSB7XG4gICAgaWYgKGxhbmcgPT09IERFRkFVTFRfTEFORykge1xuICAgICAgdHJhbnNsYXRpb25zID0ge307IC8vIEVuZ2xpc2ggaXMgdGhlIGRlZmF1bHQgXHUyMDE0IG5vIHRyYW5zbGF0aW9uIG5lZWRlZFxuICAgICAgbG9hZGVkID0gdHJ1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKGAvYXBpL3YxL2kxOG4vdHJhbnNsYXRpb25zLyR7bGFuZ31gKTtcbiAgICAgIGlmIChyZXMub2spIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgICAgIHRyYW5zbGF0aW9ucyA9IGRhdGEudHJhbnNsYXRpb25zIHx8IHt9O1xuICAgICAgICBsb2FkZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUud2FybignW2kxOG5dIEZhaWxlZCB0byBsb2FkIHRyYW5zbGF0aW9ucyBmb3InLCBsYW5nLCBlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0KGtleSkge1xuICAgIGlmIChjdXJyZW50TGFuZyA9PT0gREVGQVVMVF9MQU5HKSByZXR1cm4ga2V5O1xuICAgIHJldHVybiB0cmFuc2xhdGlvbnNba2V5XSB8fCBrZXk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRMYW5ndWFnZShsYW5nKSB7XG4gICAgaWYgKCFTVVBQT1JURURfTEFOR1MuaW5jbHVkZXMobGFuZykpIHJldHVybjtcbiAgICBjdXJyZW50TGFuZyA9IGxhbmc7XG4gICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oU1RPUkFHRV9LRVksIGxhbmcpO1xuXG4gICAgLy8gUlRMIGhhbmRsaW5nXG4gICAgY29uc3QgaXNSdGwgPSBsYW5nID09PSAnYXInO1xuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5kaXIgPSBpc1J0bCA/ICdydGwnIDogJ2x0cic7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmxhbmcgPSBsYW5nO1xuXG4gICAgbG9hZFRyYW5zbGF0aW9ucyhsYW5nKS50aGVuKCgpID0+IHtcbiAgICAgIGFwcGx5VHJhbnNsYXRpb25zKCk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRMYW5ndWFnZSgpIHtcbiAgICByZXR1cm4gY3VycmVudExhbmc7XG4gIH1cblxuICBmdW5jdGlvbiBhcHBseVRyYW5zbGF0aW9ucygpIHtcbiAgICAvLyBBcHBseSB0cmFuc2xhdGlvbnMgdG8gZWxlbWVudHMgd2l0aCBkYXRhLWkxOG4gYXR0cmlidXRlc1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWkxOG5dJykuZm9yRWFjaChlbCA9PiB7XG4gICAgICBjb25zdCBrZXkgPSBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaTE4bicpO1xuICAgICAgY29uc3QgdHJhbnNsYXRlZCA9IHQoa2V5KTtcbiAgICAgIGlmICh0cmFuc2xhdGVkICYmIHRyYW5zbGF0ZWQgIT09IGtleSkge1xuICAgICAgICBlbC50ZXh0Q29udGVudCA9IHRyYW5zbGF0ZWQ7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gQXBwbHkgdG8gcGxhY2Vob2xkZXJzXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW2RhdGEtaTE4bi1wbGFjZWhvbGRlcl0nKS5mb3JFYWNoKGVsID0+IHtcbiAgICAgIGNvbnN0IGtleSA9IGVsLmdldEF0dHJpYnV0ZSgnZGF0YS1pMThuLXBsYWNlaG9sZGVyJyk7XG4gICAgICBjb25zdCB0cmFuc2xhdGVkID0gdChrZXkpO1xuICAgICAgaWYgKHRyYW5zbGF0ZWQgJiYgdHJhbnNsYXRlZCAhPT0ga2V5KSB7XG4gICAgICAgIGVsLnBsYWNlaG9sZGVyID0gdHJhbnNsYXRlZDtcbiAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBBcHBseSB0byB0aXRsZXNcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS1pMThuLXRpdGxlXScpLmZvckVhY2goZWwgPT4ge1xuICAgICAgY29uc3Qga2V5ID0gZWwuZ2V0QXR0cmlidXRlKCdkYXRhLWkxOG4tdGl0bGUnKTtcbiAgICAgIGNvbnN0IHRyYW5zbGF0ZWQgPSB0KGtleSk7XG4gICAgICBpZiAodHJhbnNsYXRlZCAmJiB0cmFuc2xhdGVkICE9PSBrZXkpIHtcbiAgICAgICAgZWwudGl0bGUgPSB0cmFuc2xhdGVkO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlTGFuZ3VhZ2VTZWxlY3RvcigpIHtcbiAgICAvLyBGaW5kIHRoZSB0b3AgYmFyIGFyZWEgdG8gaW5zZXJ0IHRoZSBzZWxlY3RvclxuICAgIC8vIExvb2sgZm9yIHRoZSBhdXRoLXNldHRpbmdzIGFyZWEgb3IgdGhlIGhlYWRlciBhY3Rpb25zXG4gICAgY29uc3QgdGFyZ2V0Q29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmhlYWRlci1hY3Rpb25zJykgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYXV0aC1zZXR0aW5ncy1idG4nKT8ucGFyZW50RWxlbWVudCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy50b3AtYmFyLWFjdGlvbnMnKTtcblxuICAgIGlmICghdGFyZ2V0Q29udGFpbmVyKSB7XG4gICAgICAvLyBJZiB3ZSBjYW4ndCBmaW5kIGEgdGFyZ2V0LCB0cnkgdG8gYWRkIGl0IG5lYXIgdGhlIHNldHRpbmdzIGJ1dHRvblxuICAgICAgY29uc3Qgc2V0dGluZ3NCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXV0aC1zZXR0aW5ncy1idG4nKTtcbiAgICAgIGlmIChzZXR0aW5nc0J0biAmJiBzZXR0aW5nc0J0bi5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVEcm9wZG93bihzZXR0aW5nc0J0bi5wYXJlbnRFbGVtZW50KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBjcmVhdGVEcm9wZG93bih0YXJnZXRDb250YWluZXIpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlRHJvcGRvd24oY29udGFpbmVyKSB7XG4gICAgLy8gQ2hlY2sgaWYgc2VsZWN0b3IgYWxyZWFkeSBleGlzdHNcbiAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RjLWxhbmctc2VsZWN0b3InKSkgcmV0dXJuO1xuXG4gICAgY29uc3Qgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHdyYXBwZXIuaWQgPSAnZGMtbGFuZy1zZWxlY3Rvcic7XG4gICAgd3JhcHBlci5zdHlsZS5jc3NUZXh0ID0gJ2Rpc3BsYXk6IGlubGluZS1mbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDRweDsgbWFyZ2luOiAwIDhweDsgcG9zaXRpb246IHJlbGF0aXZlOyc7XG5cbiAgICBjb25zdCBidG4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICBidG4uaWQgPSAnZGMtbGFuZy1idG4nO1xuICAgIGJ0bi5jbGFzc05hbWUgPSAnbGFuZy1zZWxlY3Rvci1idG4nO1xuICAgIGJ0bi5zdHlsZS5jc3NUZXh0ID0gJ2JhY2tncm91bmQ6IHZhcigtLWNhcmQtYmFzZSwgIzJhMmEzZSk7IGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlciwgIzNhM2E0ZSk7IGNvbG9yOiB2YXIoLS10ZXh0LXByaW1hcnksICNlMGUwZTApOyBwYWRkaW5nOiA2cHggMTBweDsgYm9yZGVyLXJhZGl1czogNnB4OyBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtc2l6ZTogMC44cmVtOyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDRweDsnO1xuICAgIGJ0bi5pbm5lckhUTUwgPSBgXHVEODNDXHVERjEwIDxzcGFuIGNsYXNzPVwibGFuZy1jdXJyZW50XCI+JHtjdXJyZW50TGFuZy50b1VwcGVyQ2FzZSgpfTwvc3Bhbj5gO1xuICAgIGJ0bi50aXRsZSA9ICdMYW5ndWFnZSAvIElkaW9tYSAvIExhbmd1ZSAvIFNwcmFjaGUgLyBcdTA2MjdcdTA2NDRcdTA2NDRcdTA2M0FcdTA2MjknO1xuXG4gICAgY29uc3QgZHJvcGRvd24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkcm9wZG93bi5pZCA9ICdkYy1sYW5nLWRyb3Bkb3duJztcbiAgICBkcm9wZG93bi5zdHlsZS5jc3NUZXh0ID0gJ2Rpc3BsYXk6IG5vbmU7IHBvc2l0aW9uOiBhYnNvbHV0ZTsgdG9wOiAxMDAlOyByaWdodDogMDsgbWFyZ2luLXRvcDogNHB4OyBiYWNrZ3JvdW5kOiB2YXIoLS1jYXJkLWJhc2UsICMyYTJhM2UpOyBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIsICMzYTNhNGUpOyBib3JkZXItcmFkaXVzOiA4cHg7IGJveC1zaGFkb3c6IDAgNHB4IDEycHggcmdiYSgwLDAsMCwwLjMpOyB6LWluZGV4OiA5OTk5OyBtaW4td2lkdGg6IDE0MHB4OyBvdmVyZmxvdzogaGlkZGVuOyc7XG5cbiAgICBTVVBQT1JURURfTEFOR1MuZm9yRWFjaChsYW5nID0+IHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGl0ZW0uY2xhc3NOYW1lID0gJ2xhbmctb3B0aW9uJztcbiAgICAgIGl0ZW0uc3R5bGUuY3NzVGV4dCA9ICdwYWRkaW5nOiA4cHggMTRweDsgY3Vyc29yOiBwb2ludGVyOyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDsgZm9udC1zaXplOiAwLjg1cmVtOyBjb2xvcjogdmFyKC0tdGV4dC1wcmltYXJ5LCAjZTBlMGUwKTsnO1xuICAgICAgaXRlbS5vbm1vdXNlZW50ZXIgPSAoKSA9PiBpdGVtLnN0eWxlLmJhY2tncm91bmQgPSAndmFyKC0tY2FyZC1ob3ZlciwgcmdiYSgyNTUsMjU1LDI1NSwwLjA1KSknO1xuICAgICAgaXRlbS5vbm1vdXNlbGVhdmUgPSAoKSA9PiBpdGVtLnN0eWxlLmJhY2tncm91bmQgPSAndHJhbnNwYXJlbnQnO1xuXG4gICAgICBjb25zdCBmbGFnID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgZmxhZy50ZXh0Q29udGVudCA9IGxhbmcgPT09IGN1cnJlbnRMYW5nID8gJ1x1MjcxMycgOiAnJztcbiAgICAgIGZsYWcuc3R5bGUuY3NzVGV4dCA9ICd3aWR0aDogMTZweDsgY29sb3I6IHZhcigtLW9rLWZnLCAjNGFkZTgwKTsnO1xuXG4gICAgICBjb25zdCBuYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgbmFtZS50ZXh0Q29udGVudCA9IExBTkdfTkFNRVNbbGFuZ107XG5cbiAgICAgIGl0ZW0uYXBwZW5kQ2hpbGQoZmxhZyk7XG4gICAgICBpdGVtLmFwcGVuZENoaWxkKG5hbWUpO1xuICAgICAgaXRlbS5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICBzZXRMYW5ndWFnZShsYW5nKTtcbiAgICAgICAgZHJvcGRvd24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgLy8gVXBkYXRlIGJ1dHRvbiB0ZXh0XG4gICAgICAgIGJ0bi5xdWVyeVNlbGVjdG9yKCcubGFuZy1jdXJyZW50JykudGV4dENvbnRlbnQgPSBsYW5nLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgIC8vIFVwZGF0ZSBjaGVja21hcmtzXG4gICAgICAgIGRyb3Bkb3duLnF1ZXJ5U2VsZWN0b3JBbGwoJy5sYW5nLW9wdGlvbicpLmZvckVhY2goKG9wdCwgaSkgPT4ge1xuICAgICAgICAgIG9wdC5xdWVyeVNlbGVjdG9yKCdzcGFuJykudGV4dENvbnRlbnQgPSBTVVBQT1JURURfTEFOR1NbaV0gPT09IGxhbmcgPyAnXHUyNzEzJyA6ICcnO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gU2hvdyBub3RpZmljYXRpb25cbiAgICAgICAgaWYgKHdpbmRvdy5zaG93Tm90aWZpY2F0aW9uKSB7XG4gICAgICAgICAgd2luZG93LnNob3dOb3RpZmljYXRpb24oYExhbmd1YWdlOiAke0xBTkdfTkFNRVNbbGFuZ119YCwgJ2luZm8nKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGRyb3Bkb3duLmFwcGVuZENoaWxkKGl0ZW0pO1xuICAgIH0pO1xuXG4gICAgYnRuLm9uY2xpY2sgPSAoZSkgPT4ge1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGRyb3Bkb3duLnN0eWxlLmRpc3BsYXkgPSBkcm9wZG93bi5zdHlsZS5kaXNwbGF5ID09PSAnbm9uZScgPyAnYmxvY2snIDogJ25vbmUnO1xuICAgIH07XG5cbiAgICAvLyBDbG9zZSBvbiBvdXRzaWRlIGNsaWNrXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgaWYgKCF3cmFwcGVyLmNvbnRhaW5zKGUudGFyZ2V0KSkge1xuICAgICAgICBkcm9wZG93bi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgd3JhcHBlci5hcHBlbmRDaGlsZChidG4pO1xuICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQoZHJvcGRvd24pO1xuICAgIGNvbnRhaW5lci5pbnNlcnRCZWZvcmUod3JhcHBlciwgY29udGFpbmVyLmZpcnN0Q2hpbGQpO1xuXG4gICAgcmV0dXJuIHdyYXBwZXI7XG4gIH1cblxuICAvLyBJbml0aWFsaXplIG9uIHBhZ2UgbG9hZFxuICBmdW5jdGlvbiBpbml0KCkge1xuICAgIC8vIFNldCBpbml0aWFsIFJUTCBpZiBuZWVkZWRcbiAgICBpZiAoY3VycmVudExhbmcgPT09ICdhcicpIHtcbiAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5kaXIgPSAncnRsJztcbiAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5sYW5nID0gJ2FyJztcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgdGhlIGxhbmd1YWdlIHNlbGVjdG9yIGFmdGVyIERPTSBpcyByZWFkeVxuICAgIGlmIChkb2N1bWVudC5yZWFkeVN0YXRlID09PSAnbG9hZGluZycpIHtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCAoKSA9PiB7XG4gICAgICAgIGNyZWF0ZUxhbmd1YWdlU2VsZWN0b3IoKTtcbiAgICAgICAgaWYgKGN1cnJlbnRMYW5nICE9PSBERUZBVUxUX0xBTkcpIGxvYWRUcmFuc2xhdGlvbnMoY3VycmVudExhbmcpLnRoZW4oYXBwbHlUcmFuc2xhdGlvbnMpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNyZWF0ZUxhbmd1YWdlU2VsZWN0b3IoKTtcbiAgICAgIGlmIChjdXJyZW50TGFuZyAhPT0gREVGQVVMVF9MQU5HKSBsb2FkVHJhbnNsYXRpb25zKGN1cnJlbnRMYW5nKS50aGVuKGFwcGx5VHJhbnNsYXRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvLyBFeHBvc2UgZ2xvYmFsbHlcbiAgd2luZG93LkRDSTE4biA9IHsgdCwgc2V0TGFuZ3VhZ2UsIGdldExhbmd1YWdlLCBhcHBseVRyYW5zbGF0aW9ucywgbG9hZFRyYW5zbGF0aW9ucyB9O1xuXG4gIC8vIEF1dG8taW5pdFxuICBpbml0KCk7XG59KSgpO1xuIl0sCiAgIm1hcHBpbmdzIjogIkNBQ0MsVUFBVyxDQUVWLFlBQVksYUFBYztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsU0E0Rm5CLEVBRVAsTUFBTUEsRUFBWSxTQUFTLGVBQWUsWUFBWSxFQUNoREMsRUFBYyxTQUFTLGVBQWUsbUJBQW1CLEVBQ3pEQyxFQUFlLFNBQVMsZUFBZSxvQkFBb0IsRUFDM0RDLEVBQWEsU0FBUyxlQUFlLGFBQWEsRUFDbERDLEVBQW1CLFNBQVMsZUFBZSxnQkFBZ0IsRUFDM0RDLEVBQWMsU0FBUyxlQUFlLG1CQUFtQixFQUN6REMsRUFBZSxTQUFTLGVBQWUsb0JBQW9CLEVBQzNEQyxFQUFhLFNBQVMsZUFBZSxr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O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLFNBeUw1QixFQUVQLE1BQU1JLEVBQVEsU0FBUyxlQUFlLHFCQUFxQixFQUNyRDBQLEVBQVUsU0FBUyxlQUFlLHNCQUFzQixFQUN4RDZELEVBQVUsU0FBUyxlQUFlLG9CQUFvQixFQUN0RGxMLEVBQVksU0FBUyxlQUFlLHNCQUFzQixFQUdo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QUdBLE9BQU8sT0FBUyxDQUFFLEVBQUE1N0IsRUFBRyxZQUFBMDdCLEVBQWEsWUFBQUcsRUFBYSxrQkFBQUQsRUFBbUIsaUJBQUFKLENBQWlCLEVBR25GYyxFQUFLLENBQ1AsR0FBRyIsCiAgIm5hbWVzIjogWyJsb2dvTW9kYWwiLCAicHJldmlld0RhcmsiLCAicHJldmlld0xpZ2h0IiwgImxvZ29TdGF0dXMiLCAic2FtZUJvdGhDaGVja2JveCIsICJkdWFsVXBsb2FkcyIsICJzaW5nbGVVcGxvYWQiLCAidXBsb2FkRGFyayIsICJ1cGxvYWRMaWdodCIsICJ1cGxvYWRTaW5nbGUiLCAiYnJhbmRMb2dvRGFyayIsICJicmFuZExvZ29MaWdodCIsICJ0b3BSb3ciLCAiZGFzaGJvYXJkVGl0bGVJbnB1dCIsICJERUZBVUxUX1RJVExFIiwgInBlbmRpbmdEYXJrRGF0YSIsICJwZW5kaW5nTGlnaHREYXRhIiwgInBlbmRpbmdTaW5nbGVEYXRhIiwgImN1cnJlbnRQb3NpdGlvbiIsICJjdXJyZW50VGl0bGUiLCAicmVhZEZpbGVBc0RhdGFVUkwiLCAiZmlsZSIsICJjYWxsYmFjayIsICJyZWFkZXIiLCAiZSIsICJkYXRhIiwgImFwcGx5TG9nb1Bvc2l0aW9uIiwgInBvcyIsICJidG4iLCAiYXBwbHlEYXNoYm9hcmRUaXRsZSIsICJ0aXRsZSIsICJoZWFkZXJUaXRsZSIsICJsb2FkQ3VzdG9tTG9nbyIsICJyZXNwb25zZSIsICJlcnJvciIsICJpc0N1c3RvbSIsICJuZXdUaXRsZSIsICJwYXlsb2FkIiwgInQiLCAiZmF2aWNvbkxpbmsiLCAiZmF2aWNvblByZXZpZXciLCAiZmF2aWNvblN0YXR1cyIsICJwZW5kaW5nRmF2aWNvbkRhdGEiLCAiZmF2aWNvblVwbG9hZCIsICJsb2FkQ3VzdG9tRmF2aWNvbiIsICJldmVudCIsICJzZXR0aW5nc1R6U2VsZWN0IiwgImN1cnJlbnRUeiIsICJyZXMiLCAidHoiLCAiY2ZnIiwgInNlbGVjdEVsIiwgInNlbGVjdGVkVHoiLCAidGltZXpvbmVzIiwgImRldGVjdGVkIiwgIm9wdCIsICJjdXJyZW50Q29uZmlnVHlwZSIsICJzZXJ2ZXJDb25maWciLCAiY2hlY2tTZXJ2ZXJDb25maWciLCAic2V0dXBUelNlbGVjdCIsICJzaG93U3RlcCIsICJzdGVwSWQiLCAic3RlcCIsICJ0YXJnZXRTdGVwIiwgInNob3dTdW1tYXJ5IiwgInN1bW1hcnlDb250ZW50IiwgImh0bWwiLCAidGxkIiwgImNhTmFtZSIsICJkbnNJUCIsICJkbnNQb3J0IiwgImlwIiwgImRvbWFpbiIsICJlbWFpbCIsICJyb3V0aW5nTW9kZSIsICJleGFtcGxlVXJscyIsICJzYXZlQ29uZmlnVG9TZXJ2ZXIiLCAiY29uZmlnIiwgImZpbmlzaFNldHVwIiwgInNlbGVjdGVkUHJvdmlkZXIiLCAic2F2ZWRUb1NlcnZlciIsICJjb25maWdOYW1lIiwgInNhdmVMb2NhdGlvbiIsICJzdGVwMU5leHQiLCAic2VsZWN0ZWQiLCAic2tpcEJ0biIsICJ0bGRJbnB1dCIsICJwcmV2aWV3MSIsICJwcmV2aWV3MiIsICJob21lbGFiQmFjayIsICJob21lbGFiTmV4dCIsICJzaW1wbGVCYWNrIiwgInNpbXBsZU5leHQiLCAicmFkaW8iLCAibm90ZSIsICJwdWJsaWNCYWNrIiwgInB1YmxpY05leHQiLCAic3VtbWFyeUJhY2siLCAiZmluaXNoQnRuIiwgImNvbmZpZ1N0ciIsICJlcnJvckhhbmRsZXIiLCAiQVBQU19LRVkiLCAiYXBpVGVtcGxhdGVzIiwgImFwaUNhdGVnb3JpZXMiLCAibW9kYWwiLCAiZ3JpZCIsICJmZXRjaEFwcFRlbXBsYXRlcyIsICJjaGVja1BvcnRBdmFpbGFiaWxpdHkiLCAicG9ydCIsICJnZXRTdWdnZXN0ZWRQb3J0IiwgImJhc2VQb3J0IiwgImJ1aWxkQXBwU2VsZWN0b3IiLCAiYnlDYXRlZ29yeSIsICJhcHBJZCIsICJ0ZW1wbGF0ZSIsICJjYXRlZ29yeSIsICJjYXRlZ29yeU9yZGVyIiwgImFwcHMiLCAiYSIsICJiIiwgImhlYWRlciIsICJjYXRlZ29yeUluZm8iLCAiYXBwIiwgIm9wdGlvbiIsICJpc1dpZGdldCIsICJ3aWRnZXRFbmFibGVkIiwgIndpZGdldEJhZGdlIiwgImRpZmZpY3VsdHlCYWRnZSIsICJ0b2dnbGVEYXNoYm9hcmRXaWRnZXQiLCAic2hvd0RlcGxveUNvbmZpZyIsICJvcHRpb25FbCIsICJrZXkiLCAibmV3U3RhdGUiLCAic2VsZWN0b3IiLCAiZWwiLCAiYmFkZ2UiLCAiYXBwVGVtcGxhdGUiLCAiZGVwbG95TW9kYWwiLCAic3ViZG9tYWluSW5wdXQiLCAidXJsUHJldmlldyIsICJpcElucHV0IiwgInBvcnRJbnB1dCIsICJ0YWlsc2NhbGVDaGVja2JveCIsICJ0YWlsc2NhbGVTdGF0dXMiLCAiY2hlY2tSZXN1bHQiLCAiY29udGFpbmVyIiwgImRlZmF1bHRTdWJkb21haW4iLCAic3VicGF0aFdhcm5pbmciLCAic3VwcG9ydCIsICJjZmdEbnNUeXBlIiwgImNmZ1NzbFR5cGUiLCAiZG5zUmFkaW8iLCAic3NsUmFkaW8iLCAiZG5zU2VjdGlvbiIsICJhZHZhbmNlZERldGFpbHMiLCAiYWR2YW5jZWRDb250ZW50IiwgImRuc1NlY3Rpb25FbCIsICJzc2xTZWN0aW9uRWwiLCAibWVkaWFQYXRoU2VjdGlvbiIsICJtZWRpYVBhdGhJbnB1dCIsICJtZWRpYVBhdGhEZXNjcmlwdGlvbiIsICJkZXRlY3RlZE1vdW50c0NvbnRhaW5lciIsICJkZXRlY3RlZE1vdW50c0xpc3QiLCAibW91bnRzUmVzdWx0IiwgImF1dG9QYXRocyIsICJtIiwgIm1vdW50IiwgImlzU2VsZWN0ZWQiLCAiY3VycmVudFBhdGhzIiwgInAiLCAiaWR4IiwgInBsZXhDbGFpbVNlY3Rpb24iLCAidm9sdW1lU2VjdGlvbiIsICJ2b2x1bWVMaXN0IiwgIm1lZGlhQ29udGFpbmVyUGF0aCIsICJub25NZWRpYVZvbHVtZXMiLCAidiIsICJ2b2wiLCAiaSIsICJob3N0RGVmYXVsdCIsICJjb250YWluZXJQYXRoIiwgInJvdyIsICJpbnB1dCIsICJkZWZhdWx0UG9ydCIsICJwb3J0U3RhdHVzIiwgImNoZWNrQW5kVXBkYXRlUG9ydFN0YXR1cyIsICJwb3J0VG9DaGVjayIsICJyZXN1bHQiLCAic3VnZ2VzdGVkUG9ydCIsICJ1c2VCdG4iLCAicG9ydENoZWNrVGltZW91dCIsICJ1cGRhdGVVcmxQcmV2aWV3IiwgInN1YmRvbWFpbiIsICJkbnNUeXBlIiwgInNzbFR5cGUiLCAidXJsIiwgInByb3RvY29sIiwgImFkZEFwcFRvR3JpZCIsICJkZXBsb3lDb25maWciLCAiY3VzdG9tQXBwcyIsICJ1c2luZ0V4aXN0aW5nIiwgImV4aXN0aW5nQXBwIiwgImluZGV4IiwgInBvcnRUb1VzZSIsICJwb3J0Q2hlY2siLCAiYXBpRGVwbG95Q29uZmlnIiwgIm5ld0FwcCIsICJtZXNzYWdlIiwgImNoZWNrU1NMQ2VydGlmaWNhdGUiLCAiaW5zdHJ1Y3Rpb25zIiwgImFwcE5hbWUiLCAiYXR0ZW1wdHMiLCAibWF4QXR0ZW1wdHMiLCAiY2hlY2tDZXJ0IiwgImxvYWRDdXN0b21BcHBzIiwgIm1lZGlhUGF0aCIsICJjdXN0b21Wb2x1bWVzIiwgImZvbGRlckJyb3dzZXJNb2RhbCIsICJmb2xkZXJCcm93c2VyUGF0aCIsICJmb2xkZXJCcm93c2VyTGlzdCIsICJmb2xkZXJCcm93c2VyU2VsZWN0ZWQiLCAiZm9sZGVyQnJvd3NlclNlbGVjdGVkTGlzdCIsICJjdXJyZW50QnJvd3NlclBhdGgiLCAic2VsZWN0ZWRGb2xkZXJzIiwgInRhcmdldE1lZGlhSW5wdXQiLCAibWVkaWFJbnB1dCIsICJ1cGRhdGVTZWxlY3RlZEZvbGRlcnNEaXNwbGF5IiwgImxvYWRGb2xkZXJDb250ZW50cyIsICJwYXRoIiwgIml0ZW0iLCAiaWNvbiIsICJzZWxlY3RlZFN0eWxlIiwgInJlY2lwZVRlbXBsYXRlcyIsICJyZWNpcGVDYXRlZ29yaWVzIiwgImN1cnJlbnRSZWNpcGUiLCAiY3VycmVudFN0ZXAiLCAiaXNQcmVtaXVtIiwgImNhbmNlbEJ0biIsICJwcmV2QnRuIiwgIm5leHRCdG4iLCAiZmV0Y2hSZWNpcGVUZW1wbGF0ZXMiLCAicmVzcCIsICJjaGVja1JlY2lwZVByZW1pdW0iLCAicmVjaXBlcyIsICJnZXRQcmV2aWV3UmVjaXBlcyIsICJyZWNpcGVMaXN0IiwgInJlY2lwZSIsICJjb21wb25lbnRCYWRnZSIsICJsb2NrT3ZlcmxheSIsICJvcGVuUmVjaXBlRGVwbG95V2l6YXJkIiwgImFwcFNlbGVjdG9yTW9kYWwiLCAidXBkYXRlU3RlcFVJIiwgInJlbmRlclN0ZXAxIiwgInBhbmVsIiwgImxpc3QiLCAiY29tcG9uZW50cyIsICJjb21wIiwgImlzUmVxdWlyZWQiLCAiaXNJbnRlcm5hbCIsICJyZW5kZXJTdGVwMiIsICJzaGFyZWRWb2x1bWVzIiwgInJlbmRlclN0ZXAzIiwgImNvbnRlbnQiLCAic2VsZWN0ZWRDb21wb25lbnRzIiwgImdldFNlbGVjdGVkQ29tcG9uZW50cyIsICJ2b2x1bWVJbnB1dHMiLCAidm9sdW1lcyIsICJ0YWlsc2NhbGUiLCAiYyIsICJrIiwgImNoZWNrYm94ZXMiLCAic2VsZWN0ZWRJZHMiLCAiY2IiLCAiZXhlY3V0ZURlcGxveSIsICJwcm9ncmVzc0xpc3QiLCAicmVzdWx0RWwiLCAidXBkYXRlUHJvZ3Jlc3NJdGVtIiwgImRlcGxveWVkIiwgImVyciIsICJzIiwgImNvbXBvbmVudElkIiwgInN0YXR1cyIsICJ0ZXh0IiwgInN0YXR1c0VsIiwgImNhcmRzIiwgImdyb3VwcyIsICJjYXJkIiwgInJlY2lwZUlkIiwgImdyb3VwQ2FyZHMiLCAibGFiZWwiLCAiYWN0aW9uIiwgImVuZHBvaW50IiwgIm1ldGhvZCIsICJyIiwgInN0eWxlIiwgImJ1dHRvbiIsICJvcmlnaW5hbFRleHQiLCAidmlld0J0biIsICJyZWZyZXNoQnRuIiwgImNsZWFyQnRuIiwgImNsb3NlQnRuIiwgImxvYWRFcnJvckxvZ3MiLCAibG9nIiwgImNsZWFyRXJyb3JMb2dzIiwgImNvbnRhaW5lclNlbGVjdCIsICJsb2dDb250ZW50IiwgImxvZ1NlYXJjaCIsICJsb2dUYWlsIiwgInN0cmVhbUJ0biIsICJkb3dubG9hZEJ0biIsICJjbGVhclNlYXJjaEJ0biIsICJjbG9zZUJ0bjIiLCAic3RyZWFtU3RhdHVzIiwgInN0cmVhbUluZGljYXRvciIsICJzdHJlYW1UZXh0IiwgImxpbmVDb3VudCIsICJmaWx0ZXJDb3VudCIsICJpbWFnZUVsIiwgImNyZWF0ZWRFbCIsICJjdXJyZW50Q29udGFpbmVySWQiLCAiY3VycmVudExvZ3MiLCAiZmlsdGVyZWRMb2dzIiwgImV2ZW50U291cmNlIiwgImlzU3RyZWFtaW5nIiwgInNlYXJjaFRpbWVvdXQiLCAiZm9ybWF0RGF0ZSIsICJkYXRlU3RyIiwgImVzY2FwZUh0bWwiLCAic3RyIiwgImRpdiIsICJmb3JtYXRMb2dFbnRyeSIsICJzdHJlYW1DbGFzcyIsICJzdHJlYW1JY29uIiwgInJlbmRlckxvZ3MiLCAibG9ncyIsICJzZWFyY2hUZXJtIiwgImxvYWRDb250YWluZXJzIiwgImNvbnRhaW5lcnMiLCAiY3VycmVudFZhbCIsICJsb2FkQ29udGFpbmVySW5mbyIsICJjb250YWluZXJJZCIsICJsb2FkTG9ncyIsICJzdG9wU3RyZWFtIiwgInRhaWwiLCAic3RhcnRTdHJlYW0iLCAiZW50cnkiLCAiZW50cnlEaXYiLCAiZG93bmxvYWRMb2dzIiwgImNvbnRhaW5lck5hbWUiLCAidGltZXN0YW1wIiwgImZpbGVuYW1lIiwgInN0cmVhbSIsICJibG9iIiwgImNsb3NlTW9kYWwiLCAib3BlbkJ0biIsICJkZXRhaWxzRGl2IiwgImNyZWF0ZUJ0biIsICJjcmVhdGVTdGF0dXMiLCAic2hvd0NvbnRhaW5lckRldGFpbHMiLCAiY3JlYXRlU25hcHNob3QiLCAibmFtZSIsICJsZWF2ZVJ1bm5pbmciLCAib3Blbk1vZGFsIiwgInRhYiIsICJjb25uZWN0QnRuIiwgInBoYXNlRGV0ZWN0IiwgInBoYXNlQ3JlZGVudGlhbHMiLCAicGhhc2VQcm9ncmVzcyIsICJwaGFzZVJlc3VsdHMiLCAiZGV0ZWN0UmVzdWx0cyIsICJjcmVkZW50aWFsSW5wdXRzIiwgInByb2dyZXNzU3RlcHMiLCAicmVzdWx0c0NvbnRlbnQiLCAicGxleExpYnJhcmllcyIsICJyZXRyeUJ0biIsICJkZXRlY3RlZERhdGEiLCAic2VydmljZUljb25zIiwgInNlcnZpY2VMYWJlbHMiLCAic2hvd1BoYXNlIiwgInBoYXNlIiwgInN0YXR1c0JhZGdlIiwgImNvbG9ycyIsICJzbWFydERldGVjdCIsICJzdmMiLCAiaW5mbyIsICJzb3VyY2UiLCAidmVyc2lvbiIsICJrZXlTYXZlZCIsICJidWlsZENyZWRlbnRpYWxJbnB1dHMiLCAic2VydmljZXMiLCAiYXJyU2VydmljZXMiLCAiaXNDb25uZWN0ZWQiLCAicGxleCIsICJwbGV4Q29ubmVjdGVkIiwgInNlZXJyIiwgInNlZXJyT2siLCAiY29uZmlndXJlZEh0bWwiLCAiY3MiLCAic2VydmljZSIsICJ1cmxJbnB1dCIsICJrZXlJbnB1dCIsICJzdGF0dXNTcGFuIiwgImFwaUtleSIsICJzbWFydENvbm5lY3QiLCAic3RlcHNIdG1sIiwgImRldGFpbENvbG9yIiwgInNob3dSZXN1bHRzIiwgImFsbEdvb2QiLCAiaGVhZGVyQ29sb3IiLCAiaGVhZGVySWNvbiIsICJoZWFkZXJUZXh0IiwgInN0IiwgImZldGNoUGxleExpYnJhcmllcyIsICJsaWIiLCAidHlwZUljb24iLCAic2F2ZUJ0biIsICJwcm92aWRlciIsICJjaGVja2JveCIsICJoZWFsdGhDaGVja0VuYWJsZWQiLCAiaGVhbHRoQ2hlY2tDb25maWciLCAibG9hZE5vdGlmaWNhdGlvbkNvbmZpZyIsICJsb2FkTm90aWZpY2F0aW9uSGlzdG9yeSIsICJkYXRlIiwgInNhdmVOb3RpZmljYXRpb25Db25maWciLCAidGVzdFByb3ZpZGVyIiwgImxvYWROb3RpZmljYXRpb25TdGF0dXMiLCAibGFzdFNlbnRFbCIsICJwYW5lbElkIiwgInRhYkJhciIsICJtb2RhbENvbnRlbnQiLCAidGFyZ2V0IiwgIkJST1dTRVJfU1RBVEVfS0VZUyIsICJjb2xsZWN0QnJvd3NlclN0YXRlIiwgInN0YXRlIiwgInZhbCIsICJqIiwgInJlc3RvcmVCcm93c2VyU3RhdGUiLCAiYnJvd3NlclN0YXRlIiwgImNvdW50IiwgImlzTGVnYWN5Rm9ybWF0IiwgInJlc3RvcmVMZWdhY3lGb3JtYXQiLCAic2x1ZyIsICJleHBvcnRCdG4iLCAic2VsZWN0RmlsZUJ0biIsICJmaWxlSW5wdXQiLCAiZmlsZU5hbWVEaXYiLCAicHJldmlld0RpdiIsICJwcmV2aWV3Q29udGVudCIsICJyZXN0b3JlQnRuIiwgInJlc3VsdERpdiIsICJzY2hlZHVsZUNvbnRhaW5lciIsICJoaXN0b3J5Q29udGFpbmVyIiwgImRpc2tDb250YWluZXIiLCAicG9pbnRpbnRpbWVDb250YWluZXIiLCAic2VsZWN0ZWRCYWNrdXAiLCAic3RhdGVDb3VudCIsICJ0aGVtZUNvdW50IiwgImJhY2t1cCIsICJwcmV2aWV3IiwgInJlbG9hZENhZGR5IiwgImJyb3dzZXJDb3VudCIsICJtc2ciLCAibG9hZFNjaGVkdWxlc1RhYiIsICJzY2hlZHVsZXMiLCAic2NoIiwgIm5leHRSdW5TdHIiLCAibGFzdFJ1blN0ciIsICJ0b2dnbGUiLCAidXBkYXRlU2NoZWR1bGUiLCAic2VsIiwgImlucCIsICJydW5CYWNrdXBOb3ciLCAiZGVsZXRlU2NoZWR1bGUiLCAiYWRkTmV3U2NoZWR1bGUiLCAidXBkYXRlcyIsICJpbnRlcnZhbCIsICJyZXRlbnRpb24iLCAiYXBwSWRJbnB1dCIsICJsb2FkRGlza0JhY2t1cHMiLCAiZmlsZXMiLCAiYnlBcHAiLCAiZiIsICJhcHBJZHMiLCAiYXBwRmlsZXMiLCAiY29tcGFyZUJhY2t1cEZpbGUiLCAicmVzdG9yZUJhY2t1cEZpbGUiLCAibG9hZEJhY2t1cEhpc3RvcnkiLCAiYmsiLCAic2l6ZU1CIiwgImJhY2t1cElkIiwgImxvYWRQb2ludEluVGltZVRhYiIsICJsaWNlbnNlUmVzIiwgImxpY2Vuc2VEYXRhIiwgInNlcnZpY2VzUmVzIiwgInNlcnZpY2VzRGF0YSIsICJsb2FkUG9pbnRJblRpbWVCYWNrdXBzIiwgImxpc3RFbCIsICJkaWZmIiwgInN2Y0NoYW5nZWQiLCAiY2ZnQ2hhbmdlZCIsICJhdXRvUmVmcmVzaENoZWNrYm94IiwgImFnZ3JlZ2F0ZWRDb250YWluZXIiLCAiYWxlcnRzQ29udGFpbmVyIiwgImxhc3RVcGRhdGVTcGFuIiwgInJlZnJlc2hJbnRlcnZhbCIsICJjYWNoZWRNb25pdG9yaW5nRGF0YSIsICJmb3JtYXRCeXRlcyIsICJieXRlcyIsICJzaXplcyIsICJnZXRDcHVDb2xvciIsICJwZXJjZW50IiwgImdldE1lbUNvbG9yIiwgImxvYWRTdGF0cyIsICJzdGF0cyIsICJpc05ld0FwaSIsICJpZCIsICJjdXIiLCAiY3B1IiwgIm1lbSIsICJjcHVDb2xvciIsICJtZW1Db2xvciIsICJtZW1Vc2VkIiwgIm1lbUxpbWl0IiwgIm5ldFJ4IiwgIm5ldFR4IiwgImFnZyIsICJsb2FkQWdncmVnYXRlZCIsICJsb2FkQWxlcnRzIiwgImFsZXJ0SGlzdG9yeSIsICJoZCIsICJhbGxDb25maWdzIiwgImNkIiwgImNvbnRhaW5lclJvd3MiLCAiaGlzdG9yeVJvd3MiLCAidGltZSIsICJub3RpZmllZE1hcmsiLCAiY29uZmlnU2VjdGlvbiIsICJjb25maWdzIiwgImNJZCIsICJzdG9wQXV0b1JlZnJlc2giLCAib3JpZyIsICJzdGFydEF1dG9SZWZyZXNoIiwgImhpc3RvcnlDb250YWluZXJTZWxlY3QiLCAiaGlzdG9yeUFyZWEiLCAicmFuZ2VCdXR0b25zIiwgImN1cnJlbnRSYW5nZSIsICJyYW5nZVRvTXMiLCAicmFuZ2UiLCAidGllckxhYmVsIiwgInRpZXIiLCAicmVuZGVyU3BhcmtsaW5lIiwgInNhbXBsZXMiLCAiYWNjZXNzb3IiLCAiY29sb3IiLCAidW5pdCIsICJ2YWx1ZXMiLCAibWF4IiwgIm1pbiIsICJ3IiwgImgiLCAicGFkIiwgInN0ZXBYIiwgInBvaW50cyIsICJ4IiwgInkiLCAibGFzdCIsICJhdmciLCAicG9wdWxhdGVIaXN0b3J5Q29udGFpbmVyU2VsZWN0IiwgInByZXZpb3VzIiwgImVudHJpZXMiLCAibG9hZEhpc3RvcnkiLCAiZW5kVGltZSIsICJzdGFydFRpbWUiLCAiaXNSYXciLCAiY3B1QWNjZXNzb3IiLCAibWVtQWNjZXNzb3IiLCAibmV0UnhBY2Nlc3NvciIsICJuZXRUeEFjY2Vzc29yIiwgInN0YXR1c0NvbnRhaW5lciIsICJpbmNpZGVudHNDb250YWluZXIiLCAiY29uZmlnQ29udGFpbmVyIiwgImFkZEJ0biIsICJmb3JtRWwiLCAiZm9ybVRpdGxlIiwgImZvcm1DYW5jZWwiLCAiZm9ybVNhdmUiLCAiSEVBTFRIX1NFVFRJTkdTX0tFWSIsICJIRUFMVEhfREVGQVVMVFMiLCAiZ2xvYmFsU2F2ZUJ0biIsICJnbG9iYWxSZXNldEJ0biIsICJnbG9iYWxTdGF0dXNTcGFuIiwgInJldGVudGlvbklucHV0IiwgImludGVydmFsSW5wdXQiLCAiZGlza1RocmVzaG9sZElucHV0IiwgImxvYWRIZWFsdGhTZXR0aW5ncyIsICJyYXciLCAic2F2ZWQiLCAiYXBwbHlIZWFsdGhTZXR0aW5nc1RvVUkiLCAic2F2ZUhlYWx0aFNldHRpbmdzIiwgInNldHRpbmdzIiwgInJlc2V0SGVhbHRoU2V0dGluZ3MiLCAiZWRpdGluZ0lkIiwgInVwdGltZUNvbG9yIiwgInBjdCIsICJzZXZlcml0eUJhZGdlIiwgInNldiIsICJsb2FkU3RhdHVzIiwgImlzVXAiLCAiZG90Q29sb3IiLCAidTI0IiwgInU3ZCIsICJhdmdSdCIsICJsYXN0Q2hlY2siLCAiZGV0YWlsUm93IiwgImQiLCAicnQiLCAibG9hZEluY2lkZW50cyIsICJvcGVuUmVzIiwgImhpc3RSZXMiLCAib3BlbkRhdGEiLCAiaGlzdERhdGEiLCAib3BlbiIsICJpbmMiLCAiaGlzdG9yeSIsICJyZXNvbHZlZCIsICJkdXIiLCAibG9hZENvbmZpZyIsICJzaG93Rm9ybSIsICJ0aW1lb3V0IiwgImNvZGVzIiwgInNsYSIsICJzbG93IiwgImhpZGVGb3JtIiwgImJvZHkiLCAiY2hlY2tCdG4iLCAiYXZhaWxhYmxlQ29udGFpbmVyIiwgImF1dG9Db250YWluZXIiLCAibGFzdENoZWNrU3BhbiIsICJsb2FkQXZhaWxhYmxlIiwgInUiLCAiY291bnRCYWRnZSIsICJ1cGRhdGVBbGxCdG4iLCAidXBkYXRlQWxsQ29udGFpbmVycyIsICJzdWNjZXNzIiwgImZhaWxlZCIsICJjaGVja0ZvclVwZGF0ZXMiLCAib2siLCAibG9hZEF1dG9Db25maWciLCAiY29udGFpbmVyc1JlcyIsICJjb25maWdSZXMiLCAiY29udGFpbmVyc0RhdGEiLCAiY29uZmlnRGF0YSIsICJzYXZlZENvbmZpZyIsICJjaWQiLCAic2NoZWR1bGVWYWwiLCAicm9sbGJhY2tWYWwiLCAid2luZG93VmFsIiwgImxhc3RSdW4iLCAic2NoZWR1bGUiLCAicm9sbGJhY2siLCAid2luZG93IiwgImRjVmVyc2lvbkluZm8iLCAiZGNVcGRhdGVCYWRnZSIsICJkY1VwZGF0ZURldGFpbHMiLCAiZGNOZXdWZXJzaW9uIiwgImRjQ2hhbmdlbG9nIiwgImRjQXBwbHlCdG4iLCAiZGNDaGVja0J0biIsICJkY1JvbGxiYWNrQnRuIiwgImRjU3RhdHVzQmFyIiwgImRjSGlzdG9yeUNvbnRhaW5lciIsICJkY0xhc3RDaGVjayIsICJkY1Nob3dTdGF0dXMiLCAidHlwZSIsICJkY0xvYWRWZXJzaW9uIiwgImNvbW1pdCIsICJkY0NoZWNrRm9yVXBkYXRlIiwgInNpbGVudCIsICJ1cGRhdGVzQnRuIiwgImRvdCIsICJkY1RhYiIsICJkY0FwcGx5VXBkYXRlIiwgImRjTG9hZEhpc3RvcnkiLCAic3RDb2xvciIsICJkY1Nob3dSb2xsYmFjayIsICJ2ZXJzaW9ucyIsICJmbXRCeXRlcyIsICJ1bml0cyIsICJsb2FkVm9sdW1lcyIsICJ2b2xzIiwgImlzU3lzdGVtIiwgIm5hbWVJbnB1dCIsICJsb2FkTmV0d29ya3MiLCAibmV0cyIsICJuIiwgImRyaXZlclNlbGVjdCIsICJsb2FkRGlza1VzYWdlIiwgInNlY3Rpb25zIiwgInBhcnNlZERhdGEiLCAieWFtbFN0ciIsICJzdGFja05hbWUiLCAib3JpZ1RleHQiLCAicmVuZGVyUHJldmlldyIsICJib3JkZXJDb2xvciIsICJwYXJ0cyIsICJwcm9ncmVzc0VsIiwgInRlcm1FbCIsICJ0ZXJtIiwgIndzIiwgImZpdEFkZG9uIiwgImNsZWFudXAiLCAib3BlbkV4ZWMiLCAiZGltcyIsICJjb2xzIiwgInJvd3MiLCAicmVzaXplSGFuZGxlciIsICJmaWx0ZXJTZWxlY3QiLCAibG9hZE1vcmVCdG4iLCAiY3VycmVudE9mZnNldCIsICJQQUdFX1NJWkUiLCAibG9hZEF1ZGl0IiwgImFwcGVuZCIsICJmaWx0ZXIiLCAidGFibGUiLCAiZGV0YWlsIiwgInRhYnMiLCAicGFuZWxzIiwgImFsbEV2ZW50cyIsICJhbGxIb3N0cyIsICJzc2VTb3VyY2UiLCAicmVmcmVzaE92ZXJ2aWV3IiwgInJlZnJlc2hFdmVudHMiLCAicmVmcmVzaEhvc3RzIiwgInN0YXJ0TGl2ZVRhaWwiLCAic3RvcExpdmVUYWlsIiwgInJlbmRlckV2ZW50cyIsICJldiIsICJhY3RpdmUiLCAic2luY2UiLCAic3RhdHNSZXMiLCAiaG9zdHNSZXMiLCAiZXZlbnRzUmVzIiwgImhvc3RzIiwgImV2ZW50c0NvdW50IiwgInJlbmRlclRvcExpc3QiLCAiaXRlbXMiLCAiaXQiLCAiZmlsdGVyU291cmNlIiwgImZpbHRlclNldmVyaXR5IiwgImZpbHRlckhvc3QiLCAiZmlsdGVyQWN0b3IiLCAiZGVib3VuY2UiLCAicGFyYW1zIiwgInJlZnJlc2hIb3N0RmlsdGVyIiwgInJlbmRlckV2ZW50Um93IiwgInNldkNvbG9yIiwgImFjdG9yIiwgIm91dGNvbWUiLCAiY3VycmVudCIsICJyZWdpc3Rlckhvc3RQcm9tcHQiLCAiZm4iLCAibXMiLCAiTE9DQVRJT05fS0VZIiwgIkxFR0FDWV9LRVkiLCAiR0VPX0NBQ0hFX0tFWSIsICJVTklUX0tFWSIsICJnZXRVbml0IiwgImdldFdlYXRoZXJFbGVtZW50cyIsICJ3bW9EZXNjcmlwdGlvbnMiLCAid21vSWNvbnMiLCAid2luZERpcnMiLCAiZGVnVG9EaXIiLCAiZGVnIiwgImdlb2NvZGVMb2NhdGlvbiIsICJxdWVyeSIsICJjYWNoZWQiLCAiZ2VvIiwgImZvcm1hdExvY2F0aW9uIiwgImZldGNoV2VhdGhlciIsICJsb2NhdGlvbiIsICJ0ZW1wVW5pdCIsICJ3aW5kVW5pdCIsICJjb2RlIiwgInVwZGF0ZVdlYXRoZXIiLCAid2VhdGhlcldpZGdldCIsICJ3ZWF0aGVyIiwgInRlbXBTdWZmaXgiLCAid2luZExhYmVsIiwgImxvY2F0aW9uSW5wdXQiLCAibG9jIiwgInVuaXRSYWRpbyIsICJuZXdVbml0IiwgIm9sZFVuaXQiLCAid2lkZ2V0IiwgInJlbmRlciIsICJEQVlTIiwgIk1PTlRIUyIsICJST01BTiIsICJjdXJyZW50U3R5bGUiLCAibGFzdENoaW1lSG91ciIsICJjaGltZVBsYXlpbmciLCAicHJldkZsaXBEaWdpdHMiLCAiYWN0aXZlTGF5b3V0IiwgImRpZ2l0YWxSZWZzIiwgInRpY2tUaW1lciIsICJwbGF5Q2hpbWVzIiwgInN0cmlrZSIsICJiZWxsIiwgIm5vdyIsICJyZXNldFJlbmRlckxheW91dCIsICJlbnN1cmVEaWdpdGFsTGF5b3V0IiwgInJlbmRlckRlZmF1bHQiLCAiaDI0IiwgImFtcG0iLCAicmVmcyIsICJyZW5kZXJMY2QiLCAiY2xzIiwgInJlbmRlckZsaXAiLCAiZGlnaXRzIiwgImZsaXBDYXJkIiwgImRpZ2l0IiwgInJlbmRlckJpbmFyeSIsICJiaXQiLCAiY29sIiwgIm9uIiwgInJlbmRlckFuYWxvZyIsICJ1c2VSb21hbiIsICJzaXplIiwgImN4IiwgImN5IiwgInNBbmdsZSIsICJtQW5nbGUiLCAiaEFuZ2xlIiwgImxhYmVscyIsICJhbmdsZSIsICJ0aWNrcyIsICJvdXRlciIsICJpbm5lciIsICJ4MSIsICJ5MSIsICJ4MiIsICJ5MiIsICJzdmciLCAidGljayIsICJuZXh0Q2xhc3NOYW1lIiwgInNjaGVkdWxlTmV4dFRpY2siLCAiZGVsYXkiLCAiU1RZTEVTIiwgInN0eWxlT3B0aW9uc0h0bWwiLCAiY2hpbWVzVG9nZ2xlIiwgInZvbHVtZVNsaWRlciIsICJsb2FkU2V0dGluZ3MiLCAicmVmcmVzaENhcmRIZWFsdGgiLCAic2VydmljZUlkIiwgInVwdGltZUVsIiwgImJhckVsIiwgInVwdGltZTI0IiwgImRpc21pc3NlZFVwZGF0ZXMiLCAia25vd25VcGRhdGVzIiwgInJlZnJlc2hDYXJkVXBkYXRlcyIsICJub3RpZnlOZXciLCAicHJldiIsICJ1cGQiLCAidXBkYXRlQnRuIiwgInNjaGVkdWxlQ2FyZEVuaGFuY2VtZW50cyIsICJvcmlnUmVmcmVzaEFsbCIsICJ0aGVtZUJlZm9yZUJ1aWxkZXIiLCAiZWRpdGluZ1NsdWciLCAiYWR2YW5jZWRPdmVycmlkZXMiLCAiVEhFTUVfTEFCRUxTIiwgIkZJRUxEUyIsICJ0aGVtZUJ0biIsICJ0aGVtZUxhYmVsIiwgImdldExhYmVsRm9yIiwgInVzZXJUaGVtZXMiLCAidXBkYXRlTGFiZWwiLCAibmV4dCIsICJidWlsZEZpZWxkc0hUTUwiLCAiZ3JvdXBlZCIsICJidWlsZFN0YXJ0RnJvbU9wdGlvbnMiLCAibW9kYWxIVE1MIiwgInN0YXJ0U2VsZWN0IiwgImVkaXRTZWxlY3QiLCAiZXhpc3RpbmdTZWN0aW9uIiwgImxpZ2h0QmdDaGVjayIsICJwaWNrZXJzIiwgImFkdmFuY2VkU2VjdGlvbiIsICJhZHZhbmNlZFRvZ2dsZSIsICJhZHZhbmNlZFZpc2libGUiLCAiZ2V0Q3VycmVudENvbG9ycyIsICJnZXRCYXNlQ29sb3JzIiwgInVwZGF0ZUFkdmFuY2VkRnJvbURlcml2ZWQiLCAiYmFzZSIsICJkZXJpdmVkIiwgImhleCIsICJsb2FkVGhlbWVJbnRvUGlja2VycyIsICJ0aGVtZU5hbWUiLCAidXBkYXRlUHJldmlldyIsICJsb2FkVXNlclRoZW1lSW50b1BpY2tlcnMiLCAidGhlbWUiLCAibXV0ZWQiLCAiYmFkZ2VPayIsICJiYWRnZUJhZCIsICJkb3RPayIsICJkb3RCYWQiLCAiZG90cyIsICJhcHBseUNvbG9yc0xpdmUiLCAicHJvcCIsICJyZWZyZXNoRWRpdERyb3Bkb3duIiwgInNsdWdzIiwgInJlZnJlc2hTdGFydEZyb20iLCAib3BlbkJ1aWxkZXIiLCAiY3VzdG9taXplQnRuIiwgIm9sZFNsdWciLCAibmV3U2x1ZyIsICJ0aGVtZURhdGEiLCAiYXBpQ29sb3JzIiwgInNsdWdUb0RlbGV0ZSIsICJmYWxsYmFjayIsICJleHBvcnREYXRhIiwgInRoZW1lQ29sb3JzIiwgInRoZW1lTGlnaHRCZyIsICJjb2RlSW5wdXQiLCAiYWN0aXZhdGVCdG4iLCAiZGVhY3RpdmF0ZUJ0biIsICJlcnJvckVsIiwgInN1Y2Nlc3NFbCIsICJiYWRnZUljb24iLCAiYmFkZ2VUZXh0IiwgImRldGFpbHNFbCIsICJmZWF0dXJlTGlzdCIsICJhY3RpdmF0ZVNlY3Rpb24iLCAiY3VycmVudFN0YXR1cyIsICJoaWRlTWVzc2FnZXMiLCAic2hvd0Vycm9yIiwgInNob3dTdWNjZXNzIiwgInJlbmRlclN0YXR1cyIsICJleHBpcnlMaW5lIiwgImZlYXR1cmVzIiwgImFjdGl2ZUZlYXR1cmVzIiwgInVwZGF0ZUhlYWRlckJhZGdlIiwgImFjdGl2YXRlTGljZW5zZSIsICJkZWFjdGl2YXRlTGljZW5zZSIsICJ0b3BiYXIiLCAiaWNvbkVsIiwgInRleHRFbCIsICJ0aW1lRWwiLCAiZGF5cyIsICJvcGVuTGljZW5zZU1vZGFsIiwgInJlc3QiLCAidG9wYmFyRWwiLCAiZmVhdHVyZSIsICJUVExfT1BUSU9OUyIsICJvIiwgInNlcnZpY2VOYW1lRWwiLCAiaXNzdWVkRWwiLCAiaXNzdWVkVXJsSW5wdXQiLCAiaXNzdWVkQ29weUJ0biIsICJpc3N1ZWRNZXRhRWwiLCAib3V0c3RhbmRpbmdMaXN0RWwiLCAicHVibGljQ3JlYXRlQnRuIiwgInRzQ3JlYXRlQnRuIiwgInRzRW1haWxJbnB1dCIsICJwdWJsaWNUdGxTZWxlY3QiLCAiY3VycmVudFNlcnZpY2UiLCAiYWN0aXZlVGFiIiwgIl9vcmlnaW5Gcm9tUGFnZSIsICJfYWJzVXJsIiwgInVybFBhdGgiLCAiX2Zvcm1hdEV4cGlyeSIsICJpc28iLCAiX2Zvcm1hdFJlbWFpbmluZyIsICJzZXRBY3RpdmVUYWIiLCAiaXNBY3RpdmUiLCAibG9hZE91dHN0YW5kaW5nIiwgImZpbHRlcmVkIiwgInJlbWFpbmluZyIsICJyZXZva2VTaGFyZSIsICJpc3N1ZVB1YmxpYyIsICJvcmlnaW5hbCIsICJ0dGxNcyIsICJfcmVuZGVyQXBpRXJyb3IiLCAiaXNzdWVUYWlsc2NhbGUiLCAib3BlblNoYXJlTW9kYWwiLCAiU1RPUkFHRV9LRVkiLCAiU1VQUE9SVEVEX0xBTkdTIiwgIkxBTkdfTkFNRVMiLCAiY3VycmVudExhbmciLCAidHJhbnNsYXRpb25zIiwgImxvYWRlZCIsICJsb2FkVHJhbnNsYXRpb25zIiwgImxhbmciLCAic2V0TGFuZ3VhZ2UiLCAiaXNSdGwiLCAiYXBwbHlUcmFuc2xhdGlvbnMiLCAiZ2V0TGFuZ3VhZ2UiLCAidHJhbnNsYXRlZCIsICJjcmVhdGVMYW5ndWFnZVNlbGVjdG9yIiwgInRhcmdldENvbnRhaW5lciIsICJzZXR0aW5nc0J0biIsICJjcmVhdGVEcm9wZG93biIsICJ3cmFwcGVyIiwgImRyb3Bkb3duIiwgImZsYWciLCAiaW5pdCJdCn0K
|