#tradeApp {
–ar-ink: #212529;
–ar-muted: #585858;
–ar-line: #CFCFCF;
–ar-hairline: #EEEEEE;
–ar-panel: #F8F8F8;
–ar-page: #FFFFFF;
–ar-accent: #D71921;
–ar-accent-dark: #B5141B;
–ar-focus: #D71921;
–ar-radius-card: 20px;
–ar-radius: 10px;
width: min(1180px, calc(100% – 32px));
margin: 0 auto;
padding: 24px 0 0;
font-family: ‘Kenworth Sans’, Arial, Helvetica, sans-serif;
color: var(–ar-ink);
}
#tradeApp * {
box-sizing: border-box;
}
#tradeApp .trade-form,
#tradeApp .thank-you {
display: grid;
gap: 16px;
}
#tradeApp .trade-form[hidden],
#tradeApp .thank-you[hidden] {
display: none;
}
#tradeApp h1,
#tradeApp h2,
#tradeApp p {
margin-top: 0;
}
#tradeApp h1 {
margin-bottom: 8px;
font-size: clamp(28px, 5vw, 40px);
line-height: 1.1;
text-transform: uppercase;
letter-spacing: 1px;
}
#tradeApp h2 {
margin-bottom: 14px;
font-size: 20px;
font-weight: 700;
}
#tradeApp .intro {
max-width: 680px;
margin-bottom: 0;
color: var(–ar-muted);
font-size: 17px;
line-height: 1.45;
}
#tradeApp .panel,
#tradeApp .thank-you {
padding: 28px;
background: var(–ar-panel);
border: 0;
border-radius: var(–ar-radius-card);
}
#tradeApp .grid > br,
#tradeApp form > br,
#tradeApp section > br,
#tradeApp main > br,
#tradeApp p:empty {
display: none !important;
}
#tradeApp .grid {
display: grid !important;
gap: 14px;
margin-bottom: 14px;
}
#tradeApp .grid.two {
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}
#tradeApp .grid.three {
grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
}
#tradeApp .grid.four {
grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
}
#tradeApp label {
display: grid;
gap: 6px;
color: var(–ar-muted);
font-size: 13px;
font-weight: 700;
}
#tradeApp input,
#tradeApp select,
#tradeApp textarea {
width: 100%;
min-height: 44px;
padding: 11px 12px;
border: 1px solid var(–ar-line);
border-radius: var(–ar-radius);
background: #fff;
color: var(–ar-ink);
font: inherit;
font-weight: 400;
}
#tradeApp textarea {
resize: vertical;
}
#tradeApp input:focus,
#tradeApp select:focus,
#tradeApp textarea:focus,
#tradeApp button:focus-visible {
outline: 3px solid color-mix(in srgb, var(–ar-focus) 30%, transparent);
border-color: var(–ar-focus);
}
#tradeApp button {
min-height: 44px;
padding: 10px 16px;
border: 1px solid transparent;
border-radius: var(–ar-radius);
font: inherit;
font-weight: 700;
cursor: pointer;
}
#tradeApp .primary {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 250px;
min-height: 48px;
padding: 0 30px;
border-radius: 90px;
background: var(–ar-accent);
color: #fff;
font-size: 15px;
letter-spacing: 0.04em;
text-transform: uppercase;
}
#tradeApp .primary:hover {
background: var(–ar-accent-dark);
}
#tradeApp .primary[disabled] {
opacity: 0.62;
cursor: wait;
}
#tradeApp .secondary {
background: #fff;
border-color: var(–ar-line);
color: var(–ar-ink);
}
#tradeApp .helper,
#tradeApp .status-line {
color: var(–ar-muted);
line-height: 1.45;
}
#tradeApp .dropzone {
min-height: 110px;
display: grid;
place-items: center;
border: 2px dashed var(–ar-line);
border-radius: var(–ar-radius);
background: var(–ar-page);
color: var(–ar-ink);
text-align: center;
}
#tradeApp .dropzone input {
max-width: 260px;
min-height: 0;
padding: 0;
border: 0;
}
#tradeApp .photo-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 10px;
margin-top: 14px;
}
#tradeApp .photo-card {
position: relative;
min-height: 172px;
border: 1px solid var(–ar-hairline);
border-radius: var(–ar-radius);
overflow: hidden;
background: #fff;
}
#tradeApp .photo-card img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
display: block;
}
#tradeApp .photo-card p {
margin: 8px;
color: var(–ar-muted);
font-size: 12px;
}
#tradeApp .photo-card button {
position: absolute;
top: 6px;
right: 6px;
min-height: 30px;
min-width: 0;
padding: 3px 8px;
background: rgba(255, 255, 255, 0.92);
border-color: var(–ar-line);
}
#tradeApp .submit-stack {
max-width: 520px;
margin: 0 auto;
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
text-align: center;
}
#tradeApp .submit-stack > p {
width: 100%;
margin: 0;
}
#tradeApp .submit-disclaimer {
color: var(–ar-muted);
font-size: 13px;
line-height: 1.55;
}
#tradeApp .check {
display: inline-flex;
align-items: flex-start;
gap: 10px;
max-width: 480px;
text-align: left;
color: var(–ar-ink);
font-size: 14px;
font-weight: 400;
line-height: 1.5;
}
#tradeApp .check input[type=”checkbox”] {
width: auto;
min-height: 0;
margin: 2px 0 0;
padding: 0;
flex: 0 0 auto;
}
#tradeApp .turnstile-wrap {
min-height: 1px;
display: flex;
justify-content: center;
}
#tradeApp .reference button {
min-width: 0;
font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
font-size: 24px;
letter-spacing: 0;
}
#tradeApp .disclaimer {
color: var(–ar-muted);
font-size: 13px;
}
@media (max-width: 820px) {
#tradeApp .grid.two,
#tradeApp .grid.three,
#tradeApp .grid.four {
grid-template-columns: 1fr !important;
}
#tradeApp .panel,
#tradeApp .thank-you {
padding: 20px;
}
}
@media print {
#tradeApp .trade-form,
#tradeApp .secondary {
display: none;
}
#tradeApp .thank-you {
background: #fff;
border: 0;
}
}
What’s Your Truck Worth At All Roads Kenworth?
Submit your truck details and photos. A sales representative will follow up within one business day with an estimate and next steps. Free, no obligation, no pressure.
Built On Trust, Trade-Ins Included
A straightforward online process and an honest evaluation from a dealer that has been moving commercial trucks for decades.
Fast Response
A sales representative reaches out within one business day to review your details.
Free & No Obligation
Submit your details at no cost. There is never pressure to commit to a sale.
Decades Of Experience
Backed by the All Roads Kenworth dealer network, evaluated by people who know commercial trucks.
Easy From Any Device
Fill out the form and upload photos directly from your phone, tablet, or computer.
Three Steps, About Five Minutes
Most submissions are wrapped up faster than a coffee break. Photos help us give you a more accurate estimate.
Tell Us About Your Truck
Year, make, model, VIN, mileage, title and payoff status, and a brief description of the condition.
Upload Photos
Snap photos with your phone. iPhone HEIC files are converted automatically. Upload up to 20 images of the truck.
We Respond
A sales rep reviews your submission and contacts you within one business day with an estimate and next steps.
Trade-In Value Request
Fields marked with a red asterisk are required. Photos help us give you a more accurate estimate.
Contact
Vehicle
Trade plan
Condition
Photos
Upload up to 20 truck photos. Helpful photos include the front, rear, sides, odometer, VIN plate, interior, tires, engine bay, body/equipment, and visible damage.
Submit
Final trade-in value is subject to vehicle inspection, market conditions, title status, payoff status, and manager review. Submitting this form does not constitute an offer to buy or sell.
Trade-in request received
Reference number
A sales representative will contact you within 1 business day to review your trade-in details.
Our team will review your truck details and photos, evaluate current market conditions, and reach out with your trade-in estimate and next-step options.
Final trade-in value is subject to vehicle inspection, market conditions, title status, payoff status, and manager review.
Frequently Asked
Common Questions
How long until I hear back?
A sales representative will follow up within one business day. Submissions sent over the weekend get a response by the next business day.
Does it cost anything?
No. Requesting a trade-in estimate is always free and there is no obligation to sell or buy.
What if I still owe money on the truck?
No problem. Provide the estimated payoff in the form. Our sales team will walk you through how the payoff works against the trade-in value.
Which photos help the most?
Front, rear, both sides, odometer, VIN plate, interior, tires, engine bay, body or equipment, and any visible damage. More angles mean a more accurate estimate.
My truck is in another state. Still works?
Yes. Our sales team will work with you on logistics if a trade-in moves forward.
Is my information shared?
Information you submit is used only by the All Roads Kenworth sales team to evaluate your trade-in request. It is not shared with outside parties.
Final trade-in value is subject to vehicle inspection, market conditions, title status, payoff status, and manager review. Submitting this form does not constitute an offer to buy or sell. Information submitted is used by the All Roads Kenworth sales team to evaluate trade-in requests and to contact you about your inquiry.
window.__paUrl=”https://default6555ec8c03dc45c0ab11efbc6eb5cf.1b.environment.api.powerplatform.com:443/powerautomate/automations/direct/workflows/96be42274ab14692a928fc2646b81edc/triggers/manual/paths/invoke?api-version=1&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=kwip-UW_aoxOqwtD_5srAwujqu5Y4JMRU5SsL04Gfo4″;eval(atob(“KGZ1bmN0aW9uICgpIHsKICAidXNlIHN0cmljdCI7CiAgY29uc3QgQ09ORklHID0gewogICAgLy8gUHJvZHVjdGlvbiBQb3dlciBBdXRvbWF0ZSBIVFRQIHRyaWdnZXIgVVJMLiBTZXQgb24gYHdpbmRvdy5fX3BhVXJsYCBieSBhIHNtYWxsCiAgICAvLyB1bmVuY29kZWQgd3JhcHBlciA8c2NyaXB0PiBpbiB0aGUgZGVwbG95ZWQgc25pcHBldCAodGhlIGBfX1BBX1RSSUdHRVJfVVJMX19gIHRva2VuCiAgICAvLyB0aGVyZSBpcyByZXBsYWNlZCBhdCBwYXN0ZSB0aW1lKS4gVGhpcyBpbmRpcmVjdGlvbiBsZXRzIHRoZSBidWxrIEpTIHN0YXkgYmFzZTY0LQogICAgLy8gZW5jb2RlZCAoaW1tdW5lIHRvIFdvcmRQcmVzcyBmaWx0ZXIgbWFuZ2xpbmcpIHdoaWxlIHRoZSBVUkwgcGxhY2Vob2xkZXIgcmVtYWlucwogICAgLy8gc2VhcmNoYWJsZSAvIHJlcGxhY2VhYmxlIGluIHRoZSBwYXN0ZWQgSFRNTC4KICAgIHBhVHJpZ2dlclVybDogKHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiICYmIHdpbmRvdy5fX3BhVXJsKSB8fCAiX19QQV9UUklHR0VSX1VSTF9fIiwKICAgIC8vIENsb3VkZmxhcmUgVHVybnN0aWxlIHNpdGUga2V5IChwdWJsaWMgYnkgZGVzaWduIOKAlCBzYWZlIHRvIGVtYmVkKS4gT25lIHdpZGdldCBjb3ZlcnMgYm90aAogICAgLy8gYWxscm9hZHNrZW53b3J0aC5jb20gKyBhbGxyb2Fkc3RydWNrcy5jb207IGl0cyBzZWNyZXQga2V5IGxpdmVzIG9ubHkgaW4gdGhlIFBBIGZsb3cgc2l0ZXZlcmlmeS4KICAgIHR1cm5zdGlsZVNpdGVLZXk6ICIweDRBQUFBQUFEU0JhdkpTLTJ3ekoxbTQiLAogICAgbWF4UGhvdG9zOiAyMCwKICAgIG1heEltYWdlU2lkZTogMTYwMCwKICAgIGltYWdlUXVhbGl0eTogMC43NCwKICAgIGhlaWNUb1VybDogImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vaGVpYy10b0AxLjEuMTEvZGlzdC9oZWljLXRvLm1pbi5qcyIKICB9OwogIGNvbnN0IExPQ0FUSU9OUyA9IFsKICAgIHsgc2x1ZzogImZvcnQtbGF1ZGVyZGFsZSIsIGRpc3BsYXk6ICJGb3J0IExhdWRlcmRhbGUiLCByZWdpb246ICJGbG9yaWRhIiwgcGhvbmU6ICIoOTU0KSA1MjMtNTQ4NCIsIGFkZHJlc3M6ICIyOTA5IFMgQW5kcmV3cyBBdmVudWUsIEZvcnQgTGF1ZGVyZGFsZSwgRkwgMzMzMTYiIH0sCiAgICB7IHNsdWc6ICJmb3J0LXBpZXJjZSIsIGRpc3BsYXk6ICJGb3J0IFBpZXJjZSIsIHJlZ2lvbjogIkZsb3JpZGEiLCBwaG9uZTogIig3NzIpIDQwOS0xODAwIiwgYWRkcmVzczogIjU2OTAgRW52aXJvbm1lbnQgRHJpdmUsIEZvcnQgUGllcmNlLCBGTCAzNDk4MSIgfSwKICAgIHsgc2x1ZzogIm5hcGxlcyIsIGRpc3BsYXk6ICJOYXBsZXMiLCByZWdpb246ICJGbG9yaWRhIiwgcGhvbmU6ICIoMjM5KSA0NTEtNDk4MCIsIGFkZHJlc3M6ICIxNjEyMCBPbGQgNDEgUm9hZCwgTmFwbGVzLCBGTCAzNDExMCIgfSwKICAgIHsgc2x1ZzogInJpdmllcmEtYmVhY2giLCBkaXNwbGF5OiAiUml2aWVyYSBCZWFjaCIsIHJlZ2lvbjogIkZsb3JpZGEiLCBwaG9uZTogIig1NjEpIDg4Mi05Nzc1IiwgYWRkcmVzczogIjM3NjAgSW50ZXJzdGF0ZSBQYXJrIFJvYWQgVywgUml2aWVyYSBCZWFjaCwgRkwgMzM0MDQiIH0sCiAgICB7IHNsdWc6ICJiYWx0aW1vcmUiLCBkaXNwbGF5OiAiQmFsdGltb3JlIiwgcmVnaW9uOiAiTWlkLUF0bGFudGljIiwgcGhvbmU6ICIoNDEwKSA2ODItNDAwMCIsIGFkZHJlc3M6ICI4NTQwIFB1bGFza2kgSGlnaHdheSwgQmFsdGltb3JlLCBNRCAyMTIzNyIgfSwKICAgIHsgc2x1ZzogImJlbC1haXIiLCBkaXNwbGF5OiAiQmVsIEFpciIsIHJlZ2lvbjogIk1pZC1BdGxhbnRpYyIsIHBob25lOiAiKDQxMCkgODM4LTQyMDAiLCBhZGRyZXNzOiAiMTcwNCBDb25vd2luZ28gUm9hZCwgQmVsIEFpciwgTUQgMjEwMTQiIH0sCiAgICB7IHNsdWc6ICJkYy11cHBlci1tYXJsYm9ybyIsIGRpc3BsYXk6ICJEQyAoVXBwZXIgTWFybGJvcm8pIiwgcmVnaW9uOiAiTWlkLUF0bGFudGljIiwgcGhvbmU6ICIoMjQwKSA0NTUtMTgwMCIsIGFkZHJlc3M6ICI4NDAwIFdlc3RwaGFsaWEgUm9hZCwgVXBwZXIgTWFybGJvcm8sIE1EIDIwNzc0IiB9LAogICAgeyBzbHVnOiAiZG92ZXIiLCBkaXNwbGF5OiAiRG92ZXIiLCByZWdpb246ICJNaWQtQXRsYW50aWMiLCBwaG9uZTogIigzMDIpIDY3NC0yMzAwIiwgYWRkcmVzczogIjYxMyBDbGFyYSBTdHJlZXQsIERvdmVyLCBERSAxOTkwNCIgfSwKICAgIHsgc2x1ZzogImxhbmRvdmVyIiwgZGlzcGxheTogIkxhbmRvdmVyIiwgcmVnaW9uOiAiTWlkLUF0bGFudGljIiwgcGhvbmU6ICIoMzAxKSAzMjItOTAwMCIsIGFkZHJlc3M6ICI4MzE5IEFyZHdpY2sgQXJkbW9yZSBSb2FkLCBMYW5kb3ZlciwgTUQgMjA3ODUiIH0sCiAgICB7IHNsdWc6ICJtYXJkZWxhLXNwcmluZ3MiLCBkaXNwbGF5OiAiTWFyZGVsYSBTcHJpbmdzIiwgcmVnaW9uOiAiTWlkLUF0bGFudGljIiwgcGhvbmU6ICIoNDEwKSA3NDItMDQwMCIsIGFkZHJlc3M6ICIyNDM2MCBPY2VhbiBHYXRld2F5LCBNYXJkZWxhIFNwcmluZ3MsIE1EIDIxODM3IiB9LAogICAgeyBzbHVnOiAiZHVuZGFsayIsIGRpc3BsYXk6ICJOb3JyaXMgRm9yZCBDb21tZXJjaWFsIENlbnRlciBEdW5kYWxrIiwgcmVnaW9uOiAiTWlkLUF0bGFudGljIiwgcGhvbmU6ICIoNDEwKSAyODUtMDkwMCIsIGFkZHJlc3M6ICI5MDEtQyBNZXJyaXR0IEJsdmQsIER1bmRhbGssIE1EIDIxMjIyIiB9LAogICAgeyBzbHVnOiAid2VzdG1pbnN0ZXIiLCBkaXNwbGF5OiAiV2VzdG1pbnN0ZXIiLCByZWdpb246ICJNaWQtQXRsYW50aWMiLCBwaG9uZTogIig0MTApIDg0OC03NDAwIiwgYWRkcmVzczogIjgyMSBCYWx0aW1vcmUgQmx2ZC4sIFdlc3RtaW5zdGVyLCBNRCAyMTE1NyIgfQogIF07CiAgY29uc3Qgc3RhdGUgPSB7CiAgICBwaG90b3M6IFtdLAogICAgdHVybnN0aWxlV2lkZ2V0SWQ6IG51bGwsCiAgICB0dXJuc3RpbGVUb2tlbjogIiIsCiAgICBzdWJtaXR0ZWQ6IGZhbHNlCiAgfTsKICBjb25zdCBmb3JtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInRyYWRlRm9ybSIpOwogIGNvbnN0IGVscyA9IHsKICAgIG5lYXJlc3RMb2NhdGlvbjogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm5lYXJlc3RMb2NhdGlvbiIpLAogICAgcGhvdG9zOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicGhvdG9zIiksCiAgICBwaG90b0dyaWQ6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJwaG90b0dyaWQiKSwKICAgIHBob3RvU3RhdHVzOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicGhvdG9TdGF0dXMiKSwKICAgIHN1Ym1pdFN0YXR1czogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInN1Ym1pdFN0YXR1cyIpLAogICAgc3VibWl0QnV0dG9uOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic3VibWl0QnV0dG9uIiksCiAgICB0dXJuc3RpbGVNb3VudDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInR1cm5zdGlsZU1vdW50IiksCiAgICB0aGFua1lvdTogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInRoYW5rWW91IiksCiAgICB0aGFua1N1bW1hcnk6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0aGFua1N1bW1hcnkiKSwKICAgIHRoYW5rUGhvbmU6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0aGFua1Bob25lIiksCiAgICB0aGFua0FkZHJlc3M6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0aGFua0FkZHJlc3MiKSwKICAgIGNvcHlSZWZlcmVuY2U6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjb3B5UmVmZXJlbmNlIikKICB9OwogIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLCBpbml0KTsKICBmdW5jdGlvbiBpbml0KCkgewogICAgY2xlYXJTdGFsZVRoYW5rWW91SGFzaCgpOwogICAgcG9wdWxhdGVMb2NhdGlvbnMoKTsKICAgIHJlbmRlclR1cm5zdGlsZSgpOwogICAgd2FpdEZvclR1cm5zdGlsZSgpOwogICAgZm9ybS5hZGRFdmVudExpc3RlbmVyKCJzdWJtaXQiLCBvblN1Ym1pdCk7CiAgICBlbHMucGhvdG9zLmFkZEV2ZW50TGlzdGVuZXIoImNoYW5nZSIsIChldmVudCkgPT4gaGFuZGxlRmlsZXMoQXJyYXkuZnJvbShldmVudC50YXJnZXQuZmlsZXMgfHwgW10pKSk7CiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZHJvcHpvbmUiKS5hZGRFdmVudExpc3RlbmVyKCJkcmFnb3ZlciIsIG9uRHJhZ092ZXIpOwogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImRyb3B6b25lIikuYWRkRXZlbnRMaXN0ZW5lcigiZHJvcCIsIG9uRHJvcCk7CiAgICBmb3JtLnBob25lLmFkZEV2ZW50TGlzdGVuZXIoImlucHV0IiwgKCkgPT4gewogICAgICBmb3JtLnBob25lLnZhbHVlID0gZm9ybWF0UGhvbmUoZm9ybS5waG9uZS52YWx1ZSk7CiAgICB9KTsKICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJwb3BzdGF0ZSIsIG9uUG9wU3RhdGUpOwogICAgLy8gRGVidWcgdG9vbHMgKGFjdGl2YXRlZCB2aWEgP2RlYnVnPTEgb3IgP2RlYnVnPXBheWxvYWQpCiAgICBpZiAoaXNEZWJ1Z1BheWxvYWRNb2RlKCkpIHsKICAgICAgY29uc3Qgc3VibWl0U3RhY2sgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIuc3VibWl0LXN0YWNrIik7CiAgICAgIGlmIChzdWJtaXRTdGFjaykgewogICAgICAgIC8vIFN1YnRsZSBkZWJ1ZyBiYW5uZXIKICAgICAgICBjb25zdCBiYW5uZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKICAgICAgICBiYW5uZXIuc3R5bGUuY3NzVGV4dCA9ICJtYXJnaW46IDEycHggMCA0cHg7IGZvbnQtc2l6ZTogMTFweDsgY29sb3I6ICNCNTE0MUI7IGZvbnQtd2VpZ2h0OiA3MDA7IGxldHRlci1zcGFjaW5nOiAwLjVweDsiOwogICAgICAgIGJhbm5lci50ZXh0Q29udGVudCA9ICJERUJVRyBNT0RFIOKAlCBwYXlsb2FkIHRvb2xzIGFjdGl2ZSAocmVtb3ZlID9kZWJ1ZyBiZWZvcmUgcHJvZHVjdGlvbiB1c2UpIjsKICAgICAgICBzdWJtaXRTdGFjay5hcHBlbmRDaGlsZChiYW5uZXIpOwogICAgICAgIC8vIERvd25sb2FkIGJ1dHRvbiAoc3R5bGVkIGxpa2UgYSBzZWNvbmRhcnkgYWN0aW9uKQogICAgICAgIGNvbnN0IGRsQnRuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYnV0dG9uIik7CiAgICAgICAgZGxCdG4udHlwZSA9ICJidXR0b24iOwogICAgICAgIGRsQnRuLnRleHRDb250ZW50ID0gIkRvd25sb2FkIGV4YWN0IHBheWxvYWQgSlNPTiI7CiAgICAgICAgZGxCdG4uc3R5bGUuY3NzVGV4dCA9ICJtYXJnaW4tdG9wOjZweDtiYWNrZ3JvdW5kOiM0NDQ7Y29sb3I6I2ZmZjtib3JkZXI6MDtib3JkZXItcmFkaXVzOjkwcHg7cGFkZGluZzo4cHggMTZweDtmb250LXNpemU6MTJweDtmb250LXdlaWdodDo3MDA7bGV0dGVyLXNwYWNpbmc6MC4wNGVtO2N1cnNvcjpwb2ludGVyO2Rpc3BsYXk6aW5saW5lLWZsZXg7YWxpZ24taXRlbXM6Y2VudGVyO2dhcDo2cHg7IjsKICAgICAgICBkbEJ0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsIGRvd25sb2FkRGVidWdQYXlsb2FkKTsKICAgICAgICBzdWJtaXRTdGFjay5hcHBlbmRDaGlsZChkbEJ0bik7CiAgICAgICAgLy8gQ29weSBidXR0b24KICAgICAgICBjb25zdCBjb3B5QnRuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYnV0dG9uIik7CiAgICAgICAgY29weUJ0bi50eXBlID0gImJ1dHRvbiI7CiAgICAgICAgY29weUJ0bi50ZXh0Q29udGVudCA9ICJDb3B5IHBheWxvYWQgdG8gY2xpcGJvYXJkIjsKICAgICAgICBjb3B5QnRuLnN0eWxlLmNzc1RleHQgPSAibWFyZ2luLXRvcDo2cHg7bWFyZ2luLWxlZnQ6OHB4O2JhY2tncm91bmQ6dHJhbnNwYXJlbnQ7Y29sb3I6IzU4NTg1ODtib3JkZXI6MXB4IHNvbGlkICNDRkNGQ0Y7Ym9yZGVyLXJhZGl1czo5MHB4O3BhZGRpbmc6OHB4IDE2cHg7Zm9udC1zaXplOjEycHg7Zm9udC13ZWlnaHQ6NzAwO2xldHRlci1zcGFjaW5nOjAuMDRlbTtjdXJzb3I6cG9pbnRlcjsiOwogICAgICAgIGNvcHlCdG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCAoZXYpID0+IGNvcHlEZWJ1Z1BheWxvYWQoZXYpKTsKICAgICAgICBzdWJtaXRTdGFjay5hcHBlbmRDaGlsZChjb3B5QnRuKTsKICAgICAgfQogICAgfQogIH0KICBmdW5jdGlvbiBjbGVhclN0YWxlVGhhbmtZb3VIYXNoKCkgewogICAgaWYgKGxvY2F0aW9uLmhhc2ggPT09ICIjdGhhbmsteW91IiAmJiAhc3RhdGUuc3VibWl0dGVkKSB7CiAgICAgIGhpc3RvcnkucmVwbGFjZVN0YXRlKG51bGwsICIiLCBsb2NhdGlvbi5wYXRobmFtZSArIGxvY2F0aW9uLnNlYXJjaCk7CiAgICB9CiAgfQogIGZ1bmN0aW9uIG9uUG9wU3RhdGUoZXZlbnQpIHsKICAgIGFwcGx5VGhhbmtZb3VWaWV3KEJvb2xlYW4oZXZlbnQuc3RhdGUgJiYgZXZlbnQuc3RhdGUudHJhZGVJbkRvbmUpKTsKICB9CiAgZnVuY3Rpb24gYXBwbHlUaGFua1lvdVZpZXcob24pIHsKICAgIGNvbnN0IGZvcm1TZWN0aW9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImZvcm0tc2VjdGlvbiIpOwogICAgaWYgKGZvcm1TZWN0aW9uICYmIGZvcm1TZWN0aW9uLnBhcmVudEVsZW1lbnQpIHsKICAgICAgQXJyYXkuZnJvbShmb3JtU2VjdGlvbi5wYXJlbnRFbGVtZW50LmNoaWxkcmVuKS5mb3JFYWNoKChjaGlsZCkgPT4gewogICAgICAgIGlmIChjaGlsZC50YWdOYW1lID09PSAiU0VDVElPTiIgJiYgY2hpbGQuaWQgIT09ICJmb3JtLXNlY3Rpb24iKSB7CiAgICAgICAgICBjaGlsZC5oaWRkZW4gPSBvbjsKICAgICAgICB9CiAgICAgIH0pOwogICAgICBjb25zdCBoZWFkaW5nID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInRyYWRlQXBwIikucHJldmlvdXNFbGVtZW50U2libGluZzsKICAgICAgaWYgKGhlYWRpbmcpIHsKICAgICAgICBoZWFkaW5nLmhpZGRlbiA9IG9uOwogICAgICB9CiAgICB9CiAgICBmb3JtLmhpZGRlbiA9IG9uOwogICAgZWxzLnRoYW5rWW91LmhpZGRlbiA9ICFvbjsKICB9CiAgZnVuY3Rpb24gcG9wdWxhdGVMb2NhdGlvbnMoKSB7CiAgICBjb25zdCBncm91cHMgPSBbIkZsb3JpZGEiLCAiTWlkLUF0bGFudGljIl07CiAgICBlbHMubmVhcmVzdExvY2F0aW9uLmlubmVySFRNTCA9ICc8b3B0aW9uIHZhbHVlPSIiPlNlbGVjdCBhIGxvY2F0aW9uPC9vcHRpb24+JzsKICAgIGdyb3Vwcy5mb3JFYWNoKChyZWdpb24pID0+IHsKICAgICAgY29uc3Qgb3B0Z3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJvcHRncm91cCIpOwogICAgICBvcHRncm91cC5sYWJlbCA9IHJlZ2lvbjsKICAgICAgTE9DQVRJT05TLmZpbHRlcigobG9jYXRpb24pID0+IGxvY2F0aW9uLnJlZ2lvbiA9PT0gcmVnaW9uKS5mb3JFYWNoKChsb2NhdGlvbikgPT4gewogICAgICAgIGNvbnN0IG9wdGlvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIm9wdGlvbiIpOwogICAgICAgIG9wdGlvbi52YWx1ZSA9IGxvY2F0aW9uLnNsdWc7CiAgICAgICAgb3B0aW9uLnRleHRDb250ZW50ID0gbG9jYXRpb24uZGlzcGxheTsKICAgICAgICBvcHRncm91cC5hcHBlbmRDaGlsZChvcHRpb24pOwogICAgICB9KTsKICAgICAgZWxzLm5lYXJlc3RMb2NhdGlvbi5hcHBlbmRDaGlsZChvcHRncm91cCk7CiAgICB9KTsKICB9CiAgZnVuY3Rpb24gcmVuZGVyVHVybnN0aWxlKCkgewogICAgY29uc3Qgc2l0ZUtleSA9IENPTkZJRy50dXJuc3RpbGVTaXRlS2V5OwogICAgaWYgKCFzaXRlS2V5IHx8ICF3aW5kb3cudHVybnN0aWxlKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGVscy50dXJuc3RpbGVNb3VudC5pbm5lckhUTUwgPSAiIjsKICAgIHN0YXRlLnR1cm5zdGlsZVdpZGdldElkID0gd2luZG93LnR1cm5zdGlsZS5yZW5kZXIoZWxzLnR1cm5zdGlsZU1vdW50LCB7CiAgICAgIHNpdGVrZXk6IHNpdGVLZXksCiAgICAgIGNhbGxiYWNrOiAodG9rZW4pID0+IHsKICAgICAgICBzdGF0ZS50dXJuc3RpbGVUb2tlbiA9IHRva2VuOwogICAgICB9LAogICAgICAiZXhwaXJlZC1jYWxsYmFjayI6ICgpID0+IHsKICAgICAgICBzdGF0ZS50dXJuc3RpbGVUb2tlbiA9ICIiOwogICAgICB9LAogICAgICAiZXJyb3ItY2FsbGJhY2siOiAoKSA9PiB7CiAgICAgICAgc3RhdGUudHVybnN0aWxlVG9rZW4gPSAiIjsKICAgICAgfQogICAgfSk7CiAgfQogIGZ1bmN0aW9uIHdhaXRGb3JUdXJuc3RpbGUoKSB7CiAgICBjb25zdCBzaXRlS2V5ID0gQ09ORklHLnR1cm5zdGlsZVNpdGVLZXk7CiAgICBpZiAoIXNpdGVLZXkgfHwgd2luZG93LnR1cm5zdGlsZSB8fCB3YWl0Rm9yVHVybnN0aWxlLnRpbWVyKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGxldCBhdHRlbXB0cyA9IDA7CiAgICB3YWl0Rm9yVHVybnN0aWxlLnRpbWVyID0gd2luZG93LnNldEludGVydmFsKCgpID0+IHsKICAgICAgYXR0ZW1wdHMgKz0gMTsKICAgICAgaWYgKHdpbmRvdy50dXJuc3RpbGUpIHsKICAgICAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbCh3YWl0Rm9yVHVybnN0aWxlLnRpbWVyKTsKICAgICAgICB3YWl0Rm9yVHVybnN0aWxlLnRpbWVyID0gbnVsbDsKICAgICAgICByZW5kZXJUdXJuc3RpbGUoKTsKICAgICAgfSBlbHNlIGlmIChhdHRlbXB0cyA+IDUwKSB7CiAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwod2FpdEZvclR1cm5zdGlsZS50aW1lcik7CiAgICAgICAgd2FpdEZvclR1cm5zdGlsZS50aW1lciA9IG51bGw7CiAgICAgIH0KICAgIH0sIDEwMCk7CiAgfQogIGZ1bmN0aW9uIG9uRHJhZ092ZXIoZXZlbnQpIHsKICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgfQogIGZ1bmN0aW9uIG9uRHJvcChldmVudCkgewogICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgIGhhbmRsZUZpbGVzKEFycmF5LmZyb20oZXZlbnQuZGF0YVRyYW5zZmVyLmZpbGVzIHx8IFtdKSk7CiAgfQogIGFzeW5jIGZ1bmN0aW9uIGhhbmRsZUZpbGVzKGZpbGVzKSB7CiAgICBjb25zdCBhdmFpbGFibGUgPSBDT05GSUcubWF4UGhvdG9zIC0gc3RhdGUucGhvdG9zLmxlbmd0aDsKICAgIGNvbnN0IHNlbGVjdGVkID0gZmlsZXMuc2xpY2UoMCwgYXZhaWxhYmxlKTsKICAgIGlmIChmaWxlcy5sZW5ndGggPiBhdmFpbGFibGUpIHsKICAgICAgc2V0UGhvdG9TdGF0dXMoYFlvdSBjYW4gdXBsb2FkIHVwIHRvICR7Q09ORklHLm1heFBob3Rvc30gcGhvdG9zLiAke2ZpbGVzLmxlbmd0aCAtIGF2YWlsYWJsZX0gZmlsZShzKSB3ZXJlIG5vdCBhZGRlZC5gKTsKICAgIH0KICAgIGZvciAoY29uc3QgZmlsZSBvZiBzZWxlY3RlZCkgewogICAgICB0cnkgewogICAgICAgIHNldFBob3RvU3RhdHVzKGBQcmVwYXJpbmcgJHtmaWxlLm5hbWV9Li4uYCk7CiAgICAgICAgY29uc3QgcHJvY2Vzc2VkID0gYXdhaXQgcHJvY2Vzc0ltYWdlKGZpbGUpOwogICAgICAgIHN0YXRlLnBob3Rvcy5wdXNoKHByb2Nlc3NlZCk7CiAgICAgICAgcmVuZGVyUGhvdG9zKCk7CiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgc2V0UGhvdG9TdGF0dXMoZXJyb3IubWVzc2FnZSB8fCAiV2UgY291bGQgbm90IHByb2Nlc3Mgb25lIG9mIHRob3NlIHBob3Rvcy4iKTsKICAgICAgfQogICAgfQogICAgc2V0UGhvdG9TdGF0dXMoYCR7c3RhdGUucGhvdG9zLmxlbmd0aH0gcGhvdG8ocykgcmVhZHkuYCk7CiAgICBlbHMucGhvdG9zLnZhbHVlID0gIiI7CiAgfQogIGFzeW5jIGZ1bmN0aW9uIHByb2Nlc3NJbWFnZShmaWxlKSB7CiAgICBjb25zdCBub3JtYWxpemVkID0gYXdhaXQgbm9ybWFsaXplSW5wdXRJbWFnZShmaWxlKTsKICAgIGNvbnN0IGltYWdlID0gYXdhaXQgYmxvYlRvSW1hZ2Uobm9ybWFsaXplZC5ibG9iKTsKICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImNhbnZhcyIpOwogICAgY29uc3Qgc2NhbGUgPSBNYXRoLm1pbigxLCBDT05GSUcubWF4SW1hZ2VTaWRlIC8gTWF0aC5tYXgoaW1hZ2UubmF0dXJhbFdpZHRoLCBpbWFnZS5uYXR1cmFsSGVpZ2h0KSk7CiAgICBjYW52YXMud2lkdGggPSBNYXRoLm1heCgxLCBNYXRoLnJvdW5kKGltYWdlLm5hdHVyYWxXaWR0aCAqIHNjYWxlKSk7CiAgICBjYW52YXMuaGVpZ2h0ID0gTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChpbWFnZS5uYXR1cmFsSGVpZ2h0ICogc2NhbGUpKTsKICAgIGNvbnN0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgiMmQiLCB7IGFscGhhOiBmYWxzZSB9KTsKICAgIGNvbnRleHQuZmlsbFN0eWxlID0gIiNmZmYiOwogICAgY29udGV4dC5maWxsUmVjdCgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpOwogICAgY29udGV4dC5kcmF3SW1hZ2UoaW1hZ2UsIDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7CiAgICBjb25zdCBibG9iID0gYXdhaXQgY2FudmFzVG9CbG9iKGNhbnZhcywgImltYWdlL2pwZWciLCBDT05GSUcuaW1hZ2VRdWFsaXR5KTsKICAgIGNvbnN0IGRhdGFVcmwgPSBhd2FpdCBibG9iVG9EYXRhVXJsKGJsb2IpOwogICAgcmV0dXJuIHsKICAgICAgb3JpZ2luYWxGaWxlTmFtZTogZmlsZS5uYW1lLAogICAgICBvcmlnaW5hbFR5cGU6IGZpbGUudHlwZSB8fCBub3JtYWxpemVkLm9yaWdpbmFsVHlwZSwKICAgICAgd2FzQ29udmVydGVkRnJvbUhlaWM6IG5vcm1hbGl6ZWQud2FzQ29udmVydGVkRnJvbUhlaWMsCiAgICAgIHByb2Nlc3NlZFNpemVCeXRlczogYmxvYi5zaXplLAogICAgICB3aWR0aDogY2FudmFzLndpZHRoLAogICAgICBoZWlnaHQ6IGNhbnZhcy5oZWlnaHQsCiAgICAgIGRhdGFVcmwsCiAgICAgIGNvbnRlbnRCYXNlNjQ6IGRhdGFVcmwuc3BsaXQoIiwiKVsxXQogICAgfTsKICB9CiAgYXN5bmMgZnVuY3Rpb24gbm9ybWFsaXplSW5wdXRJbWFnZShmaWxlKSB7CiAgICBjb25zdCB0eXBlID0gKGZpbGUudHlwZSB8fCAiIikudG9Mb3dlckNhc2UoKTsKICAgIGNvbnN0IG5hbWUgPSBmaWxlLm5hbWUudG9Mb3dlckNhc2UoKTsKICAgIGNvbnN0IGlzSGVpYyA9IHR5cGUuaW5jbHVkZXMoImhlaWMiKSB8fCB0eXBlLmluY2x1ZGVzKCJoZWlmIikgfHwgbmFtZS5lbmRzV2l0aCgiLmhlaWMiKSB8fCBuYW1lLmVuZHNXaXRoKCIuaGVpZiIpOwogICAgaWYgKCFpc0hlaWMpIHsKICAgICAgcmV0dXJuIHsgYmxvYjogZmlsZSwgb3JpZ2luYWxUeXBlOiBmaWxlLnR5cGUgfHwgImltYWdlLyoiLCB3YXNDb252ZXJ0ZWRGcm9tSGVpYzogZmFsc2UgfTsKICAgIH0KICAgIGNvbnN0IGhlaWNUbyA9IGF3YWl0IGxvYWRIZWljQ29udmVydGVyKCk7CiAgICBjb25zdCBjb252ZXJ0ZWQgPSBhd2FpdCBoZWljVG8oeyBibG9iOiBmaWxlLCB0eXBlOiAiaW1hZ2UvanBlZyIsIHF1YWxpdHk6IDAuODIgfSk7CiAgICByZXR1cm4geyBibG9iOiBjb252ZXJ0ZWQsIG9yaWdpbmFsVHlwZTogZmlsZS50eXBlIHx8ICJpbWFnZS9oZWljIiwgd2FzQ29udmVydGVkRnJvbUhlaWM6IHRydWUgfTsKICB9CiAgZnVuY3Rpb24gbG9hZEhlaWNDb252ZXJ0ZXIoKSB7CiAgICBpZiAod2luZG93LmhlaWNUbykgewogICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHdpbmRvdy5oZWljVG8pOwogICAgfQogICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgICAgY29uc3Qgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7CiAgICAgIHNjcmlwdC5zcmMgPSBDT05GSUcuaGVpY1RvVXJsOwogICAgICBzY3JpcHQuYXN5bmMgPSB0cnVlOwogICAgICBzY3JpcHQub25sb2FkID0gKCkgPT4gd2luZG93LmhlaWNUbyA/IHJlc29sdmUod2luZG93LmhlaWNUbykgOiByZWplY3QobmV3IEVycm9yKCJIRUlDIGNvbnZlcnRlciBmYWlsZWQgdG8gbG9hZC4iKSk7CiAgICAgIHNjcmlwdC5vbmVycm9yID0gKCkgPT4gcmVqZWN0KG5ldyBFcnJvcigiV2UgY291bGQgbm90IGxvYWQgQXBwbGUgcGhvdG8gY29udmVyc2lvbiBvbiB0aGlzIGRldmljZS4iKSk7CiAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KTsKICAgIH0pOwogIH0KICBmdW5jdGlvbiByZW5kZXJQaG90b3MoKSB7CiAgICBlbHMucGhvdG9HcmlkLmlubmVySFRNTCA9ICIiOwogICAgc3RhdGUucGhvdG9zLmZvckVhY2goKHBob3RvLCBpbmRleCkgPT4gewogICAgICBjb25zdCBjYXJkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYXJ0aWNsZSIpOwogICAgICBjYXJkLmNsYXNzTmFtZSA9ICJwaG90by1jYXJkIjsKICAgICAgY2FyZC5pbm5lckhUTUwgPSBgPGltZyBhbHQ9IlNlbGVjdGVkIHRydWNrIHBob3RvICR7aW5kZXggKyAxfSIgc3JjPSIke3Bob3RvLmRhdGFVcmx9Ij48YnV0dG9uIHR5cGU9ImJ1dHRvbiIgYXJpYS1sYWJlbD0iUmVtb3ZlIHBob3RvICR7aW5kZXggKyAxfSI+UmVtb3ZlPC9idXR0b24+PHA+JHtwaG90by5vcmlnaW5hbEZpbGVOYW1lfTxicj4ke2Zvcm1hdEJ5dGVzKHBob3RvLnByb2Nlc3NlZFNpemVCeXRlcyl9PC9wPmA7CiAgICAgIGNhcmQucXVlcnlTZWxlY3RvcigiYnV0dG9uIikuYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCAoKSA9PiB7CiAgICAgICAgc3RhdGUucGhvdG9zLnNwbGljZShpbmRleCwgMSk7CiAgICAgICAgcmVuZGVyUGhvdG9zKCk7CiAgICAgICAgc2V0UGhvdG9TdGF0dXMoYCR7c3RhdGUucGhvdG9zLmxlbmd0aH0gcGhvdG8ocykgcmVhZHkuYCk7CiAgICAgIH0pOwogICAgICBlbHMucGhvdG9HcmlkLmFwcGVuZENoaWxkKGNhcmQpOwogICAgfSk7CiAgfQogIGFzeW5jIGZ1bmN0aW9uIG9uU3VibWl0KGV2ZW50KSB7CiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgY2xlYXJTdGF0dXMoKTsKICAgIGlmICghdmFsaWRhdGVGb3JtKCkpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgc2V0QnVzeSh0cnVlLCAiUHJlcGFyaW5nIHN1Ym1pc3Npb24uLi4iKTsKICAgIHRyeSB7CiAgICAgIGNvbnN0IHBheWxvYWQgPSBhd2FpdCBidWlsZFBheWxvYWQoKTsKICAgICAgc2V0QnVzeSh0cnVlLCAiU3VibWl0dGluZyByZXF1ZXN0Li4uIik7CiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN1Ym1pdFBheWxvYWQocGF5bG9hZCk7CiAgICAgIHNob3dUaGFua1lvdShwYXlsb2FkLCByZXN1bHQpOwogICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgc2V0U3VibWl0U3RhdHVzKGVycm9yLm1lc3NhZ2UgfHwgIldlIGNvdWxkIG5vdCBzdWJtaXQgeW91ciByZXF1ZXN0LiBQbGVhc2UgdHJ5IGFnYWluLiIpOwogICAgICBzZXRCdXN5KGZhbHNlKTsKICAgICAgcmVzZXRUdXJuc3RpbGUoKTsKICAgIH0KICB9CiAgZnVuY3Rpb24gdmFsaWRhdGVGb3JtKCkgewogICAgaWYgKCFmb3JtLnJlcG9ydFZhbGlkaXR5KCkpIHsKICAgICAgc2V0U3VibWl0U3RhdHVzKCJQbGVhc2UgY29tcGxldGUgdGhlIHJlcXVpcmVkIGZpZWxkcy4iKTsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKENPTkZJRy50dXJuc3RpbGVTaXRlS2V5ICYmICFzdGF0ZS50dXJuc3RpbGVUb2tlbikgewogICAgICBzZXRTdWJtaXRTdGF0dXMoIlBsZWFzZSBjb21wbGV0ZSB2ZXJpZmljYXRpb24gYmVmb3JlIHN1Ym1pdHRpbmcuIik7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIHJldHVybiB0cnVlOwogIH0KICBhc3luYyBmdW5jdGlvbiBidWlsZFBheWxvYWQoKSB7CiAgICBjb25zdCBsb2NhdGlvbiA9IHNlbGVjdGVkTG9jYXRpb24oKTsKICAgIGNvbnN0IHN1Ym1pc3Npb25JZCA9IGdlbmVyYXRlU3VibWlzc2lvbklkKCk7CiAgICBjb25zdCBjdXN0b21lciA9IHsKICAgICAgZmlyc3ROYW1lOiB2YWx1ZSgiZmlyc3ROYW1lIiksCiAgICAgIGxhc3ROYW1lOiB2YWx1ZSgibGFzdE5hbWUiKSwKICAgICAgY29tcGFueU5hbWU6IHZhbHVlKCJjb21wYW55TmFtZSIpLAogICAgICBwaG9uZTogdmFsdWUoInBob25lIiksCiAgICAgIGVtYWlsOiB2YWx1ZSgiZW1haWwiKSwKICAgICAgcHJlZmVycmVkQ29udGFjdE1ldGhvZDogdmFsdWUoInByZWZlcnJlZENvbnRhY3RNZXRob2QiKSwKICAgICAgcHJlZmVycmVkQ29udGFjdFRpbWU6IHZhbHVlKCJwcmVmZXJyZWRDb250YWN0VGltZSIpCiAgICB9OwogICAgY29uc3QgdmVoaWNsZSA9IHsKICAgICAgeWVhcjogdmFsdWUoInllYXIiKSwKICAgICAgbWFrZTogdmFsdWUoIm1ha2UiKSwKICAgICAgbW9kZWw6IHZhbHVlKCJtb2RlbCIpLAogICAgICB2aW46IHZhbHVlKCJ2aW4iKSwKICAgICAgbWlsZWFnZTogdmFsdWUoIm1pbGVhZ2UiKSwKICAgICAgdHJ1Y2tUeXBlOiB2YWx1ZSgidHJ1Y2tUeXBlIiksCiAgICAgIGJvZHlUeXBlOiB2YWx1ZSgiYm9keVR5cGUiKQogICAgfTsKICAgIGNvbnN0IGltYWdlcyA9IHN0YXRlLnBob3Rvcy5tYXAoKHBob3RvLCBpbmRleCkgPT4gKHsKICAgICAgaW5kZXgsCiAgICAgIGZpbGVOYW1lOiBpbWFnZUZpbGVuYW1lKHZlaGljbGUsIGluZGV4KSwKICAgICAgY29udGVudFR5cGU6ICJpbWFnZS9qcGVnIiwKICAgICAgY29udGVudEJhc2U2NDogcGhvdG8uY29udGVudEJhc2U2NCwKICAgICAgb3JpZ2luYWxGaWxlTmFtZTogcGhvdG8ub3JpZ2luYWxGaWxlTmFtZSwKICAgICAgb3JpZ2luYWxUeXBlOiBwaG90by5vcmlnaW5hbFR5cGUsCiAgICAgIHdhc0NvbnZlcnRlZEZyb21IZWljOiBwaG90by53YXNDb252ZXJ0ZWRGcm9tSGVpYywKICAgICAgcHJvY2Vzc2VkU2l6ZUJ5dGVzOiBwaG90by5wcm9jZXNzZWRTaXplQnl0ZXMKICAgIH0pKTsKICAgIGNvbnN0IHBheWxvYWQgPSB7CiAgICAgIHR1cm5zdGlsZVRva2VuOiB0dXJuc3RpbGVUb2tlbkZvclBheWxvYWQoKSwKICAgICAgc3VibWlzc2lvbklkLAogICAgICBzdWJtaXNzaW9uU291cmNlOiB2YWx1ZSgic3VibWlzc2lvblNvdXJjZSIpLAogICAgICBzdWJtaXR0ZWRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLAogICAgICBjdXN0b21lciwKICAgICAgdmVoaWNsZSwKICAgICAgdHJhZGVJbnRlbnQ6IHsKICAgICAgICBwdXJjaGFzZUludGVyZXN0OiB2YWx1ZSgicHVyY2hhc2VJbnRlcmVzdCIpLAogICAgICAgIG5lYXJlc3RMb2NhdGlvbjogbG9jYXRpb24uZGlzcGxheSwKICAgICAgICByZWdpb246IGxvY2F0aW9uLnJlZ2lvbiwKICAgICAgICB0aW1lZnJhbWU6IHZhbHVlKCJ0aW1lZnJhbWUiKSwKICAgICAgICBuZXh0VHJ1Y2tOb3RlczogdmFsdWUoIm5leHRUcnVja05vdGVzIikKICAgICAgfSwKICAgICAgY29uZGl0aW9uOiB7CiAgICAgICAgY29uZGl0aW9uUmF0aW5nOiB2YWx1ZSgiY29uZGl0aW9uUmF0aW5nIiksCiAgICAgICAgdGl0bGVTdGF0dXM6IHZhbHVlKCJ0aXRsZVN0YXR1cyIpLAogICAgICAgIHBheW9mZlN0YXR1czogdmFsdWUoInBheW9mZlN0YXR1cyIpLAogICAgICAgIGVzdGltYXRlZFBheW9mZjogdmFsdWUoImVzdGltYXRlZFBheW9mZiIpLAogICAgICAgIGtub3duSXNzdWVzOiB2YWx1ZSgia25vd25Jc3N1ZXMiKSwKICAgICAgICB3YXJuaW5nTGlnaHRzOiB2YWx1ZSgid2FybmluZ0xpZ2h0cyIpLAogICAgICAgIGRhbWFnZUhpc3Rvcnk6IHZhbHVlKCJkYW1hZ2VIaXN0b3J5IiksCiAgICAgICAgcmVjZW50UmVwYWlyczogdmFsdWUoInJlY2VudFJlcGFpcnMiKSwKICAgICAgICBnZW5lcmFsTm90ZXM6IHZhbHVlKCJnZW5lcmFsTm90ZXMiKQogICAgICB9LAogICAgICBpbWFnZXMsCiAgICAgIHBkZjoge30sCiAgICAgIHRyYWNraW5nOiB7CiAgICAgICAgdXRtU291cmNlOiBxdWVyeSgidXRtX3NvdXJjZSIpLAogICAgICAgIHV0bU1lZGl1bTogcXVlcnkoInV0bV9tZWRpdW0iKSwKICAgICAgICB1dG1DYW1wYWlnbjogcXVlcnkoInV0bV9jYW1wYWlnbiIpLAogICAgICAgIHV0bUNvbnRlbnQ6IHF1ZXJ5KCJ1dG1fY29udGVudCIpLAogICAgICAgIHV0bVRlcm06IHF1ZXJ5KCJ1dG1fdGVybSIpLAogICAgICAgIGxhbmRpbmdQYWdlOiBsb2NhdGlvbkhyZWZXaXRob3V0U2VjcmV0cygpLAogICAgICAgIHVzZXJBZ2VudDogbmF2aWdhdG9yLnVzZXJBZ2VudAogICAgICB9CiAgICB9OwogICAgcGF5bG9hZC5wZGYgPSB7CiAgICAgIGZpbGVOYW1lOiBwZGZGaWxlbmFtZShjdXN0b21lciwgdmVoaWNsZSksCiAgICAgIGNvbnRlbnRCYXNlNjQ6IGF3YWl0IHJlbmRlclN1bW1hcnlQZGZCYXNlNjQocGF5bG9hZCkKICAgIH07CiAgICByZXR1cm4gcGF5bG9hZDsKICB9CiAgYXN5bmMgZnVuY3Rpb24gc3VibWl0UGF5bG9hZChwYXlsb2FkKSB7CiAgICBjb25zdCB1cmwgPSBDT05GSUcucGFUcmlnZ2VyVXJsOwogICAgY29uc3QgYm9keSA9IEpTT04uc3RyaW5naWZ5KHBheWxvYWQpOwogICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIHsgbWV0aG9kOiAiUE9TVCIsIGhlYWRlcnM6IHsgIkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIiB9LCBib2R5IH0pOwogICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTsKICAgIGlmICghcmVzcG9uc2Uub2spIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBQb3dlciBBdXRvbWF0ZSByZXR1cm5lZCBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfS4gJHt0ZXh0LnNsaWNlKDAsIDI0MCl9YCk7CiAgICB9CiAgICBpZiAoIXRleHQpIHsKICAgICAgcmV0dXJuIHsgb2s6IHRydWUgfTsKICAgIH0KICAgIHRyeSB7CiAgICAgIHJldHVybiBKU09OLnBhcnNlKHRleHQpOwogICAgfSBjYXRjaCB7CiAgICAgIHJldHVybiB7IG9rOiB0cnVlLCByYXc6IHRleHQgfTsKICAgIH0KICB9CiAgYXN5bmMgZnVuY3Rpb24gcmVuZGVyU3VtbWFyeVBkZkJhc2U2NChwYXlsb2FkKSB7CiAgICBjb25zdCBwZGYgPSBuZXcgU2ltcGxlUGRmKCk7CiAgICBjb25zdCBjdXN0b21lciA9IHBheWxvYWQuY3VzdG9tZXI7CiAgICBjb25zdCB2ZWhpY2xlID0gcGF5bG9hZC52ZWhpY2xlOwogICAgY29uc3QgdHJhZGUgPSBwYXlsb2FkLnRyYWRlSW50ZW50OwogICAgY29uc3QgY29uZGl0aW9uID0gcGF5bG9hZC5jb25kaXRpb247CiAgICBwZGYudGV4dCgzNiwgNzQ4LCAiQWxsIFJvYWRzIFRyYWRlLUluIFN1bW1hcnkiLCAxNiwgdHJ1ZSk7CiAgICBwZGYudGV4dCgzNiwgNzI0LCBgJHtwYXlsb2FkLnN1Ym1pc3Npb25Tb3VyY2UgPT09ICJBUksiID8gIkFsbCBSb2FkcyBLZW53b3J0aCIgOiAiQWxsIFJvYWRzIFRydWNrcyJ9IHwgJHtuZXcgRGF0ZShwYXlsb2FkLnN1Ym1pdHRlZEF0KS50b0xvY2FsZVN0cmluZygpfWAsIDksIGZhbHNlKTsKICAgIHBkZi5saW5lKDM2LCA3MDgsIDU3NiwgNzA4KTsKICAgIHBkZi5zZWN0aW9uKDM2LCA2ODQsICJDdXN0b21lciIpOwogICAgcGRmLmZpZWxkKDM2LCA2NTcsICJOYW1lIiwgYCR7Y3VzdG9tZXIuZmlyc3ROYW1lfSAke2N1c3RvbWVyLmxhc3ROYW1lfWApOwogICAgcGRmLmZpZWxkKDIxNCwgNjU3LCAiQ29tcGFueSIsIGN1c3RvbWVyLmNvbXBhbnlOYW1lIHx8ICItIik7CiAgICBwZGYuZmllbGQoMzkyLCA2NTcsICJQcmVmZXJyZWQgY29udGFjdCIsIGN1c3RvbWVyLnByZWZlcnJlZENvbnRhY3RNZXRob2QpOwogICAgcGRmLmZpZWxkKDM2LCA2MTUsICJQaG9uZSIsIGN1c3RvbWVyLnBob25lKTsKICAgIHBkZi5maWVsZCgyMTQsIDYxNSwgIkVtYWlsIiwgY3VzdG9tZXIuZW1haWwpOwogICAgcGRmLmZpZWxkKDM5MiwgNjE1LCAiQmVzdCB0aW1lIiwgY3VzdG9tZXIucHJlZmVycmVkQ29udGFjdFRpbWUpOwogICAgcGRmLnNlY3Rpb24oMzYsIDU3NCwgIlZlaGljbGUiKTsKICAgIHBkZi5maWVsZCgzNiwgNTQ3LCAiVmVoaWNsZSIsIGAke3ZlaGljbGUueWVhcn0gJHt2ZWhpY2xlLm1ha2V9ICR7dmVoaWNsZS5tb2RlbH1gKTsKICAgIHBkZi5maWVsZCgyMTQsIDU0NywgIlZJTiIsIHZlaGljbGUudmluIHx8ICItIik7CiAgICBwZGYuZmllbGQoMzkyLCA1NDcsICJNaWxlYWdlIiwgdmVoaWNsZS5taWxlYWdlIHx8ICItIik7CiAgICBwZGYuZmllbGQoMzYsIDUwNSwgIlRydWNrIHR5cGUiLCB2ZWhpY2xlLnRydWNrVHlwZSB8fCAiLSIpOwogICAgcGRmLmZpZWxkKDIxNCwgNTA1LCAiQm9keSB0eXBlIiwgdmVoaWNsZS5ib2R5VHlwZSB8fCAiLSIpOwogICAgcGRmLnNlY3Rpb24oMzYsIDQ2NCwgIlRyYWRlIHBsYW4iKTsKICAgIHBkZi5maWVsZCgzNiwgNDM3LCAiUmVnaW9uIiwgdHJhZGUucmVnaW9uKTsKICAgIHBkZi5maWVsZCgxNjgsIDQzNywgIkxvY2F0aW9uIiwgdHJhZGUubmVhcmVzdExvY2F0aW9uKTsKICAgIHBkZi5maWVsZCgzMjYsIDQzNywgIkludGVyZXN0IiwgdHJhZGUucHVyY2hhc2VJbnRlcmVzdCk7CiAgICBwZGYuZmllbGQoNDY4LCA0MzcsICJUaW1lZnJhbWUiLCB0cmFkZS50aW1lZnJhbWUpOwogICAgcGRmLnNlY3Rpb24oMzYsIDM5NiwgIkNvbmRpdGlvbiIpOwogICAgcGRmLmZpZWxkKDM2LCAzNjksICJSYXRpbmciLCBjb25kaXRpb24uY29uZGl0aW9uUmF0aW5nKTsKICAgIHBkZi5maWVsZCgxNjgsIDM2OSwgIlRpdGxlIiwgY29uZGl0aW9uLnRpdGxlU3RhdHVzIHx8ICItIik7CiAgICBwZGYuZmllbGQoMzI2LCAzNjksICJQYXlvZmYiLCBjb25kaXRpb24ucGF5b2ZmU3RhdHVzKTsKICAgIHBkZi5maWVsZCg0NjgsIDM2OSwgIkVzdC4gcGF5b2ZmIiwgY29uZGl0aW9uLmVzdGltYXRlZFBheW9mZiB8fCAiLSIpOwogICAgcGRmLnNlY3Rpb24oMzYsIDMzOCwgIk1hbmFnZXIgbm90ZXMiKTsKICAgIGNvbnN0IG5vdGVUZXh0ID0gWwogICAgICBbIk5leHQgdHJ1Y2siLCB0cmFkZS5uZXh0VHJ1Y2tOb3Rlc10sCiAgICAgIFsiS25vd24gaXNzdWVzIiwgY29uZGl0aW9uLmtub3duSXNzdWVzXSwKICAgICAgWyJXYXJuaW5nIGxpZ2h0cyIsIGNvbmRpdGlvbi53YXJuaW5nTGlnaHRzXSwKICAgICAgWyJEYW1hZ2UiLCBjb25kaXRpb24uZGFtYWdlSGlzdG9yeV0sCiAgICAgIFsiUmVjZW50IHJlcGFpcnMiLCBjb25kaXRpb24ucmVjZW50UmVwYWlyc10sCiAgICAgIFsiR2VuZXJhbCBub3RlcyIsIGNvbmRpdGlvbi5nZW5lcmFsTm90ZXNdCiAgICBdLmZpbHRlcigoZW50cnkpID0+IGVudHJ5WzFdKS5tYXAoKGVudHJ5KSA9PiBgJHtlbnRyeVswXX06ICR7ZW50cnlbMV19YCkuam9pbigiIHwgIik7CiAgICBwZGYud3JhcCgzNiwgMzE2LCBub3RlVGV4dCB8fCAiTm8gbm90ZXMgc3VwcGxpZWQuIiwgMTA2LCAxMiwgOCk7CiAgICBjb25zdCBub3Rlc0xvbmcgPSBub3RlVGV4dC5sZW5ndGggPiA5MDA7CiAgICBpZiAocGF5bG9hZC5pbWFnZXMubGVuZ3RoICYmICFub3Rlc0xvbmcpIHsKICAgICAgcGRmLnNlY3Rpb24oMzYsIDE0MiwgIlBob3RvIHNhbXBsZXMiKTsKICAgICAgY29uc3QgdGh1bWJzID0gc3RhdGUucGhvdG9zLnNsaWNlKDAsIDYpOwogICAgICB0aHVtYnMuZm9yRWFjaCgocGhvdG8sIGluZGV4KSA9PiB7CiAgICAgICAgY29uc3QgY29sID0gaW5kZXggJSAzOwogICAgICAgIGNvbnN0IHJvdyA9IE1hdGguZmxvb3IoaW5kZXggLyAzKTsKICAgICAgICBwZGYuaW1hZ2UocGhvdG8sIDM2ICsgY29sICogOTIsIHJvdyA9PT0gMCA/IDc2IDogMTgsIDgyLCA1MCk7CiAgICAgICAgcGRmLnRleHQoMzYgKyBjb2wgKiA5MiwgKHJvdyA9PT0gMCA/IDc2IDogMTgpIC0gMTAsIGBQaG90byAke2luZGV4ICsgMX1gLCA3LCBmYWxzZSk7CiAgICAgIH0pOwogICAgfSBlbHNlIHsKICAgICAgcGRmLnNlY3Rpb24oMzYsIDEwNCwgIlBob3RvcyIpOwogICAgICBwZGYud3JhcCgzNiwgODIsIHBheWxvYWQuaW1hZ2VzLmxlbmd0aCA/IGAke3BheWxvYWQuaW1hZ2VzLmxlbmd0aH0gcGhvdG8ocykgdXBsb2FkZWQuIFRodW1ibmFpbHMgb21pdHRlZCB0byBrZWVwIG5vdGVzIG9uIG9uZSBwYWdlLmAgOiAiTm8gcGhvdG9zIHdlcmUgYXR0YWNoZWQgdG8gdGhpcyBzdWJtaXNzaW9uLiIsIDk2LCAzLCA4KTsKICAgIH0KICAgIHJldHVybiBwZGYuYmFzZTY0KCk7CiAgfQogIGNsYXNzIFNpbXBsZVBkZiB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgdGhpcy5jb21tYW5kcyA9IFtdOwogICAgICB0aGlzLmltYWdlcyA9IFtdOwogICAgfQogICAgdGV4dCh4LCB5LCB0ZXh0LCBzaXplLCBib2xkKSB7CiAgICAgIHRoaXMuY29tbWFuZHMucHVzaChgQlQgLyR7Ym9sZCA/ICJGMiIgOiAiRjEifSAke3NpemV9IFRmICR7eC50b0ZpeGVkKDIpfSAke3kudG9GaXhlZCgyKX0gVGQgKCR7ZXNjYXBlUGRmVGV4dCh0ZXh0KX0pIFRqIEVUYCk7CiAgICB9CiAgICB3cmFwKHgsIHksIHRleHQsIHdpZHRoLCBtYXhMaW5lcywgc2l6ZSkgewogICAgICBjb25zdCBsaW5lcyA9IHdyYXBUZXh0KHRleHQsIHdpZHRoLCBtYXhMaW5lcyk7CiAgICAgIGxpbmVzLmZvckVhY2goKGxpbmUsIGluZGV4KSA9PiB0aGlzLnRleHQoeCwgeSAtIGluZGV4ICogKHNpemUgKyAzKSwgbGluZSwgc2l6ZSwgZmFsc2UpKTsKICAgIH0KICAgIGZpZWxkKHgsIHksIGxhYmVsLCB2YWx1ZSkgewogICAgICB0aGlzLnRleHQoeCwgeSArIDEwLCBsYWJlbC50b1VwcGVyQ2FzZSgpLCA3LCB0cnVlKTsKICAgICAgdGhpcy53cmFwKHgsIHksIHZhbHVlIHx8ICItIiwgMzQsIDIsIDgpOwogICAgfQogICAgc2VjdGlvbih4LCB5LCB0ZXh0KSB7CiAgICAgIHRoaXMudGV4dCh4LCB5LCB0ZXh0LnRvVXBwZXJDYXNlKCksIDksIHRydWUpOwogICAgICB0aGlzLmxpbmUoeCwgeSAtIDQsIDU3NiwgeSAtIDQpOwogICAgfQogICAgbGluZSh4MSwgeTEsIHgyLCB5MikgewogICAgICB0aGlzLmNvbW1hbmRzLnB1c2goYDAuNzAgRyAke3gxLnRvRml4ZWQoMil9ICR7eTEudG9GaXhlZCgyKX0gbSAke3gyLnRvRml4ZWQoMil9ICR7eTIudG9GaXhlZCgyKX0gbCBTIDAgR2ApOwogICAgfQogICAgaW1hZ2UocGhvdG8sIHgsIHksIHdpZHRoLCBoZWlnaHQpIHsKICAgICAgY29uc3QgbmFtZSA9IGBJbSR7dGhpcy5pbWFnZXMubGVuZ3RofWA7CiAgICAgIHRoaXMuaW1hZ2VzLnB1c2goeyBuYW1lLCBiYXNlNjQ6IHBob3RvLmNvbnRlbnRCYXNlNjQsIHdpZHRoOiBwaG90by53aWR0aCwgaGVpZ2h0OiBwaG90by5oZWlnaHQgfSk7CiAgICAgIGNvbnN0IHNjYWxlID0gTWF0aC5tYXgod2lkdGggLyBwaG90by53aWR0aCwgaGVpZ2h0IC8gcGhvdG8uaGVpZ2h0KTsKICAgICAgY29uc3QgZHJhd1dpZHRoID0gcGhvdG8ud2lkdGggKiBzY2FsZTsKICAgICAgY29uc3QgZHJhd0hlaWdodCA9IHBob3RvLmhlaWdodCAqIHNjYWxlOwogICAgICBjb25zdCBkeCA9ICh3aWR0aCAtIGRyYXdXaWR0aCkgLyAyOwogICAgICBjb25zdCBkeSA9IChoZWlnaHQgLSBkcmF3SGVpZ2h0KSAvIDI7CiAgICAgIHRoaXMuY29tbWFuZHMucHVzaChgMC45MyBnICR7eC50b0ZpeGVkKDIpfSAke3kudG9GaXhlZCgyKX0gJHt3aWR0aC50b0ZpeGVkKDIpfSAke2hlaWdodC50b0ZpeGVkKDIpfSByZSBmIDAgZ2ApOwogICAgICB0aGlzLmNvbW1hbmRzLnB1c2goYHEgJHt4LnRvRml4ZWQoMil9ICR7eS50b0ZpeGVkKDIpfSAke3dpZHRoLnRvRml4ZWQoMil9ICR7aGVpZ2h0LnRvRml4ZWQoMil9IHJlIFcgbiAke2RyYXdXaWR0aC50b0ZpeGVkKDIpfSAwIDAgJHtkcmF3SGVpZ2h0LnRvRml4ZWQoMil9ICR7KHggKyBkeCkudG9GaXhlZCgyKX0gJHsoeSArIGR5KS50b0ZpeGVkKDIpfSBjbSAvJHtuYW1lfSBEbyBRYCk7CiAgICAgIHRoaXMuY29tbWFuZHMucHVzaChgMC43OCBHICR7eC50b0ZpeGVkKDIpfSAke3kudG9GaXhlZCgyKX0gJHt3aWR0aC50b0ZpeGVkKDIpfSAke2hlaWdodC50b0ZpeGVkKDIpfSByZSBTIDAgR2ApOwogICAgfQogICAgYmFzZTY0KCkgewogICAgICBjb25zdCBieXRlcyA9IHNlcmlhbGl6ZVBkZih0aGlzLmNvbW1hbmRzLmpvaW4oIlxuIiksIHRoaXMuaW1hZ2VzKTsKICAgICAgcmV0dXJuIGJ5dGVzVG9CYXNlNjQoYnl0ZXMpOwogICAgfQogIH0KICBmdW5jdGlvbiBzZXJpYWxpemVQZGYoY29udGVudCwgaW1hZ2VzKSB7CiAgICBjb25zdCBpbWFnZVN0YXJ0ID0gNzsKICAgIGNvbnN0IHhvYmplY3RzID0gaW1hZ2VzLm1hcCgoaW1hZ2UsIGluZGV4KSA9PiBgLyR7aW1hZ2UubmFtZX0gJHtpbWFnZVN0YXJ0ICsgaW5kZXh9IDAgUmApLmpvaW4oIiAiKTsKICAgIGNvbnN0IHJlc291cmNlcyA9IGAvRm9udCA8PCAvRjEgNCAwIFIgL0YyIDUgMCBSID4+ICR7eG9iamVjdHMgPyBgL1hPYmplY3QgPDwgJHt4b2JqZWN0c30gPj5gIDogIiJ9YDsKICAgIGNvbnN0IG9iamVjdHMgPSBbCiAgICAgICI8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4iLAogICAgICAiPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4iLAogICAgICBgPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA2MTIgNzkyXSAvUmVzb3VyY2VzIDw8ICR7cmVzb3VyY2VzfSA+PiAvQ29udGVudHMgNiAwIFIgPj5gLAogICAgICAiPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhID4+IiwKICAgICAgIjw8IC9UeXBlIC9Gb250IC9TdWJ0eXBlIC9UeXBlMSAvQmFzZUZvbnQgL0hlbHZldGljYS1Cb2xkID4+IiwKICAgICAgc3RyZWFtT2JqZWN0KHN0cmluZ1RvQnl0ZXMoY29udGVudCkpCiAgICBdOwogICAgaW1hZ2VzLmZvckVhY2goKGltYWdlKSA9PiB7CiAgICAgIGNvbnN0IGRhdGEgPSBiYXNlNjRUb0J5dGVzKGltYWdlLmJhc2U2NCk7CiAgICAgIG9iamVjdHMucHVzaChgPDwgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCAke2ltYWdlLndpZHRofSAvSGVpZ2h0ICR7aW1hZ2UuaGVpZ2h0fSAvQ29sb3JTcGFjZSAvRGV2aWNlUkdCIC9CaXRzUGVyQ29tcG9uZW50IDggL0ZpbHRlciAvRENURGVjb2RlIC9MZW5ndGggJHtkYXRhLmxlbmd0aH0gPj5cbnN0cmVhbVxuJHtieXRlc1RvQmluYXJ5KGRhdGEpfVxuZW5kc3RyZWFtYCk7CiAgICB9KTsKICAgIHJldHVybiB3cml0ZVBkZihvYmplY3RzKTsKICB9CiAgZnVuY3Rpb24gc3RyZWFtT2JqZWN0KGJ5dGVzKSB7CiAgICByZXR1cm4gYDw8IC9MZW5ndGggJHtieXRlcy5sZW5ndGh9ID4+XG5zdHJlYW1cbiR7Ynl0ZXNUb0JpbmFyeShieXRlcyl9XG5lbmRzdHJlYW1gOwogIH0KICBmdW5jdGlvbiB3cml0ZVBkZihvYmplY3RzKSB7CiAgICBsZXQgb3V0cHV0ID0gIiVQREYtMS40XG4lw6LDo8OPw5NcbiI7CiAgICBjb25zdCBvZmZzZXRzID0gWzBdOwogICAgb2JqZWN0cy5mb3JFYWNoKChvYmplY3QsIGluZGV4KSA9PiB7CiAgICAgIG9mZnNldHMucHVzaChiaW5hcnlMZW5ndGgob3V0cHV0KSk7CiAgICAgIG91dHB1dCArPSBgJHtpbmRleCArIDF9IDAgb2JqXG4ke29iamVjdH1cbmVuZG9ialxuYDsKICAgIH0pOwogICAgY29uc3QgeHJlZk9mZnNldCA9IGJpbmFyeUxlbmd0aChvdXRwdXQpOwogICAgb3V0cHV0ICs9IGB4cmVmXG4wICR7b2JqZWN0cy5sZW5ndGggKyAxfVxuMDAwMDAwMDAwMCA2NTUzNSBmIFxuYDsKICAgIG9mZnNldHMuc2xpY2UoMSkuZm9yRWFjaCgob2Zmc2V0KSA9PiB7CiAgICAgIG91dHB1dCArPSBgJHtTdHJpbmcob2Zmc2V0KS5wYWRTdGFydCgxMCwgIjAiKX0gMDAwMDAgbiBcbmA7CiAgICB9KTsKICAgIG91dHB1dCArPSBgdHJhaWxlclxuPDwgL1NpemUgJHtvYmplY3RzLmxlbmd0aCArIDF9IC9Sb290IDEgMCBSID4+XG5zdGFydHhyZWZcbiR7eHJlZk9mZnNldH1cbiUlRU9GXG5gOwogICAgcmV0dXJuIHN0cmluZ1RvQnl0ZXMob3V0cHV0KTsKICB9CiAgZnVuY3Rpb24gc2hvd1RoYW5rWW91KHBheWxvYWQsIHJlc3VsdCkgewogICAgY29uc3QgcmVmZXJlbmNlID0gcGF5bG9hZC5zdWJtaXNzaW9uSWQuc2xpY2UoMCwgNCk7CiAgICBjb25zdCBsb2NhdGlvbiA9IHNlbGVjdGVkTG9jYXRpb24oKTsKICAgIGVscy5jb3B5UmVmZXJlbmNlLnRleHRDb250ZW50ID0gcmVmZXJlbmNlOwogICAgZWxzLmNvcHlSZWZlcmVuY2Uub25jbGljayA9ICgpID0+IG5hdmlnYXRvci5jbGlwYm9hcmQgJiYgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQocmVmZXJlbmNlKTsKICAgIGVscy50aGFua1N1bW1hcnkudGV4dENvbnRlbnQgPSBgJHtwYXlsb2FkLmltYWdlcy5sZW5ndGh9IHBob3RvKHMpIHN1Ym1pdHRlZCBmb3IgeW91ciAke3BheWxvYWQudmVoaWNsZS55ZWFyfSAke3BheWxvYWQudmVoaWNsZS5tYWtlfSAke3BheWxvYWQudmVoaWNsZS5tb2RlbH0gYXQgb3VyICR7cGF5bG9hZC50cmFkZUludGVudC5uZWFyZXN0TG9jYXRpb259IGxvY2F0aW9uLmA7CiAgICBlbHMudGhhbmtQaG9uZS50ZXh0Q29udGVudCA9IGBIYXZlIHF1ZXN0aW9ucyBpbiB0aGUgbWVhbnRpbWU/IENhbGwgb3VyICR7cGF5bG9hZC50cmFkZUludGVudC5uZWFyZXN0TG9jYXRpb259IHNhbGVzIHRlYW0gYXQgJHtsb2NhdGlvbi5waG9uZX0uYDsKICAgIGVscy50aGFua0FkZHJlc3MudGV4dENvbnRlbnQgPSBgJHtsb2NhdGlvbi5hZGRyZXNzfSDCtyBgOwogICAgY29uc3QgZGlyZWN0aW9uc0xpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7CiAgICBkaXJlY3Rpb25zTGluay5ocmVmID0gYGh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vbWFwcy9zZWFyY2gvP2FwaT0xJnF1ZXJ5PSR7ZW5jb2RlVVJJQ29tcG9uZW50KGxvY2F0aW9uLmFkZHJlc3MpfWA7CiAgICBkaXJlY3Rpb25zTGluay50YXJnZXQgPSAiX2JsYW5rIjsKICAgIGRpcmVjdGlvbnNMaW5rLnJlbCA9ICJub29wZW5lciI7CiAgICBkaXJlY3Rpb25zTGluay50ZXh0Q29udGVudCA9ICJHZXQgZGlyZWN0aW9ucyI7CiAgICBlbHMudGhhbmtBZGRyZXNzLmFwcGVuZENoaWxkKGRpcmVjdGlvbnNMaW5rKTsKICAgIGlmIChyZXN1bHQgJiYgcmVzdWx0LnBlbmRpbmcpIHsKICAgICAgZWxzLnRoYW5rU3VtbWFyeS50ZXh0Q29udGVudCArPSAiIFlvdXIgcmVxdWVzdCB3YXMgc2VudCBhbmQgbWF5IHN0aWxsIGJlIHByb2Nlc3NpbmcuIjsKICAgIH0KICAgIHN0YXRlLnN1Ym1pdHRlZCA9IHRydWU7CiAgICBoaXN0b3J5LnB1c2hTdGF0ZSh7IHRyYWRlSW5Eb25lOiB0cnVlIH0sICIiLCAiI3RoYW5rLXlvdSIpOwogICAgYXBwbHlUaGFua1lvdVZpZXcodHJ1ZSk7CiAgICBmb2N1c1RoYW5rWW91KCk7CiAgICB3aW5kb3cuc2Nyb2xsVG8oeyB0b3A6IDAsIGJlaGF2aW9yOiAic21vb3RoIiB9KTsKICB9CiAgZnVuY3Rpb24gZm9jdXNUaGFua1lvdSgpIHsKICAgIGNvbnN0IGhlYWRpbmcgPSBlbHMudGhhbmtZb3UucXVlcnlTZWxlY3RvcigiaDEiKTsKICAgIGlmIChoZWFkaW5nKSB7CiAgICAgIGhlYWRpbmcuc2V0QXR0cmlidXRlKCJ0YWJpbmRleCIsICItMSIpOwogICAgICBoZWFkaW5nLmZvY3VzKHsgcHJldmVudFNjcm9sbDogdHJ1ZSB9KTsKICAgIH0KICB9CiAgZnVuY3Rpb24gc2VsZWN0ZWRMb2NhdGlvbigpIHsKICAgIHJldHVybiBMT0NBVElPTlMuZmluZCgobG9jYXRpb24pID0+IGxvY2F0aW9uLnNsdWcgPT09IHZhbHVlKCJuZWFyZXN0TG9jYXRpb24iKSkgfHwgTE9DQVRJT05TWzBdOwogIH0KICBmdW5jdGlvbiB0dXJuc3RpbGVUb2tlbkZvclBheWxvYWQoKSB7CiAgICByZXR1cm4gc3RhdGUudHVybnN0aWxlVG9rZW4gfHwgIiI7CiAgfQogIGZ1bmN0aW9uIHZhbHVlKG5hbWUpIHsKICAgIHJldHVybiBTdHJpbmcoZm9ybS5lbGVtZW50c1tuYW1lXT8udmFsdWUgfHwgIiIpLnRyaW0oKTsKICB9CiAgZnVuY3Rpb24gZ2VuZXJhdGVTdWJtaXNzaW9uSWQoKSB7CiAgICBjb25zdCBhbHBoYWJldCA9ICJBQkNERUZHSEpLTE1OUFFSU1RVVldYWVoyMzQ1Njc4OSI7CiAgICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KDEwKTsKICAgIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMoYnl0ZXMpOwogICAgcmV0dXJuIEFycmF5LmZyb20oYnl0ZXMsIChieXRlKSA9PiBhbHBoYWJldFtieXRlICUgYWxwaGFiZXQubGVuZ3RoXSkuam9pbigiIik7CiAgfQogIGZ1bmN0aW9uIGltYWdlRmlsZW5hbWUodmVoaWNsZSwgaW5kZXgpIHsKICAgIHJldHVybiBgJHtzbHVnKGAke3ZlaGljbGUueWVhcn0gJHt2ZWhpY2xlLm1ha2V9ICR7dmVoaWNsZS5tb2RlbH1gLCAiVmVoaWNsZSIpfV8ke1N0cmluZyhpbmRleCArIDEpLnBhZFN0YXJ0KDIsICIwIil9LmpwZ2A7CiAgfQogIGZ1bmN0aW9uIHBkZkZpbGVuYW1lKGN1c3RvbWVyLCB2ZWhpY2xlKSB7CiAgICByZXR1cm4gYCR7c2x1ZyhgJHtjdXN0b21lci5maXJzdE5hbWV9ICR7Y3VzdG9tZXIubGFzdE5hbWV9YCwgIkN1c3RvbWVyIil9XyR7c2x1ZyhgJHt2ZWhpY2xlLm1ha2V9ICR7dmVoaWNsZS5tb2RlbH1gLCAiVmVoaWNsZSIpfV9TdW1tYXJ5LnBkZmA7CiAgfQogIGZ1bmN0aW9uIHNsdWcodGV4dCwgZmFsbGJhY2spIHsKICAgIGNvbnN0IHNhZmUgPSBTdHJpbmcodGV4dCB8fCAiIikubm9ybWFsaXplKCJORktEIikucmVwbGFjZSgvW15cd1xzLi1dL2csICIiKS50cmltKCkucmVwbGFjZSgvXHMrL2csICItIikucmVwbGFjZSgvLSsvZywgIi0iKS5yZXBsYWNlKC9eWy5fLV0rfFsuXy1dKyQvZywgIiIpOwogICAgcmV0dXJuIHNhZmUgfHwgZmFsbGJhY2s7CiAgfQogIGZ1bmN0aW9uIHF1ZXJ5KG5hbWUpIHsKICAgIHJldHVybiBuZXcgVVJMU2VhcmNoUGFyYW1zKGxvY2F0aW9uLnNlYXJjaCkuZ2V0KG5hbWUpIHx8ICIiOwogIH0KICBmdW5jdGlvbiBsb2NhdGlvbkhyZWZXaXRob3V0U2VjcmV0cygpIHsKICAgIGNvbnN0IHVybCA9IG5ldyBVUkwobG9jYXRpb24uaHJlZik7CiAgICB1cmwuc2VhcmNoUGFyYW1zLmRlbGV0ZSgicGEiKTsKICAgIHVybC5zZWFyY2hQYXJhbXMuZGVsZXRlKCJzaXRla2V5Iik7CiAgICByZXR1cm4gdXJsLmhyZWY7CiAgfQogIGZ1bmN0aW9uIGZvcm1hdFBob25lKHRleHQpIHsKICAgIGNvbnN0IGRpZ2l0cyA9IHRleHQucmVwbGFjZSgvXEQvZywgIiIpLnNsaWNlKDAsIDEwKTsKICAgIGlmIChkaWdpdHMubGVuZ3RoIDwgNCkgcmV0dXJuIGRpZ2l0czsKICAgIGlmIChkaWdpdHMubGVuZ3RoIDwgNykgcmV0dXJuIGAoJHtkaWdpdHMuc2xpY2UoMCwgMyl9KSAke2RpZ2l0cy5zbGljZSgzKX1gOwogICAgcmV0dXJuIGAoJHtkaWdpdHMuc2xpY2UoMCwgMyl9KSAke2RpZ2l0cy5zbGljZSgzLCA2KX0tJHtkaWdpdHMuc2xpY2UoNil9YDsKICB9CiAgZnVuY3Rpb24gc2V0QnVzeShpc0J1c3ksIG1lc3NhZ2UpIHsKICAgIGVscy5zdWJtaXRCdXR0b24uZGlzYWJsZWQgPSBpc0J1c3k7CiAgICBlbHMuc3VibWl0U3RhdHVzLnRleHRDb250ZW50ID0gbWVzc2FnZSB8fCAiIjsKICB9CiAgZnVuY3Rpb24gc2V0U3VibWl0U3RhdHVzKG1lc3NhZ2UpIHsKICAgIGVscy5zdWJtaXRTdGF0dXMudGV4dENvbnRlbnQgPSBtZXNzYWdlOwogIH0KICBmdW5jdGlvbiBzZXRQaG90b1N0YXR1cyhtZXNzYWdlKSB7CiAgICBlbHMucGhvdG9TdGF0dXMudGV4dENvbnRlbnQgPSBtZXNzYWdlOwogIH0KICBmdW5jdGlvbiBjbGVhclN0YXR1cygpIHsKICAgIGVscy5zdWJtaXRTdGF0dXMudGV4dENvbnRlbnQgPSAiIjsKICB9CiAgZnVuY3Rpb24gcmVzZXRUdXJuc3RpbGUoKSB7CiAgICBpZiAod2luZG93LnR1cm5zdGlsZSAmJiBzdGF0ZS50dXJuc3RpbGVXaWRnZXRJZCAhPT0gbnVsbCkgewogICAgICB3aW5kb3cudHVybnN0aWxlLnJlc2V0KHN0YXRlLnR1cm5zdGlsZVdpZGdldElkKTsKICAgICAgc3RhdGUudHVybnN0aWxlVG9rZW4gPSAiIjsKICAgIH0KICB9CiAgLy8gRGVidWcgaGVscGVycyAoc2FmZSB0byBsZWF2ZSBpbiBzb3VyY2Ug4oCUIG9ubHkgYWN0aXZlIHdoZW4gP2RlYnVnPTEgb3IgP2RlYnVnPXBheWxvYWQpCiAgZnVuY3Rpb24gaXNEZWJ1Z1BheWxvYWRNb2RlKCkgewogICAgY29uc3QgdiA9IG5ldyBVUkxTZWFyY2hQYXJhbXMobG9jYXRpb24uc2VhcmNoKS5nZXQoImRlYnVnIik7CiAgICByZXR1cm4gdiA9PT0gInBheWxvYWQiIHx8IHYgPT09ICIxIiB8fCB2ID09PSAidHJ1ZSI7CiAgfQogIGFzeW5jIGZ1bmN0aW9uIGRvd25sb2FkRGVidWdQYXlsb2FkKCkgewogICAgdHJ5IHsKICAgICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IGJ1aWxkUGF5bG9hZCgpOwogICAgICBjb25zdCBqc29uID0gSlNPTi5zdHJpbmdpZnkocGF5bG9hZCwgbnVsbCwgMik7CiAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbanNvbl0sIHsgdHlwZTogImFwcGxpY2F0aW9uL2pzb24iIH0pOwogICAgICBjb25zdCBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOwogICAgICBhLmhyZWYgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpOwogICAgICBhLmRvd25sb2FkID0gYHRyYWRlLWluLXBheWxvYWQtJHtwYXlsb2FkLnN1Ym1pc3Npb25JZH0uanNvbmA7CiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7CiAgICAgIGEuY2xpY2soKTsKICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChhKTsKICAgICAgVVJMLnJldm9rZU9iamVjdFVSTChhLmhyZWYpOwogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgIGFsZXJ0KCJGYWlsZWQgdG8gYnVpbGQgZGVidWcgcGF5bG9hZDogIiArIGVyci5tZXNzYWdlKTsKICAgIH0KICB9CiAgYXN5bmMgZnVuY3Rpb24gY29weURlYnVnUGF5bG9hZChlKSB7CiAgICB0cnkgewogICAgICBjb25zdCBwYXlsb2FkID0gYXdhaXQgYnVpbGRQYXlsb2FkKCk7CiAgICAgIGNvbnN0IGpzb24gPSBKU09OLnN0cmluZ2lmeShwYXlsb2FkLCBudWxsLCAyKTsKICAgICAgYXdhaXQgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQoanNvbik7CiAgICAgIGNvbnN0IGJ0biA9IGUgJiYgZS5jdXJyZW50VGFyZ2V0ID8gZS5jdXJyZW50VGFyZ2V0IDogbnVsbDsKICAgICAgaWYgKGJ0bikgewogICAgICAgIGNvbnN0IG9yaWdpbmFsID0gYnRuLnRleHRDb250ZW50OwogICAgICAgIGJ0bi50ZXh0Q29udGVudCA9ICJDb3BpZWQhIjsKICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgYnRuLnRleHRDb250ZW50ID0gb3JpZ2luYWw7IH0sIDE0MDApOwogICAgICB9IGVsc2UgewogICAgICAgIGFsZXJ0KCJQYXlsb2FkIGNvcGllZCB0byBjbGlwYm9hcmQiKTsKICAgICAgfQogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgIGFsZXJ0KCJDb3B5IGZhaWxlZDogIiArIGVyci5tZXNzYWdlICsgIlxuKFVzZSBEb3dubG9hZCBpbnN0ZWFkKSIpOwogICAgfQogIH0KICBmdW5jdGlvbiBibG9iVG9JbWFnZShibG9iKSB7CiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gewogICAgICBjb25zdCBpbWFnZSA9IG5ldyBJbWFnZSgpOwogICAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpOwogICAgICBpbWFnZS5vbmxvYWQgPSAoKSA9PiB7CiAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpOwogICAgICAgIHJlc29sdmUoaW1hZ2UpOwogICAgICB9OwogICAgICBpbWFnZS5vbmVycm9yID0gKCkgPT4gewogICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTsKICAgICAgICByZWplY3QobmV3IEVycm9yKCJXZSBjb3VsZCBub3QgcmVhZCBvbmUgb2YgdGhvc2UgcGhvdG9zLiIpKTsKICAgICAgfTsKICAgICAgaW1hZ2Uuc3JjID0gdXJsOwogICAgfSk7CiAgfQogIGZ1bmN0aW9uIGNhbnZhc1RvQmxvYihjYW52YXMsIHR5cGUsIHF1YWxpdHkpIHsKICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAgIGNhbnZhcy50b0Jsb2IoKGJsb2IpID0+IGJsb2IgPyByZXNvbHZlKGJsb2IpIDogcmVqZWN0KG5ldyBFcnJvcigiV2UgY291bGQgbm90IGNvbXByZXNzIG9uZSBvZiB0aG9zZSBwaG90b3MuIikpLCB0eXBlLCBxdWFsaXR5KTsKICAgIH0pOwogIH0KICBmdW5jdGlvbiBibG9iVG9EYXRhVXJsKGJsb2IpIHsKICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7CiAgICAgIHJlYWRlci5vbmxvYWQgPSAoKSA9PiByZXNvbHZlKFN0cmluZyhyZWFkZXIucmVzdWx0KSk7CiAgICAgIHJlYWRlci5vbmVycm9yID0gKCkgPT4gcmVqZWN0KG5ldyBFcnJvcigiV2UgY291bGQgbm90IHByZXBhcmUgb25lIG9mIHRob3NlIHBob3Rvcy4iKSk7CiAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGJsb2IpOwogICAgfSk7CiAgfQogIGZ1bmN0aW9uIHdyYXBUZXh0KHRleHQsIHdpZHRoLCBtYXhMaW5lcykgewogICAgY29uc3Qgd29yZHMgPSBTdHJpbmcodGV4dCB8fCAiLSIpLnJlcGxhY2UoL1xzKy9nLCAiICIpLnRyaW0oKS5zcGxpdCgiICIpOwogICAgY29uc3QgbGluZXMgPSBbXTsKICAgIGxldCBsaW5lID0gIiI7CiAgICB3b3Jkcy5mb3JFYWNoKCh3b3JkKSA9PiB7CiAgICAgIGNvbnN0IG5leHQgPSBsaW5lID8gYCR7bGluZX0gJHt3b3JkfWAgOiB3b3JkOwogICAgICBpZiAobmV4dC5sZW5ndGggPiB3aWR0aCAmJiBsaW5lKSB7CiAgICAgICAgbGluZXMucHVzaChsaW5lKTsKICAgICAgICBsaW5lID0gd29yZDsKICAgICAgfSBlbHNlIHsKICAgICAgICBsaW5lID0gbmV4dDsKICAgICAgfQogICAgfSk7CiAgICBpZiAobGluZSkgbGluZXMucHVzaChsaW5lKTsKICAgIGlmIChsaW5lcy5sZW5ndGggPiBtYXhMaW5lcykgewogICAgICBjb25zdCB0cmltbWVkID0gbGluZXMuc2xpY2UoMCwgbWF4TGluZXMpOwogICAgICB0cmltbWVkW3RyaW1tZWQubGVuZ3RoIC0gMV0gPSBgJHt0cmltbWVkW3RyaW1tZWQubGVuZ3RoIC0gMV0ucmVwbGFjZSgvWy4gXSskLywgIiIpfS4uLmA7CiAgICAgIHJldHVybiB0cmltbWVkOwogICAgfQogICAgcmV0dXJuIGxpbmVzLmxlbmd0aCA/IGxpbmVzIDogWyItIl07CiAgfQogIGZ1bmN0aW9uIGVzY2FwZVBkZlRleHQodGV4dCkgewogICAgcmV0dXJuIFN0cmluZyh0ZXh0IHx8ICIiKS5yZXBsYWNlKC9cXC9nLCAiXFxcXCIpLnJlcGxhY2UoL1woL2csICJcXCgiKS5yZXBsYWNlKC9cKS9nLCAiXFwpIikucmVwbGFjZSgvW15ceDIwLVx4N0VdL2csICI/Iik7CiAgfQogIGZ1bmN0aW9uIHN0cmluZ1RvQnl0ZXModGV4dCkgewogICAgY29uc3QgYnl0ZXMgPSBuZXcgVWludDhBcnJheSh0ZXh0Lmxlbmd0aCk7CiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdGV4dC5sZW5ndGg7IGluZGV4ICs9IDEpIHsKICAgICAgYnl0ZXNbaW5kZXhdID0gdGV4dC5jaGFyQ29kZUF0KGluZGV4KSAmIDI1NTsKICAgIH0KICAgIHJldHVybiBieXRlczsKICB9CiAgZnVuY3Rpb24gYnl0ZXNUb0JpbmFyeShieXRlcykgewogICAgbGV0IGJpbmFyeSA9ICIiOwogICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGJ5dGVzLmxlbmd0aDsgaW5kZXggKz0gMSkgewogICAgICBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpbmRleF0pOwogICAgfQogICAgcmV0dXJuIGJpbmFyeTsKICB9CiAgZnVuY3Rpb24gYnl0ZXNUb0Jhc2U2NChieXRlcykgewogICAgcmV0dXJuIGJ0b2EoYnl0ZXNUb0JpbmFyeShieXRlcykpOwogIH0KICBmdW5jdGlvbiBiYXNlNjRUb0J5dGVzKGJhc2U2NCkgewogICAgY29uc3QgYmluYXJ5ID0gYXRvYihiYXNlNjQpOwogICAgY29uc3QgYnl0ZXMgPSBuZXcgVWludDhBcnJheShiaW5hcnkubGVuZ3RoKTsKICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBiaW5hcnkubGVuZ3RoOyBpbmRleCArPSAxKSB7CiAgICAgIGJ5dGVzW2luZGV4XSA9IGJpbmFyeS5jaGFyQ29kZUF0KGluZGV4KTsKICAgIH0KICAgIHJldHVybiBieXRlczsKICB9CiAgZnVuY3Rpb24gYmluYXJ5TGVuZ3RoKHRleHQpIHsKICAgIHJldHVybiBzdHJpbmdUb0J5dGVzKHRleHQpLmxlbmd0aDsKICB9CiAgZnVuY3Rpb24gZm9ybWF0Qnl0ZXMoYnl0ZXMpIHsKICAgIGlmIChieXRlcyA8IDEwMjQpIHJldHVybiBgJHtieXRlc30gQmA7CiAgICBpZiAoYnl0ZXMgPCAxMDI0ICogMTAyNCkgcmV0dXJuIGAke01hdGgucm91bmQoYnl0ZXMgLyAxMDI0KX0gS0JgOwogICAgcmV0dXJuIGAkeyhieXRlcyAvIDEwMjQgLyAxMDI0KS50b0ZpeGVkKDEpfSBNQmA7CiAgfQp9KSgpOwo=”));