{"id":7582,"date":"2026-08-13T20:17:54","date_gmt":"2026-08-13T20:17:54","guid":{"rendered":"https:\/\/h-in-q.com\/?page_id=7582"},"modified":"2026-08-13T20:38:15","modified_gmt":"2026-08-13T20:38:15","slug":"crosstab-builder","status":"publish","type":"page","link":"https:\/\/h-in-q.com\/es\/crosstab-builder\/","title":{"rendered":"Crosstab Builder \u2014 Free Survey Cross-Tabulation Tool | H-in-Q"},"content":{"rendered":"<div class=\"hin-back-nav\" style=\"max-width: 1440px; margin: 0 auto; padding: 14px 24px 0;\"><a style=\"color: #1c75bc; text-decoration: none; font-weight: 600; font-size: 14px;\" href=\"https:\/\/h-in-q.com\/free-tools\/\">\u2190 Back to Free Tools<\/a><\/div>\n<style>:root{   --blue-deep:#1C75BC;   --blue-light:#27AAE1;   --orange:#F7941E;   --grey-text:#4A5568;   --grey-line:#E8ECF0;   --bg:#F7FAFC;   --white:#FFFFFF;   --blue-tint:#EDF6FC;   --orange-tint:#FEF4E7;   --radius:6px;   --shadow:0 1px 2px rgba(28,117,188,.06), 0 4px 12px rgba(28,117,188,.06); }.hinq-ctb *{box-sizing:border-box}.hinq-ctb, .hinq-ctb{margin:0;padding:0}.hinq-ctb{   background:var(--bg);   color:var(--grey-text);   font:15px\/1.55 -apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif;   -webkit-font-smoothing:antialiased; }.hinq-ctb h1, .hinq-ctb h2, .hinq-ctb h3{color:var(--blue-deep);margin:0;font-weight:650;letter-spacing:-.01em}.hinq-ctb h1{font-size:21px}.hinq-ctb h2{font-size:16px}.hinq-ctb h3{font-size:14px}.hinq-ctb a{color:var(--blue-deep)}.hinq-ctb button{font-family:inherit;font-size:14px}.hinq-ctb .wrap{max-width:1440px;margin:0 auto;padding:0 24px 80px}.hinq-ctb header{background:var(--white);border-bottom:1px solid var(--grey-line)}.hinq-ctb .head-in{max-width:1440px;margin:0 auto;padding:14px 24px;display:flex;align-items:center;gap:14px;flex-wrap:wrap}.hinq-ctb .head-in img{height:40px;width:auto;display:block}.hinq-ctb .head-txt{flex:1;min-width:200px}.hinq-ctb .head-txt p{margin:1px 0 0;font-size:12.5px;color:#7A8798}.hinq-ctb .privacy{   display:inline-flex;align-items:center;gap:6px;background:var(--blue-tint);   color:var(--blue-deep);border-radius:100px;padding:5px 13px;font-size:12.5px;font-weight:600; }.hinq-ctb .privacy::before{content:\"\";width:7px;height:7px;border-radius:50%;background:var(--blue-light)}.hinq-ctb .help{background:var(--white);border:1px solid var(--grey-line);border-radius:var(--radius);margin:20px 0 4px}.hinq-ctb .help summary{padding:13px 18px;cursor:pointer;font-weight:600;color:var(--blue-deep);font-size:14px;list-style:none;display:flex;align-items:center;gap:8px}.hinq-ctb .help summary::-webkit-details-marker{display:none}.hinq-ctb .help summary::before{content:\"?\";display:grid;place-items:center;width:19px;height:19px;border-radius:50%;background:var(--blue-light);color:#fff;font-size:12px;font-weight:700;flex:none}.hinq-ctb .help-body{padding:0 18px 18px;font-size:13.5px;max-width:76ch}.hinq-ctb .help-body p{margin:0 0 9px}.hinq-ctb .help-body b{color:var(--blue-deep)}.hinq-ctb .step{background:var(--white);border:1px solid var(--grey-line);border-radius:var(--radius);margin-top:16px;box-shadow:var(--shadow)}.hinq-ctb .step-head{display:flex;align-items:center;gap:11px;padding:15px 18px;border-bottom:1px solid var(--grey-line)}.hinq-ctb .step-n{   flex:none;width:23px;height:23px;border-radius:50%;display:grid;place-items:center;   background:var(--blue-deep);color:#fff;font-size:12px;font-weight:700 }.hinq-ctb .step[data-done=\"1\"] .step-n{background:var(--blue-light)}.hinq-ctb .step[data-locked=\"1\"]{opacity:.45;pointer-events:none}.hinq-ctb .step[data-locked=\"1\"] .step-n{background:#C3CCD6}.hinq-ctb .step-body{padding:18px}.hinq-ctb .step-note{margin-left:auto;font-size:12.5px;color:#8A96A6}.hinq-ctb .drop{   border:2px dashed #BEDCF0;border-radius:var(--radius);background:var(--blue-tint);   padding:34px 20px;text-align:center;cursor:pointer;transition:border-color .15s,background .15s }.hinq-ctb .drop:hover, .hinq-ctb .drop.over{border-color:var(--blue-light);background:#E3F2FB}.hinq-ctb .drop p{margin:0 0 4px;font-size:15px;color:var(--blue-deep);font-weight:600}.hinq-ctb .drop small{color:#7A8798}.hinq-ctb .btn{   background:var(--blue-deep);color:#fff;border:0;border-radius:var(--radius);   padding:9px 18px;font-weight:600;cursor:pointer;transition:background .15s }.hinq-ctb .btn:hover{background:#17629E}.hinq-ctb .btn:disabled{background:#C3CCD6;cursor:not-allowed}.hinq-ctb .btn-sec{background:var(--white);color:var(--blue-deep);border:1px solid #BEDCF0}.hinq-ctb .btn-sec:hover{background:var(--blue-tint)}.hinq-ctb .btn-sm{padding:5px 11px;font-size:13px}.hinq-ctb :focus-visible{outline:2px solid var(--blue-light);outline-offset:2px}.hinq-ctb .summary-grid{display:flex;gap:26px;flex-wrap:wrap;margin-bottom:14px}.hinq-ctb .stat b{display:block;font-size:22px;color:var(--blue-deep);line-height:1.2;font-variant-numeric:tabular-nums}.hinq-ctb .stat span{font-size:12px;color:#8A96A6;text-transform:uppercase;letter-spacing:.05em}.hinq-ctb .preview{overflow:auto;border:1px solid var(--grey-line);border-radius:var(--radius);max-height:210px}.hinq-ctb .preview table{border-collapse:collapse;font-size:12.5px;width:100%}.hinq-ctb .preview th, .hinq-ctb .preview td{padding:6px 11px;border-bottom:1px solid var(--grey-line);white-space:nowrap;text-align:left}.hinq-ctb .preview th{background:var(--blue-tint);color:var(--blue-deep);position:sticky;top:0;font-weight:600}.hinq-ctb .vars{display:grid;grid-template-columns:repeat(auto-fill,minmax(310px,1fr));gap:9px}.hinq-ctb .var{border:1px solid var(--grey-line);border-radius:var(--radius);padding:10px 12px;background:var(--white)}.hinq-ctb .var-top{display:flex;align-items:center;gap:9px}.hinq-ctb .var-name{font-weight:600;color:var(--blue-deep);font-size:13.5px;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hinq-ctb .var select{font-size:12.5px;padding:3px 6px;border:1px solid var(--grey-line);border-radius:4px;background:var(--white);color:var(--grey-text)}.hinq-ctb .var-meta{font-size:12px;color:#8A96A6;margin-top:4px}.hinq-ctb .var-flag{color:var(--orange);font-weight:600}.hinq-ctb .cats{margin-top:9px;border-top:1px solid var(--grey-line);padding-top:8px;display:none}.hinq-ctb .var.open .cats{display:block}.hinq-ctb .cat{display:flex;align-items:center;gap:7px;padding:3px 0;font-size:12.5px}.hinq-ctb .cat-handle{cursor:grab;color:#B7C2CF;font-size:13px;user-select:none;flex:none;letter-spacing:-1px}.hinq-ctb .cat.drag{opacity:.4}.hinq-ctb .cat code{background:var(--bg);padding:1px 5px;border-radius:3px;color:#8A96A6;font-size:11.5px;flex:none;min-width:26px;text-align:center}.hinq-ctb .cat input{flex:1;min-width:0;border:1px solid var(--grey-line);border-radius:4px;padding:3px 7px;font:inherit;font-size:12.5px;color:var(--grey-text)}.hinq-ctb .cat input:focus{border-color:var(--blue-light)}.hinq-ctb .link{background:none;border:0;color:var(--blue-light);cursor:pointer;font-size:12px;font-weight:600;padding:2px 0}.hinq-ctb .picker{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:6px}.hinq-ctb .chip{   border:1px solid var(--grey-line);background:var(--white);border-radius:100px;   padding:6px 14px;cursor:pointer;font-size:13px;color:var(--grey-text);transition:.12s }.hinq-ctb .chip:hover{border-color:var(--blue-light);color:var(--blue-deep)}.hinq-ctb .chip[aria-pressed=\"true\"]{background:var(--blue-deep);border-color:var(--blue-deep);color:#fff;font-weight:600}.hinq-ctb .chip:disabled{opacity:.4;cursor:not-allowed}.hinq-ctb .opts{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:7px 20px;margin-top:16px;padding-top:15px;border-top:1px solid var(--grey-line)}.hinq-ctb .opt{display:flex;align-items:center;gap:8px;font-size:13.5px;cursor:pointer}.hinq-ctb .opt input{accent-color:var(--blue-deep);width:15px;height:15px;flex:none}.hinq-ctb .alpha{display:flex;align-items:center;gap:15px;margin-top:15px;padding-top:15px;border-top:1px solid var(--grey-line);flex-wrap:wrap}.hinq-ctb .alpha-label{font-size:13.5px;font-weight:600;color:var(--blue-deep)}.hinq-ctb .alpha label{display:flex;align-items:center;gap:6px;font-size:13.5px;cursor:pointer}.hinq-ctb .alpha input{accent-color:var(--blue-deep)}.hinq-ctb .actions{display:flex;gap:10px;margin-top:18px;flex-wrap:wrap;align-items:center}.hinq-ctb .results{display:grid;grid-template-columns:236px 1fr;gap:18px;margin-top:22px;align-items:start}.hinq-ctb .nav{background:var(--white);border:1px solid var(--grey-line);border-radius:var(--radius);position:sticky;top:14px;max-height:calc(100vh - 28px);display:flex;flex-direction:column;box-shadow:var(--shadow)}.hinq-ctb .nav-head{padding:13px 14px 10px;border-bottom:1px solid var(--grey-line)}.hinq-ctb .nav-head input{width:100%;border:1px solid var(--grey-line);border-radius:4px;padding:6px 9px;font:inherit;font-size:13px;color:var(--grey-text)}.hinq-ctb .nav-head input:focus{border-color:var(--blue-light)}.hinq-ctb .nav-list{overflow:auto;padding:6px}.hinq-ctb .nav-list a{   display:block;padding:6px 10px;border-radius:4px;text-decoration:none;color:var(--grey-text);   font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis }.hinq-ctb .nav-list a:hover{background:var(--blue-tint);color:var(--blue-deep)}.hinq-ctb .nav-foot{padding:11px 14px;border-top:1px solid var(--grey-line)}.hinq-ctb .nav-foot .btn{width:100%}.hinq-ctb .tbl-card{background:var(--white);border:1px solid var(--grey-line);border-radius:var(--radius);margin-bottom:18px;box-shadow:var(--shadow);overflow:hidden;scroll-margin-top:14px}.hinq-ctb .tbl-head{padding:13px 16px;border-bottom:1px solid var(--grey-line);display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}.hinq-ctb .tbl-head .vn{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:#8A96A6;background:var(--bg);padding:2px 7px;border-radius:3px}.hinq-ctb .scroller{overflow:auto;max-height:74vh}.hinq-ctb table.ct{border-collapse:separate;border-spacing:0;font-size:13px;font-variant-numeric:tabular-nums;width:100%}.hinq-ctb table.ct th, .hinq-ctb table.ct td{padding:7px 11px;border-bottom:1px solid var(--grey-line);text-align:right;white-space:nowrap}.hinq-ctb table.ct thead th{background:var(--blue-tint);color:var(--blue-deep);position:sticky;z-index:2;font-weight:600}.hinq-ctb table.ct thead tr:nth-child(1) th{top:0}.hinq-ctb table.ct thead tr:nth-child(2) th{top:29px}.hinq-ctb table.ct th.grp{text-align:center;border-left:1px solid #D3E6F4;font-size:12px;text-transform:uppercase;letter-spacing:.05em}.hinq-ctb table.ct th.rowhead, .hinq-ctb table.ct td.rowhead{   text-align:left;position:sticky;left:0;background:var(--white);z-index:1;   min-width:190px;max-width:280px;white-space:normal }.hinq-ctb table.ct thead th.rowhead{background:var(--blue-tint);z-index:3}.hinq-ctb table.ct tbody tr:hover td{background:#FAFCFE}.hinq-ctb table.ct tbody tr:hover td.rowhead{background:#FAFCFE}.hinq-ctb tr.base td, .hinq-ctb tr.base th{font-weight:600;color:var(--blue-deep);background:#FBFDFE;border-bottom:1px solid #D3E6F4}.hinq-ctb td.total, .hinq-ctb th.total{background:#FCFDFE;border-right:1px solid #D3E6F4}.hinq-ctb .letter{display:inline-block;background:var(--blue-deep);color:#fff;border-radius:3px;padding:0 4px;margin-left:5px;font-size:10.5px;font-weight:700;letter-spacing:.04em;vertical-align:1px}.hinq-ctb .col-letter{display:inline-block;background:var(--white);border:1px solid #BEDCF0;color:var(--blue-deep);border-radius:3px;padding:0 5px;font-size:11px;font-weight:700;margin-left:5px}.hinq-ctb .cnt{color:#93A0B0;font-size:11.5px;margin-right:5px}.hinq-ctb .rowpct{color:var(--blue-light);font-size:11.5px;margin-left:5px}.hinq-ctb .idx{color:#93A0B0;font-size:11.5px;margin-left:5px}.hinq-ctb .fragile{color:var(--orange)}.hinq-ctb .tbl-foot{padding:9px 16px;font-size:12px;color:#8A96A6;background:#FCFDFE;border-top:1px solid var(--grey-line)}.hinq-ctb .tbl-foot .warn{color:var(--orange);font-weight:600}.hinq-ctb .chi{margin-right:14px}.hinq-ctb .info{   position:relative;display:inline-grid;place-items:center;width:15px;height:15px;   border-radius:50%;background:#D3E6F4;color:var(--blue-deep);font-size:10.5px;font-weight:700;   cursor:help;flex:none;margin-left:2px;font-style:normal }.hinq-ctb .info::after{   content:attr(data-tip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);   background:#2A3B4D;color:#fff;font-size:12px;font-weight:400;line-height:1.45;   padding:8px 11px;border-radius:6px;width:240px;white-space:normal;text-align:left;   opacity:0;pointer-events:none;transition:opacity .12s;z-index:50;   box-shadow:0 4px 14px rgba(0,0,0,.18) }.hinq-ctb .info::before{   content:\"\";position:absolute;bottom:calc(100% + 3px);left:50%;transform:translateX(-50%);   border:5px solid transparent;border-top-color:#2A3B4D;opacity:0;transition:opacity .12s;pointer-events:none;z-index:50 }.hinq-ctb .info:hover::after, .hinq-ctb .info:hover::before, .hinq-ctb .info:focus::after, .hinq-ctb .info:focus::before{opacity:1}.hinq-ctb .banner-recap{font-size:12.5px;color:#8A96A6;margin-top:10px}.hinq-ctb .banner-recap b{color:var(--blue-deep)}.hinq-ctb .alert{border-radius:var(--radius);padding:11px 14px;font-size:13.5px;margin-top:12px;border:1px solid}.hinq-ctb .alert-warn{background:var(--orange-tint);border-color:#F6D5A8;color:#9A5B06}.hinq-ctb .alert-info{background:var(--blue-tint);border-color:#BEDCF0;color:#155F98}.hinq-ctb .overlay{position:fixed;inset:0;background:rgba(247,250,252,.9);display:none;place-items:center;z-index:100}.hinq-ctb .overlay.on{display:grid}.hinq-ctb .overlay-in{text-align:center}.hinq-ctb .bar{width:230px;height:5px;background:var(--grey-line);border-radius:100px;overflow:hidden;margin:12px auto 0}.hinq-ctb .bar i{display:block;height:100%;background:var(--blue-light);width:30%;border-radius:100px;transition:width .2s}.hinq-ctb .overlay p{margin:0;color:var(--blue-deep);font-weight:600;font-size:14px}.hinq-ctb footer{text-align:center;padding:30px 20px;font-size:13px;color:#8A96A6}.hinq-ctb footer a{font-weight:600;text-decoration:none}.hinq-ctb .hidden{display:none!important}@media (max-width:900px){.hinq-ctb .results{grid-template-columns:1fr}.hinq-ctb .nav{position:static;max-height:none}}@media (prefers-reduced-motion:reduce){.hinq-ctb *{transition:none!important;animation:none!important}}<\/style>\n<p><script src=\"https:\/\/cdn.jsdelivr.net\/npm\/xlsx@0.18.5\/dist\/xlsx.full.min.js\"><\/script><script src=\"https:\/\/cdn.jsdelivr.net\/npm\/exceljs@4.4.0\/dist\/exceljs.min.js\"><\/script><\/p>\n<div class=\"hinq-ctb\">\n<header>\n<div class=\"head-in\">\n<p><a href=\"https:\/\/h-in-q.com\"><img decoding=\"async\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAAB4CAMAAAAqj4tlAAAAflBMVEX+\/v4nquEbdLsMa7cheL0Xo97P6fZqxOlMuOVRlcs2hMMdpuBspdOoyeSy1+yNudy54\/SP0+\/F2+1EjceZw+Lj7fbb8fk4seMHndwrfsBhns9+sNiWv+Agpt8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJ9mriAAAAIHRSTlP\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/8AAM945p8AAAafSURBVHja1ZzreqsqEIZVEAUF6iFN0q59\/7e5QZSDomLUxM6P9WRVxVcYhhH4jGKPpSjabojxEjcEJtIgJA0uOVsuiIvzRvaMDgFiHJMECEss6\/5PMGfzQM756kn2AyGO4QhlhAUxRzNA0AuUpulAon6GA91anEgYmMwalFAJ\/ncLBsqzLMsVkPiVbQCqS3mvBRgDJc77YWFAaSUOValuqrwIBKJNGI1hamgwULsZiJItOAMSoScBMbKRRjMRFgSUpXFRBAMhDIAHB8Kht6tOB33nAIDRcrdXPnTPpYUB8QT4WDoM+GywsC5Aqj9MqEDCdbM3RBkcA1m2BoSacWupji1CIK2tvn2rqQqXyeR00Ixv0ICXgdoEwKmvlnTmEkTLqfdDkLRHAZVu4ZLmWbKVHlA+weSychkIVZ2tASECRuUmmAbFLBHQXSRA0BJQ9pCjxmPFqWvoNhdIyjp0kJFR3W02WC8AVYWMQ8UyEHXcU3Tgn01ZAfpxgoX4SeeBQgIjBW5r4XprylRjt91AO19D60AtcCu8fSGJi6jb6JoID6AiQUszhFCmgJj4efeP9tRNvvAteslu2C2nJyKgtyQ0H2LAaf02etlaxxOBChk1ZbQzFpgx1m6PraMdNood47KCgJDTu3C007DT29ALQNYzwVGMfclKuzyyHag8mGexxAAgal\/No0OM22W224CQ7T9ldJD92n6ENgE1+tIDeexWg6DZAsStC3F0oGGrYB4OZDVYQqJDjSS+RlsDsmMGOhYIeWPbCpAZMkad4QijVqOxQCCTFxzrQJPqJ2FAdgi6HQ8UWcGIBgGR6QUnNZquokUgc\/5sg6EvYwvH0GyjjZ94EUh7UALmMo7sUaS9\/Tc+lj+GQ2k+9zzmDs06UA3WQ3RWmOsmx1J9KF8P2P0zLwFZY\/JsCLJuugBU5KvBaHjoJaCQMWwvkP3UtxWgNqCC9gOhUWqzAKR7wFJM3A00vs08EAqKQfuBqNsQ80CmxZ7RmUA6+qo2mwcaqnI5LTsASLt112bzQHA1KB4EVJuMYgnIJB6LedkBQGbElEnILNCQuq4k0kcAlfpWfAHIuBA9G4jaTjQLRMIy1yOAkJ21zwGhwNT+CCDn4fUczAioDgnTRwGZYC2nYyrGqilQazva2UD63U\/cTBVznwAZz6fnAxmvLgXQtwRSaVaRToCmM0onANVmqrAHinPUWRYPU3pmLvB2PtBNO7UGynQhAkkCGcePzgeKrHePMVD0nXVAMPCF\/hgg\/fhPGwj1yzDVwwJypkpOA7Inzg1Q9rhXUyD8DiDjsTZQVcSP7FJAaVxcDSj9A0AfdGov0Ae6feQFInae+97A2MrRPmcVywtxIauq\/MNDh8qHxD9Fv0L16cHVnzF+MP3wA30wQfMDfTCFvVyS\/0deg673oni5V+nLTTZcbjrmehNW\/\/TgQa4xpXe5Sc\/3Tws3f23i\/JZcbGnh3YsvP1dbnmKbFvDQ2Qt4ScAC3vWWOC+3COwsk58BtHmZPCKnbiT42byR4HpbLS63GeV623Uut6HpDVu+km1bvtxNcb9H8fDXN8VdbtvgGRsrf3dtrHz31lM9Wiv7\/OZcKeeyLGT78q4I6W5fnrz0xenXmPCtG7xphDC0RVVx6spEvmcEb+1ZW+DRE3RcczU0BzQRCbyUH41FAly4p\/gLtBbBFFCm1FNLQCOig2QUqCeE6MsByqW+rIgXgXYLTcqp0GTgEUAxc2ooHV4bFoB2SXGQT4oj\/AcOnf\/eO7MBEvHoe7aX+XrsbrGS4ZFAffcyQCIeVVW+IrwtgUdctirnmkrMunhvBUjYCVyYDdRPeazpXMeCNxgmeIM+wZsTr++xItJOPQjf1oS3I0mgutuiJFAe90oCyaiGYgmhgL7lon33pve9rgTmdiX94u6WWiNJPKJJ4fzcrh4+Df89UFzYkbpKw4CkrHSoJDEU1V2jdEr1say0qztAONLTBDJ+ISuQaFn7rd\/tYUdqloY0mTp1EN6qmC\/cVtWHJaBXbEnDazU\/6BHeymfTFmugavhTVnwhxALF24M0Gfb9HrVlAxNgWfLEva9LzblPmizsK74r0zMor+vte\/G2lHHS3pkRazkvhfGWDl8jQK3U43vF26pZ3Hvv+gAA+xF36fwEii6GvJ2+SXoaj7zdR7TziwQ3jnvJfdfxy19RM7Uw1v4rVRP2QaHhs\/mKS3TsJxKAY6ufSPARHfsRicnnGpY\/IqEvt6cFc5+9\/JkNTJ4qvXkSvP6ZDUNkgP4HUchySfSVhl8AAAAASUVORK5CYII=\" alt=\"H-in-Q\" \/><\/a><\/p>\n<div class=\"head-txt\">\n<h1>Crosstab Builder<\/h1>\n<p>Cross-tabulation with significance testing, for survey data<\/p>\n<\/div>\n<p><span class=\"privacy\">Your data stays in your browser<\/span><\/p>\n<\/div>\n<\/header>\n<div class=\"wrap\">\n<details class=\"help\">\n<summary>How this works<\/summary>\n<div class=\"help-body\">\n<p>A <b>banner<\/b> is the set of variables you put in the columns \u2014 typically gender, age group, or region. Every other variable in your file is then tabulated against it, one table per variable.<\/p>\n<p>Each banner column gets a <b>letter<\/b>. When a figure is significantly higher than another column in the same banner variable, the letters of the columns it beats appear next to it. So <b>27.1%<\/b> <span class=\"letter\">B<\/span> means this column is significantly higher than column B.<\/p>\n<p>Columns are only ever compared <b>within the same banner variable<\/b>. Comparing &#8220;Men&#8221; to &#8220;25\u201334&#8221; would be meaningless \u2014 the two groups overlap, and the test assumes they don&#8217;t.<\/p>\n<p>Proportions use a two-tailed z-test with pooled variance; means use Welch&#8217;s t-test. Columns with a base under 30 are not tested; under 100 they are flagged as fragile.<\/p>\n<p>As is standard in banner books, no multiple-comparison correction is applied \u2014 across many tables and columns, a few significant letters will appear by chance alone. Treat isolated letters as leads, not proof.<\/p>\n<p>Nothing is uploaded. The file is read and all calculations run inside your browser \u2014 close the tab and the data is gone.<\/p>\n<\/div>\n<\/details>\n<section id=\"step1\" class=\"step\">\n<div class=\"step-head\">\n<p><span class=\"step-n\">1<\/span><\/p>\n<h2>Load your data<\/h2>\n<p><span id=\"s1note\" class=\"step-note\">CSV, XLSX or XLS \u2014 one row per respondent<\/span><\/p>\n<\/div>\n<div class=\"step-body\">\n<div id=\"drop\" class=\"drop\">\n<p>Drop your data file here<\/p>\n<p><small>or click to browse \u2014 CSV, XLSX, XLS<\/small> <input id=\"file\" class=\"hidden\" accept=\".csv,.xlsx,.xls,.tsv,.txt\" type=\"file\" \/><\/p>\n<\/div>\n<div id=\"loaded\" class=\"hidden\">\n<div class=\"summary-grid\">\n<div class=\"stat\"><b id=\"nResp\">0<\/b>Respondents<\/div>\n<div class=\"stat\"><b id=\"nVars\">0<\/b>Variables<\/div>\n<div class=\"stat\"><b id=\"fName\">\u2014<\/b>File<\/div>\n<\/div>\n<div id=\"preview\" class=\"preview\"><\/div>\n<div class=\"actions\"><button id=\"reset\" class=\"btn btn-sec btn-sm\">Load a different file<\/button><\/div>\n<\/div>\n<div id=\"loadErr\"><\/div>\n<\/div>\n<\/section>\n<section id=\"step2\" class=\"step\" data-locked=\"1\">\n<div class=\"step-head\">\n<p><span class=\"step-n\">2<\/span><\/p>\n<h2>Check variables and labels<\/h2>\n<p><span class=\"step-note\">Types are detected automatically \u2014 correct anything that looks wrong<\/span><\/p>\n<\/div>\n<div class=\"step-body\">\n<div class=\"actions\" style=\"margin-top: 0; margin-bottom: 14px;\"><label class=\"opt\"><input id=\"opt99\" checked=\"checked\" type=\"checkbox\" \/> Treat 99 and 999 as missing on categorical variables <i class=\"info\" tabindex=\"0\" data-tip=\"Survey software often codes 'Don't know \/ Refused' as 99 or 999. On numeric variables (income, exact age) these stay as real values either way.\">i<\/i><\/label> <button id=\"loadDict\" class=\"btn btn-sec btn-sm\">Import a label dictionary (CSV)<\/button> <input id=\"dictFile\" class=\"hidden\" accept=\".csv\" type=\"file\" \/><\/div>\n<div id=\"vars\" class=\"vars\"><\/div>\n<\/div>\n<\/section>\n<section id=\"step3\" class=\"step\" data-locked=\"1\">\n<div class=\"step-head\">\n<p><span class=\"step-n\">3<\/span><\/p>\n<h2>Build the banner<\/h2>\n<p><span id=\"s3note\" class=\"step-note\">Pick 1 to 5 variables for the columns<\/span><\/p>\n<\/div>\n<div class=\"step-body\">\n<div id=\"picker\" class=\"picker\"><\/div>\n<div id=\"recap\" class=\"banner-recap\"><\/div>\n<div id=\"bannerWarn\"><\/div>\n<div class=\"alpha\"><span class=\"alpha-label\">Confidence level <i class=\"info\" tabindex=\"0\" data-tip=\"How strict the significance test is. 95% is the market-research standard. 90% flags more differences (more false positives); 99% flags only very strong ones.\">i<\/i><\/span> <label><input name=\"alpha\" type=\"radio\" value=\"0.10\" \/> 90%<\/label> <label><input checked=\"checked\" name=\"alpha\" type=\"radio\" value=\"0.05\" \/> 95%<\/label> <label><input name=\"alpha\" type=\"radio\" value=\"0.01\" \/> 99%<\/label><\/div>\n<div class=\"opts\"><label class=\"opt\"><input id=\"oCount\" checked=\"checked\" type=\"checkbox\" \/> Show counts <i class=\"info\" tabindex=\"0\" data-tip=\"The raw number of respondents in each cell, shown in grey before the percentage.\">i<\/i><\/label> <label class=\"opt\"><input id=\"oColPct\" checked=\"checked\" type=\"checkbox\" \/> Show column % <i class=\"info\" tabindex=\"0\" data-tip=\"Percentage of each column's base \u2014 the standard reading of a banner table. Significance letters test these.\">i<\/i><\/label> <label class=\"opt\"><input id=\"oRowPct\" type=\"checkbox\" \/> Show row % <i class=\"info\" tabindex=\"0\" data-tip=\"Percentage across the row, within each banner variable (marked 'r'). Shown as \u2014 in the Total column, where it has no meaning.\">i<\/i><\/label> <label class=\"opt\"><input id=\"oHideZero\" checked=\"checked\" type=\"checkbox\" \/> Hide all-zero rows <i class=\"info\" tabindex=\"0\" data-tip=\"Skips answer categories that no one selected in any column.\">i<\/i><\/label> <label class=\"opt\"><input id=\"oIndex\" type=\"checkbox\" \/> Show index vs Total (base 100) <i class=\"info\" tabindex=\"0\" data-tip=\"Column % divided by Total %, times 100 (marked 'i'). i120 means this group over-indexes by 20% versus the overall sample.\">i<\/i><\/label> <label class=\"opt\"><input id=\"oChi\" type=\"checkbox\" \/> Show chi-square test <i class=\"info\" tabindex=\"0\" data-tip=\"One overall test per banner variable: is the whole distribution of this question different across its columns? Complements the pairwise letters.\">i<\/i><\/label><\/div>\n<div class=\"actions\"><button id=\"run\" class=\"btn\" disabled=\"disabled\">Build tables<\/button> <button id=\"pickRows\" class=\"btn btn-sec\">Choose which variables to tabulate<\/button><\/div>\n<div id=\"rowPicker\" class=\"hidden\" style=\"margin-top: 14px;\">\n<div id=\"rowChips\" class=\"picker\"><\/div>\n<\/div>\n<\/div>\n<\/section>\n<div id=\"results\" class=\"results hidden\">\n<aside class=\"nav\">\n<div class=\"nav-head\"><input id=\"navSearch\" type=\"search\" placeholder=\"Find a table\u2026\" aria-label=\"Find a table\" \/><\/div>\n<div id=\"navList\" class=\"nav-list\"><\/div>\n<div class=\"nav-foot\"><button id=\"export\" class=\"btn\">Download Excel<\/button><\/div>\n<\/aside>\n<p>&nbsp;<\/p>\n<\/div>\n<\/div>\n<footer>Free tool by <a href=\"https:\/\/h-in-q.com\">H-in-Q<\/a> \u2014 see all our <a href=\"https:\/\/h-in-q.com\/free-tools\/\">free tools for market researchers<\/a><\/footer>\n<div id=\"overlay\" class=\"overlay\">\n<div class=\"overlay-in\">\n<p id=\"ovText\">Working\u2026<\/p>\n<div class=\"bar\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><script>eval(decodeURIComponent(escape(window.atob(\"Ci8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgTU9URVVSIERFIENBTENVTCDigJQgdmFsaWTDqSBpbmTDqXBlbmRhbW1lbnQgZGUgbCdpbnRlcmZhY2UKICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgQ3Jvc3N0YWIgQnVpbGRlciDigJQgbW90ZXVyIGRlIGNhbGN1bAogICBILWluLVEuY29tIOKAlCBvdXRpbCBncmF0dWl0IGRlIHRhYnVsYXRpb24gY3JvaXPDqWUKICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgIEF1Y3VuZSBkw6lwZW5kYW5jZSwgYXVjdW4gYWNjw6hzIGF1IERPTS4gVXRpbGlzYWJsZSB0ZWwgcXVlbCBkYW5zIE5vZGUKICAgcG91ciBsZXMgdGVzdHMsIGV0IGRhbnMgbGUgbmF2aWdhdGV1ciBwb3VyIGwnb3V0aWwgZmluYWwuCiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKJ3VzZSBzdHJpY3QnOwoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgIDEuIENPTlNUQU5URVMgRVQgVkFMRVVSUyBNQU5RVUFOVEVTCiAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKY29uc3QgTUlTU0lOR19TVFJJTkdTID0gWycnLCAnTkEnLCAnTi9BJywgJyNOVUxMIScsICcuJywgJ05VTEwnLCAnLSddOwpjb25zdCBNSVNTSU5HX0NPREVTID0gWyc5OScsICc5OTknXTsgICAvLyBjYXTDqWdvcmllbGxlcyB1bmlxdWVtZW50Cgpjb25zdCBNSU5fQkFTRV9URVNUID0gMzA7ICAgIC8vIGVuIGRlc3NvdXMgOiBhdWN1biB0ZXN0CmNvbnN0IE1JTl9CQVNFX1dBUk4gPSAxMDA7ICAgLy8gZW4gZGVzc291cyA6IHBvdXJjZW50YWdlcyBzaWduYWzDqXMgY29tbWUgZnJhZ2lsZXMKCi8qKgogKiBVbmUgdmFsZXVyIGVzdC1lbGxlIG1hbnF1YW50ZSA\/CiAqIExlcyBjb2RlcyA5OSAvIDk5OSBuZSBzb250IG1hbnF1YW50cyBxdWUgc3VyIHVuZSB2YXJpYWJsZSBDQVRFR09SSUVMTEUuCiAqIFN1ciB1bmUgdmFyaWFibGUgY29udGludWUgKHJldmVudSwgw6JnZSBleGFjdCksIDk5OSBlc3QgdW5lIHZhbGV1ciBsw6lnaXRpbWUuCiAqLwpmdW5jdGlvbiBpc01pc3NpbmcodmFsdWUsIGlzQ2F0ZWdvcmljYWwsIHRyZWF0OTlBc01pc3NpbmcpIHsKICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHRydWU7CiAgY29uc3QgcyA9IFN0cmluZyh2YWx1ZSkudHJpbSgpOwogIGlmIChNSVNTSU5HX1NUUklOR1MuaW5kZXhPZihzLnRvVXBwZXJDYXNlKCkpICE9PSAtMSkgcmV0dXJuIHRydWU7CiAgaWYgKGlzQ2F0ZWdvcmljYWwgJiYgdHJlYXQ5OUFzTWlzc2luZyAmJiBNSVNTSU5HX0NPREVTLmluZGV4T2YocykgIT09IC0xKSByZXR1cm4gdHJ1ZTsKICByZXR1cm4gZmFsc2U7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAyLiBGT05DVElPTlMgREUgRElTVFJJQlVUSU9OCiAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLyoqCiAqIEZvbmN0aW9uIGdhbW1hIGluY29tcGzDqHRlIHLDqWd1bGFyaXPDqWUgUChhLCB4KSwgcGFyIGTDqXZlbG9wcGVtZW50IGVuIHPDqXJpZS4KICogQ29udmVyZ2VudCBwb3VyIHggPCBhICsgMS4KICovCmZ1bmN0aW9uIGdhbW1hUFNlcmllcyhhLCB4KSB7CiAgY29uc3QgSVRNQVggPSA1MDAsIEVQUyA9IDNlLTE0OwogIGxldCBhcCA9IGEsIHN1bSA9IDEgLyBhLCBkZWwgPSBzdW07CiAgZm9yIChsZXQgbiA9IDA7IG4gPCBJVE1BWDsgbisrKSB7CiAgICBhcCsrOwogICAgZGVsICo9IHggLyBhcDsKICAgIHN1bSArPSBkZWw7CiAgICBpZiAoTWF0aC5hYnMoZGVsKSA8IE1hdGguYWJzKHN1bSkgKiBFUFMpIGJyZWFrOwogIH0KICByZXR1cm4gc3VtICogTWF0aC5leHAoLXggKyBhICogTWF0aC5sb2coeCkgLSBsb2dHYW1tYShhKSk7Cn0KCi8qKgogKiBGb25jdGlvbiBnYW1tYSBpbmNvbXBsw6h0ZSByw6lndWxhcmlzw6llIFEoYSwgeCkgPSAxIC0gUChhLCB4KSwKICogcGFyIGZyYWN0aW9uIGNvbnRpbnVlIChMZW50eikuIENvbnZlcmdlbnQgcG91ciB4ID49IGEgKyAxLgogKi8KZnVuY3Rpb24gZ2FtbWFRQ29udGludWVkRnJhY3Rpb24oYSwgeCkgewogIGNvbnN0IElUTUFYID0gNTAwLCBFUFMgPSAzZS0xNCwgRlBNSU4gPSAxZS0zMDA7CiAgbGV0IGIgPSB4ICsgMSAtIGEsIGMgPSAxIC8gRlBNSU4sIGQgPSAxIC8gYiwgaCA9IGQ7CiAgZm9yIChsZXQgaSA9IDE7IGkgPD0gSVRNQVg7IGkrKykgewogICAgY29uc3QgYW4gPSAtaSAqIChpIC0gYSk7CiAgICBiICs9IDI7CiAgICBkID0gYW4gKiBkICsgYjsgaWYgKE1hdGguYWJzKGQpIDwgRlBNSU4pIGQgPSBGUE1JTjsKICAgIGMgPSBiICsgYW4gLyBjOyBpZiAoTWF0aC5hYnMoYykgPCBGUE1JTikgYyA9IEZQTUlOOwogICAgZCA9IDEgLyBkOwogICAgY29uc3QgZGVsID0gZCAqIGM7CiAgICBoICo9IGRlbDsKICAgIGlmIChNYXRoLmFicyhkZWwgLSAxKSA8IEVQUykgYnJlYWs7CiAgfQogIHJldHVybiBNYXRoLmV4cCgteCArIGEgKiBNYXRoLmxvZyh4KSAtIGxvZ0dhbW1hKGEpKSAqIGg7Cn0KCi8qKiBQKGEsIHgpIHLDqWd1bGFyaXPDqWUsIGFpZ3VpbGxhZ2Ugc8OpcmllIC8gZnJhY3Rpb24gY29udGludWUuICovCmZ1bmN0aW9uIGdhbW1hUChhLCB4KSB7CiAgaWYgKHggPD0gMCkgcmV0dXJuIDA7CiAgaWYgKHggPCBhICsgMSkgcmV0dXJuIGdhbW1hUFNlcmllcyhhLCB4KTsKICByZXR1cm4gMSAtIGdhbW1hUUNvbnRpbnVlZEZyYWN0aW9uKGEsIHgpOwp9CgovKioKICogRm9uY3Rpb24gZCdlcnJldXIsIHZpYSBlcmYoeCkgPSBzaWduZSh4KSAqIFAoMS8yLCB4wrIpLgogKiBQcsOpY2lzaW9uIHByb2NoZSBkZSBsJ2Vwc2lsb24gbWFjaGluZSAofjFlLTE1KSwgY29udHJlIDEuNWUtNyBwb3VyCiAqIGwnYXBwcm94aW1hdGlvbiBwb2x5bm9taWFsZSBkJ0FicmFtb3dpdHogJiBTdGVndW4uCiAqLwpmdW5jdGlvbiBlcmYoeCkgewogIGlmICh4ID09PSAwKSByZXR1cm4gMDsKICBjb25zdCBzaWduID0geCA8IDAgPyAtMSA6IDE7CiAgcmV0dXJuIHNpZ24gKiBnYW1tYVAoMC41LCB4ICogeCk7Cn0KCi8qKiBMb2kgbm9ybWFsZSBjZW50csOpZSByw6lkdWl0ZSA6IFAoWiA8PSB6KS4gKi8KZnVuY3Rpb24gbm9ybWFsQ0RGKHopIHsKICByZXR1cm4gMC41ICogKDEgKyBlcmYoeiAvIE1hdGguU1FSVDIpKTsKfQoKLyoqIHAtdmFsdWUgYmlsYXTDqXJhbGUgZCd1biB6LiAqLwpmdW5jdGlvbiB6VHdvVGFpbGVkUCh6KSB7CiAgcmV0dXJuIDIgKiAoMSAtIG5vcm1hbENERihNYXRoLmFicyh6KSkpOwp9CgovKiogTG9nIGRlIGxhIGZvbmN0aW9uIGdhbW1hIOKAlCBhcHByb3hpbWF0aW9uIGRlIExhbmN6b3MuICovCmZ1bmN0aW9uIGxvZ0dhbW1hKHgpIHsKICBjb25zdCBjID0gWzc2LjE4MDA5MTcyOTQ3MTQ2LCAtODYuNTA1MzIwMzI5NDE2NzcsIDI0LjAxNDA5ODI0MDgzMDkxLAogICAgICAgICAgICAgLTEuMjMxNzM5NTcyNDUwMTU1LCAwLjEyMDg2NTA5NzM4NjYxNzllLTIsIC0wLjUzOTUyMzkzODQ5NTNlLTVdOwogIGxldCB5ID0geCwgdG1wID0geCArIDUuNTsKICB0bXAgLT0gKHggKyAwLjUpICogTWF0aC5sb2codG1wKTsKICBsZXQgc2VyID0gMS4wMDAwMDAwMDAxOTAwMTU7CiAgZm9yIChsZXQgaiA9IDA7IGogPCA2OyBqKyspIHNlciArPSBjW2pdIC8gKyt5OwogIHJldHVybiAtdG1wICsgTWF0aC5sb2coMi41MDY2MjgyNzQ2MzEwMDA1ICogc2VyIC8geCk7Cn0KCi8qKiBGcmFjdGlvbiBjb250aW51ZSBkZSBsYSBmb25jdGlvbiBiw6p0YSBpbmNvbXBsw6h0ZSAoTGVudHopLiAqLwpmdW5jdGlvbiBiZXRhQ29udGludWVkRnJhY3Rpb24oYSwgYiwgeCkgewogIGNvbnN0IE1BWElUID0gMzAwLCBFUFMgPSAzZS0xMiwgRlBNSU4gPSAxZS0zMDA7CiAgY29uc3QgcWFiID0gYSArIGIsIHFhcCA9IGEgKyAxLCBxYW0gPSBhIC0gMTsKICBsZXQgYyA9IDEsIGQgPSAxIC0gcWFiICogeCAvIHFhcDsKICBpZiAoTWF0aC5hYnMoZCkgPCBGUE1JTikgZCA9IEZQTUlOOwogIGQgPSAxIC8gZDsKICBsZXQgaCA9IGQ7CiAgZm9yIChsZXQgbSA9IDE7IG0gPD0gTUFYSVQ7IG0rKykgewogICAgY29uc3QgbTIgPSAyICogbTsKICAgIGxldCBhYSA9IG0gKiAoYiAtIG0pICogeCAvICgocWFtICsgbTIpICogKGEgKyBtMikpOwogICAgZCA9IDEgKyBhYSAqIGQ7IGlmIChNYXRoLmFicyhkKSA8IEZQTUlOKSBkID0gRlBNSU47CiAgICBjID0gMSArIGFhIC8gYzsgaWYgKE1hdGguYWJzKGMpIDwgRlBNSU4pIGMgPSBGUE1JTjsKICAgIGQgPSAxIC8gZDsgaCAqPSBkICogYzsKICAgIGFhID0gLShhICsgbSkgKiAocWFiICsgbSkgKiB4IC8gKChhICsgbTIpICogKHFhcCArIG0yKSk7CiAgICBkID0gMSArIGFhICogZDsgaWYgKE1hdGguYWJzKGQpIDwgRlBNSU4pIGQgPSBGUE1JTjsKICAgIGMgPSAxICsgYWEgLyBjOyBpZiAoTWF0aC5hYnMoYykgPCBGUE1JTikgYyA9IEZQTUlOOwogICAgZCA9IDEgLyBkOwogICAgY29uc3QgZGVsID0gZCAqIGM7IGggKj0gZGVsOwogICAgaWYgKE1hdGguYWJzKGRlbCAtIDEpIDwgRVBTKSBicmVhazsKICB9CiAgcmV0dXJuIGg7Cn0KCi8qKiBGb25jdGlvbiBiw6p0YSBpbmNvbXBsw6h0ZSByw6lndWxhcmlzw6llIElfeChhLCBiKS4gKi8KZnVuY3Rpb24gaW5jb21wbGV0ZUJldGEoYSwgYiwgeCkgewogIGlmICh4IDw9IDApIHJldHVybiAwOwogIGlmICh4ID49IDEpIHJldHVybiAxOwogIGNvbnN0IGJ0ID0gTWF0aC5leHAobG9nR2FtbWEoYSArIGIpIC0gbG9nR2FtbWEoYSkgLSBsb2dHYW1tYShiKQogICAgICAgICAgICAgICAgICAgICAgKyBhICogTWF0aC5sb2coeCkgKyBiICogTWF0aC5sb2coMSAtIHgpKTsKICBpZiAoeCA8IChhICsgMSkgLyAoYSArIGIgKyAyKSkgewogICAgcmV0dXJuIGJ0ICogYmV0YUNvbnRpbnVlZEZyYWN0aW9uKGEsIGIsIHgpIC8gYTsKICB9CiAgcmV0dXJuIDEgLSBidCAqIGJldGFDb250aW51ZWRGcmFjdGlvbihiLCBhLCAxIC0geCkgLyBiOwp9CgovKiogcC12YWx1ZSBiaWxhdMOpcmFsZSBkJ3VuIHQgZGUgU3R1ZGVudCDDoCBkZiBkZWdyw6lzIGRlIGxpYmVydMOpLiAqLwpmdW5jdGlvbiB0VHdvVGFpbGVkUCh0LCBkZikgewogIGlmICghaXNGaW5pdGUodCkgfHwgZGYgPD0gMCkgcmV0dXJuIDE7CiAgY29uc3QgeCA9IGRmIC8gKGRmICsgdCAqIHQpOwogIHJldHVybiBpbmNvbXBsZXRlQmV0YShkZiAvIDIsIDAuNSwgeCk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAzLiBURVNUUyBERSBTSUdOSUZJQ0FUSVZJVEUKICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioKICogQ29tcGFyYWlzb24gZGUgZGV1eCBwcm9wb3J0aW9ucyBpbmTDqXBlbmRhbnRlcy4KICogVGVzdCB6IGJpbGF0w6lyYWwsIHZhcmlhbmNlIGdyb3Vww6llIChwb29sZWQpLgogKiAgIHBfcG9vbCA9ICh4MSArIHgyKSAvIChuMSArIG4yKQogKiAgIHogPSAocDEgLSBwMikgLyBzcXJ0KCBwX3Bvb2wgKDEgLSBwX3Bvb2wpICgxL24xICsgMS9uMikgKQogKi8KZnVuY3Rpb24gelRlc3RQcm9wb3J0aW9ucyh4MSwgbjEsIHgyLCBuMikgewogIGlmIChuMSA8IE1JTl9CQVNFX1RFU1QgfHwgbjIgPCBNSU5fQkFTRV9URVNUKSB7CiAgICByZXR1cm4geyB0ZXN0ZWQ6IGZhbHNlLCByZWFzb246ICdiYXNlIDwgJyArIE1JTl9CQVNFX1RFU1QgfTsKICB9CiAgY29uc3QgcDEgPSB4MSAvIG4xLCBwMiA9IHgyIC8gbjI7CiAgY29uc3QgcFBvb2wgPSAoeDEgKyB4MikgLyAobjEgKyBuMik7CiAgaWYgKHBQb29sIDw9IDAgfHwgcFBvb2wgPj0gMSkgewogICAgcmV0dXJuIHsgdGVzdGVkOiBmYWxzZSwgcmVhc29uOiAncHJvcG9ydGlvbiBkw6lnw6luw6lyw6llICgwIG91IDEwMCAlIHBhcnRvdXQpJyB9OwogIH0KICBjb25zdCBzZSA9IE1hdGguc3FydChwUG9vbCAqICgxIC0gcFBvb2wpICogKDEgLyBuMSArIDEgLyBuMikpOwogIGlmIChzZSA9PT0gMCkgcmV0dXJuIHsgdGVzdGVkOiBmYWxzZSwgcmVhc29uOiAnZXJyZXVyIHR5cGUgbnVsbGUnIH07CiAgY29uc3QgeiA9IChwMSAtIHAyKSAvIHNlOwogIHJldHVybiB7IHRlc3RlZDogdHJ1ZSwgcDE6IHAxLCBwMjogcDIsIHBQb29sOiBwUG9vbCwgc2U6IHNlLAogICAgICAgICAgIHo6IHosIHA6IHpUd29UYWlsZWRQKHopIH07Cn0KCi8qKgogKiBDb21wYXJhaXNvbiBkZSBkZXV4IG1veWVubmVzIOKAlCB0ZXN0IHQgZGUgV2VsY2ggKHZhcmlhbmNlcyBpbsOpZ2FsZXMpLgogKiAgIHQgID0gKG0xIC0gbTIpIC8gc3FydCggczHCsi9uMSArIHMywrIvbjIgKQogKiAgIGRmID0gKHMxwrIvbjEgKyBzMsKyL24yKcKyIC8gWyAoczHCsi9uMSnCsi8objEtMSkgKyAoczLCsi9uMinCsi8objItMSkgXQogKi8KZnVuY3Rpb24gd2VsY2hUVGVzdChtMSwgczEsIG4xLCBtMiwgczIsIG4yKSB7CiAgaWYgKG4xIDwgTUlOX0JBU0VfVEVTVCB8fCBuMiA8IE1JTl9CQVNFX1RFU1QpIHsKICAgIHJldHVybiB7IHRlc3RlZDogZmFsc2UsIHJlYXNvbjogJ2Jhc2UgPCAnICsgTUlOX0JBU0VfVEVTVCB9OwogIH0KICBjb25zdCB2MSA9IHMxICogczEgLyBuMSwgdjIgPSBzMiAqIHMyIC8gbjI7CiAgY29uc3Qgc2UgPSBNYXRoLnNxcnQodjEgKyB2Mik7CiAgaWYgKHNlID09PSAwKSByZXR1cm4geyB0ZXN0ZWQ6IGZhbHNlLCByZWFzb246ICd2YXJpYW5jZSBudWxsZScgfTsKICBjb25zdCB0ID0gKG0xIC0gbTIpIC8gc2U7CiAgY29uc3QgZGYgPSBNYXRoLnBvdyh2MSArIHYyLCAyKSAvCiAgICAgICAgICAgICAodjEgKiB2MSAvIChuMSAtIDEpICsgdjIgKiB2MiAvIChuMiAtIDEpKTsKICByZXR1cm4geyB0ZXN0ZWQ6IHRydWUsIHYxOiB2MSwgdjI6IHYyLCBzZTogc2UsIHQ6IHQsIGRmOiBkZiwKICAgICAgICAgICBwOiB0VHdvVGFpbGVkUCh0LCBkZikgfTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgIDQuIFRZUEFHRSBERVMgVkFSSUFCTEVTCiAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKZnVuY3Rpb24gaW5mZXJUeXBlKHZhbHVlcykgewogIGNvbnN0IGNsZWFuID0gdmFsdWVzLmZpbHRlcih2ID0+ICFpc01pc3NpbmcodiwgZmFsc2UsIGZhbHNlKSk7CiAgY29uc3QgZGlzdGluY3QgPSBuZXcgU2V0KGNsZWFuLm1hcChTdHJpbmcpKTsKICBjb25zdCBuRGlzdGluY3QgPSBkaXN0aW5jdC5zaXplOwoKICBpZiAoY2xlYW4ubGVuZ3RoID4gMCAmJiBuRGlzdGluY3QgPT09IGNsZWFuLmxlbmd0aCAmJiBuRGlzdGluY3QgPiAzMCkgewogICAgcmV0dXJuICdpZCc7CiAgfQogIGNvbnN0IGFsbE51bWVyaWMgPSBjbGVhbi5ldmVyeSh2ID0+IHYgIT09ICcnICYmICFpc05hTihOdW1iZXIodikpKTsKICBpZiAoYWxsTnVtZXJpYykgewogICAgY29uc3QgYWxsSW50ZWdlciA9IGNsZWFuLmV2ZXJ5KHYgPT4gTnVtYmVyLmlzSW50ZWdlcihOdW1iZXIodikpKTsKICAgIGlmIChhbGxJbnRlZ2VyICYmIG5EaXN0aW5jdCA8PSAxNSkgcmV0dXJuICdjYXRlZ29yaWNhbCc7CiAgICByZXR1cm4gJ251bWVyaWMnOwogIH0KICBpZiAobkRpc3RpbmN0IDw9IDMwKSByZXR1cm4gJ2NhdGVnb3JpY2FsJzsKICByZXR1cm4gJ3RleHQnOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgNS4gQ09OU1RSVUNUSU9OIERFIExBIEJBTk5JRVJFCiAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKY29uc3QgTEVUVEVSUyA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWic7CgpmdW5jdGlvbiBjb2x1bW5MZXR0ZXIoaSkgewogIGlmIChpIDwgMjYpIHJldHVybiBMRVRURVJTW2ldOwogIHJldHVybiBMRVRURVJTW01hdGguZmxvb3IoaSAvIDI2KSAtIDFdICsgTEVUVEVSU1tpICUgMjZdOwp9CgovKioKICogQ29uc3RydWl0IGxlcyBjb2xvbm5lcyBkZSBsYSBiYW5uacOocmUuCiAqIENoYXF1ZSBjb2xvbm5lIHBvcnRlIGwnZW5zZW1ibGUgZGVzIGluZGV4IGRlIHLDqXBvbmRhbnRzIHF1aSBsYSBjb21wb3NlbnQsCiAqIGV0IHVuIGdyb3VwSWQgOiBTRVVMRVMgbGVzIGNvbG9ubmVzIGRlIG3Dqm1lIGdyb3VwSWQgc29udCBjb21wYXJhYmxlcyBlbnRyZQogKiBlbGxlcyAoZGV1eCB2YXJpYWJsZXMgZGUgYmFubmnDqHJlIGRpZmbDqXJlbnRlcyBzZSByZWNvdXBlbnQg4oCUIGNvbXBhcmVyCiAqICJIb21tZXMiIMOgICIyNS0zNCBhbnMiIHZpb2xlcmFpdCBsJ2h5cG90aMOoc2UgZCdpbmTDqXBlbmRhbmNlIGR1IHRlc3QpLgogKi8KZnVuY3Rpb24gYnVpbGRCYW5uZXIoZGF0YSwgYmFubmVyVmFycywgbWV0YSwgb3B0aW9ucykgewogIGNvbnN0IG9wdHMgPSBvcHRpb25zIHx8IHt9OwogIGNvbnN0IHRyZWF0OTkgPSBvcHRzLnRyZWF0OTlBc01pc3NpbmcgIT09IGZhbHNlOwogIGNvbnN0IG4gPSBkYXRhLmxlbmd0aDsKICBjb25zdCBjb2x1bW5zID0gW3sKICAgIGtleTogJ1RPVEFMJywgZ3JvdXBJZDogbnVsbCwgdmFyTmFtZTogbnVsbCwKICAgIGxhYmVsOiAnVG90YWwnLCBsZXR0ZXI6IG51bGwsCiAgICBpbmRpY2VzOiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBuIH0sIChfLCBpKSA9PiBpKQogIH1dOwoKICBsZXQgbGV0dGVySW5kZXggPSAwOwogIGJhbm5lclZhcnMuZm9yRWFjaCgodmFyTmFtZSwgZ0lkeCkgPT4gewogICAgY29uc3QgaXNDYXQgPSBtZXRhW3Zhck5hbWVdLnR5cGUgPT09ICdjYXRlZ29yaWNhbCc7CiAgICBjb25zdCBidWNrZXRzID0gbmV3IE1hcCgpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgY29uc3QgcmF3ID0gZGF0YVtpXVt2YXJOYW1lXTsKICAgICAgaWYgKGlzTWlzc2luZyhyYXcsIGlzQ2F0LCB0cmVhdDk5KSkgY29udGludWU7CiAgICAgIGNvbnN0IGtleSA9IFN0cmluZyhyYXcpLnRyaW0oKTsKICAgICAgaWYgKCFidWNrZXRzLmhhcyhrZXkpKSBidWNrZXRzLnNldChrZXksIFtdKTsKICAgICAgYnVja2V0cy5nZXQoa2V5KS5wdXNoKGkpOwogICAgfQogICAgY29uc3Qga2V5cyA9IEFycmF5LmZyb20oYnVja2V0cy5rZXlzKCkpLnNvcnQoc29ydENvZGVzKTsKICAgIGtleXMuZm9yRWFjaChrID0+IHsKICAgICAgY29sdW1ucy5wdXNoKHsKICAgICAgICBrZXk6IHZhck5hbWUgKyAnPScgKyBrLAogICAgICAgIGdyb3VwSWQ6ICdHJyArIGdJZHgsCiAgICAgICAgdmFyTmFtZTogdmFyTmFtZSwKICAgICAgICBsYWJlbDogbGFiZWxPZihtZXRhLCB2YXJOYW1lLCBrKSwKICAgICAgICBsZXR0ZXI6IGNvbHVtbkxldHRlcihsZXR0ZXJJbmRleCsrKSwKICAgICAgICBpbmRpY2VzOiBidWNrZXRzLmdldChrKQogICAgICB9KTsKICAgIH0pOwogIH0pOwogIHJldHVybiBjb2x1bW5zOwp9CgpmdW5jdGlvbiBzb3J0Q29kZXMoYSwgYikgewogIGNvbnN0IG5hID0gTnVtYmVyKGEpLCBuYiA9IE51bWJlcihiKTsKICBpZiAoIWlzTmFOKG5hKSAmJiAhaXNOYU4obmIpKSByZXR1cm4gbmEgLSBuYjsKICByZXR1cm4gU3RyaW5nKGEpLmxvY2FsZUNvbXBhcmUoU3RyaW5nKGIpKTsKfQoKZnVuY3Rpb24gbGFiZWxPZihtZXRhLCB2YXJOYW1lLCBjb2RlKSB7CiAgY29uc3QgbGFiZWxzID0gbWV0YVt2YXJOYW1lXSAmJiBtZXRhW3Zhck5hbWVdLmxhYmVsczsKICByZXR1cm4gKGxhYmVscyAmJiBsYWJlbHNbY29kZV0gIT09IHVuZGVmaW5lZCkgPyBsYWJlbHNbY29kZV0gOiBTdHJpbmcoY29kZSk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICA2LiBUQUJVTEFUSU9OIEQnVU5FIFZBUklBQkxFIENBVEVHT1JJRUxMRQogICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCmZ1bmN0aW9uIHRhYnVsYXRlQ2F0ZWdvcmljYWwoZGF0YSwgcm93VmFyLCBjb2x1bW5zLCBtZXRhLCBvcHRpb25zKSB7CiAgY29uc3Qgb3B0cyA9IG9wdGlvbnMgfHwge307CiAgY29uc3QgYWxwaGEgPSBvcHRzLmFscGhhICE9PSB1bmRlZmluZWQgPyBvcHRzLmFscGhhIDogMC4wNTsKICBjb25zdCB0cmVhdDk5ID0gb3B0cy50cmVhdDk5QXNNaXNzaW5nICE9PSBmYWxzZTsKCiAgLy8gTW9kYWxpdMOpcyBwcsOpc2VudGVzLCBkYW5zIGwnb3JkcmUgZMOpZmluaSBwYXIgbWV0YSBzaSBmb3VybmkuCiAgY29uc3Qgc2VlbiA9IG5ldyBTZXQoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHsKICAgIGNvbnN0IHJhdyA9IGRhdGFbaV1bcm93VmFyXTsKICAgIGlmIChpc01pc3NpbmcocmF3LCB0cnVlLCB0cmVhdDk5KSkgY29udGludWU7CiAgICBzZWVuLmFkZChTdHJpbmcocmF3KS50cmltKCkpOwogIH0KICBsZXQgY2F0ZWdvcmllcyA9IEFycmF5LmZyb20oc2Vlbikuc29ydChzb3J0Q29kZXMpOwogIGlmIChtZXRhW3Jvd1Zhcl0gJiYgbWV0YVtyb3dWYXJdLm9yZGVyKSB7CiAgICBjb25zdCBvcmQgPSBtZXRhW3Jvd1Zhcl0ub3JkZXIubWFwKFN0cmluZyk7CiAgICBjYXRlZ29yaWVzID0gb3JkLmZpbHRlcihjID0+IHNlZW4uaGFzKGMpKQogICAgICAgICAgICAgICAgICAgIC5jb25jYXQoY2F0ZWdvcmllcy5maWx0ZXIoYyA9PiBvcmQuaW5kZXhPZihjKSA9PT0gLTEpKTsKICB9CgogIC8vIEJhc2VzIGV0IGVmZmVjdGlmcyBwYXIgY29sb25uZS4KICBjb25zdCBiYXNlcyA9IFtdLCBjb3VudHMgPSBbXTsKICBjb2x1bW5zLmZvckVhY2goY29sID0+IHsKICAgIGNvbnN0IGMgPSB7fTsKICAgIGNhdGVnb3JpZXMuZm9yRWFjaChjYXQgPT4geyBjW2NhdF0gPSAwOyB9KTsKICAgIGxldCBiYXNlID0gMDsKICAgIGNvbC5pbmRpY2VzLmZvckVhY2goaSA9PiB7CiAgICAgIGNvbnN0IHJhdyA9IGRhdGFbaV1bcm93VmFyXTsKICAgICAgaWYgKGlzTWlzc2luZyhyYXcsIHRydWUsIHRyZWF0OTkpKSByZXR1cm47CiAgICAgIGNbU3RyaW5nKHJhdykudHJpbSgpXSsrOwogICAgICBiYXNlKys7CiAgICB9KTsKICAgIGJhc2VzLnB1c2goYmFzZSk7CiAgICBjb3VudHMucHVzaChjKTsKICB9KTsKCiAgLy8gVGVzdHMgZGV1eCDDoCBkZXV4LCB1bmlxdWVtZW50IMOgIGwnaW50w6lyaWV1ciBkJ3VuIG3Dqm1lIGdyb3VwZSBkZSBiYW5uacOocmUuCiAgY29uc3Qgcm93cyA9IGNhdGVnb3JpZXMubWFwKGNhdCA9PiB7CiAgICBjb25zdCBjZWxscyA9IGNvbHVtbnMubWFwKChjb2wsIGNpKSA9PiAoewogICAgICBjb3VudDogY291bnRzW2NpXVtjYXRdLAogICAgICBiYXNlOiBiYXNlc1tjaV0sCiAgICAgIHBjdDogYmFzZXNbY2ldID4gMCA\/IGNvdW50c1tjaV1bY2F0XSAvIGJhc2VzW2NpXSA6IG51bGwsCiAgICAgIGhpZ2hlclRoYW46IFtdLAogICAgICBsb3dCYXNlOiBiYXNlc1tjaV0gPCBNSU5fQkFTRV9URVNULAogICAgICBmcmFnaWxlOiBiYXNlc1tjaV0gPCBNSU5fQkFTRV9XQVJOCiAgICB9KSk7CgogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb2x1bW5zLmxlbmd0aDsgaSsrKSB7CiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY29sdW1ucy5sZW5ndGg7IGorKykgewogICAgICAgIGlmIChpID09PSBqKSBjb250aW51ZTsKICAgICAgICBjb25zdCBBID0gY29sdW1uc1tpXSwgQiA9IGNvbHVtbnNbal07CiAgICAgICAgaWYgKEEuZ3JvdXBJZCA9PT0gbnVsbCB8fCBCLmdyb3VwSWQgPT09IG51bGwpIGNvbnRpbnVlOyAvLyBUb3RhbCBleGNsdQogICAgICAgIGlmIChBLmdyb3VwSWQgIT09IEIuZ3JvdXBJZCkgY29udGludWU7ICAgICAgICAgICAgICAgICAgLy8gcsOoZ2xlIGRlIGdhcmRlCiAgICAgICAgY29uc3QgciA9IHpUZXN0UHJvcG9ydGlvbnMoY291bnRzW2ldW2NhdF0sIGJhc2VzW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50c1tqXVtjYXRdLCBiYXNlc1tqXSk7CiAgICAgICAgaWYgKHIudGVzdGVkICYmIHIucCA8IGFscGhhICYmIHIueiA+IDApIHsKICAgICAgICAgIGNlbGxzW2ldLmhpZ2hlclRoYW4ucHVzaChCLmxldHRlcik7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICByZXR1cm4geyBjYXRlZ29yeTogY2F0LCBsYWJlbDogbGFiZWxPZihtZXRhLCByb3dWYXIsIGNhdCksIGNlbGxzOiBjZWxscyB9OwogIH0pOwoKICByZXR1cm4geyB2YXJpYWJsZTogcm93VmFyLCB0eXBlOiAnY2F0ZWdvcmljYWwnLCBiYXNlczogYmFzZXMsIHJvd3M6IHJvd3MgfTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgIDcuIFRBQlVMQVRJT04gRCdVTkUgVkFSSUFCTEUgTlVNRVJJUVVFCiAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKZnVuY3Rpb24gZGVzY3JpYmUodmFsdWVzKSB7CiAgY29uc3QgbiA9IHZhbHVlcy5sZW5ndGg7CiAgaWYgKG4gPT09IDApIHJldHVybiB7IG46IDAsIG1lYW46IG51bGwsIHNkOiBudWxsLCBtZWRpYW46IG51bGwsIG1pbjogbnVsbCwgbWF4OiBudWxsIH07CiAgY29uc3Qgc29ydGVkID0gdmFsdWVzLnNsaWNlKCkuc29ydCgoYSwgYikgPT4gYSAtIGIpOwogIGNvbnN0IG1lYW4gPSB2YWx1ZXMucmVkdWNlKChzLCB2KSA9PiBzICsgdiwgMCkgLyBuOwogIGNvbnN0IHZhclNhbXBsZSA9IG4gPiAxCiAgICA\/IHZhbHVlcy5yZWR1Y2UoKHMsIHYpID0+IHMgKyAodiAtIG1lYW4pICogKHYgLSBtZWFuKSwgMCkgLyAobiAtIDEpCiAgICA6IDA7CiAgY29uc3QgbWVkaWFuID0gbiAlIDIKICAgID8gc29ydGVkWyhuIC0gMSkgLyAyXQogICAgOiAoc29ydGVkW24gLyAyIC0gMV0gKyBzb3J0ZWRbbiAvIDJdKSAvIDI7CiAgcmV0dXJuIHsgbjogbiwgbWVhbjogbWVhbiwgc2Q6IE1hdGguc3FydCh2YXJTYW1wbGUpLCBtZWRpYW46IG1lZGlhbiwKICAgICAgICAgICBtaW46IHNvcnRlZFswXSwgbWF4OiBzb3J0ZWRbbiAtIDFdIH07Cn0KCmZ1bmN0aW9uIHRhYnVsYXRlTnVtZXJpYyhkYXRhLCByb3dWYXIsIGNvbHVtbnMsIG9wdGlvbnMpIHsKICBjb25zdCBvcHRzID0gb3B0aW9ucyB8fCB7fTsKICBjb25zdCBhbHBoYSA9IG9wdHMuYWxwaGEgIT09IHVuZGVmaW5lZCA\/IG9wdHMuYWxwaGEgOiAwLjA1OwoKICBjb25zdCBzdGF0cyA9IGNvbHVtbnMubWFwKGNvbCA9PiB7CiAgICBjb25zdCB2YWxzID0gW107CiAgICBjb2wuaW5kaWNlcy5mb3JFYWNoKGkgPT4gewogICAgICBjb25zdCByYXcgPSBkYXRhW2ldW3Jvd1Zhcl07CiAgICAgIGlmIChpc01pc3NpbmcocmF3LCBmYWxzZSwgZmFsc2UpKSByZXR1cm47ICAvLyA5OS85OTkgPSB2YWxldXJzIGzDqWdpdGltZXMKICAgICAgY29uc3QgdiA9IE51bWJlcihyYXcpOwogICAgICBpZiAoIWlzTmFOKHYpKSB2YWxzLnB1c2godik7CiAgICB9KTsKICAgIHJldHVybiBkZXNjcmliZSh2YWxzKTsKICB9KTsKCiAgY29uc3QgaGlnaGVyVGhhbiA9IGNvbHVtbnMubWFwKCgpID0+IFtdKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbHVtbnMubGVuZ3RoOyBpKyspIHsKICAgIGZvciAobGV0IGogPSAwOyBqIDwgY29sdW1ucy5sZW5ndGg7IGorKykgewogICAgICBpZiAoaSA9PT0gaikgY29udGludWU7CiAgICAgIGNvbnN0IEEgPSBjb2x1bW5zW2ldLCBCID0gY29sdW1uc1tqXTsKICAgICAgaWYgKEEuZ3JvdXBJZCA9PT0gbnVsbCB8fCBCLmdyb3VwSWQgPT09IG51bGwpIGNvbnRpbnVlOwogICAgICBpZiAoQS5ncm91cElkICE9PSBCLmdyb3VwSWQpIGNvbnRpbnVlOwogICAgICBjb25zdCByID0gd2VsY2hUVGVzdChzdGF0c1tpXS5tZWFuLCBzdGF0c1tpXS5zZCwgc3RhdHNbaV0ubiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHNbal0ubWVhbiwgc3RhdHNbal0uc2QsIHN0YXRzW2pdLm4pOwogICAgICBpZiAoci50ZXN0ZWQgJiYgci5wIDwgYWxwaGEgJiYgci50ID4gMCkgaGlnaGVyVGhhbltpXS5wdXNoKEIubGV0dGVyKTsKICAgIH0KICB9CgogIHJldHVybiB7IHZhcmlhYmxlOiByb3dWYXIsIHR5cGU6ICdudW1lcmljJywgc3RhdHM6IHN0YXRzLCBoaWdoZXJUaGFuOiBoaWdoZXJUaGFuIH07Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKY29uc3QgZW5naW5lID0gewogIGlzTWlzc2luZywgaW5mZXJUeXBlLCBidWlsZEJhbm5lciwgY29sdW1uTGV0dGVyLAogIHRhYnVsYXRlQ2F0ZWdvcmljYWwsIHRhYnVsYXRlTnVtZXJpYywgZGVzY3JpYmUsCiAgelRlc3RQcm9wb3J0aW9ucywgd2VsY2hUVGVzdCwKICBub3JtYWxDREYsIHpUd29UYWlsZWRQLCB0VHdvVGFpbGVkUCwgaW5jb21wbGV0ZUJldGEsIGVyZiwgbG9nR2FtbWEsIGdhbW1hUCwKICBNSU5fQkFTRV9URVNULCBNSU5fQkFTRV9XQVJOLCBNSVNTSU5HX0NPREVTCn07CgoKaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB3aW5kb3cuQ3Jvc3N0YWJFbmdpbmUgPSBlbmdpbmU7CgoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICBJTlRFUkZBQ0UKICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwooZnVuY3Rpb24oKXsKJ3VzZSBzdHJpY3QnOwp2YXIgRSA9IENyb3NzdGFiRW5naW5lOwp2YXIgJCA9IGZ1bmN0aW9uKGlkKXsgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTsgfTsKCnZhciBTID0gewogIGZpbGVOYW1lOicnLCBoZWFkZXJzOltdLCBkYXRhOltdLCBtZXRhOnt9LAogIGJhbm5lcjpbXSwgcm93VmFyczpbXSwgY29sdW1uczpbXSwgdGFibGVzOltdLCBhbHBoYTowLjA1LCB0cmVhdDk5OnRydWUKfTsKCi8qIC0tLS0tLS0tLS0gdXRpbGl0YWlyZXMgLS0tLS0tLS0tLSAqLwpmdW5jdGlvbiBlc2Mocyl7CiAgcmV0dXJuIFN0cmluZyhzKS5yZXBsYWNlKC9bJjw+Il0vZywgZnVuY3Rpb24oYyl7CiAgICByZXR1cm4geycmJzonJmFtcDsnLCc8JzonJmx0OycsJz4nOicmZ3Q7JywnIic6JyZxdW90Oyd9W2NdOwogIH0pOwp9CmZ1bmN0aW9uIHBjdCh4KXsgcmV0dXJuICh4KjEwMCkudG9GaXhlZCgxKSArICclJzsgfQpmdW5jdGlvbiBvdmVybGF5KG9uLCB0ZXh0LCBmcmFjKXsKICAkKCdvdmVybGF5JykuY2xhc3NMaXN0LnRvZ2dsZSgnb24nLCAhIW9uKTsKICBpZih0ZXh0KSAkKCdvdlRleHQnKS50ZXh0Q29udGVudCA9IHRleHQ7CiAgaWYoZnJhYyAhPT0gdW5kZWZpbmVkKSAkKCdvdkJhcicpLnN0eWxlLndpZHRoID0gTWF0aC5yb3VuZChmcmFjKjEwMCkgKyAnJSc7Cn0KZnVuY3Rpb24gYWxlcnRCb3goZWwsIGtpbmQsIGh0bWwpewogIGVsLmlubmVySFRNTCA9IGh0bWwgPyAnPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtJyArIGtpbmQgKyAnIj4nICsgaHRtbCArICc8L2Rpdj4nIDogJyc7Cn0KCi8qIC0tLS0tLS0tLS0gbGVjdHVyZSBkZSBmaWNoaWVyIC0tLS0tLS0tLS0gKi8KZnVuY3Rpb24gZGVjb2RlQnl0ZXMoYnVmKXsKICB0cnl7CiAgICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCd1dGYtOCcsIHtmYXRhbDp0cnVlfSkuZGVjb2RlKGJ1Zik7CiAgfWNhdGNoKGUpewogICAgcmV0dXJuIG5ldyBUZXh0RGVjb2Rlcignd2luZG93cy0xMjUyJykuZGVjb2RlKGJ1Zik7CiAgfQp9CmZ1bmN0aW9uIGRldGVjdERlbGltaXRlcihsaW5lKXsKICB2YXIgYmVzdCA9ICcsJywgYmVzdE4gPSAtMTsKICBbJywnLCc7JywnXHQnLCd8J10uZm9yRWFjaChmdW5jdGlvbihkKXsKICAgIHZhciBuID0gMCwgcSA9IGZhbHNlOwogICAgZm9yKHZhciBpPTA7aTxsaW5lLmxlbmd0aDtpKyspewogICAgICB2YXIgYyA9IGxpbmVbaV07CiAgICAgIGlmKGMgPT09ICciJykgcSA9ICFxOwogICAgICBlbHNlIGlmKGMgPT09IGQgJiYgIXEpIG4rKzsKICAgIH0KICAgIGlmKG4gPiBiZXN0Til7IGJlc3ROID0gbjsgYmVzdCA9IGQ7IH0KICB9KTsKICByZXR1cm4gYmVzdDsKfQpmdW5jdGlvbiBwYXJzZUNTVih0ZXh0LCBkZWxpbSl7CiAgdmFyIHJvd3MgPSBbXSwgcm93ID0gW10sIGZpZWxkID0gJycsIHEgPSBmYWxzZSwgaSA9IDA7CiAgaWYodGV4dC5jaGFyQ29kZUF0KDApID09PSAweEZFRkYpIHRleHQgPSB0ZXh0LnNsaWNlKDEpOwogIHdoaWxlKGkgPCB0ZXh0Lmxlbmd0aCl7CiAgICB2YXIgYyA9IHRleHRbaV07CiAgICBpZihxKXsKICAgICAgaWYoYyA9PT0gJyInKXsKICAgICAgICBpZih0ZXh0W2krMV0gPT09ICciJyl7IGZpZWxkICs9ICciJzsgaSArPSAyOyBjb250aW51ZTsgfQogICAgICAgIHEgPSBmYWxzZTsgaSsrOyBjb250aW51ZTsKICAgICAgfQogICAgICBmaWVsZCArPSBjOyBpKys7IGNvbnRpbnVlOwogICAgfQogICAgaWYoYyA9PT0gJyInKXsgcSA9IHRydWU7IGkrKzsgY29udGludWU7IH0KICAgIGlmKGMgPT09IGRlbGltKXsgcm93LnB1c2goZmllbGQpOyBmaWVsZCA9ICcnOyBpKys7IGNvbnRpbnVlOyB9CiAgICBpZihjID09PSAnXHInKXsgaSsrOyBjb250aW51ZTsgfQogICAgaWYoYyA9PT0gJ1xuJyl7IHJvdy5wdXNoKGZpZWxkKTsgcm93cy5wdXNoKHJvdyk7IHJvdyA9IFtdOyBmaWVsZCA9ICcnOyBpKys7IGNvbnRpbnVlOyB9CiAgICBmaWVsZCArPSBjOyBpKys7CiAgfQogIGlmKGZpZWxkLmxlbmd0aCB8fCByb3cubGVuZ3RoKXsgcm93LnB1c2goZmllbGQpOyByb3dzLnB1c2gocm93KTsgfQogIHJldHVybiByb3dzLmZpbHRlcihmdW5jdGlvbihyKXsgcmV0dXJuIHIubGVuZ3RoID4gMSB8fCAoclswXSB8fCAnJykudHJpbSgpICE9PSAnJzsgfSk7Cn0KZnVuY3Rpb24gZnJvbU1hdHJpeChtYXRyaXgpewogIGlmKCFtYXRyaXggfHwgIW1hdHJpeC5sZW5ndGggfHwgIW1hdHJpeFswXSB8fCAhbWF0cml4WzBdLmxlbmd0aCl7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBmaWxlIGFwcGVhcnMgdG8gYmUgZW1wdHkg4oCUIG5vIGhlYWRlciByb3cgd2FzIGZvdW5kLicpOwogIH0KICB2YXIgaGVhZGVycyA9IG1hdHJpeFswXS5tYXAoZnVuY3Rpb24oaCwgaSl7CiAgICB2YXIgcyA9IFN0cmluZyhoID09PSB1bmRlZmluZWQgfHwgaCA9PT0gbnVsbCA\/ICcnIDogaCkudHJpbSgpOwogICAgcmV0dXJuIHMgfHwgKCdjb2x1bW5fJyArIChpKzEpKTsKICB9KTsKICB2YXIgc2Vlbk5hbWVzID0ge307CiAgaGVhZGVycyA9IGhlYWRlcnMubWFwKGZ1bmN0aW9uKGgpewogICAgaWYoc2Vlbk5hbWVzW2hdKXsgc2Vlbk5hbWVzW2hdKys7IHJldHVybiBoICsgJ18nICsgc2Vlbk5hbWVzW2hdOyB9CiAgICBzZWVuTmFtZXNbaF0gPSAxOyByZXR1cm4gaDsKICB9KTsKICB2YXIgZGF0YSA9IFtdOwogIGZvcih2YXIgciA9IDE7IHIgPCBtYXRyaXgubGVuZ3RoOyByKyspewogICAgdmFyIG8gPSB7fSwgYW55ID0gZmFsc2U7CiAgICBmb3IodmFyIGMgPSAwOyBjIDwgaGVhZGVycy5sZW5ndGg7IGMrKyl7CiAgICAgIHZhciB2ID0gbWF0cml4W3JdW2NdOwogICAgICB2ID0gKHYgPT09IHVuZGVmaW5lZCB8fCB2ID09PSBudWxsKSA\/ICcnIDogU3RyaW5nKHYpLnRyaW0oKTsKICAgICAgaWYodiAhPT0gJycpIGFueSA9IHRydWU7CiAgICAgIG9baGVhZGVyc1tjXV0gPSB2OwogICAgfQogICAgaWYoYW55KSBkYXRhLnB1c2gobyk7CiAgfQogIHJldHVybiB7aGVhZGVyczogaGVhZGVycywgZGF0YTogZGF0YX07Cn0KCmZ1bmN0aW9uIGhhbmRsZUZpbGUoZmlsZSl7CiAgYWxlcnRCb3goJCgnbG9hZEVycicpLCAnd2FybicsICcnKTsKICBTLmZpbGVOYW1lID0gZmlsZS5uYW1lOwogIHZhciBpc0V4Y2VsID0gL1wuKHhsc3h8eGxzKSQvaS50ZXN0KGZpbGUubmFtZSk7CiAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7CiAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKGV2KXsKICAgIHRyeXsKICAgICAgdmFyIHBhcnNlZDsKICAgICAgaWYoaXNFeGNlbCl7CiAgICAgICAgdmFyIHdiID0gWExTWC5yZWFkKG5ldyBVaW50OEFycmF5KGV2LnRhcmdldC5yZXN1bHQpLCB7dHlwZTonYXJyYXknfSk7CiAgICAgICAgdmFyIHNoZWV0ID0gd2IuU2hlZXRzW3diLlNoZWV0TmFtZXNbMF1dOwogICAgICAgIHZhciBtYXRyaXggPSBYTFNYLnV0aWxzLnNoZWV0X3RvX2pzb24oc2hlZXQsIHtoZWFkZXI6MSwgcmF3OmZhbHNlLCBkZWZ2YWw6Jyd9KTsKICAgICAgICBwYXJzZWQgPSBmcm9tTWF0cml4KG1hdHJpeCk7CiAgICAgIH1lbHNlewogICAgICAgIHZhciB0ZXh0ID0gZGVjb2RlQnl0ZXMoZXYudGFyZ2V0LnJlc3VsdCk7CiAgICAgICAgdmFyIGZpcnN0TGluZSA9IHRleHQuc3BsaXQoL1xyP1xuLylbMF0gfHwgJyc7CiAgICAgICAgcGFyc2VkID0gZnJvbU1hdHJpeChwYXJzZUNTVih0ZXh0LCBkZXRlY3REZWxpbWl0ZXIoZmlyc3RMaW5lKSkpOwogICAgICB9CiAgICAgIGlmKCFwYXJzZWQuZGF0YS5sZW5ndGgpIHRocm93IG5ldyBFcnJvcignTm8gZGF0YSByb3dzIGZvdW5kIGJlbG93IHRoZSBoZWFkZXIgbGluZS4nKTsKICAgICAgUy5oZWFkZXJzID0gcGFyc2VkLmhlYWRlcnM7CiAgICAgIFMuZGF0YSA9IHBhcnNlZC5kYXRhOwogICAgICBhZnRlckxvYWQoKTsKICAgIH1jYXRjaChlcnIpewogICAgICBhbGVydEJveCgkKCdsb2FkRXJyJyksICd3YXJuJywKICAgICAgICAnPGI+VGhhdCBmaWxlIGNvdWxkIG5vdCBiZSByZWFkLjwvYj4gJyArIGVzYyhlcnIubWVzc2FnZSkgKwogICAgICAgICcgQ2hlY2sgdGhhdCB0aGUgZmlyc3Qgcm93IGNvbnRhaW5zIHZhcmlhYmxlIG5hbWVzIGFuZCB0aGF0IHRoZXJlIGlzIGF0IGxlYXN0IG9uZSByb3cgb2YgZGF0YSBiZWxvdyBpdC4nKTsKICAgIH0KICB9OwogIHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihmaWxlKTsKfQoKLyogLS0tLS0tLS0tLSBhcHLDqHMgY2hhcmdlbWVudCAtLS0tLS0tLS0tICovCmZ1bmN0aW9uIGFmdGVyTG9hZCgpewogIFMubWV0YSA9IHt9OwogIFMuaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uKGgpewogICAgdmFyIGNvbCA9IFMuZGF0YS5tYXAoZnVuY3Rpb24ocil7IHJldHVybiByW2hdOyB9KTsKICAgIFMubWV0YVtoXSA9IHt0eXBlOiBFLmluZmVyVHlwZShjb2wpLCBsYWJlbHM6e30sIG9yZGVyOm51bGx9OwogIH0pOwoKICAkKCduUmVzcCcpLnRleHRDb250ZW50ID0gUy5kYXRhLmxlbmd0aC50b0xvY2FsZVN0cmluZygnZW4tVVMnKTsKICAkKCduVmFycycpLnRleHRDb250ZW50ID0gUy5oZWFkZXJzLmxlbmd0aDsKICAkKCdmTmFtZScpLnRleHRDb250ZW50ID0gUy5maWxlTmFtZS5sZW5ndGggPiAyMiA\/IFMuZmlsZU5hbWUuc2xpY2UoMCwyMCkgKyAn4oCmJyA6IFMuZmlsZU5hbWU7CiAgJCgnZk5hbWUnKS50aXRsZSA9IFMuZmlsZU5hbWU7CiAgJCgnZHJvcCcpLmNsYXNzTGlzdC5hZGQoJ2hpZGRlbicpOwogICQoJ2xvYWRlZCcpLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlbicpOwogICQoJ3Mxbm90ZScpLnRleHRDb250ZW50ID0gJ0xvYWRlZCDigJQgbm90aGluZyB3YXMgdXBsb2FkZWQnOwogICQoJ3N0ZXAxJykuZGF0YXNldC5kb25lID0gJzEnOwogICQoJ3N0ZXAyJykuZGF0YXNldC5sb2NrZWQgPSAnMCc7CiAgJCgnc3RlcDMnKS5kYXRhc2V0LmxvY2tlZCA9ICcwJzsKCiAgcmVuZGVyUHJldmlldygpOwogIHJlbmRlclZhcnMoKTsKICByZW5kZXJQaWNrZXIoKTsKICBTLnJvd1ZhcnMgPSBudWxsOwogICQoJ3Jlc3VsdHMnKS5jbGFzc0xpc3QuYWRkKCdoaWRkZW4nKTsKfQoKZnVuY3Rpb24gcmVuZGVyUHJldmlldygpewogIHZhciBoID0gJzx0YWJsZT48dGhlYWQ+PHRyPic7CiAgUy5oZWFkZXJzLmZvckVhY2goZnVuY3Rpb24oayl7IGggKz0gJzx0aD4nICsgZXNjKGspICsgJzwvdGg+JzsgfSk7CiAgaCArPSAnPC90cj48L3RoZWFkPjx0Ym9keT4nOwogIFMuZGF0YS5zbGljZSgwLDUpLmZvckVhY2goZnVuY3Rpb24ocil7CiAgICBoICs9ICc8dHI+JzsKICAgIFMuaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uKGspeyBoICs9ICc8dGQ+JyArIGVzYyhyW2tdKSArICc8L3RkPic7IH0pOwogICAgaCArPSAnPC90cj4nOwogIH0pOwogICQoJ3ByZXZpZXcnKS5pbm5lckhUTUwgPSBoICsgJzwvdGJvZHk+PC90YWJsZT4nOwp9CgovKiAtLS0tLS0tLS0tIHBhbm5lYXUgdmFyaWFibGVzIC0tLS0tLS0tLS0gKi8KdmFyIFRZUEVfTEFCRUwgPSB7Y2F0ZWdvcmljYWw6J0NhdGVnb3JpY2FsJywgbnVtZXJpYzonTnVtZXJpYycsIHRleHQ6J1RleHQnLCBpZDonSWRlbnRpZmllcid9OwoKZnVuY3Rpb24gZGlzdGluY3RPZih2KXsKICB2YXIgaXNDYXQgPSBTLm1ldGFbdl0udHlwZSA9PT0gJ2NhdGVnb3JpY2FsJzsKICB2YXIgc2V0ID0ge30sIG91dCA9IFtdOwogIFMuZGF0YS5mb3JFYWNoKGZ1bmN0aW9uKHIpewogICAgdmFyIHJhdyA9IHJbdl07CiAgICBpZihFLmlzTWlzc2luZyhyYXcsIGlzQ2F0LCBTLnRyZWF0OTkpKSByZXR1cm47CiAgICB2YXIgayA9IFN0cmluZyhyYXcpLnRyaW0oKTsKICAgIGlmKCFzZXRba10peyBzZXRba10gPSAxOyBvdXQucHVzaChrKTsgfQogIH0pOwogIG91dC5zb3J0KGZ1bmN0aW9uKGEsYil7CiAgICB2YXIgbmEgPSBOdW1iZXIoYSksIG5iID0gTnVtYmVyKGIpOwogICAgaWYoIWlzTmFOKG5hKSAmJiAhaXNOYU4obmIpKSByZXR1cm4gbmEgLSBuYjsKICAgIHJldHVybiBhLmxvY2FsZUNvbXBhcmUoYik7CiAgfSk7CiAgaWYoUy5tZXRhW3ZdLm9yZGVyKXsKICAgIHZhciBvcmQgPSBTLm1ldGFbdl0ub3JkZXIuZmlsdGVyKGZ1bmN0aW9uKGMpeyByZXR1cm4gb3V0LmluZGV4T2YoYykgIT09IC0xOyB9KTsKICAgIG91dCA9IG9yZC5jb25jYXQob3V0LmZpbHRlcihmdW5jdGlvbihjKXsgcmV0dXJuIG9yZC5pbmRleE9mKGMpID09PSAtMTsgfSkpOwogIH0KICByZXR1cm4gb3V0Owp9CmZ1bmN0aW9uIG1pc3NpbmdDb3VudCh2KXsKICB2YXIgaXNDYXQgPSBTLm1ldGFbdl0udHlwZSA9PT0gJ2NhdGVnb3JpY2FsJzsKICB2YXIgbiA9IDA7CiAgUy5kYXRhLmZvckVhY2goZnVuY3Rpb24ocil7IGlmKEUuaXNNaXNzaW5nKHJbdl0sIGlzQ2F0LCBTLnRyZWF0OTkpKSBuKys7IH0pOwogIHJldHVybiBuOwp9CgpmdW5jdGlvbiByZW5kZXJWYXJzKCl7CiAgdmFyIGh0bWwgPSAnJzsKICBTLmhlYWRlcnMuZm9yRWFjaChmdW5jdGlvbih2KXsKICAgIHZhciBtID0gUy5tZXRhW3ZdOwogICAgdmFyIG1pc3MgPSBtaXNzaW5nQ291bnQodik7CiAgICB2YXIgbkNhdCA9IG0udHlwZSA9PT0gJ2NhdGVnb3JpY2FsJyA\/IGRpc3RpbmN0T2YodikubGVuZ3RoIDogMDsKICAgIHZhciBtZXRhID0gbS50eXBlID09PSAnY2F0ZWdvcmljYWwnCiAgICAgID8gbkNhdCArICcgY2F0ZWdvcmllcycKICAgICAgOiAobS50eXBlID09PSAnbnVtZXJpYycgPyAnY29udGludW91cycgOiBUWVBFX0xBQkVMW20udHlwZV0udG9Mb3dlckNhc2UoKSk7CiAgICBpZihtaXNzKSBtZXRhICs9ICcgwrcgPHNwYW4gY2xhc3M9InZhci1mbGFnIj4nICsgbWlzcyArICcgbWlzc2luZzwvc3Bhbj4nOwoKICAgIGh0bWwgKz0gJzxkaXYgY2xhc3M9InZhciIgZGF0YS12PSInICsgZXNjKHYpICsgJyI+JyArCiAgICAgICc8ZGl2IGNsYXNzPSJ2YXItdG9wIj4nICsKICAgICAgICAnPHNwYW4gY2xhc3M9InZhci1uYW1lIiB0aXRsZT0iJyArIGVzYyh2KSArICciPicgKyBlc2ModikgKyAnPC9zcGFuPicgKwogICAgICAgICc8c2VsZWN0IGRhdGEtdHlwZT0iJyArIGVzYyh2KSArICciPicgKwogICAgICAgICAgWydjYXRlZ29yaWNhbCcsJ251bWVyaWMnLCd0ZXh0JywnaWQnXS5tYXAoZnVuY3Rpb24odCl7CiAgICAgICAgICAgIHJldHVybiAnPG9wdGlvbiB2YWx1ZT0iJyArIHQgKyAnIicgKyAodCA9PT0gbS50eXBlID8gJyBzZWxlY3RlZCcgOiAnJykgKyAnPicgKyBUWVBFX0xBQkVMW3RdICsgJzwvb3B0aW9uPic7CiAgICAgICAgICB9KS5qb2luKCcnKSArCiAgICAgICAgJzwvc2VsZWN0PicgKwogICAgICAnPC9kaXY+JyArCiAgICAgICc8ZGl2IGNsYXNzPSJ2YXItbWV0YSI+JyArIG1ldGEgKwogICAgICAgIChtLnR5cGUgPT09ICdjYXRlZ29yaWNhbCcgPyAnIMK3IDxidXR0b24gY2xhc3M9ImxpbmsiIGRhdGEtdG9nZ2xlPSInICsgZXNjKHYpICsgJyI+ZWRpdCBsYWJlbHM8L2J1dHRvbj4nIDogJycpICsKICAgICAgJzwvZGl2PicgKwogICAgICAobS50eXBlID09PSAnY2F0ZWdvcmljYWwnID8gJzxkaXYgY2xhc3M9ImNhdHMiIGRhdGEtY2F0cz0iJyArIGVzYyh2KSArICciPjwvZGl2PicgOiAnJykgKwogICAgJzwvZGl2Pic7CiAgfSk7CiAgJCgndmFycycpLmlubmVySFRNTCA9IGh0bWw7CgogICQoJ3ZhcnMnKS5xdWVyeVNlbGVjdG9yQWxsKCdzZWxlY3RbZGF0YS10eXBlXScpLmZvckVhY2goZnVuY3Rpb24oc2VsKXsKICAgIHNlbC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBmdW5jdGlvbigpewogICAgICBTLm1ldGFbc2VsLmRhdGFzZXQudHlwZV0udHlwZSA9IHNlbC52YWx1ZTsKICAgICAgUy5tZXRhW3NlbC5kYXRhc2V0LnR5cGVdLm9yZGVyID0gbnVsbDsKICAgICAgcmVuZGVyVmFycygpOyByZW5kZXJQaWNrZXIoKTsgaW52YWxpZGF0ZSgpOwogICAgfSk7CiAgfSk7CiAgJCgndmFycycpLnF1ZXJ5U2VsZWN0b3JBbGwoJ2J1dHRvbltkYXRhLXRvZ2dsZV0nKS5mb3JFYWNoKGZ1bmN0aW9uKGIpewogICAgYi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCl7CiAgICAgIHZhciB2ID0gYi5kYXRhc2V0LnRvZ2dsZTsKICAgICAgdmFyIGNhcmQgPSAkKCd2YXJzJykucXVlcnlTZWxlY3RvcignLnZhcltkYXRhLXY9IicgKyBDU1MuZXNjYXBlKHYpICsgJyJdJyk7CiAgICAgIGlmKGNhcmQuY2xhc3NMaXN0LmNvbnRhaW5zKCdvcGVuJykpeyBjYXJkLmNsYXNzTGlzdC5yZW1vdmUoJ29wZW4nKTsgYi50ZXh0Q29udGVudCA9ICdlZGl0IGxhYmVscyc7IH0KICAgICAgZWxzZSB7IHJlbmRlckNhdHModik7IGNhcmQuY2xhc3NMaXN0LmFkZCgnb3BlbicpOyBiLnRleHRDb250ZW50ID0gJ2hpZGUgbGFiZWxzJzsgfQogICAgfSk7CiAgfSk7Cn0KCmZ1bmN0aW9uIHJlbmRlckNhdHModil7CiAgdmFyIGJveCA9ICQoJ3ZhcnMnKS5xdWVyeVNlbGVjdG9yKCdbZGF0YS1jYXRzPSInICsgQ1NTLmVzY2FwZSh2KSArICciXScpOwogIHZhciBjYXRzID0gZGlzdGluY3RPZih2KTsKICBib3guaW5uZXJIVE1MID0gY2F0cy5tYXAoZnVuY3Rpb24oYyl7CiAgICByZXR1cm4gJzxkaXYgY2xhc3M9ImNhdCIgZHJhZ2dhYmxlPSJ0cnVlIiBkYXRhLWNvZGU9IicgKyBlc2MoYykgKyAnIj4nICsKICAgICAgJzxzcGFuIGNsYXNzPSJjYXQtaGFuZGxlIiBhcmlhLWhpZGRlbj0idHJ1ZSI+4ouu4ouuPC9zcGFuPicgKwogICAgICAnPGNvZGU+JyArIGVzYyhjKSArICc8L2NvZGU+JyArCiAgICAgICc8aW5wdXQgdHlwZT0idGV4dCIgdmFsdWU9IicgKyBlc2MoUy5tZXRhW3ZdLmxhYmVsc1tjXSB8fCAnJykgKyAnIiBwbGFjZWhvbGRlcj0iTGFiZWwgZm9yICcgKyBlc2MoYykgKyAnIj4nICsKICAgICc8L2Rpdj4nOwogIH0pLmpvaW4oJycpICsgJzxkaXYgc3R5bGU9Im1hcmdpbi10b3A6NnB4Ij48c21hbGwgc3R5bGU9ImNvbG9yOiM4QTk2QTY7Zm9udC1zaXplOjExLjVweCI+RHJhZyB0byByZW9yZGVyIOKAlCB0aGUgb3JkZXIgaGVyZSBpcyB0aGUgb3JkZXIgaW4gdGhlIHRhYmxlcy48L3NtYWxsPjwvZGl2Pic7CgogIGJveC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dCcpLmZvckVhY2goZnVuY3Rpb24oaW5wKXsKICAgIGlucC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIGZ1bmN0aW9uKCl7CiAgICAgIHZhciBjb2RlID0gaW5wLnBhcmVudE5vZGUuZGF0YXNldC5jb2RlOwogICAgICB2YXIgdmFsID0gaW5wLnZhbHVlLnRyaW0oKTsKICAgICAgaWYodmFsKSBTLm1ldGFbdl0ubGFiZWxzW2NvZGVdID0gdmFsOyBlbHNlIGRlbGV0ZSBTLm1ldGFbdl0ubGFiZWxzW2NvZGVdOwogICAgICBpbnZhbGlkYXRlKCk7CiAgICB9KTsKICB9KTsKCiAgdmFyIGRyYWdnZWQgPSBudWxsOwogIGJveC5xdWVyeVNlbGVjdG9yQWxsKCcuY2F0JykuZm9yRWFjaChmdW5jdGlvbihyb3cpewogICAgcm93LmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdzdGFydCcsIGZ1bmN0aW9uKCl7IGRyYWdnZWQgPSByb3c7IHJvdy5jbGFzc0xpc3QuYWRkKCdkcmFnJyk7IH0pOwogICAgcm93LmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdlbmQnLCBmdW5jdGlvbigpewogICAgICByb3cuY2xhc3NMaXN0LnJlbW92ZSgnZHJhZycpOwogICAgICBTLm1ldGFbdl0ub3JkZXIgPSBBcnJheS5wcm90b3R5cGUubWFwLmNhbGwoYm94LnF1ZXJ5U2VsZWN0b3JBbGwoJy5jYXQnKSwgZnVuY3Rpb24ocil7IHJldHVybiByLmRhdGFzZXQuY29kZTsgfSk7CiAgICAgIGludmFsaWRhdGUoKTsKICAgIH0pOwogICAgcm93LmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdvdmVyJywgZnVuY3Rpb24oZSl7CiAgICAgIGUucHJldmVudERlZmF1bHQoKTsKICAgICAgaWYoIWRyYWdnZWQgfHwgZHJhZ2dlZCA9PT0gcm93KSByZXR1cm47CiAgICAgIHZhciByID0gcm93LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgICBib3guaW5zZXJ0QmVmb3JlKGRyYWdnZWQsIChlLmNsaWVudFkgLSByLnRvcCkgLyByLmhlaWdodCA+IDAuNSA\/IHJvdy5uZXh0U2libGluZyA6IHJvdyk7CiAgICB9KTsKICB9KTsKfQoKLyogLS0tLS0tLS0tLSBkaWN0aW9ubmFpcmUgZCfDqXRpcXVldHRlcyAtLS0tLS0tLS0tICovCmZ1bmN0aW9uIGltcG9ydERpY3Rpb25hcnkoZmlsZSl7CiAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7CiAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKGV2KXsKICAgIHZhciB0ZXh0ID0gZGVjb2RlQnl0ZXMoZXYudGFyZ2V0LnJlc3VsdCk7CiAgICB2YXIgcm93cyA9IHBhcnNlQ1NWKHRleHQsIGRldGVjdERlbGltaXRlcih0ZXh0LnNwbGl0KC9ccj9cbi8pWzBdIHx8ICcnKSk7CiAgICB2YXIgYXBwbGllZCA9IDAsIHN0YXJ0ID0gMDsKICAgIHZhciBoMCA9IChyb3dzWzBdIHx8IFtdKS5tYXAoZnVuY3Rpb24oeCl7IHJldHVybiBTdHJpbmcoeCkudG9Mb3dlckNhc2UoKS50cmltKCk7IH0pOwogICAgaWYoaDBbMF0gPT09ICd2YXJpYWJsZScgfHwgaDBbMF0gPT09ICd2YXInKSBzdGFydCA9IDE7CiAgICBmb3IodmFyIGkgPSBzdGFydDsgaSA8IHJvd3MubGVuZ3RoOyBpKyspewogICAgICB2YXIgdiA9IChyb3dzW2ldWzBdIHx8ICcnKS50cmltKCk7CiAgICAgIHZhciBjb2RlID0gKHJvd3NbaV1bMV0gfHwgJycpLnRyaW0oKTsKICAgICAgdmFyIGxhYiA9IChyb3dzW2ldWzJdIHx8ICcnKS50cmltKCk7CiAgICAgIGlmKFMubWV0YVt2XSAmJiBjb2RlICYmIGxhYil7IFMubWV0YVt2XS5sYWJlbHNbY29kZV0gPSBsYWI7IGFwcGxpZWQrKzsgfQogICAgfQogICAgYWxlcnRCb3goJCgnbG9hZEVycicpLCBhcHBsaWVkID8gJ2luZm8nIDogJ3dhcm4nLCBhcHBsaWVkCiAgICAgID8gYXBwbGllZCArICcgbGFiZWxzIGFwcGxpZWQuJwogICAgICA6ICc8Yj5ObyBsYWJlbHMgYXBwbGllZC48L2I+IFRoZSBkaWN0aW9uYXJ5IG5lZWRzIHRocmVlIGNvbHVtbnM6IHZhcmlhYmxlIG5hbWUsIGNvZGUsIGxhYmVsLicpOwogICAgcmVuZGVyVmFycygpOyByZW5kZXJQaWNrZXIoKTsgaW52YWxpZGF0ZSgpOwogIH07CiAgcmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGZpbGUpOwp9CgovKiAtLS0tLS0tLS0tIGJhbm5pw6hyZSAtLS0tLS0tLS0tICovCmZ1bmN0aW9uIGJhbm5lckNhbmRpZGF0ZXMoKXsKICByZXR1cm4gUy5oZWFkZXJzLmZpbHRlcihmdW5jdGlvbih2KXsgcmV0dXJuIFMubWV0YVt2XS50eXBlID09PSAnY2F0ZWdvcmljYWwnOyB9KTsKfQpmdW5jdGlvbiByZW5kZXJQaWNrZXIoKXsKICB2YXIgY2FuZHMgPSBiYW5uZXJDYW5kaWRhdGVzKCk7CiAgUy5iYW5uZXIgPSBTLmJhbm5lci5maWx0ZXIoZnVuY3Rpb24odil7IHJldHVybiBjYW5kcy5pbmRleE9mKHYpICE9PSAtMTsgfSk7CiAgaWYoIWNhbmRzLmxlbmd0aCl7CiAgICAkKCdwaWNrZXInKS5pbm5lckhUTUwgPSAnJzsKICAgIGFsZXJ0Qm94KCQoJ2Jhbm5lcldhcm4nKSwgJ3dhcm4nLAogICAgICAnPGI+Tm8gY2F0ZWdvcmljYWwgdmFyaWFibGVzIGZvdW5kLjwvYj4gU2V0IGF0IGxlYXN0IG9uZSB2YXJpYWJsZSB0byBDYXRlZ29yaWNhbCBpbiBzdGVwIDIgdG8gYnVpbGQgYSBiYW5uZXIuJyk7CiAgICAkKCdydW4nKS5kaXNhYmxlZCA9IHRydWU7CiAgICByZXR1cm47CiAgfQogICQoJ3BpY2tlcicpLmlubmVySFRNTCA9IGNhbmRzLm1hcChmdW5jdGlvbih2KXsKICAgIHZhciBvbiA9IFMuYmFubmVyLmluZGV4T2YodikgIT09IC0xOwogICAgdmFyIGZ1bGwgPSAhb24gJiYgUy5iYW5uZXIubGVuZ3RoID49IDU7CiAgICByZXR1cm4gJzxidXR0b24gY2xhc3M9ImNoaXAiIGRhdGEtYj0iJyArIGVzYyh2KSArICciIGFyaWEtcHJlc3NlZD0iJyArIG9uICsgJyInICsKICAgICAgKGZ1bGwgPyAnIGRpc2FibGVkJyA6ICcnKSArICc+JyArIGVzYyh2KSArICc8L2J1dHRvbj4nOwogIH0pLmpvaW4oJycpOwogICQoJ3BpY2tlcicpLnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWJdJykuZm9yRWFjaChmdW5jdGlvbihiKXsKICAgIGIuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpewogICAgICB2YXIgdiA9IGIuZGF0YXNldC5iLCBpID0gUy5iYW5uZXIuaW5kZXhPZih2KTsKICAgICAgaWYoaSA9PT0gLTEpIFMuYmFubmVyLnB1c2godik7IGVsc2UgUy5iYW5uZXIuc3BsaWNlKGksMSk7CiAgICAgIHJlbmRlclBpY2tlcigpOyBpbnZhbGlkYXRlKCk7CiAgICB9KTsKICB9KTsKICB1cGRhdGVSZWNhcCgpOwp9CgpmdW5jdGlvbiB1cGRhdGVSZWNhcCgpewogIHZhciBuID0gUy5iYW5uZXIubGVuZ3RoOwogICQoJ3J1bicpLmRpc2FibGVkID0gbiA9PT0gMDsKICAkKCdzM25vdGUnKS50ZXh0Q29udGVudCA9IG4gPyBuICsgJyBvZiA1IGJhbm5lciB2YXJpYWJsZXMgc2VsZWN0ZWQnIDogJ1BpY2sgMSB0byA1IHZhcmlhYmxlcyBmb3IgdGhlIGNvbHVtbnMnOwogIGlmKCFuKXsgJCgncmVjYXAnKS5pbm5lckhUTUwgPSAnJzsgYWxlcnRCb3goJCgnYmFubmVyV2FybicpLCd3YXJuJywnJyk7IHJldHVybjsgfQoKICB2YXIgY29scyA9IEUuYnVpbGRCYW5uZXIoUy5kYXRhLCBTLmJhbm5lciwgUy5tZXRhLCB7dHJlYXQ5OUFzTWlzc2luZzpTLnRyZWF0OTl9KTsKICB2YXIgcGFydHMgPSBTLmJhbm5lci5tYXAoZnVuY3Rpb24odil7CiAgICB2YXIgY3MgPSBjb2xzLmZpbHRlcihmdW5jdGlvbihjKXsgcmV0dXJuIGMudmFyTmFtZSA9PT0gdjsgfSk7CiAgICByZXR1cm4gJzxiPicgKyBlc2ModikgKyAnPC9iPiAoJyArIGNzLm1hcChmdW5jdGlvbihjKXsgcmV0dXJuIGVzYyhjLmxhYmVsKSArICcgJyArIGMubGV0dGVyOyB9KS5qb2luKCcsICcpICsgJyknOwogIH0pOwogICQoJ3JlY2FwJykuaW5uZXJIVE1MID0gY29scy5sZW5ndGggKyAnIGNvbHVtbnMg4oCUIFRvdGFsLCB0aGVuICcgKyBwYXJ0cy5qb2luKCcgwrcgJyk7CgogIHZhciBzbWFsbCA9IGNvbHMuZmlsdGVyKGZ1bmN0aW9uKGMpeyByZXR1cm4gYy5sZXR0ZXIgJiYgYy5pbmRpY2VzLmxlbmd0aCA8IDMwOyB9KTsKICB2YXIgbXNncyA9IFtdOwogIGlmKGNvbHMubGVuZ3RoID4gMjEpIG1zZ3MucHVzaCgnVGhpcyBiYW5uZXIgaGFzICcgKyAoY29scy5sZW5ndGgtMSkgKyAnIGNvbHVtbnMuIEFib3ZlIDIwIHRoZSB0YWJsZXMgZ2V0IGhhcmQgdG8gcmVhZCBvbiBzY3JlZW4g4oCUIHRoZSBFeGNlbCBleHBvcnQgd2lsbCBzdGlsbCBiZSBmaW5lLicpOwogIGlmKHNtYWxsLmxlbmd0aCkgbXNncy5wdXNoKCc8Yj4nICsgc21hbGwubGVuZ3RoICsgJyBjb2x1bW4nICsgKHNtYWxsLmxlbmd0aD4xPydzIGhhdmUnOicgaGFzJykgKyAnIGEgYmFzZSB1bmRlciAzMDwvYj4gKCcgKwogICAgc21hbGwubWFwKGZ1bmN0aW9uKGMpeyByZXR1cm4gZXNjKGMubGFiZWwpICsgJyBuPScgKyBjLmluZGljZXMubGVuZ3RoOyB9KS5qb2luKCcsICcpICsgJykuIFRob3NlIGNvbHVtbnMgd2lsbCBiZSBzaG93biBidXQgbm90IHRlc3RlZC4nKTsKICBhbGVydEJveCgkKCdiYW5uZXJXYXJuJyksICd3YXJuJywgbXNncy5qb2luKCcgJykpOwp9CgpmdW5jdGlvbiByb3dDYW5kaWRhdGVzKCl7CiAgcmV0dXJuIFMuaGVhZGVycy5maWx0ZXIoZnVuY3Rpb24odil7CiAgICB2YXIgdCA9IFMubWV0YVt2XS50eXBlOwogICAgcmV0dXJuICh0ID09PSAnY2F0ZWdvcmljYWwnIHx8IHQgPT09ICdudW1lcmljJykgJiYgUy5iYW5uZXIuaW5kZXhPZih2KSA9PT0gLTE7CiAgfSk7Cn0KZnVuY3Rpb24gcmVuZGVyUm93Q2hpcHMoKXsKICB2YXIgY2FuZHMgPSByb3dDYW5kaWRhdGVzKCk7CiAgaWYoUy5yb3dWYXJzID09PSBudWxsKSBTLnJvd1ZhcnMgPSBjYW5kcy5zbGljZSgpOwogIFMucm93VmFycyA9IFMucm93VmFycy5maWx0ZXIoZnVuY3Rpb24odil7IHJldHVybiBjYW5kcy5pbmRleE9mKHYpICE9PSAtMTsgfSk7CiAgJCgncm93Q2hpcHMnKS5pbm5lckhUTUwgPSBjYW5kcy5tYXAoZnVuY3Rpb24odil7CiAgICByZXR1cm4gJzxidXR0b24gY2xhc3M9ImNoaXAiIGRhdGEtcj0iJyArIGVzYyh2KSArICciIGFyaWEtcHJlc3NlZD0iJyArIChTLnJvd1ZhcnMuaW5kZXhPZih2KSAhPT0gLTEpICsgJyI+JyArIGVzYyh2KSArICc8L2J1dHRvbj4nOwogIH0pLmpvaW4oJycpOwogICQoJ3Jvd0NoaXBzJykucXVlcnlTZWxlY3RvckFsbCgnW2RhdGEtcl0nKS5mb3JFYWNoKGZ1bmN0aW9uKGIpewogICAgYi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCl7CiAgICAgIHZhciB2ID0gYi5kYXRhc2V0LnIsIGkgPSBTLnJvd1ZhcnMuaW5kZXhPZih2KTsKICAgICAgaWYoaSA9PT0gLTEpIFMucm93VmFycy5wdXNoKHYpOyBlbHNlIFMucm93VmFycy5zcGxpY2UoaSwxKTsKICAgICAgcmVuZGVyUm93Q2hpcHMoKTsKICAgIH0pOwogIH0pOwp9CgpmdW5jdGlvbiBpbnZhbGlkYXRlKCl7CiAgJCgncmVzdWx0cycpLmNsYXNzTGlzdC5hZGQoJ2hpZGRlbicpOwogIFMudGFibGVzID0gW107CiAgaWYoUy5yb3dWYXJzICE9PSBudWxsKSBTLnJvd1ZhcnMgPSBudWxsOwogIGlmKCEkKCdyb3dQaWNrZXInKS5jbGFzc0xpc3QuY29udGFpbnMoJ2hpZGRlbicpKSByZW5kZXJSb3dDaGlwcygpOwogIHVwZGF0ZVJlY2FwKCk7Cn0KCi8qIC0tLS0tLS0tLS0gY2hpLTIgLS0tLS0tLS0tLSAqLwpmdW5jdGlvbiBjaGlTcXVhcmUoZGF0YSwgcm93VmFyLCBjb2xzLCB0cmVhdDk5KXsKICB2YXIgY2F0cyA9IHt9LCBsaXN0ID0gW107CiAgY29scy5mb3JFYWNoKGZ1bmN0aW9uKGMpewogICAgYy5pbmRpY2VzLmZvckVhY2goZnVuY3Rpb24oaSl7CiAgICAgIHZhciByYXcgPSBkYXRhW2ldW3Jvd1Zhcl07CiAgICAgIGlmKEUuaXNNaXNzaW5nKHJhdywgdHJ1ZSwgdHJlYXQ5OSkpIHJldHVybjsKICAgICAgdmFyIGsgPSBTdHJpbmcocmF3KS50cmltKCk7CiAgICAgIGlmKCFjYXRzW2tdKXsgY2F0c1trXSA9IDE7IGxpc3QucHVzaChrKTsgfQogICAgfSk7CiAgfSk7CiAgdmFyIG9icyA9IGNvbHMubWFwKGZ1bmN0aW9uKGMpewogICAgdmFyIG8gPSB7fTsgbGlzdC5mb3JFYWNoKGZ1bmN0aW9uKGspeyBvW2tdID0gMDsgfSk7CiAgICBjLmluZGljZXMuZm9yRWFjaChmdW5jdGlvbihpKXsKICAgICAgdmFyIHJhdyA9IGRhdGFbaV1bcm93VmFyXTsKICAgICAgaWYoRS5pc01pc3NpbmcocmF3LCB0cnVlLCB0cmVhdDk5KSkgcmV0dXJuOwogICAgICBvW1N0cmluZyhyYXcpLnRyaW0oKV0rKzsKICAgIH0pOwogICAgcmV0dXJuIG87CiAgfSk7CiAgdmFyIGNvbFRvdCA9IG9icy5tYXAoZnVuY3Rpb24obyl7IHJldHVybiBsaXN0LnJlZHVjZShmdW5jdGlvbihzLGspeyByZXR1cm4gcyArIG9ba107IH0sIDApOyB9KTsKICB2YXIgcm93VG90ID0gbGlzdC5tYXAoZnVuY3Rpb24oayl7IHJldHVybiBvYnMucmVkdWNlKGZ1bmN0aW9uKHMsbyl7IHJldHVybiBzICsgb1trXTsgfSwgMCk7IH0pOwogIHZhciBOID0gY29sVG90LnJlZHVjZShmdW5jdGlvbihhLGIpeyByZXR1cm4gYStiOyB9LCAwKTsKICBpZihOID09PSAwIHx8IGxpc3QubGVuZ3RoIDwgMiB8fCBjb2xzLmxlbmd0aCA8IDIpIHJldHVybiBudWxsOwogIHZhciBjaGkgPSAwLCBsb3dDZWxscyA9IDAsIG5DZWxscyA9IDA7CiAgbGlzdC5mb3JFYWNoKGZ1bmN0aW9uKGssIHJpKXsKICAgIG9icy5mb3JFYWNoKGZ1bmN0aW9uKG8sIGNpKXsKICAgICAgdmFyIGV4cCA9IHJvd1RvdFtyaV0gKiBjb2xUb3RbY2ldIC8gTjsKICAgICAgbkNlbGxzKys7CiAgICAgIGlmKGV4cCA8IDUpIGxvd0NlbGxzKys7CiAgICAgIGlmKGV4cCA+IDApIGNoaSArPSBNYXRoLnBvdyhvW2tdIC0gZXhwLCAyKSAvIGV4cDsKICAgIH0pOwogIH0pOwogIHZhciBkZiA9IChsaXN0Lmxlbmd0aCAtIDEpICogKGNvbHMubGVuZ3RoIC0gMSk7CiAgdmFyIHAgPSAxIC0gRS5nYW1tYVAoZGYvMiwgY2hpLzIpOwogIHJldHVybiB7Y2hpOmNoaSwgZGY6ZGYsIHA6cCwgbG93U2hhcmU6IGxvd0NlbGxzL25DZWxsc307Cn0KCi8qIC0tLS0tLS0tLS0gY2FsY3VsIC0tLS0tLS0tLS0gKi8KZnVuY3Rpb24gYnVpbGQoKXsKICBTLmFscGhhID0gcGFyc2VGbG9hdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPSJhbHBoYSJdOmNoZWNrZWQnKS52YWx1ZSk7CiAgUy50cmVhdDk5ID0gJCgnb3B0OTknKS5jaGVja2VkOwogIFMuY29sdW1ucyA9IEUuYnVpbGRCYW5uZXIoUy5kYXRhLCBTLmJhbm5lciwgUy5tZXRhLCB7dHJlYXQ5OUFzTWlzc2luZzpTLnRyZWF0OTl9KTsKICBpZihTLnJvd1ZhcnMgPT09IG51bGwpIFMucm93VmFycyA9IHJvd0NhbmRpZGF0ZXMoKTsKICB2YXIgdmFycyA9IFMucm93VmFycy5zbGljZSgpOwogIGlmKCF2YXJzLmxlbmd0aCl7CiAgICBhbGVydEJveCgkKCdiYW5uZXJXYXJuJyksJ3dhcm4nLCc8Yj5Ob3RoaW5nIHRvIHRhYnVsYXRlLjwvYj4gRXZlcnkgYXZhaWxhYmxlIHZhcmlhYmxlIGlzIGVpdGhlciBpbiB0aGUgYmFubmVyIG9yIHVuc2VsZWN0ZWQuJyk7CiAgICByZXR1cm47CiAgfQogIFMudGFibGVzID0gW107CiAgdmFyIGkgPSAwOwogIHZhciBiaWcgPSBTLmRhdGEubGVuZ3RoID4gMTAwMDsKICBvdmVybGF5KHRydWUsICdCdWlsZGluZyAnICsgdmFycy5sZW5ndGggKyAnIHRhYmxlc+KApicsIDApOwoKICBmdW5jdGlvbiBzdGVwKCl7CiAgICB2YXIgdDAgPSBEYXRlLm5vdygpOwogICAgd2hpbGUoaSA8IHZhcnMubGVuZ3RoICYmIChEYXRlLm5vdygpIC0gdDApIDwgNjApewogICAgICB2YXIgdiA9IHZhcnNbaV07CiAgICAgIHZhciBvcHRzID0ge2FscGhhOlMuYWxwaGEsIHRyZWF0OTlBc01pc3Npbmc6Uy50cmVhdDk5fTsKICAgICAgdmFyIHJlcyA9IFMubWV0YVt2XS50eXBlID09PSAnY2F0ZWdvcmljYWwnCiAgICAgICAgPyBFLnRhYnVsYXRlQ2F0ZWdvcmljYWwoUy5kYXRhLCB2LCBTLmNvbHVtbnMsIFMubWV0YSwgb3B0cykKICAgICAgICA6IEUudGFidWxhdGVOdW1lcmljKFMuZGF0YSwgdiwgUy5jb2x1bW5zLCBvcHRzKTsKICAgICAgaWYoUy5tZXRhW3ZdLnR5cGUgPT09ICdjYXRlZ29yaWNhbCcgJiYgJCgnb0NoaScpLmNoZWNrZWQpewogICAgICAgIHJlcy5jaGkgPSBTLmJhbm5lci5tYXAoZnVuY3Rpb24oYnYsIGdpKXsKICAgICAgICAgIHZhciBncnAgPSBTLmNvbHVtbnMuZmlsdGVyKGZ1bmN0aW9uKGMpeyByZXR1cm4gYy5ncm91cElkID09PSAnRycgKyBnaTsgfSk7CiAgICAgICAgICByZXR1cm4ge3ZhcmlhYmxlOmJ2LCByZXN1bHQ6IGNoaVNxdWFyZShTLmRhdGEsIHYsIGdycCwgUy50cmVhdDk5KX07CiAgICAgICAgfSk7CiAgICAgIH0KICAgICAgUy50YWJsZXMucHVzaChyZXMpOwogICAgICBpKys7CiAgICB9CiAgICBvdmVybGF5KHRydWUsICdCdWlsZGluZyAnICsgdmFycy5sZW5ndGggKyAnIHRhYmxlc+KApicsIGkvdmFycy5sZW5ndGgpOwogICAgaWYoaSA8IHZhcnMubGVuZ3RoKXsgc2V0VGltZW91dChzdGVwLCAwKTsgfQogICAgZWxzZSB7IG92ZXJsYXkoZmFsc2UpOyByZW5kZXIoKTsgfQogIH0KICBpZihiaWcpIHNldFRpbWVvdXQoc3RlcCwgMzApOyBlbHNlIHsgc3RlcCgpOyB9Cn0KCi8qIC0tLS0tLS0tLS0gcmVuZHUgLS0tLS0tLS0tLSAqLwpmdW5jdGlvbiBsYWJlbE9mKHYsIGNvZGUpewogIHZhciBsID0gUy5tZXRhW3ZdICYmIFMubWV0YVt2XS5sYWJlbHM7CiAgcmV0dXJuIChsICYmIGxbY29kZV0gIT09IHVuZGVmaW5lZCAmJiBsW2NvZGVdICE9PSAnJykgPyBsW2NvZGVdIDogU3RyaW5nKGNvZGUpOwp9CgpmdW5jdGlvbiBoZWFkZXJIVE1MKCl7CiAgdmFyIGdyb3VwcyA9IFtdOwogIFMuY29sdW1ucy5mb3JFYWNoKGZ1bmN0aW9uKGMpewogICAgaWYoIWMudmFyTmFtZSl7IGdyb3Vwcy5wdXNoKHtuYW1lOm51bGwsIG46MX0pOyByZXR1cm47IH0KICAgIHZhciBsYXN0ID0gZ3JvdXBzW2dyb3Vwcy5sZW5ndGgtMV07CiAgICBpZihsYXN0ICYmIGxhc3QubmFtZSA9PT0gYy52YXJOYW1lKSBsYXN0Lm4rKzsKICAgIGVsc2UgZ3JvdXBzLnB1c2goe25hbWU6Yy52YXJOYW1lLCBuOjF9KTsKICB9KTsKICB2YXIgaCA9ICc8dGhlYWQ+PHRyPjx0aCBjbGFzcz0icm93aGVhZCIgcm93c3Bhbj0iMiI+PC90aD4nOwogIGdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uKGcpewogICAgaCArPSBnLm5hbWUgPT09IG51bGwKICAgICAgPyAnPHRoIGNsYXNzPSJ0b3RhbCIgcm93c3Bhbj0iMiI+VG90YWw8L3RoPicKICAgICAgOiAnPHRoIGNsYXNzPSJncnAiIGNvbHNwYW49IicgKyBnLm4gKyAnIj4nICsgZXNjKGcubmFtZSkgKyAnPC90aD4nOwogIH0pOwogIGggKz0gJzwvdHI+PHRyPic7CiAgUy5jb2x1bW5zLmZvckVhY2goZnVuY3Rpb24oYyl7CiAgICBpZighYy52YXJOYW1lKSByZXR1cm47CiAgICB2YXIgbG93ID0gYy5pbmRpY2VzLmxlbmd0aCA8IEUuTUlOX0JBU0VfVEVTVCA\/ICc8c3BhbiBjbGFzcz0iZnJhZ2lsZSIgdGl0bGU9IkJhc2UgdW5kZXIgMzAg4oCUIG5vdCB0ZXN0ZWQiPio8L3NwYW4+JyA6ICcnOwogICAgaCArPSAnPHRoPicgKyBlc2MoYy5sYWJlbCkgKyBsb3cgKyAnPHNwYW4gY2xhc3M9ImNvbC1sZXR0ZXIiPicgKyBjLmxldHRlciArICc8L3NwYW4+PC90aD4nOwogIH0pOwogIHJldHVybiBoICsgJzwvdHI+PC90aGVhZD4nOwp9CgpmdW5jdGlvbiBjZWxsSFRNTChjZWxsLCB0b3RhbFBjdCwgcm93VG90YWxzLCBjb2xJZHgsIGlzVG90YWxDb2wpewogIHZhciBiaXRzID0gW107CiAgaWYoJCgnb0NvdW50JykuY2hlY2tlZCkgYml0cy5wdXNoKCc8c3BhbiBjbGFzcz0iY250Ij4nICsgY2VsbC5jb3VudCArICc8L3NwYW4+Jyk7CiAgaWYoJCgnb0NvbFBjdCcpLmNoZWNrZWQpIGJpdHMucHVzaCgnPHNwYW4nICsgKGNlbGwuZnJhZ2lsZSA\/ICcgY2xhc3M9ImZyYWdpbGUiJyA6ICcnKSArICc+JyArIChjZWxsLnBjdCA9PT0gbnVsbCA\/ICfigJQnIDogcGN0KGNlbGwucGN0KSkgKyAnPC9zcGFuPicpOwogIGlmKCEkKCdvQ291bnQnKS5jaGVja2VkICYmICEkKCdvQ29sUGN0JykuY2hlY2tlZCkgYml0cy5wdXNoKFN0cmluZyhjZWxsLmNvdW50KSk7CiAgaWYoJCgnb1Jvd1BjdCcpLmNoZWNrZWQpewogICAgdmFyIGRlbm9tID0gaXNUb3RhbENvbCA\/IDAgOiByb3dUb3RhbHNbY29sSWR4XTsgLyogcm93ICUgaXMgbWVhbmluZ2xlc3Mgb24gVG90YWwgKi8KICAgIGJpdHMucHVzaCgnPHNwYW4gY2xhc3M9InJvd3BjdCI+JyArIChkZW5vbSA\/IHBjdChjZWxsLmNvdW50L2Rlbm9tKSA6ICfigJQnKSArICcgcjwvc3Bhbj4nKTsKICB9CiAgaWYoJCgnb0luZGV4JykuY2hlY2tlZCAmJiAhaXNUb3RhbENvbCAmJiB0b3RhbFBjdCl7CiAgICBiaXRzLnB1c2goJzxzcGFuIGNsYXNzPSJpZHgiPicgKyAoY2VsbC5wY3QgPT09IG51bGwgPyAnaeKAlCcgOiAnaScgKyBNYXRoLnJvdW5kKChjZWxsLnBjdC90b3RhbFBjdCkqMTAwKSkgKyAnPC9zcGFuPicpOwogIH0KICBpZihjZWxsLmhpZ2hlclRoYW4ubGVuZ3RoKXsKICAgIGJpdHMucHVzaCgnPHNwYW4gY2xhc3M9ImxldHRlciI+JyArIGNlbGwuaGlnaGVyVGhhbi5qb2luKCcnKSArICc8L3NwYW4+Jyk7CiAgfQogIHJldHVybiBiaXRzLmpvaW4oJyAnKTsKfQoKZnVuY3Rpb24gcmVuZGVyQ2F0ZWdvcmljYWwocmVzKXsKICB2YXIgaGlkZVplcm8gPSAkKCdvSGlkZVplcm8nKS5jaGVja2VkOwogIHZhciBoID0gJzx0YWJsZSBjbGFzcz0iY3QiPicgKyBoZWFkZXJIVE1MKCkgKyAnPHRib2R5Pic7CiAgaCArPSAnPHRyIGNsYXNzPSJiYXNlIj48dGQgY2xhc3M9InJvd2hlYWQiPkJhc2U8L3RkPic7CiAgcmVzLmJhc2VzLmZvckVhY2goZnVuY3Rpb24oYiwgaSl7CiAgICBoICs9ICc8dGQgY2xhc3M9IicgKyAoaT09PTA\/J3RvdGFsJzonJykgKyAnIj4nICsgYiArIChiIDwgRS5NSU5fQkFTRV9XQVJOICYmIGk+MCA\/ICc8c3BhbiBjbGFzcz0iZnJhZ2lsZSIgdGl0bGU9IlNtYWxsIGJhc2UiPio8L3NwYW4+JyA6ICcnKSArICc8L3RkPic7CiAgfSk7CiAgaCArPSAnPC90cj4nOwoKICB2YXIgc2hvd24gPSAwOwogIHJlcy5yb3dzLmZvckVhY2goZnVuY3Rpb24ocm93KXsKICAgIHZhciBhbGxaZXJvID0gcm93LmNlbGxzLmV2ZXJ5KGZ1bmN0aW9uKGMpeyByZXR1cm4gYy5jb3VudCA9PT0gMDsgfSk7CiAgICBpZihoaWRlWmVybyAmJiBhbGxaZXJvKSByZXR1cm47CiAgICBzaG93bisrOwogICAgLy8gdG90YXV4IGRlIGxpZ25lIHBhciBncm91cGUgZGUgYmFubmnDqHJlLCBwb3VyIGxlICUgbGlnbmUKICAgIHZhciByb3dUb3RhbHMgPSBbXTsKICAgIHZhciBieUdyb3VwID0ge307CiAgICBTLmNvbHVtbnMuZm9yRWFjaChmdW5jdGlvbihjLCBpKXsKICAgICAgaWYoIWMuZ3JvdXBJZCkgcmV0dXJuOwogICAgICBieUdyb3VwW2MuZ3JvdXBJZF0gPSAoYnlHcm91cFtjLmdyb3VwSWRdIHx8IDApICsgcm93LmNlbGxzW2ldLmNvdW50OwogICAgfSk7CiAgICBTLmNvbHVtbnMuZm9yRWFjaChmdW5jdGlvbihjLCBpKXsgcm93VG90YWxzW2ldID0gYy5ncm91cElkID8gYnlHcm91cFtjLmdyb3VwSWRdIDogcm93LmNlbGxzW2ldLmNvdW50OyB9KTsKCiAgICB2YXIgdG90YWxQY3QgPSByb3cuY2VsbHNbMF0ucGN0OwogICAgaCArPSAnPHRyPjx0ZCBjbGFzcz0icm93aGVhZCI+JyArIGVzYyhsYWJlbE9mKHJlcy52YXJpYWJsZSwgcm93LmNhdGVnb3J5KSkgKyAnPC90ZD4nOwogICAgcm93LmNlbGxzLmZvckVhY2goZnVuY3Rpb24oY2VsbCwgaSl7CiAgICAgIGggKz0gJzx0ZCBjbGFzcz0iJyArIChpPT09MD8ndG90YWwnOicnKSArICciPicgKyBjZWxsSFRNTChjZWxsLCB0b3RhbFBjdCwgcm93VG90YWxzLCBpLCBpPT09MCkgKyAnPC90ZD4nOwogICAgfSk7CiAgICBoICs9ICc8L3RyPic7CiAgfSk7CiAgaWYoIXNob3duKSBoICs9ICc8dHI+PHRkIGNsYXNzPSJyb3doZWFkIiBjb2xzcGFuPSInICsgKFMuY29sdW1ucy5sZW5ndGgrMSkgKyAnIj5ObyBub24tZW1wdHkgY2F0ZWdvcmllcyB0byBzaG93LjwvdGQ+PC90cj4nOwogIHJldHVybiBoICsgJzwvdGJvZHk+PC90YWJsZT4nOwp9CgpmdW5jdGlvbiByZW5kZXJOdW1lcmljKHJlcyl7CiAgdmFyIHJvd3MgPSBbWydCYXNlJywnbicsMF0sWydNZWFuJywnbWVhbicsMV0sWydTdGQuIGRldmlhdGlvbicsJ3NkJywxXSxbJ01lZGlhbicsJ21lZGlhbicsMV0sWydNaW5pbXVtJywnbWluJywxXSxbJ01heGltdW0nLCdtYXgnLDFdXTsKICB2YXIgaCA9ICc8dGFibGUgY2xhc3M9ImN0Ij4nICsgaGVhZGVySFRNTCgpICsgJzx0Ym9keT4nOwogIHJvd3MuZm9yRWFjaChmdW5jdGlvbihyKXsKICAgIGggKz0gJzx0cicgKyAoclsxXT09PSduJyA\/ICcgY2xhc3M9ImJhc2UiJyA6ICcnKSArICc+PHRkIGNsYXNzPSJyb3doZWFkIj4nICsgclswXSArICc8L3RkPic7CiAgICByZXMuc3RhdHMuZm9yRWFjaChmdW5jdGlvbihzLCBpKXsKICAgICAgdmFyIHYgPSBzW3JbMV1dOwogICAgICB2YXIgdHh0ID0gdiA9PT0gbnVsbCA\/ICfigJQnIDogKHJbMl0gPyBOdW1iZXIodikudG9Mb2NhbGVTdHJpbmcoJ2VuLVVTJyx7bWF4aW11bUZyYWN0aW9uRGlnaXRzOjJ9KSA6IHYpOwogICAgICBpZihyWzFdPT09J24nICYmIHYgPCBFLk1JTl9CQVNFX1dBUk4gJiYgaT4wKSB0eHQgKz0gJzxzcGFuIGNsYXNzPSJmcmFnaWxlIiB0aXRsZT0iU21hbGwgYmFzZSI+Kjwvc3Bhbj4nOwogICAgICBpZihyWzFdPT09J21lYW4nICYmIHJlcy5oaWdoZXJUaGFuW2ldLmxlbmd0aCkgdHh0ICs9ICc8c3BhbiBjbGFzcz0ibGV0dGVyIj4nICsgcmVzLmhpZ2hlclRoYW5baV0uam9pbignJykgKyAnPC9zcGFuPic7CiAgICAgIGggKz0gJzx0ZCBjbGFzcz0iJyArIChpPT09MD8ndG90YWwnOicnKSArICciPicgKyB0eHQgKyAnPC90ZD4nOwogICAgfSk7CiAgICBoICs9ICc8L3RyPic7CiAgfSk7CiAgcmV0dXJuIGggKyAnPC90Ym9keT48L3RhYmxlPic7Cn0KCmZ1bmN0aW9uIGZvb3ROb3RlcyhyZXMpewogIHZhciBub3RlcyA9IFtdOwogIHZhciBzbWFsbCA9IFMuY29sdW1ucy5maWx0ZXIoZnVuY3Rpb24oYywgaSl7CiAgICB2YXIgYiA9IHJlcy50eXBlID09PSAnY2F0ZWdvcmljYWwnID8gcmVzLmJhc2VzW2ldIDogcmVzLnN0YXRzW2ldLm47CiAgICByZXR1cm4gYy5sZXR0ZXIgJiYgYiA8IEUuTUlOX0JBU0VfVEVTVDsKICB9KTsKICB2YXIgZnJhZ2lsZSA9IFMuY29sdW1ucy5maWx0ZXIoZnVuY3Rpb24oYywgaSl7CiAgICB2YXIgYiA9IHJlcy50eXBlID09PSAnY2F0ZWdvcmljYWwnID8gcmVzLmJhc2VzW2ldIDogcmVzLnN0YXRzW2ldLm47CiAgICByZXR1cm4gYy5sZXR0ZXIgJiYgYiA+PSBFLk1JTl9CQVNFX1RFU1QgJiYgYiA8IEUuTUlOX0JBU0VfV0FSTjsKICB9KTsKICBpZihyZXMuY2hpKXsKICAgIHJlcy5jaGkuZm9yRWFjaChmdW5jdGlvbihjKXsKICAgICAgaWYoIWMucmVzdWx0KSByZXR1cm47CiAgICAgIG5vdGVzLnB1c2goJzxzcGFuIGNsYXNzPSJjaGkiPs+HwrIgdnMgPGI+JyArIGVzYyhjLnZhcmlhYmxlKSArICc8L2I+OiAnICsKICAgICAgICBjLnJlc3VsdC5jaGkudG9GaXhlZCgyKSArICcsIGRmICcgKyBjLnJlc3VsdC5kZiArICcsIHAgJyArCiAgICAgICAgKGMucmVzdWx0LnAgPCAwLjAwMSA\/ICcmbHQ7IDAuMDAxJyA6IGMucmVzdWx0LnAudG9GaXhlZCgzKSkgKwogICAgICAgIChjLnJlc3VsdC5sb3dTaGFyZSA+IDAuMiA\/ICcgPHNwYW4gY2xhc3M9Indhcm4iPuKAlCBvdmVyIDIwJSBvZiBleHBlY3RlZCBjb3VudHMgYXJlIGJlbG93IDUsIHJlYWQgd2l0aCBjYXJlPC9zcGFuPicgOiAnJykgKwogICAgICAgICc8L3NwYW4+Jyk7CiAgICB9KTsKICB9CiAgaWYoc21hbGwubGVuZ3RoKSBub3Rlcy5wdXNoKCc8c3BhbiBjbGFzcz0id2FybiI+Kjwvc3Bhbj4gQmFzZSB1bmRlciAzMCDigJQgc2hvd24gYnV0IG5vdCB0ZXN0ZWQ6ICcgKyBzbWFsbC5tYXAoZnVuY3Rpb24oYyl7IHJldHVybiBlc2MoYy5sYWJlbCk7IH0pLmpvaW4oJywgJykgKyAnLicpOwogIGlmKGZyYWdpbGUubGVuZ3RoKSBub3Rlcy5wdXNoKCc8c3BhbiBjbGFzcz0id2FybiI+Kjwvc3Bhbj4gQmFzZSB1bmRlciAxMDAg4oCUIHBlcmNlbnRhZ2VzIGFyZSBmcmFnaWxlOiAnICsgZnJhZ2lsZS5tYXAoZnVuY3Rpb24oYyl7IHJldHVybiBlc2MoYy5sYWJlbCk7IH0pLmpvaW4oJywgJykgKyAnLicpOwogIHZhciBsdmwgPSBTLmFscGhhID09PSAwLjEwID8gJzkwJScgOiAoUy5hbHBoYSA9PT0gMC4wMSA\/ICc5OSUnIDogJzk1JScpOwogIG5vdGVzLnB1c2goJ0xldHRlcnMgbWFyayBjb2x1bW5zIHRoaXMgb25lIGlzIHNpZ25pZmljYW50bHkgaGlnaGVyIHRoYW4sIGF0ICcgKyBsdmwgKyAnLicpOwogIHJldHVybiBub3Rlcy5qb2luKCcgJyk7Cn0KCmZ1bmN0aW9uIHJlbmRlcigpewogIHZhciBtYWluID0gJCgndGFibGVzJyksIG5hdiA9ICQoJ25hdkxpc3QnKTsKICBtYWluLmlubmVySFRNTCA9IFMudGFibGVzLm1hcChmdW5jdGlvbihyZXMsIGkpewogICAgcmV0dXJuICc8c2VjdGlvbiBjbGFzcz0idGJsLWNhcmQiIGlkPSJ0JyArIGkgKyAnIj4nICsKICAgICAgJzxkaXYgY2xhc3M9InRibC1oZWFkIj48aDM+JyArIGVzYyhyZXMudmFyaWFibGUpICsgJzwvaDM+JyArCiAgICAgICAgJzxzcGFuIGNsYXNzPSJ2biI+JyArIChyZXMudHlwZSA9PT0gJ2NhdGVnb3JpY2FsJyA\/ICdjYXRlZ29yaWNhbCcgOiAnbnVtZXJpYycpICsgJzwvc3Bhbj48L2Rpdj4nICsKICAgICAgJzxkaXYgY2xhc3M9InNjcm9sbGVyIj4nICsgKHJlcy50eXBlID09PSAnY2F0ZWdvcmljYWwnID8gcmVuZGVyQ2F0ZWdvcmljYWwocmVzKSA6IHJlbmRlck51bWVyaWMocmVzKSkgKyAnPC9kaXY+JyArCiAgICAgICc8ZGl2IGNsYXNzPSJ0YmwtZm9vdCI+JyArIGZvb3ROb3RlcyhyZXMpICsgJzwvZGl2PicgKwogICAgJzwvc2VjdGlvbj4nOwogIH0pLmpvaW4oJycpOwogIG5hdi5pbm5lckhUTUwgPSBTLnRhYmxlcy5tYXAoZnVuY3Rpb24ocmVzLCBpKXsKICAgIHJldHVybiAnPGEgaHJlZj0iI3QnICsgaSArICciIGRhdGEtbmFtZT0iJyArIGVzYyhyZXMudmFyaWFibGUudG9Mb3dlckNhc2UoKSkgKyAnIj4nICsgZXNjKHJlcy52YXJpYWJsZSkgKyAnPC9hPic7CiAgfSkuam9pbignJyk7CiAgJCgncmVzdWx0cycpLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlbicpOwogIGlmKCQoJ3Jlc3VsdHMnKS5zY3JvbGxJbnRvVmlldykgJCgncmVzdWx0cycpLnNjcm9sbEludG9WaWV3KHtiZWhhdmlvcjonc21vb3RoJywgYmxvY2s6J3N0YXJ0J30pOwp9CgovKiAtLS0tLS0tLS0tIGV4cG9ydCBFeGNlbCAoc3R5bGVkIGJhbm5lciBib29rLCBFeGNlbEpTKSAtLS0tLS0tLS0tICovCi8qIFBhbGV0dGUgbWlycm9ycyB0aGUgZnJvbnQgZW5kICgtLWJsdWUtZGVlcCBldGMuKSwgQVJHQiBmb3IgRXhjZWwuICovCnZhciBYTCA9IHsKICBibHVlRGVlcCA6ICdGRjFDNzVCQycsCiAgYmx1ZUxpZ2h0OiAnRkYyN0FBRTEnLAogIGJsdWVUaW50IDogJ0ZGRURGNkZDJywKICBibHVlTGluZSA6ICdGRkQzRTZGNCcsCiAgZ3JleVRleHQgOiAnRkY0QTU1NjgnLAogIGdyZXlNdXRlIDogJ0ZGOEE5NkE2JywKICBncmV5TGluZSA6ICdGRkU4RUNGMCcsCiAgb3JhbmdlICAgOiAnRkZGNzk0MUUnLAogIGJhc2VGaWxsIDogJ0ZGRkJGREZFJywKICB0b3RhbEZpbGw6ICdGRkZDRkRGRScsCiAgd2hpdGUgICAgOiAnRkZGRkZGRkYnLAogIGZvbnQgICAgIDogJ0NhbGlicmknCn07CmZ1bmN0aW9uIHhsQm9yZGVyKGNvbG9yKXsgcmV0dXJuIHtzdHlsZTondGhpbicsIGNvbG9yOnthcmdiOmNvbG9yIHx8IFhMLmdyZXlMaW5lfX07IH0KCmZ1bmN0aW9uIGV4cG9ydEV4Y2VsKCl7CiAgb3ZlcmxheSh0cnVlLCAnUHJlcGFyaW5nIHRoZSB3b3JrYm9va+KApicsIDAuMyk7CiAgc2V0VGltZW91dChmdW5jdGlvbigpewogICAgZXhwb3J0RXhjZWxTdHlsZWQoKS50aGVuKGZ1bmN0aW9uKCl7IG92ZXJsYXkoZmFsc2UpOyB9KQogICAgLmNhdGNoKGZ1bmN0aW9uKGVycil7CiAgICAgIGFsZXJ0Qm94KCQoJ2Jhbm5lcldhcm4nKSwnd2FybicsJzxiPlRoZSB3b3JrYm9vayBjb3VsZCBub3QgYmUgd3JpdHRlbi48L2I+ICcgKyBlc2MoZXJyLm1lc3NhZ2UpKTsKICAgICAgb3ZlcmxheShmYWxzZSk7CiAgICB9KTsKICB9LCA0MCk7Cn0KCmZ1bmN0aW9uIGV4cG9ydEV4Y2VsU3R5bGVkKCl7CiAgdmFyIHdiID0gbmV3IEV4Y2VsSlMuV29ya2Jvb2soKTsKICB3Yi5jcmVhdG9yID0gJ0Nyb3NzdGFiIEJ1aWxkZXIg4oCUIGgtaW4tcS5jb20nOwogIHdiLmNyZWF0ZWQgPSBuZXcgRGF0ZSgpOwogIHZhciBsdmwgPSBTLmFscGhhID09PSAwLjEwID8gJzkwJScgOiAoUy5hbHBoYSA9PT0gMC4wMSA\/ICc5OSUnIDogJzk1JScpOwogIHZhciBzaG93Q291bnQgPSAkKCdvQ291bnQnKS5jaGVja2VkLCBzaG93UGN0ID0gJCgnb0NvbFBjdCcpLmNoZWNrZWQ7CiAgdmFyIHNob3dSb3dQY3QgPSAkKCdvUm93UGN0JykuY2hlY2tlZCwgc2hvd0lkeCA9ICQoJ29JbmRleCcpLmNoZWNrZWQ7CiAgdmFyIGhpZGVaZXJvID0gJCgnb0hpZGVaZXJvJykuY2hlY2tlZDsKCiAgLyogPT09PT0gU2hlZXQgMSA6IFN1bW1hcnkgPT09PT0gKi8KICB2YXIgd3MxID0gd2IuYWRkV29ya3NoZWV0KCdTdW1tYXJ5Jywge3ZpZXdzOlt7c2hvd0dyaWRMaW5lczpmYWxzZX1dfSk7CiAgd3MxLmNvbHVtbnMgPSBbe3dpZHRoOjI0fSx7d2lkdGg6NDZ9LHt3aWR0aDoxMH0se3dpZHRoOjEwfV07CgogIHZhciByID0gd3MxLmFkZFJvdyhbJ0NST1NTVEFCIEJVSUxERVIg4oCUIEgtSU4tUS5DT00nXSk7CiAgd3MxLm1lcmdlQ2VsbHMoci5udW1iZXIsIDEsIHIubnVtYmVyLCA0KTsKICByLmdldENlbGwoMSkuZm9udCA9IHtuYW1lOlhMLmZvbnQsIHNpemU6MTUsIGJvbGQ6dHJ1ZSwgY29sb3I6e2FyZ2I6WEwud2hpdGV9fTsKICByLmdldENlbGwoMSkuZmlsbCA9IHt0eXBlOidwYXR0ZXJuJywgcGF0dGVybjonc29saWQnLCBmZ0NvbG9yOnthcmdiOlhMLmJsdWVEZWVwfX07CiAgci5nZXRDZWxsKDEpLmFsaWdubWVudCA9IHt2ZXJ0aWNhbDonbWlkZGxlJywgaW5kZW50OjF9OwogIHIuaGVpZ2h0ID0gMzA7CiAgd3MxLmFkZFJvdyhbXSk7CgogIGZ1bmN0aW9uIHN1bUtWKGssIHYpewogICAgdmFyIHJvdyA9IHdzMS5hZGRSb3coW2ssIHZdKTsKICAgIHJvdy5nZXRDZWxsKDEpLmZvbnQgPSB7bmFtZTpYTC5mb250LCBzaXplOjExLCBib2xkOnRydWUsIGNvbG9yOnthcmdiOlhMLmJsdWVEZWVwfX07CiAgICByb3cuZ2V0Q2VsbCgyKS5mb250ID0ge25hbWU6WEwuZm9udCwgc2l6ZToxMSwgY29sb3I6e2FyZ2I6WEwuZ3JleVRleHR9fTsKICAgIHJvdy5nZXRDZWxsKDIpLmFsaWdubWVudCA9IHt3cmFwVGV4dDp0cnVlLCB2ZXJ0aWNhbDondG9wJ307CiAgfQogIHN1bUtWKCdHZW5lcmF0ZWQnLCBuZXcgRGF0ZSgpLnRvTG9jYWxlU3RyaW5nKCdlbi1VUycpKTsKICBzdW1LVignU291cmNlIGZpbGUnLCBTLmZpbGVOYW1lKTsKICBzdW1LVignUmVzcG9uZGVudHMnLCBTLmRhdGEubGVuZ3RoKTsKICBzdW1LVignQ29uZmlkZW5jZSBsZXZlbCcsIGx2bCk7CiAgc3VtS1YoJ1NpZ25pZmljYW5jZSB0ZXN0JywgJ1Byb3BvcnRpb25zOiB0d28tdGFpbGVkIHotdGVzdCwgcG9vbGVkIHZhcmlhbmNlLiBNZWFuczogV2VsY2ggdC10ZXN0LicpOwogIHN1bUtWKCdUZXN0aW5nIHJ1bGUnLCAnQ29sdW1ucyBhcmUgb25seSBjb21wYXJlZCB3aXRoaW4gdGhlIHNhbWUgYmFubmVyIHZhcmlhYmxlLiBObyBtdWx0aXBsZS1jb21wYXJpc29uIGNvcnJlY3Rpb24gaXMgYXBwbGllZC4nKTsKICBzdW1LVignTWluaW11bSBiYXNlJywgJ05vIHRlc3QgYmVsb3cgMzAuIFBlcmNlbnRhZ2VzIGZsYWdnZWQgYmVsb3cgMTAwLicpOwogIHN1bUtWKCdNaXNzaW5nIHZhbHVlcycsIFMudHJlYXQ5OSA\/ICdCbGFua3MsIE5BLCA5OSBhbmQgOTk5IG9uIGNhdGVnb3JpY2FsIHZhcmlhYmxlcy4nIDogJ0JsYW5rcyBhbmQgTkEgb25seS4nKTsKICBzdW1LVignSG93IHRvIHJlYWQnLCAnQSBsZXR0ZXIgYWZ0ZXIgYSBmaWd1cmUgbWVhbnMgaXQgaXMgc2lnbmlmaWNhbnRseSBoaWdoZXIgdGhhbiB0aGF0IGNvbHVtbiwgZS5nLiAyNy4xJSAoQikgYmVhdHMgY29sdW1uIEIuJyk7CiAgd3MxLmFkZFJvdyhbXSk7CgogIGZ1bmN0aW9uIHN1bVNlY3Rpb24odGl0bGUpewogICAgdmFyIHJvdyA9IHdzMS5hZGRSb3coW3RpdGxlXSk7CiAgICB3czEubWVyZ2VDZWxscyhyb3cubnVtYmVyLCAxLCByb3cubnVtYmVyLCA0KTsKICAgIHJvdy5nZXRDZWxsKDEpLmZvbnQgPSB7bmFtZTpYTC5mb250LCBzaXplOjExLCBib2xkOnRydWUsIGNvbG9yOnthcmdiOlhMLmJsdWVEZWVwfX07CiAgICByb3cuZ2V0Q2VsbCgxKS5maWxsID0ge3R5cGU6J3BhdHRlcm4nLCBwYXR0ZXJuOidzb2xpZCcsIGZnQ29sb3I6e2FyZ2I6WEwuYmx1ZVRpbnR9fTsKICAgIHJvdy5oZWlnaHQgPSAyMDsKICAgIHJvdy5nZXRDZWxsKDEpLmFsaWdubWVudCA9IHt2ZXJ0aWNhbDonbWlkZGxlJywgaW5kZW50OjF9OwogIH0KICBzdW1TZWN0aW9uKCdCQU5ORVInKTsKICB2YXIgaGRyID0gd3MxLmFkZFJvdyhbJ1ZhcmlhYmxlJywnQ29sdW1uJywnTGV0dGVyJywnQmFzZSddKTsKICBoZHIuZWFjaENlbGwoZnVuY3Rpb24oYyl7CiAgICBjLmZvbnQgPSB7bmFtZTpYTC5mb250LCBzaXplOjEwLCBib2xkOnRydWUsIGNvbG9yOnthcmdiOlhMLmdyZXlNdXRlfX07CiAgICBjLmJvcmRlciA9IHtib3R0b206eGxCb3JkZXIoWEwuYmx1ZUxpbmUpfTsKICB9KTsKICBTLmNvbHVtbnMuZm9yRWFjaChmdW5jdGlvbihjKXsKICAgIHZhciByb3cgPSB3czEuYWRkUm93KFtjLnZhck5hbWUgfHwgJycsIGMubGFiZWwsIGMubGV0dGVyIHx8ICfigJQnLCBjLmluZGljZXMubGVuZ3RoXSk7CiAgICByb3cuZWFjaENlbGwoZnVuY3Rpb24oY2VsbCwgY2kpewogICAgICBjZWxsLmZvbnQgPSB7bmFtZTpYTC5mb250LCBzaXplOjExLCBjb2xvcjp7YXJnYjpYTC5ncmV5VGV4dH19OwogICAgICBjZWxsLmJvcmRlciA9IHtib3R0b206eGxCb3JkZXIoKX07CiAgICAgIGlmKGNpID09PSAzKSBjZWxsLmFsaWdubWVudCA9IHtob3Jpem9udGFsOidjZW50ZXInfTsKICAgIH0pOwogICAgaWYoYy5sZXR0ZXIgJiYgYy5pbmRpY2VzLmxlbmd0aCA8IEUuTUlOX0JBU0VfVEVTVCl7CiAgICAgIHJvdy5nZXRDZWxsKDQpLmZvbnQgPSB7bmFtZTpYTC5mb250LCBzaXplOjExLCBib2xkOnRydWUsIGNvbG9yOnthcmdiOlhMLm9yYW5nZX19OwogICAgfQogIH0pOwogIHdzMS5hZGRSb3coW10pOwogIHN1bVNlY3Rpb24oJ1RBQkxFUyBJTiBUSElTIFdPUktCT09LJyk7CiAgUy50YWJsZXMuZm9yRWFjaChmdW5jdGlvbih0KXsKICAgIHZhciByb3cgPSB3czEuYWRkUm93KFt0LnZhcmlhYmxlLCB0LnR5cGUgPT09ICdjYXRlZ29yaWNhbCcgPyAnY2F0ZWdvcmljYWwg4oCUIGNvbHVtbiAlJyA6ICdudW1lcmljIOKAlCBzdW1tYXJ5IHN0YXRpc3RpY3MnXSk7CiAgICByb3cuZ2V0Q2VsbCgxKS5mb250ID0ge25hbWU6WEwuZm9udCwgc2l6ZToxMSwgYm9sZDp0cnVlLCBjb2xvcjp7YXJnYjpYTC5ncmV5VGV4dH19OwogICAgcm93LmdldENlbGwoMikuZm9udCA9IHtuYW1lOlhMLmZvbnQsIHNpemU6MTAsIGl0YWxpYzp0cnVlLCBjb2xvcjp7YXJnYjpYTC5ncmV5TXV0ZX19OwogIH0pOwogIHdzMS5hZGRSb3coW10pOwogIHZhciBjcmVkID0gd3MxLmFkZFJvdyhbJ0dlbmVyYXRlZCB3aXRoIHRoZSBmcmVlIENyb3NzdGFiIEJ1aWxkZXIg4oCUIGgtaW4tcS5jb20nXSk7CiAgY3JlZC5nZXRDZWxsKDEpLmZvbnQgPSB7bmFtZTpYTC5mb250LCBzaXplOjEwLCBpdGFsaWM6dHJ1ZSwgY29sb3I6e2FyZ2I6WEwuZ3JleU11dGV9fTsKCiAgLyogPT09PT0gU2hlZXQgMiA6IFRhYmxlcyA9PT09PSAqLwogIHZhciB3czIgPSB3Yi5hZGRXb3Jrc2hlZXQoJ1RhYmxlcycsIHsKICAgIHZpZXdzOlt7c2hvd0dyaWRMaW5lczpmYWxzZSwgc3RhdGU6J2Zyb3plbicsIHhTcGxpdDoxfV0KICB9KTsKICB3czIuZ2V0Q29sdW1uKDEpLndpZHRoID0gMzQ7CiAgZm9yKHZhciBjaSA9IDI7IGNpIDw9IFMuY29sdW1ucy5sZW5ndGggKyAxOyBjaSsrKSB3czIuZ2V0Q29sdW1uKGNpKS53aWR0aCA9IDE4OwogIHZhciBuQ29scyA9IFMuY29sdW1ucy5sZW5ndGggKyAxOwoKICBmdW5jdGlvbiBjZWxsVGV4dChjZWxsLCB0b3RhbFBjdCwgcm93VG90YWwsIGlzVG90YWxDb2wpewogICAgdmFyIGJpdHMgPSBbXTsKICAgIGlmKHNob3dDb3VudCkgYml0cy5wdXNoKFN0cmluZyhjZWxsLmNvdW50KSk7CiAgICBpZihzaG93UGN0KSBiaXRzLnB1c2goY2VsbC5wY3QgPT09IG51bGwgPyAn4oCUJyA6IHBjdChjZWxsLnBjdCkpOwogICAgaWYoIWJpdHMubGVuZ3RoKSBiaXRzLnB1c2goU3RyaW5nKGNlbGwuY291bnQpKTsKICAgIGlmKHNob3dSb3dQY3QpIGJpdHMucHVzaCgoaXNUb3RhbENvbCB8fCAhcm93VG90YWwpID8gJ+KAlCByJyA6IHBjdChjZWxsLmNvdW50L3Jvd1RvdGFsKSArICcgcicpOwogICAgaWYoc2hvd0lkeCAmJiAhaXNUb3RhbENvbCAmJiB0b3RhbFBjdCkgYml0cy5wdXNoKGNlbGwucGN0ID09PSBudWxsID8gJ2nigJQnIDogJ2knICsgTWF0aC5yb3VuZCgoY2VsbC5wY3QvdG90YWxQY3QpKjEwMCkpOwogICAgdmFyIHQgPSBiaXRzLmpvaW4oJyAgJyk7CiAgICBpZihjZWxsLmhpZ2hlclRoYW4ubGVuZ3RoKSB0ICs9ICcgICgnICsgY2VsbC5oaWdoZXJUaGFuLmpvaW4oJycpICsgJyknOwogICAgcmV0dXJuIHQ7CiAgfQoKICBTLnRhYmxlcy5mb3JFYWNoKGZ1bmN0aW9uKHJlcyl7CiAgICAvKiB0aXRsZSBiYXIgKi8KICAgIHZhciB0ciA9IHdzMi5hZGRSb3coW3Jlcy52YXJpYWJsZSArICcgIOKAlCAgJyArIChyZXMudHlwZSA9PT0gJ2NhdGVnb3JpY2FsJyA\/ICdjb2x1bW4gJScgOiAnc3VtbWFyeSBzdGF0aXN0aWNzJyldKTsKICAgIHdzMi5tZXJnZUNlbGxzKHRyLm51bWJlciwgMSwgdHIubnVtYmVyLCBuQ29scyk7CiAgICB0ci5nZXRDZWxsKDEpLmZvbnQgPSB7bmFtZTpYTC5mb250LCBzaXplOjEyLCBib2xkOnRydWUsIGNvbG9yOnthcmdiOlhMLndoaXRlfX07CiAgICB0ci5nZXRDZWxsKDEpLmZpbGwgPSB7dHlwZToncGF0dGVybicsIHBhdHRlcm46J3NvbGlkJywgZmdDb2xvcjp7YXJnYjpYTC5ibHVlRGVlcH19OwogICAgdHIuZ2V0Q2VsbCgxKS5hbGlnbm1lbnQgPSB7dmVydGljYWw6J21pZGRsZScsIGluZGVudDoxfTsKICAgIHRyLmhlaWdodCA9IDI0OwoKICAgIC8qIGJhbm5lciBncm91cCByb3cgKG1lcmdlZCBwZXIgYmFubmVyIHZhcmlhYmxlLCBsaWtlIHRoZSBmcm9udC1lbmQgaGVhZGVyKSAqLwogICAgdmFyIGcxID0gd3MyLmFkZFJvdyhbJyddKTsKICAgIHZhciBjb2wgPSAyOwogICAgdmFyIGdyb3VwcyA9IFtdOwogICAgUy5jb2x1bW5zLmZvckVhY2goZnVuY3Rpb24oYyl7CiAgICAgIGlmKCFjLnZhck5hbWUpeyBncm91cHMucHVzaCh7bmFtZTonVG90YWwnLCBuOjEsIHRvdGFsOnRydWV9KTsgcmV0dXJuOyB9CiAgICAgIHZhciBsYXN0ID0gZ3JvdXBzW2dyb3Vwcy5sZW5ndGgtMV07CiAgICAgIGlmKGxhc3QgJiYgIWxhc3QudG90YWwgJiYgbGFzdC5uYW1lID09PSBjLnZhck5hbWUpIGxhc3QubisrOwogICAgICBlbHNlIGdyb3Vwcy5wdXNoKHtuYW1lOmMudmFyTmFtZSwgbjoxfSk7CiAgICB9KTsKICAgIGdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uKGcpewogICAgICBnMS5nZXRDZWxsKGNvbCkudmFsdWUgPSBnLnRvdGFsID8gJycgOiBnLm5hbWUudG9VcHBlckNhc2UoKTsKICAgICAgaWYoZy5uID4gMSkgd3MyLm1lcmdlQ2VsbHMoZzEubnVtYmVyLCBjb2wsIGcxLm51bWJlciwgY29sICsgZy5uIC0gMSk7CiAgICAgIGZvcih2YXIgayA9IGNvbDsgayA8IGNvbCArIGcubjsgaysrKXsKICAgICAgICB2YXIgYyA9IGcxLmdldENlbGwoayk7CiAgICAgICAgYy5maWxsID0ge3R5cGU6J3BhdHRlcm4nLCBwYXR0ZXJuOidzb2xpZCcsIGZnQ29sb3I6e2FyZ2I6WEwuYmx1ZVRpbnR9fTsKICAgICAgICBjLmZvbnQgPSB7bmFtZTpYTC5mb250LCBzaXplOjksIGJvbGQ6dHJ1ZSwgY29sb3I6e2FyZ2I6WEwuYmx1ZURlZXB9fTsKICAgICAgICBjLmFsaWdubWVudCA9IHtob3Jpem9udGFsOidjZW50ZXInLCB2ZXJ0aWNhbDonbWlkZGxlJ307CiAgICAgICAgYy5ib3JkZXIgPSB7bGVmdDp4bEJvcmRlcihYTC5ibHVlTGluZSksIGJvdHRvbTp4bEJvcmRlcihYTC5ibHVlTGluZSl9OwogICAgICB9CiAgICAgIGNvbCArPSBnLm47CiAgICB9KTsKICAgIGcxLmdldENlbGwoMSkuZmlsbCA9IHt0eXBlOidwYXR0ZXJuJywgcGF0dGVybjonc29saWQnLCBmZ0NvbG9yOnthcmdiOlhMLmJsdWVUaW50fX07CiAgICBnMS5nZXRDZWxsKDEpLmJvcmRlciA9IHtib3R0b206eGxCb3JkZXIoWEwuYmx1ZUxpbmUpfTsKCiAgICAvKiBjb2x1bW4gbGFiZWxzICsgbGV0dGVycyAqLwogICAgdmFyIGcydmFscyA9IFsnJ107CiAgICBTLmNvbHVtbnMuZm9yRWFjaChmdW5jdGlvbihjKXsKICAgICAgZzJ2YWxzLnB1c2goYy5sZXR0ZXIgPyBjLmxhYmVsICsgJyAgKCcgKyBjLmxldHRlciArICcpJyA6ICdUb3RhbCcpOwogICAgfSk7CiAgICB2YXIgZzIgPSB3czIuYWRkUm93KGcydmFscyk7CiAgICBnMi5oZWlnaHQgPSAyMDsKICAgIGcyLmVhY2hDZWxsKHtpbmNsdWRlRW1wdHk6dHJ1ZX0sIGZ1bmN0aW9uKGMsIGkpewogICAgICBjLmZpbGwgPSB7dHlwZToncGF0dGVybicsIHBhdHRlcm46J3NvbGlkJywgZmdDb2xvcjp7YXJnYjpYTC5ibHVlVGludH19OwogICAgICBjLmZvbnQgPSB7bmFtZTpYTC5mb250LCBzaXplOjEwLCBib2xkOnRydWUsIGNvbG9yOnthcmdiOlhMLmJsdWVEZWVwfX07CiAgICAgIGMuYWxpZ25tZW50ID0ge2hvcml6b250YWw6aSA9PT0gMSA\/ICdsZWZ0JyA6ICdjZW50ZXInLCB2ZXJ0aWNhbDonbWlkZGxlJywgd3JhcFRleHQ6dHJ1ZX07CiAgICAgIGMuYm9yZGVyID0ge2JvdHRvbTp4bEJvcmRlcihYTC5ibHVlTGluZSl9OwogICAgfSk7CiAgICAvKiBtYXJrIHVudGVzdGVkIGNvbHVtbnMgaW4gdGhlIGhlYWRlciwgbGlrZSB0aGUgKiBvbiBzY3JlZW4gKi8KICAgIFMuY29sdW1ucy5mb3JFYWNoKGZ1bmN0aW9uKGMsIGkpewogICAgICBpZihjLmxldHRlciAmJiBjLmluZGljZXMubGVuZ3RoIDwgRS5NSU5fQkFTRV9URVNUKXsKICAgICAgICB2YXIgY2VsbCA9IGcyLmdldENlbGwoaSArIDIpOwogICAgICAgIGNlbGwudmFsdWUgPSBjZWxsLnZhbHVlICsgJyAqJzsKICAgICAgICBjZWxsLmZvbnQgPSB7bmFtZTpYTC5mb250LCBzaXplOjEwLCBib2xkOnRydWUsIGNvbG9yOnthcmdiOlhMLm9yYW5nZX19OwogICAgICB9CiAgICB9KTsKCiAgICBmdW5jdGlvbiBzdHlsZURhdGFDZWxsKGMsIGksIG9wdHMpewogICAgICBvcHRzID0gb3B0cyB8fCB7fTsKICAgICAgYy5mb250ID0ge25hbWU6WEwuZm9udCwgc2l6ZToxMC41LAogICAgICAgICAgICAgICAgYm9sZDohIW9wdHMuYm9sZCwKICAgICAgICAgICAgICAgIGNvbG9yOnthcmdiOiBvcHRzLmNvbG9yIHx8IFhMLmdyZXlUZXh0fX07CiAgICAgIGMuYWxpZ25tZW50ID0ge2hvcml6b250YWw6IGkgPT09IDEgPyAnbGVmdCcgOiAnY2VudGVyJywgdmVydGljYWw6J21pZGRsZScsIHdyYXBUZXh0OiBpID09PSAxfTsKICAgICAgYy5ib3JkZXIgPSB7Ym90dG9tOnhsQm9yZGVyKCl9OwogICAgICBpZihvcHRzLmZpbGwpIGMuZmlsbCA9IHt0eXBlOidwYXR0ZXJuJywgcGF0dGVybjonc29saWQnLCBmZ0NvbG9yOnthcmdiOm9wdHMuZmlsbH19OwogICAgICBlbHNlIGlmKGkgPT09IDIpIGMuZmlsbCA9IHt0eXBlOidwYXR0ZXJuJywgcGF0dGVybjonc29saWQnLCBmZ0NvbG9yOnthcmdiOlhMLnRvdGFsRmlsbH19OyAvKiBUb3RhbCBjb2x1bW4gdGludCAqLwogICAgfQoKICAgIGlmKHJlcy50eXBlID09PSAnY2F0ZWdvcmljYWwnKXsKICAgICAgLyogQmFzZSByb3cgKi8KICAgICAgdmFyIGJyID0gd3MyLmFkZFJvdyhbJ0Jhc2UnXS5jb25jYXQocmVzLmJhc2VzKSk7CiAgICAgIGJyLmVhY2hDZWxsKHtpbmNsdWRlRW1wdHk6dHJ1ZX0sIGZ1bmN0aW9uKGMsIGkpewogICAgICAgIHN0eWxlRGF0YUNlbGwoYywgaSwge2JvbGQ6dHJ1ZSwgY29sb3I6WEwuYmx1ZURlZXAsIGZpbGw6WEwuYmFzZUZpbGx9KTsKICAgICAgICBjLmJvcmRlciA9IHtib3R0b206eGxCb3JkZXIoWEwuYmx1ZUxpbmUpfTsKICAgICAgICBpZihpID4gMiAmJiByZXMuYmFzZXNbaS0yXSA8IEUuTUlOX0JBU0VfV0FSTikgYy5mb250ID0ge25hbWU6WEwuZm9udCwgc2l6ZToxMC41LCBib2xkOnRydWUsIGNvbG9yOnthcmdiOlhMLm9yYW5nZX19OwogICAgICB9KTsKCiAgICAgIHJlcy5yb3dzLmZvckVhY2goZnVuY3Rpb24ocm93KXsKICAgICAgICBpZihoaWRlWmVybyAmJiByb3cuY2VsbHMuZXZlcnkoZnVuY3Rpb24oYyl7IHJldHVybiBjLmNvdW50ID09PSAwOyB9KSkgcmV0dXJuOwogICAgICAgIC8qIHJvdyB0b3RhbHMgcGVyIGJhbm5lciBncm91cCBmb3Igcm93ICUgKi8KICAgICAgICB2YXIgYnlHcm91cCA9IHt9OwogICAgICAgIFMuY29sdW1ucy5mb3JFYWNoKGZ1bmN0aW9uKGMsIGkpewogICAgICAgICAgaWYoIWMuZ3JvdXBJZCkgcmV0dXJuOwogICAgICAgICAgYnlHcm91cFtjLmdyb3VwSWRdID0gKGJ5R3JvdXBbYy5ncm91cElkXSB8fCAwKSArIHJvdy5jZWxsc1tpXS5jb3VudDsKICAgICAgICB9KTsKICAgICAgICB2YXIgdG90YWxQY3QgPSByb3cuY2VsbHNbMF0ucGN0OwogICAgICAgIHZhciB2YWxzID0gW2xhYmVsT2YocmVzLnZhcmlhYmxlLCByb3cuY2F0ZWdvcnkpXTsKICAgICAgICByb3cuY2VsbHMuZm9yRWFjaChmdW5jdGlvbihjZWxsLCBpKXsKICAgICAgICAgIHZhciBjID0gUy5jb2x1bW5zW2ldOwogICAgICAgICAgdmFscy5wdXNoKGNlbGxUZXh0KGNlbGwsIHRvdGFsUGN0LCBjLmdyb3VwSWQgPyBieUdyb3VwW2MuZ3JvdXBJZF0gOiAwLCBpID09PSAwKSk7CiAgICAgICAgfSk7CiAgICAgICAgdmFyIGRyID0gd3MyLmFkZFJvdyh2YWxzKTsKICAgICAgICBkci5lYWNoQ2VsbCh7aW5jbHVkZUVtcHR5OnRydWV9LCBmdW5jdGlvbihjLCBpKXsKICAgICAgICAgIHN0eWxlRGF0YUNlbGwoYywgaSk7CiAgICAgICAgICBpZihpID4gMSl7CiAgICAgICAgICAgIHZhciBjZWxsID0gcm93LmNlbGxzW2ktMl07CiAgICAgICAgICAgIGlmKGNlbGwuaGlnaGVyVGhhbi5sZW5ndGgpIGMuZm9udCA9IHtuYW1lOlhMLmZvbnQsIHNpemU6MTAuNSwgYm9sZDp0cnVlLCBjb2xvcjp7YXJnYjpYTC5ibHVlRGVlcH19OwogICAgICAgICAgICBlbHNlIGlmKGNlbGwuZnJhZ2lsZSAmJiBpID4gMikgYy5mb250ID0ge25hbWU6WEwuZm9udCwgc2l6ZToxMC41LCBjb2xvcjp7YXJnYjpYTC5vcmFuZ2V9fTsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfSk7CiAgICB9IGVsc2UgewogICAgICBbWydCYXNlJywnbicsMF0sWydNZWFuJywnbWVhbicsMV0sWydTdGQuIGRldmlhdGlvbicsJ3NkJywxXSxbJ01lZGlhbicsJ21lZGlhbicsMV0sWydNaW5pbXVtJywnbWluJywxXSxbJ01heGltdW0nLCdtYXgnLDFdXS5mb3JFYWNoKGZ1bmN0aW9uKHJ3KXsKICAgICAgICB2YXIgdmFscyA9IFtyd1swXV07CiAgICAgICAgcmVzLnN0YXRzLmZvckVhY2goZnVuY3Rpb24ocywgaSl7CiAgICAgICAgICB2YXIgdiA9IHNbcndbMV1dOwogICAgICAgICAgdmFyIHR4dCA9IHYgPT09IG51bGwgPyAn4oCUJyA6IChyd1syXSA\/IE51bWJlcih2KS50b0xvY2FsZVN0cmluZygnZW4tVVMnLHttYXhpbXVtRnJhY3Rpb25EaWdpdHM6Mn0pIDogU3RyaW5nKHYpKTsKICAgICAgICAgIGlmKHJ3WzFdID09PSAnbWVhbicgJiYgcmVzLmhpZ2hlclRoYW5baV0ubGVuZ3RoKSB0eHQgKz0gJyAgKCcgKyByZXMuaGlnaGVyVGhhbltpXS5qb2luKCcnKSArICcpJzsKICAgICAgICAgIHZhbHMucHVzaCh0eHQpOwogICAgICAgIH0pOwogICAgICAgIHZhciBkciA9IHdzMi5hZGRSb3codmFscyk7CiAgICAgICAgdmFyIGlzQmFzZSA9IHJ3WzFdID09PSAnbic7CiAgICAgICAgZHIuZWFjaENlbGwoe2luY2x1ZGVFbXB0eTp0cnVlfSwgZnVuY3Rpb24oYywgaSl7CiAgICAgICAgICBzdHlsZURhdGFDZWxsKGMsIGksIGlzQmFzZSA\/IHtib2xkOnRydWUsIGNvbG9yOlhMLmJsdWVEZWVwLCBmaWxsOlhMLmJhc2VGaWxsfSA6IHt9KTsKICAgICAgICAgIGlmKCFpc0Jhc2UgJiYgcndbMV0gPT09ICdtZWFuJyAmJiBpID4gMSAmJiByZXMuaGlnaGVyVGhhbltpLTJdLmxlbmd0aCl7CiAgICAgICAgICAgIGMuZm9udCA9IHtuYW1lOlhMLmZvbnQsIHNpemU6MTAuNSwgYm9sZDp0cnVlLCBjb2xvcjp7YXJnYjpYTC5ibHVlRGVlcH19OwogICAgICAgICAgfQogICAgICAgICAgaWYoaXNCYXNlICYmIGkgPiAyICYmIHJlcy5zdGF0c1tpLTJdLm4gPCBFLk1JTl9CQVNFX1dBUk4pewogICAgICAgICAgICBjLmZvbnQgPSB7bmFtZTpYTC5mb250LCBzaXplOjEwLjUsIGJvbGQ6dHJ1ZSwgY29sb3I6e2FyZ2I6WEwub3JhbmdlfX07CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgIH0pOwogICAgfQoKICAgIC8qIGZvb3Rub3RlICovCiAgICB2YXIgZm9vdCA9IGZvb3ROb3RlcyhyZXMpLnJlcGxhY2UoLzxbXj5dKz4vZywnJykucmVwbGFjZSgvJmx0Oy9nLCc8JykucmVwbGFjZSgvXHMrL2csJyAnKS50cmltKCk7CiAgICB2YXIgZnIgPSB3czIuYWRkUm93KFtmb290XSk7CiAgICB3czIubWVyZ2VDZWxscyhmci5udW1iZXIsIDEsIGZyLm51bWJlciwgbkNvbHMpOwogICAgZnIuZ2V0Q2VsbCgxKS5mb250ID0ge25hbWU6WEwuZm9udCwgc2l6ZTo5LCBpdGFsaWM6dHJ1ZSwgY29sb3I6e2FyZ2I6WEwuZ3JleU11dGV9fTsKICAgIGZyLmdldENlbGwoMSkuYWxpZ25tZW50ID0ge3dyYXBUZXh0OnRydWUsIHZlcnRpY2FsOid0b3AnLCBpbmRlbnQ6MX07CiAgICBmci5nZXRDZWxsKDEpLmZpbGwgPSB7dHlwZToncGF0dGVybicsIHBhdHRlcm46J3NvbGlkJywgZmdDb2xvcjp7YXJnYjpYTC50b3RhbEZpbGx9fTsKICAgIGZyLmhlaWdodCA9IE1hdGgubWluKDQ4LCAxNCAqIE1hdGguY2VpbChmb290Lmxlbmd0aCAvIDE0MCkgKyA2KTsKICAgIHdzMi5hZGRSb3coW10pOyB3czIuYWRkUm93KFtdKTsKICB9KTsKCiAgLyogZG93bmxvYWQgKi8KICByZXR1cm4gd2IueGxzeC53cml0ZUJ1ZmZlcigpLnRoZW4oZnVuY3Rpb24oYnVmKXsKICAgIHZhciBiYXNlID0gUy5maWxlTmFtZS5yZXBsYWNlKC9cLlteLl0rJC8sJycpIHx8ICdjcm9zc3RhYnMnOwogICAgdmFyIGJsb2IgPSBuZXcgQmxvYihbYnVmXSwge3R5cGU6J2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0J30pOwogICAgdmFyIGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7CiAgICBhLmhyZWYgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpOwogICAgYS5kb3dubG9hZCA9IGJhc2UgKyAnX2Nyb3NzdGFicy54bHN4JzsKICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7CiAgICBhLmNsaWNrKCk7CiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7IFVSTC5yZXZva2VPYmplY3RVUkwoYS5ocmVmKTsgYS5yZW1vdmUoKTsgfSwgMTUwMCk7CiAgfSk7Cn0KCi8qIC0tLS0tLS0tLS0gYnJhbmNoZW1lbnRzIC0tLS0tLS0tLS0gKi8KJCgnZHJvcCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKXsgJCgnZmlsZScpLmNsaWNrKCk7IH0pOwokKCdkcm9wJykuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCBmdW5jdGlvbihlKXsgZS5wcmV2ZW50RGVmYXVsdCgpOyAkKCdkcm9wJykuY2xhc3NMaXN0LmFkZCgnb3ZlcicpOyB9KTsKJCgnZHJvcCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdsZWF2ZScsIGZ1bmN0aW9uKCl7ICQoJ2Ryb3AnKS5jbGFzc0xpc3QucmVtb3ZlKCdvdmVyJyk7IH0pOwokKCdkcm9wJykuYWRkRXZlbnRMaXN0ZW5lcignZHJvcCcsIGZ1bmN0aW9uKGUpewogIGUucHJldmVudERlZmF1bHQoKTsgJCgnZHJvcCcpLmNsYXNzTGlzdC5yZW1vdmUoJ292ZXInKTsKICBpZihlLmRhdGFUcmFuc2Zlci5maWxlc1swXSkgaGFuZGxlRmlsZShlLmRhdGFUcmFuc2Zlci5maWxlc1swXSk7Cn0pOwokKCdmaWxlJykuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24oZSl7IGlmKGUudGFyZ2V0LmZpbGVzWzBdKSBoYW5kbGVGaWxlKGUudGFyZ2V0LmZpbGVzWzBdKTsgfSk7CiQoJ3Jlc2V0JykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpewogIFMuYmFubmVyID0gW107IFMucm93VmFycyA9IG51bGw7IFMudGFibGVzID0gW107CiAgJCgnZmlsZScpLnZhbHVlID0gJyc7CiAgJCgnZHJvcCcpLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlbicpOwogICQoJ2xvYWRlZCcpLmNsYXNzTGlzdC5hZGQoJ2hpZGRlbicpOwogICQoJ3Jlc3VsdHMnKS5jbGFzc0xpc3QuYWRkKCdoaWRkZW4nKTsKICAkKCdzdGVwMicpLmRhdGFzZXQubG9ja2VkID0gJzEnOwogICQoJ3N0ZXAzJykuZGF0YXNldC5sb2NrZWQgPSAnMSc7CiAgJCgnc3RlcDEnKS5kYXRhc2V0LmRvbmUgPSAnJzsKICAkKCdzMW5vdGUnKS50ZXh0Q29udGVudCA9ICdDU1YsIFhMU1ggb3IgWExTIOKAlCBvbmUgcm93IHBlciByZXNwb25kZW50JzsKICBhbGVydEJveCgkKCdsb2FkRXJyJyksJ2luZm8nLCcnKTsKfSk7CiQoJ29wdDk5JykuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24oKXsKICBTLnRyZWF0OTkgPSAkKCdvcHQ5OScpLmNoZWNrZWQ7CiAgcmVuZGVyVmFycygpOyByZW5kZXJQaWNrZXIoKTsgaW52YWxpZGF0ZSgpOwp9KTsKJCgnbG9hZERpY3QnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCl7ICQoJ2RpY3RGaWxlJykuY2xpY2soKTsgfSk7CiQoJ2RpY3RGaWxlJykuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24oZSl7IGlmKGUudGFyZ2V0LmZpbGVzWzBdKSBpbXBvcnREaWN0aW9uYXJ5KGUudGFyZ2V0LmZpbGVzWzBdKTsgfSk7CiQoJ3BpY2tSb3dzJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpewogIHZhciBib3ggPSAkKCdyb3dQaWNrZXInKSwgb3BlbiA9IGJveC5jbGFzc0xpc3QudG9nZ2xlKCdoaWRkZW4nKTsKICBpZighb3Blbil7IHJlbmRlclJvd0NoaXBzKCk7ICQoJ3BpY2tSb3dzJykudGV4dENvbnRlbnQgPSAnSGlkZSB2YXJpYWJsZSBzZWxlY3Rpb24nOyB9CiAgZWxzZSAkKCdwaWNrUm93cycpLnRleHRDb250ZW50ID0gJ0Nob29zZSB3aGljaCB2YXJpYWJsZXMgdG8gdGFidWxhdGUnOwp9KTsKJCgncnVuJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBidWlsZCk7CiQoJ2V4cG9ydCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZXhwb3J0RXhjZWwpOwpkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFtuYW1lPSJhbHBoYSJdJykuZm9yRWFjaChmdW5jdGlvbihyKXsgci5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBpbnZhbGlkYXRlKTsgfSk7Clsnb0NvdW50Jywnb0NvbFBjdCcsJ29Sb3dQY3QnLCdvSGlkZVplcm8nLCdvSW5kZXgnLCdvQ2hpJ10uZm9yRWFjaChmdW5jdGlvbihpZCl7CiAgJChpZCkuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24oKXsgaWYoUy50YWJsZXMubGVuZ3RoKSBidWlsZCgpOyB9KTsKfSk7CiQoJ25hdlNlYXJjaCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgZnVuY3Rpb24oKXsKICB2YXIgcSA9ICQoJ25hdlNlYXJjaCcpLnZhbHVlLnRvTG93ZXJDYXNlKCk7CiAgJCgnbmF2TGlzdCcpLnF1ZXJ5U2VsZWN0b3JBbGwoJ2EnKS5mb3JFYWNoKGZ1bmN0aW9uKGEpewogICAgYS5zdHlsZS5kaXNwbGF5ID0gYS5kYXRhc2V0Lm5hbWUuaW5kZXhPZihxKSA9PT0gLTEgPyAnbm9uZScgOiAnJzsKICB9KTsKfSk7Cn0pKCk7Cg==\"))));<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u2190 Back to Free Tools Crosstab Builder Cross-tabulation with significance testing, for survey data Your data stays in your browser How this works A banner is the set of variables you put in the columns \u2014 typically gender, age group, or region. Every other variable in your file is then tabulated against it, one table&#8230;<\/p>","protected":false},"author":10,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-7582","page","type-page","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/h-in-q.com\/es\/wp-json\/wp\/v2\/pages\/7582","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/h-in-q.com\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/h-in-q.com\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/h-in-q.com\/es\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/h-in-q.com\/es\/wp-json\/wp\/v2\/comments?post=7582"}],"version-history":[{"count":2,"href":"https:\/\/h-in-q.com\/es\/wp-json\/wp\/v2\/pages\/7582\/revisions"}],"predecessor-version":[{"id":7591,"href":"https:\/\/h-in-q.com\/es\/wp-json\/wp\/v2\/pages\/7582\/revisions\/7591"}],"wp:attachment":[{"href":"https:\/\/h-in-q.com\/es\/wp-json\/wp\/v2\/media?parent=7582"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}