IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMKIyAgRG9jTWFrZXIgMC4xIChjKSAyMDAwLTIwMDEgRGF2aWQgVHVybmVyIDxkYXZpZEBmcmVldHlwZS5vcmc+CiMKIyAgRG9jTWFrZXIgaXMgYSB2ZXJ5IHNpbXBsZSBwcm9ncmFtIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIEFQSSBSZWZlcmVuY2UKIyAgb2YgcHJvZ3JhbXMgYnkgZXh0cmFjdGluZyBjb21tZW50cyBmcm9tIHNvdXJjZSBmaWxlcywgYW5kIGdlbmVyYXRpbmcKIyAgdGhlIGVxdWl2YWxlbnQgSFRNTCBkb2N1bWVudGF0aW9uLgojCiMgIERvY01ha2VyIGlzIHZlcnkgc2ltaWxhciB0byBvdGhlciB0b29scyBsaWtlIERveHlnZW4sIHdpdGggdGhlCiMgIGZvbGxvd2luZyBkaWZmZXJlbmNlczoKIwojICAgIC0gSXQgaXMgd3JpdHRlbiBpbiBQeXRob24gKHNvIGl0IGlzIHNsb3csIGJ1dCBlYXN5IHRvIG1haW50YWluIGFuZAojICAgICAgaW1wcm92ZSkuCiMKIyAgICAtIFRoZSBjb21tZW50IHN5bnRheCB1c2VkIGJ5IERvY01ha2VyIGlzIHNpbXBsZXIgYW5kIG1ha2VzIGZvcgojICAgICAgY2xlYXJlciBjb21tZW50cy4KIwojICBPZiBjb3Vyc2UsIGl0IGRvZXNuJ3QgaGF2ZSBhbGwgdGhlIGdvb2RpZXMgb2YgbW9zdCBzaW1pbGFyIHRvb2xzLAojICAoZS5nLiBDKysgY2xhc3MgaGllcmFyY2hpZXMpLCBidXQgaGV5LCBpdCBpcyBvbmx5IDIwMDAgbGluZXMgb2YKIyAgUHl0aG9uLgojCiMgIERvY01ha2VyIGlzIG1haW5seSB1c2VkIHRvIGdlbmVyYXRlIHRoZSBBUEkgcmVmZXJlbmNlcyBvZiBzZXZlcmFsCiMgIEZyZWVUeXBlIHBhY2thZ2VzLgojCiMgICAtIERhdmlkCiMKCmltcG9ydCBmaWxlaW5wdXQsIHN5cywgb3MsIHRpbWUsIHN0cmluZywgZ2xvYiwgZ2V0b3B0CgojIFRoZSBQcm9qZWN0J3MgdGl0bGUuICBUaGlzIGNhbiBiZSBvdmVycmlkZGVuIGZyb20gdGhlIGNvbW1hbmQgbGluZSB3aXRoCiMgdGhlIG9wdGlvbnMgIi10IiBvciAiLS10aXRsZSIuCiMKcHJvamVjdF90aXRsZSA9ICJQcm9qZWN0IgoKIyBUaGUgcHJvamVjdCdzIGZpbGVuYW1lIHByZWZpeC4gIFRoaXMgY2FuIGJlIHNldCBmcm9tIHRoZSBjb21tYW5kIGxpbmUgd2l0aAojIHRoZSBvcHRpb25zICItcCIgb3IgIi0tcHJlZml4IgojCnByb2plY3RfcHJlZml4ID0gIiIKCiMgVGhlIHByb2plY3QncyBkb2N1bWVudGF0aW9uIG91dHB1dCBkaXJlY3RvcnkuICBUaGlzIGNhbiBiZSBzZXQgZnJvbSB0aGUKIyBjb21tYW5kIGxpbmUgd2l0aCB0aGUgb3B0aW9ucyAiLW8iIG9yICItLW91dHB1dCIuCiMKb3V0cHV0X2RpciA9IE5vbmUKCgojIFRoZSBmb2xsb3dpbmcgZGVmaW5lcyB0aGUgSFRNTCBoZWFkZXIgdXNlZCBieSBhbGwgZ2VuZXJhdGVkIHBhZ2VzLgojCmh0bWxfaGVhZGVyXzEgPSAiIiJcCjxodG1sPgo8aGVhZGVyPgo8dGl0bGU+IiIiCgpodG1sX2hlYWRlcl8yPSAiIiIgQVBJIFJlZmVyZW5jZTwvdGl0bGU+CjxiYXNlZm9udCBmYWNlPSJWZXJkYW5hLEdlbmV2YSxBcmlhbCxIZWx2ZXRpY2EiPgo8c3R5bGUgY29udGVudD0idGV4dC9jc3MiPgogIFAgeyB0ZXh0LWFsaWduPWp1c3RpZnkgfQogIEgxIHsgdGV4dC1hbGlnbj1jZW50ZXIgfQogIExJIHsgdGV4dC1hbGlnbj1qdXN0aWZ5IH0KPC9zdHlsZT4KPC9oZWFkZXI+Cjxib2R5IHRleHQ9IzAwMDAwMAogICAgICBiZ2NvbG9yPSNGRkZGRkYKICAgICAgbGluaz0jMDAwMEVGCiAgICAgIHZsaW5rPSM1MTE4OEUKICAgICAgYWxpbms9I0ZGMDAwMD4KPGNlbnRlcj48aDE+IiIiCgpodG1sX2hlYWRlcl8zPSIiIiBBUEkgUmVmZXJlbmNlPC9oMT48L2NlbnRlcj4KIiIiCgojIFRoaXMgaXMgcmVjb21wdXRlZCBsYXRlciB3aGVuIHRoZSBwcm9qZWN0IHRpdGxlIGNoYW5nZXMuCiMKaHRtbF9oZWFkZXIgPSBodG1sX2hlYWRlcl8xICsgcHJvamVjdF90aXRsZSArIGh0bWxfaGVhZGVyXzIgKyBwcm9qZWN0X3RpdGxlICsgaHRtbF9oZWFkZXJfMwoKCiMgVGhlIEhUTUwgZm9vdGVyIHVzZWQgYnkgYWxsIGdlbmVyYXRlZCBwYWdlcy4KIwpodG1sX2Zvb3RlciA9ICIiIlwKPC9ib2R5Pgo8L2h0bWw+IiIiCgojIFRoZSBoZWFkZXIgYW5kIGZvb3RlciB1c2VkIGZvciBlYWNoIHNlY3Rpb24uCiMKc2VjdGlvbl90aXRsZV9oZWFkZXIgPSAiPGNlbnRlcj48aDE+IgpzZWN0aW9uX3RpdGxlX2Zvb3RlciA9ICI8L2gxPjwvY2VudGVyPiIKCiMgVGhlIGhlYWRlciBhbmQgZm9vdGVyIHVzZWQgZm9yIGNvZGUgc2VnbWVudHMuCiMKY29kZV9oZWFkZXIgPSAiPGZvbnQgY29sb3I9Ymx1ZT48cHJlPiIKY29kZV9mb290ZXIgPSAiPC9wcmU+PC9mb250PiIKCiMgUGFyYWdyYXBoIGhlYWRlciBhbmQgZm9vdGVyLgojCnBhcmFfaGVhZGVyID0gIjxwPiIKcGFyYV9mb290ZXIgPSAiPC9wPiIKCiMgQmxvY2sgaGVhZGVyIGFuZCBmb290ZXIuCiMKYmxvY2tfaGVhZGVyID0gIjxjZW50ZXI+PHRhYmxlIHdpZHRoPTc1JT48dHI+PHRkPiIKYmxvY2tfZm9vdGVyID0gIjwvdGQ+PC90cj48L3RhYmxlPjxociB3aWR0aD03NSU+PC9jZW50ZXI+IgoKIyBEZXNjcmlwdGlvbiBoZWFkZXIvZm9vdGVyLgojCmRlc2NyaXB0aW9uX2hlYWRlciA9ICI8Y2VudGVyPjx0YWJsZSB3aWR0aD04NyU+PHRyPjx0ZD4iCmRlc2NyaXB0aW9uX2Zvb3RlciA9ICI8L3RkPjwvdHI+PC90YWJsZT48L2NlbnRlcj48YnI+IgoKIyBNYXJrZXIgaGVhZGVyL2ludGVyL2Zvb3RlciBjb21iaW5hdGlvbi4KIwptYXJrZXJfaGVhZGVyID0gIjxjZW50ZXI+PHRhYmxlIHdpZHRoPTg3JSBjZWxscGFkZGluZz01Pjx0ciBiZ2NvbG9yPSNFRUVFRkY+PHRkPjxlbT48Yj4iCm1hcmtlcl9pbnRlciAgPSAiPC9iPjwvZW0+PC90ZD48L3RyPjx0cj48dGQ+IgptYXJrZXJfZm9vdGVyID0gIjwvdGQ+PC90cj48L3RhYmxlPjwvY2VudGVyPiIKCiMgU291cmNlIGNvZGUgZXh0cmFjdHMgaGVhZGVyL2Zvb3Rlci4KIwpzb3VyY2VfaGVhZGVyID0gIjxjZW50ZXI+PHRhYmxlIHdpZHRoPTg3JT48dHIgYmdjb2xvcj0jRDZFOEZGIHdpZHRoPTEwMCU+PHRkPjxwcmU+Igpzb3VyY2VfZm9vdGVyID0gIjwvcHJlPjwvdGFibGU+PC9jZW50ZXI+PGJyPiIKCiMgQ2hhcHRlciBoZWFkZXIvaW50ZXIvZm9vdGVyLgojCmNoYXB0ZXJfaGVhZGVyID0gIjxjZW50ZXI+PHRhYmxlIHdpZHRoPTc1JT48dHI+PHRkPjxoMj4iCmNoYXB0ZXJfaW50ZXIgID0gIjwvaDI+PHVsPiIKY2hhcHRlcl9mb290ZXIgPSAiPC91bD48L3RkPjwvdHI+PC90YWJsZT48L2NlbnRlcj4iCgpjdXJyZW50X3NlY3Rpb24gPSBOb25lCgoKIyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gc29ydCB0aGUgaW5kZXguICBJdCBpcyBhIHNpbXBsZSBsZXhpY29ncmFwaGljYWwKIyBzb3J0LCBleGNlcHQgdGhhdCBpdCBwbGFjZXMgY2FwaXRhbCBsZXR0ZXJzIGJlZm9yZSBsb3dlcmNhc2Ugb25lcy4KIwpkZWYgaW5kZXhfc29ydCggczEsIHMyICk6CiAgICBpZiBub3QgczE6CiAgICAgICAgcmV0dXJuIC0xCgogICAgaWYgbm90IHMyOgogICAgICAgIHJldHVybiAxCgogICAgbDEgPSBsZW4oIHMxICkKICAgIGwyID0gbGVuKCBzMiApCiAgICBtMSA9IHN0cmluZy5sb3dlciggczEgKQogICAgbTIgPSBzdHJpbmcubG93ZXIoIHMyICkKCiAgICBmb3IgaSBpbiByYW5nZSggbDEgKToKICAgICAgICBpZiBpID49IGwyIG9yIG0xW2ldID4gbTJbaV06CiAgICAgICAgICAgIHJldHVybiAxCgogICAgICAgIGlmIG0xW2ldIDwgbTJbaV06CiAgICAgICAgICAgIHJldHVybiAtMQoKICAgICAgICBpZiBzMVtpXSA8IHMyW2ldOgogICAgICAgICAgICByZXR1cm4gLTEKCiAgICAgICAgaWYgczFbaV0gPiBzMltpXToKICAgICAgICAgICAgcmV0dXJuIDEKCiAgICBpZiBsMiA+IGwxOgogICAgICAgIHJldHVybiAtMQoKICAgIHJldHVybiAwCgoKIyBTb3J0IGlucHV0X2xpc3QsIHBsYWNpbmcgdGhlIGVsZW1lbnRzIG9mIG9yZGVyX2xpc3QgaW4gZnJvbnQuCiMKZGVmIHNvcnRfb3JkZXJfbGlzdCggaW5wdXRfbGlzdCwgb3JkZXJfbGlzdCApOgogICAgbmV3X2xpc3QgPSBvcmRlcl9saXN0WzpdCiAgICBmb3IgaWQgaW4gaW5wdXRfbGlzdDoKICAgICAgICBpZiBub3QgaWQgaW4gb3JkZXJfbGlzdDoKICAgICAgICAgICAgbmV3X2xpc3QuYXBwZW5kKCBpZCApCiAgICByZXR1cm4gbmV3X2xpc3QKCgojIFRyYW5zbGF0ZSBhIHNpbmdsZSBsaW5lIG9mIHNvdXJjZSB0byBIVE1MLiAgVGhpcyB3aWxsIGNvbnZlcnQKIyBhICI8IiBpbnRvICImbHQuIiwgIj4iIGludG8gIiZndC4iLCBldGMuCiMKZGVmIGh0bWxfcXVvdGUoIGxpbmUgKToKICAgIHJlc3VsdCA9IHN0cmluZy5yZXBsYWNlKCBsaW5lLCAgICImIiwgIiZhbXA7IiApCiAgICByZXN1bHQgPSBzdHJpbmcucmVwbGFjZSggcmVzdWx0LCAiPCIsICImbHQ7IiApCiAgICByZXN1bHQgPSBzdHJpbmcucmVwbGFjZSggcmVzdWx0LCAiPiIsICImZ3Q7IiApCiAgICByZXR1cm4gcmVzdWx0CgojIHNhbWUgYXMgJ2h0bWxfcXVvdGUnLCBidXQgaWdub3JlcyBsZWZ0IGFuZCByaWdodCBicmFja2V0cwojCmRlZiBodG1sX3F1b3RlMCggbGluZSApOgogICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKCBsaW5lLCAiJiIsICImYW1wOyIgKQoKCiMgT3BlbiB0aGUgc3RhbmRhcmQgb3V0cHV0IHRvIGEgZ2l2ZW4gcHJvamVjdCBkb2N1bWVudGF0aW9uIGZpbGUuICBVc2UKIyAib3V0cHV0X2RpciIgdG8gZGV0ZXJtaW5lIHRoZSBmaWxlbmFtZSBsb2NhdGlvbiBpZiBuZWNlc3NhcnkgYW5kIHNhdmUgdGhlCiMgb2xkIHN0ZG91dCBpbiBhIHR1cGxlIHRoYXQgaXMgcmV0dXJuZWQgYnkgdGhpcyBmdW5jdGlvbi4KIwpkZWYgb3Blbl9vdXRwdXQoIGZpbGVuYW1lICk6CiAgICBnbG9iYWwgb3V0cHV0X2RpcgoKICAgIGlmIG91dHB1dF9kaXIgYW5kIG91dHB1dF9kaXIgIT0gIiI6CiAgICAgICAgZmlsZW5hbWUgPSBvdXRwdXRfZGlyICsgb3Muc2VwICsgZmlsZW5hbWUKCiAgICBvbGRfc3Rkb3V0ID0gc3lzLnN0ZG91dAogICAgbmV3X2ZpbGUgICA9IG9wZW4oIGZpbGVuYW1lLCAidyIgKQogICAgc3lzLnN0ZG91dCA9IG5ld19maWxlCgogICAgcmV0dXJuICggbmV3X2ZpbGUsIG9sZF9zdGRvdXQgKQoKCiMgQ2xvc2UgdGhlIG91dHB1dCB0aGF0IHdhcyByZXR1cm5lZCBieSAiY2xvc2Vfb3V0cHV0Ii4KIwpkZWYgY2xvc2Vfb3V0cHV0KCBvdXRwdXQgKToKICAgIG91dHB1dFswXS5jbG9zZSgpCiAgICBzeXMuc3Rkb3V0ID0gb3V0cHV0WzFdCgoKIyBDaGVjayBvdXRwdXQgZGlyZWN0b3J5LgojCmRlZiBjaGVja19vdXRwdXQoICk6CiAgICBnbG9iYWwgb3V0cHV0X2RpcgogICAgaWYgb3V0cHV0X2RpcjoKICAgICAgICBpZiBvdXRwdXRfZGlyICE9ICIiOgogICAgICAgICAgICBpZiBub3Qgb3MucGF0aC5pc2Rpciggb3V0cHV0X2RpciApOgogICAgICAgICAgICAgICAgc3lzLnN0ZGVyci53cml0ZSggImFyZ3VtZW50IiArICIgJyIgKyBvdXRwdXRfZGlyICsgIicgIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaXMgbm90IGEgdmFsaWQgZGlyZWN0b3J5IiApCiAgICAgICAgICAgICAgICBzeXMuZXhpdCggMiApCiAgICAgICAgZWxzZToKICAgICAgICAgICAgb3V0cHV0X2RpciA9IE5vbmUKCgpkZWYgY29tcHV0ZV90aW1lX2h0bWwoICk6CiAgICBnbG9iYWwgaHRtbF9mb290ZXIKICAgIHRpbWVfc3RyaW5nID0gdGltZS5hc2N0aW1lKCB0aW1lLmxvY2FsdGltZSggdGltZS50aW1lKCkgKSApCiAgICBodG1sX2Zvb3RlciA9ICI8cD48Y2VudGVyPjxmb250IHNpemU9IiItMiIiPmdlbmVyYXRlZCBvbiAiICsgdGltZV9zdHJpbmcgKyAiPC9mb250PjwvcD48L2NlbnRlcj4iICsgaHRtbF9mb290ZXIKCiMgVGhlIEZyZWVUeXBlIDIgcmVmZXJlbmNlIGlzIGV4dHJhY3RlZCBmcm9tIHRoZSBzb3VyY2UgZmlsZXMuICBUaGVzZQojIGNvbnRhaW4gdmFyaW91cyBjb21tZW50IGJsb2NrcyB0aGF0IGZvbGxvdyBvbmUgb2YgdGhlIGZvbGxvd2luZyBmb3JtYXRzOgojCiMgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKgojICAgKgojICAgKiAgRk9STUFUMQojICAgKgojICAgKgojICAgKgojICAgKgojICAgKioqKioqKioqKioqKioqKioqKioqKioqKi8KIwojICAvKioqKioqKioqKioqKioqKioqKioqKioqKiovCiMgIC8qICAgICAgICAgICAgICAgICAgICAgICAgKi8KIyAgLyogIEZPUk1BVDIgICAgICAgICAgICAgICAqLwojICAvKiAgICAgICAgICAgICAgICAgICAgICAgICovCiMgIC8qICAgICAgICAgICAgICAgICAgICAgICAgKi8KIyAgLyogICAgICAgICAgICAgICAgICAgICAgICAqLwojICAvKiAgICAgICAgICAgICAgICAgICAgICAgICovCiMKIyAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqLwojICAvKiAgICAgICAgICAgICAgICAgICAgICAgICovCiMgIC8qICBGT1JNQVQzICAgICAgICAgICAgICAgKi8KIyAgLyogICAgICAgICAgICAgICAgICAgICAgICAqLwojICAvKiAgICAgICAgICAgICAgICAgICAgICAgICovCiMgIC8qICAgICAgICAgICAgICAgICAgICAgICAgKi8KIyAgLyogICAgICAgICAgICAgICAgICAgICAgICAqLwojICAvKioqKioqKioqKioqKioqKioqKioqKioqKiovCiMKIyBFYWNoIGJsb2NrIGNvbnRhaW5zIGEgbGlzdCBvZiBtYXJrZXJzOyBlYWNoIG9uZSBjYW4gYmUgZm9sbG93ZWQgYnkKIyBzb21lIGFyYml0cmFyeSB0ZXh0IG9yIGEgbGlzdCBvZiBmaWVsZHMuICBIZXJlIGFuIGV4YW1wbGU6CiMKIyAgICA8U3RydWN0PgojICAgICAgIE15U3RydWN0CiMKIyAgICA8RGVzY3JpcHRpb24+CiMgICAgICAgdGhpcyBzdHJ1Y3R1cmUgaG9sZHMgc29tZSBkYXRhCiMKIyAgICA8RmllbGRzPgojICAgICAgIHggOjogaG9yaXpvbnRhbCBjb29yZGluYXRlCiMgICAgICAgeSA6OiB2ZXJ0aWNhbCBjb29yZGluYXRlCiMKIwojIFRoaXMgZXhhbXBsZSBkZWZpbmVzIHRocmVlIG1hcmtlcnM6ICdTdHJ1Y3QnLCAnRGVzY3JpcHRpb24nICYgJ0ZpZWxkcycuCiMgVGhlIGZpcnN0IHR3byBtYXJrZXJzIGNvbnRhaW4gYXJiaXRyYXJ5IHRleHQsIHdoaWxlIHRoZSBsYXN0IG9uZSBjb250YWlucwojIGEgbGlzdCBvZiBmaWVsZHMuCiMKIyBFYWNoIGZpZWxkIGlzIHNpbXBseSBvZiB0aGUgZm9ybWF0OiAgV09SRCA6OiBURVhULi4uCiMKIyBOb3RlIHRoYXQgdHlwaWNhbGx5IGVhY2ggY29tbWVudCBibG9jayBpcyBmb2xsb3dlZCBieSBzb21lIHNvdXJjZSBjb2RlCiMgZGVjbGFyYXRpb24gdGhhdCBtYXkgbmVlZCB0byBiZSBrZXB0IGluIHRoZSByZWZlcmVuY2UuCiMKIyBOb3RlIHRoYXQgbWFya2VycyBjYW4gYWx0ZXJuYXRpdmVseSBiZSB3cml0dGVuIGFzICJATUFSS0VSOiIgaW5zdGVhZCBvZgojICI8TUFSS0VSPiIuICBBbGwgbWFya2VyIGlkZW50aWZpZXJzIGFyZSBjb252ZXJ0ZWQgdG8gbG93ZXIgY2FzZSBkdXJpbmcKIyBwYXJzaW5nIGluIG9yZGVyIHRvIHNpbXBseSBzb3J0aW5nLgojCiMgV2UgYXNzb2NpYXRlIHdpdGggZWFjaCBibG9jayB0aGUgZm9sbG93aW5nIHNvdXJjZSBsaW5lcyB0aGF0IGRvIG5vdCBiZWdpbgojIHdpdGggYSBjb21tZW50LiAgRm9yIGV4YW1wbGUsIHRoZSBmb2xsb3dpbmc6CiMKIyAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiMgICAgKgojICAgICogPG15dGFnPiAgYmxhYmxhCiMgICAgKgojICAgICovCiMKIyAgIGJsYV9ibGFfYmxhCiMgICBiaWxpcF9iaWxpcAojCiMgICAvKiAtIHRoaXMgY29tbWVudCBhY3RzIGFzIGEgc2VwYXJhdG9yIC0gKi8KIwojICAgYmxvX2Jsb19ibG8KIwojCiMgd2lsbCBvbmx5IGtlZXAgdGhlIGZpcnN0IHR3byBsaW5lcyBvZiBzb3VyY2VzIHdpdGgKIyB0aGUgImJsYWJsYSIgYmxvY2suCiMKIyBIb3dldmVyLCB0aGUgY29tbWVudCB3aWxsIGJlIGtlcHQsIHdpdGggZm9sbG93aW5nIHNvdXJjZSBsaW5lcyBpZiBpdAojIGNvbnRhaW5zIGEgc3RhcnRpbmcgJyMnIG9yICdAJyBhcyBpbjoKIwojICAgLypALi4uLi4qLwojICAgLyojLi4uLi4qLwojICAgLyogQC4uLi4uKi8KIyAgIC8qICMuLi4uLiovCiMKCgoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIwojIFRoZSBEb2NDb2RlIGNsYXNzIGlzIHVzZWQgdG8gc3RvcmUgc291cmNlIGNvZGUgbGluZXMuCiMKIyAgICdzZWxmLmxpbmVzJyBjb250YWlucyBhIHNldCBvZiBzb3VyY2UgY29kZSBsaW5lcyB0aGF0IHdpbGwgYmUgZHVtcGVkIGFzCiMgICBIVE1MIGluIGEgPFBSRT4gdGFnLgojCiMgICBUaGUgb2JqZWN0IGlzIGZpbGxlZCBsaW5lIGJ5IGxpbmUgYnkgdGhlIHBhcnNlcjsgaXQgc3RyaXBzIHRoZSBsZWFkaW5nCiMgICAibWFyZ2luIiBzcGFjZSBmcm9tIGVhY2ggaW5wdXQgbGluZSBiZWZvcmUgc3RvcmluZyBpdCBpbiAnc2VsZi5saW5lcycuCiMKY2xhc3MgRG9jQ29kZToKCiAgICBkZWYgX19pbml0X18oIHNlbGYsIG1hcmdpbiA9IDAgKToKICAgICAgICBzZWxmLmxpbmVzICA9IFtdCiAgICAgICAgc2VsZi5tYXJnaW4gPSBtYXJnaW4KCgogICAgZGVmIGFkZCggc2VsZiwgbGluZSApOgogICAgICAgICMgcmVtb3ZlIG1hcmdpbiB3aGl0ZXNwYWNlCiAgICAgICAgIwogICAgICAgIGlmIHN0cmluZy5zdHJpcCggbGluZVs6IHNlbGYubWFyZ2luXSApID09ICIiOgogICAgICAgICAgICBsaW5lID0gbGluZVtzZWxmLm1hcmdpbiA6XQogICAgICAgIHNlbGYubGluZXMuYXBwZW5kKCBsaW5lICkKCgogICAgZGVmIGR1bXAoIHNlbGYgKToKICAgICAgICBmb3IgbGluZSBpbiBzZWxmLmxpbmVzOgogICAgICAgICAgICBwcmludCAiLS0iICsgbGluZQogICAgICAgIHByaW50ICIiCgoKICAgIGRlZiBnZXRfaWRlbnRpZmllciggc2VsZiApOgogICAgICAgICMgdGhpcyBmdW5jdGlvbiBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkCiAgICAgICAgIwogICAgICAgIHJldHVybiAiVU5LTk9XTl9DT0RFX0lERU5USUZJRVIhIgoKCiAgICBkZWYgZHVtcF9odG1sKCBzZWxmLCBpZGVudGlmaWVycyA9IE5vbmUgKToKICAgICAgICAjIGNsZWFuIHRoZSBsYXN0IGVtcHR5IGxpbmVzCiAgICAgICAgIwogICAgICAgIGwgPSBsZW4oIHNlbGYubGluZXMgKSAtIDEKICAgICAgICB3aGlsZSBsID4gMCBhbmQgc3RyaW5nLnN0cmlwKCBzZWxmLmxpbmVzW2wgLSAxXSApID09ICIiOgogICAgICAgICAgICBsID0gbCAtIDEKCiAgICAgICAgIyBUaGUgY29kZSBmb290ZXIgc2hvdWxkIGJlIGRpcmVjdGx5IGFwcGVuZGVkIHRvIHRoZSBsYXN0IGNvZGUKICAgICAgICAjIGxpbmUgdG8gYXZvaWQgYW4gYWRkaXRpb25hbCBibGFuayBsaW5lLgogICAgICAgICMKICAgICAgICBwcmludCBjb2RlX2hlYWRlciwKICAgICAgICBmb3IgbGluZSBpbiBzZWxmLmxpbmVzWzAgOiBsKzFdOgogICAgICAgICAgICBwcmludCAnXG4nICsgaHRtbF9xdW90ZShsaW5lKSwKICAgICAgICBwcmludCBjb2RlX2Zvb3RlciwKCgoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIwojIFRoZSBEb2NQYXJhZ3JhcGggaXMgdXNlZCB0byBzdG9yZSB0ZXh0IHBhcmFncmFwaHMuCiMgJ3NlbGYud29yZHMnIGlzIHNpbXBseSBhIGxpc3Qgb2Ygd29yZHMgZm9yIHRoZSBwYXJhZ3JhcGguCiMKIyBUaGUgcGFyYWdyYXBoIGlzIGZpbGxlZCBsaW5lIGJ5IGxpbmUgYnkgdGhlIHBhcnNlci4KIwpjbGFzcyBEb2NQYXJhZ3JhcGg6CgogICAgZGVmIF9faW5pdF9fKCBzZWxmICk6CiAgICAgICAgc2VsZi53b3JkcyA9IFtdCgoKICAgIGRlZiBhZGQoIHNlbGYsIGxpbmUgKToKICAgICAgICAjIEdldCByaWQgb2YgdW53YW50ZWQgc3BhY2VzIGluIHRoZSBwYXJhZ3JhcGguCiAgICAgICAgIwogICAgICAgICMgVGhlIGZvbGxvd2luZyB0d28gbGluZXMgYXJlIHRoZSBzYW1lIGFzCiAgICAgICAgIwogICAgICAgICMgICBzZWxmLndvcmRzLmV4dGVuZCggc3RyaW5nLnNwbGl0KCBsaW5lICkgKQogICAgICAgICMKICAgICAgICAjIGJ1dCBvbGRlciBQeXRob24gdmVyc2lvbnMgZG9uJ3QgaGF2ZSB0aGUgYGV4dGVuZCcgYXR0cmlidXRlLgogICAgICAgICMKICAgICAgICBsYXN0ID0gbGVuKCBzZWxmLndvcmRzICkKICAgICAgICBzZWxmLndvcmRzW2xhc3QgOiBsYXN0XSA9IHN0cmluZy5zcGxpdCggbGluZSApCgoKICAgICMgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIHJldHJpZXZlIHRoZSBmaXJzdCB3b3JkIG9mIGEgZ2l2ZW4KICAgICMgcGFyYWdyYXBoLgogICAgIwogICAgZGVmIGdldF9pZGVudGlmaWVyKCBzZWxmICk6CiAgICAgICAgaWYgc2VsZi53b3JkczoKICAgICAgICAgICAgcmV0dXJuIHNlbGYud29yZHNbMF0KCiAgICAgICAgIyBzaG91bGQgbmV2ZXIgaGFwcGVuCiAgICAgICAgIwogICAgICAgIHJldHVybiAiVU5LTk9XTl9QQVJBX0lERU5USUZJRVIhIgoKCiAgICBkZWYgZ2V0X3dvcmRzKCBzZWxmICk6CiAgICAgICAgcmV0dXJuIHNlbGYud29yZHNbOl0KCgogICAgZGVmIGR1bXAoIHNlbGYsIGlkZW50aWZpZXJzID0gTm9uZSApOgogICAgICAgIG1heF93aWR0aCA9IDUwCiAgICAgICAgY3Vyc29yICAgID0gMAogICAgICAgIGxpbmUgICAgICA9ICIiCiAgICAgICAgZXh0cmEgICAgID0gTm9uZQogICAgICAgIGFscGhhbnVtICA9IHN0cmluZy5sb3dlcmNhc2UgKyBzdHJpbmcudXBwZXJjYXNlICsgc3RyaW5nLmRpZ2l0cyArICdfJwoKICAgICAgICBmb3Igd29yZCBpbiBzZWxmLndvcmRzOgogICAgICAgICAgICAjIHByb2Nlc3MgY3Jvc3MgcmVmZXJlbmNlcyBpZiBuZWVkZWQKICAgICAgICAgICAgIwogICAgICAgICAgICBpZiBpZGVudGlmaWVycyBhbmQgd29yZCBhbmQgd29yZFswXSA9PSAnQCc6CiAgICAgICAgICAgICAgICB3b3JkID0gd29yZFsxIDpdCgogICAgICAgICAgICAgICAgIyB3ZSBuZWVkIHRvIGZpbmQgbm9uLWFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzCiAgICAgICAgICAgICAgICAjCiAgICAgICAgICAgICAgICBsID0gbGVuKCB3b3JkICkKICAgICAgICAgICAgICAgIGkgPSAwCiAgICAgICAgICAgICAgICB3aGlsZSBpIDwgbCBhbmQgd29yZFtpXSBpbiBhbHBoYW51bToKICAgICAgICAgICAgICAgICAgICBpID0gaSArIDEKCiAgICAgICAgICAgICAgICBpZiBpIDwgbDoKICAgICAgICAgICAgICAgICAgICBleHRyYSA9IHdvcmRbaSA6XQogICAgICAgICAgICAgICAgICAgIHdvcmQgID0gd29yZFswIDogaV0KCiAgICAgICAgICAgICAgICBibG9jayA9IGlkZW50aWZpZXJzLmdldCggd29yZCApCiAgICAgICAgICAgICAgICBpZiBibG9jazoKICAgICAgICAgICAgICAgICAgICB3b3JkID0gJzxhIGhyZWY9IicgKyBibG9jay5odG1sX2FkZHJlc3MoKSArICciPicgKyB3b3JkICsgJzwvYT4nCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHdvcmQgPSAnPycgKyB3b3JkCgogICAgICAgICAgICBpZiBjdXJzb3IgKyBsZW4oIHdvcmQgKSArIDEgPiBtYXhfd2lkdGg6CiAgICAgICAgICAgICAgICBwcmludCBodG1sX3F1b3RlMChsaW5lKQogICAgICAgICAgICAgICAgY3Vyc29yID0gMAogICAgICAgICAgICAgICAgbGluZSAgID0gIiIKCiAgICAgICAgICAgIGxpbmUgPSBsaW5lICsgd29yZAogICAgICAgICAgICBpZiBub3QgZXh0cmE6CiAgICAgICAgICAgICAgICBsaW5lID0gbGluZSArICIgIgoKICAgICAgICAgICAgY3Vyc29yID0gY3Vyc29yICsgbGVuKCB3b3JkICkgKyAxCgoKICAgICAgICAgICAgIyBIYW5kbGUgdHJhaWxpbmcgcGVyaW9kcywgY29tbWFzLCBldGMuIGF0IHRoZSBlbmQgb2YgY3Jvc3MKICAgICAgICAgICAgIyByZWZlcmVuY2VzLgogICAgICAgICAgICAjCiAgICAgICAgICAgIGlmIGV4dHJhOgogICAgICAgICAgICAgICAgaWYgY3Vyc29yICsgbGVuKCBleHRyYSApICsgMSA+IG1heF93aWR0aDoKICAgICAgICAgICAgICAgICAgICBwcmludCBodG1sX3F1b3RlMChsaW5lKQogICAgICAgICAgICAgICAgICAgIGN1cnNvciA9IDAKICAgICAgICAgICAgICAgICAgICBsaW5lICAgPSAiIgoKICAgICAgICAgICAgICAgIGxpbmUgICA9IGxpbmUgKyBleHRyYSArICIgIgogICAgICAgICAgICAgICAgY3Vyc29yID0gY3Vyc29yICsgbGVuKCBleHRyYSApICsgMQogICAgICAgICAgICAgICAgZXh0cmEgID0gTm9uZQoKICAgICAgICBpZiBjdXJzb3IgPiAwOgogICAgICAgICAgICBwcmludCBodG1sX3F1b3RlMChsaW5lKQoKICAgICAgICAjIHByaW50ICKnIiAjIGZvciBkZWJ1Z2dpbmcgb25seQoKCiAgICBkZWYgZHVtcF9zdHJpbmcoIHNlbGYgKToKICAgICAgICBzICAgICA9ICIiCiAgICAgICAgc3BhY2UgPSAiIgogICAgICAgIGZvciB3b3JkIGluIHNlbGYud29yZHM6CiAgICAgICAgICAgIHMgICAgID0gcyArIHNwYWNlICsgd29yZAogICAgICAgICAgICBzcGFjZSA9ICIgIgoKICAgICAgICByZXR1cm4gcwoKCiAgICBkZWYgZHVtcF9odG1sKCBzZWxmLCBpZGVudGlmaWVycyA9IE5vbmUgKToKICAgICAgICBwcmludCBwYXJhX2hlYWRlcgogICAgICAgIHNlbGYuZHVtcCggaWRlbnRpZmllcnMgKQogICAgICAgIHByaW50IHBhcmFfZm9vdGVyCgoKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMKIyBEb2NDb250ZW50IGlzIHVzZWQgdG8gc3RvcmUgdGhlIGNvbnRlbnQgb2YgYSBnaXZlbiBtYXJrZXIuCiMKIyBUaGUgInNlbGYuaXRlbXMiIGxpc3QgY29udGFpbnMgKGZpZWxkLGVsZW1lbnRzKSByZWNvcmRzLCB3aGVyZSAiZmllbGQiCiMgY29ycmVzcG9uZHMgdG8gYSBnaXZlbiBzdHJ1Y3R1cmUgZmllbGQgb3IgZnVuY3Rpb24gcGFyYW1ldGVyIChpbmRpY2F0ZWQKIyBieSBhICI6OiIpLCBvciBOVUxMIGZvciBhIG5vcm1hbCBzZWN0aW9uIG9mIHRleHQvY29kZS4KIwojIEhlbmNlLCB0aGUgZm9sbG93aW5nIGV4YW1wbGU6CiMKIyAgIDxNeU1hcmtlcj4KIyAgICAgIFRoaXMgaXMgYW4gZXhhbXBsZSBvZiB3aGF0IGNhbiBiZSBwdXQgaW4gYSBjb250ZW50IHNlY3Rpb24sCiMKIyAgICAgIEEgc2Vjb25kIGxpbmUgb2YgZXhhbXBsZSB0ZXh0LgojCiMgICAgICB4IDo6IEEgc2ltcGxlIHRlc3QgZmllbGQsIHdpdGggc29tZSBjb250ZW50cy4KIyAgICAgIHkgOjogRXZlbiBiZWZvcmUsIHRoaXMgZmllbGQgaGFzIHNvbWUgY29kZSBjb250ZW50cy4KIyAgICAgICAgICAgewojICAgICAgICAgICAgIHkgPSB4KzI7CiMgICAgICAgICAgIH0KIwojIHNob3VsZCBiZSBzdG9yZWQgYXMKIwojICAgICBbICggTm9uZSwgWyBEb2NQYXJhZ3JhcGgsIERvY1BhcmFncmFwaF0gKSwKIyAgICAgICAoICJ4IiwgIFsgRG9jUGFyYWdyYXBoIF0gKSwKIyAgICAgICAoICJ5IiwgIFsgRG9jUGFyYWdyYXBoLCBEb2NDb2RlIF0gKSBdCiMKIyBpbiAnc2VsZi5pdGVtcycuCiMKIyBUaGUgRG9jQ29udGVudCBvYmplY3QgaXMgZW50aXJlbHkgYnVpbHQgYXQgY3JlYXRpb24gdGltZTsgeW91IG11c3QgcGFzcyBhCiMgbGlzdCBvZiBpbnB1dCB0ZXh0IGxpbmVzIGluIHRoZSAibGluZXNfbGlzdCIgcGFyYW1ldGVyLgojCmNsYXNzIERvY0NvbnRlbnQ6CgogICAgZGVmIF9faW5pdF9fKCBzZWxmLCBsaW5lc19saXN0ICk6CiAgICAgICAgc2VsZi5pdGVtcyAgPSBbXQogICAgICAgIGNvZGVfbW9kZSAgID0gMAogICAgICAgIGNvZGVfbWFyZ2luID0gMAogICAgICAgIHRleHQgICAgICAgID0gW10KICAgICAgICBwYXJhZ3JhcGggICA9IE5vbmUgICAjIHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgRG9jUGFyYWdyYXBoCiAgICAgICAgY29kZSAgICAgICAgPSBOb25lICAgIyByZXByZXNlbnRzIHRoZSBjdXJyZW50IERvY0NvZGUKCiAgICAgICAgZWxlbWVudHMgICAgPSBbXSAgICAgIyB0aGUgbGlzdCBvZiBlbGVtZW50cyBmb3IgdGhlIGN1cnJlbnQgZmllbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBjb250YWlucyBEb2NQYXJhZ3JhcGggb3IgRG9jQ29kZSBvYmplY3RzCgogICAgICAgIGZpZWxkICAgICAgID0gTm9uZSAgICMgdGhlIGN1cnJlbnQgZmllbGQKCiAgICAgICAgZm9yIGFsaW5lIGluIGxpbmVzX2xpc3Q6CiAgICAgICAgICAgIGlmIGNvZGVfbW9kZSA9PSAwOgogICAgICAgICAgICAgICAgbGluZSAgID0gc3RyaW5nLmxzdHJpcCggYWxpbmUgKQogICAgICAgICAgICAgICAgbCAgICAgID0gbGVuKCBsaW5lICkKICAgICAgICAgICAgICAgIG1hcmdpbiA9IGxlbiggYWxpbmUgKSAtIGwKCiAgICAgICAgICAgICAgICAjIGlmIHRoZSBsaW5lIGlzIGVtcHR5LCB0aGlzIGlzIHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQKICAgICAgICAgICAgICAgICMgcGFyYWdyYXBoCiAgICAgICAgICAgICAgICAjCiAgICAgICAgICAgICAgICBpZiBsID09IDAgb3IgbGluZSA9PSAneyc6CiAgICAgICAgICAgICAgICAgICAgaWYgcGFyYWdyYXBoOgogICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cy5hcHBlbmQoIHBhcmFncmFwaCApCiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFncmFwaCA9IE5vbmUKCiAgICAgICAgICAgICAgICAgICAgaWYgbGluZSA9PSAiIjoKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgICAgICAgICAgY29kZV9tb2RlICAgPSAxCiAgICAgICAgICAgICAgICAgICAgY29kZV9tYXJnaW4gPSBtYXJnaW4KICAgICAgICAgICAgICAgICAgICBjb2RlICAgICAgICA9IE5vbmUKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgICAgIHdvcmRzID0gc3RyaW5nLnNwbGl0KCBsaW5lICkKCiAgICAgICAgICAgICAgICAjIHRlc3QgZm9yIGEgZmllbGQgZGVsaW1pdGVyIG9uIHRoZSBzdGFydCBvZiB0aGUgbGluZSwgaS5lLgogICAgICAgICAgICAgICAgIyB0aGUgdG9rZW4gYDo6JwogICAgICAgICAgICAgICAgIwogICAgICAgICAgICAgICAgaWYgbGVuKCB3b3JkcyApID49IDIgYW5kIHdvcmRzWzFdID09ICI6OiI6CiAgICAgICAgICAgICAgICAgICAgIyBzdGFydCBhIG5ldyBmaWVsZCAtIGNvbXBsZXRlIGN1cnJlbnQgcGFyYWdyYXBoIGlmIGFueQogICAgICAgICAgICAgICAgICAgICMKICAgICAgICAgICAgICAgICAgICBpZiBwYXJhZ3JhcGg6CiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLmFwcGVuZCggcGFyYWdyYXBoICkKICAgICAgICAgICAgICAgICAgICAgICAgcGFyYWdyYXBoID0gTm9uZQoKICAgICAgICAgICAgICAgICAgICAjIGFwcGVuZCBwcmV2aW91cyAiZmllbGQiIHRvIHNlbGYuaXRlbXMKICAgICAgICAgICAgICAgICAgICAjCiAgICAgICAgICAgICAgICAgICAgc2VsZi5pdGVtcy5hcHBlbmQoICggZmllbGQsIGVsZW1lbnRzICkgKQoKICAgICAgICAgICAgICAgICAgICAjIHN0YXJ0IG5ldyBmaWVsZCBhbmQgZWxlbWVudHMgbGlzdAogICAgICAgICAgICAgICAgICAgICMKICAgICAgICAgICAgICAgICAgICBmaWVsZCAgICA9IHdvcmRzWzBdCiAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMgPSBbXQogICAgICAgICAgICAgICAgICAgIHdvcmRzICAgID0gd29yZHNbMiA6XQoKICAgICAgICAgICAgICAgICMgYXBwZW5kIHJlbWFpbmluZyB3b3JkcyB0byBjdXJyZW50IHBhcmFncmFwaAogICAgICAgICAgICAgICAgIwogICAgICAgICAgICAgICAgaWYgbGVuKCB3b3JkcyApID4gMDoKICAgICAgICAgICAgICAgICAgICBsaW5lID0gc3RyaW5nLmpvaW4oIHdvcmRzICkKICAgICAgICAgICAgICAgICAgICBpZiBub3QgcGFyYWdyYXBoOgogICAgICAgICAgICAgICAgICAgICAgICBwYXJhZ3JhcGggPSBEb2NQYXJhZ3JhcGgoKQogICAgICAgICAgICAgICAgICAgIHBhcmFncmFwaC5hZGQoIGxpbmUgKQoKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgd2UgYXJlIGluIGNvZGUgbW9kZS4uLgogICAgICAgICAgICAgICAgIwogICAgICAgICAgICAgICAgbGluZSA9IGFsaW5lCgogICAgICAgICAgICAgICAgIyB0aGUgY29kZSBibG9jayBlbmRzIHdpdGggYSBsaW5lIHRoYXQgaGFzIGEgc2luZ2xlICd9JyBvbgogICAgICAgICAgICAgICAgIyBpdCB0aGF0IGlzIGxvY2F0ZWQgYXQgdGhlIHNhbWUgY29sdW1uIHRoYXQgdGhlIG9wZW5pbmcKICAgICAgICAgICAgICAgICMgYWNjb2xhZGUuLi4KICAgICAgICAgICAgICAgICMKICAgICAgICAgICAgICAgIGlmIGxpbmUgPT0gIiAiICogY29kZV9tYXJnaW4gKyAnfSc6CiAgICAgICAgICAgICAgICAgICAgaWYgY29kZToKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMuYXBwZW5kKCBjb2RlICkKICAgICAgICAgICAgICAgICAgICAgICAgY29kZSA9IE5vbmUKCiAgICAgICAgICAgICAgICAgICAgY29kZV9tb2RlICAgPSAwCiAgICAgICAgICAgICAgICAgICAgY29kZV9tYXJnaW4gPSAwCgogICAgICAgICAgICAgICAgIyBvdGhlcndpc2UsIGFkZCB0aGUgbGluZSB0byB0aGUgY3VycmVudCBwYXJhZ3JhcGgKICAgICAgICAgICAgICAgICMKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IGNvZGU6CiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUgPSBEb2NDb2RlKCkKICAgICAgICAgICAgICAgICAgICBjb2RlLmFkZCggbGluZSApCgogICAgICAgIGlmIHBhcmFncmFwaDoKICAgICAgICAgICAgZWxlbWVudHMuYXBwZW5kKCBwYXJhZ3JhcGggKQoKICAgICAgICBpZiBjb2RlOgogICAgICAgICAgICBlbGVtZW50cy5hcHBlbmQoIGNvZGUgKQoKICAgICAgICBzZWxmLml0ZW1zLmFwcGVuZCggKCBmaWVsZCwgZWxlbWVudHMgKSApCgoKICAgIGRlZiBnZXRfaWRlbnRpZmllciggc2VsZiApOgogICAgICAgIGlmIHNlbGYuaXRlbXM6CiAgICAgICAgICAgIGl0ZW0gPSBzZWxmLml0ZW1zWzBdCiAgICAgICAgICAgIGZvciBlbGVtZW50IGluIGl0ZW1bMV06CiAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudC5nZXRfaWRlbnRpZmllcigpCgogICAgICAgICMgc2hvdWxkIG5ldmVyIGhhcHBlbgogICAgICAgICMKICAgICAgICByZXR1cm4gIlVOS05PV05fQ09OVEVOVF9JREVOVElGSUVSISIKCgogICAgZGVmIGdldF90aXRsZSggc2VsZiApOgogICAgICAgIGlmIHNlbGYuaXRlbXM6CiAgICAgICAgICAgIGl0ZW0gPSBzZWxmLml0ZW1zWzBdCiAgICAgICAgICAgIGZvciBlbGVtZW50IGluIGl0ZW1bMV06CiAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudC5kdW1wX3N0cmluZygpCgogICAgICAgICMgc2hvdWxkIG5ldmVyIGhhcHBlbgogICAgICAgICMKICAgICAgICByZXR1cm4gIlVOS05PV05fQ09OVEVOVF9USVRMRSEiCgoKICAgIGRlZiBkdW1wKCBzZWxmICk6CiAgICAgICAgZm9yIGl0ZW0gaW4gc2VsZi5pdGVtczoKICAgICAgICAgICAgZmllbGQgPSBpdGVtWzBdCiAgICAgICAgICAgIGlmIGZpZWxkOgogICAgICAgICAgICAgICAgcHJpbnQgIjxmaWVsZCAiICsgZmllbGQgKyAiPiIKCiAgICAgICAgICAgIGZvciBlbGVtZW50IGluIGl0ZW1bMV06CiAgICAgICAgICAgICAgICBlbGVtZW50LmR1bXAoKQoKICAgICAgICAgICAgaWYgZmllbGQ6CiAgICAgICAgICAgICAgICBwcmludCAiPC9maWVsZD4iCgoKICAgIGRlZiBkdW1wX2h0bWwoIHNlbGYsIGlkZW50aWZpZXJzID0gTm9uZSApOgogICAgICAgIG4gICAgICAgID0gbGVuKCBzZWxmLml0ZW1zICkKICAgICAgICBpbl90YWJsZSA9IDAKCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoIG4gKToKICAgICAgICAgICAgaXRlbSAgPSBzZWxmLml0ZW1zW2ldCiAgICAgICAgICAgIGZpZWxkID0gaXRlbVswXQoKICAgICAgICAgICAgaWYgbm90IGZpZWxkOgogICAgICAgICAgICAgICAgaWYgaW5fdGFibGU6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIjwvdGQ+PC90cj48L3RhYmxlPiIKICAgICAgICAgICAgICAgICAgICBpbl90YWJsZSA9IDAKCiAgICAgICAgICAgICAgICBmb3IgZWxlbWVudCBpbiBpdGVtWzFdOgogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuZHVtcF9odG1sKCBpZGVudGlmaWVycyApCgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgbm90IGluX3RhYmxlOgogICAgICAgICAgICAgICAgICAgIHByaW50ICI8dGFibGUgY2VsbHBhZGRpbmc9ND48dHIgdmFsaWduPXRvcD48dGQ+IgogICAgICAgICAgICAgICAgICAgIGluX3RhYmxlID0gMQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBwcmludCAiPC90ZD48L3RyPjx0ciB2YWxpZ249dG9wPjx0ZD4iCgogICAgICAgICAgICAgICAgcHJpbnQgIjxiPiIgKyBmaWVsZCArICI8L2I+PC90ZD48dGQ+IgoKICAgICAgICAgICAgICAgIGZvciBlbGVtZW50IGluIGl0ZW1bMV06CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5kdW1wX2h0bWwoIGlkZW50aWZpZXJzICkKCiAgICAgICAgaWYgaW5fdGFibGU6CiAgICAgICAgICAgIHByaW50ICI8L3RkPjwvdHI+PC90YWJsZT4iCgoKICAgIGRlZiBkdW1wX2h0bWxfaW5fdGFibGUoIHNlbGYsIGlkZW50aWZpZXJzID0gTm9uZSApOgogICAgICAgIG4gICAgICAgID0gbGVuKCBzZWxmLml0ZW1zICkKICAgICAgICBpbl90YWJsZSA9IDAKCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoIG4gKToKICAgICAgICAgICAgaXRlbSAgPSBzZWxmLml0ZW1zW2ldCiAgICAgICAgICAgIGZpZWxkID0gaXRlbVswXQoKICAgICAgICAgICAgaWYgbm90IGZpZWxkOgogICAgICAgICAgICAgICAgaWYgaXRlbVsxXToKICAgICAgICAgICAgICAgICAgICBwcmludCAiPHRyPjx0ZCBjb2xzcGFuPTI+IgogICAgICAgICAgICAgICAgICAgIGZvciBlbGVtZW50IGluIGl0ZW1bMV06CiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuZHVtcF9odG1sKCBpZGVudGlmaWVycyApCiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIjwvdGQ+PC90cj4iCgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcHJpbnQgIjx0cj48dGQ+PGI+IiArIGZpZWxkICsgIjwvYj48L3RkPjx0ZD4iCgogICAgICAgICAgICAgICAgZm9yIGVsZW1lbnQgaW4gaXRlbVsxXToKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmR1bXBfaHRtbCggaWRlbnRpZmllcnMgKQoKICAgICAgICAgICAgICAgIHByaW50ICI8L3RkPjwvdHI+IgoKCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojCiMgVGhlIERvY0Jsb2NrIGNsYXNzIGlzIHVzZWQgdG8gc3RvcmUgYSBnaXZlbiBjb21tZW50IGJsb2NrLiAgSXQgY29udGFpbnMKIyBhIGxpc3Qgb2YgbWFya2VycywgYXMgd2VsbCBhcyBhIGxpc3Qgb2YgY29udGVudHMgZm9yIGVhY2ggbWFya2VyLgojCiMgICAic2VsZi5pdGVtcyIgaXMgYSBsaXN0IG9mIChtYXJrZXIsIGNvbnRlbnRzKSBlbGVtZW50cywgd2hlcmUgJ21hcmtlcicgaXMKIyAgIGEgbG93ZXJjYXNlIG1hcmtlciBzdHJpbmcsIGFuZCAnY29udGVudHMnIGlzIGEgRG9jQ29udGVudCBvYmplY3QuCiMKIyAgICJzZWxmLnNvdXJjZSIgaXMgc2ltcGx5IGEgbGlzdCBvZiB0ZXh0IGxpbmVzIHRha2VuIGZyb20gdGhlIHVuY29tbWVudGVkCiMgICBzb3VyY2UgaXRzZWxmLgojCiMgICBGaW5hbGx5LCAic2VsZi5uYW1lIiBpcyBhIHNpbXBsZSBpZGVudGlmaWVyIHVzZWQgdG8gdW5pcXVlbHkgaWRlbnRpZnkKIyAgIHRoZSBibG9jay4gSXQgaXMgdGFrZW4gZnJvbSB0aGUgZmlyc3Qgd29yZCBvZiB0aGUgZmlyc3QgcGFyYWdyYXBoIG9mIHRoZQojICAgZmlyc3QgbWFya2VyIG9mIGEgZ2l2ZW4gYmxvY2ssIGkuZToKIwojICAgICAgPFR5cGU+IEdvbwojICAgICAgPERlc2NyaXB0aW9uPiBCbGEgYmxhIGJsYQojCiMgICB3aWxsIGhhdmUgYSBuYW1lIG9mICJHb28iCiMKY2xhc3MgRG9jQmxvY2s6CgogICAgZGVmIF9faW5pdF9fKCBzZWxmLCBibG9ja19saW5lX2xpc3QgPSBbXSwgc291cmNlX2xpbmVfbGlzdCA9IFtdICk6CiAgICAgICAgc2VsZi5pdGVtcyAgICA9IFtdICAgICAgICAgICAgICAgIyBjdXJyZW50ICggbWFya2VyLCBjb250ZW50cyApIGxpc3QKICAgICAgICBzZWxmLnNlY3Rpb24gID0gTm9uZSAgICAgICAgICAgICAjIHNlY3Rpb24gdGhpcyBibG9jayBiZWxvbmdzIHRvCiAgICAgICAgc2VsZi5maWxlbmFtZSA9ICJ1bmtub3duIiAgICAgICAgIyBmaWxlbmFtZSBkZWZpbmluZyB0aGlzIGJsb2NrCiAgICAgICAgc2VsZi5saW5lbm8gICA9IDAgICAgICAgICAgICAgICAgIyBsaW5lIG51bWJlciBpbiBmaWxlbmFtZQoKICAgICAgICBtYXJrZXIgICAgICAgID0gTm9uZSAgICAgICAgICAgICAjIGN1cnJlbnQgbWFya2VyCiAgICAgICAgY29udGVudCAgICAgICA9IFtdICAgICAgICAgICAgICAgIyBjdXJyZW50IGNvbnRlbnQgbGluZXMgbGlzdAogICAgICAgIGFscGhhbnVtICAgICAgPSBzdHJpbmcubGV0dGVycyArIHN0cmluZy5kaWdpdHMgKyAiXyIKICAgICAgICBzZWxmLm5hbWUgICAgID0gTm9uZQoKICAgICAgICBmb3IgbGluZSBpbiBibG9ja19saW5lX2xpc3Q6CiAgICAgICAgICAgIGxpbmUyICA9IHN0cmluZy5sc3RyaXAoIGxpbmUgKQogICAgICAgICAgICBsICAgICAgPSBsZW4oIGxpbmUyICkKICAgICAgICAgICAgbWFyZ2luID0gbGVuKCBsaW5lICkgLSBsCgogICAgICAgICAgICBpZiBsID4gMzoKICAgICAgICAgICAgICAgIGVuZGVyID0gTm9uZQogICAgICAgICAgICAgICAgaWYgbGluZTJbMF0gPT0gJzwnOgogICAgICAgICAgICAgICAgICAgIGVuZGVyID0gJz4nCiAgICAgICAgICAgICAgICBlbGlmIGxpbmUyWzBdID09ICdAJzoKICAgICAgICAgICAgICAgICAgICBlbmRlciA9ICc6JwoKICAgICAgICAgICAgICAgIGlmIGVuZGVyOgogICAgICAgICAgICAgICAgICAgIGkgPSAxCiAgICAgICAgICAgICAgICAgICAgd2hpbGUgaSA8IGwgYW5kIGxpbmUyW2ldIGluIGFscGhhbnVtOgogICAgICAgICAgICAgICAgICAgICAgICBpID0gaSArIDEKICAgICAgICAgICAgICAgICAgICBpZiBpIDwgbCBhbmQgbGluZTJbaV0gPT0gZW5kZXI6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG1hcmtlciBhbmQgY29udGVudDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYWRkKCBtYXJrZXIsIGNvbnRlbnQgKQogICAgICAgICAgICAgICAgICAgICAgICBtYXJrZXIgID0gbGluZTJbMSA6IGldCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBbXQogICAgICAgICAgICAgICAgICAgICAgICBsaW5lMiAgID0gc3RyaW5nLmxzdHJpcCggbGluZTJbaSsxIDpdICkKICAgICAgICAgICAgICAgICAgICAgICAgbCAgICAgICA9IGxlbiggbGluZTIgKQogICAgICAgICAgICAgICAgICAgICAgICBsaW5lICAgID0gIiAiICogbWFyZ2luICsgbGluZTIKCiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kKCBsaW5lICkKCiAgICAgICAgaWYgbWFya2VyIGFuZCBjb250ZW50OgogICAgICAgICAgICBzZWxmLmFkZCggbWFya2VyLCBjb250ZW50ICkKCiAgICAgICAgc2VsZi5zb3VyY2UgPSBbXQogICAgICAgIGlmIHNlbGYuaXRlbXM6CiAgICAgICAgICAgIHNlbGYuc291cmNlID0gc291cmNlX2xpbmVfbGlzdAoKICAgICAgICAjIG5vdyByZXRyaWV2ZSBibG9jayBuYW1lIHdoZW4gcG9zc2libGUKICAgICAgICAjCiAgICAgICAgaWYgc2VsZi5pdGVtczoKICAgICAgICAgICAgZmlyc3QgICAgID0gc2VsZi5pdGVtc1swXQogICAgICAgICAgICBzZWxmLm5hbWUgPSBmaXJzdFsxXS5nZXRfaWRlbnRpZmllcigpCgoKICAgICMgVGhpcyBmdW5jdGlvbiBhZGRzIGEgbmV3IGVsZW1lbnQgdG8gJ3NlbGYuaXRlbXMnLgogICAgIwogICAgIyAgICdtYXJrZXInIGlzIGEgbWFya2VyIHN0cmluZywgb3IgTm9uZS4KICAgICMgICAnbGluZXMnICBpcyBhIGxpc3Qgb2YgdGV4dCBsaW5lcyB1c2VkIHRvIGNvbXB1dGUgYSBsaXN0IG9mCiAgICAjICAgICAgICAgICAgRG9jQ29udGVudCBvYmplY3RzLgogICAgIwogICAgZGVmIGFkZCggc2VsZiwgbWFya2VyLCBsaW5lcyApOgogICAgICAgICMgcmVtb3ZlIHRoZSBmaXJzdCBhbmQgbGFzdCBlbXB0eSBsaW5lcyBmcm9tIHRoZSBjb250ZW50IGxpc3QKICAgICAgICAjCiAgICAgICAgbCA9IGxlbiggbGluZXMgKQogICAgICAgIGlmIGwgPiAwOgogICAgICAgICAgICBpID0gMAogICAgICAgICAgICB3aGlsZSBsID4gMCBhbmQgc3RyaW5nLnN0cmlwKCBsaW5lc1tsIC0gMV0gKSA9PSAiIjoKICAgICAgICAgICAgICAgIGwgPSBsIC0gMQogICAgICAgICAgICB3aGlsZSBpIDwgbCBhbmQgc3RyaW5nLnN0cmlwKCBsaW5lc1tpXSApID09ICIiOgogICAgICAgICAgICAgICAgaSA9IGkgKyAxCiAgICAgICAgICAgIGxpbmVzID0gbGluZXNbaSA6IGxdCiAgICAgICAgICAgIGwgICAgID0gbGVuKCBsaW5lcyApCgogICAgICAgICMgYWRkIGEgbmV3IG1hcmtlciBvbmx5IGlmIGl0cyBtYXJrZXIgYW5kIGl0cyBjb250ZW50IGxpc3QKICAgICAgICAjIGFyZSBub3QgZW1wdHkKICAgICAgICAjCiAgICAgICAgaWYgbCA+IDAgYW5kIG1hcmtlcjoKICAgICAgICAgICAgY29udGVudCA9IERvY0NvbnRlbnQoIGxpbmVzICkKICAgICAgICAgICAgc2VsZi5pdGVtcy5hcHBlbmQoICggc3RyaW5nLmxvd2VyKCBtYXJrZXIgKSwgY29udGVudCApICkKCgogICAgZGVmIGZpbmRfY29udGVudCggc2VsZiwgbWFya2VyICk6CiAgICAgICAgZm9yIGl0ZW0gaW4gc2VsZi5pdGVtczoKICAgICAgICAgICAgaWYgKCBpdGVtWzBdID09IG1hcmtlciApOgogICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW1bMV0KICAgICAgICByZXR1cm4gTm9uZQoKCiAgICBkZWYgaHRtbF9hZGRyZXNzKCBzZWxmICk6CiAgICAgICAgc2VjdGlvbiA9IHNlbGYuc2VjdGlvbgogICAgICAgIGlmIHNlY3Rpb24gYW5kIHNlY3Rpb24uZmlsZW5hbWU6CiAgICAgICAgICAgIHJldHVybiBzZWN0aW9uLmZpbGVuYW1lICsgJyMnICsgc2VsZi5uYW1lCgogICAgICAgIHJldHVybiAiIiAgIyB0aGlzIGJsb2NrIGlzIG5vdCBpbiBhIHNlY3Rpb24/CgoKICAgIGRlZiBsb2NhdGlvbiggc2VsZiApOgogICAgICAgIHJldHVybiBzZWxmLmZpbGVuYW1lICsgJzonICsgc3RyKCBzZWxmLmxpbmVubyApCgoKICAgIGRlZiBwcmludF93YXJuaW5nKCBzZWxmLCBtZXNzYWdlICk6CiAgICAgICAgc3lzLnN0ZGVyci53cml0ZSggIldBUk5JTkc6IiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sb2NhdGlvbigpICsgIjogIiArIG1lc3NhZ2UgKyAnXG4nICkKCgogICAgZGVmIHByaW50X2Vycm9yKCBzZWxmLCBtZXNzYWdlICk6CiAgICAgICAgc3lzLnN0ZGVyci53cml0ZSggIkVSUk9SOiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubG9jYXRpb24oKSArICI6ICIgKyBtZXNzYWdlICsgJ1xuJyApCiAgICAgICAgc3lzLmV4aXQoKQoKCiAgICBkZWYgZHVtcCggc2VsZiApOgogICAgICAgIGZvciBpIGluIHJhbmdlKCBsZW4oIHNlbGYuaXRlbXMgKSApOgogICAgICAgICAgICBwcmludCAiWyIgKyBzZWxmLml0ZW1zW2ldWzBdICsgIl0iCiAgICAgICAgICAgIGNvbnRlbnQgPSBzZWxmLml0ZW1zW2ldWzFdCiAgICAgICAgICAgIGNvbnRlbnQuZHVtcCgpCgoKICAgIGRlZiBkdW1wX2h0bWwoIHNlbGYsIGlkZW50aWZpZXJzID0gTm9uZSApOgogICAgICAgIHR5cGVzICAgICAgPSBbJ3R5cGUnLCAnc3RydWN0JywgJ2Z1bmN0eXBlJywgJ2Z1bmN0aW9uJywKICAgICAgICAgICAgICAgICAgICAgICdjb25zdGFudCcsICdlbnVtJywgJ21hY3JvJywgJ3N0cnVjdHVyZScsICdhbHNvJ10KCiAgICAgICAgcGFyYW1ldGVycyA9IFsnaW5wdXQnLCAnaW5vdXQnLCAnb3V0cHV0JywgJ3JldHVybiddCgogICAgICAgIGlmIG5vdCBzZWxmLml0ZW1zOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgIyBzdGFydCBvZiBhIGJsb2NrCiAgICAgICAgIwogICAgICAgIHByaW50IGJsb2NrX2hlYWRlcgoKICAgICAgICAjIHBsYWNlIGh0bWwgYW5jaG9yIGlmIG5lZWRlZAogICAgICAgICMKICAgICAgICBpZiBzZWxmLm5hbWU6CiAgICAgICAgICAgIHByaW50ICc8YSBuYW1lPSInICsgc2VsZi5uYW1lICsgJyI+JwogICAgICAgICAgICBwcmludCAiPGg0PiIgKyBzZWxmLm5hbWUgKyAiPC9oND4iCiAgICAgICAgICAgIHByaW50ICI8L2E+IgoKICAgICAgICAjIHByaW50IHNvdXJjZSBjb2RlCiAgICAgICAgIwogICAgICAgIGlmIG5vdCBzZWxmLnNvdXJjZToKICAgICAgICAgICAgcHJpbnQgYmxvY2tfZm9vdGVyCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBsaW5lcyA9IHNlbGYuc291cmNlCiAgICAgICAgbCAgICAgPSBsZW4oIGxpbmVzICkgLSAxCiAgICAgICAgd2hpbGUgbCA+PSAwIGFuZCBzdHJpbmcuc3RyaXAoIGxpbmVzW2xdICkgPT0gIiI6CiAgICAgICAgICAgIGwgPSBsIC0gMQogICAgICAgIHByaW50IHNvdXJjZV9oZWFkZXIKICAgICAgICBwcmludCAiIgogICAgICAgIGZvciBsaW5lIGluIGxpbmVzWzAgOiBsKzFdOgogICAgICAgICAgICBwcmludCBodG1sX3F1b3RlKGxpbmUpCiAgICAgICAgcHJpbnQgc291cmNlX2Zvb3RlcgoKICAgICAgICBpbl90YWJsZSA9IDAKCiAgICAgICAgIyBkdW1wIGVhY2ggKG1hcmtlcixjb250ZW50KSBlbGVtZW50CiAgICAgICAgIwogICAgICAgIGZvciBlbGVtZW50IGluIHNlbGYuaXRlbXM6CiAgICAgICAgICAgIG1hcmtlciAgPSBlbGVtZW50WzBdCiAgICAgICAgICAgIGNvbnRlbnQgPSBlbGVtZW50WzFdCgogICAgICAgICAgICBpZiBtYXJrZXIgPT0gImRlc2NyaXB0aW9uIjoKICAgICAgICAgICAgICAgIHByaW50IGRlc2NyaXB0aW9uX2hlYWRlcgogICAgICAgICAgICAgICAgY29udGVudC5kdW1wX2h0bWwoIGlkZW50aWZpZXJzICkKICAgICAgICAgICAgICAgIHByaW50IGRlc2NyaXB0aW9uX2Zvb3RlcgoKICAgICAgICAgICAgZWxpZiBub3QgKCBtYXJrZXIgaW4gdHlwZXMgKToKICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoIG1hcmtlcl9oZWFkZXIgKQogICAgICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZSggbWFya2VyICkKICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoIG1hcmtlcl9pbnRlciArICdcbicgKQogICAgICAgICAgICAgICAgY29udGVudC5kdW1wX2h0bWwoIGlkZW50aWZpZXJzICkKICAgICAgICAgICAgICAgIHByaW50IG1hcmtlcl9mb290ZXIKCiAgICAgICAgcHJpbnQgIiIKCiAgICAgICAgcHJpbnQgYmxvY2tfZm9vdGVyCgoKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMKIyBUaGUgRG9jU2VjdGlvbiBjbGFzcyBpcyB1c2VkIHRvIHN0b3JlIGEgZ2l2ZW4gZG9jdW1lbnRhdGlvbiBzZWN0aW9uLgojCiMgRWFjaCBzZWN0aW9uIGlzIG1hZGUgb2YgYW4gaWRlbnRpZmllciwgYW4gYWJzdHJhY3QgYW5kIGEgZGVzY3JpcHRpb24uCiMKIyBGb3IgZXhhbXBsZSwgbG9vayBhdDoKIwojICAgPFNlY3Rpb24+IEJhc2ljX0RhdGFfVHlwZXMKIwojICAgPFRpdGxlPiBGcmVlVHlwZSAyIEJhc2ljIERhdGEgVHlwZXMKIwojICAgPEFic3RyYWN0PgojICAgICAgRGVmaW5pdGlvbnMgb2YgYmFzaWMgRnJlZVR5cGUgZGF0YSB0eXBlcwojCiMgICA8RGVzY3JpcHRpb24+CiMgICAgICBGcmVlVHlwZSBkZWZpbmVzIHNldmVyYWwgYmFzaWMgZGF0YSB0eXBlcyBmb3IgYWxsIGl0cwojICAgICAgb3BlcmF0aW9ucy4uLgojCmNsYXNzIERvY1NlY3Rpb246CgogICAgZGVmIF9faW5pdF9fKCBzZWxmLCBibG9jayApOgogICAgICAgIHNlbGYuYmxvY2sgICAgICAgPSBibG9jawogICAgICAgIHNlbGYubmFtZSAgICAgICAgPSBzdHJpbmcubG93ZXIoIGJsb2NrLm5hbWUgKQogICAgICAgIHNlbGYuYWJzdHJhY3QgICAgPSBibG9jay5maW5kX2NvbnRlbnQoICJhYnN0cmFjdCIgKQogICAgICAgIHNlbGYuZGVzY3JpcHRpb24gPSBibG9jay5maW5kX2NvbnRlbnQoICJkZXNjcmlwdGlvbiIgKQogICAgICAgIHNlbGYuZWxlbWVudHMgICAgPSB7fQogICAgICAgIHNlbGYubGlzdCAgICAgICAgPSBbXQogICAgICAgIHNlbGYuZmlsZW5hbWUgICAgPSBzZWxmLm5hbWUgKyAiLmh0bWwiCiAgICAgICAgc2VsZi5jaGFwdGVyICAgICA9IE5vbmUKCiAgICAgICAgIyBzeXMuc3RkZXJyLndyaXRlKCAibmV3IHNlY3Rpb24gJyIgKyBzZWxmLm5hbWUgKyAiJyIgKQoKCiAgICBkZWYgYWRkX2VsZW1lbnQoIHNlbGYsIGJsb2NrICk6CiAgICAgICAgIyBjaGVjayB0aGF0IHdlIGRvbid0IGhhdmUgYSBkdXBsaWNhdGUgZWxlbWVudCBpbiB0aGlzCiAgICAgICAgIyBzZWN0aW9uCiAgICAgICAgIwogICAgICAgIGlmIHNlbGYuZWxlbWVudHMuaGFzX2tleSggYmxvY2submFtZSApOgogICAgICAgICAgICBibG9jay5wcmludF9lcnJvciggImR1cGxpY2F0ZSBlbGVtZW50IGRlZmluaXRpb24gZm9yICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiciICsgYmxvY2submFtZSArICInICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImluIHNlY3Rpb24gIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJyIgKyBzZWxmLm5hbWUgKyAiJ1xuIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicHJldmlvdXMgZGVmaW5pdGlvbiBpbiAiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICInIiArIHNlbGYuZWxlbWVudHNbYmxvY2submFtZV0ubG9jYXRpb24oKSArICInIiApCgogICAgICAgIHNlbGYuZWxlbWVudHNbYmxvY2submFtZV0gPSBibG9jawogICAgICAgIHNlbGYubGlzdC5hcHBlbmQoIGJsb2NrICkKCgogICAgZGVmIHByaW50X3dhcm5pbmcoIHNlbGYsIG1lc3NhZ2UgKToKICAgICAgICBzZWxmLmJsb2NrLnByaW50X3dhcm5pbmcoIG1lc3NhZ2UgKQoKCiAgICBkZWYgcHJpbnRfZXJyb3IoIHNlbGYsIG1lc3NhZ2UgKToKICAgICAgICBzZWxmLmJsb2NrLnByaW50X2Vycm9yKCBtZXNzYWdlICkKCgogICAgZGVmIGR1bXBfaHRtbCggc2VsZiwgaWRlbnRpZmllcnMgPSBOb25lICk6CiAgICAgICAgIiIibWFrZSBhbiBIVE1MIHBhZ2UgZnJvbSBhIGdpdmVuIERvY1NlY3Rpb24iIiIKCiAgICAgICAgIyBwcmludCBIVE1MIGhlYWRlcgogICAgICAgICMKICAgICAgICBwcmludCBodG1sX2hlYWRlcgoKICAgICAgICAjIHByaW50IHRpdGxlCiAgICAgICAgIwogICAgICAgIHByaW50IHNlY3Rpb25fdGl0bGVfaGVhZGVyCiAgICAgICAgcHJpbnQgc2VsZi50aXRsZQogICAgICAgIHByaW50IHNlY3Rpb25fdGl0bGVfZm9vdGVyCgogICAgICAgICMgcHJpbnQgZGVzY3JpcHRpb24KICAgICAgICAjCiAgICAgICAgcHJpbnQgYmxvY2tfaGVhZGVyCiAgICAgICAgc2VsZi5kZXNjcmlwdGlvbi5kdW1wX2h0bWwoIGlkZW50aWZpZXJzICkKICAgICAgICBwcmludCBibG9ja19mb290ZXIKCiAgICAgICAgIyBwcmludCBlbGVtZW50cwogICAgICAgICMKICAgICAgICBmb3IgZWxlbWVudCBpbiBzZWxmLmxpc3Q6CiAgICAgICAgICAgIGVsZW1lbnQuZHVtcF9odG1sKCBpZGVudGlmaWVycyApCgogICAgICAgIHByaW50IGh0bWxfZm9vdGVyCgoKY2xhc3MgRG9jU2VjdGlvbkxpc3Q6CgogICAgZGVmIF9faW5pdF9fKCBzZWxmICk6CiAgICAgICAgc2VsZi5zZWN0aW9ucyAgICAgICAgPSB7fSAgICAjIG1hcCBzZWN0aW9uIG5hbWVzIHRvIHNlY3Rpb24gb2JqZWN0cwogICAgICAgIHNlbGYubGlzdCAgICAgICAgICAgID0gW10gICAgIyBsaXN0IG9mIHNlY3Rpb25zIChpbiBjcmVhdGlvbiBvcmRlcikKICAgICAgICBzZWxmLmN1cnJlbnRfc2VjdGlvbiA9IE5vbmUgICMgY3VycmVudCBzZWN0aW9uCiAgICAgICAgc2VsZi5pZGVudGlmaWVycyAgICAgPSB7fSAgICAjIG1hcCBpZGVudGlmaWVycyB0byBibG9ja3MKCgogICAgZGVmIGFwcGVuZF9zZWN0aW9uKCBzZWxmLCBibG9jayApOgogICAgICAgIG5hbWUgICAgID0gc3RyaW5nLmxvd2VyKCBibG9jay5uYW1lICkKICAgICAgICBhYnN0cmFjdCA9IGJsb2NrLmZpbmRfY29udGVudCggImFic3RyYWN0IiApCgogICAgICAgIGlmIHNlbGYuc2VjdGlvbnMuaGFzX2tleSggbmFtZSApOgogICAgICAgICAgICAjIFRoZXJlIGlzIGFscmVhZHkgYSBzZWN0aW9uIHdpdGggdGhpcyBuYW1lIGluIG91ciBsaXN0LiAgV2UKICAgICAgICAgICAgIyB3aWxsIHRyeSB0byBjb21wbGV0ZSBpdC4KICAgICAgICAgICAgIwogICAgICAgICAgICBzZWN0aW9uID0gc2VsZi5zZWN0aW9uc1tuYW1lXQogICAgICAgICAgICBpZiBzZWN0aW9uLmFic3RyYWN0OgogICAgICAgICAgICAgICAgIyBUaGlzIHNlY3Rpb24gYWxyZWFkeSBoYXMgYW4gYWJzdHJhY3QgZGVmaW5lZDsgc2ltcGx5IGNoZWNrCiAgICAgICAgICAgICAgICAjIHRoYXQgdGhlIG5ldyBzZWN0aW9uIGRvZXNuJ3QgcHJvdmlkZSBhIG5ldyBvbmUuCiAgICAgICAgICAgICAgICAjCiAgICAgICAgICAgICAgICBpZiBhYnN0cmFjdDoKICAgICAgICAgICAgICAgICAgICBzZWN0aW9uLmJsb2NrLnByaW50X2Vycm9yKAogICAgICAgICAgICAgICAgICAgICAgImR1cGxpY2F0ZSBzZWN0aW9uIGRlZmluaXRpb24gZm9yICIgKwogICAgICAgICAgICAgICAgICAgICAgIiciICsgbmFtZSArICInXG4iICsKICAgICAgICAgICAgICAgICAgICAgICJwcmV2aW91cyBkZWZpbml0aW9uIGluICIgKwogICAgICAgICAgICAgICAgICAgICAgIiciICsgc2VjdGlvbi5ibG9jay5sb2NhdGlvbigpICsgIidcbiIgKwogICAgICAgICAgICAgICAgICAgICAgInNlY29uZCBkZWZpbml0aW9uIGluICIgKwogICAgICAgICAgICAgICAgICAgICAgIiciICsgYmxvY2subG9jYXRpb24oKSArICInIiApCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIFRoZSBvbGQgc2VjdGlvbiBkaWRuJ3QgY29udGFpbiBhbiBhYnN0cmFjdDsgd2UgYXJlIG5vdwogICAgICAgICAgICAgICAgIyBnb2luZyB0byByZXBsYWNlIGl0LgogICAgICAgICAgICAgICAgIwogICAgICAgICAgICAgICAgc2VjdGlvbi5hYnN0cmFjdCAgICA9IGFic3RyYWN0CiAgICAgICAgICAgICAgICBzZWN0aW9uLmRlc2NyaXB0aW9uID0gYmxvY2suZmluZF9jb250ZW50KCAiZGVzY3JpcHRpb24iICkKICAgICAgICAgICAgICAgIHNlY3Rpb24uYmxvY2sgICAgICAgPSBibG9jawoKICAgICAgICBlbHNlOgogICAgICAgICAgICAjIGEgbmV3IHNlY3Rpb24KICAgICAgICAgICAgIwogICAgICAgICAgICBzZWN0aW9uID0gRG9jU2VjdGlvbiggYmxvY2sgKQogICAgICAgICAgICBzZWxmLnNlY3Rpb25zW25hbWVdID0gc2VjdGlvbgogICAgICAgICAgICBzZWxmLmxpc3QuYXBwZW5kKCBzZWN0aW9uICkKCiAgICAgICAgc2VsZi5jdXJyZW50X3NlY3Rpb24gPSBzZWN0aW9uCgoKICAgIGRlZiBhcHBlbmRfYmxvY2soIHNlbGYsIGJsb2NrICk6CiAgICAgICAgaWYgYmxvY2submFtZToKICAgICAgICAgICAgc2VjdGlvbiA9IGJsb2NrLmZpbmRfY29udGVudCggInNlY3Rpb24iICkKICAgICAgICAgICAgaWYgc2VjdGlvbjoKICAgICAgICAgICAgICAgIHNlbGYuYXBwZW5kX3NlY3Rpb24oIGJsb2NrICkKCiAgICAgICAgICAgIGVsaWYgc2VsZi5jdXJyZW50X3NlY3Rpb246CiAgICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRfc2VjdGlvbi5hZGRfZWxlbWVudCggYmxvY2sgKQogICAgICAgICAgICAgICAgYmxvY2suc2VjdGlvbiAgICAgICAgICAgICAgICA9IHNlbGYuY3VycmVudF9zZWN0aW9uCiAgICAgICAgICAgICAgICBzZWxmLmlkZW50aWZpZXJzW2Jsb2NrLm5hbWVdID0gYmxvY2sKCgogICAgZGVmIHByZXBhcmVfZmlsZXMoIHNlbGYsIGZpbGVfcHJlZml4ID0gTm9uZSApOgogICAgICAgICMgcHJlcGFyZSB0aGUgc2VjdGlvbiBsaXN0LCBieSBjb21wdXRpbmcgc2VjdGlvbiBmaWxlbmFtZXMgYW5kIHRoZQogICAgICAgICMgaW5kZXgKICAgICAgICAjCiAgICAgICAgaWYgZmlsZV9wcmVmaXg6CiAgICAgICAgICAgIHByZWZpeCA9IGZpbGVfcHJlZml4ICsgIi0iCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcHJlZml4ID0gIiIKCiAgICAgICAgIyBjb21wdXRlIHNlY3Rpb24gbmFtZXMKICAgICAgICAjCiAgICAgICAgZm9yIHNlY3Rpb24gaW4gc2VsZi5zZWN0aW9ucy52YWx1ZXMoKToKICAgICAgICAgICAgdGl0bGVfY29udGVudCAgICAgPSBzZWN0aW9uLmJsb2NrLmZpbmRfY29udGVudCggInRpdGxlIiApCiAgICAgICAgICAgIGlmIHRpdGxlX2NvbnRlbnQ6CiAgICAgICAgICAgICAgICBzZWN0aW9uLnRpdGxlID0gdGl0bGVfY29udGVudC5nZXRfdGl0bGUoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VjdGlvbi50aXRsZSA9ICJVTktOT1dOX1NFQ1RJT05fVElUTEUhIgoKCiAgICAgICAgIyBzb3J0IHNlY3Rpb24gZWxlbWVudHMgYWNjb3JkaW5nIHRvIHRoZSA8b3JkZXI+IG1hcmtlciBpZiBhdmFpbGFibGUKICAgICAgICAjCiAgICAgICAgZm9yIHNlY3Rpb24gaW4gc2VsZi5zZWN0aW9ucy52YWx1ZXMoKToKICAgICAgICAgICAgb3JkZXIgPSBzZWN0aW9uLmJsb2NrLmZpbmRfY29udGVudCggIm9yZGVyIiApCiAgICAgICAgICAgIGlmIG9yZGVyOgogICAgICAgICAgICAgICAgIyBzeXMuc3RkZXJyLndyaXRlKCAiPG9yZGVyPiBmb3VuZCBhdCAiCiAgICAgICAgICAgICAgICAjICAgICAgICAgICAgICAgICAgICsgc2VjdGlvbi5ibG9jay5sb2NhdGlvbigpICsgJ1xuJyApCiAgICAgICAgICAgICAgICBvcmRlcl9saXN0ID0gW10KICAgICAgICAgICAgICAgIGZvciBpdGVtIGluIG9yZGVyLml0ZW1zOgogICAgICAgICAgICAgICAgICAgIGZvciBlbGVtZW50IGluIGl0ZW1bMV06CiAgICAgICAgICAgICAgICAgICAgICAgIHdvcmRzID0gTm9uZQogICAgICAgICAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JkcyA9IGVsZW1lbnQuZ2V0X3dvcmRzKCkKICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VjdGlvbi5ibG9jay5wcmludF93YXJuaW5nKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBjb250ZW50IGluIDxvcmRlcj4gbWFya2VyXG4iICkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgd29yZHM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3Igd29yZCBpbiB3b3JkczoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBibG9jayA9IHNlbGYuaWRlbnRpZmllcnMuZ2V0KCB3b3JkICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBibG9jazoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYmxvY2suc2VjdGlvbiA9PSBzZWN0aW9uOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJfbGlzdC5hcHBlbmQoIGJsb2NrICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY3Rpb24uYmxvY2sucHJpbnRfd2FybmluZygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgcmVmZXJlbmNlIHRvICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJyIgKyB3b3JkICsgIicgIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkZWZpbmVkIGluIG90aGVyIHNlY3Rpb24iICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWN0aW9uLmJsb2NrLnByaW50X3dhcm5pbmcoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgcmVmZXJlbmNlIHRvICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICInIiArIHdvcmQgKyAiJyIgKQoKICAgICAgICAgICAgICAgICMgbm93IHNvcnQgdGhlIGxpc3Qgb2YgYmxvY2tzIGFjY29yZGluZyB0byB0aGUgb3JkZXIgbGlzdAogICAgICAgICAgICAgICAgIwogICAgICAgICAgICAgICAgbmV3X2xpc3QgPSBvcmRlcl9saXN0WzpdCiAgICAgICAgICAgICAgICBmb3IgYmxvY2sgaW4gc2VjdGlvbi5saXN0OgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBibG9jayBpbiBvcmRlcl9saXN0OgogICAgICAgICAgICAgICAgICAgICAgICBuZXdfbGlzdC5hcHBlbmQoIGJsb2NrICkKCiAgICAgICAgICAgICAgICBzZWN0aW9uLmxpc3QgPSBuZXdfbGlzdAoKICAgICAgICAjIGNvbXB1dGUgc2VjdGlvbiBmaWxlbmFtZXMKICAgICAgICAjCiAgICAgICAgZm9yIHNlY3Rpb24gaW4gc2VsZi5zZWN0aW9ucy52YWx1ZXMoKToKICAgICAgICAgICAgc2VjdGlvbi5maWxlbmFtZSA9IHByZWZpeCArIHNlY3Rpb24ubmFtZSArICIuaHRtbCIKCiAgICAgICAgc2VsZi50b2NfZmlsZW5hbWUgICA9IHByZWZpeCArICJ0b2MuaHRtbCIKICAgICAgICBzZWxmLmluZGV4X2ZpbGVuYW1lID0gcHJlZml4ICsgImluZGV4Lmh0bWwiCgogICAgICAgICMgY29tcHV0ZSB0aGUgc29ydGVkIGxpc3Qgb2YgaWRlbnRpZmllcnMgZm9yIHRoZSBpbmRleAogICAgICAgICMKICAgICAgICBzZWxmLmluZGV4ID0gc2VsZi5pZGVudGlmaWVycy5rZXlzKCkKICAgICAgICBzZWxmLmluZGV4LnNvcnQoIGluZGV4X3NvcnQgKQoKCiAgICBkZWYgZHVtcF9odG1sX3NlY3Rpb25zKCBzZWxmICk6CiAgICAgICAgZm9yIHNlY3Rpb24gaW4gc2VsZi5zZWN0aW9ucy52YWx1ZXMoKToKICAgICAgICAgICAgaWYgc2VjdGlvbi5maWxlbmFtZToKICAgICAgICAgICAgICAgIG91dHB1dCA9IG9wZW5fb3V0cHV0KCBzZWN0aW9uLmZpbGVuYW1lICkKCiAgICAgICAgICAgICAgICBzZWN0aW9uLmR1bXBfaHRtbCggc2VsZi5pZGVudGlmaWVycyApCgogICAgICAgICAgICAgICAgY2xvc2Vfb3V0cHV0KCBvdXRwdXQgKQoKCiAgICBkZWYgZHVtcF9odG1sX2luZGV4KCBzZWxmICk6CiAgICAgICAgb3V0cHV0ID0gb3Blbl9vdXRwdXQoIHNlbGYuaW5kZXhfZmlsZW5hbWUgKQoKICAgICAgICBudW1fY29sdW1ucyA9IDMKICAgICAgICB0b3RhbCAgICAgICA9IGxlbiggc2VsZi5pbmRleCApCiAgICAgICAgbGluZSAgICAgICAgPSAwCgogICAgICAgIHByaW50IGh0bWxfaGVhZGVyCiAgICAgICAgcHJpbnQgIjxjZW50ZXI+PGgxPkdlbmVyYWwgSW5kZXg8L2gxPjwvY2VudGVyPiIKICAgICAgICBwcmludCAiPGNlbnRlcj48dGFibGUgY2VsbHBhZGRpbmc9NT48dHIgdmFsaWduPXRvcD48dGQ+IgoKICAgICAgICBmb3IgaWRlbnQgaW4gc2VsZi5pbmRleDoKICAgICAgICAgICAgYmxvY2sgPSBzZWxmLmlkZW50aWZpZXJzW2lkZW50XQogICAgICAgICAgICBpZiBibG9jazoKICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoICc8YSBocmVmPSInICsgYmxvY2suaHRtbF9hZGRyZXNzKCkgKyAnIj4nICkKICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoIGJsb2NrLm5hbWUgKQogICAgICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZSggJzwvYT48YnI+JyArICdcbicgKQoKICAgICAgICAgICAgICAgIGlmIGxpbmUgKiBudW1fY29sdW1ucyA+PSB0b3RhbDoKICAgICAgICAgICAgICAgICAgICBwcmludCAiPC90ZD48dGQ+IgogICAgICAgICAgICAgICAgICAgIGxpbmUgPSAwCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGxpbmUgPSBsaW5lICsgMQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc3lzLnN0ZGVyci53cml0ZSggImlkZW50aWZpZXIgJyIgKyBpZGVudCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJyBoYXMgbm8gZGVmaW5pdGlvbiIgKyAnXG4nICkKCiAgICAgICAgcHJpbnQgIjwvdHI+PC90YWJsZT48L2NlbnRlcj4iCiAgICAgICAgcHJpbnQgaHRtbF9mb290ZXIKCiAgICAgICAgY2xvc2Vfb3V0cHV0KCBvdXRwdXQgKQoKCgojIEZpbHRlciBhIGdpdmVuIGxpc3Qgb2YgRG9jQmxvY2tzLiAgUmV0dXJucyBhIG5ldyBsaXN0IG9mIERvY0Jsb2NrIG9iamVjdHMKIyB0aGF0IG9ubHkgY29udGFpbnMgZWxlbWVudCB3aG9zZSAidHlwZSIgKGkuZS4gZmlyc3QgbWFya2VyKSBpcyBpbiB0aGUKIyAidHlwZXMiIHBhcmFtZXRlci4KIwpjbGFzcyBEb2NDaGFwdGVyOgoKICAgIGRlZiBfX2luaXRfXyggc2VsZiwgYmxvY2sgKToKICAgICAgICBzZWxmLnNlY3Rpb25zX25hbWVzID0gW10gICAgIyBvcmRlcmVkIGxpc3Qgb2Ygc2VjdGlvbiBuYW1lcwogICAgICAgIHNlbGYuc2VjdGlvbnMgICAgICAgPSBbXSAgICAjIG9yZGVyZWQgbGlzdCBvZiBEb2NTZWN0aW9uIG9iamVjdHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBmb3IgdGhpcyBjaGFwdGVyCiAgICAgICAgc2VsZi5ibG9jayAgICAgICAgICA9IGJsb2NrCgogICAgICAgICMgbG9vayBmb3IgY2hhcHRlciB0aXRsZQogICAgICAgIGNvbnRlbnQgPSBibG9jay5maW5kX2NvbnRlbnQoICJ0aXRsZSIgKQogICAgICAgIGlmIGNvbnRlbnQ6CiAgICAgICAgICAgIHNlbGYudGl0bGUgPSBjb250ZW50LmdldF90aXRsZSgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi50aXRsZSA9ICJVTktOT1dOIENIQVBURVIgVElUTEUiCgogICAgICAgICMgbG9vayBmb3Igc2VjdGlvbiBsaXN0CiAgICAgICAgY29udGVudCA9IGJsb2NrLmZpbmRfY29udGVudCggInNlY3Rpb25zIiApCiAgICAgICAgaWYgbm90IGNvbnRlbnQ6CiAgICAgICAgICAgIGJsb2NrLnByaW50X2Vycm9yKCAiY2hhcHRlciBoYXMgbm8gPHNlY3Rpb25zPiBjb250ZW50IiApCgogICAgICAgICMgY29tcHV0ZSBsaXN0IG9mIHNlY3Rpb24gbmFtZXMKICAgICAgICBzbGlzdCA9IFtdCiAgICAgICAgZm9yIGl0ZW0gaW4gY29udGVudC5pdGVtczoKICAgICAgICAgICAgZm9yIGVsZW1lbnQgaW4gaXRlbVsxXToKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICB3b3JkcyAgICAgICAgPSBlbGVtZW50LmdldF93b3JkcygpCiAgICAgICAgICAgICAgICAgICAgbCAgICAgICAgICAgID0gbGVuKCBzbGlzdCApCiAgICAgICAgICAgICAgICAgICAgc2xpc3RbbCA6IGxdID0gd29yZHMKICAgICAgICAgICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgICAgICAgICBibG9jay5wcmludF93YXJuaW5nKAogICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgY29udGVudCBpbiA8c2VjdGlvbnM+IG1hcmtlciIgKQoKICAgICAgICBzZWxmLnNlY3Rpb25fbmFtZXMgPSBzbGlzdAoKCmNsYXNzIERvY0RvY3VtZW50OgoKICAgIGRlZiBfX2luaXRfXyggc2VsZiApOgogICAgICAgIHNlbGYuc2VjdGlvbl9saXN0ICA9IERvY1NlY3Rpb25MaXN0KCkgICAjIHNlY3Rpb24gbGlzdCBvYmplY3QKICAgICAgICBzZWxmLmNoYXB0ZXJzICAgICAgPSBbXSAgICAgICAgICAgICAgICAgIyBsaXN0IG9mIGNoYXB0ZXJzCiAgICAgICAgc2VsZi5sb3N0X3NlY3Rpb25zID0gW10gICAgICAgICAgICAgICAgICMgbGlzdCBvZiBzZWN0aW9ucyB3aXRoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbm8gY2hhcHRlcgoKICAgIGRlZiBhcHBlbmRfYmxvY2soIHNlbGYsIGJsb2NrICk6CiAgICAgICAgaWYgYmxvY2submFtZToKICAgICAgICAgICAgY29udGVudCA9IGJsb2NrLmZpbmRfY29udGVudCggImNoYXB0ZXIiICkKICAgICAgICAgICAgaWYgY29udGVudDoKICAgICAgICAgICAgICAgICMgYSBjaGFwdGVyIGRlZmluaXRpb24gLS0gYWRkIGl0IHRvIG91ciBsaXN0CiAgICAgICAgICAgICAgICAjCiAgICAgICAgICAgICAgICBjaGFwdGVyID0gRG9jQ2hhcHRlciggYmxvY2sgKQogICAgICAgICAgICAgICAgc2VsZi5jaGFwdGVycy5hcHBlbmQoIGNoYXB0ZXIgKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5zZWN0aW9uX2xpc3QuYXBwZW5kX2Jsb2NrKCBibG9jayApCgoKICAgIGRlZiBwcmVwYXJlX2NoYXB0ZXJzKCBzZWxmICk6CiAgICAgICAgIyBjaGVjayBzZWN0aW9uIG5hbWVzCiAgICAgICAgIwogICAgICAgIGZvciBjaGFwdGVyIGluIHNlbGYuY2hhcHRlcnM6CiAgICAgICAgICAgIHNsaXN0ID0gW10KICAgICAgICAgICAgZm9yIG5hbWUgaW4gY2hhcHRlci5zZWN0aW9uX25hbWVzOgogICAgICAgICAgICAgICAgIHNlY3Rpb24gPSBzZWxmLnNlY3Rpb25fbGlzdC5zZWN0aW9ucy5nZXQoIG5hbWUgKQogICAgICAgICAgICAgICAgIGlmIG5vdCBzZWN0aW9uOgogICAgICAgICAgICAgICAgICAgICBjaGFwdGVyLmJsb2NrLnByaW50X3dhcm5pbmcoCiAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgcmVmZXJlbmNlIHRvIHVua25vd24gc2VjdGlvbiAnIiArIG5hbWUgKyAiJyIgKQogICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgIHNlY3Rpb24uY2hhcHRlciA9IGNoYXB0ZXIKICAgICAgICAgICAgICAgICAgICAgc2xpc3QuYXBwZW5kKCBzZWN0aW9uICkKCiAgICAgICAgICAgIGNoYXB0ZXIuc2VjdGlvbnMgPSBzbGlzdAoKICAgICAgICBmb3Igc2VjdGlvbiBpbiBzZWxmLnNlY3Rpb25fbGlzdC5saXN0OgogICAgICAgICAgICBpZiBub3Qgc2VjdGlvbi5jaGFwdGVyOgogICAgICAgICAgICAgICAgc2VjdGlvbi5ibG9jay5wcmludF93YXJuaW5nKAogICAgICAgICAgICAgICAgICAic2VjdGlvbiAnIiArIHNlY3Rpb24ubmFtZSArICInIGlzIG5vdCBpbiBhbnkgY2hhcHRlciIgKQogICAgICAgICAgICAgICAgc2VsZi5sb3N0X3NlY3Rpb25zLmFwcGVuZCggc2VjdGlvbiApCgoKICAgIGRlZiBwcmVwYXJlX2ZpbGVzKCBzZWxmLCBmaWxlX3ByZWZpeCA9IE5vbmUgKToKICAgICAgICBzZWxmLnNlY3Rpb25fbGlzdC5wcmVwYXJlX2ZpbGVzKCBmaWxlX3ByZWZpeCApCiAgICAgICAgc2VsZi5wcmVwYXJlX2NoYXB0ZXJzKCkKCgogICAgZGVmIGR1bXBfdG9jX2h0bWwoIHNlbGYgKToKICAgICAgICAjIGR1bXAgYW4gaHRtbCB0YWJsZSBvZiBjb250ZW50cwogICAgICAgICMKICAgICAgICBvdXRwdXQgPSBvcGVuX291dHB1dCggc2VsZi5zZWN0aW9uX2xpc3QudG9jX2ZpbGVuYW1lICkKCiAgICAgICAgcHJpbnQgaHRtbF9oZWFkZXIKCiAgICAgICAgcHJpbnQgIjxjZW50ZXI+PGgxPlRhYmxlIG9mIENvbnRlbnRzPC9oMT48L2NlbnRlcj4iCgogICAgICAgIGZvciBjaGFwdGVyIGluIHNlbGYuY2hhcHRlcnM6CiAgICAgICAgICAgIHByaW50IGNoYXB0ZXJfaGVhZGVyICsgY2hhcHRlci50aXRsZSArIGNoYXB0ZXJfaW50ZXIKCiAgICAgICAgICAgIHByaW50ICI8dGFibGUgY2VsbHBhZGRpbmc9NT4iCiAgICAgICAgICAgIGZvciBzZWN0aW9uIGluIGNoYXB0ZXIuc2VjdGlvbnM6CiAgICAgICAgICAgICAgICBpZiBzZWN0aW9uLmFic3RyYWN0OgogICAgICAgICAgICAgICAgICAgIHByaW50ICI8dHIgdmFsaWduPXRvcD48dGQ+IgogICAgICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoICc8YSBocmVmPSInICsgc2VjdGlvbi5maWxlbmFtZSArICciPicgKQogICAgICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoIHNlY3Rpb24udGl0bGUgKQogICAgICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoICI8L2E+PC90ZD48dGQ+IiArICdcbicgKQogICAgICAgICAgICAgICAgICAgIHNlY3Rpb24uYWJzdHJhY3QuZHVtcF9odG1sKCBzZWxmLnNlY3Rpb25fbGlzdC5pZGVudGlmaWVycyApCiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIjwvdGQ+PC90cj4iCgogICAgICAgICAgICBwcmludCAiPC90YWJsZT4iCgogICAgICAgICAgICBwcmludCBjaGFwdGVyX2Zvb3RlcgoKICAgICAgICAjIGxpc3QgbG9zdCBzZWN0aW9ucwogICAgICAgICMKICAgICAgICBpZiBzZWxmLmxvc3Rfc2VjdGlvbnM6CiAgICAgICAgICAgIHByaW50IGNoYXB0ZXJfaGVhZGVyICsgIk9USEVSIFNFQ1RJT05TOiIgKyBjaGFwdGVyX2ludGVyCgogICAgICAgICAgICBwcmludCAiPHRhYmxlIGNlbGxwYWRkaW5nPTU+IgogICAgICAgICAgICBmb3Igc2VjdGlvbiBpbiBzZWxmLmxvc3Rfc2VjdGlvbnM6CiAgICAgICAgICAgICAgICBpZiBzZWN0aW9uLmFic3RyYWN0OgogICAgICAgICAgICAgICAgICAgIHByaW50ICI8dHIgdmFsaWduPXRvcD48dGQ+IgogICAgICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoICc8YSBocmVmPSInICsgc2VjdGlvbi5maWxlbmFtZSArICciPicgKQogICAgICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoIHNlY3Rpb24udGl0bGUgKQogICAgICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoICI8L2E+PC90ZD48dGQ+IiArICdcbicgKQogICAgICAgICAgICAgICAgICAgIHNlY3Rpb24uYWJzdHJhY3QuZHVtcF9odG1sKCBzZWxmLnNlY3Rpb25fbGlzdC5pZGVudGlmaWVycyApCiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIjwvdGQ+PC90cj4iCgogICAgICAgICAgICBwcmludCAiPC90YWJsZT4iCgogICAgICAgICAgICBwcmludCBjaGFwdGVyX2Zvb3RlcgoKICAgICAgICAjIGluZGV4CiAgICAgICAgIwogICAgICAgIHByaW50IGNoYXB0ZXJfaGVhZGVyICsgJzxhIGhyZWY9IicgKyBzZWxmLnNlY3Rpb25fbGlzdC5pbmRleF9maWxlbmFtZSArICciPkluZGV4PC9hPicgKyBjaGFwdGVyX2Zvb3RlcgoKICAgICAgICBwcmludCBodG1sX2Zvb3RlcgoKICAgICAgICBjbG9zZV9vdXRwdXQoIG91dHB1dCApCgoKICAgIGRlZiBkdW1wX2luZGV4X2h0bWwoIHNlbGYgKToKICAgICAgICBzZWxmLnNlY3Rpb25fbGlzdC5kdW1wX2h0bWxfaW5kZXgoKQoKCiAgICBkZWYgZHVtcF9zZWN0aW9uc19odG1sKCBzZWxmICk6CiAgICAgICAgc2VsZi5zZWN0aW9uX2xpc3QuZHVtcF9odG1sX3NlY3Rpb25zKCkKCgpkZWYgZmlsdGVyX2Jsb2Nrc19ieV90eXBlKCBibG9ja19saXN0LCB0eXBlcyApOgogICAgbmV3X2xpc3QgPSBbXQogICAgZm9yIGJsb2NrIGluIGJsb2NrX2xpc3Q6CiAgICAgICAgaWYgYmxvY2suaXRlbXM6CiAgICAgICAgICAgIGVsZW1lbnQgPSBibG9jay5pdGVtc1swXQogICAgICAgICAgICBtYXJrZXIgID0gZWxlbWVudFswXQogICAgICAgICAgICBpZiBtYXJrZXIgaW4gdHlwZXM6CiAgICAgICAgICAgICAgICBuZXdfbGlzdC5hcHBlbmQoIGJsb2NrICkKCiAgICByZXR1cm4gbmV3X2xpc3QKCgpkZWYgZmlsdGVyX3NlY3Rpb25fYmxvY2tzKCBibG9jayApOgogICAgcmV0dXJuIGJsb2NrLnNlY3Rpb24gIT0gTm9uZQoKCiMgUGVyZm9ybSBhIGxleGljb2dyYXBoaWNhbCBjb21wYXJpc29uIG9mIHR3byBEb2NCbG9jayBvYmplY3RzLiAgUmV0dXJucyAtMSwKIyAwIG9yIDEuCiMKZGVmIGJsb2NrX2xleGljb2dyYXBoaWNhbF9jb21wYXJlKCBiMSwgYjIgKToKICAgIGlmIG5vdCBiMS5uYW1lOgogICAgICAgIHJldHVybiAtMQogICAgaWYgbm90IGIyLm5hbWU6CiAgICAgICAgcmV0dXJuIDEKCiAgICBpZDEgPSBzdHJpbmcubG93ZXIoIGIxLm5hbWUgKQogICAgaWQyID0gc3RyaW5nLmxvd2VyKCBiMi5uYW1lICkKCiAgICBpZiBpZDEgPCBpZDI6CiAgICAgICAgcmV0dXJuIC0xCiAgICBlbGlmIGlkMSA9PSBpZDI6CiAgICAgICAgcmV0dXJuIDAKICAgIGVsc2U6CiAgICAgICAgcmV0dXJuIDEKCgojIER1bXAgYSBsaXN0IGJsb2NrIGFzIGEgc2luZ2xlIEhUTUwgcGFnZS4KIwpkZWYgZHVtcF9odG1sXzEoIGJsb2NrX2xpc3QgKToKICAgIHByaW50IGh0bWxfaGVhZGVyCgogICAgZm9yIGJsb2NrIGluIGJsb2NrX2xpc3Q6CiAgICAgICAgYmxvY2suZHVtcF9odG1sKCkKCiAgICBwcmludCBodG1sX2Zvb3RlcgoKCmRlZiBmaWxlX2V4aXN0cyggcGF0aG5hbWUgKToKICAgIHJlc3VsdCA9IDEKICAgIHRyeToKICAgICAgICBmaWxlID0gb3BlbiggcGF0aG5hbWUsICJyIiApCiAgICAgICAgZmlsZS5jbG9zZSgpCiAgICBleGNlcHQ6CiAgICAgICAgcmVzdWx0ID0gTm9uZQoKICAgIHJldHVybiByZXN1bHQKCgpkZWYgYWRkX25ld19ibG9jayggbGlzdCwgZmlsZW5hbWUsIGxpbmVubywgYmxvY2tfbGluZXMsIHNvdXJjZV9saW5lcyApOgogICAgIiIiYWRkIGEgbmV3IGJsb2NrIHRvIHRoZSBsaXN0IiIiCiAgICBibG9jayAgICAgICAgICA9IERvY0Jsb2NrKCBibG9ja19saW5lcywgc291cmNlX2xpbmVzICkKICAgIGJsb2NrLmZpbGVuYW1lID0gZmlsZW5hbWUKICAgIGJsb2NrLmxpbmVubyAgID0gbGluZW5vCiAgICBsaXN0LmFwcGVuZCggYmxvY2sgKQoKCmRlZiBtYWtlX2Jsb2NrX2xpc3QoIGFyZ3MgPSBOb25lICk6CiAgICAiIiJwYXJzZSBhIGZpbGUgYW5kIGV4dHJhY3QgY29tbWVudHMgYmxvY2tzIGZyb20gaXQiIiIKCiAgICBmaWxlX2xpc3QgPSBbXQogICAgIyBzeXMuc3RkZXJyLndyaXRlKCByZXByKCBzeXMuYXJndlsxIDpdICkgKyAnXG4nICkKCiAgICBpZiBub3QgYXJnczoKICAgICAgICBhcmdzID0gc3lzLmFyZ3ZbMSA6XQoKICAgIGZvciBwYXRobmFtZSBpbiBhcmdzOgogICAgICAgIGlmIHN0cmluZy5maW5kKCBwYXRobmFtZSwgJyonICkgPj0gMDoKICAgICAgICAgICAgbmV3cGF0aCA9IGdsb2IuZ2xvYiggcGF0aG5hbWUgKQogICAgICAgICAgICBuZXdwYXRoLnNvcnQoKSAgIyBzb3J0IGZpbGVzIC0tIHRoaXMgaXMgaW1wb3J0YW50IGJlY2F1c2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgb2YgdGhlIG9yZGVyIG9mIGZpbGVzCiAgICAgICAgZWxzZToKICAgICAgICAgICAgbmV3cGF0aCA9IFtwYXRobmFtZV0KCiAgICAgICAgbGFzdCA9IGxlbiggZmlsZV9saXN0ICkKICAgICAgICBmaWxlX2xpc3RbbGFzdCA6IGxhc3RdID0gbmV3cGF0aAoKICAgIGlmIGxlbiggZmlsZV9saXN0ICkgPT0gMDoKICAgICAgICBmaWxlX2xpc3QgPSBOb25lCiAgICBlbHNlOgogICAgICAgICMgbm93IGZpbHRlciB0aGUgZmlsZSBsaXN0IHRvIHJlbW92ZSBub24tZXhpc3Rpbmcgb25lcwogICAgICAgIGZpbGVfbGlzdCA9IGZpbHRlciggZmlsZV9leGlzdHMsIGZpbGVfbGlzdCApCgogICAgbGlzdCAgID0gW10KICAgIGJsb2NrICA9IFtdCiAgICBmb3JtYXQgPSAwCiAgICBsaW5lbm8gPSAwCgogICAgIyBXZSB1c2UgImZvcm1hdCIgdG8gc3RvcmUgdGhlIHN0YXRlIG9mIG91ciBwYXJzZXI6CiAgICAjCiAgICAjICAwIC0gd2FpdCBmb3IgYmVnaW5uaW5nIG9mIGNvbW1lbnQKICAgICMgIDEgLSBwYXJzZSBjb21tZW50IGZvcm1hdCAxCiAgICAjICAyIC0gcGFyc2UgY29tbWVudCBmb3JtYXQgMgogICAgIwogICAgIyAgNCAtIHdhaXQgZm9yIGJlZ2lubmluZyBvZiBzb3VyY2UgKG9yIGNvbW1lbnQ/KQogICAgIyAgNSAtIHByb2Nlc3Mgc291cmNlCiAgICAjCiAgICBjb21tZW50ID0gW10KICAgIHNvdXJjZSAgPSBbXQogICAgc3RhdGUgICA9IDAKCiAgICBmaWxlaW5wdXQuY2xvc2UoKQogICAgZm9yIGxpbmUgaW4gZmlsZWlucHV0LmlucHV0KCBmaWxlX2xpc3QgKToKICAgICAgICBsID0gbGVuKCBsaW5lICkKICAgICAgICBpZiBsID4gMCBhbmQgbGluZVtsIC0gMV0gPT0gJ1wwMTInOgogICAgICAgICAgICBsaW5lID0gbGluZVswIDogbC0xXQoKICAgICAgICAjIHN0cmlwcGVkIHZlcnNpb24gb2YgdGhlIGxpbmUKICAgICAgICAjCiAgICAgICAgbGluZTIgPSBzdHJpbmcuc3RyaXAoIGxpbmUgKQogICAgICAgIGwgICAgID0gbGVuKCBsaW5lMiApCgogICAgICAgICMgaWYgdGhpcyBsaW5lIGJlZ2lucyB3aXRoIGEgY29tbWVudCBhbmQgd2UgYXJlIHByb2Nlc3Npbmcgc29tZQogICAgICAgICMgc291cmNlLCBleGl0IHRvIHN0YXRlIDAKICAgICAgICAjCiAgICAgICAgIyB1bmxlc3Mgd2UgZW5jb3VudGVyIHNvbWV0aGluZyBsaWtlOgogICAgICAgICMKICAgICAgICAjICAgIC8qQC4uLi4uCiAgICAgICAgIyAgICAvKiMuLi4uLgogICAgICAgICMKICAgICAgICAjICAgIC8qIEAuLi4uLgogICAgICAgICMgICAgLyogIy4uLi4uCiAgICAgICAgIwogICAgICAgIGlmIGZvcm1hdCA+PSA0IGFuZCBsID4gMiBhbmQgbGluZTJbMCA6IDJdID09ICcvKic6CiAgICAgICAgICAgIGlmIGwgPCA0IG9yICggbGluZTJbMl0gIT0gJ0AnIGFuZCBsaW5lMlsyIDogNF0gIT0gJyBAJyBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lMlsyXSAhPSAnIycgYW5kIGxpbmUyWzIgOiA0XSAhPSAnICMnKToKICAgICAgICAgICAgICAgIGFkZF9uZXdfYmxvY2soIGxpc3QsIGZpbGVpbnB1dC5maWxlbmFtZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZW5vLCBibG9jaywgc291cmNlICkKICAgICAgICAgICAgICAgIGZvcm1hdCA9IDAKCiAgICAgICAgaWYgZm9ybWF0ID09IDA6ICAjIyMjIHdhaXQgZm9yIGJlZ2lubmluZyBvZiBjb21tZW50ICMjIyMKICAgICAgICAgICAgaWYgbCA+IDMgYW5kIGxpbmUyWzAgOiAzXSA9PSAnLyoqJzoKICAgICAgICAgICAgICAgIGkgPSAzCiAgICAgICAgICAgICAgICB3aGlsZSBpIDwgbCBhbmQgbGluZTJbaV0gPT0gJyonOgogICAgICAgICAgICAgICAgICAgIGkgPSBpICsgMQoKICAgICAgICAgICAgICAgIGlmIGkgPT0gbDoKICAgICAgICAgICAgICAgICAgICAjIHRoaXMgaXMgJy8qKicgZm9sbG93ZWQgYnkgYW55IG51bWJlciBvZiAnKicsIHRoZQogICAgICAgICAgICAgICAgICAgICMgYmVnaW5uaW5nIG9mIGEgRm9ybWF0IDEgYmxvY2sKICAgICAgICAgICAgICAgICAgICAjCiAgICAgICAgICAgICAgICAgICAgYmxvY2sgID0gW10KICAgICAgICAgICAgICAgICAgICBzb3VyY2UgPSBbXQogICAgICAgICAgICAgICAgICAgIGZvcm1hdCA9IDEKICAgICAgICAgICAgICAgICAgICBsaW5lbm8gPSBmaWxlaW5wdXQuZmlsZWxpbmVubygpCgogICAgICAgICAgICAgICAgZWxpZiBpID09IGwgLSAxIGFuZCBsaW5lMltpXSA9PSAnLyc6CiAgICAgICAgICAgICAgICAgICAgIyB0aGlzIGlzICcvKionIGZvbGxvd2VkIGJ5IGFueSBudW1iZXIgb2YgJyonLCBmb2xsb3dlZAogICAgICAgICAgICAgICAgICAgICMgYnkgYSAnLycsIGkuZS4gdGhlIGJlZ2lubmluZyBvZiBhIEZvcm1hdCAyIG9yIDMgYmxvY2sKICAgICAgICAgICAgICAgICAgICAjCiAgICAgICAgICAgICAgICAgICAgYmxvY2sgID0gW10KICAgICAgICAgICAgICAgICAgICBzb3VyY2UgPSBbXQogICAgICAgICAgICAgICAgICAgIGZvcm1hdCA9IDIKICAgICAgICAgICAgICAgICAgICBsaW5lbm8gPSBmaWxlaW5wdXQuZmlsZWxpbmVubygpCgogICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiAgICAgICAgIwogICAgICAgICMgRk9STUFUIDEKICAgICAgICAjCiAgICAgICAgZWxpZiBmb3JtYXQgPT0gMToKCiAgICAgICAgICAgICMgSWYgdGhlIGxpbmUgZG9lc24ndCBiZWdpbiB3aXRoIGEgIioiLCBzb21ldGhpbmcgd2VudCB3cm9uZywKICAgICAgICAgICAgIyBhbmQgd2UgbXVzdCBleGl0LCBhbmQgZm9yZ2V0IHRoZSBjdXJyZW50IGJsb2NrLgogICAgICAgICAgICAjCiAgICAgICAgICAgIGlmIGwgPT0gMCBvciBsaW5lMlswXSAhPSAnKic6CiAgICAgICAgICAgICAgICBibG9jayAgPSBbXQogICAgICAgICAgICAgICAgZm9ybWF0ID0gMAoKICAgICAgICAgICAgIyBPdGhlcndpc2UsIHdlIHRlc3QgZm9yIGFuIGVuZCBvZiBibG9jaywgd2hpY2ggaXMgYW4gYXJiaXRyYXJ5CiAgICAgICAgICAgICMgbnVtYmVyIG9mICcqJywgZm9sbG93ZWQgYnkgJy8nLgogICAgICAgICAgICAjCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBpID0gMQogICAgICAgICAgICAgICAgd2hpbGUgaSA8IGwgYW5kIGxpbmUyW2ldID09ICcqJzoKICAgICAgICAgICAgICAgICAgICBpID0gaSArIDEKCiAgICAgICAgICAgICAgICAjIHRlc3QgZm9yIHRoZSBlbmQgb2YgdGhlIGJsb2NrCiAgICAgICAgICAgICAgICAjCiAgICAgICAgICAgICAgICBpZiBpIDwgbCBhbmQgbGluZTJbaV0gPT0gJy8nOgogICAgICAgICAgICAgICAgICAgIGlmIGJsb2NrICE9IFtdOgogICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQgPSA0CiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0gMAogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAjIG90aGVyd2lzZSBzaW1wbHkgYXBwZW5kIGxpbmUgdG8gY3VycmVudCBibG9jawogICAgICAgICAgICAgICAgICAgICMKICAgICAgICAgICAgICAgICAgICBibG9jay5hcHBlbmQoIGxpbmUyW2kgOl0gKQoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiAgICAgICAgIwogICAgICAgICMgRk9STUFUIDIKICAgICAgICAjCiAgICAgICAgZWxpZiBmb3JtYXQgPT0gMjoKCiAgICAgICAgICAgICMgSWYgdGhlIGxpbmUgZG9lc24ndCBiZWdpbiB3aXRoICcvKicgYW5kIGVuZCB3aXRoICcqLycsIHRoaXMgaXMKICAgICAgICAgICAgIyB0aGUgZW5kIG9mIHRoZSBmb3JtYXQgMiBmb3JtYXQuCiAgICAgICAgICAgICMKICAgICAgICAgICAgaWYgbCA8IDQgb3IgbGluZTJbOiAyXSAhPSAnLyonIG9yIGxpbmUyWy0yIDpdICE9ICcqLyc6CiAgICAgICAgICAgICAgICBpZiBibG9jayAhPSBbXToKICAgICAgICAgICAgICAgICAgICBmb3JtYXQgPSA0CiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGZvcm1hdCA9IDAKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgcmVtb3ZlIHRoZSBzdGFydCBhbmQgZW5kIGNvbW1lbnQgZGVsaW1pdGVycywgdGhlbgogICAgICAgICAgICAgICAgIyByaWdodC1zdHJpcCB0aGUgbGluZQogICAgICAgICAgICAgICAgIwogICAgICAgICAgICAgICAgbGluZTIgPSBzdHJpbmcucnN0cmlwKCBsaW5lMlsyIDogLTJdICkKCiAgICAgICAgICAgICAgICAjIGNoZWNrIGZvciBlbmQgb2YgYSBmb3JtYXQyIGJsb2NrLCBpLmUuIGEgcnVuIG9mICcqJwogICAgICAgICAgICAgICAgIwogICAgICAgICAgICAgICAgaWYgc3RyaW5nLmNvdW50KCBsaW5lMiwgJyonICkgPT0gbCAtIDQ6CiAgICAgICAgICAgICAgICAgICAgaWYgYmxvY2sgIT0gW106CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdCA9IDQKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQgPSAwCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICMgb3RoZXJ3aXNlLCBhZGQgdGhlIGxpbmUgdG8gdGhlIGN1cnJlbnQgYmxvY2sKICAgICAgICAgICAgICAgICAgICAjCiAgICAgICAgICAgICAgICAgICAgYmxvY2suYXBwZW5kKCBsaW5lMiApCgogICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgaWYgZm9ybWF0ID49IDQ6ICAjIyMjIHNvdXJjZSBwcm9jZXNzaW5nICMjIyMKICAgICAgICAgICAgaWYgbCA+IDA6CiAgICAgICAgICAgICAgICBmb3JtYXQgPSA1CgogICAgICAgICAgICBpZiBmb3JtYXQgPT0gNToKICAgICAgICAgICAgICAgIHNvdXJjZS5hcHBlbmQoIGxpbmUgKQoKICAgIGlmIGZvcm1hdCA+PSA0OgogICAgICAgIGFkZF9uZXdfYmxvY2soIGxpc3QsIGZpbGVpbnB1dC5maWxlbmFtZSgpLCBsaW5lbm8sIGJsb2NrLCBzb3VyY2UgKQoKICAgIHJldHVybiBsaXN0CgoKCiMgVGhpcyBmdW5jdGlvbiBpcyBvbmx5IHVzZWQgZm9yIGRlYnVnZ2luZwojCmRlZiBkdW1wX2Jsb2NrX2xpc3QoIGxpc3QgKToKICAgICIiImR1bXAgYSBjb21tZW50IGJsb2NrIGxpc3QiIiIKICAgIGZvciBibG9jayBpbiBsaXN0OgogICAgICAgIHByaW50ICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIgogICAgICAgIGZvciBsaW5lIGluIGJsb2NrWzBdOgogICAgICAgICAgICBwcmludCBsaW5lCiAgICAgICAgZm9yIGxpbmUgaW4gYmxvY2tbMV06CiAgICAgICAgICAgIHByaW50IGxpbmUKCiAgICBwcmludCAiLS0tLS0tLS0tdGhlIGVuZC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIgoKCmRlZiB1c2FnZSgpOgogICAgcHJpbnQgIlxuRG9jTWFrZXIgMC4xIFVzYWdlIGluZm9ybWF0aW9uXG4iCiAgICBwcmludCAiICBkb2NtYWtlciBbb3B0aW9uc10gZmlsZTEgWyBmaWxlMiAuLi4gXVxuIgogICAgcHJpbnQgInVzaW5nIHRoZSBmb2xsb3dpbmcgb3B0aW9uczpcbiIKICAgIHByaW50ICIgIC1oIDogcHJpbnQgdGhpcyBwYWdlIgogICAgcHJpbnQgIiAgLXQgOiBzZXQgcHJvamVjdCB0aXRsZSwgYXMgaW4gJy10IFwiTXkgUHJvamVjdFwiJyIKICAgIHByaW50ICIgIC1vIDogc2V0IG91dHB1dCBkaXJlY3RvcnksIGFzIGluICctbyBteWRpciciCiAgICBwcmludCAiICAtcCA6IHNldCBkb2N1bWVudGF0aW9uIHByZWZpeCwgYXMgaW4gJy1wIGZ0MiciCiAgICBwcmludCAiIgogICAgcHJpbnQgIiAgLS10aXRsZSAgOiBzYW1lIGFzIC10LCBhcyBpbiAnLS10aXRsZT1cIk15IFByb2plY3RcIiciCiAgICBwcmludCAiICAtLW91dHB1dCA6IHNhbWUgYXMgLW8sIGFzIGluICctLW91dHB1dD1teWRpciciCiAgICBwcmludCAiICAtLXByZWZpeCA6IHNhbWUgYXMgLXAsIGFzIGluICctLXByZWZpeD1mdDInIgoKCmRlZiBtYWluKCBhcmd2ICk6CiAgICAiIiJtYWluIHByb2dyYW0gbG9vcCIiIgoKICAgIGdsb2JhbCBvdXRwdXRfZGlyLCBwcm9qZWN0X3RpdGxlLCBwcm9qZWN0X3ByZWZpeAogICAgZ2xvYmFsIGh0bWxfaGVhZGVyLCBodG1sX2hlYWRlcjEsIGh0bWxfaGVhZGVyMiwgaHRtbF9oZWFkZXIzCgogICAgdHJ5OgogICAgICAgIG9wdHMsIGFyZ3MgPSBnZXRvcHQuZ2V0b3B0KCBzeXMuYXJndlsxOl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJodDpvOnA6IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyAiaGVscCIsICJ0aXRsZT0iLCAib3V0cHV0PSIsICJwcmVmaXg9IiBdICkKCiAgICBleGNlcHQgZ2V0b3B0LkdldG9wdEVycm9yOgogICAgICAgIHVzYWdlKCkKICAgICAgICBzeXMuZXhpdCggMiApCgogICAgaWYgYXJncyA9PSBbXToKICAgICAgICB1c2FnZSgpCiAgICAgICAgc3lzLmV4aXQoIDEgKQoKICAgICMgcHJvY2VzcyBvcHRpb25zCiAgICAjCiAgICBwcm9qZWN0X3RpdGxlICA9ICJQcm9qZWN0IgogICAgcHJvamVjdF9wcmVmaXggPSBOb25lCiAgICBvdXRwdXRfZGlyICAgICA9IE5vbmUKCiAgICBmb3Igb3B0IGluIG9wdHM6CiAgICAgICAgaWYgb3B0WzBdIGluICggIi1oIiwgIi0taGVscCIgKToKICAgICAgICAgICAgdXNhZ2UoKQogICAgICAgICAgICBzeXMuZXhpdCggMCApCgogICAgICAgIGlmIG9wdFswXSBpbiAoICItdCIsICItLXRpdGxlIiApOgogICAgICAgICAgICBwcm9qZWN0X3RpdGxlID0gb3B0WzFdCgogICAgICAgIGlmIG9wdFswXSBpbiAoICItbyIsICItLW91dHB1dCIgKToKICAgICAgICAgICAgb3V0cHV0X2RpciA9IG9wdFsxXQoKICAgICAgICBpZiBvcHRbMF0gaW4gKCAiLXAiLCAiLS1wcmVmaXgiICk6CiAgICAgICAgICAgIHByb2plY3RfcHJlZml4ID0gb3B0WzFdCgogICAgaHRtbF9oZWFkZXIgPSBodG1sX2hlYWRlcl8xICsgcHJvamVjdF90aXRsZSArIGh0bWxfaGVhZGVyXzIgKyBwcm9qZWN0X3RpdGxlICsgaHRtbF9oZWFkZXJfMwogICAgY2hlY2tfb3V0cHV0KCApCiAgICBjb21wdXRlX3RpbWVfaHRtbCgpCgogICAgIyB3ZSBiZWdpbiBieSBzaW1wbHkgYnVpbGRpbmcgYSBsaXN0IG9mIERvY0Jsb2NrIGVsZW1lbnRzCiAgICAjCiAgICBsaXN0ID0gbWFrZV9ibG9ja19saXN0KCBhcmdzICkKCiAgICAjIG5vdywgc29ydCB0aGUgYmxvY2tzIGludG8gc2VjdGlvbnMKICAgICMKICAgIGRvY3VtZW50ID0gRG9jRG9jdW1lbnQoKQogICAgZm9yIGJsb2NrIGluIGxpc3Q6CiAgICAgICAgZG9jdW1lbnQuYXBwZW5kX2Jsb2NrKCBibG9jayApCgogICAgZG9jdW1lbnQucHJlcGFyZV9maWxlcyggcHJvamVjdF9wcmVmaXggKQoKICAgIGRvY3VtZW50LmR1bXBfdG9jX2h0bWwoKQogICAgZG9jdW1lbnQuZHVtcF9zZWN0aW9uc19odG1sKCkKICAgIGRvY3VtZW50LmR1bXBfaW5kZXhfaHRtbCgpCgojIGlmIGNhbGxlZCBmcm9tIHRoZSBjb21tYW5kIGxpbmUKIwppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgbWFpbiggc3lzLmFyZ3YgKQoKCiMgZW9mCg==