diff --git a/src/main/resources/warehouse/contract.json b/src/main/resources/warehouse/contract.json index c053992ab..5cc936920 100644 --- a/src/main/resources/warehouse/contract.json +++ b/src/main/resources/warehouse/contract.json @@ -12,7 +12,7 @@ "contractFolderId" : 1, "contractName" : "LibString", "contractDesc" : "# String library\n\nString library\n\nProvides common string-related operations, including copying, finding, replacing, and so on。", - "contractSrc" : "Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgPj0wLjQuMjQgPDAuNi4xMDsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBieXRlc1RvU3RyaW5nKGJ5dGVzIG1lbW9yeSBfYnl0ZXMpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSl7CiAgICAgICAgYnl0ZXMgbWVtb3J5IGJ5dGVzQXJyYXkgPSBuZXcgYnl0ZXMoX2J5dGVzLmxlbmd0aCk7CiAgICAgICAgZm9yICh1aW50MjU2IGk7IGkgPCBfYnl0ZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgYnl0ZXNBcnJheVtpXSA9IF9ieXRlc1tpXTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZyhfYnl0ZXMpOwogICAgfQoKICAgIGZ1bmN0aW9uIHN0cmluZ1RvQnl0ZXMoc3RyaW5nIG1lbW9yeSBfc3RyaW5nKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGJ5dGVzIG1lbW9yeSl7CiAgICAgICAgYnl0ZXMgbWVtb3J5IF9ieXRlcyA9IGJ5dGVzKF9zdHJpbmcpOwogICAgICAgIHJldHVybiBfYnl0ZXM7CiAgICB9CiAgICAKIAogICAgZnVuY3Rpb24gYnl0ZXMzMlRvU3RyaW5nKGJ5dGVzMzIgX2J5dGVzMzIpIGludGVybmFsIHB1cmUgcmV0dXJucyhzdHJpbmcgbWVtb3J5KXsKICAgICAgICBieXRlcyBtZW1vcnkgYnl0ZXNTdHJpbmcgPSBuZXcgYnl0ZXMoMzIpOwogICAgICAgIHVpbnQgY2hhckNvdW50ID0gMCA7CiAgICAgICAgZm9yKHVpbnQgaSA9IDAgOyBpPDMyO2krKyl7CiAgICAgICAgICAgIGJ5dGUgY2hhciA9IGJ5dGUoYnl0ZXMzMih1aW50KF9ieXRlczMyKSAqMiAqKig4KmkpKSk7CiAgICAgICAgICAgIGlmKGNoYXIgIT0wKXsKICAgICAgICAgICAgICAgIGJ5dGVzU3RyaW5nW2NoYXJDb3VudF0gPSBjaGFyOwogICAgICAgICAgICAgICAgY2hhckNvdW50Kys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnl0ZXMgbWVtb3J5IGJ5dGVzU3RyaW5nVHJpbW1lZCA9IG5ldyBieXRlcyhjaGFyQ291bnQpOwogICAgICAgIGZvcih1aW50IGo9MDtqPGNoYXJDb3VudDtqKyspewogICAgICAgICAgICBieXRlc1N0cmluZ1RyaW1tZWRbal09Ynl0ZXNTdHJpbmdbal07CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmcoYnl0ZXNTdHJpbmdUcmltbWVkKTsKICAgIH0KCgogICAgZnVuY3Rpb24gc3RyaW5nVG9CeXRlczMyKHN0cmluZyBtZW1vcnkgc291cmNlKSBpbnRlcm5hbCBwdXJlIHJldHVybnMoYnl0ZXMzMiByZXN1bHQpewogICAgICAgIGFzc2VtYmx5ewogICAgICAgICAgICByZXN1bHQgOj0gbWxvYWQoYWRkKHNvdXJjZSwzMikpCiAgICAgICAgfQogICAgfQoKCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVtpXSA8IGJ5dGVzKF9zdHIpW2ldKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGNvbXBhcmVOb0Nhc2Uoc3RyaW5nIG1lbW9yeSBfc2VsZiwgc3RyaW5nIG1lbW9yeSBfc3RyKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGJ5dGUgY2gxID0gYnl0ZXMoX3NlbGYpW2ldfDB4MjA7CiAgICAgICAgICAgIGJ5dGUgY2gyID0gYnl0ZXMoX3N0cilbaV18MHgyMDsKICAgICAgICAgICAgaWYgKGNoMSA+PSAnYScgJiYgY2gxIDw9J3onICYmIGNoMiA+PSAnYScgJiYgY2gyIDw9J3onKSB7CiAgICAgICAgICAgICAgICBpZiAoY2gxID4gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoMSA8IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChieXRlcyhfc2VsZilbaV0gPCBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZXF1YWxzKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIpIGludGVybmFsIHB1cmUgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggIT0gYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGJ5dGUgY2gxID0gYnl0ZXMoX3NlbGYpW2ldfDB4MjA7CiAgICAgICAgICAgIGJ5dGUgY2gyID0gYnl0ZXMoX3N0cilbaV18MHgyMDsKICAgICAgICAgICAgaWYgKGNoMSA+PSAnYScgJiYgY2gxIDw9J3onICYmIGNoMiA+PSAnYScgJiYgY2gyIDw9J3onKSB7CiAgICAgICAgICAgICAgICBpZiAoY2gxICE9IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gIT0gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIHN1YnN0cihzdHJpbmcgbWVtb3J5IF9zZWxmLCB1aW50IF9zdGFydCwgdWludCBfbGVuKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgbWVtb3J5IF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoX2xlbik7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIrX3N0YXJ0LCBfbGVuKTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gY29uY2F0KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9zdHIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBzdHJwdHIgOj0gYWRkKF9zdHIsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbWVtY3B5KHJldHB0ciwgc2VsZnB0ciwgYnl0ZXMoX3NlbGYpLmxlbmd0aCk7CiAgICAgICAgbWVtY3B5KHJldHB0citieXRlcyhfc2VsZikubGVuZ3RoLCBzdHJwdHIsIGJ5dGVzKF9zdHIpLmxlbmd0aCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIxLCBzdHJpbmcgbWVtb3J5IF9zdHIyKQogICAgICAgIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIxLCBzdHJpbmcgbWVtb3J5IF9zdHIyLCBzdHJpbmcgbWVtb3J5IF9zdHIzKQogICAgICAgIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aAogICAgICAgICAgICArIGJ5dGVzKF9zdHIzKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHIxcHRyOwogICAgICAgIHVpbnQgc3RyMnB0cjsKICAgICAgICB1aW50IHN0cjNwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RyMXB0ciA6PSBhZGQoX3N0cjEsIDB4MjApCiAgICAgICAgICAgIHN0cjJwdHIgOj0gYWRkKF9zdHIyLCAweDIwKQogICAgICAgICAgICBzdHIzcHRyIDo9IGFkZChfc3RyMywgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjNwdHIsIGJ5dGVzKF9zdHIzKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMykubGVuZ3RoOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBtZW1vcnkgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIHVpbnQgaTsKICAgICAgICB1aW50OCBjaDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShjaCA9PSAweDIwIHx8IGNoID09IDB4MDkgfHwgY2ggPT0gMHgwRCB8fCBjaCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludCBzdGFydCA9IGk7CiAgICAgICAgCiAgICAgICAgZm9yIChpPWJ5dGVzKF9zZWxmKS5sZW5ndGg7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIGNoID0gdWludDgoYnl0ZXMoX3NlbGYpW2ktMV0pOwogICAgICAgICAgICBpZiAoIShjaCA9PSAweDIwIHx8IGNoID09IDB4MDkgfHwgY2ggPT0gMHgwRCB8fCBjaCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludCBlbmQgPSBpOwogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGVuZC1zdGFydCk7CiAgICAgICAgCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbWVtY3B5KHJldHB0ciwgc2VsZnB0citzdGFydCwgZW5kLXN0YXJ0KTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CiAgICAgICAgdWludDE2IGk7CiAgICAgICAgdWludDE2IGo7CiAgICAgICAgYm9vbCBtYXRjaGVkOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBtYXRjaGVkID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoaj0wOyBqPGJ5dGVzKF9jaGFycykubGVuZ3RoOyArK2opIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPT0gYnl0ZXMoX2NoYXJzKVtqXSkgewogICAgICAgICAgICAgICAgICAgIG1hdGNoZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghbWF0Y2hlZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludDE2IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9dWludDE2KGJ5dGVzKF9zZWxmKS5sZW5ndGgpOyBpPjA7IC0taSkgewogICAgICAgICAgICBtYXRjaGVkID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoaj0wOyBqPGJ5dGVzKF9jaGFycykubGVuZ3RoOyArK2opIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaS0xXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgZW5kID0gaTsKCiAgICAgICAgaWYgKGVuZCA8PSBzdGFydCkgewoJCSAgICBfcmV0ID0gIiI7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhlbmQtc3RhcnQpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIrc3RhcnQsIGVuZC1zdGFydCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIG1lbW9yeSBzcmMsIHN0cmluZyBtZW1vcnkgdmFsdWUpCiAgICAgICAgaW50ZXJuYWwKICAgICAgICBwdXJlCiAgICAgICAgcmV0dXJucyAoaW50KSB7CiAgICAgICAgcmV0dXJuIGluZGV4T2Yoc3JjLCB2YWx1ZSwgMCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nICBtZW1vcnkgc3JjLCBzdHJpbmcgbWVtb3J5IHZhbHVlLCB1aW50IG9mZnNldCkKICAgICAgICBpbnRlcm5hbAogICAgICAgIHB1cmUKICAgICAgICByZXR1cm5zIChpbnQpIHsKICAgICAgICBieXRlcyBtZW1vcnkgc3JjQnl0ZXMgPSBieXRlcyhzcmMpOwogICAgICAgIGJ5dGVzIG1lbW9yeSB2YWx1ZUJ5dGVzID0gYnl0ZXModmFsdWUpOwoKICAgICAgICBhc3NlcnQodmFsdWVCeXRlcy5sZW5ndGggPT0gMSk7CgogICAgICAgIGZvciAodWludCBpID0gb2Zmc2V0OyBpIDwgc3JjQnl0ZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgaWYgKHNyY0J5dGVzW2ldID09IHZhbHVlQnl0ZXNbMF0pIHsKICAgICAgICAgICAgICAgIHJldHVybiBpbnQoaSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgbWVtb3J5IHNyYywgc3RyaW5nIG1lbW9yeSBzZXBhcmF0b3IpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc3RyaW5nW10gbWVtb3J5IHNwbGl0QXJyKSB7CiAgICAgICAgYnl0ZXMgbWVtb3J5IHNyY0J5dGVzID0gYnl0ZXMoc3JjKTsKCiAgICAgICAgdWludCBvZmZzZXQgPSAwOwogICAgICAgIHVpbnQgc3BsaXRzQ291bnQgPSAxOwogICAgICAgIGludCBsaW1pdCA9IC0xOwogICAgICAgIHdoaWxlIChvZmZzZXQgPCBzcmNCeXRlcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICAgIGxpbWl0ID0gaW5kZXhPZihzcmMsIHNlcGFyYXRvciwgb2Zmc2V0KTsKICAgICAgICAgICAgaWYgKGxpbWl0ID09IC0xKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgc3BsaXRzQ291bnQrKzsKICAgICAgICAgICAgICAgIG9mZnNldCA9IHVpbnQobGltaXQpICsgMTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3BsaXRBcnIgPSBuZXcgc3RyaW5nW10oc3BsaXRzQ291bnQpOwoKICAgICAgICBvZmZzZXQgPSAwOwogICAgICAgIHNwbGl0c0NvdW50ID0gMDsKICAgICAgICB3aGlsZSAob2Zmc2V0IDwgc3JjQnl0ZXMubGVuZ3RoIC0gMSkgewoKICAgICAgICAgICAgbGltaXQgPSBpbmRleE9mKHNyYywgc2VwYXJhdG9yLCBvZmZzZXQpOwogICAgICAgICAgICBpZiAobGltaXQgPT0gLSAxKSB7CiAgICAgICAgICAgICAgICBsaW1pdCA9IGludChzcmNCeXRlcy5sZW5ndGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IHRtcCA9IG5ldyBzdHJpbmcodWludChsaW1pdCkgLSBvZmZzZXQpOwogICAgICAgICAgICBieXRlcyBtZW1vcnkgdG1wQnl0ZXMgPSBieXRlcyh0bXApOwoKICAgICAgICAgICAgdWludCBqID0gMDsKICAgICAgICAgICAgZm9yICh1aW50IGkgPSBvZmZzZXQ7IGkgPCB1aW50KGxpbWl0KTsgaSsrKSB7CiAgICAgICAgICAgICAgICB0bXBCeXRlc1tqKytdID0gc3JjQnl0ZXNbaV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb2Zmc2V0ID0gdWludChsaW1pdCkgKyAxOwogICAgICAgICAgICBzcGxpdEFycltzcGxpdHNDb3VudCsrXSA9IHN0cmluZyh0bXBCeXRlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzcGxpdEFycjsKICAgIH0KICAgIAoKICAgIAogICAgZnVuY3Rpb24gdG9JbnQoc3RyaW5nIG1lbW9yeSBfc2VsZikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgbWVtb3J5IF9zZWxmKSBpbnRlcm5hbCByZXR1cm5zIChhZGRyZXNzIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGgtaSA8IDIpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICAvL211c3Qgc3RhcnQgd2l0aCAweAogICAgICAgIGlmICghKGJ5dGVzKF9zZWxmKVtpXSA9PSAnMCcgJiYgYnl0ZXMoX3NlbGYpW2krMV18MHgyMCA9PSAneCcpKSB7CiAgICAgICAgICAgIHJldHVybiBhZGRyZXNzKDApOwogICAgICAgIH0KCiAgICAgICAgdWludCBhZGRyID0gMDsKICAgICAgICAKICAgICAgICBmb3IgKGkrPTI7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKGRpZ2l0ID49IDB4MzAgJiYgZGlnaXQgPD0gMHgzOSkgLy8nMCctJzknCiAgICAgICAgICAgICAgICBkaWdpdCAtPSAweDMwOwogICAgICAgICAgICBlbHNlIGlmIChkaWdpdHwweDIwID49IDB4NjEgJiYgZGlnaXR8MHgyMCA8PSAweDY2KSAvLydhJy0nZicKICAgICAgICAgICAgICAgIGRpZ2l0ID0gZGlnaXQtMHg2MSsxMDsKICAgICAgICAgICAgZWxzZSAKICAgICAgICAgICAgICAgIHJldHVybiBhZGRyZXNzKDApOyAKICAgICAgICAgICAgCiAgICAgICAgICAgIGFkZHIgPSBhZGRyKjE2K2RpZ2l0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gYWRkcmVzcyhhZGRyKTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9LZXlWYWx1ZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfa2V5KS5sZW5ndGggKyA1KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBrZXlwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAga2V5cHRyIDo9IGFkZChfa2V5LCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQgcG9zID0gMDsKCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBrZXlwdHIsIGJ5dGVzKF9rZXkpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9rZXkpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJzonOwogICAgICAgIAogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc2VsZnB0ciwgYnl0ZXMoX3NlbGYpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTdHJpbmdWYWx1ZUJ5S2V5KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CgkJX3JldCA9ICIiOwogICAgICAgIGludCBwb3MgPSAtMTsKICAgICAgICB1aW50IHNlYXJjaFN0YXJ0ID0gMDsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCJcIiIuY29uY2F0KF9rZXksICJcIiIpLCBzZWFyY2hTdGFydCk7CiAgICAgICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgICAgIHBvcyA9IF9zZWxmLmluZGV4T2YoIiciLmNvbmNhdChfa2V5LCAiJyIpLCBzZWFyY2hTdGFydCk7CiAgICAgICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHBvcyArPSBpbnQoYnl0ZXMoX2tleSkubGVuZ3RoKzIpOwoKICAgICAgICAgICAgYm9vbCBjb2xvbiA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAodWludChwb3MpIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICcgJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXHQnIAogICAgICAgICAgICAgICAgICAgIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdccicgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xuJykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnOicpIHsKICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgICAgICBjb2xvbiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZih1aW50KHBvcykgPT0gYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzdGFydCArPSAxOwogICAgICAgIAogICAgICAgIGludCBlbmQ7CiAgICAgICAgaWYgKGRvdWJsZVF1b3RlcykgewogICAgICAgICAgICBlbmQgPSBfc2VsZi5pbmRleE9mKCJcIiIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbmQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChzdGFydCkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW5kID09IC0xKSB7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICBfcmV0ID0gX3NlbGYuc3Vic3RyKHVpbnQoc3RhcnQpLCB1aW50KGVuZC1zdGFydCkpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRJbnRWYWx1ZUJ5S2V5KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwb3MgKz0gaW50KGJ5dGVzKF9rZXkpLmxlbmd0aCsyKTsKCiAgICAgICAgICAgIGJvb2wgY29sb24gPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKHVpbnQocG9zKSA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnICcgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1x0JyAKICAgICAgICAgICAgICAgICAgICB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXHInIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcbicpIHsKICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJzonKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICAgICAgY29sb24gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodWludChwb3MpID09IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29sb24pIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VhcmNoU3RhcnQgPSB1aW50KHBvcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHVpbnQgaSA9IHVpbnQocG9zKTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBIAogICAgICAgICAgICB8fCBkaWdpdCA9PSAweDNBIC8qOiovIHx8IGRpZ2l0ID09IDB4MjIgLyoiKi8gfHwgZGlnaXQgPT0gMHgyNyAvKicqLykpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGJvb2wgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPT0gJysnKSB7CiAgICAgICAgICAgIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0gZWxzZSBpZihieXRlcyhfc2VsZilbaV0gPT0gJy0nKSB7CiAgICAgICAgICAgIHBvc2l0aXZlID0gZmFsc2U7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9CgogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID49IDB4MzAgJiYgZGlnaXQgPD0gMHgzOSkpIHsKICAgICAgICAgICAgICAgIGlmICghcG9zaXRpdmUpIHsKICAgICAgICAgICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIHRvVXBwZXJjYXNlKHN0cmluZyBtZW1vcnkgc3JjKSBpbnRlcm5hbCBwdXJlIHJldHVybnMoc3RyaW5nIG1lbW9yeSl7CiAgICAgICAgYnl0ZXMgbWVtb3J5IHNyY2IgPSBieXRlcyhzcmMpOwogICAgICAgIGZvcih1aW50IGk9MDtpPHNyY2IubGVuZ3RoO2krKyl7CiAgICAgICAgICAgIGJ5dGUgYiA9IHNyY2JbaV07CiAgICAgICAgICAgIGlmKGIgPj0gJ2EnICYmIGIgPD0gJ3onKXsKICAgICAgICAgICAgICAgIGIgJj0gYnl0ZSgweERGKTsvLyAtMzIKICAgICAgICAgICAgICAgIHNyY2JbaV0gPSBiIDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc3JjOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0xvd2VyY2FzZShzdHJpbmcgbWVtb3J5IHNyYykgaW50ZXJuYWwgcHVyZSByZXR1cm5zKHN0cmluZyBtZW1vcnkpewogICAgICAgIGJ5dGVzIG1lbW9yeSBzcmNiID0gYnl0ZXMoc3JjKTsKICAgICAgICBmb3IodWludCBpPTA7aTxzcmNiLmxlbmd0aDtpKyspewogICAgICAgICAgICBieXRlIGIgPSBzcmNiW2ldOwogICAgICAgICAgICBpZihiID49ICdBJyAmJiBiIDw9ICdaJyl7CiAgICAgICAgICAgICAgICBiIHw9IDB4MjA7CiAgICAgICAgICAgICAgICBzcmNiW2ldID0gYjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc3JjOwogICAgfQoKCQogICAgZnVuY3Rpb24ga2V5RXhpc3RzKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIG1lbW9yeSBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHMoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KIAogICAgZnVuY3Rpb24gaW5BcnJheU5vQ2FzZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFsc05vQ2FzZShfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICB9", + "contractSrc" : "Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgPj0wLjQuMjQgPDAuNi4xMDsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBieXRlc1RvU3RyaW5nKGJ5dGVzIG1lbW9yeSBfYnl0ZXMpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSl7CiAgICAgICAgcmV0dXJuIHN0cmluZyhfYnl0ZXMpOwogICAgfQoKICAgIGZ1bmN0aW9uIHN0cmluZ1RvQnl0ZXMoc3RyaW5nIG1lbW9yeSBfc3RyaW5nKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGJ5dGVzIG1lbW9yeSl7CiAgICAgICAgYnl0ZXMgbWVtb3J5IF9ieXRlcyA9IGJ5dGVzKF9zdHJpbmcpOwogICAgICAgIHJldHVybiBfYnl0ZXM7CiAgICB9CiAgICAKIAogICAgZnVuY3Rpb24gYnl0ZXMzMlRvU3RyaW5nKGJ5dGVzMzIgX2J5dGVzMzIpIGludGVybmFsIHB1cmUgcmV0dXJucyhzdHJpbmcgbWVtb3J5KXsKICAgICAgICBieXRlcyBtZW1vcnkgYnl0ZXNTdHJpbmcgPSBuZXcgYnl0ZXMoMzIpOwogICAgICAgIHVpbnQgY2hhckNvdW50ID0gMCA7CiAgICAgICAgZm9yKHVpbnQgaSA9IDAgOyBpPDMyO2krKyl7CiAgICAgICAgICAgIGJ5dGUgY2hhciA9IGJ5dGUoYnl0ZXMzMih1aW50KF9ieXRlczMyKSAqMiAqKig4KmkpKSk7CiAgICAgICAgICAgIGlmKGNoYXIgIT0wKXsKICAgICAgICAgICAgICAgIGJ5dGVzU3RyaW5nW2NoYXJDb3VudF0gPSBjaGFyOwogICAgICAgICAgICAgICAgY2hhckNvdW50Kys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnl0ZXMgbWVtb3J5IGJ5dGVzU3RyaW5nVHJpbW1lZCA9IG5ldyBieXRlcyhjaGFyQ291bnQpOwogICAgICAgIGZvcih1aW50IGo9MDtqPGNoYXJDb3VudDtqKyspewogICAgICAgICAgICBieXRlc1N0cmluZ1RyaW1tZWRbal09Ynl0ZXNTdHJpbmdbal07CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmcoYnl0ZXNTdHJpbmdUcmltbWVkKTsKICAgIH0KCgogICAgZnVuY3Rpb24gc3RyaW5nVG9CeXRlczMyKHN0cmluZyBtZW1vcnkgc291cmNlKSBpbnRlcm5hbCBwdXJlIHJldHVybnMoYnl0ZXMzMiByZXN1bHQpewogICAgICAgIGFzc2VtYmx5ewogICAgICAgICAgICByZXN1bHQgOj0gbWxvYWQoYWRkKHNvdXJjZSwzMikpCiAgICAgICAgfQogICAgfQoKCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVtpXSA8IGJ5dGVzKF9zdHIpW2ldKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGNvbXBhcmVOb0Nhc2Uoc3RyaW5nIG1lbW9yeSBfc2VsZiwgc3RyaW5nIG1lbW9yeSBfc3RyKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGJ5dGUgY2gxID0gYnl0ZXMoX3NlbGYpW2ldfDB4MjA7CiAgICAgICAgICAgIGJ5dGUgY2gyID0gYnl0ZXMoX3N0cilbaV18MHgyMDsKICAgICAgICAgICAgaWYgKGNoMSA+PSAnYScgJiYgY2gxIDw9J3onICYmIGNoMiA+PSAnYScgJiYgY2gyIDw9J3onKSB7CiAgICAgICAgICAgICAgICBpZiAoY2gxID4gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoMSA8IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChieXRlcyhfc2VsZilbaV0gPCBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZXF1YWxzKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIpIGludGVybmFsIHB1cmUgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggIT0gYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGJ5dGUgY2gxID0gYnl0ZXMoX3NlbGYpW2ldfDB4MjA7CiAgICAgICAgICAgIGJ5dGUgY2gyID0gYnl0ZXMoX3N0cilbaV18MHgyMDsKICAgICAgICAgICAgaWYgKGNoMSA+PSAnYScgJiYgY2gxIDw9J3onICYmIGNoMiA+PSAnYScgJiYgY2gyIDw9J3onKSB7CiAgICAgICAgICAgICAgICBpZiAoY2gxICE9IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gIT0gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIHN1YnN0cihzdHJpbmcgbWVtb3J5IF9zZWxmLCB1aW50IF9zdGFydCwgdWludCBfbGVuKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgbWVtb3J5IF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoX2xlbik7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIrX3N0YXJ0LCBfbGVuKTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gY29uY2F0KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9zdHIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBzdHJwdHIgOj0gYWRkKF9zdHIsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbWVtY3B5KHJldHB0ciwgc2VsZnB0ciwgYnl0ZXMoX3NlbGYpLmxlbmd0aCk7CiAgICAgICAgbWVtY3B5KHJldHB0citieXRlcyhfc2VsZikubGVuZ3RoLCBzdHJwdHIsIGJ5dGVzKF9zdHIpLmxlbmd0aCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIxLCBzdHJpbmcgbWVtb3J5IF9zdHIyKQogICAgICAgIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIxLCBzdHJpbmcgbWVtb3J5IF9zdHIyLCBzdHJpbmcgbWVtb3J5IF9zdHIzKQogICAgICAgIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aAogICAgICAgICAgICArIGJ5dGVzKF9zdHIzKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHIxcHRyOwogICAgICAgIHVpbnQgc3RyMnB0cjsKICAgICAgICB1aW50IHN0cjNwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RyMXB0ciA6PSBhZGQoX3N0cjEsIDB4MjApCiAgICAgICAgICAgIHN0cjJwdHIgOj0gYWRkKF9zdHIyLCAweDIwKQogICAgICAgICAgICBzdHIzcHRyIDo9IGFkZChfc3RyMywgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjNwdHIsIGJ5dGVzKF9zdHIzKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMykubGVuZ3RoOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBtZW1vcnkgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIHVpbnQgaTsKICAgICAgICB1aW50OCBjaDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShjaCA9PSAweDIwIHx8IGNoID09IDB4MDkgfHwgY2ggPT0gMHgwRCB8fCBjaCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludCBzdGFydCA9IGk7CiAgICAgICAgCiAgICAgICAgZm9yIChpPWJ5dGVzKF9zZWxmKS5sZW5ndGg7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIGNoID0gdWludDgoYnl0ZXMoX3NlbGYpW2ktMV0pOwogICAgICAgICAgICBpZiAoIShjaCA9PSAweDIwIHx8IGNoID09IDB4MDkgfHwgY2ggPT0gMHgwRCB8fCBjaCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludCBlbmQgPSBpOwogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGVuZC1zdGFydCk7CiAgICAgICAgCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbWVtY3B5KHJldHB0ciwgc2VsZnB0citzdGFydCwgZW5kLXN0YXJ0KTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CiAgICAgICAgdWludDE2IGk7CiAgICAgICAgdWludDE2IGo7CiAgICAgICAgYm9vbCBtYXRjaGVkOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBtYXRjaGVkID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoaj0wOyBqPGJ5dGVzKF9jaGFycykubGVuZ3RoOyArK2opIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPT0gYnl0ZXMoX2NoYXJzKVtqXSkgewogICAgICAgICAgICAgICAgICAgIG1hdGNoZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghbWF0Y2hlZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludDE2IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9dWludDE2KGJ5dGVzKF9zZWxmKS5sZW5ndGgpOyBpPjA7IC0taSkgewogICAgICAgICAgICBtYXRjaGVkID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoaj0wOyBqPGJ5dGVzKF9jaGFycykubGVuZ3RoOyArK2opIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaS0xXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgZW5kID0gaTsKCiAgICAgICAgaWYgKGVuZCA8PSBzdGFydCkgewoJCSAgICBfcmV0ID0gIiI7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhlbmQtc3RhcnQpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIrc3RhcnQsIGVuZC1zdGFydCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIG1lbW9yeSBzcmMsIHN0cmluZyBtZW1vcnkgdmFsdWUpCiAgICAgICAgaW50ZXJuYWwKICAgICAgICBwdXJlCiAgICAgICAgcmV0dXJucyAoaW50KSB7CiAgICAgICAgcmV0dXJuIGluZGV4T2Yoc3JjLCB2YWx1ZSwgMCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nICBtZW1vcnkgc3JjLCBzdHJpbmcgbWVtb3J5IHZhbHVlLCB1aW50IG9mZnNldCkKICAgICAgICBpbnRlcm5hbAogICAgICAgIHB1cmUKICAgICAgICByZXR1cm5zIChpbnQpIHsKICAgICAgICBieXRlcyBtZW1vcnkgc3JjQnl0ZXMgPSBieXRlcyhzcmMpOwogICAgICAgIGJ5dGVzIG1lbW9yeSB2YWx1ZUJ5dGVzID0gYnl0ZXModmFsdWUpOwoKICAgICAgICBhc3NlcnQodmFsdWVCeXRlcy5sZW5ndGggPT0gMSk7CgogICAgICAgIGZvciAodWludCBpID0gb2Zmc2V0OyBpIDwgc3JjQnl0ZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgaWYgKHNyY0J5dGVzW2ldID09IHZhbHVlQnl0ZXNbMF0pIHsKICAgICAgICAgICAgICAgIHJldHVybiBpbnQoaSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgbWVtb3J5IHNyYywgc3RyaW5nIG1lbW9yeSBzZXBhcmF0b3IpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc3RyaW5nW10gbWVtb3J5IHNwbGl0QXJyKSB7CiAgICAgICAgYnl0ZXMgbWVtb3J5IHNyY0J5dGVzID0gYnl0ZXMoc3JjKTsKCiAgICAgICAgdWludCBvZmZzZXQgPSAwOwogICAgICAgIHVpbnQgc3BsaXRzQ291bnQgPSAxOwogICAgICAgIGludCBsaW1pdCA9IC0xOwogICAgICAgIHdoaWxlIChvZmZzZXQgPCBzcmNCeXRlcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICAgIGxpbWl0ID0gaW5kZXhPZihzcmMsIHNlcGFyYXRvciwgb2Zmc2V0KTsKICAgICAgICAgICAgaWYgKGxpbWl0ID09IC0xKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgc3BsaXRzQ291bnQrKzsKICAgICAgICAgICAgICAgIG9mZnNldCA9IHVpbnQobGltaXQpICsgMTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3BsaXRBcnIgPSBuZXcgc3RyaW5nW10oc3BsaXRzQ291bnQpOwoKICAgICAgICBvZmZzZXQgPSAwOwogICAgICAgIHNwbGl0c0NvdW50ID0gMDsKICAgICAgICB3aGlsZSAob2Zmc2V0IDwgc3JjQnl0ZXMubGVuZ3RoIC0gMSkgewoKICAgICAgICAgICAgbGltaXQgPSBpbmRleE9mKHNyYywgc2VwYXJhdG9yLCBvZmZzZXQpOwogICAgICAgICAgICBpZiAobGltaXQgPT0gLSAxKSB7CiAgICAgICAgICAgICAgICBsaW1pdCA9IGludChzcmNCeXRlcy5sZW5ndGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IHRtcCA9IG5ldyBzdHJpbmcodWludChsaW1pdCkgLSBvZmZzZXQpOwogICAgICAgICAgICBieXRlcyBtZW1vcnkgdG1wQnl0ZXMgPSBieXRlcyh0bXApOwoKICAgICAgICAgICAgdWludCBqID0gMDsKICAgICAgICAgICAgZm9yICh1aW50IGkgPSBvZmZzZXQ7IGkgPCB1aW50KGxpbWl0KTsgaSsrKSB7CiAgICAgICAgICAgICAgICB0bXBCeXRlc1tqKytdID0gc3JjQnl0ZXNbaV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb2Zmc2V0ID0gdWludChsaW1pdCkgKyAxOwogICAgICAgICAgICBzcGxpdEFycltzcGxpdHNDb3VudCsrXSA9IHN0cmluZyh0bXBCeXRlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzcGxpdEFycjsKICAgIH0KICAgIAoKICAgIAogICAgZnVuY3Rpb24gdG9JbnQoc3RyaW5nIG1lbW9yeSBfc2VsZikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgbWVtb3J5IF9zZWxmKSBpbnRlcm5hbCByZXR1cm5zIChhZGRyZXNzIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGgtaSA8IDIpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICAvL211c3Qgc3RhcnQgd2l0aCAweAogICAgICAgIGlmICghKGJ5dGVzKF9zZWxmKVtpXSA9PSAnMCcgJiYgYnl0ZXMoX3NlbGYpW2krMV18MHgyMCA9PSAneCcpKSB7CiAgICAgICAgICAgIHJldHVybiBhZGRyZXNzKDApOwogICAgICAgIH0KCiAgICAgICAgdWludCBhZGRyID0gMDsKICAgICAgICAKICAgICAgICBmb3IgKGkrPTI7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKGRpZ2l0ID49IDB4MzAgJiYgZGlnaXQgPD0gMHgzOSkgLy8nMCctJzknCiAgICAgICAgICAgICAgICBkaWdpdCAtPSAweDMwOwogICAgICAgICAgICBlbHNlIGlmIChkaWdpdHwweDIwID49IDB4NjEgJiYgZGlnaXR8MHgyMCA8PSAweDY2KSAvLydhJy0nZicKICAgICAgICAgICAgICAgIGRpZ2l0ID0gZGlnaXQtMHg2MSsxMDsKICAgICAgICAgICAgZWxzZSAKICAgICAgICAgICAgICAgIHJldHVybiBhZGRyZXNzKDApOyAKICAgICAgICAgICAgCiAgICAgICAgICAgIGFkZHIgPSBhZGRyKjE2K2RpZ2l0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gYWRkcmVzcyhhZGRyKTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9LZXlWYWx1ZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfa2V5KS5sZW5ndGggKyA1KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBrZXlwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAga2V5cHRyIDo9IGFkZChfa2V5LCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQgcG9zID0gMDsKCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBrZXlwdHIsIGJ5dGVzKF9rZXkpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9rZXkpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJzonOwogICAgICAgIAogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc2VsZnB0ciwgYnl0ZXMoX3NlbGYpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTdHJpbmdWYWx1ZUJ5S2V5KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CgkJX3JldCA9ICIiOwogICAgICAgIGludCBwb3MgPSAtMTsKICAgICAgICB1aW50IHNlYXJjaFN0YXJ0ID0gMDsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCJcIiIuY29uY2F0KF9rZXksICJcIiIpLCBzZWFyY2hTdGFydCk7CiAgICAgICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgICAgIHBvcyA9IF9zZWxmLmluZGV4T2YoIiciLmNvbmNhdChfa2V5LCAiJyIpLCBzZWFyY2hTdGFydCk7CiAgICAgICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHBvcyArPSBpbnQoYnl0ZXMoX2tleSkubGVuZ3RoKzIpOwoKICAgICAgICAgICAgYm9vbCBjb2xvbiA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAodWludChwb3MpIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICcgJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXHQnIAogICAgICAgICAgICAgICAgICAgIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdccicgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xuJykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnOicpIHsKICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgICAgICBjb2xvbiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZih1aW50KHBvcykgPT0gYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzdGFydCArPSAxOwogICAgICAgIAogICAgICAgIGludCBlbmQ7CiAgICAgICAgaWYgKGRvdWJsZVF1b3RlcykgewogICAgICAgICAgICBlbmQgPSBfc2VsZi5pbmRleE9mKCJcIiIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbmQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChzdGFydCkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW5kID09IC0xKSB7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICBfcmV0ID0gX3NlbGYuc3Vic3RyKHVpbnQoc3RhcnQpLCB1aW50KGVuZC1zdGFydCkpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRJbnRWYWx1ZUJ5S2V5KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwb3MgKz0gaW50KGJ5dGVzKF9rZXkpLmxlbmd0aCsyKTsKCiAgICAgICAgICAgIGJvb2wgY29sb24gPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKHVpbnQocG9zKSA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnICcgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1x0JyAKICAgICAgICAgICAgICAgICAgICB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXHInIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcbicpIHsKICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJzonKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICAgICAgY29sb24gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodWludChwb3MpID09IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29sb24pIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VhcmNoU3RhcnQgPSB1aW50KHBvcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHVpbnQgaSA9IHVpbnQocG9zKTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBIAogICAgICAgICAgICB8fCBkaWdpdCA9PSAweDNBIC8qOiovIHx8IGRpZ2l0ID09IDB4MjIgLyoiKi8gfHwgZGlnaXQgPT0gMHgyNyAvKicqLykpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGJvb2wgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPT0gJysnKSB7CiAgICAgICAgICAgIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0gZWxzZSBpZihieXRlcyhfc2VsZilbaV0gPT0gJy0nKSB7CiAgICAgICAgICAgIHBvc2l0aXZlID0gZmFsc2U7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9CgogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID49IDB4MzAgJiYgZGlnaXQgPD0gMHgzOSkpIHsKICAgICAgICAgICAgICAgIGlmICghcG9zaXRpdmUpIHsKICAgICAgICAgICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIHRvVXBwZXJjYXNlKHN0cmluZyBtZW1vcnkgc3JjKSBpbnRlcm5hbCBwdXJlIHJldHVybnMoc3RyaW5nIG1lbW9yeSl7CiAgICAgICAgYnl0ZXMgbWVtb3J5IHNyY2IgPSBieXRlcyhzcmMpOwogICAgICAgIGZvcih1aW50IGk9MDtpPHNyY2IubGVuZ3RoO2krKyl7CiAgICAgICAgICAgIGJ5dGUgYiA9IHNyY2JbaV07CiAgICAgICAgICAgIGlmKGIgPj0gJ2EnICYmIGIgPD0gJ3onKXsKICAgICAgICAgICAgICAgIGIgJj0gYnl0ZSgweERGKTsvLyAtMzIKICAgICAgICAgICAgICAgIHNyY2JbaV0gPSBiIDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc3JjOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0xvd2VyY2FzZShzdHJpbmcgbWVtb3J5IHNyYykgaW50ZXJuYWwgcHVyZSByZXR1cm5zKHN0cmluZyBtZW1vcnkpewogICAgICAgIGJ5dGVzIG1lbW9yeSBzcmNiID0gYnl0ZXMoc3JjKTsKICAgICAgICBmb3IodWludCBpPTA7aTxzcmNiLmxlbmd0aDtpKyspewogICAgICAgICAgICBieXRlIGIgPSBzcmNiW2ldOwogICAgICAgICAgICBpZihiID49ICdBJyAmJiBiIDw9ICdaJyl7CiAgICAgICAgICAgICAgICBiIHw9IDB4MjA7CiAgICAgICAgICAgICAgICBzcmNiW2ldID0gYjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc3JjOwogICAgfQoKCQogICAgZnVuY3Rpb24ga2V5RXhpc3RzKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIG1lbW9yeSBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHMoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KIAogICAgZnVuY3Rpb24gaW5BcnJheU5vQ2FzZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFsc05vQ2FzZShfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICB9", "contractDesc_en" : "# String library\n\nString library\n\nProvides common string-related operations, including copying, finding, replacing, and so on。" }, { @@ -343,4 +343,4 @@ "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=", "contractDesc_en" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n" } -] \ No newline at end of file +]