diff --git a/Gruntfile.js b/Gruntfile.js index 1a1917cb..dccf85d5 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -23,11 +23,12 @@ module.exports = function(grunt) { }, unittests: { files: { - 'test/test-bundle.js': [] + 'test/lib/test-bundle.js': [] }, options: { debug: true, - alias: './test/test-all.js:test-bundle.js' + alias: './test/test-all.js:unittests', + external: [ 'openpgp' ] } }, ci_tests: { diff --git a/Makefile b/Makefile index 99f7deb2..945013b5 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ bundle: @browserify -d -r ./src/:openpgp > ./resources/openpgp.debug.js bundle-test: - @browserify -d -r ./test/test-all.js:test-bundle.js > ./test/test-bundle.js + @browserify -d -r ./test/test-all.js:unittests > ./test/lib/test-bundle.js bundle-ci-test: @browserify -d -x openpgp -r ./test/ci-tests-all.js:ci-tests > ./test/lib/ci-tests-bundle.js diff --git a/resources/openpgp.js b/resources/openpgp.js index 81c9b0af..be013441 100644 --- a/resources/openpgp.js +++ b/resources/openpgp.js @@ -9230,7 +9230,7 @@ var enums = { module.exports = enums; -},{}],"IKGp/G":[function(require,module,exports){ +},{}],"h6CH+m":[function(require,module,exports){ module.exports = require('./openpgp.js'); module.exports.key = require('./key.js'); @@ -9247,7 +9247,7 @@ module.exports.config = require('./config'); module.exports.crypto = require('./crypto'); },{"./cleartext.js":1,"./config":3,"./crypto":16,"./encoding/armor.js":25,"./enums.js":27,"./key.js":30,"./message.js":31,"./openpgp.js":32,"./packet":35,"./type/keyid.js":53,"./type/mpi.js":54,"./type/s2k.js":55,"./util":56}],"openpgp":[function(require,module,exports){ -module.exports=require('IKGp/G'); +module.exports=require('h6CH+m'); },{}],30:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH @@ -9370,6 +9370,19 @@ Key.prototype.getPrivateKeyPacket = function(keyIds) { return findKey(keys, keyIds); }; +/** + * Returns userids + * @return {string} userid[] + */ +Key.prototype.getUserIds = function() { + var userids = []; + var useridPackets = this.packets.filterByTag(enums.packet.userid); + for (var i = 0; i < useridPackets.length; i++) { + userids.push(useridPackets[i].write()); + } + return userids; +}; + /** * Returns true if this is a public key * @return {Boolean} @@ -13295,5 +13308,4 @@ var Util = function() { module.exports = new Util(); },{"../config":3}]},{},[]) -//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jbGVhcnRleHQuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jb21wcmVzc2lvbi9qeGcuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jb25maWcvY29uZmlnLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NmYi5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9jaXBoZXIvYWVzLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NpcGhlci9ibG93ZmlzaC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9jaXBoZXIvY2FzdDUuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vY2lwaGVyL2Rlcy5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9jaXBoZXIvaW5kZXguanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vY2lwaGVyL3R3b2Zpc2guanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vY3J5cHRvLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2hhc2gvaW5kZXguanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vaGFzaC9tZDUuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vaGFzaC9yaXBlLW1kLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2hhc2gvc2hhLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2luZGV4LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL3BrY3MxLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvZHNhLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvZWxnYW1hbC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9wdWJsaWNfa2V5L2luZGV4LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvanNibi5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9wdWJsaWNfa2V5L3JzYS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9yYW5kb20uanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vc2lnbmF0dXJlLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvZW5jb2RpbmcvYXJtb3IuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9lbmNvZGluZy9iYXNlNjQuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9lbnVtcy5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2luZGV4LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMva2V5LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvbWVzc2FnZS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL29wZW5wZ3AuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvYWxsX3BhY2tldHMuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvY29tcHJlc3NlZC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9pbmRleC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9saXRlcmFsLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L21hcmtlci5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9vbmVfcGFzc19zaWduYXR1cmUuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvcGFja2V0LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3BhY2tldGxpc3QuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvcHVibGljX2tleS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9wdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9wdWJsaWNfc3Via2V5LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3NlY3JldF9rZXkuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvc2VjcmV0X3N1YmtleS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9zaWduYXR1cmUuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3N5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvc3ltbWV0cmljYWxseV9lbmNyeXB0ZWQuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvdHJ1c3QuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvdXNlcl9hdHRyaWJ1dGUuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvdXNlcmlkLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvdHlwZS9rZXlpZC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3R5cGUvbXBpLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvdHlwZS9zMmsuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy91dGlsL3V0aWwuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbnZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNWxDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDenFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOVJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbFFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFtQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0tBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKTtcbnZhciBwYWNrZXQgPSByZXF1aXJlKCcuL3BhY2tldCcpO1xudmFyIGVudW1zID0gcmVxdWlyZSgnLi9lbnVtcy5qcycpO1xudmFyIGFybW9yID0gcmVxdWlyZSgnLi9lbmNvZGluZy9hcm1vci5qcycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBDbGFzcyB0aGF0IHJlcHJlc2VudHMgYW4gT3BlblBHUCBjbGVhcnRleHQgc2lnbmVkIG1lc3NhZ2UuXG4gKiBTZWUgaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNDg4MCNzZWN0aW9uLTdcbiAqIEBwYXJhbSAge1N0cmluZ30gICAgIHRleHQgICAgICAgVGhlIGNsZWFydGV4dCBvZiB0aGUgc2lnbmVkIG1lc3NhZ2VcbiAqIEBwYXJhbSAge3BhY2tldGxpc3R9IHBhY2tldGxpc3QgVGhlIHBhY2tldGxpc3Qgd2l0aCBzaWduYXR1cmUgcGFja2V0cyBvciB1bmRlZmluZWRcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbWVzc2FnZSBub3QgeWV0IHNpZ25lZFxuICovXG5cbmZ1bmN0aW9uIENsZWFydGV4dE1lc3NhZ2UodGV4dCwgcGFja2V0bGlzdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ2xlYXJ0ZXh0TWVzc2FnZSkpIHtcbiAgICByZXR1cm4gbmV3IENsZWFydGV4dE1lc3NhZ2UocGFja2V0bGlzdCk7XG4gIH1cbiAgLy8gbm9ybWFsaXplIEVPTCB0byBjYW5vbmljYWwgZm9ybSA8Q1I+PExGPlxuICB0aGlzLnRleHQgPSB0ZXh0LnJlcGxhY2UoL1xcci9nLCAnJykucmVwbGFjZSgvW1xcdCBdK1xcbi9nLCBcIlxcblwiKS5yZXBsYWNlKC9cXG4vZyxcIlxcclxcblwiKTtcbiAgdGhpcy5wYWNrZXRzID0gcGFja2V0bGlzdCB8fCBuZXcgcGFja2V0Lmxpc3QoKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBrZXkgSURzIG9mIHRoZSBrZXlzIHRoYXQgc2lnbmVkIHRoZSBjbGVhcnRleHQgbWVzc2FnZVxuICogQHJldHVybiB7W2tleUlkXX0gYXJyYXkgb2Yga2V5aWQgb2JqZWN0c1xuICovXG5DbGVhcnRleHRNZXNzYWdlLnByb3RvdHlwZS5nZXRTaWduaW5nS2V5SWRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrZXlJZHMgPSBbXTtcbiAgdmFyIHNpZ25hdHVyZUxpc3QgPSB0aGlzLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnNpZ25hdHVyZSk7XG4gIHNpZ25hdHVyZUxpc3QuZm9yRWFjaChmdW5jdGlvbihwYWNrZXQpIHtcbiAgICBrZXlJZHMucHVzaChwYWNrZXQuaXNzdWVyS2V5SWQpO1xuICB9KTtcbiAgcmV0dXJuIGtleUlkcztcbn07XG5cbi8qKlxuICogU2lnbiB0aGUgY2xlYXJ0ZXh0IG1lc3NhZ2VcbiAqIEBwYXJhbSAge1trZXldfSBwcml2YXRlS2V5cyBwcml2YXRlIGtleXMgd2l0aCBkZWNyeXB0ZWQgc2VjcmV0IGtleSBkYXRhIGZvciBzaWduaW5nXG4gKi9cbkNsZWFydGV4dE1lc3NhZ2UucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbihwcml2YXRlS2V5cykge1xuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpOyAgXG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldCA9IG5ldyBwYWNrZXQubGl0ZXJhbCgpO1xuICBsaXRlcmFsRGF0YVBhY2tldC5zZXRUZXh0KHRoaXMudGV4dCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJpdmF0ZUtleXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc2lnbmF0dXJlUGFja2V0ID0gbmV3IHBhY2tldC5zaWduYXR1cmUoKTtcbiAgICBzaWduYXR1cmVQYWNrZXQuc2lnbmF0dXJlVHlwZSA9IGVudW1zLnNpZ25hdHVyZS50ZXh0O1xuICAgIHNpZ25hdHVyZVBhY2tldC5oYXNoQWxnb3JpdGhtID0gY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobTtcbiAgICB2YXIgc2lnbmluZ0tleVBhY2tldCA9IHByaXZhdGVLZXlzW2ldLmdldFNpZ25pbmdLZXlQYWNrZXQoKTtcbiAgICBzaWduYXR1cmVQYWNrZXQucHVibGljS2V5QWxnb3JpdGhtID0gc2lnbmluZ0tleVBhY2tldC5hbGdvcml0aG07XG4gICAgaWYgKCFzaWduaW5nS2V5UGFja2V0LmlzRGVjcnlwdGVkKSB0aHJvdyBuZXcgRXJyb3IoJ1ByaXZhdGUga2V5IGlzIG5vdCBkZWNyeXB0ZWQuJyk7XG4gICAgc2lnbmF0dXJlUGFja2V0LnNpZ24oc2lnbmluZ0tleVBhY2tldCwgbGl0ZXJhbERhdGFQYWNrZXQpO1xuICAgIHBhY2tldGxpc3QucHVzaChzaWduYXR1cmVQYWNrZXQpO1xuICB9XG4gIHRoaXMucGFja2V0cyA9IHBhY2tldGxpc3Q7XG59O1xuXG4vKipcbiAqIFZlcmlmeSBzaWduYXR1cmVzIG9mIGNsZWFydGV4dCBzaWduZWQgbWVzc2FnZVxuICogQHBhcmFtIHtba2V5XX0gcHVibGljS2V5cyBwdWJsaWMga2V5cyB0byB2ZXJpZnkgc2lnbmF0dXJlc1xuICogQHJldHVybiB7W3sna2V5aWQnOiBrZXlpZCwgJ3ZhbGlkJzogQm9vbGVhbn1dfSBsaXN0IG9mIHNpZ25lcidzIGtleWlkIGFuZCB2YWxpZGl0eSBvZiBzaWduYXR1cmVcbiAqL1xuQ2xlYXJ0ZXh0TWVzc2FnZS5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24ocHVibGljS2V5cykge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBzaWduYXR1cmVMaXN0ID0gdGhpcy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5zaWduYXR1cmUpO1xuICB2YXIgbGl0ZXJhbERhdGFQYWNrZXQgPSBuZXcgcGFja2V0LmxpdGVyYWwoKTtcbiAgLy8gd2UgYXNzdW1lIHRoYXQgY2xlYXJ0ZXh0IHNpZ25hdHVyZSBpcyBnZW5lcmF0ZWQgYmFzZWQgb24gVVRGOCBjbGVhcnRleHQsXG4gIC8vIGZhaWxzIGZvciBvdGhlciBlbmNvZGluZ3MsIHNlZSBDUC0xMjUyIHRlc3QgY2FzZSBpbiB0ZXN0L3NpZ25hdHVyZS5qc1xuICBsaXRlcmFsRGF0YVBhY2tldC5zZXRUZXh0KHRoaXMudGV4dCk7XG4gIHB1YmxpY0tleXMuZm9yRWFjaChmdW5jdGlvbihwdWJLZXkpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ25hdHVyZUxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBwdWJsaWNLZXlQYWNrZXQgPSBwdWJLZXkuZ2V0UHVibGljS2V5UGFja2V0KFtzaWduYXR1cmVMaXN0W2ldLmlzc3VlcktleUlkXSk7XG4gICAgICBpZiAocHVibGljS2V5UGFja2V0KSB7XG4gICAgICAgIHZhciB2ZXJpZmllZFNpZyA9IHt9O1xuICAgICAgICB2ZXJpZmllZFNpZy5rZXlpZCA9IHNpZ25hdHVyZUxpc3RbaV0uaXNzdWVyS2V5SWQ7XG4gICAgICAgIHZlcmlmaWVkU2lnLnN0YXR1cyA9IHNpZ25hdHVyZUxpc3RbaV0udmVyaWZ5KHB1YmxpY0tleVBhY2tldCwgbGl0ZXJhbERhdGFQYWNrZXQpO1xuICAgICAgICByZXN1bHQucHVzaCh2ZXJpZmllZFNpZyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIEdldCBjbGVhcnRleHRcbiAqIEByZXR1cm4ge1N0cmluZ30gY2xlYXJ0ZXh0IG9mIG1lc3NhZ2VcbiAqL1xuQ2xlYXJ0ZXh0TWVzc2FnZS5wcm90b3R5cGUuZ2V0VGV4dCA9IGZ1bmN0aW9uKCkge1xuICAvLyBub3JtYWxpemUgZW5kIG9mIGxpbmUgdG8gXFxuXG4gIHJldHVybiB0aGlzLnRleHQucmVwbGFjZSgvXFxyXFxuL2csXCJcXG5cIik7XG59O1xuXG4vKipcbiAqIFJldHVybnMgQVNDSUkgYXJtb3JlZCB0ZXh0IG9mIGNsZWFydGV4dCBzaWduZWQgbWVzc2FnZVxuICogQHJldHVybiB7U3RyaW5nfSBBU0NJSSBhcm1vclxuICovXG5DbGVhcnRleHRNZXNzYWdlLnByb3RvdHlwZS5hcm1vciA9IGZ1bmN0aW9uKCkge1xuICB2YXIgYm9keSA9IHtcbiAgICBoYXNoOiBlbnVtcy5yZWFkKGVudW1zLmhhc2gsIGNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG0pLnRvVXBwZXJDYXNlKCksXG4gICAgdGV4dDogdGhpcy50ZXh0LFxuICAgIGRhdGE6IHRoaXMucGFja2V0cy53cml0ZSgpXG4gIH1cbiAgcmV0dXJuIGFybW9yLmVuY29kZShlbnVtcy5hcm1vci5zaWduZWQsIGJvZHkpO1xufTtcblxuXG4vKipcbiAqIHJlYWRzIGFuIE9wZW5QR1AgY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlIGFuZCByZXR1cm5zIGEgQ2xlYXJ0ZXh0TWVzc2FnZSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBhcm1vcmVkVGV4dCB0ZXh0IHRvIGJlIHBhcnNlZFxuICogQHJldHVybiB7Q2xlYXJ0ZXh0TWVzc2FnZX0gbmV3IGNsZWFydGV4dCBtZXNzYWdlIG9iamVjdFxuICovXG5mdW5jdGlvbiByZWFkQXJtb3JlZChhcm1vcmVkVGV4dCkge1xuICB2YXIgaW5wdXQgPSBhcm1vci5kZWNvZGUoYXJtb3JlZFRleHQpO1xuICBpZiAoaW5wdXQudHlwZSAhPT0gZW51bXMuYXJtb3Iuc2lnbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyBjbGVhcnRleHQgc2lnbmVkIG1lc3NhZ2UuJyk7XG4gIH1cbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgcGFja2V0bGlzdC5yZWFkKGlucHV0LmRhdGEpO1xuICB2YXIgbmV3TWVzc2FnZSA9IG5ldyBDbGVhcnRleHRNZXNzYWdlKGlucHV0LnRleHQsIHBhY2tldGxpc3QpO1xuICByZXR1cm4gbmV3TWVzc2FnZTtcbn1cblxuZXhwb3J0cy5DbGVhcnRleHRNZXNzYWdlID0gQ2xlYXJ0ZXh0TWVzc2FnZTtcbmV4cG9ydHMucmVhZEFybW9yZWQgPSByZWFkQXJtb3JlZDtcbiIsIkpYRyA9IHtcbiAgZXhpc3RzOiAoZnVuY3Rpb24odW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHYpIHtcbiAgICAgIHJldHVybiAhKHYgPT09IHVuZGVmaW5lZCB8fCB2ID09PSBudWxsKTtcbiAgICB9XG4gIH0pKClcbn07XG5KWEcuZGVjb21wcmVzcyA9IGZ1bmN0aW9uKHN0cikge1xuICByZXR1cm4gdW5lc2NhcGUoKG5ldyBKWEcuVXRpbC5VbnppcChKWEcuVXRpbC5CYXNlNjQuZGVjb2RlQXNBcnJheShzdHIpKSkudW56aXAoKVswXVswXSk7XG59O1xuLypcbiAgICBDb3B5cmlnaHQgMjAwOC0yMDEyXG4gICAgICAgIE1hdHRoaWFzIEVobWFubixcbiAgICAgICAgTWljaGFlbCBHZXJoYWV1c2VyLFxuICAgICAgICBDYXJzdGVuIE1pbGxlcixcbiAgICAgICAgQmlhbmNhIFZhbGVudGluLFxuICAgICAgICBBbGZyZWQgV2Fzc2VybWFubixcbiAgICAgICAgUGV0ZXIgV2lsZmFocnRcblxuICAgIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEpTWEdyYXBoLlxuICAgIFxuICAgIER1YWwgbGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIFZlcnNpb24gMi4wLCBvciBMR1BMIFZlcnNpb24gMyBsaWNlbnNlcy5cblxuICAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICAgIGFsb25nIHdpdGggSlNYQ29tcHJlc3Nvci4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAgICBcbiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBBcGFjaGUgTGljZW5zZSBhbG9uZyB3aXRoIEpTWENvbXByZXNzb3IuICBcbiAgICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLz4uXG5cbiovXG5cbi8qKlxuICogQGNsYXNzIFV0aWwgY2xhc3NcbiAqIEBjbGFzc2Rlc2MgVXRpbGl0aWVzIGZvciB1bmNvbXByZXNzaW5nIGFuZCBiYXNlNjQgZGVjb2RpbmdcbiAqIENsYXNzIGZvciBndW56aXBwaW5nLCB1bnppcHBpbmcgYW5kIGJhc2U2NCBkZWNvZGluZyBvZiBmaWxlcy5cbiAqIEl0IGlzIHVzZWQgZm9yIHJlYWRpbmcgR0VPTkV4VCwgR2VvZ2VicmEgYW5kIEludGVyZ2VvIGZpbGVzLlxuICpcbiAqIE9ubHkgSHVmZm1hbiBjb2RlcyBhcmUgZGVjb2RlZCBpbiBndW56aXAuXG4gKiBUaGUgY29kZSBpcyBiYXNlZCBvbiB0aGUgc291cmNlIGNvZGUgZm9yIGd1bnppcC5jIGJ5IFBhc2kgT2phbGEgXG4gKiB7QGxpbmsgaHR0cDovL3d3dy5jcy50dXQuZmkvfmFsYmVydC9EZXYvZ3VuemlwL2d1bnppcC5jfVxuICoge0BsaW5rIGh0dHA6Ly93d3cuY3MudHV0LmZpL35hbGJlcnR9XG4gKi9cbkpYRy5VdGlsID0ge307XG5cbi8qKlxuICogVW56aXAgemlwIGZpbGVzXG4gKi9cbkpYRy5VdGlsLlVuemlwID0gZnVuY3Rpb24oYmFycmF5KSB7XG4gIHZhciBvdXRwdXRBcnIgPSBbXSxcbiAgICBvdXRwdXQgPSBcIlwiLFxuICAgIGRlYnVnID0gZmFsc2UsXG4gICAgZ3BmbGFncyxcbiAgICBmaWxlcyA9IDAsXG4gICAgdW56aXBwZWQgPSBbXSxcbiAgICBjcmMsXG4gICAgYnVmMzJrID0gbmV3IEFycmF5KDMyNzY4KSxcbiAgICBiSWR4ID0gMCxcbiAgICBtb2RlWklQID0gZmFsc2UsXG5cbiAgICBDUkMsIFNJWkUsXG5cbiAgICBiaXRSZXZlcnNlID0gW1xuICAgICAgICAweDAwLCAweDgwLCAweDQwLCAweGMwLCAweDIwLCAweGEwLCAweDYwLCAweGUwLFxuICAgICAgICAweDEwLCAweDkwLCAweDUwLCAweGQwLCAweDMwLCAweGIwLCAweDcwLCAweGYwLFxuICAgICAgICAweDA4LCAweDg4LCAweDQ4LCAweGM4LCAweDI4LCAweGE4LCAweDY4LCAweGU4LFxuICAgICAgICAweDE4LCAweDk4LCAweDU4LCAweGQ4LCAweDM4LCAweGI4LCAweDc4LCAweGY4LFxuICAgICAgICAweDA0LCAweDg0LCAweDQ0LCAweGM0LCAweDI0LCAweGE0LCAweDY0LCAweGU0LFxuICAgICAgICAweDE0LCAweDk0LCAweDU0LCAweGQ0LCAweDM0LCAweGI0LCAweDc0LCAweGY0LFxuICAgICAgICAweDBjLCAweDhjLCAweDRjLCAweGNjLCAweDJjLCAweGFjLCAweDZjLCAweGVjLFxuICAgICAgICAweDFjLCAweDljLCAweDVjLCAweGRjLCAweDNjLCAweGJjLCAweDdjLCAweGZjLFxuICAgICAgICAweDAyLCAweDgyLCAweDQyLCAweGMyLCAweDIyLCAweGEyLCAweDYyLCAweGUyLFxuICAgICAgICAweDEyLCAweDkyLCAweDUyLCAweGQyLCAweDMyLCAweGIyLCAweDcyLCAweGYyLFxuICAgICAgICAweDBhLCAweDhhLCAweDRhLCAweGNhLCAweDJhLCAweGFhLCAweDZhLCAweGVhLFxuICAgICAgICAweDFhLCAweDlhLCAweDVhLCAweGRhLCAweDNhLCAweGJhLCAweDdhLCAweGZhLFxuICAgICAgICAweDA2LCAweDg2LCAweDQ2LCAweGM2LCAweDI2LCAweGE2LCAweDY2LCAweGU2LFxuICAgICAgICAweDE2LCAweDk2LCAweDU2LCAweGQ2LCAweDM2LCAweGI2LCAweDc2LCAweGY2LFxuICAgICAgICAweDBlLCAweDhlLCAweDRlLCAweGNlLCAweDJlLCAweGFlLCAweDZlLCAweGVlLFxuICAgICAgICAweDFlLCAweDllLCAweDVlLCAweGRlLCAweDNlLCAweGJlLCAweDdlLCAweGZlLFxuICAgICAgICAweDAxLCAweDgxLCAweDQxLCAweGMxLCAweDIxLCAweGExLCAweDYxLCAweGUxLFxuICAgICAgICAweDExLCAweDkxLCAweDUxLCAweGQxLCAweDMxLCAweGIxLCAweDcxLCAweGYxLFxuICAgICAgICAweDA5LCAweDg5LCAweDQ5LCAweGM5LCAweDI5LCAweGE5LCAweDY5LCAweGU5LFxuICAgICAgICAweDE5LCAweDk5LCAweDU5LCAweGQ5LCAweDM5LCAweGI5LCAweDc5LCAweGY5LFxuICAgICAgICAweDA1LCAweDg1LCAweDQ1LCAweGM1LCAweDI1LCAweGE1LCAweDY1LCAweGU1LFxuICAgICAgICAweDE1LCAweDk1LCAweDU1LCAweGQ1LCAweDM1LCAweGI1LCAweDc1LCAweGY1LFxuICAgICAgICAweDBkLCAweDhkLCAweDRkLCAweGNkLCAweDJkLCAweGFkLCAweDZkLCAweGVkLFxuICAgICAgICAweDFkLCAweDlkLCAweDVkLCAweGRkLCAweDNkLCAweGJkLCAweDdkLCAweGZkLFxuICAgICAgICAweDAzLCAweDgzLCAweDQzLCAweGMzLCAweDIzLCAweGEzLCAweDYzLCAweGUzLFxuICAgICAgICAweDEzLCAweDkzLCAweDUzLCAweGQzLCAweDMzLCAweGIzLCAweDczLCAweGYzLFxuICAgICAgICAweDBiLCAweDhiLCAweDRiLCAweGNiLCAweDJiLCAweGFiLCAweDZiLCAweGViLFxuICAgICAgICAweDFiLCAweDliLCAweDViLCAweGRiLCAweDNiLCAweGJiLCAweDdiLCAweGZiLFxuICAgICAgICAweDA3LCAweDg3LCAweDQ3LCAweGM3LCAweDI3LCAweGE3LCAweDY3LCAweGU3LFxuICAgICAgICAweDE3LCAweDk3LCAweDU3LCAweGQ3LCAweDM3LCAweGI3LCAweDc3LCAweGY3LFxuICAgICAgICAweDBmLCAweDhmLCAweDRmLCAweGNmLCAweDJmLCAweGFmLCAweDZmLCAweGVmLFxuICAgICAgICAweDFmLCAweDlmLCAweDVmLCAweGRmLCAweDNmLCAweGJmLCAweDdmLCAweGZmXG4gICAgXSxcblxuICAgIGNwbGVucyA9IFtcbiAgICAgICAgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMywgMTUsIDE3LCAxOSwgMjMsIDI3LCAzMSxcbiAgICAgICAgMzUsIDQzLCA1MSwgNTksIDY3LCA4MywgOTksIDExNSwgMTMxLCAxNjMsIDE5NSwgMjI3LCAyNTgsIDAsIDBcbiAgICBdLFxuXG4gICAgY3BsZXh0ID0gW1xuICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAyLCAyLCAyLCAyLFxuICAgICAgICAzLCAzLCAzLCAzLCA0LCA0LCA0LCA0LCA1LCA1LCA1LCA1LCAwLCA5OSwgOTlcbiAgICBdLFxuICAgIC8qIDk5PT1pbnZhbGlkICovXG5cbiAgICBjcGRpc3QgPSBbXG4gICAgICAgIDB4MDAwMSwgMHgwMDAyLCAweDAwMDMsIDB4MDAwNCwgMHgwMDA1LCAweDAwMDcsIDB4MDAwOSwgMHgwMDBkLFxuICAgICAgICAweDAwMTEsIDB4MDAxOSwgMHgwMDIxLCAweDAwMzEsIDB4MDA0MSwgMHgwMDYxLCAweDAwODEsIDB4MDBjMSxcbiAgICAgICAgMHgwMTAxLCAweDAxODEsIDB4MDIwMSwgMHgwMzAxLCAweDA0MDEsIDB4MDYwMSwgMHgwODAxLCAweDBjMDEsXG4gICAgICAgIDB4MTAwMSwgMHgxODAxLCAweDIwMDEsIDB4MzAwMSwgMHg0MDAxLCAweDYwMDFcbiAgICBdLFxuXG4gICAgY3BkZXh0ID0gW1xuICAgICAgICAwLCAwLCAwLCAwLCAxLCAxLCAyLCAyLFxuICAgICAgICAzLCAzLCA0LCA0LCA1LCA1LCA2LCA2LFxuICAgICAgICA3LCA3LCA4LCA4LCA5LCA5LCAxMCwgMTAsXG4gICAgICAgIDExLCAxMSwgMTIsIDEyLCAxMywgMTNcbiAgICBdLFxuXG4gICAgYm9yZGVyID0gWzE2LCAxNywgMTgsIDAsIDgsIDcsIDksIDYsIDEwLCA1LCAxMSwgNCwgMTIsIDMsIDEzLCAyLCAxNCwgMSwgMTVdLFxuXG4gICAgYkEgPSBiYXJyYXksXG5cbiAgICBieXRlcG9zID0gMCxcbiAgICBiaXRwb3MgPSAwLFxuICAgIGJiID0gMSxcbiAgICBiaXRzID0gMCxcblxuICAgIE5BTUVNQVggPSAyNTYsXG5cbiAgICBuYW1lQnVmID0gW10sXG5cbiAgICBmaWxlb3V0O1xuXG4gIGZ1bmN0aW9uIHJlYWRCeXRlKCkge1xuICAgIGJpdHMgKz0gODtcbiAgICBpZiAoYnl0ZXBvcyA8IGJBLmxlbmd0aCkge1xuICAgICAgLy9pZiAoZGVidWcpXG4gICAgICAvLyAgICBkb2N1bWVudC53cml0ZShieXRlcG9zK1wiOiBcIitiQVtieXRlcG9zXStcIjxicj5cIik7XG4gICAgICByZXR1cm4gYkFbYnl0ZXBvcysrXTtcbiAgICB9IGVsc2VcbiAgICAgIHJldHVybiAtMTtcbiAgfTtcblxuICBmdW5jdGlvbiBieXRlQWxpZ24oKSB7XG4gICAgYmIgPSAxO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHJlYWRCaXQoKSB7XG4gICAgdmFyIGNhcnJ5O1xuICAgIGJpdHMrKztcbiAgICBjYXJyeSA9IChiYiAmIDEpO1xuICAgIGJiID4+PSAxO1xuICAgIGlmIChiYiA9PSAwKSB7XG4gICAgICBiYiA9IHJlYWRCeXRlKCk7XG4gICAgICBjYXJyeSA9IChiYiAmIDEpO1xuICAgICAgYmIgPSAoYmIgPj4gMSkgfCAweDgwO1xuICAgIH1cbiAgICByZXR1cm4gY2Fycnk7XG4gIH07XG5cbiAgZnVuY3Rpb24gcmVhZEJpdHMoYSkge1xuICAgIHZhciByZXMgPSAwLFxuICAgICAgaSA9IGE7XG5cbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICByZXMgPSAocmVzIDw8IDEpIHwgcmVhZEJpdCgpO1xuICAgIH1cbiAgICBpZiAoYSkge1xuICAgICAgcmVzID0gYml0UmV2ZXJzZVtyZXNdID4+ICg4IC0gYSk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgZnVuY3Rpb24gZmx1c2hCdWZmZXIoKSB7XG4gICAgLy9kb2N1bWVudC53cml0ZSgnRkxVU0hCVUZGRVI6JytidWYzMmspO1xuICAgIGJJZHggPSAwO1xuICB9O1xuXG4gIGZ1bmN0aW9uIGFkZEJ1ZmZlcihhKSB7XG4gICAgU0laRSsrO1xuICAgIC8vQ1JDPXVwZGNyYyhhLGNyYyk7XG4gICAgYnVmMzJrW2JJZHgrK10gPSBhO1xuICAgIG91dHB1dEFyci5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYSkpO1xuICAgIC8vb3V0cHV0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKGEpO1xuICAgIGlmIChiSWR4ID09IDB4ODAwMCkge1xuICAgICAgLy9kb2N1bWVudC53cml0ZSgnQUREQlVGRkVSOicrYnVmMzJrKTtcbiAgICAgIGJJZHggPSAwO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBIdWZOb2RlKCkge1xuICAgIHRoaXMuYjAgPSAwO1xuICAgIHRoaXMuYjEgPSAwO1xuICAgIHRoaXMuanVtcCA9IG51bGw7XG4gICAgdGhpcy5qdW1wcG9zID0gLTE7XG4gIH07XG5cbiAgdmFyIExJVEVSQUxTID0gMjg4O1xuXG4gIHZhciBsaXRlcmFsVHJlZSA9IG5ldyBBcnJheShMSVRFUkFMUyk7XG4gIHZhciBkaXN0YW5jZVRyZWUgPSBuZXcgQXJyYXkoMzIpO1xuICB2YXIgdHJlZXBvcyA9IDA7XG4gIHZhciBQbGFjZXMgPSBudWxsO1xuICB2YXIgUGxhY2VzMiA9IG51bGw7XG5cbiAgdmFyIGltcERpc3RhbmNlVHJlZSA9IG5ldyBBcnJheSg2NCk7XG4gIHZhciBpbXBMZW5ndGhUcmVlID0gbmV3IEFycmF5KDY0KTtcblxuICB2YXIgbGVuID0gMDtcbiAgdmFyIGZwb3MgPSBuZXcgQXJyYXkoMTcpO1xuICBmcG9zWzBdID0gMDtcbiAgdmFyIGZsZW5zO1xuICB2YXIgZm1heDtcblxuICBmdW5jdGlvbiBJc1BhdCgpIHtcbiAgICB3aGlsZSAoMSkge1xuICAgICAgaWYgKGZwb3NbbGVuXSA+PSBmbWF4KVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgICBpZiAoZmxlbnNbZnBvc1tsZW5dXSA9PSBsZW4pXG4gICAgICAgIHJldHVybiBmcG9zW2xlbl0rKztcbiAgICAgIGZwb3NbbGVuXSsrO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBSZWMoKSB7XG4gICAgdmFyIGN1cnBsYWNlID0gUGxhY2VzW3RyZWVwb3NdO1xuICAgIHZhciB0bXA7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+bGVuOlwiICsgbGVuICsgXCIgdHJlZXBvczpcIiArIHRyZWVwb3MpO1xuICAgIGlmIChsZW4gPT0gMTcpIHsgLy93YXIgMTdcbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgdHJlZXBvcysrO1xuICAgIGxlbisrO1xuXG4gICAgdG1wID0gSXNQYXQoKTtcbiAgICBpZiAoZGVidWcpXG4gICAgICBkb2N1bWVudC53cml0ZShcIjxicj5Jc1BhdCBcIiArIHRtcCk7XG4gICAgaWYgKHRtcCA+PSAwKSB7XG4gICAgICBjdXJwbGFjZS5iMCA9IHRtcDsgLyogbGVhZiBjZWxsIGZvciAwLWJpdCAqL1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5iMCBcIiArIGN1cnBsYWNlLmIwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLyogTm90IGEgTGVhZiBjZWxsICovXG4gICAgICBjdXJwbGFjZS5iMCA9IDB4ODAwMDtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+YjAgXCIgKyBjdXJwbGFjZS5iMCk7XG4gICAgICBpZiAoUmVjKCkpXG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgdG1wID0gSXNQYXQoKTtcbiAgICBpZiAodG1wID49IDApIHtcbiAgICAgIGN1cnBsYWNlLmIxID0gdG1wOyAvKiBsZWFmIGNlbGwgZm9yIDEtYml0ICovXG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPmIxIFwiICsgY3VycGxhY2UuYjEpO1xuICAgICAgY3VycGxhY2UuanVtcCA9IG51bGw7IC8qIEp1c3QgZm9yIHRoZSBkaXNwbGF5IHJvdXRpbmUgKi9cbiAgICB9IGVsc2Uge1xuICAgICAgLyogTm90IGEgTGVhZiBjZWxsICovXG4gICAgICBjdXJwbGFjZS5iMSA9IDB4ODAwMDtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+YjEgXCIgKyBjdXJwbGFjZS5iMSk7XG4gICAgICBjdXJwbGFjZS5qdW1wID0gUGxhY2VzW3RyZWVwb3NdO1xuICAgICAgY3VycGxhY2UuanVtcHBvcyA9IHRyZWVwb3M7XG4gICAgICBpZiAoUmVjKCkpXG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgbGVuLS07XG4gICAgcmV0dXJuIDA7XG4gIH07XG5cbiAgZnVuY3Rpb24gQ3JlYXRlVHJlZShjdXJyZW50VHJlZSwgbnVtdmFsLCBsZW5ndGhzLCBzaG93KSB7XG4gICAgdmFyIGk7XG4gICAgLyogQ3JlYXRlIHRoZSBIdWZmbWFuIGRlY29kZSB0cmVlL3RhYmxlICovXG4gICAgLy9kb2N1bWVudC53cml0ZShcIjxicj5jcmVhdGV0cmVlPGJyPlwiKTtcbiAgICBpZiAoZGVidWcpXG4gICAgICBkb2N1bWVudC53cml0ZShcImN1cnJlbnRUcmVlIFwiICsgY3VycmVudFRyZWUgKyBcIiBudW12YWwgXCIgKyBudW12YWwgKyBcIiBsZW5ndGhzIFwiICsgbGVuZ3RocyArIFwiIHNob3cgXCIgKyBzaG93KTtcbiAgICBQbGFjZXMgPSBjdXJyZW50VHJlZTtcbiAgICB0cmVlcG9zID0gMDtcbiAgICBmbGVucyA9IGxlbmd0aHM7XG4gICAgZm1heCA9IG51bXZhbDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgMTc7IGkrKylcbiAgICAgIGZwb3NbaV0gPSAwO1xuICAgIGxlbiA9IDA7XG4gICAgaWYgKFJlYygpKSB7XG4gICAgICAvL2ZwcmludGYoc3RkZXJyLCBcImludmFsaWQgaHVmZm1hbiB0cmVlXFxuXCIpO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcImludmFsaWQgaHVmZm1hbiB0cmVlXFxuXCIpO1xuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgICBpZiAoZGVidWcpIHtcbiAgICAgIGRvY3VtZW50LndyaXRlKCc8YnI+VHJlZTogJyArIFBsYWNlcy5sZW5ndGgpO1xuICAgICAgZm9yICh2YXIgYSA9IDA7IGEgPCAzMjsgYSsrKSB7XG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiUGxhY2VzW1wiICsgYSArIFwiXS5iMD1cIiArIFBsYWNlc1thXS5iMCArIFwiPGJyPlwiKTtcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCJQbGFjZXNbXCIgKyBhICsgXCJdLmIxPVwiICsgUGxhY2VzW2FdLmIxICsgXCI8YnI+XCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qaWYoc2hvdykge1xuICAgICAgICAgICAgdmFyIHRtcDtcbiAgICAgICAgICAgIGZvcih0bXA9Y3VycmVudFRyZWU7dG1wPFBsYWNlczt0bXArKykge1xuICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCBcIjB4JTAzeCAgMHglMDN4ICgweCUwNHgpXCIsdG1wLWN1cnJlbnRUcmVlLCB0bXAtPmp1bXA/dG1wLT5qdW1wLWN1cnJlbnRUcmVlOjAsKHRtcC0+anVtcD90bXAtPmp1bXAtY3VycmVudFRyZWU6MCkqNisweGNmMCk7XG4gICAgICAgICAgICAgICAgaWYoISh0bXAuYjAgJiAweDgwMDApKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vZnByaW50ZihzdGRvdXQsIFwiICAweCUwM3ggKCVjKVwiLCB0bXAtPmIwLCh0bXAtPmIwPDI1NiAmJiBpc3ByaW50KHRtcC0+YjApKT90bXAtPmIwOifvv70nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYoISh0bXAuYjEgJiAweDgwMDApKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmKCh0bXAuYjAgJiAweDgwMDApKVxuICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRvdXQsIFwiICAgICAgICAgICBcIik7XG4gICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCBcIiAgMHglMDN4ICglYylcIiwgdG1wLT5iMSwodG1wLT5iMTwyNTYgJiYgaXNwcmludCh0bXAtPmIxKSk/dG1wLT5iMTon77+9Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCBcIlxcblwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSovXG4gICAgcmV0dXJuIDA7XG4gIH07XG5cbiAgZnVuY3Rpb24gRGVjb2RlVmFsdWUoY3VycmVudFRyZWUpIHtcbiAgICB2YXIgbGVuLCBpLFxuICAgICAgeHRyZWVwb3MgPSAwLFxuICAgICAgWCA9IGN1cnJlbnRUcmVlW3h0cmVlcG9zXSxcbiAgICAgIGI7XG5cbiAgICAvKiBkZWNvZGUgb25lIHN5bWJvbCBvZiB0aGUgZGF0YSAqL1xuICAgIHdoaWxlICgxKSB7XG4gICAgICBiID0gcmVhZEJpdCgpO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBkb2N1bWVudC53cml0ZShcImI9XCIgKyBiKTtcbiAgICAgIGlmIChiKSB7XG4gICAgICAgIGlmICghKFguYjEgJiAweDgwMDApKSB7XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCJyZXQxXCIpO1xuICAgICAgICAgIHJldHVybiBYLmIxOyAvKiBJZiBsZWFmIG5vZGUsIHJldHVybiBkYXRhICovXG4gICAgICAgIH1cbiAgICAgICAgWCA9IFguanVtcDtcbiAgICAgICAgbGVuID0gY3VycmVudFRyZWUubGVuZ3RoO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICBpZiAoY3VycmVudFRyZWVbaV0gPT09IFgpIHtcbiAgICAgICAgICAgIHh0cmVlcG9zID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL3h0cmVlcG9zKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIShYLmIwICYgMHg4MDAwKSkge1xuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwicmV0MlwiKTtcbiAgICAgICAgICByZXR1cm4gWC5iMDsgLyogSWYgbGVhZiBub2RlLCByZXR1cm4gZGF0YSAqL1xuICAgICAgICB9XG4gICAgICAgIC8vWCsrOyAvLz8/Pz8/Pz8/Pz8/Pz8/Pz8/P1xuICAgICAgICB4dHJlZXBvcysrO1xuICAgICAgICBYID0gY3VycmVudFRyZWVbeHRyZWVwb3NdO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBEZWZsYXRlTG9vcCgpIHtcbiAgICB2YXIgbGFzdCwgYywgdHlwZSwgaSwgbGVuO1xuXG4gICAgZG8ge1xuICAgICAgLyppZigobGFzdCA9IHJlYWRCaXQoKSkpe1xuICAgICAgICAgICAgZnByaW50ZihlcnJmcCwgXCJMYXN0IEJsb2NrOiBcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmcHJpbnRmKGVycmZwLCBcIk5vdCBMYXN0IEJsb2NrOiBcIik7XG4gICAgICAgIH0qL1xuICAgICAgbGFzdCA9IHJlYWRCaXQoKTtcbiAgICAgIHR5cGUgPSByZWFkQml0cygyKTtcbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQoXCJTdG9yZWRcXG5cIik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBhbGVydChcIkZpeGVkIEh1ZmZtYW4gY29kZXNcXG5cIik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBhbGVydChcIkR5bmFtaWMgSHVmZm1hbiBjb2Rlc1xcblwiKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGFsZXJ0KFwiUmVzZXJ2ZWQgYmxvY2sgdHlwZSEhXFxuXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGFsZXJ0KFwiVW5leHBlY3RlZCB2YWx1ZSAlZCFcXG5cIiwgdHlwZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlID09IDApIHtcbiAgICAgICAgdmFyIGJsb2NrTGVuLCBjU3VtO1xuXG4gICAgICAgIC8vIFN0b3JlZCBcbiAgICAgICAgYnl0ZUFsaWduKCk7XG4gICAgICAgIGJsb2NrTGVuID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgYmxvY2tMZW4gfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG5cbiAgICAgICAgY1N1bSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGNTdW0gfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG5cbiAgICAgICAgaWYgKCgoYmxvY2tMZW4gXiB+Y1N1bSkgJiAweGZmZmYpKSB7XG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCJCbG9ja0xlbiBjaGVja3N1bSBtaXNtYXRjaFxcblwiKTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoYmxvY2tMZW4tLSkge1xuICAgICAgICAgIGMgPSByZWFkQnl0ZSgpO1xuICAgICAgICAgIGFkZEJ1ZmZlcihjKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlID09IDEpIHtcbiAgICAgICAgdmFyIGo7XG5cbiAgICAgICAgLyogRml4ZWQgSHVmZm1hbiB0YWJsZXMgLS0gZml4ZWQgZGVjb2RlIHJvdXRpbmUgKi9cbiAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgIDI1NiAgICAwMDAwMDAwICAgICAgICAwXG4gICAgICAgICAgICAgICAgOiAgIDogICAgIDpcbiAgICAgICAgICAgICAgICAyNzkgICAgMDAxMDExMSAgICAgICAgMjNcbiAgICAgICAgICAgICAgICAwICAgMDAxMTAwMDAgICAgNDhcbiAgICAgICAgICAgICAgICA6ICAgIDogICAgICA6XG4gICAgICAgICAgICAgICAgMTQzICAgIDEwMTExMTExICAgIDE5MVxuICAgICAgICAgICAgICAgIDI4MCAxMTAwMDAwMCAgICAxOTJcbiAgICAgICAgICAgICAgICA6ICAgIDogICAgICA6XG4gICAgICAgICAgICAgICAgMjg3IDExMDAwMTExICAgIDE5OVxuICAgICAgICAgICAgICAgIDE0NCAgICAxMTAwMTAwMDAgICAgNDAwXG4gICAgICAgICAgICAgICAgOiAgICA6ICAgICAgIDpcbiAgICAgICAgICAgICAgICAyNTUgICAgMTExMTExMTExICAgIDUxMVxuICAgIFxuICAgICAgICAgICAgICAgIE5vdGUgdGhlIGJpdCBvcmRlciFcbiAgICAgICAgICAgICAgICAqL1xuXG4gICAgICAgICAgaiA9IChiaXRSZXZlcnNlW3JlYWRCaXRzKDcpXSA+PiAxKTtcbiAgICAgICAgICBpZiAoaiA+IDIzKSB7XG4gICAgICAgICAgICBqID0gKGogPDwgMSkgfCByZWFkQml0KCk7IC8qIDQ4Li4yNTUgKi9cblxuICAgICAgICAgICAgaWYgKGogPiAxOTkpIHsgLyogMjAwLi4yNTUgKi9cbiAgICAgICAgICAgICAgaiAtPSAxMjg7IC8qICA3Mi4uMTI3ICovXG4gICAgICAgICAgICAgIGogPSAoaiA8PCAxKSB8IHJlYWRCaXQoKTsgLyogMTQ0Li4yNTUgPDwgKi9cbiAgICAgICAgICAgIH0gZWxzZSB7IC8qICA0OC4uMTk5ICovXG4gICAgICAgICAgICAgIGogLT0gNDg7IC8qICAgMC4uMTUxICovXG4gICAgICAgICAgICAgIGlmIChqID4gMTQzKSB7XG4gICAgICAgICAgICAgICAgaiA9IGogKyAxMzY7IC8qIDI4MC4uMjg3IDw8ICovXG4gICAgICAgICAgICAgICAgLyogICAwLi4xNDMgPDwgKi9cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7IC8qICAgMC4uMjMgKi9cbiAgICAgICAgICAgIGogKz0gMjU2OyAvKiAyNTYuLjI3OSA8PCAqL1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaiA8IDI1Nikge1xuICAgICAgICAgICAgYWRkQnVmZmVyKGopO1xuICAgICAgICAgICAgLy9kb2N1bWVudC53cml0ZShcIm91dDpcIitTdHJpbmcuZnJvbUNoYXJDb2RlKGopKTtcbiAgICAgICAgICAgIC8qZnByaW50ZihlcnJmcCwgXCJAJWQgJTAyeFxcblwiLCBTSVpFLCBqKTsqL1xuICAgICAgICAgIH0gZWxzZSBpZiAoaiA9PSAyNTYpIHtcbiAgICAgICAgICAgIC8qIEVPRiAqL1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBsZW4sIGRpc3Q7XG5cbiAgICAgICAgICAgIGogLT0gMjU2ICsgMTsgLyogYnl0ZXMgKyBFT0YgKi9cbiAgICAgICAgICAgIGxlbiA9IHJlYWRCaXRzKGNwbGV4dFtqXSkgKyBjcGxlbnNbal07XG5cbiAgICAgICAgICAgIGogPSBiaXRSZXZlcnNlW3JlYWRCaXRzKDUpXSA+PiAzO1xuICAgICAgICAgICAgaWYgKGNwZGV4dFtqXSA+IDgpIHtcbiAgICAgICAgICAgICAgZGlzdCA9IHJlYWRCaXRzKDgpO1xuICAgICAgICAgICAgICBkaXN0IHw9IChyZWFkQml0cyhjcGRleHRbal0gLSA4KSA8PCA4KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGRpc3QgPSByZWFkQml0cyhjcGRleHRbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGlzdCArPSBjcGRpc3Rbal07XG5cbiAgICAgICAgICAgIC8qZnByaW50ZihlcnJmcCwgXCJAJWQgKGwlMDJ4LGQlMDR4KVxcblwiLCBTSVpFLCBsZW4sIGRpc3QpOyovXG4gICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgbGVuOyBqKyspIHtcbiAgICAgICAgICAgICAgdmFyIGMgPSBidWYzMmtbKGJJZHggLSBkaXN0KSAmIDB4N2ZmZl07XG4gICAgICAgICAgICAgIGFkZEJ1ZmZlcihjKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gLy8gd2hpbGVcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSAyKSB7XG4gICAgICAgIHZhciBqLCBuLCBsaXRlcmFsQ29kZXMsIGRpc3RDb2RlcywgbGVuQ29kZXM7XG4gICAgICAgIHZhciBsbCA9IG5ldyBBcnJheSgyODggKyAzMik7IC8vIFwic3RhdGljXCIganVzdCB0byBwcmVzZXJ2ZSBzdGFja1xuXG4gICAgICAgIC8vIER5bmFtaWMgSHVmZm1hbiB0YWJsZXMgXG5cbiAgICAgICAgbGl0ZXJhbENvZGVzID0gMjU3ICsgcmVhZEJpdHMoNSk7XG4gICAgICAgIGRpc3RDb2RlcyA9IDEgKyByZWFkQml0cyg1KTtcbiAgICAgICAgbGVuQ29kZXMgPSA0ICsgcmVhZEJpdHMoNCk7XG4gICAgICAgIC8vZG9jdW1lbnQud3JpdGUoXCI8YnI+cGFyYW06IFwiK2xpdGVyYWxDb2RlcytcIiBcIitkaXN0Q29kZXMrXCIgXCIrbGVuQ29kZXMrXCI8YnI+XCIpO1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgMTk7IGorKykge1xuICAgICAgICAgIGxsW2pdID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCB0aGUgZGVjb2RlIHRyZWUgY29kZSBsZW5ndGhzXG5cbiAgICAgICAgLy9kb2N1bWVudC53cml0ZShcIjxicj5cIik7XG4gICAgICAgIGZvciAoaiA9IDA7IGogPCBsZW5Db2RlczsgaisrKSB7XG4gICAgICAgICAgbGxbYm9yZGVyW2pdXSA9IHJlYWRCaXRzKDMpO1xuICAgICAgICAgIC8vZG9jdW1lbnQud3JpdGUobGxbYm9yZGVyW2pdXStcIiBcIik7XG4gICAgICAgIH1cbiAgICAgICAgLy9mcHJpbnRmKGVycmZwLCBcIlxcblwiKTtcbiAgICAgICAgLy9kb2N1bWVudC53cml0ZSgnPGJyPmxsOicrbGwpO1xuICAgICAgICBsZW4gPSBkaXN0YW5jZVRyZWUubGVuZ3RoO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICAgICAgZGlzdGFuY2VUcmVlW2ldID0gbmV3IEh1Zk5vZGUoKTtcbiAgICAgICAgaWYgKENyZWF0ZVRyZWUoZGlzdGFuY2VUcmVlLCAxOSwgbGwsIDApKSB7XG4gICAgICAgICAgZmx1c2hCdWZmZXIoKTtcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5kaXN0YW5jZVRyZWVcIik7XG4gICAgICAgICAgZm9yICh2YXIgYSA9IDA7IGEgPCBkaXN0YW5jZVRyZWUubGVuZ3RoOyBhKyspIHtcbiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPlwiICsgZGlzdGFuY2VUcmVlW2FdLmIwICsgXCIgXCIgKyBkaXN0YW5jZVRyZWVbYV0uYjEgKyBcIiBcIiArIGRpc3RhbmNlVHJlZVthXS5qdW1wICsgXCIgXCIgK1xuICAgICAgICAgICAgICBkaXN0YW5jZVRyZWVbYV0uanVtcHBvcyk7XG4gICAgICAgICAgICAvKmlmIChkaXN0YW5jZVRyZWVbYV0uanVtcHBvcyE9LTEpXG4gICAgICAgICAgICAgICAgICAgIFx0ZG9jdW1lbnQud3JpdGUoXCIgXCIrZGlzdGFuY2VUcmVlW2FdLmp1bXAuYjArXCIgXCIrZGlzdGFuY2VUcmVlW2FdLmp1bXAuYjEpO1xuICAgICAgICAgICAgICAgIFx0Ki9cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy9kb2N1bWVudC53cml0ZSgnPEJSPnRyZWUgY3JlYXRlZCcpO1xuXG4gICAgICAgIC8vcmVhZCBpbiBsaXRlcmFsIGFuZCBkaXN0YW5jZSBjb2RlIGxlbmd0aHNcbiAgICAgICAgbiA9IGxpdGVyYWxDb2RlcyArIGRpc3RDb2RlcztcbiAgICAgICAgaSA9IDA7XG4gICAgICAgIHZhciB6ID0gLTE7XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5uPVwiICsgbiArIFwiIGJpdHM6IFwiICsgYml0cyArIFwiPGJyPlwiKTtcbiAgICAgICAgd2hpbGUgKGkgPCBuKSB7XG4gICAgICAgICAgeisrO1xuICAgICAgICAgIGogPSBEZWNvZGVWYWx1ZShkaXN0YW5jZVRyZWUpO1xuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPlwiICsgeiArIFwiIGk6XCIgKyBpICsgXCIgZGVjb2RlOiBcIiArIGogKyBcIiAgICBiaXRzIFwiICsgYml0cyArIFwiPGJyPlwiKTtcbiAgICAgICAgICBpZiAoaiA8IDE2KSB7IC8vIGxlbmd0aCBvZiBjb2RlIGluIGJpdHMgKDAuLjE1KVxuICAgICAgICAgICAgbGxbaSsrXSA9IGo7XG4gICAgICAgICAgfSBlbHNlIGlmIChqID09IDE2KSB7IC8vIHJlcGVhdCBsYXN0IGxlbmd0aCAzIHRvIDYgdGltZXMgXG4gICAgICAgICAgICB2YXIgbDtcbiAgICAgICAgICAgIGogPSAzICsgcmVhZEJpdHMoMik7XG4gICAgICAgICAgICBpZiAoaSArIGogPiBuKSB7XG4gICAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbCA9IGkgPyBsbFtpIC0gMV0gOiAwO1xuICAgICAgICAgICAgd2hpbGUgKGotLSkge1xuICAgICAgICAgICAgICBsbFtpKytdID0gbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGogPT0gMTcpIHsgLy8gMyB0byAxMCB6ZXJvIGxlbmd0aCBjb2Rlc1xuICAgICAgICAgICAgICBqID0gMyArIHJlYWRCaXRzKDMpO1xuICAgICAgICAgICAgfSBlbHNlIHsgLy8gaiA9PSAxODogMTEgdG8gMTM4IHplcm8gbGVuZ3RoIGNvZGVzIFxuICAgICAgICAgICAgICBqID0gMTEgKyByZWFkQml0cyg3KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpICsgaiA+IG4pIHtcbiAgICAgICAgICAgICAgZmx1c2hCdWZmZXIoKTtcbiAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3aGlsZSAoai0tKSB7XG4gICAgICAgICAgICAgIGxsW2krK10gPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvKmZvcihqPTA7IGo8bGl0ZXJhbENvZGVzK2Rpc3RDb2RlczsgaisrKSB7XG4gICAgICAgICAgICAgICAgLy9mcHJpbnRmKGVycmZwLCBcIiVkIFwiLCBsbFtqXSk7XG4gICAgICAgICAgICAgICAgaWYgKChqJjcpPT03KVxuICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKGVycmZwLCBcIlxcblwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZwcmludGYoZXJyZnAsIFwiXFxuXCIpOyovXG4gICAgICAgIC8vIENhbiBvdmVyd3JpdGUgdHJlZSBkZWNvZGUgdHJlZSBhcyBpdCBpcyBub3QgdXNlZCBhbnltb3JlXG4gICAgICAgIGxlbiA9IGxpdGVyYWxUcmVlLmxlbmd0aDtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgIGxpdGVyYWxUcmVlW2ldID0gbmV3IEh1Zk5vZGUoKTtcbiAgICAgICAgaWYgKENyZWF0ZVRyZWUobGl0ZXJhbFRyZWUsIGxpdGVyYWxDb2RlcywgbGwsIDApKSB7XG4gICAgICAgICAgZmx1c2hCdWZmZXIoKTtcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBsZW4gPSBsaXRlcmFsVHJlZS5sZW5ndGg7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgICAgICBkaXN0YW5jZVRyZWVbaV0gPSBuZXcgSHVmTm9kZSgpO1xuICAgICAgICB2YXIgbGwyID0gbmV3IEFycmF5KCk7XG4gICAgICAgIGZvciAoaSA9IGxpdGVyYWxDb2RlczsgaSA8IGxsLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgbGwyW2kgLSBsaXRlcmFsQ29kZXNdID0gbGxbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKENyZWF0ZVRyZWUoZGlzdGFuY2VUcmVlLCBkaXN0Q29kZXMsIGxsMiwgMCkpIHtcbiAgICAgICAgICBmbHVzaEJ1ZmZlcigpO1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5saXRlcmFsVHJlZVwiKTtcbiAgICAgICAgb3V0ZXI6IHdoaWxlICgxKSB7XG4gICAgICAgICAgaiA9IERlY29kZVZhbHVlKGxpdGVyYWxUcmVlKTtcbiAgICAgICAgICBpZiAoaiA+PSAyNTYpIHsgLy8gSW4gQzY0OiBpZiBjYXJyeSBzZXRcbiAgICAgICAgICAgIHZhciBsZW4sIGRpc3Q7XG4gICAgICAgICAgICBqIC09IDI1NjtcbiAgICAgICAgICAgIGlmIChqID09IDApIHtcbiAgICAgICAgICAgICAgLy8gRU9GXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgai0tO1xuICAgICAgICAgICAgbGVuID0gcmVhZEJpdHMoY3BsZXh0W2pdKSArIGNwbGVuc1tqXTtcblxuICAgICAgICAgICAgaiA9IERlY29kZVZhbHVlKGRpc3RhbmNlVHJlZSk7XG4gICAgICAgICAgICBpZiAoY3BkZXh0W2pdID4gOCkge1xuICAgICAgICAgICAgICBkaXN0ID0gcmVhZEJpdHMoOCk7XG4gICAgICAgICAgICAgIGRpc3QgfD0gKHJlYWRCaXRzKGNwZGV4dFtqXSAtIDgpIDw8IDgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZGlzdCA9IHJlYWRCaXRzKGNwZGV4dFtqXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkaXN0ICs9IGNwZGlzdFtqXTtcbiAgICAgICAgICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgICAgICAgICBpZiAoYklkeCAtIGRpc3QgPCAwKSB7XG4gICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdmFyIGMgPSBidWYzMmtbKGJJZHggLSBkaXN0KSAmIDB4N2ZmZl07XG4gICAgICAgICAgICAgIGFkZEJ1ZmZlcihjKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWRkQnVmZmVyKGopO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gd2hpbGUgKCFsYXN0KTtcbiAgICBmbHVzaEJ1ZmZlcigpO1xuXG4gICAgYnl0ZUFsaWduKCk7XG4gICAgcmV0dXJuIDA7XG4gIH07XG5cbiAgSlhHLlV0aWwuVW56aXAucHJvdG90eXBlLnVuemlwRmlsZSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgaTtcbiAgICB0aGlzLnVuemlwKCk7XG4gICAgLy9hbGVydCh1bnppcHBlZFswXVsxXSk7XG4gICAgZm9yIChpID0gMDsgaSA8IHVuemlwcGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodW56aXBwZWRbaV1bMV0gPT0gbmFtZSkge1xuICAgICAgICByZXR1cm4gdW56aXBwZWRbaV1bMF07XG4gICAgICB9XG4gICAgfVxuXG4gIH07XG5cbiAgSlhHLlV0aWwuVW56aXAucHJvdG90eXBlLmRlZmxhdGUgPSBmdW5jdGlvbigpIHtcbiAgICBvdXRwdXRBcnIgPSBbXTtcbiAgICB2YXIgdG1wID0gW107XG4gICAgbW9kZVpJUCA9IGZhbHNlO1xuICAgIERlZmxhdGVMb29wKCk7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICB1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7XG4gICAgdW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IFwiREVGTEFURVwiO1xuICAgIGZpbGVzKys7XG4gICAgcmV0dXJuIHVuemlwcGVkO1xuICB9XG5cbiAgSlhHLlV0aWwuVW56aXAucHJvdG90eXBlLnVuemlwID0gZnVuY3Rpb24oKSB7XG4gICAgLy9jb252ZXJ0VG9CeXRlQXJyYXkoaW5wdXQpO1xuICAgIGlmIChkZWJ1ZylcbiAgICAgIGFsZXJ0KGJBKTtcbiAgICAvKmZvciAoaT0wO2k8YkEubGVuZ3RoKjg7aSsrKXtcblx0XHRkb2N1bWVudC53cml0ZShyZWFkQml0KCkpO1xuXHRcdGlmICgoaSsxKSU4PT0wKVxuXHRcdFx0ZG9jdW1lbnQud3JpdGUoXCIgXCIpO1xuXHR9Ki9cbiAgICAvKmZvciAoaT0wO2k8YkEubGVuZ3RoO2krKyl7XG5cdFx0ZG9jdW1lbnQud3JpdGUocmVhZEJ5dGUoKStcIiBcIik7XG5cdFx0aWYgKChpKzEpJTg9PTApXG5cdFx0XHRkb2N1bWVudC53cml0ZShcIiBcIik7XG5cdH1cblx0Zm9yIChpPTA7aTxiQS5sZW5ndGg7aSsrKXtcblx0XHRkb2N1bWVudC53cml0ZShiQVtpXStcIiBcIik7XG5cdFx0aWYgKChpKzEpJTE2PT0wKVxuXHRcdFx0ZG9jdW1lbnQud3JpdGUoXCI8YnI+XCIpO1xuXHR9XHRcblx0Ki9cbiAgICAvL2FsZXJ0KGJBKTtcbiAgICBuZXh0RmlsZSgpO1xuICAgIHJldHVybiB1bnppcHBlZDtcbiAgfTtcblxuICBmdW5jdGlvbiBuZXh0RmlsZSgpIHtcbiAgICBpZiAoZGVidWcpXG4gICAgICBhbGVydChcIk5FWFRGSUxFXCIpO1xuICAgIG91dHB1dEFyciA9IFtdO1xuICAgIHZhciB0bXAgPSBbXTtcbiAgICBtb2RlWklQID0gZmFsc2U7XG4gICAgdG1wWzBdID0gcmVhZEJ5dGUoKTtcbiAgICB0bXBbMV0gPSByZWFkQnl0ZSgpO1xuICAgIGlmIChkZWJ1ZylcbiAgICAgIGFsZXJ0KFwidHlwZTogXCIgKyB0bXBbMF0gKyBcIiBcIiArIHRtcFsxXSk7XG4gICAgaWYgKHRtcFswXSA9PSBwYXJzZUludChcIjc4XCIsIDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCJkYVwiLCAxNikpIHsgLy9HWklQXG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KFwiR0VPTkV4VC1HWklQXCIpO1xuICAgICAgRGVmbGF0ZUxvb3AoKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXSA9IG5ldyBBcnJheSgyKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IFwiZ2VvbmV4dC5neHRcIjtcbiAgICAgIGZpbGVzKys7XG4gICAgfVxuICAgIGlmICh0bXBbMF0gPT0gcGFyc2VJbnQoXCI3OFwiLCAxNikgJiYgdG1wWzFdID09IHBhcnNlSW50KFwiOWNcIiwgMTYpKSB7IC8vWkxJQlxuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcIlpMSUJcIik7XG4gICAgICBEZWZsYXRlTG9vcCgpO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChvdXRwdXRBcnIuam9pbignJykpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdWzFdID0gXCJaTElCXCI7XG4gICAgICBmaWxlcysrO1xuICAgIH1cbiAgICBpZiAodG1wWzBdID09IHBhcnNlSW50KFwiMWZcIiwgMTYpICYmIHRtcFsxXSA9PSBwYXJzZUludChcIjhiXCIsIDE2KSkgeyAvL0daSVBcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJHWklQXCIpO1xuICAgICAgLy9EZWZsYXRlTG9vcCgpO1xuICAgICAgc2tpcGRpcigpO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChvdXRwdXRBcnIuam9pbignJykpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdWzFdID0gXCJmaWxlXCI7XG4gICAgICBmaWxlcysrO1xuICAgIH1cbiAgICBpZiAodG1wWzBdID09IHBhcnNlSW50KFwiNTBcIiwgMTYpICYmIHRtcFsxXSA9PSBwYXJzZUludChcIjRiXCIsIDE2KSkgeyAvL1pJUFxuICAgICAgbW9kZVpJUCA9IHRydWU7XG4gICAgICB0bXBbMl0gPSByZWFkQnl0ZSgpO1xuICAgICAgdG1wWzNdID0gcmVhZEJ5dGUoKTtcbiAgICAgIGlmICh0bXBbMl0gPT0gcGFyc2VJbnQoXCIzXCIsIDE2KSAmJiB0bXBbM10gPT0gcGFyc2VJbnQoXCI0XCIsIDE2KSkge1xuICAgICAgICAvL01PREVfWklQXG4gICAgICAgIHRtcFswXSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIHRtcFsxXSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBhbGVydChcIlpJUC1WZXJzaW9uOiBcIiArIHRtcFsxXSArIFwiIFwiICsgdG1wWzBdIC8gMTAgKyBcIi5cIiArIHRtcFswXSAlIDEwKTtcblxuICAgICAgICBncGZsYWdzID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgZ3BmbGFncyB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgIGFsZXJ0KFwiZ3BmbGFnczogXCIgKyBncGZsYWdzKTtcblxuICAgICAgICB2YXIgbWV0aG9kID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgbWV0aG9kIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgYWxlcnQoXCJtZXRob2Q6IFwiICsgbWV0aG9kKTtcblxuICAgICAgICByZWFkQnl0ZSgpO1xuICAgICAgICByZWFkQnl0ZSgpO1xuICAgICAgICByZWFkQnl0ZSgpO1xuICAgICAgICByZWFkQnl0ZSgpO1xuXG4gICAgICAgIHZhciBjcmMgPSByZWFkQnl0ZSgpO1xuICAgICAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG5cbiAgICAgICAgdmFyIGNvbXBTaXplID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgY29tcFNpemUgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDE2KTtcbiAgICAgICAgY29tcFNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMjQpO1xuXG4gICAgICAgIHZhciBzaXplID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMjQpO1xuXG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBhbGVydChcImxvY2FsIENSQzogXCIgKyBjcmMgKyBcIlxcbmxvY2FsIFNpemU6IFwiICsgc2l6ZSArIFwiXFxubG9jYWwgQ29tcFNpemU6IFwiICsgY29tcFNpemUpO1xuXG4gICAgICAgIHZhciBmaWxlbGVuID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgZmlsZWxlbiB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcblxuICAgICAgICB2YXIgZXh0cmFsZW4gPSByZWFkQnl0ZSgpO1xuICAgICAgICBleHRyYWxlbiB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcblxuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgYWxlcnQoXCJmaWxlbGVuIFwiICsgZmlsZWxlbik7XG4gICAgICAgIGkgPSAwO1xuICAgICAgICBuYW1lQnVmID0gW107XG4gICAgICAgIHdoaWxlIChmaWxlbGVuLS0pIHtcbiAgICAgICAgICB2YXIgYyA9IHJlYWRCeXRlKCk7XG4gICAgICAgICAgaWYgKGMgPT0gXCIvXCIgfCBjID09IFwiOlwiKSB7XG4gICAgICAgICAgICBpID0gMDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGkgPCBOQU1FTUFYIC0gMSlcbiAgICAgICAgICAgIG5hbWVCdWZbaSsrXSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgIGFsZXJ0KFwibmFtZUJ1ZjogXCIgKyBuYW1lQnVmKTtcblxuICAgICAgICAvL25hbWVCdWZbaV0gPSBcIlxcMFwiO1xuICAgICAgICBpZiAoIWZpbGVvdXQpXG4gICAgICAgICAgZmlsZW91dCA9IG5hbWVCdWY7XG5cbiAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICB3aGlsZSAoaSA8IGV4dHJhbGVuKSB7XG4gICAgICAgICAgYyA9IHJlYWRCeXRlKCk7XG4gICAgICAgICAgaSsrO1xuICAgICAgICB9XG5cbiAgICAgICAgQ1JDID0gMHhmZmZmZmZmZjtcbiAgICAgICAgU0laRSA9IDA7XG5cbiAgICAgICAgaWYgKHNpemUgPT0gMCAmJiBmaWxlT3V0LmNoYXJBdChmaWxlb3V0Lmxlbmd0aCAtIDEpID09IFwiL1wiKSB7XG4gICAgICAgICAgLy9za2lwZGlyXG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQoXCJza2lwZGlyXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRob2QgPT0gOCkge1xuICAgICAgICAgIERlZmxhdGVMb29wKCk7XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICAgICAgICB1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7XG4gICAgICAgICAgdW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgICAgICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IG5hbWVCdWYuam9pbignJyk7XG4gICAgICAgICAgZmlsZXMrKztcbiAgICAgICAgICAvL3JldHVybiBvdXRwdXRBcnIuam9pbignJyk7XG4gICAgICAgIH1cbiAgICAgICAgc2tpcGRpcigpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBza2lwZGlyKCkge1xuICAgIHZhciBjcmMsXG4gICAgICB0bXAgPSBbXSxcbiAgICAgIGNvbXBTaXplLCBzaXplLCBvcywgaSwgYztcblxuICAgIGlmICgoZ3BmbGFncyAmIDgpKSB7XG4gICAgICB0bXBbMF0gPSByZWFkQnl0ZSgpO1xuICAgICAgdG1wWzFdID0gcmVhZEJ5dGUoKTtcbiAgICAgIHRtcFsyXSA9IHJlYWRCeXRlKCk7XG4gICAgICB0bXBbM10gPSByZWFkQnl0ZSgpO1xuXG4gICAgICBpZiAodG1wWzBdID09IHBhcnNlSW50KFwiNTBcIiwgMTYpICYmXG4gICAgICAgIHRtcFsxXSA9PSBwYXJzZUludChcIjRiXCIsIDE2KSAmJlxuICAgICAgICB0bXBbMl0gPT0gcGFyc2VJbnQoXCIwN1wiLCAxNikgJiZcbiAgICAgICAgdG1wWzNdID09IHBhcnNlSW50KFwiMDhcIiwgMTYpKSB7XG4gICAgICAgIGNyYyA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDE2KTtcbiAgICAgICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNyYyA9IHRtcFswXSB8ICh0bXBbMV0gPDwgOCkgfCAodG1wWzJdIDw8IDE2KSB8ICh0bXBbM10gPDwgMjQpO1xuICAgICAgfVxuXG4gICAgICBjb21wU2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICBjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDE2KTtcbiAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgc2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICBzaXplIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICBzaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcIkNSQzpcIik7XG4gICAgfVxuXG4gICAgaWYgKG1vZGVaSVApXG4gICAgICBuZXh0RmlsZSgpO1xuXG4gICAgdG1wWzBdID0gcmVhZEJ5dGUoKTtcbiAgICBpZiAodG1wWzBdICE9IDgpIHtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJVbmtub3duIGNvbXByZXNzaW9uIG1ldGhvZCFcIik7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBncGZsYWdzID0gcmVhZEJ5dGUoKTtcbiAgICBpZiAoZGVidWcpIHtcbiAgICAgIGlmICgoZ3BmbGFncyAmIH4ocGFyc2VJbnQoXCIxZlwiLCAxNikpKSlcbiAgICAgICAgYWxlcnQoXCJVbmtub3duIGZsYWdzIHNldCFcIik7XG4gICAgfVxuXG4gICAgcmVhZEJ5dGUoKTtcbiAgICByZWFkQnl0ZSgpO1xuICAgIHJlYWRCeXRlKCk7XG4gICAgcmVhZEJ5dGUoKTtcblxuICAgIHJlYWRCeXRlKCk7XG4gICAgb3MgPSByZWFkQnl0ZSgpO1xuXG4gICAgaWYgKChncGZsYWdzICYgNCkpIHtcbiAgICAgIHRtcFswXSA9IHJlYWRCeXRlKCk7XG4gICAgICB0bXBbMl0gPSByZWFkQnl0ZSgpO1xuICAgICAgbGVuID0gdG1wWzBdICsgMjU2ICogdG1wWzFdO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcIkV4dHJhIGZpZWxkIHNpemU6IFwiICsgbGVuKTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICB9XG5cbiAgICBpZiAoKGdwZmxhZ3MgJiA4KSkge1xuICAgICAgaSA9IDA7XG4gICAgICBuYW1lQnVmID0gW107XG4gICAgICB3aGlsZSAoYyA9IHJlYWRCeXRlKCkpIHtcbiAgICAgICAgaWYgKGMgPT0gXCI3XCIgfHwgYyA9PSBcIjpcIilcbiAgICAgICAgICBpID0gMDtcbiAgICAgICAgaWYgKGkgPCBOQU1FTUFYIC0gMSlcbiAgICAgICAgICBuYW1lQnVmW2krK10gPSBjO1xuICAgICAgfVxuICAgICAgLy9uYW1lQnVmW2ldID0gXCJcXDBcIjtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJvcmlnaW5hbCBmaWxlIG5hbWU6IFwiICsgbmFtZUJ1Zik7XG4gICAgfVxuXG4gICAgaWYgKChncGZsYWdzICYgMTYpKSB7XG4gICAgICB3aGlsZSAoYyA9IHJlYWRCeXRlKCkpIHtcbiAgICAgICAgLy9GSUxFIENPTU1FTlRcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoKGdwZmxhZ3MgJiAyKSkge1xuICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgIHJlYWRCeXRlKCk7XG4gICAgfVxuXG4gICAgRGVmbGF0ZUxvb3AoKTtcblxuICAgIGNyYyA9IHJlYWRCeXRlKCk7XG4gICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgIHNpemUgPSByZWFkQnl0ZSgpO1xuICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG5cbiAgICBpZiAobW9kZVpJUClcbiAgICAgIG5leHRGaWxlKCk7XG5cbiAgfTtcblxufTtcblxuLyoqXG4gKiAgQmFzZTY0IGVuY29kaW5nIC8gZGVjb2RpbmdcbiAqICB7QGxpbmsgaHR0cDovL3d3dy53ZWJ0b29sa2l0LmluZm8vfVxuICovXG5KWEcuVXRpbC5CYXNlNjQgPSB7XG5cbiAgLy8gcHJpdmF0ZSBwcm9wZXJ0eVxuICBfa2V5U3RyOiBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89XCIsXG5cbiAgLy8gcHVibGljIG1ldGhvZCBmb3IgZW5jb2RpbmdcbiAgZW5jb2RlOiBmdW5jdGlvbihpbnB1dCkge1xuICAgIHZhciBvdXRwdXQgPSBbXSxcbiAgICAgIGNocjEsIGNocjIsIGNocjMsIGVuYzEsIGVuYzIsIGVuYzMsIGVuYzQsXG4gICAgICBpID0gMDtcblxuICAgIGlucHV0ID0gSlhHLlV0aWwuQmFzZTY0Ll91dGY4X2VuY29kZShpbnB1dCk7XG5cbiAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkge1xuXG4gICAgICBjaHIxID0gaW5wdXQuY2hhckNvZGVBdChpKyspO1xuICAgICAgY2hyMiA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgIGNocjMgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgIGVuYzEgPSBjaHIxID4+IDI7XG4gICAgICBlbmMyID0gKChjaHIxICYgMykgPDwgNCkgfCAoY2hyMiA+PiA0KTtcbiAgICAgIGVuYzMgPSAoKGNocjIgJiAxNSkgPDwgMikgfCAoY2hyMyA+PiA2KTtcbiAgICAgIGVuYzQgPSBjaHIzICYgNjM7XG5cbiAgICAgIGlmIChpc05hTihjaHIyKSkge1xuICAgICAgICBlbmMzID0gZW5jNCA9IDY0O1xuICAgICAgfSBlbHNlIGlmIChpc05hTihjaHIzKSkge1xuICAgICAgICBlbmM0ID0gNjQ7XG4gICAgICB9XG5cbiAgICAgIG91dHB1dC5wdXNoKFt0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzEpLFxuICAgICAgICAgIHRoaXMuX2tleVN0ci5jaGFyQXQoZW5jMiksXG4gICAgICAgICAgdGhpcy5fa2V5U3RyLmNoYXJBdChlbmMzKSxcbiAgICAgICAgICB0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzQpXG4gICAgICBdLmpvaW4oJycpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0LmpvaW4oJycpO1xuICB9LFxuXG4gIC8vIHB1YmxpYyBtZXRob2QgZm9yIGRlY29kaW5nXG4gIGRlY29kZTogZnVuY3Rpb24oaW5wdXQsIHV0ZjgpIHtcbiAgICB2YXIgb3V0cHV0ID0gW10sXG4gICAgICBjaHIxLCBjaHIyLCBjaHIzLFxuICAgICAgZW5jMSwgZW5jMiwgZW5jMywgZW5jNCxcbiAgICAgIGkgPSAwO1xuXG4gICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKC9bXkEtWmEtejAtOVxcK1xcL1xcPV0vZywgXCJcIik7XG5cbiAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkge1xuXG4gICAgICBlbmMxID0gdGhpcy5fa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuICAgICAgZW5jMiA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcbiAgICAgIGVuYzMgPSB0aGlzLl9rZXlTdHIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICBlbmM0ID0gdGhpcy5fa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuXG4gICAgICBjaHIxID0gKGVuYzEgPDwgMikgfCAoZW5jMiA+PiA0KTtcbiAgICAgIGNocjIgPSAoKGVuYzIgJiAxNSkgPDwgNCkgfCAoZW5jMyA+PiAyKTtcbiAgICAgIGNocjMgPSAoKGVuYzMgJiAzKSA8PCA2KSB8IGVuYzQ7XG5cbiAgICAgIG91dHB1dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMSkpO1xuXG4gICAgICBpZiAoZW5jMyAhPSA2NCkge1xuICAgICAgICBvdXRwdXQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGNocjIpKTtcbiAgICAgIH1cbiAgICAgIGlmIChlbmM0ICE9IDY0KSB7XG4gICAgICAgIG91dHB1dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMykpO1xuICAgICAgfVxuICAgIH1cblxuICAgIG91dHB1dCA9IG91dHB1dC5qb2luKCcnKTtcblxuICAgIGlmICh1dGY4KSB7XG4gICAgICBvdXRwdXQgPSBKWEcuVXRpbC5CYXNlNjQuX3V0ZjhfZGVjb2RlKG91dHB1dCk7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG5cbiAgfSxcblxuICAvLyBwcml2YXRlIG1ldGhvZCBmb3IgVVRGLTggZW5jb2RpbmdcbiAgX3V0ZjhfZW5jb2RlOiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZSgvXFxyXFxuL2csIFwiXFxuXCIpO1xuICAgIHZhciB1dGZ0ZXh0ID0gXCJcIjtcblxuICAgIGZvciAodmFyIG4gPSAwOyBuIDwgc3RyaW5nLmxlbmd0aDsgbisrKSB7XG5cbiAgICAgIHZhciBjID0gc3RyaW5nLmNoYXJDb2RlQXQobik7XG5cbiAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjKTtcbiAgICAgIH0gZWxzZSBpZiAoKGMgPiAxMjcpICYmIChjIDwgMjA0OCkpIHtcbiAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjID4+IDYpIHwgMTkyKTtcbiAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjICYgNjMpIHwgMTI4KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoYyA+PiAxMikgfCAyMjQpO1xuICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChjID4+IDYpICYgNjMpIHwgMTI4KTtcbiAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjICYgNjMpIHwgMTI4KTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIHJldHVybiB1dGZ0ZXh0O1xuICB9LFxuXG4gIC8vIHByaXZhdGUgbWV0aG9kIGZvciBVVEYtOCBkZWNvZGluZ1xuICBfdXRmOF9kZWNvZGU6IGZ1bmN0aW9uKHV0ZnRleHQpIHtcbiAgICB2YXIgc3RyaW5nID0gW10sXG4gICAgICBpID0gMCxcbiAgICAgIGMgPSAwLFxuICAgICAgYzIgPSAwLFxuICAgICAgYzMgPSAwO1xuXG4gICAgd2hpbGUgKGkgPCB1dGZ0ZXh0Lmxlbmd0aCkge1xuICAgICAgYyA9IHV0ZnRleHQuY2hhckNvZGVBdChpKTtcbiAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYykpO1xuICAgICAgICBpKys7XG4gICAgICB9IGVsc2UgaWYgKChjID4gMTkxKSAmJiAoYyA8IDIyNCkpIHtcbiAgICAgICAgYzIgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSArIDEpO1xuICAgICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAmIDMxKSA8PCA2KSB8IChjMiAmIDYzKSkpO1xuICAgICAgICBpICs9IDI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpICsgMSk7XG4gICAgICAgIGMzID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAyKTtcbiAgICAgICAgc3RyaW5nLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgJiAxNSkgPDwgMTIpIHwgKChjMiAmIDYzKSA8PCA2KSB8IChjMyAmIDYzKSkpO1xuICAgICAgICBpICs9IDM7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzdHJpbmcuam9pbignJyk7XG4gIH0sXG5cbiAgX2Rlc3RyaXA6IGZ1bmN0aW9uKHN0cmlwcGVkLCB3cmFwKSB7XG4gICAgdmFyIGxpbmVzID0gW10sXG4gICAgICBsaW5lbm8sIGksXG4gICAgICBkZXN0cmlwcGVkID0gW107XG5cbiAgICBpZiAod3JhcCA9PSBudWxsKVxuICAgICAgd3JhcCA9IDc2O1xuXG4gICAgc3RyaXBwZWQucmVwbGFjZSgvIC9nLCBcIlwiKTtcbiAgICBsaW5lbm8gPSBzdHJpcHBlZC5sZW5ndGggLyB3cmFwO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsaW5lbm87IGkrKylcbiAgICAgIGxpbmVzW2ldID0gc3RyaXBwZWQuc3Vic3RyKGkgKiB3cmFwLCB3cmFwKTtcbiAgICBpZiAobGluZW5vICE9IHN0cmlwcGVkLmxlbmd0aCAvIHdyYXApXG4gICAgICBsaW5lc1tsaW5lcy5sZW5ndGhdID0gc3RyaXBwZWQuc3Vic3RyKGxpbmVubyAqIHdyYXAsIHN0cmlwcGVkLmxlbmd0aCAtIChsaW5lbm8gKiB3cmFwKSk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspXG4gICAgICBkZXN0cmlwcGVkLnB1c2gobGluZXNbaV0pO1xuICAgIHJldHVybiBkZXN0cmlwcGVkLmpvaW4oJ1xcbicpO1xuICB9LFxuXG4gIGRlY29kZUFzQXJyYXk6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgdmFyIGRlYyA9IHRoaXMuZGVjb2RlKGlucHV0KSxcbiAgICAgIGFyID0gW10sXG4gICAgICBpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBkZWMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGFyW2ldID0gZGVjLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICAgIHJldHVybiBhcjtcbiAgfSxcblxuICBkZWNvZGVHRU9ORXhUOiBmdW5jdGlvbihpbnB1dCkge1xuICAgIHJldHVybiBkZWNvZGVBc0FycmF5KGRlc3RyaXAoaW5wdXQpLCBmYWxzZSk7XG4gIH1cbn07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuSlhHLlV0aWwuYXNjaWlDaGFyQ29kZUF0ID0gZnVuY3Rpb24oc3RyLCBpKSB7XG4gIHZhciBjID0gc3RyLmNoYXJDb2RlQXQoaSk7XG4gIGlmIChjID4gMjU1KSB7XG4gICAgc3dpdGNoIChjKSB7XG4gICAgICBjYXNlIDgzNjQ6XG4gICAgICAgIGMgPSAxMjg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjE4OlxuICAgICAgICBjID0gMTMwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNDAyOlxuICAgICAgICBjID0gMTMxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyMjpcbiAgICAgICAgYyA9IDEzMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMzA6XG4gICAgICAgIGMgPSAxMzM7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjI0OlxuICAgICAgICBjID0gMTM0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyNTpcbiAgICAgICAgYyA9IDEzNTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDcxMDpcbiAgICAgICAgYyA9IDEzNjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyNDA6XG4gICAgICAgIGMgPSAxMzc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzNTI6XG4gICAgICAgIGMgPSAxMzg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjQ5OlxuICAgICAgICBjID0gMTM5O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzM4OlxuICAgICAgICBjID0gMTQwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzgxOlxuICAgICAgICBjID0gMTQyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIxNjpcbiAgICAgICAgYyA9IDE0NTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMTc6XG4gICAgICAgIGMgPSAxNDY7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjIwOlxuICAgICAgICBjID0gMTQ3O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyMTpcbiAgICAgICAgYyA9IDE0ODtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMjY6XG4gICAgICAgIGMgPSAxNDk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjExOlxuICAgICAgICBjID0gMTUwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIxMjpcbiAgICAgICAgYyA9IDE1MTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDczMjpcbiAgICAgICAgYyA9IDE1MjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDg0ODI6XG4gICAgICAgIGMgPSAxNTM7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzNTM6XG4gICAgICAgIGMgPSAxNTQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjUwOlxuICAgICAgICBjID0gMTU1O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzM5OlxuICAgICAgICBjID0gMTU2O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzgyOlxuICAgICAgICBjID0gMTU4O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzc2OlxuICAgICAgICBjID0gMTU5O1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYztcbn07XG5cbi8qKlxuICogRGVjb2Rpbmcgc3RyaW5nIGludG8gdXRmLThcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJpbmcgdG8gZGVjb2RlXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHV0ZjggZGVjb2RlZCBzdHJpbmdcbiAqL1xuSlhHLlV0aWwudXRmOERlY29kZSA9IGZ1bmN0aW9uKHV0ZnRleHQpIHtcbiAgdmFyIHN0cmluZyA9IFtdO1xuICB2YXIgaSA9IDA7XG4gIHZhciBjID0gMCxcbiAgICBjMSA9IDAsXG4gICAgYzIgPSAwLFxuICAgIGMzO1xuICBpZiAoIUpYRy5leGlzdHModXRmdGV4dCkpIHJldHVybiAnJztcblxuICB3aGlsZSAoaSA8IHV0ZnRleHQubGVuZ3RoKSB7XG4gICAgYyA9IHV0ZnRleHQuY2hhckNvZGVBdChpKTtcblxuICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGMpKTtcbiAgICAgIGkrKztcbiAgICB9IGVsc2UgaWYgKChjID4gMTkxKSAmJiAoYyA8IDIyNCkpIHtcbiAgICAgIGMyID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAxKTtcbiAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoKChjICYgMzEpIDw8IDYpIHwgKGMyICYgNjMpKSk7XG4gICAgICBpICs9IDI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGMyID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAxKTtcbiAgICAgIGMzID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAyKTtcbiAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoKChjICYgMTUpIDw8IDEyKSB8ICgoYzIgJiA2MykgPDwgNikgfCAoYzMgJiA2MykpKTtcbiAgICAgIGkgKz0gMztcbiAgICB9XG4gIH07XG4gIHJldHVybiBzdHJpbmcuam9pbignJyk7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlIGEgcmFuZG9tIHV1aWQuXG4gKiBodHRwOi8vd3d3LmJyb29mYS5jb21cbiAqIG1haWx0bzpyb2JlcnRAYnJvb2ZhLmNvbVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMCBSb2JlcnQgS2llZmZlclxuICogRHVhbCBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGFuZCBHUEwgbGljZW5zZXMuXG4gKlxuICogRVhBTVBMRVM6XG4gKiAgID4+PiBNYXRoLnV1aWQoKVxuICogICBcIjkyMzI5RDM5LTZGNUMtNDUyMC1BQkZDLUFBQjY0NTQ0RTE3MlwiXG4gKi9cbkpYRy5VdGlsLmdlblVVSUQgPSBmdW5jdGlvbigpIHtcbiAgLy8gUHJpdmF0ZSBhcnJheSBvZiBjaGFycyB0byB1c2VcbiAgdmFyIGNoYXJzID0gJzAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Jy5zcGxpdCgnJyksXG4gICAgdXVpZCA9IG5ldyBBcnJheSgzNiksXG4gICAgcm5kID0gMCxcbiAgICByO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzY7IGkrKykge1xuICAgIGlmIChpID09IDggfHwgaSA9PSAxMyB8fCBpID09IDE4IHx8IGkgPT0gMjMpIHtcbiAgICAgIHV1aWRbaV0gPSAnLSc7XG4gICAgfSBlbHNlIGlmIChpID09IDE0KSB7XG4gICAgICB1dWlkW2ldID0gJzQnO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocm5kIDw9IDB4MDIpIHJuZCA9IDB4MjAwMDAwMCArIChNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwKSB8IDA7XG4gICAgICByID0gcm5kICYgMHhmO1xuICAgICAgcm5kID0gcm5kID4+IDQ7XG4gICAgICB1dWlkW2ldID0gY2hhcnNbKGkgPT0gMTkpID8gKHIgJiAweDMpIHwgMHg4IDogcl07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHV1aWQuam9pbignJyk7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gSlhHO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vL1xuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxuLyoqXG4gKlxuICogVGhpcyBvYmplY3QgY29udGFpbnMgY29uZmlndXJhdGlvbiB2YWx1ZXMgYW5kIGltcGxlbWVudHNcbiAqIHN0b3JpbmcgYW5kIHJldHJpZXZpbmcgY29uZmlndXJhdGlvbiB0aGVtIGZyb20gSFRNTDUgbG9jYWwgc3RvcmFnZS5cbiAqXG4gKiBUaGlzIG9iamVjdCBjYW4gYmUgYWNjZXNzZWQgYWZ0ZXIgY2FsbGluZyBvcGVucGdwLmluaXQoKVxuICogdXNpbmcgb3BlbnBncC5jb25maWdcbiAqIFN0b3JlZCBjb25maWcgcGFyYW1ldGVycyBjYW4gYmUgYWNjZXNzZWQgdXNpbmdcbiAqIG9wZW5wZ3AuY29uZmlnLmNvbmZpZ1xuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBHUEc0QnJvd3NlcnMgY29uZmlnIG9iamVjdFxuICovXG52YXIgY29uZmlnID0gZnVuY3Rpb24oKSB7XG4gIC8qKlxuICAgKiBAcHJvcGVydHkge0ludGVnZXJ9IHByZWZlcl9oYXNoX2FsZ29yaXRobVxuICAgKiBAcHJvcGVydHkge0ludGVnZXJ9IGVuY3J5cHRpb25fY2lwaGVyXG4gICAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gY29tcHJlc3Npb25cbiAgICogQHByb3BlcnR5IHtCb29sZWFufSBzaG93X3ZlcnNpb25cbiAgICogQHByb3BlcnR5IHtCb29sZWFufSBzaG93X2NvbW1lbnRcbiAgICogQHByb3BlcnR5IHtCb29sZWFufSBpbnRlZ3JpdHlfcHJvdGVjdFxuICAgKiBAcHJvcGVydHkge1N0cmluZ30ga2V5c2VydmVyXG4gICAqL1xuICB0aGlzLnByZWZlcl9oYXNoX2FsZ29yaXRobSA9IGVudW1zLmhhc2guc2hhMjU2O1xuICB0aGlzLmVuY3J5cHRpb25fY2lwaGVyID0gZW51bXMuc3ltbWV0cmljLmFlczI1NjtcbiAgdGhpcy5jb21wcmVzc2lvbiA9IGVudW1zLmNvbXByZXNzaW9uLnppcDtcbiAgdGhpcy5zaG93X3ZlcnNpb24gPSB0cnVlO1xuICB0aGlzLnNob3dfY29tbWVudCA9IHRydWU7XG4gIHRoaXMuaW50ZWdyaXR5X3Byb3RlY3QgPSB0cnVlO1xuICB0aGlzLmtleXNlcnZlciA9IFwia2V5c2VydmVyLmxpbnV4Lml0XCI7IC8vIFwicGdwLm1pdC5lZHU6MTEzNzFcIlxuXG4gIHRoaXMudmVyc2lvbnN0cmluZyA9IFwiT3BlblBHUC5qcyBWRVJTSU9OXCI7XG4gIHRoaXMuY29tbWVudHN0cmluZyA9IFwiaHR0cDovL29wZW5wZ3Bqcy5vcmdcIjtcblxuICAvKipcbiAgICogSWYgZW5hYmxlZCwgZGVidWcgbWVzc2FnZXMgd2lsbCBiZSBwcmludGVkXG4gICAqL1xuICB0aGlzLmRlYnVnID0gZmFsc2U7XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IGNvbmZpZygpO1xuIiwiLy8gTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIIFxuXG4vLyBtb2RpZmllZCB2ZXJzaW9uIG9mIGh0dHA6Ly93d3cuaGFuZXdpbi5uZXQvZW5jcnlwdC9QR2RlY29kZS5qczpcblxuLyogT3BlblBHUCBlbmNyeXB0aW9uIHVzaW5nIFJTQS9BRVNcbiAqIENvcHlyaWdodCAyMDA1LTIwMDYgSGVyYmVydCBIYW5ld2lua2VsLCB3d3cuaGFuZVdJTi5kZVxuICogdmVyc2lvbiAyLjAsIGNoZWNrIHd3dy5oYW5lV0lOLmRlIGZvciB0aGUgbGF0ZXN0IHZlcnNpb25cblxuICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCBhcy1pcywgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuICBcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUgb3Igc2VsbCB0aGlzIHNvZnR3YXJlLCB3aXRoIG9yXG4gKiB3aXRob3V0IGZlZSwgZm9yIGFueSBwdXJwb3NlIGFuZCBieSBhbnkgaW5kaXZpZHVhbCBvciBvcmdhbml6YXRpb24sIGlzIGhlcmVieVxuICogZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwYXJhZ3JhcGggYXBwZWFyIFxuICogaW4gYWxsIGNvcGllcy4gRGlzdHJpYnV0aW9uIGFzIGEgcGFydCBvZiBhbiBhcHBsaWNhdGlvbiBvciBiaW5hcnkgbXVzdFxuICogaW5jbHVkZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXJcbiAqIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBhcHBsaWNhdGlvbiBvciBkaXN0cmlidXRpb24uXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNpcGhlciA9IHJlcXVpcmUoJy4vY2lwaGVyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBieXRlcywgdGhhdCBpcyBpbnRlZ2VycyB3aXRoIHZhbHVlcyBmcm9tIDAgdG8gMjU1XG4gICAqIEB0eXBlZGVmIHsoQXJyYXl8VWludDhBcnJheSl9IG9wZW5wZ3BfYnl0ZV9hcnJheVxuICAgKi9cblxuICAvKipcbiAgICogQmxvY2sgY2lwaGVyIGZ1bmN0aW9uXG4gICAqIEBjYWxsYmFjayBvcGVucGdwX2NpcGhlcl9ibG9ja19mblxuICAgKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZV9hcnJheX0gYmxvY2sgQSBibG9jayB0byBwZXJmb3JtIG9wZXJhdGlvbnMgb25cbiAgICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGtleSB0byB1c2UgaW4gZW5jcnlwdGlvbi9kZWNyeXB0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfYnl0ZV9hcnJheX0gRW5jcnlwdGVkL2RlY3J5cHRlZCBibG9ja1xuICAgKi9cblxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGVuY3J5cHRzIGEgZ2l2ZW4gd2l0aCB0aGUgc3BlY2lmaWVkIHByZWZpeHJhbmRvbSBcbiAgICogdXNpbmcgdGhlIHNwZWNpZmllZCBibG9ja2NpcGhlciB0byBlbmNyeXB0IGEgbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJlZml4cmFuZG9tIHJhbmRvbSBieXRlcyBvZiBibG9ja19zaXplIGxlbmd0aCBwcm92aWRlZCBcbiAgICogIGFzIGEgc3RyaW5nIHRvIGJlIHVzZWQgaW4gcHJlZml4aW5nIHRoZSBkYXRhXG4gICAqIEBwYXJhbSB7b3BlbnBncF9jaXBoZXJfYmxvY2tfZm59IGJsb2NrY2lwaGVyZm4gdGhlIGFsZ29yaXRobSBlbmNyeXB0IGZ1bmN0aW9uIHRvIGVuY3J5cHRcbiAgICogIGRhdGEgaW4gb25lIGJsb2NrX3NpemUgZW5jcnlwdGlvbi4gXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYmxvY2tfc2l6ZSB0aGUgYmxvY2sgc2l6ZSBpbiBieXRlcyBvZiB0aGUgYWxnb3JpdGhtIHVzZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBsYWludGV4dCBkYXRhIHRvIGJlIGVuY3J5cHRlZCBwcm92aWRlZCBhcyBhIHN0cmluZ1xuICAgKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZV9hcnJheX0ga2V5IGtleSB0byBiZSB1c2VkIHRvIGVuY3J5cHQgdGhlIGRhdGEuIFRoaXMgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIFxuICAgKiAgYmxvY2tjaXBoZXJmblxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlc3luYyBhIGJvb2xlYW4gdmFsdWUgc3BlY2lmeWluZyBpZiBhIHJlc3luYyBvZiB0aGUgXG4gICAqICBJViBzaG91bGQgYmUgdXNlZCBvciBub3QuIFRoZSBlbmNyeXB0ZWRkYXRhcGFja2V0IHVzZXMgdGhlIFxuICAgKiAgXCJvbGRcIiBzdHlsZSB3aXRoIGEgcmVzeW5jLiBFbmNyeXB0aW9uIHdpdGhpbiBhbiBcbiAgICogIGVuY3J5cHRlZGludGVncml0eXByb3RlY3RlZGRhdGEgcGFja2V0IGlzIG5vdCByZXN5bmNpbmcgdGhlIElWLlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGEgc3RyaW5nIHdpdGggdGhlIGVuY3J5cHRlZCBkYXRhXG4gICAqL1xuICBlbmNyeXB0OiBmdW5jdGlvbihwcmVmaXhyYW5kb20sIGNpcGhlcmZuLCBwbGFpbnRleHQsIGtleSwgcmVzeW5jKSB7XG4gICAgY2lwaGVyZm4gPSBuZXcgY2lwaGVyW2NpcGhlcmZuXShrZXkpO1xuICAgIHZhciBibG9ja19zaXplID0gY2lwaGVyZm4uYmxvY2tTaXplO1xuXG4gICAgdmFyIEZSID0gbmV3IEFycmF5KGJsb2NrX3NpemUpO1xuICAgIHZhciBGUkUgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG5cbiAgICBwcmVmaXhyYW5kb20gPSBwcmVmaXhyYW5kb20gKyBwcmVmaXhyYW5kb20uY2hhckF0KGJsb2NrX3NpemUgLSAyKSArIHByZWZpeHJhbmRvbS5jaGFyQXQoYmxvY2tfc2l6ZSAtIDEpO1xuICAgIHV0aWwucHJpbnRfZGVidWcoXCJwcmVmaXhyYW5kb206XCIgKyB1dGlsLmhleHN0cmR1bXAocHJlZml4cmFuZG9tKSk7XG4gICAgdmFyIGNpcGhlcnRleHQgPSBcIlwiO1xuICAgIC8vIDEuICBUaGUgZmVlZGJhY2sgcmVnaXN0ZXIgKEZSKSBpcyBzZXQgdG8gdGhlIElWLCB3aGljaCBpcyBhbGwgemVyb3MuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gMDtcblxuICAgIC8vIDIuICBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUgKEZSIEVuY3J5cHRlZCkuICBUaGlzIGlzIHRoZVxuICAgIC8vICAgICBlbmNyeXB0aW9uIG9mIGFuIGFsbC16ZXJvIHZhbHVlLlxuICAgIEZSRSA9IGNpcGhlcmZuLmVuY3J5cHQoRlIpO1xuICAgIC8vIDMuICBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgZmlyc3QgQlMgb2N0ZXRzIG9mIHJhbmRvbSBkYXRhIHByZWZpeGVkIHRvXG4gICAgLy8gICAgIHRoZSBwbGFpbnRleHQgdG8gcHJvZHVjZSBDWzFdIHRocm91Z2ggQ1tCU10sIHRoZSBmaXJzdCBCUyBvY3RldHNcbiAgICAvLyAgICAgb2YgY2lwaGVydGV4dC5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHByZWZpeHJhbmRvbS5jaGFyQ29kZUF0KGkpKTtcblxuICAgIC8vIDQuICBGUiBpcyBsb2FkZWQgd2l0aCBDWzFdIHRocm91Z2ggQ1tCU10uXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGkpO1xuXG4gICAgLy8gNS4gIEZSIGlzIGVuY3J5cHRlZCB0byBwcm9kdWNlIEZSRSwgdGhlIGVuY3J5cHRpb24gb2YgdGhlIGZpcnN0IEJTXG4gICAgLy8gXHQgICBvY3RldHMgb2YgY2lwaGVydGV4dC5cbiAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSKTtcblxuICAgIC8vIDYuICBUaGUgbGVmdCB0d28gb2N0ZXRzIG9mIEZSRSBnZXQgeG9yZWQgd2l0aCB0aGUgbmV4dCB0d28gb2N0ZXRzIG9mXG4gICAgLy8gICAgIGRhdGEgdGhhdCB3ZXJlIHByZWZpeGVkIHRvIHRoZSBwbGFpbnRleHQuICBUaGlzIHByb2R1Y2VzIENbQlMrMV1cbiAgICAvLyAgICAgYW5kIENbQlMrMl0sIHRoZSBuZXh0IHR3byBvY3RldHMgb2YgY2lwaGVydGV4dC5cbiAgICBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFWzBdIF4gcHJlZml4cmFuZG9tLmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSkpO1xuICAgIGNpcGhlcnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbMV0gXiBwcmVmaXhyYW5kb20uY2hhckNvZGVBdChibG9ja19zaXplICsgMSkpO1xuXG4gICAgaWYgKHJlc3luYykge1xuICAgICAgLy8gNy4gIChUaGUgcmVzeW5jIHN0ZXApIEZSIGlzIGxvYWRlZCB3aXRoIEMzLUMxMC5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpICsgMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcbiAgICB9XG4gICAgLy8gOC4gIEZSIGlzIGVuY3J5cHRlZCB0byBwcm9kdWNlIEZSRS5cbiAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSLCBrZXkpO1xuXG4gICAgaWYgKHJlc3luYykge1xuICAgICAgLy8gOS4gIEZSRSBpcyB4b3JlZCB3aXRoIHRoZSBmaXJzdCA4IG9jdGV0cyBvZiB0aGUgZ2l2ZW4gcGxhaW50ZXh0LCBub3dcbiAgICAgIC8vXHQgICB0aGF0IHdlIGhhdmUgZmluaXNoZWQgZW5jcnlwdGluZyB0aGUgMTAgb2N0ZXRzIG9mIHByZWZpeGVkIGRhdGEuXG4gICAgICAvLyBcdCAgIFRoaXMgcHJvZHVjZXMgQzExLUMxOCwgdGhlIG5leHQgOCBvY3RldHMgb2YgY2lwaGVydGV4dC5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKVxuICAgICAgICBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQoaSkpO1xuICAgICAgZm9yIChuID0gYmxvY2tfc2l6ZSArIDI7IG4gPCBwbGFpbnRleHQubGVuZ3RoOyBuICs9IGJsb2NrX3NpemUpIHtcbiAgICAgICAgLy8gMTAuIEZSIGlzIGxvYWRlZCB3aXRoIEMxMS1DMThcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KG4gKyBpKTtcblxuICAgICAgICAvLyAxMS4gRlIgaXMgZW5jcnlwdGVkIHRvIHByb2R1Y2UgRlJFLlxuICAgICAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSKTtcblxuICAgICAgICAvLyAxMi4gRlJFIGlzIHhvcmVkIHdpdGggdGhlIG5leHQgOCBvY3RldHMgb2YgcGxhaW50ZXh0LCB0byBwcm9kdWNlIHRoZVxuICAgICAgICAvLyBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuICBUaGVzZSBhcmUgbG9hZGVkIGludG8gRlIgYW5kIHRoZVxuICAgICAgICAvLyBwcm9jZXNzIGlzIHJlcGVhdGVkIHVudGlsIHRoZSBwbGFpbnRleHQgaXMgdXNlZCB1cC5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGNpcGhlcnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwbGFpbnRleHQuY2hhckNvZGVBdCgobiAtIDIpICtcbiAgICAgICAgICAgIGkpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcGxhaW50ZXh0ID0gXCIgIFwiICsgcGxhaW50ZXh0O1xuICAgICAgLy8gOS4gIEZSRSBpcyB4b3JlZCB3aXRoIHRoZSBmaXJzdCA4IG9jdGV0cyBvZiB0aGUgZ2l2ZW4gcGxhaW50ZXh0LCBub3dcbiAgICAgIC8vXHQgICB0aGF0IHdlIGhhdmUgZmluaXNoZWQgZW5jcnlwdGluZyB0aGUgMTAgb2N0ZXRzIG9mIHByZWZpeGVkIGRhdGEuXG4gICAgICAvLyBcdCAgIFRoaXMgcHJvZHVjZXMgQzExLUMxOCwgdGhlIG5leHQgOCBvY3RldHMgb2YgY2lwaGVydGV4dC5cbiAgICAgIGZvciAodmFyIGkgPSAyOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQoaSkpO1xuICAgICAgdmFyIHRlbXBDaXBoZXJ0ZXh0ID0gY2lwaGVydGV4dC5zdWJzdHJpbmcoMCwgMiAqIGJsb2NrX3NpemUpLnNwbGl0KCcnKTtcbiAgICAgIHZhciB0ZW1wQ2lwaGVydGV4dFN0cmluZyA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKGJsb2NrX3NpemUpO1xuICAgICAgZm9yIChuID0gYmxvY2tfc2l6ZTsgbiA8IHBsYWludGV4dC5sZW5ndGg7IG4gKz0gYmxvY2tfc2l6ZSkge1xuICAgICAgICAvLyAxMC4gRlIgaXMgbG9hZGVkIHdpdGggQzExLUMxOFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgRlJbaV0gPSB0ZW1wQ2lwaGVydGV4dFN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICAgICAgICB0ZW1wQ2lwaGVydGV4dFN0cmluZyA9ICcnO1xuXG4gICAgICAgIC8vIDExLiBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUuXG4gICAgICAgIEZSRSA9IGNpcGhlcmZuLmVuY3J5cHQoRlIpO1xuXG4gICAgICAgIC8vIDEyLiBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgbmV4dCA4IG9jdGV0cyBvZiBwbGFpbnRleHQsIHRvIHByb2R1Y2UgdGhlXG4gICAgICAgIC8vICAgICBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuICBUaGVzZSBhcmUgbG9hZGVkIGludG8gRlIgYW5kIHRoZVxuICAgICAgICAvLyAgICAgcHJvY2VzcyBpcyByZXBlYXRlZCB1bnRpbCB0aGUgcGxhaW50ZXh0IGlzIHVzZWQgdXAuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSB7XG4gICAgICAgICAgdGVtcENpcGhlcnRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KG4gKyBpKSkpO1xuICAgICAgICAgIHRlbXBDaXBoZXJ0ZXh0U3RyaW5nICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQobiArIGkpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2lwaGVydGV4dCA9IHRlbXBDaXBoZXJ0ZXh0LmpvaW4oJycpO1xuXG4gICAgfVxuXG4gICAgY2lwaGVydGV4dCA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKDAsIHBsYWludGV4dC5sZW5ndGggKyAyICsgYmxvY2tfc2l6ZSk7XG5cbiAgICByZXR1cm4gY2lwaGVydGV4dDtcbiAgfSxcblxuICAvKipcbiAgICogRGVjcnlwdHMgdGhlIHByZWZpeGVkIGRhdGEgZm9yIHRoZSBNb2RpZmljYXRpb24gRGV0ZWN0aW9uIENvZGUgKE1EQykgY29tcHV0YXRpb25cbiAgICogQHBhcmFtIHtvcGVucGdwX2Jsb2NrX2NpcGhlcl9mbn0gY2lwaGVyZm4uZW5jcnlwdCBDaXBoZXIgZnVuY3Rpb24gdG8gdXNlXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYmxvY2tfc2l6ZSBCbG9ja3NpemUgb2YgdGhlIGFsZ29yaXRobVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZV9hcnJheX0ga2V5IFRoZSBrZXkgZm9yIGVuY3J5cHRpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IGNpcGhlcnRleHQgVGhlIGVuY3J5cHRlZCBkYXRhXG4gICAqIEByZXR1cm4ge1N0cmluZ30gcGxhaW50ZXh0IERhdGEgb2YgRChjaXBoZXJ0ZXh0KSB3aXRoIGJsb2Nrc2l6ZSBsZW5ndGggKzJcbiAgICovXG4gIG1kYzogZnVuY3Rpb24oY2lwaGVyZm4sIGtleSwgY2lwaGVydGV4dCkge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBpYmxvY2sgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG4gICAgdmFyIGFibG9jayA9IG5ldyBBcnJheShibG9ja19zaXplKTtcbiAgICB2YXIgaTtcblxuXG4gICAgLy8gaW5pdGlhbGlzYXRpb24gdmVjdG9yXG4gICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgaWJsb2NrW2ldID0gMDtcblxuICAgIGlibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoaWJsb2NrKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSB7XG4gICAgICBhYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSk7XG4gICAgICBpYmxvY2tbaV0gXj0gYWJsb2NrW2ldO1xuICAgIH1cblxuICAgIGFibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoYWJsb2NrKTtcblxuICAgIHJldHVybiB1dGlsLmJpbjJzdHIoaWJsb2NrKSArXG4gICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGFibG9ja1swXSBeIGNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplKSkgK1xuICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZShhYmxvY2tbMV0gXiBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSArIDEpKTtcbiAgfSxcbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gZGVjcnlwdHMgYSBnaXZlbiBwbGFpbnRleHQgdXNpbmcgdGhlIHNwZWNpZmllZFxuICAgKiBibG9ja2NpcGhlciB0byBkZWNyeXB0IGEgbWVzc2FnZVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfY2lwaGVyX2Jsb2NrX2ZufSBibG9ja2NpcGhlcmZuIFRoZSBhbGdvcml0aG0gX2VuY3J5cHRfIGZ1bmN0aW9uIHRvIGVuY3J5cHRcbiAgICogIGRhdGEgaW4gb25lIGJsb2NrX3NpemUgZW5jcnlwdGlvbi5cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBibG9ja19zaXplIHRoZSBibG9jayBzaXplIGluIGJ5dGVzIG9mIHRoZSBhbGdvcml0aG0gdXNlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGxhaW50ZXh0IGNpcGhlcnRleHQgdG8gYmUgZGVjcnlwdGVkIHByb3ZpZGVkIGFzIGEgc3RyaW5nXG4gICAqIEBwYXJhbSB7b3BlbnBncF9ieXRlX2FycmF5fSBrZXkga2V5IHRvIGJlIHVzZWQgdG8gZGVjcnlwdCB0aGUgY2lwaGVydGV4dC4gVGhpcyB3aWxsIGJlIHBhc3NlZCB0byB0aGUgXG4gICAqICBibG9ja2NpcGhlcmZuXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVzeW5jIGEgYm9vbGVhbiB2YWx1ZSBzcGVjaWZ5aW5nIGlmIGEgcmVzeW5jIG9mIHRoZSBcbiAgICogIElWIHNob3VsZCBiZSB1c2VkIG9yIG5vdC4gVGhlIGVuY3J5cHRlZGRhdGFwYWNrZXQgdXNlcyB0aGUgXG4gICAqICBcIm9sZFwiIHN0eWxlIHdpdGggYSByZXN5bmMuIERlY3J5cHRpb24gd2l0aGluIGFuIFxuICAgKiAgZW5jcnlwdGVkaW50ZWdyaXR5cHJvdGVjdGVkZGF0YSBwYWNrZXQgaXMgbm90IHJlc3luY2luZyB0aGUgSVYuXG4gICAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmcgd2l0aCB0aGUgcGxhaW50ZXh0IGRhdGFcbiAgICovXG5cbiAgZGVjcnlwdDogZnVuY3Rpb24oY2lwaGVyZm4sIGtleSwgY2lwaGVydGV4dCwgcmVzeW5jKSB7XG4gICAgY2lwaGVyZm4gPSBuZXcgY2lwaGVyW2NpcGhlcmZuXShrZXkpO1xuICAgIHZhciBibG9ja19zaXplID0gY2lwaGVyZm4uYmxvY2tTaXplO1xuXG4gICAgdmFyIGlibG9jayA9IG5ldyBBcnJheShibG9ja19zaXplKTtcbiAgICB2YXIgYWJsb2NrID0gbmV3IEFycmF5KGJsb2NrX3NpemUpO1xuICAgIHZhciBpLCBuID0gJyc7XG4gICAgdmFyIHRleHQgPSBbXTtcblxuICAgIC8vIGluaXRpYWxpc2F0aW9uIHZlY3RvclxuICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGlibG9ja1tpXSA9IDA7XG5cbiAgICBpYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KGlibG9jaywga2V5KTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSB7XG4gICAgICBhYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSk7XG4gICAgICBpYmxvY2tbaV0gXj0gYWJsb2NrW2ldO1xuICAgIH1cblxuICAgIGFibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoYWJsb2NrLCBrZXkpO1xuXG4gICAgLy8gdGVzdCBjaGVjayBvY3RldHNcbiAgICBpZiAoaWJsb2NrW2Jsb2NrX3NpemUgLSAyXSAhPSAoYWJsb2NrWzBdIF4gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGJsb2NrX3NpemUpKSB8fCBpYmxvY2tbYmxvY2tfc2l6ZSAtIDFdICE9IChhYmxvY2tbXG4gICAgICAxXSBeIGNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplICsgMSkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZGF0YS4nKTtcbiAgICB9XG5cbiAgICAvKiAgUkZDNDg4MDogVGFnIDE4IGFuZCBSZXN5bmM6XG5cdFx0ICogIFsuLi5dIFVubGlrZSB0aGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQsIG5vXG5cdFx0ICogIHNwZWNpYWwgQ0ZCIHJlc3luY2hyb25pemF0aW9uIGlzIGRvbmUgYWZ0ZXIgZW5jcnlwdGluZyB0aGlzIHByZWZpeFxuXHRcdCAqICBkYXRhLiAgU2VlIFwiT3BlblBHUCBDRkIgTW9kZVwiIGJlbG93IGZvciBtb3JlIGRldGFpbHMuXG5cblx0XHQgKi9cblxuICAgIGlmIChyZXN5bmMpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGlibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpICsgMik7XG4gICAgICBmb3IgKG4gPSBibG9ja19zaXplICsgMjsgbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBuICs9IGJsb2NrX3NpemUpIHtcbiAgICAgICAgYWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChpYmxvY2spO1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplICYmIGkgKyBuIDwgY2lwaGVydGV4dC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChuICsgaSk7XG4gICAgICAgICAgdGV4dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYWJsb2NrW2ldIF4gaWJsb2NrW2ldKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgaWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgICAgZm9yIChuID0gYmxvY2tfc2l6ZTsgbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBuICs9IGJsb2NrX3NpemUpIHtcbiAgICAgICAgYWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChpYmxvY2spO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZSAmJiBpICsgbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQobiArIGkpO1xuICAgICAgICAgIHRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGFibG9ja1tpXSBeIGlibG9ja1tpXSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIG4gPSByZXN5bmMgPyAwIDogMjtcblxuICAgIHRleHQgPSB0ZXh0LmpvaW4oJycpO1xuXG4gICAgdGV4dCA9IHRleHQuc3Vic3RyaW5nKG4sIGNpcGhlcnRleHQubGVuZ3RoIC0gYmxvY2tfc2l6ZSAtIDIgKyBuKTtcblxuXG4gICAgcmV0dXJuIHRleHQ7XG4gIH0sXG5cblxuICBub3JtYWxFbmNyeXB0OiBmdW5jdGlvbihjaXBoZXJmbiwga2V5LCBwbGFpbnRleHQsIGl2KSB7XG4gICAgY2lwaGVyZm4gPSBuZXcgY2lwaGVyW2NpcGhlcmZuXShrZXkpO1xuICAgIHZhciBibG9ja19zaXplID0gY2lwaGVyZm4uYmxvY2tTaXplO1xuXG4gICAgdmFyIGJsb2NraSA9IFwiXCI7XG4gICAgdmFyIGJsb2NrYyA9IFwiXCI7XG4gICAgdmFyIHBvcyA9IDA7XG4gICAgdmFyIGN5cGhlcnRleHQgPSBbXTtcbiAgICB2YXIgdGVtcEJsb2NrID0gW107XG4gICAgYmxvY2tjID0gaXYuc3Vic3RyaW5nKDAsIGJsb2NrX3NpemUpO1xuICAgIHdoaWxlIChwbGFpbnRleHQubGVuZ3RoID4gYmxvY2tfc2l6ZSAqIHBvcykge1xuICAgICAgdmFyIGVuY2Jsb2NrID0gY2lwaGVyZm4uZW5jcnlwdCh1dGlsLnN0cjJiaW4oYmxvY2tjKSk7XG4gICAgICBibG9ja2kgPSBwbGFpbnRleHQuc3Vic3RyaW5nKChwb3MgKiBibG9ja19zaXplKSwgKHBvcyAqIGJsb2NrX3NpemUpICsgYmxvY2tfc2l6ZSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NraS5sZW5ndGg7IGkrKylcbiAgICAgICAgdGVtcEJsb2NrLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShibG9ja2kuY2hhckNvZGVBdChpKSBeIGVuY2Jsb2NrW2ldKSk7XG4gICAgICBibG9ja2MgPSB0ZW1wQmxvY2suam9pbignJyk7XG4gICAgICB0ZW1wQmxvY2sgPSBbXTtcbiAgICAgIGN5cGhlcnRleHQucHVzaChibG9ja2MpO1xuICAgICAgcG9zKys7XG4gICAgfVxuICAgIHJldHVybiBjeXBoZXJ0ZXh0LmpvaW4oJycpO1xuICB9LFxuXG4gIG5vcm1hbERlY3J5cHQ6IGZ1bmN0aW9uKGNpcGhlcmZuLCBrZXksIGNpcGhlcnRleHQsIGl2KSB7XG4gICAgY2lwaGVyZm4gPSBuZXcgY2lwaGVyW2NpcGhlcmZuXShrZXkpO1xuICAgIHZhciBibG9ja19zaXplID0gY2lwaGVyZm4uYmxvY2tTaXplO1xuXG4gICAgdmFyIGJsb2NrcCA9IFwiXCI7XG4gICAgdmFyIHBvcyA9IDA7XG4gICAgdmFyIHBsYWludGV4dCA9IFtdO1xuICAgIHZhciBvZmZzZXQgPSAwO1xuICAgIGlmIChpdiA9PSBudWxsKVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGJsb2NrcCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuICAgIGVsc2VcbiAgICAgIGJsb2NrcCA9IGl2LnN1YnN0cmluZygwLCBibG9ja19zaXplKTtcbiAgICB3aGlsZSAoY2lwaGVydGV4dC5sZW5ndGggPiAoYmxvY2tfc2l6ZSAqIHBvcykpIHtcbiAgICAgIHZhciBkZWNibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQodXRpbC5zdHIyYmluKGJsb2NrcCkpO1xuICAgICAgYmxvY2twID0gY2lwaGVydGV4dC5zdWJzdHJpbmcoKHBvcyAqIChibG9ja19zaXplKSkgKyBvZmZzZXQsIChwb3MgKiAoYmxvY2tfc2l6ZSkpICsgKGJsb2NrX3NpemUpICsgb2Zmc2V0KTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2twLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHBsYWludGV4dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYmxvY2twLmNoYXJDb2RlQXQoaSkgXiBkZWNibG9ja1tpXSkpO1xuICAgICAgfVxuICAgICAgcG9zKys7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBsYWludGV4dC5qb2luKCcnKTtcbiAgfVxufVxuIiwiLyogUmlqbmRhZWwgKEFFUykgRW5jcnlwdGlvblxuICogQ29weXJpZ2h0IDIwMDUgSGVyYmVydCBIYW5ld2lua2VsLCB3d3cuaGFuZVdJTi5kZVxuICogdmVyc2lvbiAxLjEsIGNoZWNrIHd3dy5oYW5lV0lOLmRlIGZvciB0aGUgbGF0ZXN0IHZlcnNpb25cblxuICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCBhcy1pcywgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuICBcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUgb3Igc2VsbCB0aGlzIHNvZnR3YXJlLCB3aXRoIG9yXG4gKiB3aXRob3V0IGZlZSwgZm9yIGFueSBwdXJwb3NlIGFuZCBieSBhbnkgaW5kaXZpZHVhbCBvciBvcmdhbml6YXRpb24sIGlzIGhlcmVieVxuICogZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwYXJhZ3JhcGggYXBwZWFyIFxuICogaW4gYWxsIGNvcGllcy4gRGlzdHJpYnV0aW9uIGFzIGEgcGFydCBvZiBhbiBhcHBsaWNhdGlvbiBvciBiaW5hcnkgbXVzdFxuICogaW5jbHVkZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXJcbiAqIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBhcHBsaWNhdGlvbiBvciBkaXN0cmlidXRpb24uXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbi8vIFRoZSByb3VuZCBjb25zdGFudHMgdXNlZCBpbiBzdWJrZXkgZXhwYW5zaW9uXG52YXIgUmNvbiA9IFtcbiAgICAweDAxLCAweDAyLCAweDA0LCAweDA4LCAweDEwLCAweDIwLCAweDQwLCAweDgwLCAweDFiLCAweDM2LCAweDZjLCAweGQ4LFxuICAgIDB4YWIsIDB4NGQsIDB4OWEsIDB4MmYsIDB4NWUsIDB4YmMsIDB4NjMsIDB4YzYsIDB4OTcsIDB4MzUsIDB4NmEsIDB4ZDQsXG4gICAgMHhiMywgMHg3ZCwgMHhmYSwgMHhlZiwgMHhjNSwgMHg5MVxuXTtcblxuLy8gUHJlY29tcHV0ZWQgbG9va3VwIHRhYmxlIGZvciB0aGUgU0JveFxudmFyIFMgPSBbXG4gICAgOTksIDEyNCwgMTE5LCAxMjMsIDI0MiwgMTA3LCAxMTEsIDE5NywgNDgsIDEsIDEwMywgNDMsIDI1NCwgMjE1LCAxNzEsXG4gICAgMTE4LCAyMDIsIDEzMCwgMjAxLCAxMjUsIDI1MCwgODksIDcxLCAyNDAsIDE3MywgMjEyLCAxNjIsIDE3NSwgMTU2LCAxNjQsXG4gICAgMTE0LCAxOTIsIDE4MywgMjUzLCAxNDcsIDM4LCA1NCwgNjMsIDI0NywgMjA0LCA1MiwgMTY1LCAyMjksIDI0MSwgMTEzLFxuICAgIDIxNiwgNDksIDIxLCA0LCAxOTksIDM1LCAxOTUsIDI0LCAxNTAsIDUsIDE1NCwgNywgMTgsIDEyOCwgMjI2LFxuICAgIDIzNSwgMzksIDE3OCwgMTE3LCA5LCAxMzEsIDQ0LCAyNiwgMjcsIDExMCwgOTAsIDE2MCwgODIsIDU5LCAyMTQsXG4gICAgMTc5LCA0MSwgMjI3LCA0NywgMTMyLCA4MywgMjA5LCAwLCAyMzcsIDMyLCAyNTIsIDE3NywgOTEsIDEwNiwgMjAzLFxuICAgIDE5MCwgNTcsIDc0LCA3NiwgODgsIDIwNywgMjA4LCAyMzksIDE3MCwgMjUxLCA2NywgNzcsIDUxLCAxMzMsIDY5LFxuICAgIDI0OSwgMiwgMTI3LCA4MCwgNjAsIDE1OSwgMTY4LCA4MSwgMTYzLCA2NCwgMTQzLCAxNDYsIDE1NywgNTYsIDI0NSxcbiAgICAxODgsIDE4MiwgMjE4LCAzMywgMTYsIDI1NSwgMjQzLCAyMTAsIDIwNSwgMTIsIDE5LCAyMzYsIDk1LCAxNTEsIDY4LFxuICAgIDIzLCAxOTYsIDE2NywgMTI2LCA2MSwgMTAwLCA5MywgMjUsIDExNSwgOTYsIDEyOSwgNzksIDIyMCwgMzQsIDQyLFxuICAgIDE0NCwgMTM2LCA3MCwgMjM4LCAxODQsIDIwLCAyMjIsIDk0LCAxMSwgMjE5LCAyMjQsIDUwLCA1OCwgMTAsIDczLFxuICAgIDYsIDM2LCA5MiwgMTk0LCAyMTEsIDE3MiwgOTgsIDE0NSwgMTQ5LCAyMjgsIDEyMSwgMjMxLCAyMDAsIDU1LCAxMDksXG4gICAgMTQxLCAyMTMsIDc4LCAxNjksIDEwOCwgODYsIDI0NCwgMjM0LCAxMDEsIDEyMiwgMTc0LCA4LCAxODYsIDEyMCwgMzcsXG4gICAgNDYsIDI4LCAxNjYsIDE4MCwgMTk4LCAyMzIsIDIyMSwgMTE2LCAzMSwgNzUsIDE4OSwgMTM5LCAxMzgsIDExMiwgNjIsXG4gICAgMTgxLCAxMDIsIDcyLCAzLCAyNDYsIDE0LCA5NywgNTMsIDg3LCAxODUsIDEzNCwgMTkzLCAyOSwgMTU4LCAyMjUsXG4gICAgMjQ4LCAxNTIsIDE3LCAxMDUsIDIxNywgMTQyLCAxNDgsIDE1NSwgMzAsIDEzNSwgMjMzLCAyMDYsIDg1LCA0MCwgMjIzLFxuICAgIDE0MCwgMTYxLCAxMzcsIDEzLCAxOTEsIDIzMCwgNjYsIDEwNCwgNjUsIDE1MywgNDUsIDE1LCAxNzYsIDg0LCAxODcsXG4gICAgMjJcbl07XG5cbnZhciBUMSA9IFtcbiAgICAweGE1NjM2M2M2LCAweDg0N2M3Y2Y4LCAweDk5Nzc3N2VlLCAweDhkN2I3YmY2LFxuICAgIDB4MGRmMmYyZmYsIDB4YmQ2YjZiZDYsIDB4YjE2ZjZmZGUsIDB4NTRjNWM1OTEsXG4gICAgMHg1MDMwMzA2MCwgMHgwMzAxMDEwMiwgMHhhOTY3NjdjZSwgMHg3ZDJiMmI1NixcbiAgICAweDE5ZmVmZWU3LCAweDYyZDdkN2I1LCAweGU2YWJhYjRkLCAweDlhNzY3NmVjLFxuICAgIDB4NDVjYWNhOGYsIDB4OWQ4MjgyMWYsIDB4NDBjOWM5ODksIDB4ODc3ZDdkZmEsXG4gICAgMHgxNWZhZmFlZiwgMHhlYjU5NTliMiwgMHhjOTQ3NDc4ZSwgMHgwYmYwZjBmYixcbiAgICAweGVjYWRhZDQxLCAweDY3ZDRkNGIzLCAweGZkYTJhMjVmLCAweGVhYWZhZjQ1LFxuICAgIDB4YmY5YzljMjMsIDB4ZjdhNGE0NTMsIDB4OTY3MjcyZTQsIDB4NWJjMGMwOWIsXG4gICAgMHhjMmI3Yjc3NSwgMHgxY2ZkZmRlMSwgMHhhZTkzOTMzZCwgMHg2YTI2MjY0YyxcbiAgICAweDVhMzYzNjZjLCAweDQxM2YzZjdlLCAweDAyZjdmN2Y1LCAweDRmY2NjYzgzLFxuICAgIDB4NWMzNDM0NjgsIDB4ZjRhNWE1NTEsIDB4MzRlNWU1ZDEsIDB4MDhmMWYxZjksXG4gICAgMHg5MzcxNzFlMiwgMHg3M2Q4ZDhhYiwgMHg1MzMxMzE2MiwgMHgzZjE1MTUyYSxcbiAgICAweDBjMDQwNDA4LCAweDUyYzdjNzk1LCAweDY1MjMyMzQ2LCAweDVlYzNjMzlkLFxuICAgIDB4MjgxODE4MzAsIDB4YTE5Njk2MzcsIDB4MGYwNTA1MGEsIDB4YjU5YTlhMmYsXG4gICAgMHgwOTA3MDcwZSwgMHgzNjEyMTIyNCwgMHg5YjgwODAxYiwgMHgzZGUyZTJkZixcbiAgICAweDI2ZWJlYmNkLCAweDY5MjcyNzRlLCAweGNkYjJiMjdmLCAweDlmNzU3NWVhLFxuICAgIDB4MWIwOTA5MTIsIDB4OWU4MzgzMWQsIDB4NzQyYzJjNTgsIDB4MmUxYTFhMzQsXG4gICAgMHgyZDFiMWIzNiwgMHhiMjZlNmVkYywgMHhlZTVhNWFiNCwgMHhmYmEwYTA1YixcbiAgICAweGY2NTI1MmE0LCAweDRkM2IzYjc2LCAweDYxZDZkNmI3LCAweGNlYjNiMzdkLFxuICAgIDB4N2IyOTI5NTIsIDB4M2VlM2UzZGQsIDB4NzEyZjJmNWUsIDB4OTc4NDg0MTMsXG4gICAgMHhmNTUzNTNhNiwgMHg2OGQxZDFiOSwgMHgwMDAwMDAwMCwgMHgyY2VkZWRjMSxcbiAgICAweDYwMjAyMDQwLCAweDFmZmNmY2UzLCAweGM4YjFiMTc5LCAweGVkNWI1YmI2LFxuICAgIDB4YmU2YTZhZDQsIDB4NDZjYmNiOGQsIDB4ZDliZWJlNjcsIDB4NGIzOTM5NzIsXG4gICAgMHhkZTRhNGE5NCwgMHhkNDRjNGM5OCwgMHhlODU4NThiMCwgMHg0YWNmY2Y4NSxcbiAgICAweDZiZDBkMGJiLCAweDJhZWZlZmM1LCAweGU1YWFhYTRmLCAweDE2ZmJmYmVkLFxuICAgIDB4YzU0MzQzODYsIDB4ZDc0ZDRkOWEsIDB4NTUzMzMzNjYsIDB4OTQ4NTg1MTEsXG4gICAgMHhjZjQ1NDU4YSwgMHgxMGY5ZjllOSwgMHgwNjAyMDIwNCwgMHg4MTdmN2ZmZSxcbiAgICAweGYwNTA1MGEwLCAweDQ0M2MzYzc4LCAweGJhOWY5ZjI1LCAweGUzYThhODRiLFxuICAgIDB4ZjM1MTUxYTIsIDB4ZmVhM2EzNWQsIDB4YzA0MDQwODAsIDB4OGE4ZjhmMDUsXG4gICAgMHhhZDkyOTIzZiwgMHhiYzlkOWQyMSwgMHg0ODM4Mzg3MCwgMHgwNGY1ZjVmMSxcbiAgICAweGRmYmNiYzYzLCAweGMxYjZiNjc3LCAweDc1ZGFkYWFmLCAweDYzMjEyMTQyLFxuICAgIDB4MzAxMDEwMjAsIDB4MWFmZmZmZTUsIDB4MGVmM2YzZmQsIDB4NmRkMmQyYmYsXG4gICAgMHg0Y2NkY2Q4MSwgMHgxNDBjMGMxOCwgMHgzNTEzMTMyNiwgMHgyZmVjZWNjMyxcbiAgICAweGUxNWY1ZmJlLCAweGEyOTc5NzM1LCAweGNjNDQ0NDg4LCAweDM5MTcxNzJlLFxuICAgIDB4NTdjNGM0OTMsIDB4ZjJhN2E3NTUsIDB4ODI3ZTdlZmMsIDB4NDczZDNkN2EsXG4gICAgMHhhYzY0NjRjOCwgMHhlNzVkNWRiYSwgMHgyYjE5MTkzMiwgMHg5NTczNzNlNixcbiAgICAweGEwNjA2MGMwLCAweDk4ODE4MTE5LCAweGQxNGY0ZjllLCAweDdmZGNkY2EzLFxuICAgIDB4NjYyMjIyNDQsIDB4N2UyYTJhNTQsIDB4YWI5MDkwM2IsIDB4ODM4ODg4MGIsXG4gICAgMHhjYTQ2NDY4YywgMHgyOWVlZWVjNywgMHhkM2I4Yjg2YiwgMHgzYzE0MTQyOCxcbiAgICAweDc5ZGVkZWE3LCAweGUyNWU1ZWJjLCAweDFkMGIwYjE2LCAweDc2ZGJkYmFkLFxuICAgIDB4M2JlMGUwZGIsIDB4NTYzMjMyNjQsIDB4NGUzYTNhNzQsIDB4MWUwYTBhMTQsXG4gICAgMHhkYjQ5NDk5MiwgMHgwYTA2MDYwYywgMHg2YzI0MjQ0OCwgMHhlNDVjNWNiOCxcbiAgICAweDVkYzJjMjlmLCAweDZlZDNkM2JkLCAweGVmYWNhYzQzLCAweGE2NjI2MmM0LFxuICAgIDB4YTg5MTkxMzksIDB4YTQ5NTk1MzEsIDB4MzdlNGU0ZDMsIDB4OGI3OTc5ZjIsXG4gICAgMHgzMmU3ZTdkNSwgMHg0M2M4Yzg4YiwgMHg1OTM3Mzc2ZSwgMHhiNzZkNmRkYSxcbiAgICAweDhjOGQ4ZDAxLCAweDY0ZDVkNWIxLCAweGQyNGU0ZTljLCAweGUwYTlhOTQ5LFxuICAgIDB4YjQ2YzZjZDgsIDB4ZmE1NjU2YWMsIDB4MDdmNGY0ZjMsIDB4MjVlYWVhY2YsXG4gICAgMHhhZjY1NjVjYSwgMHg4ZTdhN2FmNCwgMHhlOWFlYWU0NywgMHgxODA4MDgxMCxcbiAgICAweGQ1YmFiYTZmLCAweDg4Nzg3OGYwLCAweDZmMjUyNTRhLCAweDcyMmUyZTVjLFxuICAgIDB4MjQxYzFjMzgsIDB4ZjFhNmE2NTcsIDB4YzdiNGI0NzMsIDB4NTFjNmM2OTcsXG4gICAgMHgyM2U4ZThjYiwgMHg3Y2RkZGRhMSwgMHg5Yzc0NzRlOCwgMHgyMTFmMWYzZSxcbiAgICAweGRkNGI0Yjk2LCAweGRjYmRiZDYxLCAweDg2OGI4YjBkLCAweDg1OGE4YTBmLFxuICAgIDB4OTA3MDcwZTAsIDB4NDIzZTNlN2MsIDB4YzRiNWI1NzEsIDB4YWE2NjY2Y2MsXG4gICAgMHhkODQ4NDg5MCwgMHgwNTAzMDMwNiwgMHgwMWY2ZjZmNywgMHgxMjBlMGUxYyxcbiAgICAweGEzNjE2MWMyLCAweDVmMzUzNTZhLCAweGY5NTc1N2FlLCAweGQwYjliOTY5LFxuICAgIDB4OTE4Njg2MTcsIDB4NThjMWMxOTksIDB4MjcxZDFkM2EsIDB4Yjk5ZTllMjcsXG4gICAgMHgzOGUxZTFkOSwgMHgxM2Y4ZjhlYiwgMHhiMzk4OTgyYiwgMHgzMzExMTEyMixcbiAgICAweGJiNjk2OWQyLCAweDcwZDlkOWE5LCAweDg5OGU4ZTA3LCAweGE3OTQ5NDMzLFxuICAgIDB4YjY5YjliMmQsIDB4MjIxZTFlM2MsIDB4OTI4Nzg3MTUsIDB4MjBlOWU5YzksXG4gICAgMHg0OWNlY2U4NywgMHhmZjU1NTVhYSwgMHg3ODI4Mjg1MCwgMHg3YWRmZGZhNSxcbiAgICAweDhmOGM4YzAzLCAweGY4YTFhMTU5LCAweDgwODk4OTA5LCAweDE3MGQwZDFhLFxuICAgIDB4ZGFiZmJmNjUsIDB4MzFlNmU2ZDcsIDB4YzY0MjQyODQsIDB4Yjg2ODY4ZDAsXG4gICAgMHhjMzQxNDE4MiwgMHhiMDk5OTkyOSwgMHg3NzJkMmQ1YSwgMHgxMTBmMGYxZSxcbiAgICAweGNiYjBiMDdiLCAweGZjNTQ1NGE4LCAweGQ2YmJiYjZkLCAweDNhMTYxNjJjXG5dO1xuXG52YXIgVDIgPSBbXG4gICAgMHg2MzYzYzZhNSwgMHg3YzdjZjg4NCwgMHg3Nzc3ZWU5OSwgMHg3YjdiZjY4ZCxcbiAgICAweGYyZjJmZjBkLCAweDZiNmJkNmJkLCAweDZmNmZkZWIxLCAweGM1YzU5MTU0LFxuICAgIDB4MzAzMDYwNTAsIDB4MDEwMTAyMDMsIDB4Njc2N2NlYTksIDB4MmIyYjU2N2QsXG4gICAgMHhmZWZlZTcxOSwgMHhkN2Q3YjU2MiwgMHhhYmFiNGRlNiwgMHg3Njc2ZWM5YSxcbiAgICAweGNhY2E4ZjQ1LCAweDgyODIxZjlkLCAweGM5Yzk4OTQwLCAweDdkN2RmYTg3LFxuICAgIDB4ZmFmYWVmMTUsIDB4NTk1OWIyZWIsIDB4NDc0NzhlYzksIDB4ZjBmMGZiMGIsXG4gICAgMHhhZGFkNDFlYywgMHhkNGQ0YjM2NywgMHhhMmEyNWZmZCwgMHhhZmFmNDVlYSxcbiAgICAweDljOWMyM2JmLCAweGE0YTQ1M2Y3LCAweDcyNzJlNDk2LCAweGMwYzA5YjViLFxuICAgIDB4YjdiNzc1YzIsIDB4ZmRmZGUxMWMsIDB4OTM5MzNkYWUsIDB4MjYyNjRjNmEsXG4gICAgMHgzNjM2NmM1YSwgMHgzZjNmN2U0MSwgMHhmN2Y3ZjUwMiwgMHhjY2NjODM0ZixcbiAgICAweDM0MzQ2ODVjLCAweGE1YTU1MWY0LCAweGU1ZTVkMTM0LCAweGYxZjFmOTA4LFxuICAgIDB4NzE3MWUyOTMsIDB4ZDhkOGFiNzMsIDB4MzEzMTYyNTMsIDB4MTUxNTJhM2YsXG4gICAgMHgwNDA0MDgwYywgMHhjN2M3OTU1MiwgMHgyMzIzNDY2NSwgMHhjM2MzOWQ1ZSxcbiAgICAweDE4MTgzMDI4LCAweDk2OTYzN2ExLCAweDA1MDUwYTBmLCAweDlhOWEyZmI1LFxuICAgIDB4MDcwNzBlMDksIDB4MTIxMjI0MzYsIDB4ODA4MDFiOWIsIDB4ZTJlMmRmM2QsXG4gICAgMHhlYmViY2QyNiwgMHgyNzI3NGU2OSwgMHhiMmIyN2ZjZCwgMHg3NTc1ZWE5ZixcbiAgICAweDA5MDkxMjFiLCAweDgzODMxZDllLCAweDJjMmM1ODc0LCAweDFhMWEzNDJlLFxuICAgIDB4MWIxYjM2MmQsIDB4NmU2ZWRjYjIsIDB4NWE1YWI0ZWUsIDB4YTBhMDViZmIsXG4gICAgMHg1MjUyYTRmNiwgMHgzYjNiNzY0ZCwgMHhkNmQ2Yjc2MSwgMHhiM2IzN2RjZSxcbiAgICAweDI5Mjk1MjdiLCAweGUzZTNkZDNlLCAweDJmMmY1ZTcxLCAweDg0ODQxMzk3LFxuICAgIDB4NTM1M2E2ZjUsIDB4ZDFkMWI5NjgsIDB4MDAwMDAwMDAsIDB4ZWRlZGMxMmMsXG4gICAgMHgyMDIwNDA2MCwgMHhmY2ZjZTMxZiwgMHhiMWIxNzljOCwgMHg1YjViYjZlZCxcbiAgICAweDZhNmFkNGJlLCAweGNiY2I4ZDQ2LCAweGJlYmU2N2Q5LCAweDM5Mzk3MjRiLFxuICAgIDB4NGE0YTk0ZGUsIDB4NGM0Yzk4ZDQsIDB4NTg1OGIwZTgsIDB4Y2ZjZjg1NGEsXG4gICAgMHhkMGQwYmI2YiwgMHhlZmVmYzUyYSwgMHhhYWFhNGZlNSwgMHhmYmZiZWQxNixcbiAgICAweDQzNDM4NmM1LCAweDRkNGQ5YWQ3LCAweDMzMzM2NjU1LCAweDg1ODUxMTk0LFxuICAgIDB4NDU0NThhY2YsIDB4ZjlmOWU5MTAsIDB4MDIwMjA0MDYsIDB4N2Y3ZmZlODEsXG4gICAgMHg1MDUwYTBmMCwgMHgzYzNjNzg0NCwgMHg5ZjlmMjViYSwgMHhhOGE4NGJlMyxcbiAgICAweDUxNTFhMmYzLCAweGEzYTM1ZGZlLCAweDQwNDA4MGMwLCAweDhmOGYwNThhLFxuICAgIDB4OTI5MjNmYWQsIDB4OWQ5ZDIxYmMsIDB4MzgzODcwNDgsIDB4ZjVmNWYxMDQsXG4gICAgMHhiY2JjNjNkZiwgMHhiNmI2NzdjMSwgMHhkYWRhYWY3NSwgMHgyMTIxNDI2MyxcbiAgICAweDEwMTAyMDMwLCAweGZmZmZlNTFhLCAweGYzZjNmZDBlLCAweGQyZDJiZjZkLFxuICAgIDB4Y2RjZDgxNGMsIDB4MGMwYzE4MTQsIDB4MTMxMzI2MzUsIDB4ZWNlY2MzMmYsXG4gICAgMHg1ZjVmYmVlMSwgMHg5Nzk3MzVhMiwgMHg0NDQ0ODhjYywgMHgxNzE3MmUzOSxcbiAgICAweGM0YzQ5MzU3LCAweGE3YTc1NWYyLCAweDdlN2VmYzgyLCAweDNkM2Q3YTQ3LFxuICAgIDB4NjQ2NGM4YWMsIDB4NWQ1ZGJhZTcsIDB4MTkxOTMyMmIsIDB4NzM3M2U2OTUsXG4gICAgMHg2MDYwYzBhMCwgMHg4MTgxMTk5OCwgMHg0ZjRmOWVkMSwgMHhkY2RjYTM3ZixcbiAgICAweDIyMjI0NDY2LCAweDJhMmE1NDdlLCAweDkwOTAzYmFiLCAweDg4ODgwYjgzLFxuICAgIDB4NDY0NjhjY2EsIDB4ZWVlZWM3MjksIDB4YjhiODZiZDMsIDB4MTQxNDI4M2MsXG4gICAgMHhkZWRlYTc3OSwgMHg1ZTVlYmNlMiwgMHgwYjBiMTYxZCwgMHhkYmRiYWQ3NixcbiAgICAweGUwZTBkYjNiLCAweDMyMzI2NDU2LCAweDNhM2E3NDRlLCAweDBhMGExNDFlLFxuICAgIDB4NDk0OTkyZGIsIDB4MDYwNjBjMGEsIDB4MjQyNDQ4NmMsIDB4NWM1Y2I4ZTQsXG4gICAgMHhjMmMyOWY1ZCwgMHhkM2QzYmQ2ZSwgMHhhY2FjNDNlZiwgMHg2MjYyYzRhNixcbiAgICAweDkxOTEzOWE4LCAweDk1OTUzMWE0LCAweGU0ZTRkMzM3LCAweDc5NzlmMjhiLFxuICAgIDB4ZTdlN2Q1MzIsIDB4YzhjODhiNDMsIDB4MzczNzZlNTksIDB4NmQ2ZGRhYjcsXG4gICAgMHg4ZDhkMDE4YywgMHhkNWQ1YjE2NCwgMHg0ZTRlOWNkMiwgMHhhOWE5NDllMCxcbiAgICAweDZjNmNkOGI0LCAweDU2NTZhY2ZhLCAweGY0ZjRmMzA3LCAweGVhZWFjZjI1LFxuICAgIDB4NjU2NWNhYWYsIDB4N2E3YWY0OGUsIDB4YWVhZTQ3ZTksIDB4MDgwODEwMTgsXG4gICAgMHhiYWJhNmZkNSwgMHg3ODc4ZjA4OCwgMHgyNTI1NGE2ZiwgMHgyZTJlNWM3MixcbiAgICAweDFjMWMzODI0LCAweGE2YTY1N2YxLCAweGI0YjQ3M2M3LCAweGM2YzY5NzUxLFxuICAgIDB4ZThlOGNiMjMsIDB4ZGRkZGExN2MsIDB4NzQ3NGU4OWMsIDB4MWYxZjNlMjEsXG4gICAgMHg0YjRiOTZkZCwgMHhiZGJkNjFkYywgMHg4YjhiMGQ4NiwgMHg4YThhMGY4NSxcbiAgICAweDcwNzBlMDkwLCAweDNlM2U3YzQyLCAweGI1YjU3MWM0LCAweDY2NjZjY2FhLFxuICAgIDB4NDg0ODkwZDgsIDB4MDMwMzA2MDUsIDB4ZjZmNmY3MDEsIDB4MGUwZTFjMTIsXG4gICAgMHg2MTYxYzJhMywgMHgzNTM1NmE1ZiwgMHg1NzU3YWVmOSwgMHhiOWI5NjlkMCxcbiAgICAweDg2ODYxNzkxLCAweGMxYzE5OTU4LCAweDFkMWQzYTI3LCAweDllOWUyN2I5LFxuICAgIDB4ZTFlMWQ5MzgsIDB4ZjhmOGViMTMsIDB4OTg5ODJiYjMsIDB4MTExMTIyMzMsXG4gICAgMHg2OTY5ZDJiYiwgMHhkOWQ5YTk3MCwgMHg4ZThlMDc4OSwgMHg5NDk0MzNhNyxcbiAgICAweDliOWIyZGI2LCAweDFlMWUzYzIyLCAweDg3ODcxNTkyLCAweGU5ZTljOTIwLFxuICAgIDB4Y2VjZTg3NDksIDB4NTU1NWFhZmYsIDB4MjgyODUwNzgsIDB4ZGZkZmE1N2EsXG4gICAgMHg4YzhjMDM4ZiwgMHhhMWExNTlmOCwgMHg4OTg5MDk4MCwgMHgwZDBkMWExNyxcbiAgICAweGJmYmY2NWRhLCAweGU2ZTZkNzMxLCAweDQyNDI4NGM2LCAweDY4NjhkMGI4LFxuICAgIDB4NDE0MTgyYzMsIDB4OTk5OTI5YjAsIDB4MmQyZDVhNzcsIDB4MGYwZjFlMTEsXG4gICAgMHhiMGIwN2JjYiwgMHg1NDU0YThmYywgMHhiYmJiNmRkNiwgMHgxNjE2MmMzYVxuXTtcblxudmFyIFQzID0gW1xuICAgIDB4NjNjNmE1NjMsIDB4N2NmODg0N2MsIDB4NzdlZTk5NzcsIDB4N2JmNjhkN2IsXG4gICAgMHhmMmZmMGRmMiwgMHg2YmQ2YmQ2YiwgMHg2ZmRlYjE2ZiwgMHhjNTkxNTRjNSxcbiAgICAweDMwNjA1MDMwLCAweDAxMDIwMzAxLCAweDY3Y2VhOTY3LCAweDJiNTY3ZDJiLFxuICAgIDB4ZmVlNzE5ZmUsIDB4ZDdiNTYyZDcsIDB4YWI0ZGU2YWIsIDB4NzZlYzlhNzYsXG4gICAgMHhjYThmNDVjYSwgMHg4MjFmOWQ4MiwgMHhjOTg5NDBjOSwgMHg3ZGZhODc3ZCxcbiAgICAweGZhZWYxNWZhLCAweDU5YjJlYjU5LCAweDQ3OGVjOTQ3LCAweGYwZmIwYmYwLFxuICAgIDB4YWQ0MWVjYWQsIDB4ZDRiMzY3ZDQsIDB4YTI1ZmZkYTIsIDB4YWY0NWVhYWYsXG4gICAgMHg5YzIzYmY5YywgMHhhNDUzZjdhNCwgMHg3MmU0OTY3MiwgMHhjMDliNWJjMCxcbiAgICAweGI3NzVjMmI3LCAweGZkZTExY2ZkLCAweDkzM2RhZTkzLCAweDI2NGM2YTI2LFxuICAgIDB4MzY2YzVhMzYsIDB4M2Y3ZTQxM2YsIDB4ZjdmNTAyZjcsIDB4Y2M4MzRmY2MsXG4gICAgMHgzNDY4NWMzNCwgMHhhNTUxZjRhNSwgMHhlNWQxMzRlNSwgMHhmMWY5MDhmMSxcbiAgICAweDcxZTI5MzcxLCAweGQ4YWI3M2Q4LCAweDMxNjI1MzMxLCAweDE1MmEzZjE1LFxuICAgIDB4MDQwODBjMDQsIDB4Yzc5NTUyYzcsIDB4MjM0NjY1MjMsIDB4YzM5ZDVlYzMsXG4gICAgMHgxODMwMjgxOCwgMHg5NjM3YTE5NiwgMHgwNTBhMGYwNSwgMHg5YTJmYjU5YSxcbiAgICAweDA3MGUwOTA3LCAweDEyMjQzNjEyLCAweDgwMWI5YjgwLCAweGUyZGYzZGUyLFxuICAgIDB4ZWJjZDI2ZWIsIDB4Mjc0ZTY5MjcsIDB4YjI3ZmNkYjIsIDB4NzVlYTlmNzUsXG4gICAgMHgwOTEyMWIwOSwgMHg4MzFkOWU4MywgMHgyYzU4NzQyYywgMHgxYTM0MmUxYSxcbiAgICAweDFiMzYyZDFiLCAweDZlZGNiMjZlLCAweDVhYjRlZTVhLCAweGEwNWJmYmEwLFxuICAgIDB4NTJhNGY2NTIsIDB4M2I3NjRkM2IsIDB4ZDZiNzYxZDYsIDB4YjM3ZGNlYjMsXG4gICAgMHgyOTUyN2IyOSwgMHhlM2RkM2VlMywgMHgyZjVlNzEyZiwgMHg4NDEzOTc4NCxcbiAgICAweDUzYTZmNTUzLCAweGQxYjk2OGQxLCAweDAwMDAwMDAwLCAweGVkYzEyY2VkLFxuICAgIDB4MjA0MDYwMjAsIDB4ZmNlMzFmZmMsIDB4YjE3OWM4YjEsIDB4NWJiNmVkNWIsXG4gICAgMHg2YWQ0YmU2YSwgMHhjYjhkNDZjYiwgMHhiZTY3ZDliZSwgMHgzOTcyNGIzOSxcbiAgICAweDRhOTRkZTRhLCAweDRjOThkNDRjLCAweDU4YjBlODU4LCAweGNmODU0YWNmLFxuICAgIDB4ZDBiYjZiZDAsIDB4ZWZjNTJhZWYsIDB4YWE0ZmU1YWEsIDB4ZmJlZDE2ZmIsXG4gICAgMHg0Mzg2YzU0MywgMHg0ZDlhZDc0ZCwgMHgzMzY2NTUzMywgMHg4NTExOTQ4NSxcbiAgICAweDQ1OGFjZjQ1LCAweGY5ZTkxMGY5LCAweDAyMDQwNjAyLCAweDdmZmU4MTdmLFxuICAgIDB4NTBhMGYwNTAsIDB4M2M3ODQ0M2MsIDB4OWYyNWJhOWYsIDB4YTg0YmUzYTgsXG4gICAgMHg1MWEyZjM1MSwgMHhhMzVkZmVhMywgMHg0MDgwYzA0MCwgMHg4ZjA1OGE4ZixcbiAgICAweDkyM2ZhZDkyLCAweDlkMjFiYzlkLCAweDM4NzA0ODM4LCAweGY1ZjEwNGY1LFxuICAgIDB4YmM2M2RmYmMsIDB4YjY3N2MxYjYsIDB4ZGFhZjc1ZGEsIDB4MjE0MjYzMjEsXG4gICAgMHgxMDIwMzAxMCwgMHhmZmU1MWFmZiwgMHhmM2ZkMGVmMywgMHhkMmJmNmRkMixcbiAgICAweGNkODE0Y2NkLCAweDBjMTgxNDBjLCAweDEzMjYzNTEzLCAweGVjYzMyZmVjLFxuICAgIDB4NWZiZWUxNWYsIDB4OTczNWEyOTcsIDB4NDQ4OGNjNDQsIDB4MTcyZTM5MTcsXG4gICAgMHhjNDkzNTdjNCwgMHhhNzU1ZjJhNywgMHg3ZWZjODI3ZSwgMHgzZDdhNDczZCxcbiAgICAweDY0YzhhYzY0LCAweDVkYmFlNzVkLCAweDE5MzIyYjE5LCAweDczZTY5NTczLFxuICAgIDB4NjBjMGEwNjAsIDB4ODExOTk4ODEsIDB4NGY5ZWQxNGYsIDB4ZGNhMzdmZGMsXG4gICAgMHgyMjQ0NjYyMiwgMHgyYTU0N2UyYSwgMHg5MDNiYWI5MCwgMHg4ODBiODM4OCxcbiAgICAweDQ2OGNjYTQ2LCAweGVlYzcyOWVlLCAweGI4NmJkM2I4LCAweDE0MjgzYzE0LFxuICAgIDB4ZGVhNzc5ZGUsIDB4NWViY2UyNWUsIDB4MGIxNjFkMGIsIDB4ZGJhZDc2ZGIsXG4gICAgMHhlMGRiM2JlMCwgMHgzMjY0NTYzMiwgMHgzYTc0NGUzYSwgMHgwYTE0MWUwYSxcbiAgICAweDQ5OTJkYjQ5LCAweDA2MGMwYTA2LCAweDI0NDg2YzI0LCAweDVjYjhlNDVjLFxuICAgIDB4YzI5ZjVkYzIsIDB4ZDNiZDZlZDMsIDB4YWM0M2VmYWMsIDB4NjJjNGE2NjIsXG4gICAgMHg5MTM5YTg5MSwgMHg5NTMxYTQ5NSwgMHhlNGQzMzdlNCwgMHg3OWYyOGI3OSxcbiAgICAweGU3ZDUzMmU3LCAweGM4OGI0M2M4LCAweDM3NmU1OTM3LCAweDZkZGFiNzZkLFxuICAgIDB4OGQwMThjOGQsIDB4ZDViMTY0ZDUsIDB4NGU5Y2QyNGUsIDB4YTk0OWUwYTksXG4gICAgMHg2Y2Q4YjQ2YywgMHg1NmFjZmE1NiwgMHhmNGYzMDdmNCwgMHhlYWNmMjVlYSxcbiAgICAweDY1Y2FhZjY1LCAweDdhZjQ4ZTdhLCAweGFlNDdlOWFlLCAweDA4MTAxODA4LFxuICAgIDB4YmE2ZmQ1YmEsIDB4NzhmMDg4NzgsIDB4MjU0YTZmMjUsIDB4MmU1YzcyMmUsXG4gICAgMHgxYzM4MjQxYywgMHhhNjU3ZjFhNiwgMHhiNDczYzdiNCwgMHhjNjk3NTFjNixcbiAgICAweGU4Y2IyM2U4LCAweGRkYTE3Y2RkLCAweDc0ZTg5Yzc0LCAweDFmM2UyMTFmLFxuICAgIDB4NGI5NmRkNGIsIDB4YmQ2MWRjYmQsIDB4OGIwZDg2OGIsIDB4OGEwZjg1OGEsXG4gICAgMHg3MGUwOTA3MCwgMHgzZTdjNDIzZSwgMHhiNTcxYzRiNSwgMHg2NmNjYWE2NixcbiAgICAweDQ4OTBkODQ4LCAweDAzMDYwNTAzLCAweGY2ZjcwMWY2LCAweDBlMWMxMjBlLFxuICAgIDB4NjFjMmEzNjEsIDB4MzU2YTVmMzUsIDB4NTdhZWY5NTcsIDB4Yjk2OWQwYjksXG4gICAgMHg4NjE3OTE4NiwgMHhjMTk5NThjMSwgMHgxZDNhMjcxZCwgMHg5ZTI3Yjk5ZSxcbiAgICAweGUxZDkzOGUxLCAweGY4ZWIxM2Y4LCAweDk4MmJiMzk4LCAweDExMjIzMzExLFxuICAgIDB4NjlkMmJiNjksIDB4ZDlhOTcwZDksIDB4OGUwNzg5OGUsIDB4OTQzM2E3OTQsXG4gICAgMHg5YjJkYjY5YiwgMHgxZTNjMjIxZSwgMHg4NzE1OTI4NywgMHhlOWM5MjBlOSxcbiAgICAweGNlODc0OWNlLCAweDU1YWFmZjU1LCAweDI4NTA3ODI4LCAweGRmYTU3YWRmLFxuICAgIDB4OGMwMzhmOGMsIDB4YTE1OWY4YTEsIDB4ODkwOTgwODksIDB4MGQxYTE3MGQsXG4gICAgMHhiZjY1ZGFiZiwgMHhlNmQ3MzFlNiwgMHg0Mjg0YzY0MiwgMHg2OGQwYjg2OCxcbiAgICAweDQxODJjMzQxLCAweDk5MjliMDk5LCAweDJkNWE3NzJkLCAweDBmMWUxMTBmLFxuICAgIDB4YjA3YmNiYjAsIDB4NTRhOGZjNTQsIDB4YmI2ZGQ2YmIsIDB4MTYyYzNhMTZcbl07XG5cbnZhciBUNCA9IFtcbiAgICAweGM2YTU2MzYzLCAweGY4ODQ3YzdjLCAweGVlOTk3Nzc3LCAweGY2OGQ3YjdiLFxuICAgIDB4ZmYwZGYyZjIsIDB4ZDZiZDZiNmIsIDB4ZGViMTZmNmYsIDB4OTE1NGM1YzUsXG4gICAgMHg2MDUwMzAzMCwgMHgwMjAzMDEwMSwgMHhjZWE5Njc2NywgMHg1NjdkMmIyYixcbiAgICAweGU3MTlmZWZlLCAweGI1NjJkN2Q3LCAweDRkZTZhYmFiLCAweGVjOWE3Njc2LFxuICAgIDB4OGY0NWNhY2EsIDB4MWY5ZDgyODIsIDB4ODk0MGM5YzksIDB4ZmE4NzdkN2QsXG4gICAgMHhlZjE1ZmFmYSwgMHhiMmViNTk1OSwgMHg4ZWM5NDc0NywgMHhmYjBiZjBmMCxcbiAgICAweDQxZWNhZGFkLCAweGIzNjdkNGQ0LCAweDVmZmRhMmEyLCAweDQ1ZWFhZmFmLFxuICAgIDB4MjNiZjljOWMsIDB4NTNmN2E0YTQsIDB4ZTQ5NjcyNzIsIDB4OWI1YmMwYzAsXG4gICAgMHg3NWMyYjdiNywgMHhlMTFjZmRmZCwgMHgzZGFlOTM5MywgMHg0YzZhMjYyNixcbiAgICAweDZjNWEzNjM2LCAweDdlNDEzZjNmLCAweGY1MDJmN2Y3LCAweDgzNGZjY2NjLFxuICAgIDB4Njg1YzM0MzQsIDB4NTFmNGE1YTUsIDB4ZDEzNGU1ZTUsIDB4ZjkwOGYxZjEsXG4gICAgMHhlMjkzNzE3MSwgMHhhYjczZDhkOCwgMHg2MjUzMzEzMSwgMHgyYTNmMTUxNSxcbiAgICAweDA4MGMwNDA0LCAweDk1NTJjN2M3LCAweDQ2NjUyMzIzLCAweDlkNWVjM2MzLFxuICAgIDB4MzAyODE4MTgsIDB4MzdhMTk2OTYsIDB4MGEwZjA1MDUsIDB4MmZiNTlhOWEsXG4gICAgMHgwZTA5MDcwNywgMHgyNDM2MTIxMiwgMHgxYjliODA4MCwgMHhkZjNkZTJlMixcbiAgICAweGNkMjZlYmViLCAweDRlNjkyNzI3LCAweDdmY2RiMmIyLCAweGVhOWY3NTc1LFxuICAgIDB4MTIxYjA5MDksIDB4MWQ5ZTgzODMsIDB4NTg3NDJjMmMsIDB4MzQyZTFhMWEsXG4gICAgMHgzNjJkMWIxYiwgMHhkY2IyNmU2ZSwgMHhiNGVlNWE1YSwgMHg1YmZiYTBhMCxcbiAgICAweGE0ZjY1MjUyLCAweDc2NGQzYjNiLCAweGI3NjFkNmQ2LCAweDdkY2ViM2IzLFxuICAgIDB4NTI3YjI5MjksIDB4ZGQzZWUzZTMsIDB4NWU3MTJmMmYsIDB4MTM5Nzg0ODQsXG4gICAgMHhhNmY1NTM1MywgMHhiOTY4ZDFkMSwgMHgwMDAwMDAwMCwgMHhjMTJjZWRlZCxcbiAgICAweDQwNjAyMDIwLCAweGUzMWZmY2ZjLCAweDc5YzhiMWIxLCAweGI2ZWQ1YjViLFxuICAgIDB4ZDRiZTZhNmEsIDB4OGQ0NmNiY2IsIDB4NjdkOWJlYmUsIDB4NzI0YjM5MzksXG4gICAgMHg5NGRlNGE0YSwgMHg5OGQ0NGM0YywgMHhiMGU4NTg1OCwgMHg4NTRhY2ZjZixcbiAgICAweGJiNmJkMGQwLCAweGM1MmFlZmVmLCAweDRmZTVhYWFhLCAweGVkMTZmYmZiLFxuICAgIDB4ODZjNTQzNDMsIDB4OWFkNzRkNGQsIDB4NjY1NTMzMzMsIDB4MTE5NDg1ODUsXG4gICAgMHg4YWNmNDU0NSwgMHhlOTEwZjlmOSwgMHgwNDA2MDIwMiwgMHhmZTgxN2Y3ZixcbiAgICAweGEwZjA1MDUwLCAweDc4NDQzYzNjLCAweDI1YmE5ZjlmLCAweDRiZTNhOGE4LFxuICAgIDB4YTJmMzUxNTEsIDB4NWRmZWEzYTMsIDB4ODBjMDQwNDAsIDB4MDU4YThmOGYsXG4gICAgMHgzZmFkOTI5MiwgMHgyMWJjOWQ5ZCwgMHg3MDQ4MzgzOCwgMHhmMTA0ZjVmNSxcbiAgICAweDYzZGZiY2JjLCAweDc3YzFiNmI2LCAweGFmNzVkYWRhLCAweDQyNjMyMTIxLFxuICAgIDB4MjAzMDEwMTAsIDB4ZTUxYWZmZmYsIDB4ZmQwZWYzZjMsIDB4YmY2ZGQyZDIsXG4gICAgMHg4MTRjY2RjZCwgMHgxODE0MGMwYywgMHgyNjM1MTMxMywgMHhjMzJmZWNlYyxcbiAgICAweGJlZTE1ZjVmLCAweDM1YTI5Nzk3LCAweDg4Y2M0NDQ0LCAweDJlMzkxNzE3LFxuICAgIDB4OTM1N2M0YzQsIDB4NTVmMmE3YTcsIDB4ZmM4MjdlN2UsIDB4N2E0NzNkM2QsXG4gICAgMHhjOGFjNjQ2NCwgMHhiYWU3NWQ1ZCwgMHgzMjJiMTkxOSwgMHhlNjk1NzM3MyxcbiAgICAweGMwYTA2MDYwLCAweDE5OTg4MTgxLCAweDllZDE0ZjRmLCAweGEzN2ZkY2RjLFxuICAgIDB4NDQ2NjIyMjIsIDB4NTQ3ZTJhMmEsIDB4M2JhYjkwOTAsIDB4MGI4Mzg4ODgsXG4gICAgMHg4Y2NhNDY0NiwgMHhjNzI5ZWVlZSwgMHg2YmQzYjhiOCwgMHgyODNjMTQxNCxcbiAgICAweGE3NzlkZWRlLCAweGJjZTI1ZTVlLCAweDE2MWQwYjBiLCAweGFkNzZkYmRiLFxuICAgIDB4ZGIzYmUwZTAsIDB4NjQ1NjMyMzIsIDB4NzQ0ZTNhM2EsIDB4MTQxZTBhMGEsXG4gICAgMHg5MmRiNDk0OSwgMHgwYzBhMDYwNiwgMHg0ODZjMjQyNCwgMHhiOGU0NWM1YyxcbiAgICAweDlmNWRjMmMyLCAweGJkNmVkM2QzLCAweDQzZWZhY2FjLCAweGM0YTY2MjYyLFxuICAgIDB4MzlhODkxOTEsIDB4MzFhNDk1OTUsIDB4ZDMzN2U0ZTQsIDB4ZjI4Yjc5NzksXG4gICAgMHhkNTMyZTdlNywgMHg4YjQzYzhjOCwgMHg2ZTU5MzczNywgMHhkYWI3NmQ2ZCxcbiAgICAweDAxOGM4ZDhkLCAweGIxNjRkNWQ1LCAweDljZDI0ZTRlLCAweDQ5ZTBhOWE5LFxuICAgIDB4ZDhiNDZjNmMsIDB4YWNmYTU2NTYsIDB4ZjMwN2Y0ZjQsIDB4Y2YyNWVhZWEsXG4gICAgMHhjYWFmNjU2NSwgMHhmNDhlN2E3YSwgMHg0N2U5YWVhZSwgMHgxMDE4MDgwOCxcbiAgICAweDZmZDViYWJhLCAweGYwODg3ODc4LCAweDRhNmYyNTI1LCAweDVjNzIyZTJlLFxuICAgIDB4MzgyNDFjMWMsIDB4NTdmMWE2YTYsIDB4NzNjN2I0YjQsIDB4OTc1MWM2YzYsXG4gICAgMHhjYjIzZThlOCwgMHhhMTdjZGRkZCwgMHhlODljNzQ3NCwgMHgzZTIxMWYxZixcbiAgICAweDk2ZGQ0YjRiLCAweDYxZGNiZGJkLCAweDBkODY4YjhiLCAweDBmODU4YThhLFxuICAgIDB4ZTA5MDcwNzAsIDB4N2M0MjNlM2UsIDB4NzFjNGI1YjUsIDB4Y2NhYTY2NjYsXG4gICAgMHg5MGQ4NDg0OCwgMHgwNjA1MDMwMywgMHhmNzAxZjZmNiwgMHgxYzEyMGUwZSxcbiAgICAweGMyYTM2MTYxLCAweDZhNWYzNTM1LCAweGFlZjk1NzU3LCAweDY5ZDBiOWI5LFxuICAgIDB4MTc5MTg2ODYsIDB4OTk1OGMxYzEsIDB4M2EyNzFkMWQsIDB4MjdiOTllOWUsXG4gICAgMHhkOTM4ZTFlMSwgMHhlYjEzZjhmOCwgMHgyYmIzOTg5OCwgMHgyMjMzMTExMSxcbiAgICAweGQyYmI2OTY5LCAweGE5NzBkOWQ5LCAweDA3ODk4ZThlLCAweDMzYTc5NDk0LFxuICAgIDB4MmRiNjliOWIsIDB4M2MyMjFlMWUsIDB4MTU5Mjg3ODcsIDB4YzkyMGU5ZTksXG4gICAgMHg4NzQ5Y2VjZSwgMHhhYWZmNTU1NSwgMHg1MDc4MjgyOCwgMHhhNTdhZGZkZixcbiAgICAweDAzOGY4YzhjLCAweDU5ZjhhMWExLCAweDA5ODA4OTg5LCAweDFhMTcwZDBkLFxuICAgIDB4NjVkYWJmYmYsIDB4ZDczMWU2ZTYsIDB4ODRjNjQyNDIsIDB4ZDBiODY4NjgsXG4gICAgMHg4MmMzNDE0MSwgMHgyOWIwOTk5OSwgMHg1YTc3MmQyZCwgMHgxZTExMGYwZixcbiAgICAweDdiY2JiMGIwLCAweGE4ZmM1NDU0LCAweDZkZDZiYmJiLCAweDJjM2ExNjE2XG5dO1xuXG5mdW5jdGlvbiBCMCh4KSB7XG4gIHJldHVybiAoeCAmIDI1NSk7XG59XG5cbmZ1bmN0aW9uIEIxKHgpIHtcbiAgcmV0dXJuICgoeCA+PiA4KSAmIDI1NSk7XG59XG5cbmZ1bmN0aW9uIEIyKHgpIHtcbiAgcmV0dXJuICgoeCA+PiAxNikgJiAyNTUpO1xufVxuXG5mdW5jdGlvbiBCMyh4KSB7XG4gIHJldHVybiAoKHggPj4gMjQpICYgMjU1KTtcbn1cblxuZnVuY3Rpb24gRjEoeDAsIHgxLCB4MiwgeDMpIHtcbiAgcmV0dXJuIEIxKFQxW3gwICYgMjU1XSkgfCAoQjEoVDFbKHgxID4+IDgpICYgMjU1XSkgPDwgOCkgfCAoQjEoVDFbKHgyID4+IDE2KSAmIDI1NV0pIDw8IDE2KSB8IChCMShUMVt4MyA+Pj4gMjRdKSA8PFxuICAgIDI0KTtcbn1cblxuZnVuY3Rpb24gcGFja0J5dGVzKG9jdGV0cykge1xuICB2YXIgaSwgajtcbiAgdmFyIGxlbiA9IG9jdGV0cy5sZW5ndGg7XG4gIHZhciBiID0gbmV3IEFycmF5KGxlbiAvIDQpO1xuXG4gIGlmICghb2N0ZXRzIHx8IGxlbiAlIDQpIHJldHVybjtcblxuICBmb3IgKGkgPSAwLCBqID0gMDsgaiA8IGxlbjsgaiArPSA0KVxuICAgIGJbaSsrXSA9IG9jdGV0c1tqXSB8IChvY3RldHNbaiArIDFdIDw8IDgpIHwgKG9jdGV0c1tqICsgMl0gPDwgMTYpIHwgKG9jdGV0c1tqICsgM10gPDwgMjQpO1xuXG4gIHJldHVybiBiO1xufVxuXG5mdW5jdGlvbiB1bnBhY2tCeXRlcyhwYWNrZWQpIHtcbiAgdmFyIGo7XG4gIHZhciBpID0gMCxcbiAgICBsID0gcGFja2VkLmxlbmd0aDtcbiAgdmFyIHIgPSBuZXcgQXJyYXkobCAqIDQpO1xuXG4gIGZvciAoaiA9IDA7IGogPCBsOyBqKyspIHtcbiAgICByW2krK10gPSBCMChwYWNrZWRbal0pO1xuICAgIHJbaSsrXSA9IEIxKHBhY2tlZFtqXSk7XG4gICAgcltpKytdID0gQjIocGFja2VkW2pdKTtcbiAgICByW2krK10gPSBCMyhwYWNrZWRbal0pO1xuICB9XG4gIHJldHVybiByO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudmFyIG1heGtjID0gODtcbnZhciBtYXhyayA9IDE0O1xuXG5mdW5jdGlvbiBrZXlFeHBhbnNpb24oa2V5KSB7XG4gIHZhciBrYywgaSwgaiwgciwgdDtcbiAgdmFyIHJvdW5kcztcbiAgdmFyIGtleVNjaGVkID0gbmV3IEFycmF5KG1heHJrICsgMSk7XG4gIHZhciBrZXlsZW4gPSBrZXkubGVuZ3RoO1xuICB2YXIgayA9IG5ldyBBcnJheShtYXhrYyk7XG4gIHZhciB0ayA9IG5ldyBBcnJheShtYXhrYyk7XG4gIHZhciByY29ucG9pbnRlciA9IDA7XG5cbiAgaWYgKGtleWxlbiA9PSAxNikge1xuICAgIHJvdW5kcyA9IDEwO1xuICAgIGtjID0gNDtcbiAgfSBlbHNlIGlmIChrZXlsZW4gPT0gMjQpIHtcbiAgICByb3VuZHMgPSAxMjtcbiAgICBrYyA9IDY7XG4gIH0gZWxzZSBpZiAoa2V5bGVuID09IDMyKSB7XG4gICAgcm91bmRzID0gMTQ7XG4gICAga2MgPSA4O1xuICB9IGVsc2Uge1xuICAgIHV0aWwucHJpbnRfZXJyb3IoJ2Flcy5qczogSW52YWxpZCBrZXktbGVuZ3RoIGZvciBBRVMga2V5OicgKyBrZXlsZW4pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCBtYXhyayArIDE7IGkrKykga2V5U2NoZWRbaV0gPSBuZXcgQXJyYXkoNCk7XG5cbiAgZm9yIChpID0gMCwgaiA9IDA7IGogPCBrZXlsZW47IGorKywgaSArPSA0KVxuICAgIGtbal0gPSBrZXkuY2hhckNvZGVBdChpKSB8IChrZXkuY2hhckNvZGVBdChpICsgMSkgPDwgOCkgfCAoa2V5LmNoYXJDb2RlQXQoaSArIDIpIDw8IDE2KSB8IChrZXkuY2hhckNvZGVBdChpICsgMykgPDxcbiAgICAgIDI0KTtcblxuICBmb3IgKGogPSBrYyAtIDE7IGogPj0gMDsgai0tKSB0a1tqXSA9IGtbal07XG5cbiAgciA9IDA7XG4gIHQgPSAwO1xuICBmb3IgKGogPSAwO1xuICAoaiA8IGtjKSAmJiAociA8IHJvdW5kcyArIDEpOykge1xuICAgIGZvciAoO1xuICAgIChqIDwga2MpICYmICh0IDwgNCk7IGorKywgdCsrKSB7XG4gICAgICBrZXlTY2hlZFtyXVt0XSA9IHRrW2pdO1xuICAgIH1cbiAgICBpZiAodCA9PSA0KSB7XG4gICAgICByKys7XG4gICAgICB0ID0gMDtcbiAgICB9XG4gIH1cblxuICB3aGlsZSAociA8IHJvdW5kcyArIDEpIHtcbiAgICB2YXIgdGVtcCA9IHRrW2tjIC0gMV07XG5cbiAgICB0a1swXSBePSBTW0IxKHRlbXApXSB8IChTW0IyKHRlbXApXSA8PCA4KSB8IChTW0IzKHRlbXApXSA8PCAxNikgfCAoU1tCMCh0ZW1wKV0gPDwgMjQpO1xuICAgIHRrWzBdIF49IFJjb25bcmNvbnBvaW50ZXIrK107XG5cbiAgICBpZiAoa2MgIT0gOCkge1xuICAgICAgZm9yIChqID0gMTsgaiA8IGtjOyBqKyspIHRrW2pdIF49IHRrW2ogLSAxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChqID0gMTsgaiA8IGtjIC8gMjsgaisrKSB0a1tqXSBePSB0a1tqIC0gMV07XG5cbiAgICAgIHRlbXAgPSB0a1trYyAvIDIgLSAxXTtcbiAgICAgIHRrW2tjIC8gMl0gXj0gU1tCMCh0ZW1wKV0gfCAoU1tCMSh0ZW1wKV0gPDwgOCkgfCAoU1tCMih0ZW1wKV0gPDwgMTYpIHwgKFNbQjModGVtcCldIDw8IDI0KTtcblxuICAgICAgZm9yIChqID0ga2MgLyAyICsgMTsgaiA8IGtjOyBqKyspIHRrW2pdIF49IHRrW2ogLSAxXTtcbiAgICB9XG5cbiAgICBmb3IgKGogPSAwO1xuICAgIChqIDwga2MpICYmIChyIDwgcm91bmRzICsgMSk7KSB7XG4gICAgICBmb3IgKDtcbiAgICAgIChqIDwga2MpICYmICh0IDwgNCk7IGorKywgdCsrKSB7XG4gICAgICAgIGtleVNjaGVkW3JdW3RdID0gdGtbal07XG4gICAgICB9XG4gICAgICBpZiAodCA9PSA0KSB7XG4gICAgICAgIHIrKztcbiAgICAgICAgdCA9IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHRoaXMucm91bmRzID0gcm91bmRzO1xuICB0aGlzLnJrID0ga2V5U2NoZWQ7XG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiBBRVNlbmNyeXB0KGJsb2NrLCBjdHgpIHtcbiAgdmFyIHI7XG4gIHZhciB0MCwgdDEsIHQyLCB0MztcblxuICB2YXIgYiA9IHBhY2tCeXRlcyhibG9jayk7XG4gIHZhciByb3VuZHMgPSBjdHgucm91bmRzO1xuICB2YXIgYjAgPSBiWzBdO1xuICB2YXIgYjEgPSBiWzFdO1xuICB2YXIgYjIgPSBiWzJdO1xuICB2YXIgYjMgPSBiWzNdO1xuXG4gIGZvciAociA9IDA7IHIgPCByb3VuZHMgLSAxOyByKyspIHtcbiAgICB0MCA9IGIwIF4gY3R4LnJrW3JdWzBdO1xuICAgIHQxID0gYjEgXiBjdHgucmtbcl1bMV07XG4gICAgdDIgPSBiMiBeIGN0eC5ya1tyXVsyXTtcbiAgICB0MyA9IGIzIF4gY3R4LnJrW3JdWzNdO1xuXG4gICAgYjAgPSBUMVt0MCAmIDI1NV0gXiBUMlsodDEgPj4gOCkgJiAyNTVdIF4gVDNbKHQyID4+IDE2KSAmIDI1NV0gXiBUNFt0MyA+Pj4gMjRdO1xuICAgIGIxID0gVDFbdDEgJiAyNTVdIF4gVDJbKHQyID4+IDgpICYgMjU1XSBeIFQzWyh0MyA+PiAxNikgJiAyNTVdIF4gVDRbdDAgPj4+IDI0XTtcbiAgICBiMiA9IFQxW3QyICYgMjU1XSBeIFQyWyh0MyA+PiA4KSAmIDI1NV0gXiBUM1sodDAgPj4gMTYpICYgMjU1XSBeIFQ0W3QxID4+PiAyNF07XG4gICAgYjMgPSBUMVt0MyAmIDI1NV0gXiBUMlsodDAgPj4gOCkgJiAyNTVdIF4gVDNbKHQxID4+IDE2KSAmIDI1NV0gXiBUNFt0MiA+Pj4gMjRdO1xuICB9XG5cbiAgLy8gbGFzdCByb3VuZCBpcyBzcGVjaWFsXG4gIHIgPSByb3VuZHMgLSAxO1xuXG4gIHQwID0gYjAgXiBjdHgucmtbcl1bMF07XG4gIHQxID0gYjEgXiBjdHgucmtbcl1bMV07XG4gIHQyID0gYjIgXiBjdHgucmtbcl1bMl07XG4gIHQzID0gYjMgXiBjdHgucmtbcl1bM107XG5cbiAgYlswXSA9IEYxKHQwLCB0MSwgdDIsIHQzKSBeIGN0eC5ya1tyb3VuZHNdWzBdO1xuICBiWzFdID0gRjEodDEsIHQyLCB0MywgdDApIF4gY3R4LnJrW3JvdW5kc11bMV07XG4gIGJbMl0gPSBGMSh0MiwgdDMsIHQwLCB0MSkgXiBjdHgucmtbcm91bmRzXVsyXTtcbiAgYlszXSA9IEYxKHQzLCB0MCwgdDEsIHQyKSBeIGN0eC5ya1tyb3VuZHNdWzNdO1xuXG4gIHJldHVybiB1bnBhY2tCeXRlcyhiKTtcbn1cblxuZnVuY3Rpb24gbWFrZUNsYXNzKGxlbmd0aCkge1xuXG4gIHZhciBjID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgdGhpcy5rZXkgPSBrZXlFeHBhbnNpb24oa2V5KTtcblxuICAgIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG4gICAgICByZXR1cm4gQUVTZW5jcnlwdChibG9jaywgdGhpcy5rZXkpO1xuICAgIH1cbiAgfVxuXG4gIGMuYmxvY2tTaXplID0gYy5wcm90b3R5cGUuYmxvY2tTaXplID0gMTY7XG4gIGMua2V5U2l6ZSA9IGMucHJvdG90eXBlLmtleVNpemUgPSBsZW5ndGggLyA4O1xuXG4gIHJldHVybiBjO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHt9XG5cbnZhciB0eXBlcyA9IFsxMjgsIDE5MiwgMjU2XTtcblxuZm9yICh2YXIgaSBpbiB0eXBlcykge1xuICBtb2R1bGUuZXhwb3J0c1t0eXBlc1tpXV0gPSBtYWtlQ2xhc3ModHlwZXNbaV0pO1xufVxuIiwiLyogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIIFxuICogXG4gKiBPcmlnaW5hbGx5IHdyaXR0ZW4gYnkgbmtsZWluIHNvZnR3YXJlIChua2xlaW4uY29tKVxuICovXG5cbi8qIFxuICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBiYXNlZCBvbiBCcnVjZSBTY2huZWllcidzIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbi5cbiAqXG4gKlxuICogVGhlIGNvbnN0cnVjdG9yIGRvZXNuJ3QgZG8gbXVjaCBvZiBhbnl0aGluZy4gIEl0J3MganVzdCBoZXJlXG4gKiBzbyB3ZSBjYW4gc3RhcnQgZGVmaW5pbmcgcHJvcGVydGllcyBhbmQgbWV0aG9kcyBhbmQgc3VjaC5cbiAqL1xuZnVuY3Rpb24gQmxvd2Zpc2goKSB7fTtcblxuLypcbiAqIERlY2xhcmUgdGhlIGJsb2NrIHNpemUgc28gdGhhdCBwcm90b2NvbHMga25vdyB3aGF0IHNpemVcbiAqIEluaXRpYWxpemF0aW9uIFZlY3RvciAoSVYpIHRoZXkgd2lsbCBuZWVkLlxuICovXG5CbG93ZmlzaC5wcm90b3R5cGUuQkxPQ0tTSVpFID0gODtcblxuLypcbiAqIFRoZXNlIGFyZSB0aGUgZGVmYXVsdCBTQk9YRVMuXG4gKi9cbkJsb3dmaXNoLnByb3RvdHlwZS5TQk9YRVMgPSBbXG4gIFtcbiAgICAgIDB4ZDEzMTBiYTYsIDB4OThkZmI1YWMsIDB4MmZmZDcyZGIsIDB4ZDAxYWRmYjcsIDB4YjhlMWFmZWQsIDB4NmEyNjdlOTYsXG4gICAgICAweGJhN2M5MDQ1LCAweGYxMmM3Zjk5LCAweDI0YTE5OTQ3LCAweGIzOTE2Y2Y3LCAweDA4MDFmMmUyLCAweDg1OGVmYzE2LFxuICAgICAgMHg2MzY5MjBkOCwgMHg3MTU3NGU2OSwgMHhhNDU4ZmVhMywgMHhmNDkzM2Q3ZSwgMHgwZDk1NzQ4ZiwgMHg3MjhlYjY1OCxcbiAgICAgIDB4NzE4YmNkNTgsIDB4ODIxNTRhZWUsIDB4N2I1NGE0MWQsIDB4YzI1YTU5YjUsIDB4OWMzMGQ1MzksIDB4MmFmMjYwMTMsXG4gICAgICAweGM1ZDFiMDIzLCAweDI4NjA4NWYwLCAweGNhNDE3OTE4LCAweGI4ZGIzOGVmLCAweDhlNzlkY2IwLCAweDYwM2ExODBlLFxuICAgICAgMHg2YzllMGU4YiwgMHhiMDFlOGEzZSwgMHhkNzE1NzdjMSwgMHhiZDMxNGIyNywgMHg3OGFmMmZkYSwgMHg1NTYwNWM2MCxcbiAgICAgIDB4ZTY1NTI1ZjMsIDB4YWE1NWFiOTQsIDB4NTc0ODk4NjIsIDB4NjNlODE0NDAsIDB4NTVjYTM5NmEsIDB4MmFhYjEwYjYsXG4gICAgICAweGI0Y2M1YzM0LCAweDExNDFlOGNlLCAweGExNTQ4NmFmLCAweDdjNzJlOTkzLCAweGIzZWUxNDExLCAweDYzNmZiYzJhLFxuICAgICAgMHgyYmE5YzU1ZCwgMHg3NDE4MzFmNiwgMHhjZTVjM2UxNiwgMHg5Yjg3OTMxZSwgMHhhZmQ2YmEzMywgMHg2YzI0Y2Y1YyxcbiAgICAgIDB4N2EzMjUzODEsIDB4Mjg5NTg2NzcsIDB4M2I4ZjQ4OTgsIDB4NmI0YmI5YWYsIDB4YzRiZmU4MWIsIDB4NjYyODIxOTMsXG4gICAgICAweDYxZDgwOWNjLCAweGZiMjFhOTkxLCAweDQ4N2NhYzYwLCAweDVkZWM4MDMyLCAweGVmODQ1ZDVkLCAweGU5ODU3NWIxLFxuICAgICAgMHhkYzI2MjMwMiwgMHhlYjY1MWI4OCwgMHgyMzg5M2U4MSwgMHhkMzk2YWNjNSwgMHgwZjZkNmZmMywgMHg4M2Y0NDIzOSxcbiAgICAgIDB4MmUwYjQ0ODIsIDB4YTQ4NDIwMDQsIDB4NjljOGYwNGEsIDB4OWUxZjliNWUsIDB4MjFjNjY4NDIsIDB4ZjZlOTZjOWEsXG4gICAgICAweDY3MGM5YzYxLCAweGFiZDM4OGYwLCAweDZhNTFhMGQyLCAweGQ4NTQyZjY4LCAweDk2MGZhNzI4LCAweGFiNTEzM2EzLFxuICAgICAgMHg2ZWVmMGI2YywgMHgxMzdhM2JlNCwgMHhiYTNiZjA1MCwgMHg3ZWZiMmE5OCwgMHhhMWYxNjUxZCwgMHgzOWFmMDE3NixcbiAgICAgIDB4NjZjYTU5M2UsIDB4ODI0MzBlODgsIDB4OGNlZTg2MTksIDB4NDU2ZjlmYjQsIDB4N2Q4NGE1YzMsIDB4M2I4YjVlYmUsXG4gICAgICAweGUwNmY3NWQ4LCAweDg1YzEyMDczLCAweDQwMWE0NDlmLCAweDU2YzE2YWE2LCAweDRlZDNhYTYyLCAweDM2M2Y3NzA2LFxuICAgICAgMHgxYmZlZGY3MiwgMHg0MjliMDIzZCwgMHgzN2QwZDcyNCwgMHhkMDBhMTI0OCwgMHhkYjBmZWFkMywgMHg0OWYxYzA5YixcbiAgICAgIDB4MDc1MzcyYzksIDB4ODA5OTFiN2IsIDB4MjVkNDc5ZDgsIDB4ZjZlOGRlZjcsIDB4ZTNmZTUwMWEsIDB4YjY3OTRjM2IsXG4gICAgICAweDk3NmNlMGJkLCAweDA0YzAwNmJhLCAweGMxYTk0ZmI2LCAweDQwOWY2MGM0LCAweDVlNWM5ZWMyLCAweDE5NmEyNDYzLFxuICAgICAgMHg2OGZiNmZhZiwgMHgzZTZjNTNiNSwgMHgxMzM5YjJlYiwgMHgzYjUyZWM2ZiwgMHg2ZGZjNTExZiwgMHg5YjMwOTUyYyxcbiAgICAgIDB4Y2M4MTQ1NDQsIDB4YWY1ZWJkMDksIDB4YmVlM2QwMDQsIDB4ZGUzMzRhZmQsIDB4NjYwZjI4MDcsIDB4MTkyZTRiYjMsXG4gICAgICAweGMwY2JhODU3LCAweDQ1Yzg3NDBmLCAweGQyMGI1ZjM5LCAweGI5ZDNmYmRiLCAweDU1NzljMGJkLCAweDFhNjAzMjBhLFxuICAgICAgMHhkNmExMDBjNiwgMHg0MDJjNzI3OSwgMHg2NzlmMjVmZSwgMHhmYjFmYTNjYywgMHg4ZWE1ZTlmOCwgMHhkYjMyMjJmOCxcbiAgICAgIDB4M2M3NTE2ZGYsIDB4ZmQ2MTZiMTUsIDB4MmY1MDFlYzgsIDB4YWQwNTUyYWIsIDB4MzIzZGI1ZmEsIDB4ZmQyMzg3NjAsXG4gICAgICAweDUzMzE3YjQ4LCAweDNlMDBkZjgyLCAweDllNWM1N2JiLCAweGNhNmY4Y2EwLCAweDFhODc1NjJlLCAweGRmMTc2OWRiLFxuICAgICAgMHhkNTQyYThmNiwgMHgyODdlZmZjMywgMHhhYzY3MzJjNiwgMHg4YzRmNTU3MywgMHg2OTViMjdiMCwgMHhiYmNhNThjOCxcbiAgICAgIDB4ZTFmZmEzNWQsIDB4YjhmMDExYTAsIDB4MTBmYTNkOTgsIDB4ZmQyMTgzYjgsIDB4NGFmY2I1NmMsIDB4MmRkMWQzNWIsXG4gICAgICAweDlhNTNlNDc5LCAweGI2Zjg0NTY1LCAweGQyOGU0OWJjLCAweDRiZmI5NzkwLCAweGUxZGRmMmRhLCAweGE0Y2I3ZTMzLFxuICAgICAgMHg2MmZiMTM0MSwgMHhjZWU0YzZlOCwgMHhlZjIwY2FkYSwgMHgzNjc3NGMwMSwgMHhkMDdlOWVmZSwgMHgyYmYxMWZiNCxcbiAgICAgIDB4OTVkYmRhNGQsIDB4YWU5MDkxOTgsIDB4ZWFhZDhlNzEsIDB4NmI5M2Q1YTAsIDB4ZDA4ZWQxZDAsIDB4YWZjNzI1ZTAsXG4gICAgICAweDhlM2M1YjJmLCAweDhlNzU5NGI3LCAweDhmZjZlMmZiLCAweGYyMTIyYjY0LCAweDg4ODhiODEyLCAweDkwMGRmMDFjLFxuICAgICAgMHg0ZmFkNWVhMCwgMHg2ODhmYzMxYywgMHhkMWNmZjE5MSwgMHhiM2E4YzFhZCwgMHgyZjJmMjIxOCwgMHhiZTBlMTc3NyxcbiAgICAgIDB4ZWE3NTJkZmUsIDB4OGIwMjFmYTEsIDB4ZTVhMGNjMGYsIDB4YjU2Zjc0ZTgsIDB4MThhY2YzZDYsIDB4Y2U4OWUyOTksXG4gICAgICAweGI0YTg0ZmUwLCAweGZkMTNlMGI3LCAweDdjYzQzYjgxLCAweGQyYWRhOGQ5LCAweDE2NWZhMjY2LCAweDgwOTU3NzA1LFxuICAgICAgMHg5M2NjNzMxNCwgMHgyMTFhMTQ3NywgMHhlNmFkMjA2NSwgMHg3N2I1ZmE4NiwgMHhjNzU0NDJmNSwgMHhmYjlkMzVjZixcbiAgICAgIDB4ZWJjZGFmMGMsIDB4N2IzZTg5YTAsIDB4ZDY0MTFiZDMsIDB4YWUxZTdlNDksIDB4MDAyNTBlMmQsIDB4MjA3MWIzNWUsXG4gICAgICAweDIyNjgwMGJiLCAweDU3YjhlMGFmLCAweDI0NjQzNjliLCAweGYwMDliOTFlLCAweDU1NjM5MTFkLCAweDU5ZGZhNmFhLFxuICAgICAgMHg3OGMxNDM4OSwgMHhkOTVhNTM3ZiwgMHgyMDdkNWJhMiwgMHgwMmU1YjljNSwgMHg4MzI2MDM3NiwgMHg2Mjk1Y2ZhOSxcbiAgICAgIDB4MTFjODE5NjgsIDB4NGU3MzRhNDEsIDB4YjM0NzJkY2EsIDB4N2IxNGE5NGEsIDB4MWI1MTAwNTIsIDB4OWE1MzI5MTUsXG4gICAgICAweGQ2MGY1NzNmLCAweGJjOWJjNmU0LCAweDJiNjBhNDc2LCAweDgxZTY3NDAwLCAweDA4YmE2ZmI1LCAweDU3MWJlOTFmLFxuICAgICAgMHhmMjk2ZWM2YiwgMHgyYTBkZDkxNSwgMHhiNjYzNjUyMSwgMHhlN2I5ZjliNiwgMHhmZjM0MDUyZSwgMHhjNTg1NTY2NCxcbiAgICAgIDB4NTNiMDJkNWQsIDB4YTk5ZjhmYTEsIDB4MDhiYTQ3OTksIDB4NmU4NTA3NmFcbiAgXSxcbiAgW1xuICAgICAgMHg0YjdhNzBlOSwgMHhiNWIzMjk0NCwgMHhkYjc1MDkyZSwgMHhjNDE5MjYyMywgMHhhZDZlYTZiMCwgMHg0OWE3ZGY3ZCxcbiAgICAgIDB4OWNlZTYwYjgsIDB4OGZlZGIyNjYsIDB4ZWNhYThjNzEsIDB4Njk5YTE3ZmYsIDB4NTY2NDUyNmMsIDB4YzJiMTllZTEsXG4gICAgICAweDE5MzYwMmE1LCAweDc1MDk0YzI5LCAweGEwNTkxMzQwLCAweGU0MTgzYTNlLCAweDNmNTQ5ODlhLCAweDViNDI5ZDY1LFxuICAgICAgMHg2YjhmZTRkNiwgMHg5OWY3M2ZkNiwgMHhhMWQyOWMwNywgMHhlZmU4MzBmNSwgMHg0ZDJkMzhlNiwgMHhmMDI1NWRjMSxcbiAgICAgIDB4NGNkZDIwODYsIDB4ODQ3MGViMjYsIDB4NjM4MmU5YzYsIDB4MDIxZWNjNWUsIDB4MDk2ODZiM2YsIDB4M2ViYWVmYzksXG4gICAgICAweDNjOTcxODE0LCAweDZiNmE3MGExLCAweDY4N2YzNTg0LCAweDUyYTBlMjg2LCAweGI3OWM1MzA1LCAweGFhNTAwNzM3LFxuICAgICAgMHgzZTA3ODQxYywgMHg3ZmRlYWU1YywgMHg4ZTdkNDRlYywgMHg1NzE2ZjJiOCwgMHhiMDNhZGEzNywgMHhmMDUwMGMwZCxcbiAgICAgIDB4ZjAxYzFmMDQsIDB4MDIwMGIzZmYsIDB4YWUwY2Y1MWEsIDB4M2NiNTc0YjIsIDB4MjU4MzdhNTgsIDB4ZGMwOTIxYmQsXG4gICAgICAweGQxOTExM2Y5LCAweDdjYTkyZmY2LCAweDk0MzI0NzczLCAweDIyZjU0NzAxLCAweDNhZTVlNTgxLCAweDM3YzJkYWRjLFxuICAgICAgMHhjOGI1NzYzNCwgMHg5YWYzZGRhNywgMHhhOTQ0NjE0NiwgMHgwZmQwMDMwZSwgMHhlY2M4YzczZSwgMHhhNDc1MWU0MSxcbiAgICAgIDB4ZTIzOGNkOTksIDB4M2JlYTBlMmYsIDB4MzI4MGJiYTEsIDB4MTgzZWIzMzEsIDB4NGU1NDhiMzgsIDB4NGY2ZGI5MDgsXG4gICAgICAweDZmNDIwZDAzLCAweGY2MGEwNGJmLCAweDJjYjgxMjkwLCAweDI0OTc3Yzc5LCAweDU2NzliMDcyLCAweGJjYWY4OWFmLFxuICAgICAgMHhkZTlhNzcxZiwgMHhkOTkzMDgxMCwgMHhiMzhiYWUxMiwgMHhkY2NmM2YyZSwgMHg1NTEyNzIxZiwgMHgyZTZiNzEyNCxcbiAgICAgIDB4NTAxYWRkZTYsIDB4OWY4NGNkODcsIDB4N2E1ODQ3MTgsIDB4NzQwOGRhMTcsIDB4YmM5ZjlhYmMsIDB4ZTk0YjdkOGMsXG4gICAgICAweGVjN2FlYzNhLCAweGRiODUxZGZhLCAweDYzMDk0MzY2LCAweGM0NjRjM2QyLCAweGVmMWMxODQ3LCAweDMyMTVkOTA4LFxuICAgICAgMHhkZDQzM2IzNywgMHgyNGMyYmExNiwgMHgxMmExNGQ0MywgMHgyYTY1YzQ1MSwgMHg1MDk0MDAwMiwgMHgxMzNhZTRkZCxcbiAgICAgIDB4NzFkZmY4OWUsIDB4MTAzMTRlNTUsIDB4ODFhYzc3ZDYsIDB4NWYxMTE5OWIsIDB4MDQzNTU2ZjEsIDB4ZDdhM2M3NmIsXG4gICAgICAweDNjMTExODNiLCAweDU5MjRhNTA5LCAweGYyOGZlNmVkLCAweDk3ZjFmYmZhLCAweDllYmFiZjJjLCAweDFlMTUzYzZlLFxuICAgICAgMHg4NmUzNDU3MCwgMHhlYWU5NmZiMSwgMHg4NjBlNWUwYSwgMHg1YTNlMmFiMywgMHg3NzFmZTcxYywgMHg0ZTNkMDZmYSxcbiAgICAgIDB4Mjk2NWRjYjksIDB4OTllNzFkMGYsIDB4ODAzZTg5ZDYsIDB4NTI2NmM4MjUsIDB4MmU0Y2M5NzgsIDB4OWMxMGIzNmEsXG4gICAgICAweGM2MTUwZWJhLCAweDk0ZTJlYTc4LCAweGE1ZmMzYzUzLCAweDFlMGEyZGY0LCAweGYyZjc0ZWE3LCAweDM2MWQyYjNkLFxuICAgICAgMHgxOTM5MjYwZiwgMHgxOWMyNzk2MCwgMHg1MjIzYTcwOCwgMHhmNzEzMTJiNiwgMHhlYmFkZmU2ZSwgMHhlYWMzMWY2NixcbiAgICAgIDB4ZTNiYzQ1OTUsIDB4YTY3YmM4ODMsIDB4YjE3ZjM3ZDEsIDB4MDE4Y2ZmMjgsIDB4YzMzMmRkZWYsIDB4YmU2YzVhYTUsXG4gICAgICAweDY1NTgyMTg1LCAweDY4YWI5ODAyLCAweGVlY2VhNTBmLCAweGRiMmY5NTNiLCAweDJhZWY3ZGFkLCAweDViNmUyZjg0LFxuICAgICAgMHgxNTIxYjYyOCwgMHgyOTA3NjE3MCwgMHhlY2RkNDc3NSwgMHg2MTlmMTUxMCwgMHgxM2NjYTgzMCwgMHhlYjYxYmQ5NixcbiAgICAgIDB4MDMzNGZlMWUsIDB4YWEwMzYzY2YsIDB4YjU3MzVjOTAsIDB4NGM3MGEyMzksIDB4ZDU5ZTllMGIsIDB4Y2JhYWRlMTQsXG4gICAgICAweGVlY2M4NmJjLCAweDYwNjIyY2E3LCAweDljYWI1Y2FiLCAweGIyZjM4NDZlLCAweDY0OGIxZWFmLCAweDE5YmRmMGNhLFxuICAgICAgMHhhMDIzNjliOSwgMHg2NTVhYmI1MCwgMHg0MDY4NWEzMiwgMHgzYzJhYjRiMywgMHgzMTllZTlkNSwgMHhjMDIxYjhmNyxcbiAgICAgIDB4OWI1NDBiMTksIDB4ODc1ZmEwOTksIDB4OTVmNzk5N2UsIDB4NjIzZDdkYTgsIDB4ZjgzNzg4OWEsIDB4OTdlMzJkNzcsXG4gICAgICAweDExZWQ5MzVmLCAweDE2NjgxMjgxLCAweDBlMzU4ODI5LCAweGM3ZTYxZmQ2LCAweDk2ZGVkZmExLCAweDc4NThiYTk5LFxuICAgICAgMHg1N2Y1ODRhNSwgMHgxYjIyNzI2MywgMHg5YjgzYzNmZiwgMHgxYWMyNDY5NiwgMHhjZGIzMGFlYiwgMHg1MzJlMzA1NCxcbiAgICAgIDB4OGZkOTQ4ZTQsIDB4NmRiYzMxMjgsIDB4NThlYmYyZWYsIDB4MzRjNmZmZWEsIDB4ZmUyOGVkNjEsIDB4ZWU3YzNjNzMsXG4gICAgICAweDVkNGExNGQ5LCAweGU4NjRiN2UzLCAweDQyMTA1ZDE0LCAweDIwM2UxM2UwLCAweDQ1ZWVlMmI2LCAweGEzYWFhYmVhLFxuICAgICAgMHhkYjZjNGYxNSwgMHhmYWNiNGZkMCwgMHhjNzQyZjQ0MiwgMHhlZjZhYmJiNSwgMHg2NTRmM2IxZCwgMHg0MWNkMjEwNSxcbiAgICAgIDB4ZDgxZTc5OWUsIDB4ODY4NTRkYzcsIDB4ZTQ0YjQ3NmEsIDB4M2Q4MTYyNTAsIDB4Y2Y2MmExZjIsIDB4NWI4ZDI2NDYsXG4gICAgICAweGZjODg4M2EwLCAweGMxYzdiNmEzLCAweDdmMTUyNGMzLCAweDY5Y2I3NDkyLCAweDQ3ODQ4YTBiLCAweDU2OTJiMjg1LFxuICAgICAgMHgwOTViYmYwMCwgMHhhZDE5NDg5ZCwgMHgxNDYyYjE3NCwgMHgyMzgyMGUwMCwgMHg1ODQyOGQyYSwgMHgwYzU1ZjVlYSxcbiAgICAgIDB4MWRhZGY0M2UsIDB4MjMzZjcwNjEsIDB4MzM3MmYwOTIsIDB4OGQ5MzdlNDEsIDB4ZDY1ZmVjZjEsIDB4NmMyMjNiZGIsXG4gICAgICAweDdjZGUzNzU5LCAweGNiZWU3NDYwLCAweDQwODVmMmE3LCAweGNlNzczMjZlLCAweGE2MDc4MDg0LCAweDE5Zjg1MDllLFxuICAgICAgMHhlOGVmZDg1NSwgMHg2MWQ5OTczNSwgMHhhOTY5YTdhYSwgMHhjNTBjMDZjMiwgMHg1YTA0YWJmYywgMHg4MDBiY2FkYyxcbiAgICAgIDB4OWU0NDdhMmUsIDB4YzM0NTM0ODQsIDB4ZmRkNTY3MDUsIDB4MGUxZTllYzksIDB4ZGI3M2RiZDMsIDB4MTA1NTg4Y2QsXG4gICAgICAweDY3NWZkYTc5LCAweGUzNjc0MzQwLCAweGM1YzQzNDY1LCAweDcxM2UzOGQ4LCAweDNkMjhmODllLCAweGYxNmRmZjIwLFxuICAgICAgMHgxNTNlMjFlNywgMHg4ZmIwM2Q0YSwgMHhlNmUzOWYyYiwgMHhkYjgzYWRmN1xuICBdLFxuICBbXG4gICAgICAweGU5M2Q1YTY4LCAweDk0ODE0MGY3LCAweGY2NGMyNjFjLCAweDk0NjkyOTM0LCAweDQxMTUyMGY3LCAweDc2MDJkNGY3LFxuICAgICAgMHhiY2Y0NmIyZSwgMHhkNGEyMDA2OCwgMHhkNDA4MjQ3MSwgMHgzMzIwZjQ2YSwgMHg0M2I3ZDRiNywgMHg1MDAwNjFhZixcbiAgICAgIDB4MWUzOWY2MmUsIDB4OTcyNDQ1NDYsIDB4MTQyMTRmNzQsIDB4YmY4Yjg4NDAsIDB4NGQ5NWZjMWQsIDB4OTZiNTkxYWYsXG4gICAgICAweDcwZjRkZGQzLCAweDY2YTAyZjQ1LCAweGJmYmMwOWVjLCAweDAzYmQ5Nzg1LCAweDdmYWM2ZGQwLCAweDMxY2I4NTA0LFxuICAgICAgMHg5NmViMjdiMywgMHg1NWZkMzk0MSwgMHhkYTI1NDdlNiwgMHhhYmNhMGE5YSwgMHgyODUwNzgyNSwgMHg1MzA0MjlmNCxcbiAgICAgIDB4MGEyYzg2ZGEsIDB4ZTliNjZkZmIsIDB4NjhkYzE0NjIsIDB4ZDc0ODY5MDAsIDB4NjgwZWMwYTQsIDB4MjdhMThkZWUsXG4gICAgICAweDRmM2ZmZWEyLCAweGU4ODdhZDhjLCAweGI1OGNlMDA2LCAweDdhZjRkNmI2LCAweGFhY2UxZTdjLCAweGQzMzc1ZmVjLFxuICAgICAgMHhjZTc4YTM5OSwgMHg0MDZiMmE0MiwgMHgyMGZlOWUzNSwgMHhkOWYzODViOSwgMHhlZTM5ZDdhYiwgMHgzYjEyNGU4YixcbiAgICAgIDB4MWRjOWZhZjcsIDB4NGI2ZDE4NTYsIDB4MjZhMzY2MzEsIDB4ZWFlMzk3YjIsIDB4M2E2ZWZhNzQsIDB4ZGQ1YjQzMzIsXG4gICAgICAweDY4NDFlN2Y3LCAweGNhNzgyMGZiLCAweGZiMGFmNTRlLCAweGQ4ZmViMzk3LCAweDQ1NDA1NmFjLCAweGJhNDg5NTI3LFxuICAgICAgMHg1NTUzM2EzYSwgMHgyMDgzOGQ4NywgMHhmZTZiYTliNywgMHhkMDk2OTU0YiwgMHg1NWE4NjdiYywgMHhhMTE1OWE1OCxcbiAgICAgIDB4Y2NhOTI5NjMsIDB4OTllMWRiMzMsIDB4YTYyYTRhNTYsIDB4M2YzMTI1ZjksIDB4NWVmNDdlMWMsIDB4OTAyOTMxN2MsXG4gICAgICAweGZkZjhlODAyLCAweDA0MjcyZjcwLCAweDgwYmIxNTVjLCAweDA1MjgyY2UzLCAweDk1YzExNTQ4LCAweGU0YzY2ZDIyLFxuICAgICAgMHg0OGMxMTMzZiwgMHhjNzBmODZkYywgMHgwN2Y5YzllZSwgMHg0MTA0MWYwZiwgMHg0MDQ3NzlhNCwgMHg1ZDg4NmUxNyxcbiAgICAgIDB4MzI1ZjUxZWIsIDB4ZDU5YmMwZDEsIDB4ZjJiY2MxOGYsIDB4NDExMTM1NjQsIDB4MjU3Yjc4MzQsIDB4NjAyYTljNjAsXG4gICAgICAweGRmZjhlOGEzLCAweDFmNjM2YzFiLCAweDBlMTJiNGMyLCAweDAyZTEzMjllLCAweGFmNjY0ZmQxLCAweGNhZDE4MTE1LFxuICAgICAgMHg2YjIzOTVlMCwgMHgzMzNlOTJlMSwgMHgzYjI0MGI2MiwgMHhlZWJlYjkyMiwgMHg4NWIyYTIwZSwgMHhlNmJhMGQ5OSxcbiAgICAgIDB4ZGU3MjBjOGMsIDB4MmRhMmY3MjgsIDB4ZDAxMjc4NDUsIDB4OTViNzk0ZmQsIDB4NjQ3ZDA4NjIsIDB4ZTdjY2Y1ZjAsXG4gICAgICAweDU0NDlhMzZmLCAweDg3N2Q0OGZhLCAweGMzOWRmZDI3LCAweGYzM2U4ZDFlLCAweDBhNDc2MzQxLCAweDk5MmVmZjc0LFxuICAgICAgMHgzYTZmNmVhYiwgMHhmNGY4ZmQzNywgMHhhODEyZGM2MCwgMHhhMWViZGRmOCwgMHg5OTFiZTE0YywgMHhkYjZlNmIwZCxcbiAgICAgIDB4YzY3YjU1MTAsIDB4NmQ2NzJjMzcsIDB4Mjc2NWQ0M2IsIDB4ZGNkMGU4MDQsIDB4ZjEyOTBkYzcsIDB4Y2MwMGZmYTMsXG4gICAgICAweGI1MzkwZjkyLCAweDY5MGZlZDBiLCAweDY2N2I5ZmZiLCAweGNlZGI3ZDljLCAweGEwOTFjZjBiLCAweGQ5MTU1ZWEzLFxuICAgICAgMHhiYjEzMmY4OCwgMHg1MTViYWQyNCwgMHg3Yjk0NzliZiwgMHg3NjNiZDZlYiwgMHgzNzM5MmViMywgMHhjYzExNTk3OSxcbiAgICAgIDB4ODAyNmUyOTcsIDB4ZjQyZTMxMmQsIDB4Njg0MmFkYTcsIDB4YzY2YTJiM2IsIDB4MTI3NTRjY2MsIDB4NzgyZWYxMWMsXG4gICAgICAweDZhMTI0MjM3LCAweGI3OTI1MWU3LCAweDA2YTFiYmU2LCAweDRiZmI2MzUwLCAweDFhNmIxMDE4LCAweDExY2FlZGZhLFxuICAgICAgMHgzZDI1YmRkOCwgMHhlMmUxYzNjOSwgMHg0NDQyMTY1OSwgMHgwYTEyMTM4NiwgMHhkOTBjZWM2ZSwgMHhkNWFiZWEyYSxcbiAgICAgIDB4NjRhZjY3NGUsIDB4ZGE4NmE4NWYsIDB4YmViZmU5ODgsIDB4NjRlNGMzZmUsIDB4OWRiYzgwNTcsIDB4ZjBmN2MwODYsXG4gICAgICAweDYwNzg3YmY4LCAweDYwMDM2MDRkLCAweGQxZmQ4MzQ2LCAweGY2MzgxZmIwLCAweDc3NDVhZTA0LCAweGQ3MzZmY2NjLFxuICAgICAgMHg4MzQyNmIzMywgMHhmMDFlYWI3MSwgMHhiMDgwNDE4NywgMHgzYzAwNWU1ZiwgMHg3N2EwNTdiZSwgMHhiZGU4YWUyNCxcbiAgICAgIDB4NTU0NjQyOTksIDB4YmY1ODJlNjEsIDB4NGU1OGY0OGYsIDB4ZjJkZGZkYTIsIDB4ZjQ3NGVmMzgsIDB4ODc4OWJkYzIsXG4gICAgICAweDUzNjZmOWMzLCAweGM4YjM4ZTc0LCAweGI0NzVmMjU1LCAweDQ2ZmNkOWI5LCAweDdhZWIyNjYxLCAweDhiMWRkZjg0LFxuICAgICAgMHg4NDZhMGU3OSwgMHg5MTVmOTVlMiwgMHg0NjZlNTk4ZSwgMHgyMGI0NTc3MCwgMHg4Y2Q1NTU5MSwgMHhjOTAyZGU0YyxcbiAgICAgIDB4YjkwYmFjZTEsIDB4YmI4MjA1ZDAsIDB4MTFhODYyNDgsIDB4NzU3NGE5OWUsIDB4Yjc3ZjE5YjYsIDB4ZTBhOWRjMDksXG4gICAgICAweDY2MmQwOWExLCAweGM0MzI0NjMzLCAweGU4NWExZjAyLCAweDA5ZjBiZThjLCAweDRhOTlhMDI1LCAweDFkNmVmZTEwLFxuICAgICAgMHgxYWI5M2QxZCwgMHgwYmE1YTRkZiwgMHhhMTg2ZjIwZiwgMHgyODY4ZjE2OSwgMHhkY2I3ZGE4MywgMHg1NzM5MDZmZSxcbiAgICAgIDB4YTFlMmNlOWIsIDB4NGZjZDdmNTIsIDB4NTAxMTVlMDEsIDB4YTcwNjgzZmEsIDB4YTAwMmI1YzQsIDB4MGRlNmQwMjcsXG4gICAgICAweDlhZjg4YzI3LCAweDc3M2Y4NjQxLCAweGMzNjA0YzA2LCAweDYxYTgwNmI1LCAweGYwMTc3YTI4LCAweGMwZjU4NmUwLFxuICAgICAgMHgwMDYwNThhYSwgMHgzMGRjN2Q2MiwgMHgxMWU2OWVkNywgMHgyMzM4ZWE2MywgMHg1M2MyZGQ5NCwgMHhjMmMyMTYzNCxcbiAgICAgIDB4YmJjYmVlNTYsIDB4OTBiY2I2ZGUsIDB4ZWJmYzdkYTEsIDB4Y2U1OTFkNzYsIDB4NmYwNWU0MDksIDB4NGI3YzAxODgsXG4gICAgICAweDM5NzIwYTNkLCAweDdjOTI3YzI0LCAweDg2ZTM3MjVmLCAweDcyNGQ5ZGI5LCAweDFhYzE1YmI0LCAweGQzOWViOGZjLFxuICAgICAgMHhlZDU0NTU3OCwgMHgwOGZjYTViNSwgMHhkODNkN2NkMywgMHg0ZGFkMGZjNCwgMHgxZTUwZWY1ZSwgMHhiMTYxZTZmOCxcbiAgICAgIDB4YTI4NTE0ZDksIDB4NmM1MTEzM2MsIDB4NmZkNWM3ZTcsIDB4NTZlMTRlYzQsIDB4MzYyYWJmY2UsIDB4ZGRjNmM4MzcsXG4gICAgICAweGQ3OWEzMjM0LCAweDkyNjM4MjEyLCAweDY3MGVmYThlLCAweDQwNjAwMGUwXG4gIF0sXG4gIFtcbiAgICAgIDB4M2EzOWNlMzcsIDB4ZDNmYWY1Y2YsIDB4YWJjMjc3MzcsIDB4NWFjNTJkMWIsIDB4NWNiMDY3OWUsIDB4NGZhMzM3NDIsXG4gICAgICAweGQzODIyNzQwLCAweDk5YmM5YmJlLCAweGQ1MTE4ZTlkLCAweGJmMGY3MzE1LCAweGQ2MmQxYzdlLCAweGM3MDBjNDdiLFxuICAgICAgMHhiNzhjMWI2YiwgMHgyMWExOTA0NSwgMHhiMjZlYjFiZSwgMHg2YTM2NmViNCwgMHg1NzQ4YWIyZiwgMHhiYzk0NmU3OSxcbiAgICAgIDB4YzZhMzc2ZDIsIDB4NjU0OWMyYzgsIDB4NTMwZmY4ZWUsIDB4NDY4ZGRlN2QsIDB4ZDU3MzBhMWQsIDB4NGNkMDRkYzYsXG4gICAgICAweDI5MzliYmRiLCAweGE5YmE0NjUwLCAweGFjOTUyNmU4LCAweGJlNWVlMzA0LCAweGExZmFkNWYwLCAweDZhMmQ1MTlhLFxuICAgICAgMHg2M2VmOGNlMiwgMHg5YTg2ZWUyMiwgMHhjMDg5YzJiOCwgMHg0MzI0MmVmNiwgMHhhNTFlMDNhYSwgMHg5Y2YyZDBhNCxcbiAgICAgIDB4ODNjMDYxYmEsIDB4OWJlOTZhNGQsIDB4OGZlNTE1NTAsIDB4YmE2NDViZDYsIDB4MjgyNmEyZjksIDB4YTczYTNhZTEsXG4gICAgICAweDRiYTk5NTg2LCAweGVmNTU2MmU5LCAweGM3MmZlZmQzLCAweGY3NTJmN2RhLCAweDNmMDQ2ZjY5LCAweDc3ZmEwYTU5LFxuICAgICAgMHg4MGU0YTkxNSwgMHg4N2IwODYwMSwgMHg5YjA5ZTZhZCwgMHgzYjNlZTU5MywgMHhlOTkwZmQ1YSwgMHg5ZTM0ZDc5NyxcbiAgICAgIDB4MmNmMGI3ZDksIDB4MDIyYjhiNTEsIDB4OTZkNWFjM2EsIDB4MDE3ZGE2N2QsIDB4ZDFjZjNlZDYsIDB4N2M3ZDJkMjgsXG4gICAgICAweDFmOWYyNWNmLCAweGFkZjJiODliLCAweDVhZDZiNDcyLCAweDVhODhmNTRjLCAweGUwMjlhYzcxLCAweGUwMTlhNWU2LFxuICAgICAgMHg0N2IwYWNmZCwgMHhlZDkzZmE5YiwgMHhlOGQzYzQ4ZCwgMHgyODNiNTdjYywgMHhmOGQ1NjYyOSwgMHg3OTEzMmUyOCxcbiAgICAgIDB4Nzg1ZjAxOTEsIDB4ZWQ3NTYwNTUsIDB4Zjc5NjBlNDQsIDB4ZTNkMzVlOGMsIDB4MTUwNTZkZDQsIDB4ODhmNDZkYmEsXG4gICAgICAweDAzYTE2MTI1LCAweDA1NjRmMGJkLCAweGMzZWI5ZTE1LCAweDNjOTA1N2EyLCAweDk3MjcxYWVjLCAweGE5M2EwNzJhLFxuICAgICAgMHgxYjNmNmQ5YiwgMHgxZTYzMjFmNSwgMHhmNTljNjZmYiwgMHgyNmRjZjMxOSwgMHg3NTMzZDkyOCwgMHhiMTU1ZmRmNSxcbiAgICAgIDB4MDM1NjM0ODIsIDB4OGFiYTNjYmIsIDB4Mjg1MTc3MTEsIDB4YzIwYWQ5ZjgsIDB4YWJjYzUxNjcsIDB4Y2NhZDkyNWYsXG4gICAgICAweDRkZTgxNzUxLCAweDM4MzBkYzhlLCAweDM3OWQ1ODYyLCAweDkzMjBmOTkxLCAweGVhN2E5MGMyLCAweGZiM2U3YmNlLFxuICAgICAgMHg1MTIxY2U2NCwgMHg3NzRmYmUzMiwgMHhhOGI2ZTM3ZSwgMHhjMzI5M2Q0NiwgMHg0OGRlNTM2OSwgMHg2NDEzZTY4MCxcbiAgICAgIDB4YTJhZTA4MTAsIDB4ZGQ2ZGIyMjQsIDB4Njk4NTJkZmQsIDB4MDkwNzIxNjYsIDB4YjM5YTQ2MGEsIDB4NjQ0NWMwZGQsXG4gICAgICAweDU4NmNkZWNmLCAweDFjMjBjOGFlLCAweDViYmVmN2RkLCAweDFiNTg4ZDQwLCAweGNjZDIwMTdmLCAweDZiYjRlM2JiLFxuICAgICAgMHhkZGEyNmE3ZSwgMHgzYTU5ZmY0NSwgMHgzZTM1MGE0NCwgMHhiY2I0Y2RkNSwgMHg3MmVhY2VhOCwgMHhmYTY0ODRiYixcbiAgICAgIDB4OGQ2NjEyYWUsIDB4YmYzYzZmNDcsIDB4ZDI5YmU0NjMsIDB4NTQyZjVkOWUsIDB4YWVjMjc3MWIsIDB4ZjY0ZTYzNzAsXG4gICAgICAweDc0MGUwZDhkLCAweGU3NWIxMzU3LCAweGY4NzIxNjcxLCAweGFmNTM3ZDVkLCAweDQwNDBjYjA4LCAweDRlYjRlMmNjLFxuICAgICAgMHgzNGQyNDY2YSwgMHgwMTE1YWY4NCwgMHhlMWIwMDQyOCwgMHg5NTk4M2ExZCwgMHgwNmI4OWZiNCwgMHhjZTZlYTA0OCxcbiAgICAgIDB4NmYzZjNiODIsIDB4MzUyMGFiODIsIDB4MDExYTFkNGIsIDB4Mjc3MjI3ZjgsIDB4NjExNTYwYjEsIDB4ZTc5MzNmZGMsXG4gICAgICAweGJiM2E3OTJiLCAweDM0NDUyNWJkLCAweGEwODgzOWUxLCAweDUxY2U3OTRiLCAweDJmMzJjOWI3LCAweGEwMWZiYWM5LFxuICAgICAgMHhlMDFjYzg3ZSwgMHhiY2M3ZDFmNiwgMHhjZjAxMTFjMywgMHhhMWU4YWFjNywgMHgxYTkwODc0OSwgMHhkNDRmYmQ5YSxcbiAgICAgIDB4ZDBkYWRlY2IsIDB4ZDUwYWRhMzgsIDB4MDMzOWMzMmEsIDB4YzY5MTM2NjcsIDB4OGRmOTMxN2MsIDB4ZTBiMTJiNGYsXG4gICAgICAweGY3OWU1OWI3LCAweDQzZjViYjNhLCAweGYyZDUxOWZmLCAweDI3ZDk0NTljLCAweGJmOTcyMjJjLCAweDE1ZTZmYzJhLFxuICAgICAgMHgwZjkxZmM3MSwgMHg5Yjk0MTUyNSwgMHhmYWU1OTM2MSwgMHhjZWI2OWNlYiwgMHhjMmE4NjQ1OSwgMHgxMmJhYThkMSxcbiAgICAgIDB4YjZjMTA3NWUsIDB4ZTMwNTZhMGMsIDB4MTBkMjUwNjUsIDB4Y2IwM2E0NDIsIDB4ZTBlYzZlMGUsIDB4MTY5OGRiM2IsXG4gICAgICAweDRjOThhMGJlLCAweDMyNzhlOTY0LCAweDlmMWY5NTMyLCAweGUwZDM5MmRmLCAweGQzYTAzNDJiLCAweDg5NzFmMjFlLFxuICAgICAgMHgxYjBhNzQ0MSwgMHg0YmEzMzQ4YywgMHhjNWJlNzEyMCwgMHhjMzc2MzJkOCwgMHhkZjM1OWY4ZCwgMHg5Yjk5MmYyZSxcbiAgICAgIDB4ZTYwYjZmNDcsIDB4MGZlM2YxMWQsIDB4ZTU0Y2RhNTQsIDB4MWVkYWQ4OTEsIDB4Y2U2Mjc5Y2YsIDB4Y2QzZTdlNmYsXG4gICAgICAweDE2MThiMTY2LCAweGZkMmMxZDA1LCAweDg0OGZkMmM1LCAweGY2ZmIyMjk5LCAweGY1MjNmMzU3LCAweGE2MzI3NjIzLFxuICAgICAgMHg5M2E4MzUzMSwgMHg1NmNjY2QwMiwgMHhhY2YwODE2MiwgMHg1YTc1ZWJiNSwgMHg2ZTE2MzY5NywgMHg4OGQyNzNjYyxcbiAgICAgIDB4ZGU5NjYyOTIsIDB4ODFiOTQ5ZDAsIDB4NGM1MDkwMWIsIDB4NzFjNjU2MTQsIDB4ZTZjNmM3YmQsIDB4MzI3YTE0MGEsXG4gICAgICAweDQ1ZTFkMDA2LCAweGMzZjI3YjlhLCAweGM5YWE1M2ZkLCAweDYyYTgwZjAwLCAweGJiMjViZmUyLCAweDM1YmRkMmY2LFxuICAgICAgMHg3MTEyNjkwNSwgMHhiMjA0MDIyMiwgMHhiNmNiY2Y3YywgMHhjZDc2OWMyYiwgMHg1MzExM2VjMCwgMHgxNjQwZTNkMyxcbiAgICAgIDB4MzhhYmJkNjAsIDB4MjU0N2FkZjAsIDB4YmEzODIwOWMsIDB4Zjc0NmNlNzYsIDB4NzdhZmExYzUsIDB4MjA3NTYwNjAsXG4gICAgICAweDg1Y2JmZTRlLCAweDhhZTg4ZGQ4LCAweDdhYWFmOWIwLCAweDRjZjlhYTdlLCAweDE5NDhjMjVjLCAweDAyZmI4YThjLFxuICAgICAgMHgwMWMzNmFlNCwgMHhkNmViZTFmOSwgMHg5MGQ0Zjg2OSwgMHhhNjVjZGVhMCwgMHgzZjA5MjUyZCwgMHhjMjA4ZTY5ZixcbiAgICAgIDB4Yjc0ZTYxMzIsIDB4Y2U3N2UyNWIsIDB4NTc4ZmRmZTMsIDB4M2FjMzcyZTZcbiAgXVxuXTtcblxuLy8qXG4vLyogVGhpcyBpcyB0aGUgZGVmYXVsdCBQQVJSQVlcbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLlBBUlJBWSA9IFtcbiAgICAweDI0M2Y2YTg4LCAweDg1YTMwOGQzLCAweDEzMTk4YTJlLCAweDAzNzA3MzQ0LCAweGE0MDkzODIyLCAweDI5OWYzMWQwLFxuICAgIDB4MDgyZWZhOTgsIDB4ZWM0ZTZjODksIDB4NDUyODIxZTYsIDB4MzhkMDEzNzcsIDB4YmU1NDY2Y2YsIDB4MzRlOTBjNmMsXG4gICAgMHhjMGFjMjliNywgMHhjOTdjNTBkZCwgMHgzZjg0ZDViNSwgMHhiNTQ3MDkxNywgMHg5MjE2ZDVkOSwgMHg4OTc5ZmIxYlxuXTtcblxuLy8qXG4vLyogVGhpcyBpcyB0aGUgbnVtYmVyIG9mIHJvdW5kcyB0aGUgY2lwaGVyIHdpbGwgZ29cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLk5OID0gMTY7XG5cbi8vKlxuLy8qIFRoaXMgZnVuY3Rpb24gaXMgbmVlZGVkIHRvIGdldCByaWQgb2YgcHJvYmxlbXNcbi8vKiB3aXRoIHRoZSBoaWdoLWJpdCBnZXR0aW5nIHNldC4gIElmIHdlIGRvbid0IGRvXG4vLyogdGhpcywgdGhlbiBzb21ldGltZXMgKCBhYSAmIDB4MDBGRkZGRkZGRiApIGlzIG5vdFxuLy8qIGVxdWFsIHRvICggYmIgJiAweDAwRkZGRkZGRkYgKSBldmVuIHdoZW4gdGhleVxuLy8qIGFncmVlIGJpdC1mb3ItYml0IGZvciB0aGUgZmlyc3QgMzIgYml0cy5cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLl9jbGVhbiA9IGZ1bmN0aW9uKHh4KSB7XG4gIGlmICh4eCA8IDApIHtcbiAgICB2YXIgeXkgPSB4eCAmIDB4N0ZGRkZGRkY7XG4gICAgeHggPSB5eSArIDB4ODAwMDAwMDA7XG4gIH1cbiAgcmV0dXJuIHh4O1xufTtcblxuLy8qXG4vLyogVGhpcyBpcyB0aGUgbWl4aW5nIGZ1bmN0aW9uIHRoYXQgdXNlcyB0aGUgc2JveGVzXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5fRiA9IGZ1bmN0aW9uKHh4KSB7XG4gIHZhciBhYTtcbiAgdmFyIGJiO1xuICB2YXIgY2M7XG4gIHZhciBkZDtcbiAgdmFyIHl5O1xuXG4gIGRkID0geHggJiAweDAwRkY7XG4gIHh4ID4+Pj0gODtcbiAgY2MgPSB4eCAmIDB4MDBGRjtcbiAgeHggPj4+PSA4O1xuICBiYiA9IHh4ICYgMHgwMEZGO1xuICB4eCA+Pj49IDg7XG4gIGFhID0geHggJiAweDAwRkY7XG5cbiAgeXkgPSB0aGlzLnNib3hlc1swXVthYV0gKyB0aGlzLnNib3hlc1sxXVtiYl07XG4gIHl5ID0geXkgXiB0aGlzLnNib3hlc1syXVtjY107XG4gIHl5ID0geXkgKyB0aGlzLnNib3hlc1szXVtkZF07XG5cbiAgcmV0dXJuIHl5O1xufTtcblxuLy8qXG4vLyogVGhpcyBtZXRob2QgdGFrZXMgYW4gYXJyYXkgd2l0aCB0d28gdmFsdWVzLCBsZWZ0IGFuZCByaWdodFxuLy8qIGFuZCBkb2VzIE5OIHJvdW5kcyBvZiBCbG93ZmlzaCBvbiB0aGVtLlxuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuX2VuY3J5cHRfYmxvY2sgPSBmdW5jdGlvbih2YWxzKSB7XG4gIHZhciBkYXRhTCA9IHZhbHNbMF07XG4gIHZhciBkYXRhUiA9IHZhbHNbMV07XG5cbiAgdmFyIGlpO1xuXG4gIGZvciAoaWkgPSAwOyBpaSA8IHRoaXMuTk47ICsraWkpIHtcbiAgICBkYXRhTCA9IGRhdGFMIF4gdGhpcy5wYXJyYXlbaWldO1xuICAgIGRhdGFSID0gdGhpcy5fRihkYXRhTCkgXiBkYXRhUjtcblxuICAgIHZhciB0bXAgPSBkYXRhTDtcbiAgICBkYXRhTCA9IGRhdGFSO1xuICAgIGRhdGFSID0gdG1wO1xuICB9XG5cbiAgZGF0YUwgPSBkYXRhTCBeIHRoaXMucGFycmF5W3RoaXMuTk4gKyAwXTtcbiAgZGF0YVIgPSBkYXRhUiBeIHRoaXMucGFycmF5W3RoaXMuTk4gKyAxXTtcblxuICB2YWxzWzBdID0gdGhpcy5fY2xlYW4oZGF0YVIpO1xuICB2YWxzWzFdID0gdGhpcy5fY2xlYW4oZGF0YUwpO1xufTtcblxuLy8qXG4vLyogVGhpcyBtZXRob2QgdGFrZXMgYSB2ZWN0b3Igb2YgbnVtYmVycyBhbmQgdHVybnMgdGhlbVxuLy8qIGludG8gbG9uZyB3b3JkcyBzbyB0aGF0IHRoZXkgY2FuIGJlIHByb2Nlc3NlZCBieSB0aGVcbi8vKiByZWFsIGFsZ29yaXRobS5cbi8vKlxuLy8qIE1heWJlIEkgc2hvdWxkIG1ha2UgdGhlIHJlYWwgYWxnb3JpdGhtIGFib3ZlIHRha2UgYSB2ZWN0b3Jcbi8vKiBpbnN0ZWFkLiAgVGhhdCB3aWxsIGludm9sdmUgbW9yZSBsb29waW5nLCBidXQgaXQgd29uJ3QgcmVxdWlyZVxuLy8qIHRoZSBGKCkgbWV0aG9kIHRvIGRlY29uc3RydWN0IHRoZSB2ZWN0b3IuXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5lbmNyeXB0X2Jsb2NrID0gZnVuY3Rpb24odmVjdG9yKSB7XG4gIHZhciBpaTtcbiAgdmFyIHZhbHMgPSBbMCwgMF07XG4gIHZhciBvZmYgPSB0aGlzLkJMT0NLU0laRSAvIDI7XG4gIGZvciAoaWkgPSAwOyBpaSA8IHRoaXMuQkxPQ0tTSVpFIC8gMjsgKytpaSkge1xuICAgIHZhbHNbMF0gPSAodmFsc1swXSA8PCA4KSB8ICh2ZWN0b3JbaWkgKyAwXSAmIDB4MDBGRik7XG4gICAgdmFsc1sxXSA9ICh2YWxzWzFdIDw8IDgpIHwgKHZlY3RvcltpaSArIG9mZl0gJiAweDAwRkYpO1xuICB9XG5cbiAgdGhpcy5fZW5jcnlwdF9ibG9jayh2YWxzKTtcblxuICB2YXIgcmV0ID0gW107XG4gIGZvciAoaWkgPSAwOyBpaSA8IHRoaXMuQkxPQ0tTSVpFIC8gMjsgKytpaSkge1xuICAgIHJldFtpaSArIDBdID0gKHZhbHNbMF0gPj4+ICgyNCAtIDggKiAoaWkpKSAmIDB4MDBGRik7XG4gICAgcmV0W2lpICsgb2ZmXSA9ICh2YWxzWzFdID4+PiAoMjQgLSA4ICogKGlpKSkgJiAweDAwRkYpO1xuICAgIC8vIHZhbHNbIDAgXSA9ICggdmFsc1sgMCBdID4+PiA4ICk7XG4gICAgLy8gdmFsc1sgMSBdID0gKCB2YWxzWyAxIF0gPj4+IDggKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59O1xuXG4vLypcbi8vKiBUaGlzIG1ldGhvZCB0YWtlcyBhbiBhcnJheSB3aXRoIHR3byB2YWx1ZXMsIGxlZnQgYW5kIHJpZ2h0XG4vLyogYW5kIHVuZG9lcyBOTiByb3VuZHMgb2YgQmxvd2Zpc2ggb24gdGhlbS5cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLl9kZWNyeXB0X2Jsb2NrID0gZnVuY3Rpb24odmFscykge1xuICB2YXIgZGF0YUwgPSB2YWxzWzBdO1xuICB2YXIgZGF0YVIgPSB2YWxzWzFdO1xuXG4gIHZhciBpaTtcblxuICBmb3IgKGlpID0gdGhpcy5OTiArIDE7IGlpID4gMTsgLS1paSkge1xuICAgIGRhdGFMID0gZGF0YUwgXiB0aGlzLnBhcnJheVtpaV07XG4gICAgZGF0YVIgPSB0aGlzLl9GKGRhdGFMKSBeIGRhdGFSO1xuXG4gICAgdmFyIHRtcCA9IGRhdGFMO1xuICAgIGRhdGFMID0gZGF0YVI7XG4gICAgZGF0YVIgPSB0bXA7XG4gIH1cblxuICBkYXRhTCA9IGRhdGFMIF4gdGhpcy5wYXJyYXlbMV07XG4gIGRhdGFSID0gZGF0YVIgXiB0aGlzLnBhcnJheVswXTtcblxuICB2YWxzWzBdID0gdGhpcy5fY2xlYW4oZGF0YVIpO1xuICB2YWxzWzFdID0gdGhpcy5fY2xlYW4oZGF0YUwpO1xufTtcblxuLy8qXG4vLyogVGhpcyBtZXRob2QgdGFrZXMgYSBrZXkgYXJyYXkgYW5kIGluaXRpYWxpemVzIHRoZVxuLy8qIHNib3hlcyBhbmQgcGFycmF5IGZvciB0aGlzIGVuY3J5cHRpb24uXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24oa2V5KSB7XG4gIHZhciBpaTtcbiAgdmFyIGpqID0gMDtcblxuICB0aGlzLnBhcnJheSA9IFtdO1xuICBmb3IgKGlpID0gMDsgaWkgPCB0aGlzLk5OICsgMjsgKytpaSkge1xuICAgIHZhciBkYXRhID0gMHgwMDAwMDAwMDtcbiAgICB2YXIga2s7XG4gICAgZm9yIChrayA9IDA7IGtrIDwgNDsgKytraykge1xuICAgICAgZGF0YSA9IChkYXRhIDw8IDgpIHwgKGtleVtqal0gJiAweDAwRkYpO1xuICAgICAgaWYgKCsramogPj0ga2V5Lmxlbmd0aCkge1xuICAgICAgICBqaiA9IDA7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucGFycmF5W2lpXSA9IHRoaXMuUEFSUkFZW2lpXSBeIGRhdGE7XG4gIH1cblxuICB0aGlzLnNib3hlcyA9IFtdO1xuICBmb3IgKGlpID0gMDsgaWkgPCA0OyArK2lpKSB7XG4gICAgdGhpcy5zYm94ZXNbaWldID0gW107XG4gICAgZm9yIChqaiA9IDA7IGpqIDwgMjU2OyArK2pqKSB7XG4gICAgICB0aGlzLnNib3hlc1tpaV1bampdID0gdGhpcy5TQk9YRVNbaWldW2pqXTtcbiAgICB9XG4gIH1cblxuICB2YXIgdmFscyA9IFsweDAwMDAwMDAwLCAweDAwMDAwMDAwXTtcblxuICBmb3IgKGlpID0gMDsgaWkgPCB0aGlzLk5OICsgMjsgaWkgKz0gMikge1xuICAgIHRoaXMuX2VuY3J5cHRfYmxvY2sodmFscyk7XG4gICAgdGhpcy5wYXJyYXlbaWkgKyAwXSA9IHZhbHNbMF07XG4gICAgdGhpcy5wYXJyYXlbaWkgKyAxXSA9IHZhbHNbMV07XG4gIH1cblxuICBmb3IgKGlpID0gMDsgaWkgPCA0OyArK2lpKSB7XG4gICAgZm9yIChqaiA9IDA7IGpqIDwgMjU2OyBqaiArPSAyKSB7XG4gICAgICB0aGlzLl9lbmNyeXB0X2Jsb2NrKHZhbHMpO1xuICAgICAgdGhpcy5zYm94ZXNbaWldW2pqICsgMF0gPSB2YWxzWzBdO1xuICAgICAgdGhpcy5zYm94ZXNbaWldW2pqICsgMV0gPSB2YWxzWzFdO1xuICAgIH1cbiAgfVxufTtcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbi8vIGFkZGVkIGJ5IFJlY3VyaXR5IExhYnNcblxuZnVuY3Rpb24gQkZlbmNyeXB0KGJsb2NrLCBrZXkpIHtcbiAgdmFyIGJmID0gbmV3IEJsb3dmaXNoKCk7XG4gIGJmLmluaXQodXRpbC5zdHIyYmluKGtleSkpO1xuICByZXR1cm4gYmYuZW5jcnlwdF9ibG9jayhibG9jayk7XG59XG5cbmZ1bmN0aW9uIEJGKGtleSkge1xuICB0aGlzLmJmID0gbmV3IEJsb3dmaXNoKCk7XG4gIHRoaXMuYmYuaW5pdCh1dGlsLnN0cjJiaW4oa2V5KSk7XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYmxvY2spIHtcbiAgICByZXR1cm4gdGhpcy5iZi5lbmNyeXB0X2Jsb2NrKGJsb2NrKTtcbiAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gQkY7XG5tb2R1bGUuZXhwb3J0cy5rZXlTaXplID0gQkYucHJvdG90eXBlLmtleVNpemUgPSAxNjtcbm1vZHVsZS5leHBvcnRzLmJsb2NrU2l6ZSA9IEJGLnByb3RvdHlwZS5ibG9ja1NpemUgPSAxNjtcbiIsIi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlXG4vLyBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuXG5cbi8vIENvcHlyaWdodCAyMDEwIHBqYWNvYnNAeGVla3IuY29tIC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxuLy8gTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIXG5cbi8vIGZpeGVkL21vZGlmaWVkIGJ5IEhlcmJlcnQgSGFuZXdpbmtlbCwgd3d3LmhhbmVXSU4uZGVcbi8vIGNoZWNrIHd3dy5oYW5lV0lOLmRlIGZvciB0aGUgbGF0ZXN0IHZlcnNpb25cblxuLy8gY2FzdDUuanMgaXMgYSBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIENBU1QtMTI4LCBhcyBkZWZpbmVkIGluIFJGQyAyMTQ0LlxuLy8gQ0FTVC0xMjggaXMgYSBjb21tb24gT3BlblBHUCBjaXBoZXIuXG5cblxuLy8gQ0FTVDUgY29uc3RydWN0b3JcblxuXG5cbmZ1bmN0aW9uIG9wZW5wZ3Bfc3ltZW5jX2Nhc3Q1KCkge1xuICB0aGlzLkJsb2NrU2l6ZSA9IDg7XG4gIHRoaXMuS2V5U2l6ZSA9IDE2O1xuXG4gIHRoaXMuc2V0S2V5ID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgdGhpcy5tYXNraW5nID0gbmV3IEFycmF5KDE2KTtcbiAgICB0aGlzLnJvdGF0ZSA9IG5ldyBBcnJheSgxNik7XG5cbiAgICB0aGlzLnJlc2V0KCk7XG5cbiAgICBpZiAoa2V5Lmxlbmd0aCA9PSB0aGlzLktleVNpemUpIHtcbiAgICAgIHRoaXMua2V5U2NoZWR1bGUoa2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXRpbC5wcmludF9lcnJvcignY2FzdDUuanM6IENBU1QtMTI4OiBrZXlzIG11c3QgYmUgMTYgYnl0ZXMnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgdGhpcy5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgdGhpcy5tYXNraW5nW2ldID0gMDtcbiAgICAgIHRoaXMucm90YXRlW2ldID0gMDtcbiAgICB9XG4gIH07XG5cbiAgdGhpcy5nZXRCbG9ja1NpemUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gQmxvY2tTaXplO1xuICB9O1xuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKHNyYykge1xuICAgIHZhciBkc3QgPSBuZXcgQXJyYXkoc3JjLmxlbmd0aCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNyYy5sZW5ndGg7IGkgKz0gOCkge1xuICAgICAgdmFyIGwgPSBzcmNbaV0gPDwgMjQgfCBzcmNbaSArIDFdIDw8IDE2IHwgc3JjW2kgKyAyXSA8PCA4IHwgc3JjW2kgKyAzXTtcbiAgICAgIHZhciByID0gc3JjW2kgKyA0XSA8PCAyNCB8IHNyY1tpICsgNV0gPDwgMTYgfCBzcmNbaSArIDZdIDw8IDggfCBzcmNbaSArIDddO1xuICAgICAgdmFyIHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbMF0sIHRoaXMucm90YXRlWzBdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1sxXSwgdGhpcy5yb3RhdGVbMV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzJdLCB0aGlzLnJvdGF0ZVsyXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbM10sIHRoaXMucm90YXRlWzNdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzRdLCB0aGlzLnJvdGF0ZVs0XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbNV0sIHRoaXMucm90YXRlWzVdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1s2XSwgdGhpcy5yb3RhdGVbNl0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzddLCB0aGlzLnJvdGF0ZVs3XSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1s4XSwgdGhpcy5yb3RhdGVbOF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzldLCB0aGlzLnJvdGF0ZVs5XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbMTBdLCB0aGlzLnJvdGF0ZVsxMF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzExXSwgdGhpcy5yb3RhdGVbMTFdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzEyXSwgdGhpcy5yb3RhdGVbMTJdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1sxM10sIHRoaXMucm90YXRlWzEzXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbMTRdLCB0aGlzLnJvdGF0ZVsxNF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzE1XSwgdGhpcy5yb3RhdGVbMTVdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICBkc3RbaV0gPSAociA+Pj4gMjQpICYgMjU1O1xuICAgICAgZHN0W2kgKyAxXSA9IChyID4+PiAxNikgJiAyNTU7XG4gICAgICBkc3RbaSArIDJdID0gKHIgPj4+IDgpICYgMjU1O1xuICAgICAgZHN0W2kgKyAzXSA9IHIgJiAyNTU7XG4gICAgICBkc3RbaSArIDRdID0gKGwgPj4+IDI0KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgNV0gPSAobCA+Pj4gMTYpICYgMjU1O1xuICAgICAgZHN0W2kgKyA2XSA9IChsID4+PiA4KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgN10gPSBsICYgMjU1O1xuICAgIH1cblxuICAgIHJldHVybiBkc3Q7XG4gIH07XG5cbiAgdGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24oc3JjKSB7XG4gICAgdmFyIGRzdCA9IG5ldyBBcnJheShzcmMubGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3JjLmxlbmd0aDsgaSArPSA4KSB7XG4gICAgICB2YXIgbCA9IHNyY1tpXSA8PCAyNCB8IHNyY1tpICsgMV0gPDwgMTYgfCBzcmNbaSArIDJdIDw8IDggfCBzcmNbaSArIDNdO1xuICAgICAgdmFyIHIgPSBzcmNbaSArIDRdIDw8IDI0IHwgc3JjW2kgKyA1XSA8PCAxNiB8IHNyY1tpICsgNl0gPDwgOCB8IHNyY1tpICsgN107XG4gICAgICB2YXIgdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1sxNV0sIHRoaXMucm90YXRlWzE1XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbMTRdLCB0aGlzLnJvdGF0ZVsxNF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzEzXSwgdGhpcy5yb3RhdGVbMTNdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1sxMl0sIHRoaXMucm90YXRlWzEyXSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1sxMV0sIHRoaXMucm90YXRlWzExXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbMTBdLCB0aGlzLnJvdGF0ZVsxMF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzldLCB0aGlzLnJvdGF0ZVs5XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbOF0sIHRoaXMucm90YXRlWzhdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzddLCB0aGlzLnJvdGF0ZVs3XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbNl0sIHRoaXMucm90YXRlWzZdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1s1XSwgdGhpcy5yb3RhdGVbNV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzRdLCB0aGlzLnJvdGF0ZVs0XSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1szXSwgdGhpcy5yb3RhdGVbM10pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzJdLCB0aGlzLnJvdGF0ZVsyXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbMV0sIHRoaXMucm90YXRlWzFdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1swXSwgdGhpcy5yb3RhdGVbMF0pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIGRzdFtpXSA9IChyID4+PiAyNCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDFdID0gKHIgPj4+IDE2KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgMl0gPSAociA+Pj4gOCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDNdID0gciAmIDI1NTtcbiAgICAgIGRzdFtpICsgNF0gPSAobCA+Pj4gMjQpICYgMjU1O1xuICAgICAgZHN0W2kgKyA1XSA9IChsID4+IDE2KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgNl0gPSAobCA+PiA4KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgN10gPSBsICYgMjU1O1xuICAgIH1cblxuICAgIHJldHVybiBkc3Q7XG4gIH07XG4gIHZhciBzY2hlZHVsZUEgPSBuZXcgQXJyYXkoNCk7XG5cbiAgc2NoZWR1bGVBWzBdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUFbMF1bMF0gPSBuZXcgQXJyYXkoNCwgMCwgMHhkLCAweGYsIDB4YywgMHhlLCAweDgpO1xuICBzY2hlZHVsZUFbMF1bMV0gPSBuZXcgQXJyYXkoNSwgMiwgMTYgKyAwLCAxNiArIDIsIDE2ICsgMSwgMTYgKyAzLCAweGEpO1xuICBzY2hlZHVsZUFbMF1bMl0gPSBuZXcgQXJyYXkoNiwgMywgMTYgKyA3LCAxNiArIDYsIDE2ICsgNSwgMTYgKyA0LCA5KTtcbiAgc2NoZWR1bGVBWzBdWzNdID0gbmV3IEFycmF5KDcsIDEsIDE2ICsgMHhhLCAxNiArIDksIDE2ICsgMHhiLCAxNiArIDgsIDB4Yik7XG5cbiAgc2NoZWR1bGVBWzFdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUFbMV1bMF0gPSBuZXcgQXJyYXkoMCwgNiwgMTYgKyA1LCAxNiArIDcsIDE2ICsgNCwgMTYgKyA2LCAxNiArIDApO1xuICBzY2hlZHVsZUFbMV1bMV0gPSBuZXcgQXJyYXkoMSwgNCwgMCwgMiwgMSwgMywgMTYgKyAyKTtcbiAgc2NoZWR1bGVBWzFdWzJdID0gbmV3IEFycmF5KDIsIDUsIDcsIDYsIDUsIDQsIDE2ICsgMSk7XG4gIHNjaGVkdWxlQVsxXVszXSA9IG5ldyBBcnJheSgzLCA3LCAweGEsIDksIDB4YiwgOCwgMTYgKyAzKTtcblxuICBzY2hlZHVsZUFbMl0gPSBuZXcgQXJyYXkoNCk7XG4gIHNjaGVkdWxlQVsyXVswXSA9IG5ldyBBcnJheSg0LCAwLCAweGQsIDB4ZiwgMHhjLCAweGUsIDgpO1xuICBzY2hlZHVsZUFbMl1bMV0gPSBuZXcgQXJyYXkoNSwgMiwgMTYgKyAwLCAxNiArIDIsIDE2ICsgMSwgMTYgKyAzLCAweGEpO1xuICBzY2hlZHVsZUFbMl1bMl0gPSBuZXcgQXJyYXkoNiwgMywgMTYgKyA3LCAxNiArIDYsIDE2ICsgNSwgMTYgKyA0LCA5KTtcbiAgc2NoZWR1bGVBWzJdWzNdID0gbmV3IEFycmF5KDcsIDEsIDE2ICsgMHhhLCAxNiArIDksIDE2ICsgMHhiLCAxNiArIDgsIDB4Yik7XG5cblxuICBzY2hlZHVsZUFbM10gPSBuZXcgQXJyYXkoNCk7XG4gIHNjaGVkdWxlQVszXVswXSA9IG5ldyBBcnJheSgwLCA2LCAxNiArIDUsIDE2ICsgNywgMTYgKyA0LCAxNiArIDYsIDE2ICsgMCk7XG4gIHNjaGVkdWxlQVszXVsxXSA9IG5ldyBBcnJheSgxLCA0LCAwLCAyLCAxLCAzLCAxNiArIDIpO1xuICBzY2hlZHVsZUFbM11bMl0gPSBuZXcgQXJyYXkoMiwgNSwgNywgNiwgNSwgNCwgMTYgKyAxKTtcbiAgc2NoZWR1bGVBWzNdWzNdID0gbmV3IEFycmF5KDMsIDcsIDB4YSwgOSwgMHhiLCA4LCAxNiArIDMpO1xuXG4gIHZhciBzY2hlZHVsZUIgPSBuZXcgQXJyYXkoNCk7XG5cbiAgc2NoZWR1bGVCWzBdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUJbMF1bMF0gPSBuZXcgQXJyYXkoMTYgKyA4LCAxNiArIDksIDE2ICsgNywgMTYgKyA2LCAxNiArIDIpO1xuICBzY2hlZHVsZUJbMF1bMV0gPSBuZXcgQXJyYXkoMTYgKyAweGEsIDE2ICsgMHhiLCAxNiArIDUsIDE2ICsgNCwgMTYgKyA2KTtcbiAgc2NoZWR1bGVCWzBdWzJdID0gbmV3IEFycmF5KDE2ICsgMHhjLCAxNiArIDB4ZCwgMTYgKyAzLCAxNiArIDIsIDE2ICsgOSk7XG4gIHNjaGVkdWxlQlswXVszXSA9IG5ldyBBcnJheSgxNiArIDB4ZSwgMTYgKyAweGYsIDE2ICsgMSwgMTYgKyAwLCAxNiArIDB4Yyk7XG5cbiAgc2NoZWR1bGVCWzFdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUJbMV1bMF0gPSBuZXcgQXJyYXkoMywgMiwgMHhjLCAweGQsIDgpO1xuICBzY2hlZHVsZUJbMV1bMV0gPSBuZXcgQXJyYXkoMSwgMCwgMHhlLCAweGYsIDB4ZCk7XG4gIHNjaGVkdWxlQlsxXVsyXSA9IG5ldyBBcnJheSg3LCA2LCA4LCA5LCAzKTtcbiAgc2NoZWR1bGVCWzFdWzNdID0gbmV3IEFycmF5KDUsIDQsIDB4YSwgMHhiLCA3KTtcblxuXG4gIHNjaGVkdWxlQlsyXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVCWzJdWzBdID0gbmV3IEFycmF5KDE2ICsgMywgMTYgKyAyLCAxNiArIDB4YywgMTYgKyAweGQsIDE2ICsgOSk7XG4gIHNjaGVkdWxlQlsyXVsxXSA9IG5ldyBBcnJheSgxNiArIDEsIDE2ICsgMCwgMTYgKyAweGUsIDE2ICsgMHhmLCAxNiArIDB4Yyk7XG4gIHNjaGVkdWxlQlsyXVsyXSA9IG5ldyBBcnJheSgxNiArIDcsIDE2ICsgNiwgMTYgKyA4LCAxNiArIDksIDE2ICsgMik7XG4gIHNjaGVkdWxlQlsyXVszXSA9IG5ldyBBcnJheSgxNiArIDUsIDE2ICsgNCwgMTYgKyAweGEsIDE2ICsgMHhiLCAxNiArIDYpO1xuXG5cbiAgc2NoZWR1bGVCWzNdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUJbM11bMF0gPSBuZXcgQXJyYXkoOCwgOSwgNywgNiwgMyk7XG4gIHNjaGVkdWxlQlszXVsxXSA9IG5ldyBBcnJheSgweGEsIDB4YiwgNSwgNCwgNyk7XG4gIHNjaGVkdWxlQlszXVsyXSA9IG5ldyBBcnJheSgweGMsIDB4ZCwgMywgMiwgOCk7XG4gIHNjaGVkdWxlQlszXVszXSA9IG5ldyBBcnJheSgweGUsIDB4ZiwgMSwgMCwgMHhkKTtcblxuICAvLyBjaGFuZ2VkICdpbicgdG8gJ2lubicgKGluIGphdmFzY3JpcHQgJ2luJyBpcyBhIHJlc2VydmVkIHdvcmQpXG4gIHRoaXMua2V5U2NoZWR1bGUgPSBmdW5jdGlvbihpbm4pIHtcbiAgICB2YXIgdCA9IG5ldyBBcnJheSg4KTtcbiAgICB2YXIgayA9IG5ldyBBcnJheSgzMik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgdmFyIGogPSBpICogNDtcbiAgICAgIHRbaV0gPSBpbm5bal0gPDwgMjQgfCBpbm5baiArIDFdIDw8IDE2IHwgaW5uW2ogKyAyXSA8PCA4IHwgaW5uW2ogKyAzXTtcbiAgICB9XG5cbiAgICB2YXIgeCA9IFs2LCA3LCA0LCA1XTtcbiAgICB2YXIga2kgPSAwO1xuXG4gICAgZm9yICh2YXIgaGFsZiA9IDA7IGhhbGYgPCAyOyBoYWxmKyspIHtcbiAgICAgIGZvciAodmFyIHJvdW5kID0gMDsgcm91bmQgPCA0OyByb3VuZCsrKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgNDsgaisrKSB7XG4gICAgICAgICAgdmFyIGEgPSBzY2hlZHVsZUFbcm91bmRdW2pdO1xuICAgICAgICAgIHZhciB3ID0gdFthWzFdXTtcblxuICAgICAgICAgIHcgXj0gc0JveFs0XVsodFthWzJdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChhWzJdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHcgXj0gc0JveFs1XVsodFthWzNdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChhWzNdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHcgXj0gc0JveFs2XVsodFthWzRdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChhWzRdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHcgXj0gc0JveFs3XVsodFthWzVdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChhWzVdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHcgXj0gc0JveFt4W2pdXVsodFthWzZdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChhWzZdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHRbYVswXV0gPSB3O1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCA0OyBqKyspIHtcbiAgICAgICAgICB2YXIgYiA9IHNjaGVkdWxlQltyb3VuZF1bal07XG4gICAgICAgICAgdmFyIHcgPSBzQm94WzRdWyh0W2JbMF0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGJbMF0gJiAzKSkpICYgMHhmZl07XG5cbiAgICAgICAgICB3IF49IHNCb3hbNV1bKHRbYlsxXSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYlsxXSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbNl1bKHRbYlsyXSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYlsyXSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbN11bKHRbYlszXSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYlszXSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbNCArIGpdWyh0W2JbNF0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGJbNF0gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAga1traV0gPSB3O1xuICAgICAgICAgIGtpKys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICAgIHRoaXMubWFza2luZ1tpXSA9IGtbaV07XG4gICAgICB0aGlzLnJvdGF0ZVtpXSA9IGtbMTYgKyBpXSAmIDB4MWY7XG4gICAgfVxuICB9O1xuXG4gIC8vIFRoZXNlIGFyZSB0aGUgdGhyZWUgJ2YnIGZ1bmN0aW9ucy4gU2VlIFJGQyAyMTQ0LCBzZWN0aW9uIDIuMi5cblxuICBmdW5jdGlvbiBmMShkLCBtLCByKSB7XG4gICAgdmFyIHQgPSBtICsgZDtcbiAgICB2YXIgSSA9ICh0IDw8IHIpIHwgKHQgPj4+ICgzMiAtIHIpKTtcbiAgICByZXR1cm4gKChzQm94WzBdW0kgPj4+IDI0XSBeIHNCb3hbMV1bKEkgPj4+IDE2KSAmIDI1NV0pIC0gc0JveFsyXVsoSSA+Pj4gOCkgJiAyNTVdKSArIHNCb3hbM11bSSAmIDI1NV07XG4gIH1cblxuICBmdW5jdGlvbiBmMihkLCBtLCByKSB7XG4gICAgdmFyIHQgPSBtIF4gZDtcbiAgICB2YXIgSSA9ICh0IDw8IHIpIHwgKHQgPj4+ICgzMiAtIHIpKTtcbiAgICByZXR1cm4gKChzQm94WzBdW0kgPj4+IDI0XSAtIHNCb3hbMV1bKEkgPj4+IDE2KSAmIDI1NV0pICsgc0JveFsyXVsoSSA+Pj4gOCkgJiAyNTVdKSBeIHNCb3hbM11bSSAmIDI1NV07XG4gIH1cblxuICBmdW5jdGlvbiBmMyhkLCBtLCByKSB7XG4gICAgdmFyIHQgPSBtIC0gZDtcbiAgICB2YXIgSSA9ICh0IDw8IHIpIHwgKHQgPj4+ICgzMiAtIHIpKTtcbiAgICByZXR1cm4gKChzQm94WzBdW0kgPj4+IDI0XSArIHNCb3hbMV1bKEkgPj4+IDE2KSAmIDI1NV0pIF4gc0JveFsyXVsoSSA+Pj4gOCkgJiAyNTVdKSAtIHNCb3hbM11bSSAmIDI1NV07XG4gIH1cblxuICB2YXIgc0JveCA9IG5ldyBBcnJheSg4KTtcbiAgc0JveFswXSA9IG5ldyBBcnJheShcbiAgICAweDMwZmI0MGQ0LCAweDlmYTBmZjBiLCAweDZiZWNjZDJmLCAweDNmMjU4YzdhLCAweDFlMjEzZjJmLCAweDljMDA0ZGQzLCAweDYwMDNlNTQwLCAweGNmOWZjOTQ5LFxuICAgIDB4YmZkNGFmMjcsIDB4ODhiYmJkYjUsIDB4ZTIwMzQwOTAsIDB4OThkMDk2NzUsIDB4NmU2M2EwZTAsIDB4MTVjMzYxZDIsIDB4YzJlNzY2MWQsIDB4MjJkNGZmOGUsXG4gICAgMHgyODY4M2I2ZiwgMHhjMDdmZDA1OSwgMHhmZjIzNzljOCwgMHg3NzVmNTBlMiwgMHg0M2MzNDBkMywgMHhkZjJmODY1NiwgMHg4ODdjYTQxYSwgMHhhMmQyYmQyZCxcbiAgICAweGExYzllMGQ2LCAweDM0NmM0ODE5LCAweDYxYjc2ZDg3LCAweDIyNTQwZjJmLCAweDJhYmUzMmUxLCAweGFhNTQxNjZiLCAweDIyNTY4ZTNhLCAweGEyZDM0MWQwLFxuICAgIDB4NjZkYjQwYzgsIDB4YTc4NDM5MmYsIDB4MDA0ZGZmMmYsIDB4MmRiOWQyZGUsIDB4OTc5NDNmYWMsIDB4NGE5N2MxZDgsIDB4NTI3NjQ0YjcsIDB4YjVmNDM3YTcsXG4gICAgMHhiODJjYmFlZiwgMHhkNzUxZDE1OSwgMHg2ZmY3ZjBlZCwgMHg1YTA5N2ExZiwgMHg4MjdiNjhkMCwgMHg5MGVjZjUyZSwgMHgyMmIwYzA1NCwgMHhiYzhlNTkzNSxcbiAgICAweDRiNmQyZjdmLCAweDUwYmI2NGEyLCAweGQyNjY0OTEwLCAweGJlZTU4MTJkLCAweGI3MzMyMjkwLCAweGU5M2IxNTlmLCAweGI0OGVlNDExLCAweDRiZmYzNDVkLFxuICAgIDB4ZmQ0NWMyNDAsIDB4YWQzMTk3M2YsIDB4YzRmNmQwMmUsIDB4NTVmYzgxNjUsIDB4ZDViMWNhYWQsIDB4YTFhYzJkYWUsIDB4YTJkNGI3NmQsIDB4YzE5YjBjNTAsXG4gICAgMHg4ODIyNDBmMiwgMHgwYzZlNGYzOCwgMHhhNGU0YmZkNywgMHg0ZjViYTI3MiwgMHg1NjRjMWQyZiwgMHhjNTljNTMxOSwgMHhiOTQ5ZTM1NCwgMHhiMDQ2NjlmZSxcbiAgICAweGIxYjZhYjhhLCAweGM3MTM1OGRkLCAweDYzODVjNTQ1LCAweDExMGY5MzVkLCAweDU3NTM4YWQ1LCAweDZhMzkwNDkzLCAweGU2M2QzN2UwLCAweDJhNTRmNmIzLFxuICAgIDB4M2E3ODdkNWYsIDB4NjI3NmEwYjUsIDB4MTlhNmZjZGYsIDB4N2E0MjIwNmEsIDB4MjlmOWQ0ZDUsIDB4ZjYxYjE4OTEsIDB4YmI3MjI3NWUsIDB4YWE1MDgxNjcsXG4gICAgMHgzODkwMTA5MSwgMHhjNmI1MDVlYiwgMHg4NGM3Y2I4YywgMHgyYWQ3NWEwZiwgMHg4NzRhMTQyNywgMHhhMmQxOTM2YiwgMHgyYWQyODZhZiwgMHhhYTU2ZDI5MSxcbiAgICAweGQ3ODk0MzYwLCAweDQyNWM3NTBkLCAweDkzYjM5ZTI2LCAweDE4NzE4NGM5LCAweDZjMDBiMzJkLCAweDczZTJiYjE0LCAweGEwYmViYzNjLCAweDU0NjIzNzc5LFxuICAgIDB4NjQ0NTllYWIsIDB4M2YzMjhiODIsIDB4NzcxOGNmODIsIDB4NTlhMmNlYTYsIDB4MDRlZTAwMmUsIDB4ODlmZTc4ZTYsIDB4M2ZhYjA5NTAsIDB4MzI1ZmY2YzIsXG4gICAgMHg4MTM4M2YwNSwgMHg2OTYzYzVjOCwgMHg3NmNiNWFkNiwgMHhkNDk5NzRjOSwgMHhjYTE4MGRjZiwgMHgzODA3ODJkNSwgMHhjN2ZhNWNmNiwgMHg4YWMzMTUxMSxcbiAgICAweDM1ZTc5ZTEzLCAweDQ3ZGE5MWQwLCAweGY0MGY5MDg2LCAweGE3ZTI0MTllLCAweDMxMzY2MjQxLCAweDA1MWVmNDk1LCAweGFhNTczYjA0LCAweDRhODA1ZDhkLFxuICAgIDB4NTQ4MzAwZDAsIDB4MDAzMjJhM2MsIDB4YmY2NGNkZGYsIDB4YmE1N2E2OGUsIDB4NzVjNjM3MmIsIDB4NTBhZmQzNDEsIDB4YTdjMTMyNzUsIDB4OTE1YTBiZjUsXG4gICAgMHg2YjU0YmZhYiwgMHgyYjBiMTQyNiwgMHhhYjRjYzlkNywgMHg0NDljY2Q4MiwgMHhmN2ZiZjI2NSwgMHhhYjg1YzVmMywgMHgxYjU1ZGI5NCwgMHhhYWQ0ZTMyNCxcbiAgICAweGNmYTRiZDNmLCAweDJkZWFhM2UyLCAweDllMjA0ZDAyLCAweGM4YmQyNWFjLCAweGVhZGY1NWIzLCAweGQ1YmQ5ZTk4LCAweGUzMTIzMWIyLCAweDJhZDVhZDZjLFxuICAgIDB4OTU0MzI5ZGUsIDB4YWRiZTQ1MjgsIDB4ZDg3MTBmNjksIDB4YWE1MWM5MGYsIDB4YWE3ODZiZjYsIDB4MjI1MTNmMWUsIDB4YWE1MWE3OWIsIDB4MmFkMzQ0Y2MsXG4gICAgMHg3YjVhNDFmMCwgMHhkMzdjZmJhZCwgMHgxYjA2OTUwNSwgMHg0MWVjZTQ5MSwgMHhiNGMzMzJlNiwgMHgwMzIyNjhkNCwgMHhjOTYwMGFjYywgMHhjZTM4N2U2ZCxcbiAgICAweGJmNmJiMTZjLCAweDZhNzBmYjc4LCAweDBkMDNkOWM5LCAweGQ0ZGYzOWRlLCAweGUwMTA2M2RhLCAweDQ3MzZmNDY0LCAweDVhZDMyOGQ4LCAweGIzNDdjYzk2LFxuICAgIDB4NzViYjBmYzMsIDB4OTg1MTFiZmIsIDB4NGZmYmNjMzUsIDB4YjU4YmNmNmEsIDB4ZTExZjBhYmMsIDB4YmZjNWZlNGEsIDB4YTcwYWVjMTAsIDB4YWMzOTU3MGEsXG4gICAgMHgzZjA0NDQyZiwgMHg2MTg4YjE1MywgMHhlMDM5N2EyZSwgMHg1NzI3Y2I3OSwgMHg5Y2ViNDE4ZiwgMHgxY2FjZDY4ZCwgMHgyYWQzN2M5NiwgMHgwMTc1Y2I5ZCxcbiAgICAweGM2OWRmZjA5LCAweGM3NWI2NWYwLCAweGQ5ZGI0MGQ4LCAweGVjMGU3Nzc5LCAweDQ3NDRlYWQ0LCAweGIxMWMzMjc0LCAweGRkMjRjYjllLCAweDdlMWM1NGJkLFxuICAgIDB4ZjAxMTQ0ZjksIDB4ZDIyNDBlYjEsIDB4OTY3NWIzZmQsIDB4YTNhYzM3NTUsIDB4ZDQ3YzI3YWYsIDB4NTFjODVmNGQsIDB4NTY5MDc1OTYsIDB4YTViYjE1ZTYsXG4gICAgMHg1ODAzMDRmMCwgMHhjYTA0MmNmMSwgMHgwMTFhMzdlYSwgMHg4ZGJmYWFkYiwgMHgzNWJhM2U0YSwgMHgzNTI2ZmZhMCwgMHhjMzdiNGQwOSwgMHhiYzMwNmVkOSxcbiAgICAweDk4YTUyNjY2LCAweDU2NDhmNzI1LCAweGZmNWU1NjlkLCAweDBjZWQ2M2QwLCAweDdjNjNiMmNmLCAweDcwMGI0NWUxLCAweGQ1ZWE1MGYxLCAweDg1YTkyODcyLFxuICAgIDB4YWYxZmJkYTcsIDB4ZDQyMzQ4NzAsIDB4YTc4NzBiZjMsIDB4MmQzYjRkNzksIDB4NDJlMDQxOTgsIDB4MGNkMGVkZTcsIDB4MjY0NzBkYjgsIDB4Zjg4MTgxNGMsXG4gICAgMHg0NzRkNmFkNywgMHg3YzBjNWU1YywgMHhkMTIzMTk1OSwgMHgzODFiNzI5OCwgMHhmNWQyZjRkYiwgMHhhYjgzODY1MywgMHg2ZTJmMWUyMywgMHg4MzcxOWM5ZSxcbiAgICAweGJkOTFlMDQ2LCAweDlhNTY0NTZlLCAweGRjMzkyMDBjLCAweDIwYzhjNTcxLCAweDk2MmJkYTFjLCAweGUxZTY5NmZmLCAweGIxNDFhYjA4LCAweDdjY2E4OWI5LFxuICAgIDB4MWE2OWU3ODMsIDB4MDJjYzQ4NDMsIDB4YTJmN2M1NzksIDB4NDI5ZWY0N2QsIDB4NDI3YjE2OWMsIDB4NWFjOWYwNDksIDB4ZGQ4ZjBmMDAsIDB4NWM4MTY1YmYpO1xuXG4gIHNCb3hbMV0gPSBuZXcgQXJyYXkoXG4gICAgMHgxZjIwMTA5NCwgMHhlZjBiYTc1YiwgMHg2OWUzY2Y3ZSwgMHgzOTNmNDM4MCwgMHhmZTYxY2Y3YSwgMHhlZWM1MjA3YSwgMHg1NTg4OWM5NCwgMHg3MmZjMDY1MSxcbiAgICAweGFkYTdlZjc5LCAweDRlMWQ3MjM1LCAweGQ1NWE2M2NlLCAweGRlMDQzNmJhLCAweDk5YzQzMGVmLCAweDVmMGMwNzk0LCAweDE4ZGNkYjdkLCAweGExZDZlZmYzLFxuICAgIDB4YTBiNTJmN2IsIDB4NTllODM2MDUsIDB4ZWUxNWIwOTQsIDB4ZTlmZmQ5MDksIDB4ZGM0NDAwODYsIDB4ZWY5NDQ0NTksIDB4YmE4M2NjYjMsIDB4ZTBjM2NkZmIsXG4gICAgMHhkMWRhNDE4MSwgMHgzYjA5MmFiMSwgMHhmOTk3ZjFjMSwgMHhhNWU2Y2Y3YiwgMHgwMTQyMGRkYiwgMHhlNGU3ZWY1YiwgMHgyNWExZmY0MSwgMHhlMTgwZjgwNixcbiAgICAweDFmYzQxMDgwLCAweDE3OWJlZTdhLCAweGQzN2FjNmE5LCAweGZlNTgzMGE0LCAweDk4ZGU4YjdmLCAweDc3ZTgzZjRlLCAweDc5OTI5MjY5LCAweDI0ZmE5ZjdiLFxuICAgIDB4ZTExM2M4NWIsIDB4YWNjNDAwODMsIDB4ZDc1MDM1MjUsIDB4ZjdlYTYxNWYsIDB4NjIxNDMxNTQsIDB4MGQ1NTRiNjMsIDB4NWQ2ODExMjEsIDB4Yzg2NmMzNTksXG4gICAgMHgzZDYzY2Y3MywgMHhjZWUyMzRjMCwgMHhkNGQ4N2U4NywgMHg1YzY3MmIyMSwgMHgwNzFmNjE4MSwgMHgzOWY3NjI3ZiwgMHgzNjFlMzA4NCwgMHhlNGViNTczYixcbiAgICAweDYwMmY2NGE0LCAweGQ2M2FjZDljLCAweDFiYmM0NjM1LCAweDllODEwMzJkLCAweDI3MDFmNTBjLCAweDk5ODQ3YWI0LCAweGEwZTNkZjc5LCAweGJhNmNmMzhjLFxuICAgIDB4MTA4NDMwOTQsIDB4MjUzN2E5NWUsIDB4ZjQ2ZjZmZmUsIDB4YTFmZjNiMWYsIDB4MjA4Y2ZiNmEsIDB4OGY0NThjNzQsIDB4ZDllMGEyMjcsIDB4NGVjNzNhMzQsXG4gICAgMHhmYzg4NGY2OSwgMHgzZTRkZThkZiwgMHhlZjBlMDA4OCwgMHgzNTU5NjQ4ZCwgMHg4YTQ1Mzg4YywgMHgxZDgwNDM2NiwgMHg3MjFkOWJmZCwgMHhhNTg2ODRiYixcbiAgICAweGU4MjU2MzMzLCAweDg0NGU4MjEyLCAweDEyOGQ4MDk4LCAweGZlZDMzZmI0LCAweGNlMjgwYWUxLCAweDI3ZTE5YmE1LCAweGQ1YTZjMjUyLCAweGU0OTc1NGJkLFxuICAgIDB4YzVkNjU1ZGQsIDB4ZWI2NjcwNjQsIDB4Nzc4NDBiNGQsIDB4YTFiNmE4MDEsIDB4ODRkYjI2YTksIDB4ZTBiNTY3MTQsIDB4MjFmMDQzYjcsIDB4ZTVkMDU4NjAsXG4gICAgMHg1NGYwMzA4NCwgMHgwNjZmZjQ3MiwgMHhhMzFhYTE1MywgMHhkYWRjNDc1NSwgMHhiNTYyNWRiZiwgMHg2ODU2MWJlNiwgMHg4M2NhNmI5NCwgMHgyZDZlZDIzYixcbiAgICAweGVjY2YwMWRiLCAweGE2ZDNkMGJhLCAweGI2ODAzZDVjLCAweGFmNzdhNzA5LCAweDMzYjRhMzRjLCAweDM5N2JjOGQ2LCAweDVlZTIyYjk1LCAweDVmMGU1MzA0LFxuICAgIDB4ODFlZDZmNjEsIDB4MjBlNzQzNjQsIDB4YjQ1ZTEzNzgsIDB4ZGUxODYzOWIsIDB4ODgxY2ExMjIsIDB4Yjk2NzI2ZDEsIDB4ODA0OWE3ZTgsIDB4MjJiN2RhN2IsXG4gICAgMHg1ZTU1MmQyNSwgMHg1MjcyZDIzNywgMHg3OWQyOTUxYywgMHhjNjBkODk0YywgMHg0ODhjYjQwMiwgMHgxYmE0ZmU1YiwgMHhhNGIwOWY2YiwgMHgxY2E4MTVjZixcbiAgICAweGEyMGMzMDA1LCAweDg4NzFkZjYzLCAweGI5ZGUyZmNiLCAweDBjYzZjOWU5LCAweDBiZWVmZjUzLCAweGUzMjE0NTE3LCAweGI0NTQyODM1LCAweDlmNjMyOTNjLFxuICAgIDB4ZWU0MWU3MjksIDB4NmUxZDJkN2MsIDB4NTAwNDUyODYsIDB4MWU2Njg1ZjMsIDB4ZjMzNDAxYzYsIDB4MzBhMjJjOTUsIDB4MzFhNzA4NTAsIDB4NjA5MzBmMTMsXG4gICAgMHg3M2Y5ODQxNywgMHhhMTI2OTg1OSwgMHhlYzY0NWM0NCwgMHg1MmM4NzdhOSwgMHhjZGZmMzNhNiwgMHhhMDJiMTc0MSwgMHg3Y2JhZDlhMiwgMHgyMTgwMDM2ZixcbiAgICAweDUwZDk5YzA4LCAweGNiM2Y0ODYxLCAweGMyNmJkNzY1LCAweDY0YTNmNmFiLCAweDgwMzQyNjc2LCAweDI1YTc1ZTdiLCAweGU0ZTZkMWZjLCAweDIwYzcxMGU2LFxuICAgIDB4Y2RmMGI2ODAsIDB4MTc4NDRkM2IsIDB4MzFlZWY4NGQsIDB4N2UwODI0ZTQsIDB4MmNjYjQ5ZWIsIDB4ODQ2YTNiYWUsIDB4OGZmNzc4ODgsIDB4ZWU1ZDYwZjYsXG4gICAgMHg3YWY3NTY3MywgMHgyZmRkNWNkYiwgMHhhMTE2MzFjMSwgMHgzMGY2NmY0MywgMHhiM2ZhZWM1NCwgMHgxNTdmZDdmYSwgMHhlZjg1NzljYywgMHhkMTUyZGU1OCxcbiAgICAweGRiMmZmZDVlLCAweDhmMzJjZTE5LCAweDMwNmFmOTdhLCAweDAyZjAzZWY4LCAweDk5MzE5YWQ1LCAweGMyNDJmYTBmLCAweGE3ZTNlYmIwLCAweGM2OGU0OTA2LFxuICAgIDB4YjhkYTIzMGMsIDB4ODA4MjMwMjgsIDB4ZGNkZWYzYzgsIDB4ZDM1ZmIxNzEsIDB4MDg4YTFiYzgsIDB4YmVjMGM1NjAsIDB4NjFhM2M5ZTgsIDB4YmNhOGY1NGQsXG4gICAgMHhjNzJmZWZmYSwgMHgyMjgyMmU5OSwgMHg4MmM1NzBiNCwgMHhkOGQ5NGU4OSwgMHg4YjFjMzRiYywgMHgzMDFlMTZlNiwgMHgyNzNiZTk3OSwgMHhiMGZmZWFhNixcbiAgICAweDYxZDliOGM2LCAweDAwYjI0ODY5LCAweGI3ZmZjZTNmLCAweDA4ZGMyODNiLCAweDQzZGFmNjVhLCAweGY3ZTE5Nzk4LCAweDc2MTliNzJmLCAweDhmMWM5YmE0LFxuICAgIDB4ZGM4NjM3YTAsIDB4MTZhN2QzYjEsIDB4OWZjMzkzYjcsIDB4YTcxMzZlZWIsIDB4YzZiY2M2M2UsIDB4MWE1MTM3NDIsIDB4ZWY2ODI4YmMsIDB4NTIwMzY1ZDYsXG4gICAgMHgyZDZhNzdhYiwgMHgzNTI3ZWQ0YiwgMHg4MjFmZDIxNiwgMHgwOTVjNmUyZSwgMHhkYjkyZjJmYiwgMHg1ZWVhMjljYiwgMHgxNDU4OTJmNSwgMHg5MTU4NGY3ZixcbiAgICAweDU0ODM2OTdiLCAweDI2NjdhOGNjLCAweDg1MTk2MDQ4LCAweDhjNGJhY2VhLCAweDgzMzg2MGQ0LCAweDBkMjNlMGY5LCAweDZjMzg3ZThhLCAweDBhZTZkMjQ5LFxuICAgIDB4YjI4NDYwMGMsIDB4ZDgzNTczMWQsIDB4ZGNiMWM2NDcsIDB4YWM0YzU2ZWEsIDB4M2ViZDgxYjMsIDB4MjMwZWFiYjAsIDB4NjQzOGJjODcsIDB4ZjBiNWIxZmEsXG4gICAgMHg4ZjVlYTJiMywgMHhmYzE4NDY0MiwgMHgwYTAzNmI3YSwgMHg0ZmIwODliZCwgMHg2NDlkYTU4OSwgMHhhMzQ1NDE1ZSwgMHg1YzAzODMyMywgMHgzZTVkM2JiOSxcbiAgICAweDQzZDc5NTcyLCAweDdlNmRkMDdjLCAweDA2ZGZkZjFlLCAweDZjNmNjNGVmLCAweDcxNjBhNTM5LCAweDczYmZiZTcwLCAweDgzODc3NjA1LCAweDQ1MjNlY2YxKTtcblxuICBzQm94WzJdID0gbmV3IEFycmF5KFxuICAgIDB4OGRlZmMyNDAsIDB4MjVmYTVkOWYsIDB4ZWI5MDNkYmYsIDB4ZTgxMGM5MDcsIDB4NDc2MDdmZmYsIDB4MzY5ZmU0NGIsIDB4OGMxZmM2NDQsIDB4YWVjZWNhOTAsXG4gICAgMHhiZWIxZjliZiwgMHhlZWZiY2FlYSwgMHhlOGNmMTk1MCwgMHg1MWRmMDdhZSwgMHg5MjBlODgwNiwgMHhmMGFkMDU0OCwgMHhlMTNjOGQ4MywgMHg5MjcwMTBkNSxcbiAgICAweDExMTA3ZDlmLCAweDA3NjQ3ZGI5LCAweGIyZTNlNGQ0LCAweDNkNGYyODVlLCAweGI5YWZhODIwLCAweGZhZGU4MmUwLCAweGEwNjcyNjhiLCAweDgyNzI3OTJlLFxuICAgIDB4NTUzZmIyYzAsIDB4NDg5YWUyMmIsIDB4ZDRlZjk3OTQsIDB4MTI1ZTNmYmMsIDB4MjFmZmZjZWUsIDB4ODI1YjFiZmQsIDB4OTI1NWM1ZWQsIDB4MTI1N2EyNDAsXG4gICAgMHg0ZTFhODMwMiwgMHhiYWUwN2ZmZiwgMHg1MjgyNDZlNywgMHg4ZTU3MTQwZSwgMHgzMzczZjdiZiwgMHg4YzlmODE4OCwgMHhhNmZjNGVlOCwgMHhjOTgyYjVhNSxcbiAgICAweGE4YzAxZGI3LCAweDU3OWZjMjY0LCAweDY3MDk0ZjMxLCAweGYyYmQzZjVmLCAweDQwZmZmN2MxLCAweDFmYjc4ZGZjLCAweDhlNmJkMmMxLCAweDQzN2JlNTliLFxuICAgIDB4OTliMDNkYmYsIDB4YjVkYmM2NGIsIDB4NjM4ZGMwZTYsIDB4NTU4MTlkOTksIDB4YTE5N2M4MWMsIDB4NGEwMTJkNmUsIDB4YzU4ODRhMjgsIDB4Y2NjMzZmNzEsXG4gICAgMHhiODQzYzIxMywgMHg2YzA3NDNmMSwgMHg4MzA5ODkzYywgMHgwZmVkZGQ1ZiwgMHgyZjdmZTg1MCwgMHhkN2MwN2Y3ZSwgMHgwMjUwN2ZiZiwgMHg1YWZiOWEwNCxcbiAgICAweGE3NDdkMmQwLCAweDE2NTExOTJlLCAweGFmNzBiZjNlLCAweDU4YzMxMzgwLCAweDVmOTgzMDJlLCAweDcyN2NjM2M0LCAweDBhMGZiNDAyLCAweDBmN2ZlZjgyLFxuICAgIDB4OGM5NmZkYWQsIDB4NWQyYzJhYWUsIDB4OGVlOTlhNDksIDB4NTBkYTg4YjgsIDB4ODQyN2Y0YTAsIDB4MWVhYzU3OTAsIDB4Nzk2ZmI0NDksIDB4ODI1MmRjMTUsXG4gICAgMHhlZmJkN2Q5YiwgMHhhNjcyNTk3ZCwgMHhhZGE4NDBkOCwgMHg0NWY1NDUwNCwgMHhmYTVkNzQwMywgMHhlODNlYzMwNSwgMHg0ZjkxNzUxYSwgMHg5MjU2NjljMixcbiAgICAweDIzZWZlOTQxLCAweGE5MDNmMTJlLCAweDYwMjcwZGYyLCAweDAyNzZlNGI2LCAweDk0ZmQ2NTc0LCAweDkyNzk4NWIyLCAweDgyNzZkYmNiLCAweDAyNzc4MTc2LFxuICAgIDB4ZjhhZjkxOGQsIDB4NGU0OGY3OWUsIDB4OGY2MTZkZGYsIDB4ZTI5ZDg0MGUsIDB4ODQyZjdkODMsIDB4MzQwY2U1YzgsIDB4OTZiYmI2ODIsIDB4OTNiNGIxNDgsXG4gICAgMHhlZjMwM2NhYiwgMHg5ODRmYWYyOCwgMHg3NzlmYWY5YiwgMHg5MmRjNTYwZCwgMHgyMjRkMWUyMCwgMHg4NDM3YWE4OCwgMHg3ZDI5ZGM5NiwgMHgyNzU2ZDNkYyxcbiAgICAweDhiOTA3Y2VlLCAweGI1MWZkMjQwLCAweGU3YzA3Y2UzLCAweGU1NjZiNGExLCAweGMzZTk2MTVlLCAweDNjZjgyMDlkLCAweDYwOTRkMWUzLCAweGNkOWNhMzQxLFxuICAgIDB4NWM3NjQ2MGUsIDB4MDBlYTk4M2IsIDB4ZDRkNjc4ODEsIDB4ZmQ0NzU3MmMsIDB4Zjc2Y2VkZDksIDB4YmRhODIyOWMsIDB4MTI3ZGFkYWEsIDB4NDM4YTA3NGUsXG4gICAgMHgxZjk3YzA5MCwgMHgwODFiZGI4YSwgMHg5M2EwN2ViZSwgMHhiOTM4Y2ExNSwgMHg5N2IwM2NmZiwgMHgzZGMyYzBmOCwgMHg4ZDFhYjJlYywgMHg2NDM4MGU1MSxcbiAgICAweDY4Y2M3YmZiLCAweGQ5MGYyNzg4LCAweDEyNDkwMTgxLCAweDVkZTVmZmQ0LCAweGRkN2VmODZhLCAweDc2YTJlMjE0LCAweGI5YTQwMzY4LCAweDkyNWQ5NThmLFxuICAgIDB4NGIzOWZmZmEsIDB4YmEzOWFlZTksIDB4YTRmZmQzMGIsIDB4ZmFmNzkzM2IsIDB4NmQ0OTg2MjMsIDB4MTkzY2JjZmEsIDB4Mjc2Mjc1NDUsIDB4ODI1Y2Y0N2EsXG4gICAgMHg2MWJkOGJhMCwgMHhkMTFlNDJkMSwgMHhjZWFkMDRmNCwgMHgxMjdlYTM5MiwgMHgxMDQyOGRiNywgMHg4MjcyYTk3MiwgMHg5MjcwYzRhOCwgMHgxMjdkZTUwYixcbiAgICAweDI4NWJhMWM4LCAweDNjNjJmNDRmLCAweDM1YzBlYWE1LCAweGU4MDVkMjMxLCAweDQyODkyOWZiLCAweGI0ZmNkZjgyLCAweDRmYjY2YTUzLCAweDBlN2RjMTViLFxuICAgIDB4MWYwODFmYWIsIDB4MTA4NjE4YWUsIDB4ZmNmZDA4NmQsIDB4ZjlmZjI4ODksIDB4Njk0YmNjMTEsIDB4MjM2YTVjYWUsIDB4MTJkZWNhNGQsIDB4MmMzZjhjYzUsXG4gICAgMHhkMmQwMmRmZSwgMHhmOGVmNTg5NiwgMHhlNGNmNTJkYSwgMHg5NTE1NWI2NywgMHg0OTRhNDg4YywgMHhiOWI2YTgwYywgMHg1YzhmODJiYywgMHg4OWQzNmI0NSxcbiAgICAweDNhNjA5NDM3LCAweGVjMDBjOWE5LCAweDQ0NzE1MjUzLCAweDBhODc0YjQ5LCAweGQ3NzNiYzQwLCAweDdjMzQ2NzFjLCAweDAyNzE3ZWY2LCAweDRmZWI1NTM2LFxuICAgIDB4YTJkMDJmZmYsIDB4ZDJiZjYwYzQsIDB4ZDQzZjAzYzAsIDB4NTBiNGVmNmQsIDB4MDc0NzhjZDEsIDB4MDA2ZTE4ODgsIDB4YTJlNTNmNTUsIDB4YjllNmQ0YmMsXG4gICAgMHhhMjA0ODAxNiwgMHg5NzU3MzgzMywgMHhkNzIwN2Q2NywgMHhkZTBmOGYzZCwgMHg3MmY4N2IzMywgMHhhYmNjNGYzMywgMHg3Njg4YzU1ZCwgMHg3YjAwYTZiMCxcbiAgICAweDk0N2IwMDAxLCAweDU3MDA3NWQyLCAweGY5YmI4OGY4LCAweDg5NDIwMTllLCAweDQyNjRhNWZmLCAweDg1NjMwMmUwLCAweDcyZGJkOTJiLCAweGVlOTcxYjY5LFxuICAgIDB4NmVhMjJmZGUsIDB4NWYwOGFlMmIsIDB4YWY3YTYxNmQsIDB4ZTVjOTg3NjcsIDB4Y2YxZmViZDIsIDB4NjFlZmM4YzIsIDB4ZjFhYzI1NzEsIDB4Y2M4MjM5YzIsXG4gICAgMHg2NzIxNGNiOCwgMHhiMWU1ODNkMSwgMHhiN2RjM2U2MiwgMHg3ZjEwYmRjZSwgMHhmOTBhNWMzOCwgMHgwZmYwNDQzZCwgMHg2MDZlNmRjNiwgMHg2MDU0M2E0OSxcbiAgICAweDU3MjdjMTQ4LCAweDJiZTk4YTFkLCAweDhhYjQxNzM4LCAweDIwZTFiZTI0LCAweGFmOTZkYTBmLCAweDY4NDU4NDI1LCAweDk5ODMzYmU1LCAweDYwMGQ0NTdkLFxuICAgIDB4MjgyZjkzNTAsIDB4ODMzNGIzNjIsIDB4ZDkxZDExMjAsIDB4MmI2ZDhkYTAsIDB4NjQyYjFlMzEsIDB4OWMzMDVhMDAsIDB4NTJiY2U2ODgsIDB4MWIwMzU4OGEsXG4gICAgMHhmN2JhZWZkNSwgMHg0MTQyZWQ5YywgMHhhNDMxNWMxMSwgMHg4MzMyM2VjNSwgMHhkZmVmNDYzNiwgMHhhMTMzYzUwMSwgMHhlOWQzNTMxYywgMHhlZTM1Mzc4Myk7XG5cbiAgc0JveFszXSA9IG5ldyBBcnJheShcbiAgICAweDlkYjMwNDIwLCAweDFmYjZlOWRlLCAweGE3YmU3YmVmLCAweGQyNzNhMjk4LCAweDRhNGY3YmRiLCAweDY0YWQ4YzU3LCAweDg1NTEwNDQzLCAweGZhMDIwZWQxLFxuICAgIDB4N2UyODdhZmYsIDB4ZTYwZmI2NjMsIDB4MDk1ZjM1YTEsIDB4NzllYmYxMjAsIDB4ZmQwNTlkNDMsIDB4NjQ5N2I3YjEsIDB4ZjM2NDFmNjMsIDB4MjQxZTRhZGYsXG4gICAgMHgyODE0N2Y1ZiwgMHg0ZmEyYjhjZCwgMHhjOTQzMDA0MCwgMHgwY2MzMjIyMCwgMHhmZGQzMGIzMCwgMHhjMGE1Mzc0ZiwgMHgxZDJkMDBkOSwgMHgyNDE0N2IxNSxcbiAgICAweGVlNGQxMTFhLCAweDBmY2E1MTY3LCAweDcxZmY5MDRjLCAweDJkMTk1ZmZlLCAweDFhMDU2NDVmLCAweDBjMTNmZWZlLCAweDA4MWIwOGNhLCAweDA1MTcwMTIxLFxuICAgIDB4ODA1MzAxMDAsIDB4ZTgzZTVlZmUsIDB4YWM5YWY0ZjgsIDB4N2ZlNzI3MDEsIDB4ZDJiOGVlNWYsIDB4MDZkZjQyNjEsIDB4YmI5ZTliOGEsIDB4NzI5M2VhMjUsXG4gICAgMHhjZTg0ZmZkZiwgMHhmNTcxODgwMSwgMHgzZGQ2NGIwNCwgMHhhMjZmMjYzYiwgMHg3ZWQ0ODQwMCwgMHg1NDdlZWJlNiwgMHg0NDZkNGNhMCwgMHg2Y2YzZDZmNSxcbiAgICAweDI2NDlhYmRmLCAweGFlYTBjN2Y1LCAweDM2MzM4Y2MxLCAweDUwM2Y3ZTkzLCAweGQzNzcyMDYxLCAweDExYjYzOGUxLCAweDcyNTAwZTAzLCAweGY4MGViMmJiLFxuICAgIDB4YWJlMDUwMmUsIDB4ZWM4ZDc3ZGUsIDB4NTc5NzFlODEsIDB4ZTE0ZjY3NDYsIDB4YzkzMzU0MDAsIDB4NjkyMDMxOGYsIDB4MDgxZGJiOTksIDB4ZmZjMzA0YTUsXG4gICAgMHg0ZDM1MTgwNSwgMHg3ZjNkNWNlMywgMHhhNmM4NjZjNiwgMHg1ZDViY2NhOSwgMHhkYWVjNmZlYSwgMHg5ZjkyNmY5MSwgMHg5ZjQ2MjIyZiwgMHgzOTkxNDY3ZCxcbiAgICAweGE1YmY2ZDhlLCAweDExNDNjNDRmLCAweDQzOTU4MzAyLCAweGQwMjE0ZWViLCAweDAyMjA4M2I4LCAweDNmYjYxODBjLCAweDE4Zjg5MzFlLCAweDI4MTY1OGU2LFxuICAgIDB4MjY0ODZlM2UsIDB4OGJkNzhhNzAsIDB4NzQ3N2U0YzEsIDB4YjUwNmUwN2MsIDB4ZjMyZDBhMjUsIDB4NzkwOThiMDIsIDB4ZTRlYWJiODEsIDB4MjgxMjNiMjMsXG4gICAgMHg2OWRlYWQzOCwgMHgxNTc0Y2ExNiwgMHhkZjg3MWI2MiwgMHgyMTFjNDBiNywgMHhhNTFhOWVmOSwgMHgwMDE0Mzc3YiwgMHgwNDFlOGFjOCwgMHgwOTExNDAwMyxcbiAgICAweGJkNTllNGQyLCAweGUzZDE1NmQ1LCAweDRmZTg3NmQ1LCAweDJmOTFhMzQwLCAweDU1N2JlOGRlLCAweDAwZWFlNGE3LCAweDBjZTVjMmVjLCAweDRkYjRiYmE2LFxuICAgIDB4ZTc1NmJkZmYsIDB4ZGQzMzY5YWMsIDB4ZWMxN2IwMzUsIDB4MDY1NzIzMjcsIDB4OTlhZmM4YjAsIDB4NTZjOGMzOTEsIDB4NmI2NTgxMWMsIDB4NWUxNDYxMTksXG4gICAgMHg2ZTg1Y2I3NSwgMHhiZTA3YzAwMiwgMHhjMjMyNTU3NywgMHg4OTNmZjRlYywgMHg1YmJmYzkyZCwgMHhkMGVjM2IyNSwgMHhiNzgwMWFiNywgMHg4ZDZkM2IyNCxcbiAgICAweDIwYzc2M2VmLCAweGMzNjZhNWZjLCAweDljMzgyODgwLCAweDBhY2UzMjA1LCAweGFhYzk1NDhhLCAweGVjYTFkN2M3LCAweDA0MWFmYTMyLCAweDFkMTY2MjVhLFxuICAgIDB4NjcwMTkwMmMsIDB4OWI3NTdhNTQsIDB4MzFkNDc3ZjcsIDB4OTEyNmIwMzEsIDB4MzZjYzZmZGIsIDB4YzcwYjhiNDYsIDB4ZDllNjZhNDgsIDB4NTZlNTVhNzksXG4gICAgMHgwMjZhNGNlYiwgMHg1MjQzN2VmZiwgMHgyZjhmNzZiNCwgMHgwZGY5ODBhNSwgMHg4Njc0Y2RlMywgMHhlZGRhMDRlYiwgMHgxN2E5YmUwNCwgMHgyYzE4ZjRkZixcbiAgICAweGI3NzQ3ZjlkLCAweGFiMmFmN2I0LCAweGVmYzM0ZDIwLCAweDJlMDk2YjdjLCAweDE3NDFhMjU0LCAweGU1YjZhMDM1LCAweDIxM2Q0MmY2LCAweDJjMWM3YzI2LFxuICAgIDB4NjFjMmY1MGYsIDB4NjU1MmRhZjksIDB4ZDJjMjMxZjgsIDB4MjUxMzBmNjksIDB4ZDgxNjdmYTIsIDB4MDQxOGYyYzgsIDB4MDAxYTk2YTYsIDB4MGQxNTI2YWIsXG4gICAgMHg2MzMxNWMyMSwgMHg1ZTBhNzJlYywgMHg0OWJhZmVmZCwgMHgxODc5MDhkOSwgMHg4ZDBkYmQ4NiwgMHgzMTExNzBhNywgMHgzZTliNjQwYywgMHhjYzNlMTBkNyxcbiAgICAweGQ1Y2FkM2I2LCAweDBjYWVjMzg4LCAweGY3MzAwMWUxLCAweDZjNzI4YWZmLCAweDcxZWFlMmExLCAweDFmOWFmMzZlLCAweGNmY2JkMTJmLCAweGMxZGU4NDE3LFxuICAgIDB4YWMwN2JlNmIsIDB4Y2I0NGExZDgsIDB4OGI5YjBmNTYsIDB4MDEzOTg4YzMsIDB4YjFjNTJmY2EsIDB4YjRiZTMxY2QsIDB4ZDg3ODI4MDYsIDB4MTJhM2E0ZTIsXG4gICAgMHg2ZjdkZTUzMiwgMHg1OGZkN2ViNiwgMHhkMDFlZTkwMCwgMHgyNGFkZmZjMiwgMHhmNDk5MGZjNSwgMHg5NzExYWFjNSwgMHgwMDFkN2I5NSwgMHg4MmU1ZTdkMixcbiAgICAweDEwOTg3M2Y2LCAweDAwNjEzMDk2LCAweGMzMmQ5NTIxLCAweGFkYTEyMWZmLCAweDI5OTA4NDE1LCAweDdmYmI5NzdmLCAweGFmOWViM2RiLCAweDI5YzllZDJhLFxuICAgIDB4NWNlMmE0NjUsIDB4YTczMGYzMmMsIDB4ZDBhYTNmZTgsIDB4OGE1Y2MwOTEsIDB4ZDQ5ZTJjZTcsIDB4MGNlNDU0YTksIDB4ZDYwYWNkODYsIDB4MDE1ZjE5MTksXG4gICAgMHg3NzA3OTEwMywgMHhkZWEwM2FmNiwgMHg3OGE4NTY1ZSwgMHhkZWUzNTZkZiwgMHgyMWYwNWNiZSwgMHg4Yjc1ZTM4NywgMHhiM2M1MDY1MSwgMHhiOGE1YzNlZixcbiAgICAweGQ4ZWViNmQyLCAweGU1MjNiZTc3LCAweGMyMTU0NTI5LCAweDJmNjllZmRmLCAweGFmZTY3YWZiLCAweGY0NzBjNGIyLCAweGYzZTBlYjViLCAweGQ2Y2M5ODc2LFxuICAgIDB4MzllNDQ2MGMsIDB4MWZkYTg1MzgsIDB4MTk4NzgzMmYsIDB4Y2EwMDczNjcsIDB4YTk5MTQ0ZjgsIDB4Mjk2YjI5OWUsIDB4NDkyZmMyOTUsIDB4OTI2NmJlYWIsXG4gICAgMHhiNTY3NmU2OSwgMHg5YmQzZGRkYSwgMHhkZjdlMDUyZiwgMHhkYjI1NzAxYywgMHgxYjVlNTFlZSwgMHhmNjUzMjRlNiwgMHg2YWZjZTM2YywgMHgwMzE2Y2MwNCxcbiAgICAweDg2NDQyMTNlLCAweGI3ZGM1OWQwLCAweDc5NjUyOTFmLCAweGNjZDZmZDQzLCAweDQxODIzOTc5LCAweDkzMmJjZGY2LCAweGI2NTdjMzRkLCAweDRlZGZkMjgyLFxuICAgIDB4N2FlNTI5MGMsIDB4M2NiOTUzNmIsIDB4ODUxZTIwZmUsIDB4OTgzMzU1N2UsIDB4MTNlY2YwYjAsIDB4ZDNmZmIzNzIsIDB4M2Y4NWM1YzEsIDB4MGFlZjdlZDIpO1xuXG4gIHNCb3hbNF0gPSBuZXcgQXJyYXkoXG4gICAgMHg3ZWM5MGMwNCwgMHgyYzZlNzRiOSwgMHg5YjBlNjZkZiwgMHhhNjMzNzkxMSwgMHhiODZhN2ZmZiwgMHgxZGQzNThmNSwgMHg0NGRkOWQ0NCwgMHgxNzMxMTY3ZixcbiAgICAweDA4ZmJmMWZhLCAweGU3ZjUxMWNjLCAweGQyMDUxYjAwLCAweDczNWFiYTAwLCAweDJhYjcyMmQ4LCAweDM4NjM4MWNiLCAweGFjZjYyNDNhLCAweDY5YmVmZDdhLFxuICAgIDB4ZTZhMmU3N2YsIDB4ZjBjNzIwY2QsIDB4YzQ0OTQ4MTYsIDB4Y2NmNWMxODAsIDB4Mzg4NTE2NDAsIDB4MTViMGE4NDgsIDB4ZTY4YjE4Y2IsIDB4NGNhYWRlZmYsXG4gICAgMHg1ZjQ4MGEwMSwgMHgwNDEyYjJhYSwgMHgyNTk4MTRmYywgMHg0MWQwZWZlMiwgMHg0ZTQwYjQ4ZCwgMHgyNDhlYjZmYiwgMHg4ZGJhMWNmZSwgMHg0MWE5OWIwMixcbiAgICAweDFhNTUwYTA0LCAweGJhOGY2NWNiLCAweDcyNTFmNGU3LCAweDk1YTUxNzI1LCAweGMxMDZlY2Q3LCAweDk3YTU5ODBhLCAweGM1MzliOWFhLCAweDRkNzlmZTZhLFxuICAgIDB4ZjJmM2Y3NjMsIDB4NjhhZjgwNDAsIDB4ZWQwYzllNTYsIDB4MTFiNDk1OGIsIDB4ZTFlYjVhODgsIDB4ODcwOWU2YjAsIDB4ZDdlMDcxNTYsIDB4NGUyOWZlYTcsXG4gICAgMHg2MzY2ZTUyZCwgMHgwMmQxYzAwMCwgMHhjNGFjOGUwNSwgMHg5Mzc3ZjU3MSwgMHgwYzA1MzcyYSwgMHg1Nzg1MzVmMiwgMHgyMjYxYmUwMiwgMHhkNjQyYTBjOSxcbiAgICAweGRmMTNhMjgwLCAweDc0YjU1YmQyLCAweDY4MjE5OWMwLCAweGQ0MjFlNWVjLCAweDUzZmIzY2U4LCAweGM4YWRlZGIzLCAweDI4YTg3ZmM5LCAweDNkOTU5OTgxLFxuICAgIDB4NWMxZmY5MDAsIDB4ZmUzOGQzOTksIDB4MGM0ZWZmMGIsIDB4MDYyNDA3ZWEsIDB4YWEyZjRmYjEsIDB4NGZiOTY5NzYsIDB4OTBjNzk1MDUsIDB4YjBhOGE3NzQsXG4gICAgMHhlZjU1YTFmZiwgMHhlNTljYTJjMiwgMHhhNmI2MmQyNywgMHhlNjZhNDI2MywgMHhkZjY1MDAxZiwgMHgwZWM1MDk2NiwgMHhkZmRkNTViYywgMHgyOWRlMDY1NSxcbiAgICAweDkxMWU3MzlhLCAweDE3YWY4OTc1LCAweDMyYzc5MTFjLCAweDg5Zjg5NDY4LCAweDBkMDFlOTgwLCAweDUyNDc1NWY0LCAweDAzYjYzY2M5LCAweDBjYzg0NGIyLFxuICAgIDB4YmNmM2YwYWEsIDB4ODdhYzM2ZTksIDB4ZTUzYTc0MjYsIDB4MDFiM2Q4MmIsIDB4MWE5ZTc0NDksIDB4NjRlZTJkN2UsIDB4Y2RkYmIxZGEsIDB4MDFjOTQ5MTAsXG4gICAgMHhiODY4YmY4MCwgMHgwZDI2ZjNmZCwgMHg5MzQyZWRlNywgMHgwNGE1YzI4NCwgMHg2MzY3MzdiNiwgMHg1MGY1YjYxNiwgMHhmMjQ3NjZlMywgMHg4ZWNhMzZjMSxcbiAgICAweDEzNmUwNWRiLCAweGZlZjE4MzkxLCAweGZiODg3YTM3LCAweGQ2ZTdmN2Q0LCAweGM3ZmI3ZGM5LCAweDMwNjNmY2RmLCAweGI2ZjU4OWRlLCAweGVjMjk0MWRhLFxuICAgIDB4MjZlNDY2OTUsIDB4Yjc1NjY0MTksIDB4ZjY1NGVmYzUsIDB4ZDA4ZDU4YjcsIDB4NDg5MjU0MDEsIDB4YzFiYWNiN2YsIDB4ZTVmZjU1MGYsIDB4YjYwODMwNDksXG4gICAgMHg1YmI1ZDBlOCwgMHg4N2Q3MmU1YSwgMHhhYjZhNmVlMSwgMHgyMjNhNjZjZSwgMHhjNjJiZjNjZCwgMHg5ZTA4ODVmOSwgMHg2OGNiM2U0NywgMHgwODZjMDEwZixcbiAgICAweGEyMWRlODIwLCAweGQxOGI2OWRlLCAweGYzZjY1Nzc3LCAweGZhMDJjM2Y2LCAweDQwN2VkYWMzLCAweGNiYjNkNTUwLCAweDE3OTMwODRkLCAweGIwZDcwZWJhLFxuICAgIDB4MGFiMzc4ZDUsIDB4ZDk1MWZiMGMsIDB4ZGVkN2RhNTYsIDB4NDEyNGJiZTQsIDB4OTRjYTBiNTYsIDB4MGY1NzU1ZDEsIDB4ZTBlMWU1NmUsIDB4NjE4NGI1YmUsXG4gICAgMHg1ODBhMjQ5ZiwgMHg5NGY3NGJjMCwgMHhlMzI3ODg4ZSwgMHg5ZjdiNTU2MSwgMHhjM2RjMDI4MCwgMHgwNTY4NzcxNSwgMHg2NDZjNmJkNywgMHg0NDkwNGRiMyxcbiAgICAweDY2YjRmMGEzLCAweGMwZjE2NDhhLCAweDY5N2VkNWFmLCAweDQ5ZTkyZmY2LCAweDMwOWUzNzRmLCAweDJjYjYzNTZhLCAweDg1ODA4NTczLCAweDQ5OTFmODQwLFxuICAgIDB4NzZmMGFlMDIsIDB4MDgzYmU4NGQsIDB4Mjg0MjFjOWEsIDB4NDQ0ODk0MDYsIDB4NzM2ZTRjYjgsIDB4YzEwOTI5MTAsIDB4OGJjOTVmYzYsIDB4N2Q4NjljZjQsXG4gICAgMHgxMzRmNjE2ZiwgMHgyZTc3MTE4ZCwgMHhiMzFiMmJlMSwgMHhhYTkwYjQ3MiwgMHgzY2E1ZDcxNywgMHg3ZDE2MWJiYSwgMHg5Y2FkOTAxMCwgMHhhZjQ2MmJhMixcbiAgICAweDlmZTQ1OWQyLCAweDQ1ZDM0NTU5LCAweGQ5ZjJkYTEzLCAweGRiYzY1NDg3LCAweGYzZTRmOTRlLCAweDE3NmQ0ODZmLCAweDA5N2MxM2VhLCAweDYzMWRhNWM3LFxuICAgIDB4NDQ1ZjczODIsIDB4MTc1NjgzZjQsIDB4Y2RjNjZhOTcsIDB4NzBiZTAyODgsIDB4YjNjZGNmNzIsIDB4NmU1ZGQyZjMsIDB4MjA5MzYwNzksIDB4NDU5YjgwYTUsXG4gICAgMHhiZTYwZTJkYiwgMHhhOWMyMzEwMSwgMHhlYmE1MzE1YywgMHgyMjRlNDJmMiwgMHgxYzVjMTU3MiwgMHhmNjcyMWIyYywgMHgxYWQyZmZmMywgMHg4YzI1NDA0ZSxcbiAgICAweDMyNGVkNzJmLCAweDQwNjdiN2ZkLCAweDA1MjMxMzhlLCAweDVjYTNiYzc4LCAweGRjMGZkNjZlLCAweDc1OTIyMjgzLCAweDc4NGQ2YjE3LCAweDU4ZWJiMTZlLFxuICAgIDB4NDQwOTRmODUsIDB4M2Y0ODFkODcsIDB4ZmNmZWFlN2IsIDB4NzdiNWZmNzYsIDB4OGMyMzAyYmYsIDB4YWFmNDc1NTYsIDB4NWY0NmIwMmEsIDB4MmIwOTI4MDEsXG4gICAgMHgzZDM4ZjVmNywgMHgwY2E4MWYzNiwgMHg1MmFmNGE4YSwgMHg2NmQ1ZTdjMCwgMHhkZjNiMDg3NCwgMHg5NTA1NTExMCwgMHgxYjVhZDdhOCwgMHhmNjFlZDVhZCxcbiAgICAweDZjZjZlNDc5LCAweDIwNzU4MTg0LCAweGQwY2VmYTY1LCAweDg4ZjdiZTU4LCAweDRhMDQ2ODI2LCAweDBmZjZmOGYzLCAweGEwOWM3ZjcwLCAweDUzNDZhYmEwLFxuICAgIDB4NWNlOTZjMjgsIDB4ZTE3NmVkYTMsIDB4NmJhYzMwN2YsIDB4Mzc2ODI5ZDIsIDB4ODUzNjBmYTksIDB4MTdlM2ZlMmEsIDB4MjRiNzk3NjcsIDB4ZjVhOTZiMjAsXG4gICAgMHhkNmNkMjU5NSwgMHg2OGZmMWViZiwgMHg3NTU1NDQyYywgMHhmMTlmMDZiZSwgMHhmOWUwNjU5YSwgMHhlZWI5NDkxZCwgMHgzNDAxMDcxOCwgMHhiYjMwY2FiOCxcbiAgICAweGU4MjJmZTE1LCAweDg4NTcwOTgzLCAweDc1MGU2MjQ5LCAweGRhNjI3ZTU1LCAweDVlNzZmZmE4LCAweGIxNTM0NTQ2LCAweDZkNDdkZTA4LCAweGVmZTllN2Q0KTtcblxuICBzQm94WzVdID0gbmV3IEFycmF5KFxuICAgIDB4ZjZmYThmOWQsIDB4MmNhYzZjZTEsIDB4NGNhMzQ4NjcsIDB4ZTIzMzdmN2MsIDB4OTVkYjA4ZTcsIDB4MDE2ODQzYjQsIDB4ZWNlZDVjYmMsIDB4MzI1NTUzYWMsXG4gICAgMHhiZjlmMDk2MCwgMHhkZmExZTJlZCwgMHg4M2YwNTc5ZCwgMHg2M2VkODZiOSwgMHgxYWI2YTZiOCwgMHhkZTVlYmUzOSwgMHhmMzhmZjczMiwgMHg4OTg5YjEzOCxcbiAgICAweDMzZjE0OTYxLCAweGMwMTkzN2JkLCAweGY1MDZjNmRhLCAweGU0NjI1ZTdlLCAweGEzMDhlYTk5LCAweDRlMjNlMzNjLCAweDc5Y2JkN2NjLCAweDQ4YTE0MzY3LFxuICAgIDB4YTMxNDk2MTksIDB4ZmVjOTRiZDUsIDB4YTExNDE3NGEsIDB4ZWFhMDE4NjYsIDB4YTA4NGRiMmQsIDB4MDlhODQ4NmYsIDB4YTg4ODYxNGEsIDB4MjkwMGFmOTgsXG4gICAgMHgwMTY2NTk5MSwgMHhlMTk5Mjg2MywgMHhjOGYzMGM2MCwgMHgyZTc4ZWYzYywgMHhkMGQ1MTkzMiwgMHhjZjBmZWMxNCwgMHhmN2NhMDdkMiwgMHhkMGE4MjA3MixcbiAgICAweGZkNDExOTdlLCAweDkzMDVhNmIwLCAweGU4NmJlM2RhLCAweDc0YmVkM2NkLCAweDM3MmRhNTNjLCAweDRjN2Y0NDQ4LCAweGRhYjVkNDQwLCAweDZkYmEwZWMzLFxuICAgIDB4MDgzOTE5YTcsIDB4OWZiYWVlZDksIDB4NDlkYmNmYjAsIDB4NGU2NzBjNTMsIDB4NWMzZDljMDEsIDB4NjRiZGI5NDEsIDB4MmMwZTYzNmEsIDB4YmE3ZGQ5Y2QsXG4gICAgMHhlYTZmNzM4OCwgMHhlNzBiYzc2MiwgMHgzNWYyOWFkYiwgMHg1YzRjZGQ4ZCwgMHhmMGQ0OGQ4YywgMHhiODgxNTNlMiwgMHgwOGExOTg2NiwgMHgxYWUyZWFjOCxcbiAgICAweDI4NGNhZjg5LCAweGFhOTI4MjIzLCAweDkzMzRiZTUzLCAweDNiM2EyMWJmLCAweDE2NDM0YmUzLCAweDlhZWEzOTA2LCAweGVmZThjMzZlLCAweGY4OTBjZGQ5LFxuICAgIDB4ODAyMjZkYWUsIDB4YzM0MGE0YTMsIDB4ZGY3ZTljMDksIDB4YTY5NGE4MDcsIDB4NWI3YzVlY2MsIDB4MjIxZGIzYTYsIDB4OWE2OWEwMmYsIDB4Njg4MThhNTQsXG4gICAgMHhjZWIyMjk2ZiwgMHg1M2MwODQzYSwgMHhmZTg5MzY1NSwgMHgyNWJmZTY4YSwgMHhiNDYyOGFiYywgMHhjZjIyMmViZiwgMHgyNWFjNmY0OCwgMHhhOWE5OTM4NyxcbiAgICAweDUzYmRkYjY1LCAweGU3NmZmYmU3LCAweGU5NjdmZDc4LCAweDBiYTkzNTYzLCAweDhlMzQyYmMxLCAweGU4YTExYmU5LCAweDQ5ODA3NDBkLCAweGM4MDg3ZGZjLFxuICAgIDB4OGRlNGJmOTksIDB4YTExMTAxYTAsIDB4N2ZkMzc5NzUsIDB4ZGE1YTI2YzAsIDB4ZTgxZjk5NGYsIDB4OTUyOGNkODksIDB4ZmQzMzlmZWQsIDB4Yjg3ODM0YmYsXG4gICAgMHg1ZjA0NDU2ZCwgMHgyMjI1ODY5OCwgMHhjOWM0YzgzYiwgMHgyZGMxNTZiZSwgMHg0ZjYyOGRhYSwgMHg1N2Y1NWVjNSwgMHhlMjIyMGFiZSwgMHhkMjkxNmViZixcbiAgICAweDRlYzc1Yjk1LCAweDI0ZjJjM2MwLCAweDQyZDE1ZDk5LCAweGNkMGQ3ZmEwLCAweDdiNmUyN2ZmLCAweGE4ZGM4YWYwLCAweDczNDVjMTA2LCAweGY0MWUyMzJmLFxuICAgIDB4MzUxNjIzODYsIDB4ZTZlYTg5MjYsIDB4MzMzM2IwOTQsIDB4MTU3ZWM2ZjIsIDB4MzcyYjc0YWYsIDB4NjkyNTczZTQsIDB4ZTlhOWQ4NDgsIDB4ZjMxNjAyODksXG4gICAgMHgzYTYyZWYxZCwgMHhhNzg3ZTIzOCwgMHhmM2E1ZjY3NiwgMHg3NDM2NDg1MywgMHgyMDk1MTA2MywgMHg0NTc2Njk4ZCwgMHhiNmZhZDQwNywgMHg1OTJhZjk1MCxcbiAgICAweDM2ZjczNTIzLCAweDRjZmI2ZTg3LCAweDdkYTRjZWMwLCAweDZjMTUyZGFhLCAweGNiMDM5NmE4LCAweGM1MGRmZTVkLCAweGZjZDcwN2FiLCAweDA5MjFjNDJmLFxuICAgIDB4ODlkZmYwYmIsIDB4NWZlMmJlNzgsIDB4NDQ4ZjRmMzMsIDB4NzU0NjEzYzksIDB4MmIwNWQwOGQsIDB4NDhiOWQ1ODUsIDB4ZGMwNDk0NDEsIDB4YzgwOThmOWIsXG4gICAgMHg3ZGVkZTc4NiwgMHhjMzlhMzM3MywgMHg0MjQxMDAwNSwgMHg2YTA5MTc1MSwgMHgwZWYzYzhhNiwgMHg4OTAwNzJkNiwgMHgyODIwNzY4MiwgMHhhOWE5ZjdiZSxcbiAgICAweGJmMzI2NzlkLCAweGQ0NWI1Yjc1LCAweGIzNTNmZDAwLCAweGNiYjBlMzU4LCAweDgzMGYyMjBhLCAweDFmOGZiMjE0LCAweGQzNzJjZjA4LCAweGNjM2M0YTEzLFxuICAgIDB4OGNmNjMxNjYsIDB4MDYxYzg3YmUsIDB4ODhjOThmODgsIDB4NjA2MmUzOTcsIDB4NDdjZjhlN2EsIDB4YjZjODUyODMsIDB4M2NjMmFjZmIsIDB4M2ZjMDY5NzYsXG4gICAgMHg0ZThmMDI1MiwgMHg2NGQ4MzE0ZCwgMHhkYTM4NzBlMywgMHgxZTY2NTQ1OSwgMHhjMTA5MDhmMCwgMHg1MTMwMjFhNSwgMHg2YzViNjhiNywgMHg4MjJmOGFhMCxcbiAgICAweDMwMDdjZDNlLCAweDc0NzE5ZWVmLCAweGRjODcyNjgxLCAweDA3MzM0MGQ0LCAweDdlNDMyZmQ5LCAweDBjNWVjMjQxLCAweDg4MDkyODZjLCAweGY1OTJkODkxLFxuICAgIDB4MDhhOTMwZjYsIDB4OTU3ZWYzMDUsIDB4YjdmYmZmYmQsIDB4YzI2NmU5NmYsIDB4NmZlNGFjOTgsIDB4YjE3M2VjYzAsIDB4YmM2MGI0MmEsIDB4OTUzNDk4ZGEsXG4gICAgMHhmYmExYWUxMiwgMHgyZDRiZDczNiwgMHgwZjI1ZmFhYiwgMHhhNGYzZmNlYiwgMHhlMjk2OTEyMywgMHgyNTdmMGMzZCwgMHg5MzQ4YWY0OSwgMHgzNjE0MDBiYyxcbiAgICAweGU4ODE2ZjRhLCAweDM4MTRmMjAwLCAweGEzZjk0MDQzLCAweDljN2E1NGMyLCAweGJjNzA0ZjU3LCAweGRhNDFlN2Y5LCAweGMyNWFkMzNhLCAweDU0ZjRhMDg0LFxuICAgIDB4YjE3ZjU1MDUsIDB4NTkzNTdjYmUsIDB4ZWRiZDE1YzgsIDB4N2Y5N2M1YWIsIDB4YmE1YWM3YjUsIDB4YjZmNmRlYWYsIDB4M2E0NzljM2EsIDB4NTMwMmRhMjUsXG4gICAgMHg2NTNkN2U2YSwgMHg1NDI2OGQ0OSwgMHg1MWE0NzdlYSwgMHg1MDE3ZDU1YiwgMHhkN2QyNWQ4OCwgMHg0NDEzNmM3NiwgMHgwNDA0YThjOCwgMHhiOGU1YTEyMSxcbiAgICAweGI4MWE5MjhhLCAweDYwZWQ1ODY5LCAweDk3YzU1Yjk2LCAweGVhZWM5OTFiLCAweDI5OTM1OTEzLCAweDAxZmRiN2YxLCAweDA4OGU4ZGZhLCAweDlhYjZmNmY1LFxuICAgIDB4M2I0Y2JmOWYsIDB4NGE1ZGUzYWIsIDB4ZTYwNTFkMzUsIDB4YTBlMWQ4NTUsIDB4ZDM2YjRjZjEsIDB4ZjU0NGVkZWIsIDB4YjBlOTM1MjQsIDB4YmViYjhmYmQsXG4gICAgMHhhMmQ3NjJjZiwgMHg0OWM5MmY1NCwgMHgzOGI1ZjMzMSwgMHg3MTI4YTQ1NCwgMHg0ODM5MjkwNSwgMHhhNjViMWRiOCwgMHg4NTFjOTdiZCwgMHhkNjc1Y2YyZik7XG5cbiAgc0JveFs2XSA9IG5ldyBBcnJheShcbiAgICAweDg1ZTA0MDE5LCAweDMzMmJmNTY3LCAweDY2MmRiZmZmLCAweGNmYzY1NjkzLCAweDJhOGQ3ZjZmLCAweGFiOWJjOTEyLCAweGRlNjAwOGExLCAweDIwMjhkYTFmLFxuICAgIDB4MDIyN2JjZTcsIDB4NGQ2NDI5MTYsIDB4MThmYWMzMDAsIDB4NTBmMThiODIsIDB4MmNiMmNiMTEsIDB4YjIzMmU3NWMsIDB4NGIzNjk1ZjIsIDB4YjI4NzA3ZGUsXG4gICAgMHhhMDVmYmNmNiwgMHhjZDQxODFlOSwgMHhlMTUwMjEwYywgMHhlMjRlZjFiZCwgMHhiMTY4YzM4MSwgMHhmZGU0ZTc4OSwgMHg1Yzc5YjBkOCwgMHgxZThiZmQ0MyxcbiAgICAweDRkNDk1MDAxLCAweDM4YmU0MzQxLCAweDkxM2NlZTFkLCAweDkyYTc5YzNmLCAweDA4OTc2NmJlLCAweGJhZWVhZGY0LCAweDEyODZiZWNmLCAweGI2ZWFjYjE5LFxuICAgIDB4MjY2MGMyMDAsIDB4NzU2NWJkZTQsIDB4NjQyNDFmN2EsIDB4ODI0OGRjYTksIDB4YzNiM2FkNjYsIDB4MjgxMzYwODYsIDB4MGJkOGRmYTgsIDB4MzU2ZDFjZjIsXG4gICAgMHgxMDc3ODliZSwgMHhiM2IyZTljZSwgMHgwNTAyYWE4ZiwgMHgwYmMwMzUxZSwgMHgxNjZiZjUyYSwgMHhlYjEyZmY4MiwgMHhlMzQ4NjkxMSwgMHhkMzRkNzUxNixcbiAgICAweDRlN2IzYWZmLCAweDVmNDM2NzFiLCAweDljZjZlMDM3LCAweDQ5ODFhYzgzLCAweDMzNDI2NmNlLCAweDhjOTM0MWI3LCAweGQwZDg1NGMwLCAweGNiM2E2Yzg4LFxuICAgIDB4NDdiYzI4MjksIDB4NDcyNWJhMzcsIDB4YTY2YWQyMmIsIDB4N2FkNjFmMWUsIDB4MGM1Y2JhZmEsIDB4NDQzN2YxMDcsIDB4YjZlNzk5NjIsIDB4NDJkMmQ4MTYsXG4gICAgMHgwYTk2MTI4OCwgMHhlMWE1YzA2ZSwgMHgxMzc0OWU2NywgMHg3MmZjMDgxYSwgMHhiMWQxMzlmNywgMHhmOTU4Mzc0NSwgMHhjZjE5ZGY1OCwgMHhiZWMzZjc1NixcbiAgICAweGMwNmViYTMwLCAweDA3MjExYjI0LCAweDQ1YzI4ODI5LCAweGM5NWUzMTdmLCAweGJjOGVjNTExLCAweDM4YmM0NmU5LCAweGM2ZTZmYTE0LCAweGJhZTg1ODRhLFxuICAgIDB4YWQ0ZWJjNDYsIDB4NDY4ZjUwOGIsIDB4NzgyOTQzNWYsIDB4ZjEyNDE4M2IsIDB4ODIxZGJhOWYsIDB4YWZmNjBmZjQsIDB4ZWEyYzRlNmQsIDB4MTZlMzkyNjQsXG4gICAgMHg5MjU0NGE4YiwgMHgwMDliNGZjMywgMHhhYmE2OGNlZCwgMHg5YWM5NmY3OCwgMHgwNmE1Yjc5YSwgMHhiMjg1NmU2ZSwgMHgxYWVjM2NhOSwgMHhiZTgzODY4OCxcbiAgICAweDBlMDgwNGU5LCAweDU1ZjFiZTU2LCAweGU3ZTUzNjNiLCAweGIzYTFmMjVkLCAweGY3ZGViYjg1LCAweDYxZmUwMzNjLCAweDE2NzQ2MjMzLCAweDNjMDM0YzI4LFxuICAgIDB4ZGE2ZDBjNzQsIDB4NzlhYWM1NmMsIDB4M2NlNGUxYWQsIDB4NTFmMGM4MDIsIDB4OThmOGYzNWEsIDB4MTYyNmE0OWYsIDB4ZWVkODJiMjksIDB4MWQzODJmZTMsXG4gICAgMHgwYzRmYjk5YSwgMHhiYjMyNTc3OCwgMHgzZWM2ZDk3YiwgMHg2ZTc3YTZhOSwgMHhjYjY1OGI1YywgMHhkNDUyMzBjNywgMHgyYmQxNDA4YiwgMHg2MGMwM2ViNyxcbiAgICAweGI5MDY4ZDc4LCAweGEzMzc1NGY0LCAweGY0MzBjODdkLCAweGM4YTcxMzAyLCAweGI5NmQ4YzMyLCAweGViZDRlN2JlLCAweGJlOGI5ZDJkLCAweDc5NzlmYjA2LFxuICAgIDB4ZTcyMjUzMDgsIDB4OGI3NWNmNzcsIDB4MTFlZjhkYTQsIDB4ZTA4M2M4NTgsIDB4OGQ2Yjc4NmYsIDB4NWE2MzE3YTYsIDB4ZmE1Y2Y3YTAsIDB4NWRkYTAwMzMsXG4gICAgMHhmMjhlYmZiMCwgMHhmNWI5YzMxMCwgMHhhMGVhYzI4MCwgMHgwOGI5NzY3YSwgMHhhM2Q5ZDJiMCwgMHg3OWQzNDIxNywgMHgwMjFhNzE4ZCwgMHg5YWM2MzM2YSxcbiAgICAweDI3MTFmZDYwLCAweDQzODA1MGUzLCAweDA2OTkwOGE4LCAweDNkN2ZlZGM0LCAweDgyNmQyYmVmLCAweDRlZWI4NDc2LCAweDQ4OGRjZjI1LCAweDM2YzlkNTY2LFxuICAgIDB4MjhlNzRlNDEsIDB4YzI2MTBhY2EsIDB4M2Q0OWE5Y2YsIDB4YmFlM2I5ZGYsIDB4YjY1ZjhkZTYsIDB4OTJhZWFmNjQsIDB4M2FjN2Q1ZTYsIDB4OWVhODA1MDksXG4gICAgMHhmMjJiMDE3ZCwgMHhhNDE3M2Y3MCwgMHhkZDFlMTZjMywgMHgxNWUwZDdmOSwgMHg1MGIxYjg4NywgMHgyYjlmNGZkNSwgMHg2MjVhYmE4MiwgMHg2YTAxNzk2MixcbiAgICAweDJlYzAxYjljLCAweDE1NDg4YWE5LCAweGQ3MTZlNzQwLCAweDQwMDU1YTJjLCAweDkzZDI5YTIyLCAweGUzMmRiZjlhLCAweDA1ODc0NWI5LCAweDM0NTNkYzFlLFxuICAgIDB4ZDY5OTI5NmUsIDB4NDk2Y2ZmNmYsIDB4MWM5ZjQ5ODYsIDB4ZGZlMmVkMDcsIDB4Yjg3MjQyZDEsIDB4MTlkZTdlYWUsIDB4MDUzZTU2MWEsIDB4MTVhZDZmOGMsXG4gICAgMHg2NjYyNmMxYywgMHg3MTU0YzI0YywgMHhlYTA4MmIyYSwgMHg5M2ViMjkzOSwgMHgxN2RjYjBmMCwgMHg1OGQ0ZjJhZSwgMHg5ZWEyOTRmYiwgMHg1MmNmNTY0YyxcbiAgICAweDk4ODNmZTY2LCAweDJlYzQwNTgxLCAweDc2Mzk1M2MzLCAweDAxZDY2OTJlLCAweGQzYTBjMTA4LCAweGExZTcxNjBlLCAweGU0ZjJkZmE2LCAweDY5M2VkMjg1LFxuICAgIDB4NzQ5MDQ2OTgsIDB4NGMyYjBlZGQsIDB4NGY3NTc2NTYsIDB4NWQzOTMzNzgsIDB4YTEzMjIzNGYsIDB4M2QzMjFjNWQsIDB4YzNmNWUxOTQsIDB4NGIyNjkzMDEsXG4gICAgMHhjNzlmMDIyZiwgMHgzYzk5N2U3ZSwgMHg1ZTRmOTUwNCwgMHgzZmZhZmJiZCwgMHg3NmY3YWQwZSwgMHgyOTY2OTNmNCwgMHgzZDFmY2U2ZiwgMHhjNjFlNDViZSxcbiAgICAweGQzYjVhYjM0LCAweGY3MmJmOWI3LCAweDFiMDQzNGMwLCAweDRlNzJiNTY3LCAweDU1OTJhMzNkLCAweGI1MjI5MzAxLCAweGNmZDJhODdmLCAweDYwYWViNzY3LFxuICAgIDB4MTgxNDM4NmIsIDB4MzBiY2MzM2QsIDB4MzhhMGMwN2QsIDB4ZmQxNjA2ZjIsIDB4YzM2MzUxOWIsIDB4NTg5ZGQzOTAsIDB4NTQ3OWY4ZTYsIDB4MWNiOGQ2NDcsXG4gICAgMHg5N2ZkNjFhOSwgMHhlYTc3NTlmNCwgMHgyZDU3NTM5ZCwgMHg1NjlhNThjZiwgMHhlODRlNjNhZCwgMHg0NjJlMWI3OCwgMHg2NTgwZjg3ZSwgMHhmMzgxNzkxNCxcbiAgICAweDkxZGE1NWY0LCAweDQwYTIzMGYzLCAweGQxOTg4ZjM1LCAweGI2ZTMxOGQyLCAweDNmZmE1MGJjLCAweDNkNDBmMDIxLCAweGMzYzBiZGFlLCAweDQ5NThjMjRjLFxuICAgIDB4NTE4ZjM2YjIsIDB4ODRiMWQzNzAsIDB4MGZlZGNlODMsIDB4ODc4ZGRhZGEsIDB4ZjJhMjc5YzcsIDB4OTRlMDFiZTgsIDB4OTA3MTZmNGIsIDB4OTU0YjhhYTMpO1xuXG4gIHNCb3hbN10gPSBuZXcgQXJyYXkoXG4gICAgMHhlMjE2MzAwZCwgMHhiYmRkZmZmYywgMHhhN2ViZGFiZCwgMHgzNTY0ODA5NSwgMHg3Nzg5ZjhiNywgMHhlNmMxMTIxYiwgMHgwZTI0MTYwMCwgMHgwNTJjZThiNSxcbiAgICAweDExYTljZmIwLCAweGU1OTUyZjExLCAweGVjZTc5OTBhLCAweDkzODZkMTc0LCAweDJhNDI5MzFjLCAweDc2ZTM4MTExLCAweGIxMmRlZjNhLCAweDM3ZGRkZGZjLFxuICAgIDB4ZGU5YWRlYjEsIDB4MGEwY2MzMmMsIDB4YmUxOTcwMjksIDB4ODRhMDA5NDAsIDB4YmIyNDNhMGYsIDB4YjRkMTM3Y2YsIDB4YjQ0ZTc5ZjAsIDB4MDQ5ZWVkZmQsXG4gICAgMHgwYjE1YTE1ZCwgMHg0ODBkMzE2OCwgMHg4YmJiZGU1YSwgMHg2NjlkZWQ0MiwgMHhjN2VjZTgzMSwgMHgzZjhmOTVlNywgMHg3MmRmMTkxYiwgMHg3NTgwMzMwZCxcbiAgICAweDk0MDc0MjUxLCAweDVjN2RjZGZhLCAweGFiYmU2ZDYzLCAweGFhNDAyMTY0LCAweGIzMDFkNDBhLCAweDAyZTdkMWNhLCAweDUzNTcxZGFlLCAweDdhMzE4MmEyLFxuICAgIDB4MTJhOGRkZWMsIDB4ZmRhYTMzNWQsIDB4MTc2ZjQzZTgsIDB4NzFmYjQ2ZDQsIDB4MzgxMjkwMjIsIDB4Y2U5NDlhZDQsIDB4Yjg0NzY5YWQsIDB4OTY1YmQ4NjIsXG4gICAgMHg4MmYzZDA1NSwgMHg2NmZiOTc2NywgMHgxNWI4MGI0ZSwgMHgxZDViNDdhMCwgMHg0Y2ZkZTA2ZiwgMHhjMjhlYzRiOCwgMHg1N2U4NzI2ZSwgMHg2NDdhNzhmYyxcbiAgICAweDk5ODY1ZDQ0LCAweDYwOGJkNTkzLCAweDZjMjAwZTAzLCAweDM5ZGM1ZmY2LCAweDVkMGIwMGEzLCAweGFlNjNhZmYyLCAweDdlOGJkNjMyLCAweDcwMTA4YzBjLFxuICAgIDB4YmJkMzUwNDksIDB4Mjk5OGRmMDQsIDB4OTgwY2Y0MmEsIDB4OWI2ZGY0OTEsIDB4OWU3ZWRkNTMsIDB4MDY5MTg1NDgsIDB4NThjYjdlMDcsIDB4M2I3NGVmMmUsXG4gICAgMHg1MjJmZmZiMSwgMHhkMjQ3MDhjYywgMHgxYzdlMjdjZCwgMHhhNGViMjE1YiwgMHgzY2YxZDJlMiwgMHgxOWI0N2EzOCwgMHg0MjRmNzYxOCwgMHgzNTg1NjAzOSxcbiAgICAweDlkMTdkZWU3LCAweDI3ZWIzNWU2LCAweGM5YWZmNjdiLCAweDM2YmFmNWI4LCAweDA5YzQ2N2NkLCAweGMxODkxMGIxLCAweGUxMWRiZjdiLCAweDA2Y2QxYWY4LFxuICAgIDB4NzE3MGM2MDgsIDB4MmQ1ZTMzNTQsIDB4ZDRkZTQ5NWEsIDB4NjRjNmQwMDYsIDB4YmNjMGM2MmMsIDB4M2RkMDBkYjMsIDB4NzA4ZjhmMzQsIDB4NzdkNTFiNDIsXG4gICAgMHgyNjRmNjIwZiwgMHgyNGI4ZDJiZiwgMHgxNWMxYjc5ZSwgMHg0NmE1MjU2NCwgMHhmOGQ3ZTU0ZSwgMHgzZTM3ODE2MCwgMHg3ODk1Y2RhNSwgMHg4NTljMTVhNSxcbiAgICAweGU2NDU5Nzg4LCAweGMzN2JjNzVmLCAweGRiMDdiYTBjLCAweDA2NzZhM2FiLCAweDdmMjI5YjFlLCAweDMxODQyZTdiLCAweDI0MjU5ZmQ3LCAweGY4YmVmNDcyLFxuICAgIDB4ODM1ZmZjYjgsIDB4NmRmNGMxZjIsIDB4OTZmNWIxOTUsIDB4ZmQwYWYwZmMsIDB4YjBmZTEzNGMsIDB4ZTI1MDZkM2QsIDB4NGY5YjEyZWEsIDB4ZjIxNWYyMjUsXG4gICAgMHhhMjIzNzM2ZiwgMHg5ZmI0YzQyOCwgMHgyNWQwNDk3OSwgMHgzNGM3MTNmOCwgMHhjNDYxODE4NywgMHhlYTdhNmU5OCwgMHg3Y2QxNmVmYywgMHgxNDM2ODc2YyxcbiAgICAweGYxNTQ0MTA3LCAweGJlZGVlZTE0LCAweDU2ZTlhZjI3LCAweGEwNGFhNDQxLCAweDNjZjdjODk5LCAweDkyZWNiYWU2LCAweGRkNjcwMTZkLCAweDE1MTY4MmViLFxuICAgIDB4YTg0MmVlZGYsIDB4ZmRiYTYwYjQsIDB4ZjE5MDdiNzUsIDB4MjBlMzAzMGYsIDB4MjRkOGMyOWUsIDB4ZTEzOTY3M2IsIDB4ZWZhNjNmYjgsIDB4NzE4NzMwNTQsXG4gICAgMHhiNmYyY2YzYiwgMHg5ZjMyNjQ0MiwgMHhjYjE1YTRjYywgMHhiMDFhNDUwNCwgMHhmMWU0N2Q4ZCwgMHg4NDRhMWJlNSwgMHhiYWU3ZGZkYywgMHg0MmNiZGE3MCxcbiAgICAweGNkN2RhZTBhLCAweDU3ZTg1YjdhLCAweGQ1M2Y1YWY2LCAweDIwY2Y0ZDhjLCAweGNlYTRkNDI4LCAweDc5ZDEzMGE0LCAweDM0ODZlYmZiLCAweDMzZDNjZGRjLFxuICAgIDB4Nzc4NTNiNTMsIDB4MzdlZmZjYjUsIDB4YzUwNjg3NzgsIDB4ZTU4MGIzZTYsIDB4NGU2OGI4ZjQsIDB4YzVjOGIzN2UsIDB4MGQ4MDllYTIsIDB4Mzk4ZmViN2MsXG4gICAgMHgxMzJhNGY5NCwgMHg0M2I3OTUwZSwgMHgyZmVlN2QxYywgMHgyMjM2MTNiZCwgMHhkZDA2Y2FhMiwgMHgzN2RmOTMyYiwgMHhjNDI0ODI4OSwgMHhhY2YzZWJjMyxcbiAgICAweDU3MTVmNmI3LCAweGVmMzQ3OGRkLCAweGYyNjc2MTZmLCAweGMxNDhjYmU0LCAweDkwNTI4MTVlLCAweDVlNDEwZmFiLCAweGI0OGEyNDY1LCAweDJlZGE3ZmE0LFxuICAgIDB4ZTg3YjQwZTQsIDB4ZTk4ZWEwODQsIDB4NTg4OWU5ZTEsIDB4ZWZkMzkwZmMsIDB4ZGQwN2QzNWIsIDB4ZGI0ODU2OTQsIDB4MzhkN2U1YjIsIDB4NTc3MjAxMDEsXG4gICAgMHg3MzBlZGViYywgMHg1YjY0MzExMywgMHg5NDkxN2U0ZiwgMHg1MDNjMmZiYSwgMHg2NDZmMTI4MiwgMHg3NTIzZDI0YSwgMHhlMDc3OTY5NSwgMHhmOWMxN2E4ZixcbiAgICAweDdhNWIyMTIxLCAweGQxODdiODk2LCAweDI5MjYzYTRkLCAweGJhNTEwY2RmLCAweDgxZjQ3YzlmLCAweGFkMTE2M2VkLCAweGVhN2I1OTY1LCAweDFhMDA3MjZlLFxuICAgIDB4MTE0MDMwOTIsIDB4MDBkYTZkNzcsIDB4NGEwY2RkNjEsIDB4YWQxZjQ2MDMsIDB4NjA1YmRmYjAsIDB4OWVlZGMzNjQsIDB4MjJlYmU2YTgsIDB4Y2VlN2QyOGEsXG4gICAgMHhhMGU3MzZhMCwgMHg1NTY0YTZiOSwgMHgxMDg1MzIwOSwgMHhjN2ViOGYzNywgMHgyZGU3MDVjYSwgMHg4OTUxNTcwZiwgMHhkZjA5ODIyYiwgMHhiZDY5MWE2YyxcbiAgICAweGFhMTJlNGYyLCAweDg3NDUxYzBmLCAweGUwZjZhMjdhLCAweDNhZGE0ODE5LCAweDRjZjE3NjRmLCAweDBkNzcxYzJiLCAweDY3Y2RiMTU2LCAweDM1MGQ4Mzg0LFxuICAgIDB4NTkzOGZhMGYsIDB4NDIzOTllZjMsIDB4MzY5OTdiMDcsIDB4MGU4NDA5M2QsIDB4NGFhOTNlNjEsIDB4ODM2MGQ4N2IsIDB4MWZhOThiMGMsIDB4MTE0OTM4MmMsXG4gICAgMHhlOTc2MjVhNSwgMHgwNjE0ZDFiNywgMHgwZTI1MjQ0YiwgMHgwYzc2ODM0NywgMHg1ODllOGQ4MiwgMHgwZDIwNTlkMSwgMHhhNDY2YmIxZSwgMHhmOGRhMGE4MixcbiAgICAweDA0ZjE5MTMwLCAweGJhNmU0ZWMwLCAweDk5MjY1MTY0LCAweDFlZTcyMzBkLCAweDUwYjJhZDgwLCAweGVhZWU2ODAxLCAweDhkYjJhMjgzLCAweGVhOGJmNTllKTtcblxufTtcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbmZ1bmN0aW9uIGNhc3Q1KGtleSkge1xuICB0aGlzLmNhc3Q1ID0gbmV3IG9wZW5wZ3Bfc3ltZW5jX2Nhc3Q1KCk7XG4gIHRoaXMuY2FzdDUuc2V0S2V5KHV0aWwuc3RyMmJpbihrZXkpKTtcblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaykge1xuICAgIHJldHVybiB0aGlzLmNhc3Q1LmVuY3J5cHQoYmxvY2spO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2FzdDU7XG5tb2R1bGUuZXhwb3J0cy5ibG9ja1NpemUgPSBjYXN0NS5wcm90b3R5cGUuYmxvY2tTaXplID0gODtcbm1vZHVsZS5leHBvcnRzLmtleVNpemUgPSBjYXN0NS5wcm90b3R5cGUua2V5U2l6ZSA9IDE2O1xuIiwiLy9QYXVsIFRlcm8sIEp1bHkgMjAwMVxuLy9odHRwOi8vd3d3LnRlcm8uY28udWsvZGVzL1xuLy9cbi8vT3B0aW1pc2VkIGZvciBwZXJmb3JtYW5jZSB3aXRoIGxhcmdlIGJsb2NrcyBieSBNaWNoYWVsIEhheXdvcnRoLCBOb3ZlbWJlciAyMDAxXG4vL2h0dHA6Ly93d3cubmV0ZGVhbGluZy5jb21cbi8vXG4vLyBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkhcblxuLy9USElTIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkRcbi8vQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4vL0lNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4vL0FSRSBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFXG4vL0ZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4vL0RBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTXG4vL09SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKVxuLy9IT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVFxuLy9MSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZXG4vL09VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0Zcbi8vU1VDSCBEQU1BR0UuXG5cbi8vZGVzXG4vL3RoaXMgdGFrZXMgdGhlIGtleSwgdGhlIG1lc3NhZ2UsIGFuZCB3aGV0aGVyIHRvIGVuY3J5cHQgb3IgZGVjcnlwdFxuXG5cblxuXG5mdW5jdGlvbiBkZXMoa2V5cywgbWVzc2FnZSwgZW5jcnlwdCwgbW9kZSwgaXYsIHBhZGRpbmcpIHtcbiAgLy9kZWNsYXJpbmcgdGhpcyBsb2NhbGx5IHNwZWVkcyB0aGluZ3MgdXAgYSBiaXRcbiAgdmFyIHNwZnVuY3Rpb24xID0gbmV3IEFycmF5KDB4MTAxMDQwMCwgMCwgMHgxMDAwMCwgMHgxMDEwNDA0LCAweDEwMTAwMDQsIDB4MTA0MDQsIDB4NCwgMHgxMDAwMCwgMHg0MDAsIDB4MTAxMDQwMCxcbiAgICAweDEwMTA0MDQsIDB4NDAwLCAweDEwMDA0MDQsIDB4MTAxMDAwNCwgMHgxMDAwMDAwLCAweDQsIDB4NDA0LCAweDEwMDA0MDAsIDB4MTAwMDQwMCwgMHgxMDQwMCwgMHgxMDQwMCwgMHgxMDEwMDAwLFxuICAgIDB4MTAxMDAwMCwgMHgxMDAwNDA0LCAweDEwMDA0LCAweDEwMDAwMDQsIDB4MTAwMDAwNCwgMHgxMDAwNCwgMCwgMHg0MDQsIDB4MTA0MDQsIDB4MTAwMDAwMCwgMHgxMDAwMCwgMHgxMDEwNDA0LCAweDQsXG4gICAgMHgxMDEwMDAwLCAweDEwMTA0MDAsIDB4MTAwMDAwMCwgMHgxMDAwMDAwLCAweDQwMCwgMHgxMDEwMDA0LCAweDEwMDAwLCAweDEwNDAwLCAweDEwMDAwMDQsIDB4NDAwLCAweDQsIDB4MTAwMDQwNCxcbiAgICAweDEwNDA0LCAweDEwMTA0MDQsIDB4MTAwMDQsIDB4MTAxMDAwMCwgMHgxMDAwNDA0LCAweDEwMDAwMDQsIDB4NDA0LCAweDEwNDA0LCAweDEwMTA0MDAsIDB4NDA0LCAweDEwMDA0MDAsXG4gICAgMHgxMDAwNDAwLCAwLCAweDEwMDA0LCAweDEwNDAwLCAwLCAweDEwMTAwMDQpO1xuICB2YXIgc3BmdW5jdGlvbjIgPSBuZXcgQXJyYXkoLTB4N2ZlZjdmZTAsIC0weDdmZmY4MDAwLCAweDgwMDAsIDB4MTA4MDIwLCAweDEwMDAwMCwgMHgyMCwgLTB4N2ZlZmZmZTAsIC0weDdmZmY3ZmUwLCAtXG4gICAgMHg3ZmZmZmZlMCwgLTB4N2ZlZjdmZTAsIC0weDdmZWY4MDAwLCAtMHg4MDAwMDAwMCwgLTB4N2ZmZjgwMDAsIDB4MTAwMDAwLCAweDIwLCAtMHg3ZmVmZmZlMCwgMHgxMDgwMDAsIDB4MTAwMDIwLCAtXG4gICAgMHg3ZmZmN2ZlMCwgMCwgLTB4ODAwMDAwMDAsIDB4ODAwMCwgMHgxMDgwMjAsIC0weDdmZjAwMDAwLCAweDEwMDAyMCwgLTB4N2ZmZmZmZTAsIDAsIDB4MTA4MDAwLCAweDgwMjAsIC0weDdmZWY4MDAwLCAtXG4gICAgMHg3ZmYwMDAwMCwgMHg4MDIwLCAwLCAweDEwODAyMCwgLTB4N2ZlZmZmZTAsIDB4MTAwMDAwLCAtMHg3ZmZmN2ZlMCwgLTB4N2ZmMDAwMDAsIC0weDdmZWY4MDAwLCAweDgwMDAsIC0weDdmZjAwMDAwLCAtXG4gICAgMHg3ZmZmODAwMCwgMHgyMCwgLTB4N2ZlZjdmZTAsIDB4MTA4MDIwLCAweDIwLCAweDgwMDAsIC0weDgwMDAwMDAwLCAweDgwMjAsIC0weDdmZWY4MDAwLCAweDEwMDAwMCwgLTB4N2ZmZmZmZTAsXG4gICAgMHgxMDAwMjAsIC0weDdmZmY3ZmUwLCAtMHg3ZmZmZmZlMCwgMHgxMDAwMjAsIDB4MTA4MDAwLCAwLCAtMHg3ZmZmODAwMCwgMHg4MDIwLCAtMHg4MDAwMDAwMCwgLTB4N2ZlZmZmZTAsIC1cbiAgICAweDdmZWY3ZmUwLCAweDEwODAwMCk7XG4gIHZhciBzcGZ1bmN0aW9uMyA9IG5ldyBBcnJheSgweDIwOCwgMHg4MDIwMjAwLCAwLCAweDgwMjAwMDgsIDB4ODAwMDIwMCwgMCwgMHgyMDIwOCwgMHg4MDAwMjAwLCAweDIwMDA4LCAweDgwMDAwMDgsXG4gICAgMHg4MDAwMDA4LCAweDIwMDAwLCAweDgwMjAyMDgsIDB4MjAwMDgsIDB4ODAyMDAwMCwgMHgyMDgsIDB4ODAwMDAwMCwgMHg4LCAweDgwMjAyMDAsIDB4MjAwLCAweDIwMjAwLCAweDgwMjAwMDAsXG4gICAgMHg4MDIwMDA4LCAweDIwMjA4LCAweDgwMDAyMDgsIDB4MjAyMDAsIDB4MjAwMDAsIDB4ODAwMDIwOCwgMHg4LCAweDgwMjAyMDgsIDB4MjAwLCAweDgwMDAwMDAsIDB4ODAyMDIwMCwgMHg4MDAwMDAwLFxuICAgIDB4MjAwMDgsIDB4MjA4LCAweDIwMDAwLCAweDgwMjAyMDAsIDB4ODAwMDIwMCwgMCwgMHgyMDAsIDB4MjAwMDgsIDB4ODAyMDIwOCwgMHg4MDAwMjAwLCAweDgwMDAwMDgsIDB4MjAwLCAwLFxuICAgIDB4ODAyMDAwOCwgMHg4MDAwMjA4LCAweDIwMDAwLCAweDgwMDAwMDAsIDB4ODAyMDIwOCwgMHg4LCAweDIwMjA4LCAweDIwMjAwLCAweDgwMDAwMDgsIDB4ODAyMDAwMCwgMHg4MDAwMjA4LCAweDIwOCxcbiAgICAweDgwMjAwMDAsIDB4MjAyMDgsIDB4OCwgMHg4MDIwMDA4LCAweDIwMjAwKTtcbiAgdmFyIHNwZnVuY3Rpb240ID0gbmV3IEFycmF5KDB4ODAyMDAxLCAweDIwODEsIDB4MjA4MSwgMHg4MCwgMHg4MDIwODAsIDB4ODAwMDgxLCAweDgwMDAwMSwgMHgyMDAxLCAwLCAweDgwMjAwMCxcbiAgICAweDgwMjAwMCwgMHg4MDIwODEsIDB4ODEsIDAsIDB4ODAwMDgwLCAweDgwMDAwMSwgMHgxLCAweDIwMDAsIDB4ODAwMDAwLCAweDgwMjAwMSwgMHg4MCwgMHg4MDAwMDAsIDB4MjAwMSwgMHgyMDgwLFxuICAgIDB4ODAwMDgxLCAweDEsIDB4MjA4MCwgMHg4MDAwODAsIDB4MjAwMCwgMHg4MDIwODAsIDB4ODAyMDgxLCAweDgxLCAweDgwMDA4MCwgMHg4MDAwMDEsIDB4ODAyMDAwLCAweDgwMjA4MSwgMHg4MSwgMCxcbiAgICAwLCAweDgwMjAwMCwgMHgyMDgwLCAweDgwMDA4MCwgMHg4MDAwODEsIDB4MSwgMHg4MDIwMDEsIDB4MjA4MSwgMHgyMDgxLCAweDgwLCAweDgwMjA4MSwgMHg4MSwgMHgxLCAweDIwMDAsIDB4ODAwMDAxLFxuICAgIDB4MjAwMSwgMHg4MDIwODAsIDB4ODAwMDgxLCAweDIwMDEsIDB4MjA4MCwgMHg4MDAwMDAsIDB4ODAyMDAxLCAweDgwLCAweDgwMDAwMCwgMHgyMDAwLCAweDgwMjA4MCk7XG4gIHZhciBzcGZ1bmN0aW9uNSA9IG5ldyBBcnJheSgweDEwMCwgMHgyMDgwMTAwLCAweDIwODAwMDAsIDB4NDIwMDAxMDAsIDB4ODAwMDAsIDB4MTAwLCAweDQwMDAwMDAwLCAweDIwODAwMDAsXG4gICAgMHg0MDA4MDEwMCwgMHg4MDAwMCwgMHgyMDAwMTAwLCAweDQwMDgwMTAwLCAweDQyMDAwMTAwLCAweDQyMDgwMDAwLCAweDgwMTAwLCAweDQwMDAwMDAwLCAweDIwMDAwMDAsIDB4NDAwODAwMDAsXG4gICAgMHg0MDA4MDAwMCwgMCwgMHg0MDAwMDEwMCwgMHg0MjA4MDEwMCwgMHg0MjA4MDEwMCwgMHgyMDAwMTAwLCAweDQyMDgwMDAwLCAweDQwMDAwMTAwLCAwLCAweDQyMDAwMDAwLCAweDIwODAxMDAsXG4gICAgMHgyMDAwMDAwLCAweDQyMDAwMDAwLCAweDgwMTAwLCAweDgwMDAwLCAweDQyMDAwMTAwLCAweDEwMCwgMHgyMDAwMDAwLCAweDQwMDAwMDAwLCAweDIwODAwMDAsIDB4NDIwMDAxMDAsXG4gICAgMHg0MDA4MDEwMCwgMHgyMDAwMTAwLCAweDQwMDAwMDAwLCAweDQyMDgwMDAwLCAweDIwODAxMDAsIDB4NDAwODAxMDAsIDB4MTAwLCAweDIwMDAwMDAsIDB4NDIwODAwMDAsIDB4NDIwODAxMDAsXG4gICAgMHg4MDEwMCwgMHg0MjAwMDAwMCwgMHg0MjA4MDEwMCwgMHgyMDgwMDAwLCAwLCAweDQwMDgwMDAwLCAweDQyMDAwMDAwLCAweDgwMTAwLCAweDIwMDAxMDAsIDB4NDAwMDAxMDAsIDB4ODAwMDAsIDAsXG4gICAgMHg0MDA4MDAwMCwgMHgyMDgwMTAwLCAweDQwMDAwMTAwKTtcbiAgdmFyIHNwZnVuY3Rpb242ID0gbmV3IEFycmF5KDB4MjAwMDAwMTAsIDB4MjA0MDAwMDAsIDB4NDAwMCwgMHgyMDQwNDAxMCwgMHgyMDQwMDAwMCwgMHgxMCwgMHgyMDQwNDAxMCwgMHg0MDAwMDAsXG4gICAgMHgyMDAwNDAwMCwgMHg0MDQwMTAsIDB4NDAwMDAwLCAweDIwMDAwMDEwLCAweDQwMDAxMCwgMHgyMDAwNDAwMCwgMHgyMDAwMDAwMCwgMHg0MDEwLCAwLCAweDQwMDAxMCwgMHgyMDAwNDAxMCxcbiAgICAweDQwMDAsIDB4NDA0MDAwLCAweDIwMDA0MDEwLCAweDEwLCAweDIwNDAwMDEwLCAweDIwNDAwMDEwLCAwLCAweDQwNDAxMCwgMHgyMDQwNDAwMCwgMHg0MDEwLCAweDQwNDAwMCwgMHgyMDQwNDAwMCxcbiAgICAweDIwMDAwMDAwLCAweDIwMDA0MDAwLCAweDEwLCAweDIwNDAwMDEwLCAweDQwNDAwMCwgMHgyMDQwNDAxMCwgMHg0MDAwMDAsIDB4NDAxMCwgMHgyMDAwMDAxMCwgMHg0MDAwMDAsIDB4MjAwMDQwMDAsXG4gICAgMHgyMDAwMDAwMCwgMHg0MDEwLCAweDIwMDAwMDEwLCAweDIwNDA0MDEwLCAweDQwNDAwMCwgMHgyMDQwMDAwMCwgMHg0MDQwMTAsIDB4MjA0MDQwMDAsIDAsIDB4MjA0MDAwMTAsIDB4MTAsIDB4NDAwMCxcbiAgICAweDIwNDAwMDAwLCAweDQwNDAxMCwgMHg0MDAwLCAweDQwMDAxMCwgMHgyMDAwNDAxMCwgMCwgMHgyMDQwNDAwMCwgMHgyMDAwMDAwMCwgMHg0MDAwMTAsIDB4MjAwMDQwMTApO1xuICB2YXIgc3BmdW5jdGlvbjcgPSBuZXcgQXJyYXkoMHgyMDAwMDAsIDB4NDIwMDAwMiwgMHg0MDAwODAyLCAwLCAweDgwMCwgMHg0MDAwODAyLCAweDIwMDgwMiwgMHg0MjAwODAwLCAweDQyMDA4MDIsXG4gICAgMHgyMDAwMDAsIDAsIDB4NDAwMDAwMiwgMHgyLCAweDQwMDAwMDAsIDB4NDIwMDAwMiwgMHg4MDIsIDB4NDAwMDgwMCwgMHgyMDA4MDIsIDB4MjAwMDAyLCAweDQwMDA4MDAsIDB4NDAwMDAwMixcbiAgICAweDQyMDAwMDAsIDB4NDIwMDgwMCwgMHgyMDAwMDIsIDB4NDIwMDAwMCwgMHg4MDAsIDB4ODAyLCAweDQyMDA4MDIsIDB4MjAwODAwLCAweDIsIDB4NDAwMDAwMCwgMHgyMDA4MDAsIDB4NDAwMDAwMCxcbiAgICAweDIwMDgwMCwgMHgyMDAwMDAsIDB4NDAwMDgwMiwgMHg0MDAwODAyLCAweDQyMDAwMDIsIDB4NDIwMDAwMiwgMHgyLCAweDIwMDAwMiwgMHg0MDAwMDAwLCAweDQwMDA4MDAsIDB4MjAwMDAwLFxuICAgIDB4NDIwMDgwMCwgMHg4MDIsIDB4MjAwODAyLCAweDQyMDA4MDAsIDB4ODAyLCAweDQwMDAwMDIsIDB4NDIwMDgwMiwgMHg0MjAwMDAwLCAweDIwMDgwMCwgMCwgMHgyLCAweDQyMDA4MDIsIDAsXG4gICAgMHgyMDA4MDIsIDB4NDIwMDAwMCwgMHg4MDAsIDB4NDAwMDAwMiwgMHg0MDAwODAwLCAweDgwMCwgMHgyMDAwMDIpO1xuICB2YXIgc3BmdW5jdGlvbjggPSBuZXcgQXJyYXkoMHgxMDAwMTA0MCwgMHgxMDAwLCAweDQwMDAwLCAweDEwMDQxMDQwLCAweDEwMDAwMDAwLCAweDEwMDAxMDQwLCAweDQwLCAweDEwMDAwMDAwLFxuICAgIDB4NDAwNDAsIDB4MTAwNDAwMDAsIDB4MTAwNDEwNDAsIDB4NDEwMDAsIDB4MTAwNDEwMDAsIDB4NDEwNDAsIDB4MTAwMCwgMHg0MCwgMHgxMDA0MDAwMCwgMHgxMDAwMDA0MCwgMHgxMDAwMTAwMCxcbiAgICAweDEwNDAsIDB4NDEwMDAsIDB4NDAwNDAsIDB4MTAwNDAwNDAsIDB4MTAwNDEwMDAsIDB4MTA0MCwgMCwgMCwgMHgxMDA0MDA0MCwgMHgxMDAwMDA0MCwgMHgxMDAwMTAwMCwgMHg0MTA0MCxcbiAgICAweDQwMDAwLCAweDQxMDQwLCAweDQwMDAwLCAweDEwMDQxMDAwLCAweDEwMDAsIDB4NDAsIDB4MTAwNDAwNDAsIDB4MTAwMCwgMHg0MTA0MCwgMHgxMDAwMTAwMCwgMHg0MCwgMHgxMDAwMDA0MCxcbiAgICAweDEwMDQwMDAwLCAweDEwMDQwMDQwLCAweDEwMDAwMDAwLCAweDQwMDAwLCAweDEwMDAxMDQwLCAwLCAweDEwMDQxMDQwLCAweDQwMDQwLCAweDEwMDAwMDQwLCAweDEwMDQwMDAwLCAweDEwMDAxMDAwLFxuICAgIDB4MTAwMDEwNDAsIDAsIDB4MTAwNDEwNDAsIDB4NDEwMDAsIDB4NDEwMDAsIDB4MTA0MCwgMHgxMDQwLCAweDQwMDQwLCAweDEwMDAwMDAwLCAweDEwMDQxMDAwKTtcblxuICAvL2NyZWF0ZSB0aGUgMTYgb3IgNDggc3Via2V5cyB3ZSB3aWxsIG5lZWRcbiAgdmFyIG0gPSAwLFxuICAgIGksIGosIHRlbXAsIHRlbXAyLCByaWdodDEsIHJpZ2h0MiwgbGVmdCwgcmlnaHQsIGxvb3Bpbmc7XG4gIHZhciBjYmNsZWZ0LCBjYmNsZWZ0MiwgY2JjcmlnaHQsIGNiY3JpZ2h0MlxuICB2YXIgZW5kbG9vcCwgbG9vcGluYztcbiAgdmFyIGxlbiA9IG1lc3NhZ2UubGVuZ3RoO1xuICB2YXIgY2h1bmsgPSAwO1xuICAvL3NldCB1cCB0aGUgbG9vcHMgZm9yIHNpbmdsZSBhbmQgdHJpcGxlIGRlc1xuICB2YXIgaXRlcmF0aW9ucyA9IGtleXMubGVuZ3RoID09IDMyID8gMyA6IDk7IC8vc2luZ2xlIG9yIHRyaXBsZSBkZXNcbiAgaWYgKGl0ZXJhdGlvbnMgPT0gMykge1xuICAgIGxvb3BpbmcgPSBlbmNyeXB0ID8gbmV3IEFycmF5KDAsIDMyLCAyKSA6IG5ldyBBcnJheSgzMCwgLTIsIC0yKTtcbiAgfSBlbHNlIHtcbiAgICBsb29waW5nID0gZW5jcnlwdCA/IG5ldyBBcnJheSgwLCAzMiwgMiwgNjIsIDMwLCAtMiwgNjQsIDk2LCAyKSA6IG5ldyBBcnJheSg5NCwgNjIsIC0yLCAzMiwgNjQsIDIsIDMwLCAtMiwgLTIpO1xuICB9XG5cbiAgLy9wYWQgdGhlIG1lc3NhZ2UgZGVwZW5kaW5nIG9uIHRoZSBwYWRkaW5nIHBhcmFtZXRlclxuICAvL29ubHkgYWRkIHBhZGRpbmcgaWYgZW5jcnlwdGluZyAtIG5vdGUgdGhhdCB5b3UgbmVlZCB0byB1c2UgdGhlIHNhbWUgcGFkZGluZyBvcHRpb24gZm9yIGJvdGggZW5jcnlwdCBhbmQgZGVjcnlwdFxuICBpZiAoZW5jcnlwdCkge1xuICAgIG1lc3NhZ2UgPSBkZXNfYWRkUGFkZGluZyhtZXNzYWdlLCBwYWRkaW5nKTtcbiAgICBsZW4gPSBtZXNzYWdlLmxlbmd0aDtcbiAgfVxuXG4gIC8vc3RvcmUgdGhlIHJlc3VsdCBoZXJlXG4gIHJlc3VsdCA9IFwiXCI7XG4gIHRlbXByZXN1bHQgPSBcIlwiO1xuXG4gIGlmIChtb2RlID09IDEpIHsgLy9DQkMgbW9kZVxuICAgIGNiY2xlZnQgPSAoaXYuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgMTYpIHwgKGl2LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGl2LmNoYXJDb2RlQXQobSsrKTtcbiAgICBjYmNyaWdodCA9IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgMjQpIHwgKGl2LmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAoaXYuY2hhckNvZGVBdChtKyspIDw8IDgpIHwgaXYuY2hhckNvZGVBdChtKyspO1xuICAgIG0gPSAwO1xuICB9XG5cbiAgLy9sb29wIHRocm91Z2ggZWFjaCA2NCBiaXQgY2h1bmsgb2YgdGhlIG1lc3NhZ2VcbiAgd2hpbGUgKG0gPCBsZW4pIHtcbiAgICBsZWZ0ID0gKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfCBtZXNzYWdlXG4gICAgICAuY2hhckNvZGVBdChtKyspO1xuICAgIHJpZ2h0ID0gKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfFxuICAgICAgbWVzc2FnZS5jaGFyQ29kZUF0KG0rKyk7XG5cbiAgICAvL2ZvciBDaXBoZXIgQmxvY2sgQ2hhaW5pbmcgbW9kZSwgeG9yIHRoZSBtZXNzYWdlIHdpdGggdGhlIHByZXZpb3VzIHJlc3VsdFxuICAgIGlmIChtb2RlID09IDEpIHtcbiAgICAgIGlmIChlbmNyeXB0KSB7XG4gICAgICAgIGxlZnQgXj0gY2JjbGVmdDtcbiAgICAgICAgcmlnaHQgXj0gY2JjcmlnaHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYmNsZWZ0MiA9IGNiY2xlZnQ7XG4gICAgICAgIGNiY3JpZ2h0MiA9IGNiY3JpZ2h0O1xuICAgICAgICBjYmNsZWZ0ID0gbGVmdDtcbiAgICAgICAgY2JjcmlnaHQgPSByaWdodDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvL2ZpcnN0IGVhY2ggNjQgYnV0IGNodW5rIG9mIHRoZSBtZXNzYWdlIG11c3QgYmUgcGVybXV0ZWQgYWNjb3JkaW5nIHRvIElQXG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gNCkgXiByaWdodCkgJiAweDBmMGYwZjBmO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCA0KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxNikgXiByaWdodCkgJiAweDAwMDBmZmZmO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxNik7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzO1xuICAgIGxlZnQgXj0gdGVtcDtcbiAgICByaWdodCBePSAodGVtcCA8PCAyKTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IDgpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDEpIF4gcmlnaHQpICYgMHg1NTU1NTU1NTtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgMSk7XG5cbiAgICBsZWZ0ID0gKChsZWZ0IDw8IDEpIHwgKGxlZnQgPj4+IDMxKSk7XG4gICAgcmlnaHQgPSAoKHJpZ2h0IDw8IDEpIHwgKHJpZ2h0ID4+PiAzMSkpO1xuXG4gICAgLy9kbyB0aGlzIGVpdGhlciAxIG9yIDMgdGltZXMgZm9yIGVhY2ggY2h1bmsgb2YgdGhlIG1lc3NhZ2VcbiAgICBmb3IgKGogPSAwOyBqIDwgaXRlcmF0aW9uczsgaiArPSAzKSB7XG4gICAgICBlbmRsb29wID0gbG9vcGluZ1tqICsgMV07XG4gICAgICBsb29waW5jID0gbG9vcGluZ1tqICsgMl07XG4gICAgICAvL25vdyBnbyB0aHJvdWdoIGFuZCBwZXJmb3JtIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gIFxuICAgICAgZm9yIChpID0gbG9vcGluZ1tqXTsgaSAhPSBlbmRsb29wOyBpICs9IGxvb3BpbmMpIHsgLy9mb3IgZWZmaWNpZW5jeVxuICAgICAgICByaWdodDEgPSByaWdodCBeIGtleXNbaV07XG4gICAgICAgIHJpZ2h0MiA9ICgocmlnaHQgPj4+IDQpIHwgKHJpZ2h0IDw8IDI4KSkgXiBrZXlzW2kgKyAxXTtcbiAgICAgICAgLy90aGUgcmVzdWx0IGlzIGF0dGFpbmVkIGJ5IHBhc3NpbmcgdGhlc2UgYnl0ZXMgdGhyb3VnaCB0aGUgUyBzZWxlY3Rpb24gZnVuY3Rpb25zXG4gICAgICAgIHRlbXAgPSBsZWZ0O1xuICAgICAgICBsZWZ0ID0gcmlnaHQ7XG4gICAgICAgIHJpZ2h0ID0gdGVtcCBeIChzcGZ1bmN0aW9uMlsocmlnaHQxID4+PiAyNCkgJiAweDNmXSB8IHNwZnVuY3Rpb240WyhyaWdodDEgPj4+IDE2KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjZbKHJpZ2h0MSA+Pj5cbiAgICAgICAgICA4KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjhbcmlnaHQxICYgMHgzZl0gfCBzcGZ1bmN0aW9uMVsocmlnaHQyID4+PiAyNCkgJiAweDNmXSB8IHNwZnVuY3Rpb24zWyhyaWdodDIgPj4+IDE2KSAmXG4gICAgICAgICAgMHgzZl0gfCBzcGZ1bmN0aW9uNVsocmlnaHQyID4+PiA4KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjdbcmlnaHQyICYgMHgzZl0pO1xuICAgICAgfVxuICAgICAgdGVtcCA9IGxlZnQ7XG4gICAgICBsZWZ0ID0gcmlnaHQ7XG4gICAgICByaWdodCA9IHRlbXA7IC8vdW5yZXZlcnNlIGxlZnQgYW5kIHJpZ2h0XG4gICAgfSAvL2ZvciBlaXRoZXIgMSBvciAzIGl0ZXJhdGlvbnNcblxuICAgIC8vbW92ZSB0aGVuIGVhY2ggb25lIGJpdCB0byB0aGUgcmlnaHRcbiAgICBsZWZ0ID0gKChsZWZ0ID4+PiAxKSB8IChsZWZ0IDw8IDMxKSk7XG4gICAgcmlnaHQgPSAoKHJpZ2h0ID4+PiAxKSB8IChyaWdodCA8PCAzMSkpO1xuXG4gICAgLy9ub3cgcGVyZm9ybSBJUC0xLCB3aGljaCBpcyBJUCBpbiB0aGUgb3Bwb3NpdGUgZGlyZWN0aW9uXG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1O1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxKTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IDgpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiAyKSBeIGxlZnQpICYgMHgzMzMzMzMzMztcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgMik7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMTYpIF4gcmlnaHQpICYgMHgwMDAwZmZmZjtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgMTYpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDQpIF4gcmlnaHQpICYgMHgwZjBmMGYwZjtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgNCk7XG5cbiAgICAvL2ZvciBDaXBoZXIgQmxvY2sgQ2hhaW5pbmcgbW9kZSwgeG9yIHRoZSBtZXNzYWdlIHdpdGggdGhlIHByZXZpb3VzIHJlc3VsdFxuICAgIGlmIChtb2RlID09IDEpIHtcbiAgICAgIGlmIChlbmNyeXB0KSB7XG4gICAgICAgIGNiY2xlZnQgPSBsZWZ0O1xuICAgICAgICBjYmNyaWdodCA9IHJpZ2h0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGVmdCBePSBjYmNsZWZ0MjtcbiAgICAgICAgcmlnaHQgXj0gY2JjcmlnaHQyO1xuICAgICAgfVxuICAgIH1cbiAgICB0ZW1wcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGxlZnQgPj4+IDI0KSwgKChsZWZ0ID4+PiAxNikgJiAweGZmKSwgKChsZWZ0ID4+PiA4KSAmIDB4ZmYpLCAobGVmdCAmIDB4ZmYpLCAoXG4gICAgICByaWdodCA+Pj4gMjQpLCAoKHJpZ2h0ID4+PiAxNikgJiAweGZmKSwgKChyaWdodCA+Pj4gOCkgJiAweGZmKSwgKHJpZ2h0ICYgMHhmZikpO1xuXG4gICAgY2h1bmsgKz0gODtcbiAgICBpZiAoY2h1bmsgPT0gNTEyKSB7XG4gICAgICByZXN1bHQgKz0gdGVtcHJlc3VsdDtcbiAgICAgIHRlbXByZXN1bHQgPSBcIlwiO1xuICAgICAgY2h1bmsgPSAwO1xuICAgIH1cbiAgfSAvL2ZvciBldmVyeSA4IGNoYXJhY3RlcnMsIG9yIDY0IGJpdHMgaW4gdGhlIG1lc3NhZ2VcblxuICAvL3JldHVybiB0aGUgcmVzdWx0IGFzIGFuIGFycmF5XG4gIHJlc3VsdCArPSB0ZW1wcmVzdWx0O1xuXG4gIC8vb25seSByZW1vdmUgcGFkZGluZyBpZiBkZWNyeXB0aW5nIC0gbm90ZSB0aGF0IHlvdSBuZWVkIHRvIHVzZSB0aGUgc2FtZSBwYWRkaW5nIG9wdGlvbiBmb3IgYm90aCBlbmNyeXB0IGFuZCBkZWNyeXB0XG4gIGlmICghZW5jcnlwdCkge1xuICAgIHJlc3VsdCA9IGRlc19yZW1vdmVQYWRkaW5nKHJlc3VsdCwgcGFkZGluZyk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufSAvL2VuZCBvZiBkZXNcblxuXG5cbi8vZGVzX2NyZWF0ZUtleXNcbi8vdGhpcyB0YWtlcyBhcyBpbnB1dCBhIDY0IGJpdCBrZXkgKGV2ZW4gdGhvdWdoIG9ubHkgNTYgYml0cyBhcmUgdXNlZClcbi8vYXMgYW4gYXJyYXkgb2YgMiBpbnRlZ2VycywgYW5kIHJldHVybnMgMTYgNDggYml0IGtleXNcblxuZnVuY3Rpb24gZGVzX2NyZWF0ZUtleXMoa2V5KSB7XG4gIC8vZGVjbGFyaW5nIHRoaXMgbG9jYWxseSBzcGVlZHMgdGhpbmdzIHVwIGEgYml0XG4gIHBjMmJ5dGVzMCA9IG5ldyBBcnJheSgwLCAweDQsIDB4MjAwMDAwMDAsIDB4MjAwMDAwMDQsIDB4MTAwMDAsIDB4MTAwMDQsIDB4MjAwMTAwMDAsIDB4MjAwMTAwMDQsIDB4MjAwLCAweDIwNCxcbiAgICAweDIwMDAwMjAwLCAweDIwMDAwMjA0LCAweDEwMjAwLCAweDEwMjA0LCAweDIwMDEwMjAwLCAweDIwMDEwMjA0KTtcbiAgcGMyYnl0ZXMxID0gbmV3IEFycmF5KDAsIDB4MSwgMHgxMDAwMDAsIDB4MTAwMDAxLCAweDQwMDAwMDAsIDB4NDAwMDAwMSwgMHg0MTAwMDAwLCAweDQxMDAwMDEsIDB4MTAwLCAweDEwMSwgMHgxMDAxMDAsXG4gICAgMHgxMDAxMDEsIDB4NDAwMDEwMCwgMHg0MDAwMTAxLCAweDQxMDAxMDAsIDB4NDEwMDEwMSk7XG4gIHBjMmJ5dGVzMiA9IG5ldyBBcnJheSgwLCAweDgsIDB4ODAwLCAweDgwOCwgMHgxMDAwMDAwLCAweDEwMDAwMDgsIDB4MTAwMDgwMCwgMHgxMDAwODA4LCAwLCAweDgsIDB4ODAwLCAweDgwOCxcbiAgICAweDEwMDAwMDAsIDB4MTAwMDAwOCwgMHgxMDAwODAwLCAweDEwMDA4MDgpO1xuICBwYzJieXRlczMgPSBuZXcgQXJyYXkoMCwgMHgyMDAwMDAsIDB4ODAwMDAwMCwgMHg4MjAwMDAwLCAweDIwMDAsIDB4MjAyMDAwLCAweDgwMDIwMDAsIDB4ODIwMjAwMCwgMHgyMDAwMCwgMHgyMjAwMDAsXG4gICAgMHg4MDIwMDAwLCAweDgyMjAwMDAsIDB4MjIwMDAsIDB4MjIyMDAwLCAweDgwMjIwMDAsIDB4ODIyMjAwMCk7XG4gIHBjMmJ5dGVzNCA9IG5ldyBBcnJheSgwLCAweDQwMDAwLCAweDEwLCAweDQwMDEwLCAwLCAweDQwMDAwLCAweDEwLCAweDQwMDEwLCAweDEwMDAsIDB4NDEwMDAsIDB4MTAxMCwgMHg0MTAxMCwgMHgxMDAwLFxuICAgIDB4NDEwMDAsIDB4MTAxMCwgMHg0MTAxMCk7XG4gIHBjMmJ5dGVzNSA9IG5ldyBBcnJheSgwLCAweDQwMCwgMHgyMCwgMHg0MjAsIDAsIDB4NDAwLCAweDIwLCAweDQyMCwgMHgyMDAwMDAwLCAweDIwMDA0MDAsIDB4MjAwMDAyMCwgMHgyMDAwNDIwLFxuICAgIDB4MjAwMDAwMCwgMHgyMDAwNDAwLCAweDIwMDAwMjAsIDB4MjAwMDQyMCk7XG4gIHBjMmJ5dGVzNiA9IG5ldyBBcnJheSgwLCAweDEwMDAwMDAwLCAweDgwMDAwLCAweDEwMDgwMDAwLCAweDIsIDB4MTAwMDAwMDIsIDB4ODAwMDIsIDB4MTAwODAwMDIsIDAsIDB4MTAwMDAwMDAsXG4gICAgMHg4MDAwMCwgMHgxMDA4MDAwMCwgMHgyLCAweDEwMDAwMDAyLCAweDgwMDAyLCAweDEwMDgwMDAyKTtcbiAgcGMyYnl0ZXM3ID0gbmV3IEFycmF5KDAsIDB4MTAwMDAsIDB4ODAwLCAweDEwODAwLCAweDIwMDAwMDAwLCAweDIwMDEwMDAwLCAweDIwMDAwODAwLCAweDIwMDEwODAwLCAweDIwMDAwLCAweDMwMDAwLFxuICAgIDB4MjA4MDAsIDB4MzA4MDAsIDB4MjAwMjAwMDAsIDB4MjAwMzAwMDAsIDB4MjAwMjA4MDAsIDB4MjAwMzA4MDApO1xuICBwYzJieXRlczggPSBuZXcgQXJyYXkoMCwgMHg0MDAwMCwgMCwgMHg0MDAwMCwgMHgyLCAweDQwMDAyLCAweDIsIDB4NDAwMDIsIDB4MjAwMDAwMCwgMHgyMDQwMDAwLCAweDIwMDAwMDAsIDB4MjA0MDAwMCxcbiAgICAweDIwMDAwMDIsIDB4MjA0MDAwMiwgMHgyMDAwMDAyLCAweDIwNDAwMDIpO1xuICBwYzJieXRlczkgPSBuZXcgQXJyYXkoMCwgMHgxMDAwMDAwMCwgMHg4LCAweDEwMDAwMDA4LCAwLCAweDEwMDAwMDAwLCAweDgsIDB4MTAwMDAwMDgsIDB4NDAwLCAweDEwMDAwNDAwLCAweDQwOCxcbiAgICAweDEwMDAwNDA4LCAweDQwMCwgMHgxMDAwMDQwMCwgMHg0MDgsIDB4MTAwMDA0MDgpO1xuICBwYzJieXRlczEwID0gbmV3IEFycmF5KDAsIDB4MjAsIDAsIDB4MjAsIDB4MTAwMDAwLCAweDEwMDAyMCwgMHgxMDAwMDAsIDB4MTAwMDIwLCAweDIwMDAsIDB4MjAyMCwgMHgyMDAwLCAweDIwMjAsXG4gICAgMHgxMDIwMDAsIDB4MTAyMDIwLCAweDEwMjAwMCwgMHgxMDIwMjApO1xuICBwYzJieXRlczExID0gbmV3IEFycmF5KDAsIDB4MTAwMDAwMCwgMHgyMDAsIDB4MTAwMDIwMCwgMHgyMDAwMDAsIDB4MTIwMDAwMCwgMHgyMDAyMDAsIDB4MTIwMDIwMCwgMHg0MDAwMDAwLCAweDUwMDAwMDAsXG4gICAgMHg0MDAwMjAwLCAweDUwMDAyMDAsIDB4NDIwMDAwMCwgMHg1MjAwMDAwLCAweDQyMDAyMDAsIDB4NTIwMDIwMCk7XG4gIHBjMmJ5dGVzMTIgPSBuZXcgQXJyYXkoMCwgMHgxMDAwLCAweDgwMDAwMDAsIDB4ODAwMTAwMCwgMHg4MDAwMCwgMHg4MTAwMCwgMHg4MDgwMDAwLCAweDgwODEwMDAsIDB4MTAsIDB4MTAxMCxcbiAgICAweDgwMDAwMTAsIDB4ODAwMTAxMCwgMHg4MDAxMCwgMHg4MTAxMCwgMHg4MDgwMDEwLCAweDgwODEwMTApO1xuICBwYzJieXRlczEzID0gbmV3IEFycmF5KDAsIDB4NCwgMHgxMDAsIDB4MTA0LCAwLCAweDQsIDB4MTAwLCAweDEwNCwgMHgxLCAweDUsIDB4MTAxLCAweDEwNSwgMHgxLCAweDUsIDB4MTAxLCAweDEwNSk7XG5cbiAgLy9ob3cgbWFueSBpdGVyYXRpb25zICgxIGZvciBkZXMsIDMgZm9yIHRyaXBsZSBkZXMpXG4gIHZhciBpdGVyYXRpb25zID0ga2V5Lmxlbmd0aCA+IDggPyAzIDogMTsgLy9jaGFuZ2VkIGJ5IFBhdWwgMTYvNi8yMDA3IHRvIHVzZSBUcmlwbGUgREVTIGZvciA5KyBieXRlIGtleXNcbiAgLy9zdG9yZXMgdGhlIHJldHVybiBrZXlzXG4gIHZhciBrZXlzID0gbmV3IEFycmF5KDMyICogaXRlcmF0aW9ucyk7XG4gIC8vbm93IGRlZmluZSB0aGUgbGVmdCBzaGlmdHMgd2hpY2ggbmVlZCB0byBiZSBkb25lXG4gIHZhciBzaGlmdHMgPSBuZXcgQXJyYXkoMCwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMCk7XG4gIC8vb3RoZXIgdmFyaWFibGVzXG4gIHZhciBsZWZ0dGVtcCwgcmlnaHR0ZW1wLCBtID0gMCxcbiAgICBuID0gMCxcbiAgICB0ZW1wO1xuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgaXRlcmF0aW9uczsgaisrKSB7IC8vZWl0aGVyIDEgb3IgMyBpdGVyYXRpb25zXG4gICAgbGVmdCA9IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDgpIHwga2V5LmNoYXJDb2RlQXQobSsrKTtcbiAgICByaWdodCA9IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDgpIHwga2V5LmNoYXJDb2RlQXQobSsrKTtcblxuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDQpIF4gcmlnaHQpICYgMHgwZjBmMGYwZjtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgNCk7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IC0xNikgXiBsZWZ0KSAmIDB4MDAwMGZmZmY7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IC0xNik7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMikgXiByaWdodCkgJiAweDMzMzMzMzMzO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAyKTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gLTE2KSBeIGxlZnQpICYgMHgwMDAwZmZmZjtcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgLTE2KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDEpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiA4KSBeIGxlZnQpICYgMHgwMGZmMDBmZjtcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgOCk7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1O1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxKTtcblxuICAgIC8vdGhlIHJpZ2h0IHNpZGUgbmVlZHMgdG8gYmUgc2hpZnRlZCBhbmQgdG8gZ2V0IHRoZSBsYXN0IGZvdXIgYml0cyBvZiB0aGUgbGVmdCBzaWRlXG4gICAgdGVtcCA9IChsZWZ0IDw8IDgpIHwgKChyaWdodCA+Pj4gMjApICYgMHgwMDAwMDBmMCk7XG4gICAgLy9sZWZ0IG5lZWRzIHRvIGJlIHB1dCB1cHNpZGUgZG93blxuICAgIGxlZnQgPSAocmlnaHQgPDwgMjQpIHwgKChyaWdodCA8PCA4KSAmIDB4ZmYwMDAwKSB8ICgocmlnaHQgPj4+IDgpICYgMHhmZjAwKSB8ICgocmlnaHQgPj4+IDI0KSAmIDB4ZjApO1xuICAgIHJpZ2h0ID0gdGVtcDtcblxuICAgIC8vbm93IGdvIHRocm91Z2ggYW5kIHBlcmZvcm0gdGhlc2Ugc2hpZnRzIG9uIHRoZSBsZWZ0IGFuZCByaWdodCBrZXlzXG4gICAgZm9yIChpID0gMDsgaSA8IHNoaWZ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgLy9zaGlmdCB0aGUga2V5cyBlaXRoZXIgb25lIG9yIHR3byBiaXRzIHRvIHRoZSBsZWZ0XG4gICAgICBpZiAoc2hpZnRzW2ldKSB7XG4gICAgICAgIGxlZnQgPSAobGVmdCA8PCAyKSB8IChsZWZ0ID4+PiAyNik7XG4gICAgICAgIHJpZ2h0ID0gKHJpZ2h0IDw8IDIpIHwgKHJpZ2h0ID4+PiAyNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZWZ0ID0gKGxlZnQgPDwgMSkgfCAobGVmdCA+Pj4gMjcpO1xuICAgICAgICByaWdodCA9IChyaWdodCA8PCAxKSB8IChyaWdodCA+Pj4gMjcpO1xuICAgICAgfVxuICAgICAgbGVmdCAmPSAtMHhmO1xuICAgICAgcmlnaHQgJj0gLTB4ZjtcblxuICAgICAgLy9ub3cgYXBwbHkgUEMtMiwgaW4gc3VjaCBhIHdheSB0aGF0IEUgaXMgZWFzaWVyIHdoZW4gZW5jcnlwdGluZyBvciBkZWNyeXB0aW5nXG4gICAgICAvL3RoaXMgY29udmVyc2lvbiB3aWxsIGxvb2sgbGlrZSBQQy0yIGV4Y2VwdCBvbmx5IHRoZSBsYXN0IDYgYml0cyBvZiBlYWNoIGJ5dGUgYXJlIHVzZWRcbiAgICAgIC8vcmF0aGVyIHRoYW4gNDggY29uc2VjdXRpdmUgYml0cyBhbmQgdGhlIG9yZGVyIG9mIGxpbmVzIHdpbGwgYmUgYWNjb3JkaW5nIHRvIFxuICAgICAgLy9ob3cgdGhlIFMgc2VsZWN0aW9uIGZ1bmN0aW9ucyB3aWxsIGJlIGFwcGxpZWQ6IFMyLCBTNCwgUzYsIFM4LCBTMSwgUzMsIFM1LCBTN1xuICAgICAgbGVmdHRlbXAgPSBwYzJieXRlczBbbGVmdCA+Pj4gMjhdIHwgcGMyYnl0ZXMxWyhsZWZ0ID4+PiAyNCkgJiAweGZdIHwgcGMyYnl0ZXMyWyhsZWZ0ID4+PiAyMCkgJiAweGZdIHwgcGMyYnl0ZXMzWyhcbiAgICAgICAgbGVmdCA+Pj4gMTYpICYgMHhmXSB8IHBjMmJ5dGVzNFsobGVmdCA+Pj4gMTIpICYgMHhmXSB8IHBjMmJ5dGVzNVsobGVmdCA+Pj4gOCkgJiAweGZdIHwgcGMyYnl0ZXM2WyhsZWZ0ID4+PiA0KSAmXG4gICAgICAgIDB4Zl07XG4gICAgICByaWdodHRlbXAgPSBwYzJieXRlczdbcmlnaHQgPj4+IDI4XSB8IHBjMmJ5dGVzOFsocmlnaHQgPj4+IDI0KSAmIDB4Zl0gfCBwYzJieXRlczlbKHJpZ2h0ID4+PiAyMCkgJiAweGZdIHxcbiAgICAgICAgcGMyYnl0ZXMxMFsocmlnaHQgPj4+IDE2KSAmIDB4Zl0gfCBwYzJieXRlczExWyhyaWdodCA+Pj4gMTIpICYgMHhmXSB8IHBjMmJ5dGVzMTJbKHJpZ2h0ID4+PiA4KSAmIDB4Zl0gfFxuICAgICAgICBwYzJieXRlczEzWyhyaWdodCA+Pj4gNCkgJiAweGZdO1xuICAgICAgdGVtcCA9ICgocmlnaHR0ZW1wID4+PiAxNikgXiBsZWZ0dGVtcCkgJiAweDAwMDBmZmZmO1xuICAgICAga2V5c1tuKytdID0gbGVmdHRlbXAgXiB0ZW1wO1xuICAgICAga2V5c1tuKytdID0gcmlnaHR0ZW1wIF4gKHRlbXAgPDwgMTYpO1xuICAgIH1cbiAgfSAvL2ZvciBlYWNoIGl0ZXJhdGlvbnNcbiAgLy9yZXR1cm4gdGhlIGtleXMgd2UndmUgY3JlYXRlZFxuICByZXR1cm4ga2V5cztcbn0gLy9lbmQgb2YgZGVzX2NyZWF0ZUtleXNcblxuXG5mdW5jdGlvbiBkZXNfYWRkUGFkZGluZyhtZXNzYWdlLCBwYWRkaW5nKSB7XG4gIHZhciBwYWRMZW5ndGggPSA4IC0gKG1lc3NhZ2UubGVuZ3RoICUgOCk7XG4gIGlmICgocGFkZGluZyA9PSAyKSAmJiAocGFkTGVuZ3RoIDwgOCkpIHsgLy9wYWQgdGhlIG1lc3NhZ2Ugd2l0aCBzcGFjZXNcbiAgICBtZXNzYWdlICs9IFwiICAgICAgICBcIi5zdWJzdHIoMCwgcGFkTGVuZ3RoKTtcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09IDEpIHsgLy9QS0NTNyBwYWRkaW5nXG4gICAgbWVzc2FnZSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhZExlbmd0aCwgcGFkTGVuZ3RoLCBwYWRMZW5ndGgsIHBhZExlbmd0aCwgcGFkTGVuZ3RoLCBwYWRMZW5ndGgsIHBhZExlbmd0aCxcbiAgICAgIHBhZExlbmd0aCkuc3Vic3RyKDAsIHBhZExlbmd0aCk7XG4gIH0gZWxzZSBpZiAoIXBhZGRpbmcgJiYgKHBhZExlbmd0aCA8IDgpKSB7IC8vcGFkIHRoZSBtZXNzYWdlIG91dCB3aXRoIG51bGwgYnl0ZXNcbiAgICBtZXNzYWdlICs9IFwiXFwwXFwwXFwwXFwwXFwwXFwwXFwwXFwwXCIuc3Vic3RyKDAsIHBhZExlbmd0aCk7XG4gIH1cbiAgcmV0dXJuIG1lc3NhZ2U7XG59XG5cbmZ1bmN0aW9uIGRlc19yZW1vdmVQYWRkaW5nKG1lc3NhZ2UsIHBhZGRpbmcpIHtcbiAgaWYgKHBhZGRpbmcgPT0gMikgeyAvLyBzcGFjZSBwYWRkZWRcbiAgICBtZXNzYWdlID0gbWVzc2FnZS5yZXBsYWNlKC8gKiQvZywgXCJcIik7XG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PSAxKSB7IC8vIFBLQ1M3XG4gICAgdmFyIHBhZENvdW50ID0gbWVzc2FnZS5jaGFyQ29kZUF0KG1lc3NhZ2UubGVuZ3RoIC0gMSk7XG4gICAgbWVzc2FnZSA9IG1lc3NhZ2Uuc3Vic3RyKDAsIG1lc3NhZ2UubGVuZ3RoIC0gcGFkQ291bnQpO1xuICB9IGVsc2UgaWYgKCFwYWRkaW5nKSB7IC8vIG51bGwgcGFkZGluZ1xuICAgIG1lc3NhZ2UgPSBtZXNzYWdlLnJlcGxhY2UoL1xcMCokL2csIFwiXCIpO1xuICB9XG4gIHJldHVybiBtZXNzYWdlO1xufVxuXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbmZ1bmN0aW9uIERlcyhrZXkpIHtcbiAgdGhpcy5rZXkgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDM7IGkrKykge1xuICAgIHRoaXMua2V5LnB1c2goa2V5LnN1YnN0cihpICogOCwgOCkpO1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYmxvY2spIHtcbiAgICByZXR1cm4gdXRpbC5zdHIyYmluKGRlcyhkZXNfY3JlYXRlS2V5cyh0aGlzLmtleVsyXSksXG4gICAgICBkZXMoZGVzX2NyZWF0ZUtleXModGhpcy5rZXlbMV0pLFxuICAgICAgZGVzKGRlc19jcmVhdGVLZXlzKHRoaXMua2V5WzBdKSxcbiAgICAgIHV0aWwuYmluMnN0cihibG9jayksIHRydWUsIDAsIG51bGwsIG51bGwpLFxuICAgICAgZmFsc2UsIDAsIG51bGwsIG51bGwpLCB0cnVlLCAwLCBudWxsLCBudWxsKSk7XG4gIH1cbn1cblxuRGVzLmtleVNpemUgPSBEZXMucHJvdG90eXBlLmtleVNpemUgPSAyNDtcbkRlcy5ibG9ja1NpemUgPSBEZXMucHJvdG90eXBlLmJsb2NrU2l6ZSA9IDg7XG5cbi8vIFRoaXMgaXMgXCJvcmlnaW5hbFwiIERFUyAtIERlcyBpcyBhY3R1YWxseSBUcmlwbGUgREVTLlxuLy8gVGhpcyBpcyBvbmx5IGV4cG9ydGVkIHNvIHdlIGNhbiB1bml0IHRlc3QuXG5cbmZ1bmN0aW9uIE9yaWdpbmFsRGVzKGtleSkge1xuICB0aGlzLmtleSA9IGtleTtcblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaywgcGFkZGluZykge1xuICAgIHZhciBrZXlzID0gZGVzX2NyZWF0ZUtleXModGhpcy5rZXkpO1xuICAgIHJldHVybiB1dGlsLnN0cjJiaW4oZGVzKGtleXMsIHV0aWwuYmluMnN0cihibG9jayksIHRydWUsIDAsIG51bGwsIHBhZGRpbmcpKTtcbiAgfVxuXG4gIHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKGJsb2NrLCBwYWRkaW5nKSB7XG4gICAgdmFyIGtleXMgPSBkZXNfY3JlYXRlS2V5cyh0aGlzLmtleSk7XG4gICAgcmV0dXJuIHV0aWwuc3RyMmJpbihkZXMoa2V5cywgdXRpbC5iaW4yc3RyKGJsb2NrKSwgZmFsc2UsIDAsIG51bGwsIHBhZGRpbmcpKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZGVzOiBEZXMsXG4gIG9yaWdpbmFsRGVzOiBPcmlnaW5hbERlc1xufVxuIiwidmFyIGRlc01vZHVsZSA9IHJlcXVpcmUoJy4vZGVzLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBkZXM6IGRlc01vZHVsZVsnZGVzJ10sXG4gIG9yaWdpbmFsRGVzOiBkZXNNb2R1bGVbJ29yaWdpbmFsRGVzJ10sXG4gIGNhc3Q1OiByZXF1aXJlKCcuL2Nhc3Q1LmpzJyksXG4gIHR3b2Zpc2g6IHJlcXVpcmUoJy4vdHdvZmlzaC5qcycpLFxuICBibG93ZmlzaDogcmVxdWlyZSgnLi9ibG93ZmlzaC5qcycpXG59XG5cbnZhciBhZXMgPSByZXF1aXJlKCcuL2Flcy5qcycpO1xuXG5mb3IgKHZhciBpIGluIGFlcykge1xuICBtb2R1bGUuZXhwb3J0c1snYWVzJyArIGldID0gYWVzW2ldO1xufVxuIiwiLyogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIIFxuICogXG4gKiBDaXBoZXIuanNcbiAqIEEgYmxvY2stY2lwaGVyIGFsZ29yaXRobSBpbXBsZW1lbnRhdGlvbiBvbiBKYXZhU2NyaXB0XG4gKiBTZWUgQ2lwaGVyLnJlYWRtZS50eHQgZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uXG4gKlxuICogQ29weXJpZ2h0KGMpIDIwMDkgQXRzdXNoaSBPa2EgWyBodHRwOi8vb2thLm51LyBdXG4gKiBUaGlzIHNjcmlwdCBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMR1BMXG4gKlxuICogQUNLTk9XTEVER01FTlRcbiAqXG4gKiAgICAgVGhlIG1haW4gc3Vicm91dGluZXMgYXJlIHdyaXR0ZW4gYnkgTWljaGllbCB2YW4gRXZlcmRpbmdlbi5cbiAqIFxuICogICAgIE1pY2hpZWwgdmFuIEV2ZXJkaW5nZW5cbiAqICAgICBodHRwOi8vaG9tZS52ZXJzYXRlbC5ubC9NQXZhbkV2ZXJkaW5nZW4vaW5kZXguaHRtbFxuICogXG4gKiAgICAgQWxsIHJpZ2h0cyBmb3IgdGhlc2Ugcm91dGluZXMgYXJlIHJlc2VydmVkIHRvIE1pY2hpZWwgdmFuIEV2ZXJkaW5nZW4uXG4gKlxuICovXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vTWF0aFxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbnZhciBNQVhJTlQgPSAweEZGRkZGRkZGO1xuXG5mdW5jdGlvbiByb3RiKGIsIG4pIHtcbiAgcmV0dXJuIChiIDw8IG4gfCBiID4+PiAoOCAtIG4pKSAmIDB4RkY7XG59XG5cbmZ1bmN0aW9uIHJvdHcodywgbikge1xuICByZXR1cm4gKHcgPDwgbiB8IHcgPj4+ICgzMiAtIG4pKSAmIE1BWElOVDtcbn1cblxuZnVuY3Rpb24gZ2V0VyhhLCBpKSB7XG4gIHJldHVybiBhW2ldIHwgYVtpICsgMV0gPDwgOCB8IGFbaSArIDJdIDw8IDE2IHwgYVtpICsgM10gPDwgMjQ7XG59XG5cbmZ1bmN0aW9uIHNldFcoYSwgaSwgdykge1xuICBhLnNwbGljZShpLCA0LCB3ICYgMHhGRiwgKHcgPj4+IDgpICYgMHhGRiwgKHcgPj4+IDE2KSAmIDB4RkYsICh3ID4+PiAyNCkgJiAweEZGKTtcbn1cblxuZnVuY3Rpb24gc2V0V0ludihhLCBpLCB3KSB7XG4gIGEuc3BsaWNlKGksIDQsICh3ID4+PiAyNCkgJiAweEZGLCAodyA+Pj4gMTYpICYgMHhGRiwgKHcgPj4+IDgpICYgMHhGRiwgdyAmIDB4RkYpO1xufVxuXG5mdW5jdGlvbiBnZXRCKHgsIG4pIHtcbiAgcmV0dXJuICh4ID4+PiAobiAqIDgpKSAmIDB4RkY7XG59XG5cbmZ1bmN0aW9uIGdldE5yQml0cyhpKSB7XG4gIHZhciBuID0gMDtcbiAgd2hpbGUgKGkgPiAwKSB7XG4gICAgbisrO1xuICAgIGkgPj4+PSAxO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG5mdW5jdGlvbiBnZXRNYXNrKG4pIHtcbiAgcmV0dXJuICgxIDw8IG4pIC0gMTtcbn1cblxuLy9hZGRlZCAyMDA4LzExLzEzIFhYWCBNVVNUIFVTRSBPTkUtV0FZIEhBU0ggRlVOQ1RJT04gRk9SIFNFQ1VSSVRZIFJFQVNPTlxuXG5mdW5jdGlvbiByYW5kQnl0ZSgpIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDI1Nik7XG59XG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBUd29maXNoXG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNyZWF0ZVR3b2Zpc2goKSB7XG4gIC8vXG4gIHZhciBrZXlCeXRlcyA9IG51bGw7XG4gIHZhciBkYXRhQnl0ZXMgPSBudWxsO1xuICB2YXIgZGF0YU9mZnNldCA9IC0xO1xuICAvLyB2YXIgZGF0YUxlbmd0aCA9IC0xO1xuICB2YXIgYWxnb3JpdGhtTmFtZSA9IG51bGw7XG4gIC8vIHZhciBpZHgyID0gLTE7XG4gIC8vXG5cbiAgYWxnb3JpdGhtTmFtZSA9IFwidHdvZmlzaFwiO1xuXG4gIHZhciB0ZnNLZXkgPSBbXTtcbiAgdmFyIHRmc00gPSBbXG4gICAgW10sXG4gICAgW10sXG4gICAgW10sXG4gICAgW11cbiAgXTtcblxuICBmdW5jdGlvbiB0ZnNJbml0KGtleSkge1xuICAgIGtleUJ5dGVzID0ga2V5O1xuICAgIHZhciBpLCBhLCBiLCBjLCBkLCBtZUtleSA9IFtdLFxuICAgICAgbW9LZXkgPSBbXSxcbiAgICAgIGluS2V5ID0gW107XG4gICAgdmFyIGtMZW47XG4gICAgdmFyIHNLZXkgPSBbXTtcbiAgICB2YXIgZjAxLCBmNWIsIGZlZjtcblxuICAgIHZhciBxMCA9IFtcbiAgICAgIFs4LCAxLCA3LCAxMywgNiwgMTUsIDMsIDIsIDAsIDExLCA1LCA5LCAxNCwgMTIsIDEwLCA0XSxcbiAgICAgIFsyLCA4LCAxMSwgMTMsIDE1LCA3LCA2LCAxNCwgMywgMSwgOSwgNCwgMCwgMTAsIDEyLCA1XVxuICAgIF07XG4gICAgdmFyIHExID0gW1xuICAgICAgWzE0LCAxMiwgMTEsIDgsIDEsIDIsIDMsIDUsIDE1LCA0LCAxMCwgNiwgNywgMCwgOSwgMTNdLFxuICAgICAgWzEsIDE0LCAyLCAxMSwgNCwgMTIsIDMsIDcsIDYsIDEzLCAxMCwgNSwgMTUsIDksIDAsIDhdXG4gICAgXTtcbiAgICB2YXIgcTIgPSBbXG4gICAgICBbMTEsIDEwLCA1LCAxNCwgNiwgMTMsIDksIDAsIDEyLCA4LCAxNSwgMywgMiwgNCwgNywgMV0sXG4gICAgICBbNCwgMTIsIDcsIDUsIDEsIDYsIDksIDEwLCAwLCAxNCwgMTMsIDgsIDIsIDExLCAzLCAxNV1cbiAgICBdO1xuICAgIHZhciBxMyA9IFtcbiAgICAgIFsxMywgNywgMTUsIDQsIDEsIDIsIDYsIDE0LCA5LCAxMSwgMywgMCwgOCwgNSwgMTIsIDEwXSxcbiAgICAgIFsxMSwgOSwgNSwgMSwgMTIsIDMsIDEzLCAxNCwgNiwgNCwgNywgMTUsIDIsIDAsIDgsIDEwXVxuICAgIF07XG4gICAgdmFyIHJvcjQgPSBbMCwgOCwgMSwgOSwgMiwgMTAsIDMsIDExLCA0LCAxMiwgNSwgMTMsIDYsIDE0LCA3LCAxNV07XG4gICAgdmFyIGFzaHggPSBbMCwgOSwgMiwgMTEsIDQsIDEzLCA2LCAxNSwgOCwgMSwgMTAsIDMsIDEyLCA1LCAxNCwgN107XG4gICAgdmFyIHEgPSBbXG4gICAgICBbXSxcbiAgICAgIFtdXG4gICAgXTtcbiAgICB2YXIgbSA9IFtcbiAgICAgIFtdLFxuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdXG4gICAgXTtcblxuICAgIGZ1bmN0aW9uIGZmbTViKHgpIHtcbiAgICAgIHJldHVybiB4IF4gKHggPj4gMikgXiBbMCwgOTAsIDE4MCwgMjM4XVt4ICYgM107XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmZtRWYoeCkge1xuICAgICAgcmV0dXJuIHggXiAoeCA+PiAxKSBeICh4ID4+IDIpIF4gWzAsIDIzOCwgMTgwLCA5MF1beCAmIDNdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1kc1JlbShwLCBxKSB7XG4gICAgICB2YXIgaSwgdCwgdTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHtcbiAgICAgICAgdCA9IHEgPj4+IDI0O1xuICAgICAgICBxID0gKChxIDw8IDgpICYgTUFYSU5UKSB8IHAgPj4+IDI0O1xuICAgICAgICBwID0gKHAgPDwgOCkgJiBNQVhJTlQ7XG4gICAgICAgIHUgPSB0IDw8IDE7XG4gICAgICAgIGlmICh0ICYgMTI4KSB7XG4gICAgICAgICAgdSBePSAzMzM7XG4gICAgICAgIH1cbiAgICAgICAgcSBePSB0IF4gKHUgPDwgMTYpO1xuICAgICAgICB1IF49IHQgPj4+IDE7XG4gICAgICAgIGlmICh0ICYgMSkge1xuICAgICAgICAgIHUgXj0gMTY2O1xuICAgICAgICB9XG4gICAgICAgIHEgXj0gdSA8PCAyNCB8IHUgPDwgODtcbiAgICAgIH1cbiAgICAgIHJldHVybiBxO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHFwKG4sIHgpIHtcbiAgICAgIHZhciBhLCBiLCBjLCBkO1xuICAgICAgYSA9IHggPj4gNDtcbiAgICAgIGIgPSB4ICYgMTU7XG4gICAgICBjID0gcTBbbl1bYSBeIGJdO1xuICAgICAgZCA9IHExW25dW3JvcjRbYl0gXiBhc2h4W2FdXTtcbiAgICAgIHJldHVybiBxM1tuXVtyb3I0W2RdIF4gYXNoeFtjXV0gPDwgNCB8IHEyW25dW2MgXiBkXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoRnVuKHgsIGtleSkge1xuICAgICAgdmFyIGEgPSBnZXRCKHgsIDApLFxuICAgICAgICBiID0gZ2V0Qih4LCAxKSxcbiAgICAgICAgYyA9IGdldEIoeCwgMiksXG4gICAgICAgIGQgPSBnZXRCKHgsIDMpO1xuICAgICAgc3dpdGNoIChrTGVuKSB7XG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBhID0gcVsxXVthXSBeIGdldEIoa2V5WzNdLCAwKTtcbiAgICAgICAgICBiID0gcVswXVtiXSBeIGdldEIoa2V5WzNdLCAxKTtcbiAgICAgICAgICBjID0gcVswXVtjXSBeIGdldEIoa2V5WzNdLCAyKTtcbiAgICAgICAgICBkID0gcVsxXVtkXSBeIGdldEIoa2V5WzNdLCAzKTtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihrZXlbMl0sIDApO1xuICAgICAgICAgIGIgPSBxWzFdW2JdIF4gZ2V0QihrZXlbMl0sIDEpO1xuICAgICAgICAgIGMgPSBxWzBdW2NdIF4gZ2V0QihrZXlbMl0sIDIpO1xuICAgICAgICAgIGQgPSBxWzBdW2RdIF4gZ2V0QihrZXlbMl0sIDMpO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgYSA9IHFbMF1bcVswXVthXSBeIGdldEIoa2V5WzFdLCAwKV0gXiBnZXRCKGtleVswXSwgMCk7XG4gICAgICAgICAgYiA9IHFbMF1bcVsxXVtiXSBeIGdldEIoa2V5WzFdLCAxKV0gXiBnZXRCKGtleVswXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMV1bcVswXVtjXSBeIGdldEIoa2V5WzFdLCAyKV0gXiBnZXRCKGtleVswXSwgMik7XG4gICAgICAgICAgZCA9IHFbMV1bcVsxXVtkXSBeIGdldEIoa2V5WzFdLCAzKV0gXiBnZXRCKGtleVswXSwgMyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbVswXVthXSBeIG1bMV1bYl0gXiBtWzJdW2NdIF4gbVszXVtkXTtcbiAgICB9XG5cbiAgICBrZXlCeXRlcyA9IGtleUJ5dGVzLnNsaWNlKDAsIDMyKTtcbiAgICBpID0ga2V5Qnl0ZXMubGVuZ3RoO1xuICAgIHdoaWxlIChpICE9IDE2ICYmIGkgIT0gMjQgJiYgaSAhPSAzMilcbiAgICAgIGtleUJ5dGVzW2krK10gPSAwO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGtleUJ5dGVzLmxlbmd0aDsgaSArPSA0KSB7XG4gICAgICBpbktleVtpID4+IDJdID0gZ2V0VyhrZXlCeXRlcywgaSk7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgcVswXVtpXSA9IHFwKDAsIGkpO1xuICAgICAgcVsxXVtpXSA9IHFwKDEsIGkpO1xuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcbiAgICAgIGYwMSA9IHFbMV1baV07XG4gICAgICBmNWIgPSBmZm01YihmMDEpO1xuICAgICAgZmVmID0gZmZtRWYoZjAxKTtcbiAgICAgIG1bMF1baV0gPSBmMDEgKyAoZjViIDw8IDgpICsgKGZlZiA8PCAxNikgKyAoZmVmIDw8IDI0KTtcbiAgICAgIG1bMl1baV0gPSBmNWIgKyAoZmVmIDw8IDgpICsgKGYwMSA8PCAxNikgKyAoZmVmIDw8IDI0KTtcbiAgICAgIGYwMSA9IHFbMF1baV07XG4gICAgICBmNWIgPSBmZm01YihmMDEpO1xuICAgICAgZmVmID0gZmZtRWYoZjAxKTtcbiAgICAgIG1bMV1baV0gPSBmZWYgKyAoZmVmIDw8IDgpICsgKGY1YiA8PCAxNikgKyAoZjAxIDw8IDI0KTtcbiAgICAgIG1bM11baV0gPSBmNWIgKyAoZjAxIDw8IDgpICsgKGZlZiA8PCAxNikgKyAoZjViIDw8IDI0KTtcbiAgICB9XG5cbiAgICBrTGVuID0gaW5LZXkubGVuZ3RoIC8gMjtcbiAgICBmb3IgKGkgPSAwOyBpIDwga0xlbjsgaSsrKSB7XG4gICAgICBhID0gaW5LZXlbaSArIGldO1xuICAgICAgbWVLZXlbaV0gPSBhO1xuICAgICAgYiA9IGluS2V5W2kgKyBpICsgMV07XG4gICAgICBtb0tleVtpXSA9IGI7XG4gICAgICBzS2V5W2tMZW4gLSBpIC0gMV0gPSBtZHNSZW0oYSwgYik7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCA0MDsgaSArPSAyKSB7XG4gICAgICBhID0gMHgxMDEwMTAxICogaTtcbiAgICAgIGIgPSBhICsgMHgxMDEwMTAxO1xuICAgICAgYSA9IGhGdW4oYSwgbWVLZXkpO1xuICAgICAgYiA9IHJvdHcoaEZ1bihiLCBtb0tleSksIDgpO1xuICAgICAgdGZzS2V5W2ldID0gKGEgKyBiKSAmIE1BWElOVDtcbiAgICAgIHRmc0tleVtpICsgMV0gPSByb3R3KGEgKyAyICogYiwgOSk7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgYSA9IGIgPSBjID0gZCA9IGk7XG4gICAgICBzd2l0Y2ggKGtMZW4pIHtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihzS2V5WzNdLCAwKTtcbiAgICAgICAgICBiID0gcVswXVtiXSBeIGdldEIoc0tleVszXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMF1bY10gXiBnZXRCKHNLZXlbM10sIDIpO1xuICAgICAgICAgIGQgPSBxWzFdW2RdIF4gZ2V0QihzS2V5WzNdLCAzKTtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihzS2V5WzJdLCAwKTtcbiAgICAgICAgICBiID0gcVsxXVtiXSBeIGdldEIoc0tleVsyXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMF1bY10gXiBnZXRCKHNLZXlbMl0sIDIpO1xuICAgICAgICAgIGQgPSBxWzBdW2RdIF4gZ2V0QihzS2V5WzJdLCAzKTtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHRmc01bMF1baV0gPSBtWzBdW3FbMF1bcVswXVthXSBeIGdldEIoc0tleVsxXSwgMCldIF4gZ2V0QihzS2V5WzBdLCAwKV07XG4gICAgICAgICAgdGZzTVsxXVtpXSA9IG1bMV1bcVswXVtxWzFdW2JdIF4gZ2V0QihzS2V5WzFdLCAxKV0gXiBnZXRCKHNLZXlbMF0sIDEpXTtcbiAgICAgICAgICB0ZnNNWzJdW2ldID0gbVsyXVtxWzFdW3FbMF1bY10gXiBnZXRCKHNLZXlbMV0sIDIpXSBeIGdldEIoc0tleVswXSwgMildO1xuICAgICAgICAgIHRmc01bM11baV0gPSBtWzNdW3FbMV1bcVsxXVtkXSBeIGdldEIoc0tleVsxXSwgMyldIF4gZ2V0QihzS2V5WzBdLCAzKV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdGZzRzAoeCkge1xuICAgIHJldHVybiB0ZnNNWzBdW2dldEIoeCwgMCldIF4gdGZzTVsxXVtnZXRCKHgsIDEpXSBeIHRmc01bMl1bZ2V0Qih4LCAyKV0gXiB0ZnNNWzNdW2dldEIoeCwgMyldO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRzEoeCkge1xuICAgIHJldHVybiB0ZnNNWzBdW2dldEIoeCwgMyldIF4gdGZzTVsxXVtnZXRCKHgsIDApXSBeIHRmc01bMl1bZ2V0Qih4LCAxKV0gXiB0ZnNNWzNdW2dldEIoeCwgMildO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRnJuZChyLCBibGspIHtcbiAgICB2YXIgYSA9IHRmc0cwKGJsa1swXSk7XG4gICAgdmFyIGIgPSB0ZnNHMShibGtbMV0pO1xuICAgIGJsa1syXSA9IHJvdHcoYmxrWzJdIF4gKGEgKyBiICsgdGZzS2V5WzQgKiByICsgOF0pICYgTUFYSU5ULCAzMSk7XG4gICAgYmxrWzNdID0gcm90dyhibGtbM10sIDEpIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogciArIDldKSAmIE1BWElOVDtcbiAgICBhID0gdGZzRzAoYmxrWzJdKTtcbiAgICBiID0gdGZzRzEoYmxrWzNdKTtcbiAgICBibGtbMF0gPSByb3R3KGJsa1swXSBeIChhICsgYiArIHRmc0tleVs0ICogciArIDEwXSkgJiBNQVhJTlQsIDMxKTtcbiAgICBibGtbMV0gPSByb3R3KGJsa1sxXSwgMSkgXiAoYSArIDIgKiBiICsgdGZzS2V5WzQgKiByICsgMTFdKSAmIE1BWElOVDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRmc0lybmQoaSwgYmxrKSB7XG4gICAgdmFyIGEgPSB0ZnNHMChibGtbMF0pO1xuICAgIHZhciBiID0gdGZzRzEoYmxrWzFdKTtcbiAgICBibGtbMl0gPSByb3R3KGJsa1syXSwgMSkgXiAoYSArIGIgKyB0ZnNLZXlbNCAqIGkgKyAxMF0pICYgTUFYSU5UO1xuICAgIGJsa1szXSA9IHJvdHcoYmxrWzNdIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogaSArIDExXSkgJiBNQVhJTlQsIDMxKTtcbiAgICBhID0gdGZzRzAoYmxrWzJdKTtcbiAgICBiID0gdGZzRzEoYmxrWzNdKTtcbiAgICBibGtbMF0gPSByb3R3KGJsa1swXSwgMSkgXiAoYSArIGIgKyB0ZnNLZXlbNCAqIGkgKyA4XSkgJiBNQVhJTlQ7XG4gICAgYmxrWzFdID0gcm90dyhibGtbMV0gXiAoYSArIDIgKiBiICsgdGZzS2V5WzQgKiBpICsgOV0pICYgTUFYSU5ULCAzMSk7XG4gIH1cblxuICBmdW5jdGlvbiB0ZnNDbG9zZSgpIHtcbiAgICB0ZnNLZXkgPSBbXTtcbiAgICB0ZnNNID0gW1xuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdLFxuICAgICAgW11cbiAgICBdO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRW5jcnlwdChkYXRhLCBvZmZzZXQpIHtcbiAgICBkYXRhQnl0ZXMgPSBkYXRhO1xuICAgIGRhdGFPZmZzZXQgPSBvZmZzZXQ7XG4gICAgdmFyIGJsayA9IFtnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCkgXiB0ZnNLZXlbMF0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgNCkgXiB0ZnNLZXlbMV0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCkgXiB0ZnNLZXlbMl0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIpIF4gdGZzS2V5WzNdXG4gICAgXTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IDg7IGorKykge1xuICAgICAgdGZzRnJuZChqLCBibGspO1xuICAgIH1cbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCwgYmxrWzJdIF4gdGZzS2V5WzRdKTtcbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDQsIGJsa1szXSBeIHRmc0tleVs1XSk7XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA4LCBibGtbMF0gXiB0ZnNLZXlbNl0pO1xuICAgIHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIsIGJsa1sxXSBeIHRmc0tleVs3XSk7XG4gICAgZGF0YU9mZnNldCArPSAxNjtcbiAgICByZXR1cm4gZGF0YUJ5dGVzO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRGVjcnlwdChkYXRhLCBvZmZzZXQpIHtcbiAgICBkYXRhQnl0ZXMgPSBkYXRhO1xuICAgIGRhdGFPZmZzZXQgPSBvZmZzZXQ7XG4gICAgdmFyIGJsayA9IFtnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCkgXiB0ZnNLZXlbNF0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgNCkgXiB0ZnNLZXlbNV0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCkgXiB0ZnNLZXlbNl0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIpIF4gdGZzS2V5WzddXG4gICAgXTtcbiAgICBmb3IgKHZhciBqID0gNzsgaiA+PSAwOyBqLS0pIHtcbiAgICAgIHRmc0lybmQoaiwgYmxrKTtcbiAgICB9XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQsIGJsa1syXSBeIHRmc0tleVswXSk7XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA0LCBibGtbM10gXiB0ZnNLZXlbMV0pO1xuICAgIHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCwgYmxrWzBdIF4gdGZzS2V5WzJdKTtcbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDEyLCBibGtbMV0gXiB0ZnNLZXlbM10pO1xuICAgIGRhdGFPZmZzZXQgKz0gMTY7XG4gIH1cblxuICAvLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbiAgZnVuY3Rpb24gdGZzRmluYWwoKSB7XG4gICAgcmV0dXJuIGRhdGFCeXRlcztcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJ0d29maXNoXCIsXG4gICAgYmxvY2tzaXplOiAxMjggLyA4LFxuICAgIG9wZW46IHRmc0luaXQsXG4gICAgY2xvc2U6IHRmc0Nsb3NlLFxuICAgIGVuY3J5cHQ6IHRmc0VuY3J5cHQsXG4gICAgZGVjcnlwdDogdGZzRGVjcnlwdCxcbiAgICAvLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG4gICAgZmluYWxpemU6IHRmc0ZpbmFsXG4gIH07XG59XG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbmZ1bmN0aW9uIFRGZW5jcnlwdChibG9jaywga2V5KSB7XG4gIHZhciBibG9ja19jb3B5ID0gW10uY29uY2F0KGJsb2NrKTtcbiAgdmFyIHRmID0gY3JlYXRlVHdvZmlzaCgpO1xuICB0Zi5vcGVuKHV0aWwuc3RyMmJpbihrZXkpLCAwKTtcbiAgdmFyIHJlc3VsdCA9IHRmLmVuY3J5cHQoYmxvY2tfY29weSwgMCk7XG4gIHRmLmNsb3NlKCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIFRGKGtleSkge1xuICB0aGlzLnRmID0gY3JlYXRlVHdvZmlzaCgpO1xuICB0aGlzLnRmLm9wZW4odXRpbC5zdHIyYmluKGtleSksIDApO1xuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG4gICAgcmV0dXJuIHRoaXMudGYuZW5jcnlwdChbXS5jb25jYXQoYmxvY2spLCAwKTtcbiAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gVEY7XG5tb2R1bGUuZXhwb3J0cy5rZXlTaXplID0gVEYucHJvdG90eXBlLmtleVNpemUgPSAzMjtcbm1vZHVsZS5leHBvcnRzLmJsb2NrU2l6ZSA9IFRGLnByb3RvdHlwZS5ibG9ja1NpemUgPSAxNjtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBIFxuXG4vLyBUaGUgR1BHNEJyb3dzZXJzIGNyeXB0byBpbnRlcmZhY2VcblxudmFyIHJhbmRvbSA9IHJlcXVpcmUoJy4vcmFuZG9tLmpzJyksXG4gIGNpcGhlciA9IHJlcXVpcmUoJy4vY2lwaGVyJyksXG4gIHB1YmxpY0tleSA9IHJlcXVpcmUoJy4vcHVibGljX2tleScpLFxuICB0eXBlX21waSA9IHJlcXVpcmUoJy4uL3R5cGUvbXBpLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAvKipcbiAgICogRW5jcnlwdHMgZGF0YSB1c2luZyB0aGUgc3BlY2lmaWVkIHB1YmxpYyBrZXkgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG4gICAqIGFuZCB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobS5cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEFsZ29yaXRobSB0byBiZSB1c2VkIChTZWUgUkZDNDg4MCA5LjEpXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBwdWJsaWNNUElzIEFsZ29yaXRobSBkZXBlbmRlbnQgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnNcbiAgICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpfSBkYXRhIERhdGEgdG8gYmUgZW5jcnlwdGVkIGFzIE1QSVxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3R5cGVfbXBpW119IGlmIFJTQSBhbiBvcGVucGdwX3R5cGVfbXBpOyBcbiAgICogaWYgZWxnYW1hbCBlbmNyeXB0aW9uIGFuIGFycmF5IG9mIHR3byBvcGVucGdwX3R5cGVfbXBpIGlzIHJldHVybmVkOyBvdGhlcndpc2UgbnVsbFxuICAgKi9cbiAgcHVibGljS2V5RW5jcnlwdDogZnVuY3Rpb24oYWxnbywgcHVibGljTVBJcywgZGF0YSkge1xuICAgIHZhciByZXN1bHQgPSAoZnVuY3Rpb24oKSB7XG4gICAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgICAgICBjYXNlICdyc2FfZW5jcnlwdF9zaWduJzpcbiAgICAgICAgICB2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcbiAgICAgICAgICB2YXIgbiA9IHB1YmxpY01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIGUgPSBwdWJsaWNNUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBtID0gZGF0YS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICByZXR1cm4gW3JzYS5lbmNyeXB0KG0sIGUsIG4pXTtcblxuICAgICAgICBjYXNlICdlbGdhbWFsJzpcbiAgICAgICAgICB2YXIgZWxnYW1hbCA9IG5ldyBwdWJsaWNLZXkuZWxnYW1hbCgpO1xuICAgICAgICAgIHZhciBwID0gcHVibGljTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgZyA9IHB1YmxpY01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIHkgPSBwdWJsaWNNUElzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBtID0gZGF0YS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICByZXR1cm4gZWxnYW1hbC5lbmNyeXB0KG0sIGcsIHAsIHkpO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0pKCk7XG5cbiAgICByZXR1cm4gcmVzdWx0Lm1hcChmdW5jdGlvbihibikge1xuICAgICAgdmFyIG1waSA9IG5ldyB0eXBlX21waSgpO1xuICAgICAgbXBpLmZyb21CaWdJbnRlZ2VyKGJuKTtcbiAgICAgIHJldHVybiBtcGk7XG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIGRhdGEgdXNpbmcgdGhlIHNwZWNpZmllZCBwdWJsaWMga2V5IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIG9mIHRoZSBwcml2YXRlIGtleSxcbiAgICogdGhlIHNwZWNpZmllZCBzZWNyZXRNUElzIG9mIHRoZSBwcml2YXRlIGtleSBhbmQgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBbGdvcml0aG0gdG8gYmUgdXNlZCAoU2VlIFJGQzQ4ODAgOS4xKVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gcHVibGljTVBJcyBBbGdvcml0aG0gZGVwZW5kZW50IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICAgKiBvZiB0aGUgcHVibGljIGtleSBwYXJ0IG9mIHRoZSBwcml2YXRlIGtleVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gc2VjcmV0TVBJcyBBbGdvcml0aG0gZGVwZW5kZW50IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICAgKiBvZiB0aGUgcHJpdmF0ZSBrZXkgdXNlZFxuICAgKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGl9IGRhdGEgRGF0YSB0byBiZSBlbmNyeXB0ZWQgYXMgTVBJXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfdHlwZV9tcGl9IHJldHVybnMgYSBiaWcgaW50ZWdlciBjb250YWluaW5nIHRoZSBkZWNyeXB0ZWQgZGF0YTsgb3RoZXJ3aXNlIG51bGxcbiAgICovXG5cbiAgcHVibGljS2V5RGVjcnlwdDogZnVuY3Rpb24oYWxnbywga2V5SW50ZWdlcnMsIGRhdGFJbnRlZ2Vycykge1xuICAgIHZhciBibiA9IChmdW5jdGlvbigpIHtcbiAgICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgICBjYXNlICdyc2FfZW5jcnlwdF9zaWduJzpcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgICAgICAgIHZhciByc2EgPSBuZXcgcHVibGljS2V5LnJzYSgpO1xuICAgICAgICAgIC8vIDAgYW5kIDEgYXJlIHRoZSBwdWJsaWMga2V5LlxuICAgICAgICAgIHZhciBkID0ga2V5SW50ZWdlcnNbMl0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIHAgPSBrZXlJbnRlZ2Vyc1szXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgcSA9IGtleUludGVnZXJzWzRdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciB1ID0ga2V5SW50ZWdlcnNbNV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIG0gPSBkYXRhSW50ZWdlcnNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgcmV0dXJuIHJzYS5kZWNyeXB0KG0sIGQsIHAsIHEsIHUpO1xuICAgICAgICBjYXNlICdlbGdhbWFsJzpcbiAgICAgICAgICB2YXIgZWxnYW1hbCA9IG5ldyBwdWJsaWNLZXkuZWxnYW1hbCgpO1xuICAgICAgICAgIHZhciB4ID0ga2V5SW50ZWdlcnNbM10udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIGMxID0gZGF0YUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBjMiA9IGRhdGFJbnRlZ2Vyc1sxXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgcCA9IGtleUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHJldHVybiBlbGdhbWFsLmRlY3J5cHQoYzEsIGMyLCBwLCB4KTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgdmFyIHJlc3VsdCA9IG5ldyB0eXBlX21waSgpO1xuICAgIHJlc3VsdC5mcm9tQmlnSW50ZWdlcihibik7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcblxuICAvKiogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGludGVnZXJzIGNvbXByaXNpbmcgdGhlIHByaXZhdGUga2V5IG9mIGFuIGFsZ29yaXRobVxuICAgKiBAcGFyYW0ge29wZW5wZ3AucHVibGlja2V5fSBhbGdvIFRoZSBwdWJsaWMga2V5IGFsZ29yaXRobVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBUaGUgbnVtYmVyIG9mIGludGVnZXJzLlxuICAgKi9cbiAgZ2V0UHJpdmF0ZU1waUNvdW50OiBmdW5jdGlvbihhbGdvKSB7XG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlICdyc2FfZW5jcnlwdCc6XG4gICAgICBjYXNlICdyc2FfZW5jcnlwdF9zaWduJzpcbiAgICAgIGNhc2UgJ3JzYV9zaWduJzpcbiAgICAgICAgLy8gICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBSU0Egc2VjcmV0IGtleXM6XG4gICAgICAgIC8vICAgLSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VyIChNUEkpIG9mIFJTQSBzZWNyZXQgZXhwb25lbnQgZC5cbiAgICAgICAgLy8gICAtIE1QSSBvZiBSU0Egc2VjcmV0IHByaW1lIHZhbHVlIHAuXG4gICAgICAgIC8vICAgLSBNUEkgb2YgUlNBIHNlY3JldCBwcmltZSB2YWx1ZSBxIChwIDwgcSkuXG4gICAgICAgIC8vICAgLSBNUEkgb2YgdSwgdGhlIG11bHRpcGxpY2F0aXZlIGludmVyc2Ugb2YgcCwgbW9kIHEuXG4gICAgICAgIHJldHVybiA0O1xuICAgICAgY2FzZSAnZWxnYW1hbCc6XG4gICAgICAgIC8vIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIEVsZ2FtYWwgc2VjcmV0IGtleXM6XG4gICAgICAgIC8vICAgLSBNUEkgb2YgRWxnYW1hbCBzZWNyZXQgZXhwb25lbnQgeC5cbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICBjYXNlICdkc2EnOlxuICAgICAgICAvLyBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBEU0Egc2VjcmV0IGtleXM6XG4gICAgICAgIC8vICAgLSBNUEkgb2YgRFNBIHNlY3JldCBleHBvbmVudCB4LlxuICAgICAgICByZXR1cm4gMTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBhbGdvcml0aG0nKTtcbiAgICB9XG4gIH0sXG5cbiAgZ2V0UHVibGljTXBpQ291bnQ6IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICAvLyAtIEEgc2VyaWVzIG9mIG11bHRpcHJlY2lzaW9uIGludGVnZXJzIGNvbXByaXNpbmcgdGhlIGtleSBtYXRlcmlhbDpcbiAgICAvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBwdWJsaWMga2V5czpcbiAgICAvLyAgICAgICAtIGEgbXVsdGlwcmVjaXNpb24gaW50ZWdlciAoTVBJKSBvZiBSU0EgcHVibGljIG1vZHVsdXMgbjtcbiAgICAvLyAgICAgICAtIGFuIE1QSSBvZiBSU0EgcHVibGljIGVuY3J5cHRpb24gZXhwb25lbnQgZS5cbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0X3NpZ24nOlxuICAgICAgY2FzZSAncnNhX3NpZ24nOlxuICAgICAgICByZXR1cm4gMjtcblxuICAgICAgICAvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIEVsZ2FtYWwgcHVibGljIGtleXM6XG4gICAgICAgIC8vICAgICAtIE1QSSBvZiBFbGdhbWFsIHByaW1lIHA7XG4gICAgICAgIC8vICAgICAtIE1QSSBvZiBFbGdhbWFsIGdyb3VwIGdlbmVyYXRvciBnO1xuICAgICAgICAvLyAgICAgLSBNUEkgb2YgRWxnYW1hbCBwdWJsaWMga2V5IHZhbHVlIHkgKD0gZyoqeCBtb2QgcCB3aGVyZSB4ICBpcyBzZWNyZXQpLlxuICAgICAgY2FzZSAnZWxnYW1hbCc6XG4gICAgICAgIHJldHVybiAzO1xuXG4gICAgICAgIC8vICAgQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRFNBIHB1YmxpYyBrZXlzOlxuICAgICAgICAvLyAgICAgICAtIE1QSSBvZiBEU0EgcHJpbWUgcDtcbiAgICAgICAgLy8gICAgICAgLSBNUEkgb2YgRFNBIGdyb3VwIG9yZGVyIHEgKHEgaXMgYSBwcmltZSBkaXZpc29yIG9mIHAtMSk7XG4gICAgICAgIC8vICAgICAgIC0gTVBJIG9mIERTQSBncm91cCBnZW5lcmF0b3IgZztcbiAgICAgICAgLy8gICAgICAgLSBNUEkgb2YgRFNBIHB1YmxpYy1rZXkgdmFsdWUgeSAoPSBnKip4IG1vZCBwIHdoZXJlIHggIGlzIHNlY3JldCkuXG4gICAgICBjYXNlICdkc2EnOlxuICAgICAgICByZXR1cm4gNDtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGFsZ29yaXRobS4nKTtcbiAgICB9XG4gIH0sXG5cbiAgZ2VuZXJhdGVNcGk6IGZ1bmN0aW9uKGFsZ28sIGJpdHMpIHtcbiAgICB2YXIgcmVzdWx0ID0gKGZ1bmN0aW9uKCkge1xuICAgICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICAgIGNhc2UgJ3JzYV9zaWduJzpcbiAgICAgICAgICAvL3JlbWVtYmVyIFwicHVibGljS2V5XCIgcmVmZXJzIHRvIHRoZSBjcnlwdG8vcHVibGljX2tleSBkaXJcbiAgICAgICAgICB2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcbiAgICAgICAgICB2YXIga2V5T2JqZWN0ID0gcnNhLmdlbmVyYXRlKGJpdHMsIFwiMTAwMDFcIik7XG4gICAgICAgICAgdmFyIG91dHB1dCA9IFtdO1xuICAgICAgICAgIG91dHB1dC5wdXNoKGtleU9iamVjdC5uKTtcbiAgICAgICAgICBvdXRwdXQucHVzaChrZXlPYmplY3QuZWUpO1xuICAgICAgICAgIG91dHB1dC5wdXNoKGtleU9iamVjdC5kKTtcbiAgICAgICAgICBvdXRwdXQucHVzaChrZXlPYmplY3QucCk7XG4gICAgICAgICAgb3V0cHV0LnB1c2goa2V5T2JqZWN0LnEpO1xuICAgICAgICAgIG91dHB1dC5wdXNoKGtleU9iamVjdC51KTtcbiAgICAgICAgICByZXR1cm4gb3V0cHV0O1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgYWxnb3JpdGhtIGZvciBrZXkgZ2VuZXJhdGlvbi4nKTtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgcmV0dXJuIHJlc3VsdC5tYXAoZnVuY3Rpb24oYm4pIHtcbiAgICAgIHZhciBtcGkgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICAgIG1waS5mcm9tQmlnSW50ZWdlcihibik7XG4gICAgICByZXR1cm4gbXBpO1xuICAgIH0pO1xuICB9LFxuXG5cbiAgLyoqXG4gICAqIGdlbmVyYXRlIHJhbmRvbSBieXRlIHByZWZpeCBhcyBzdHJpbmcgZm9yIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBbGdvcml0aG0gdG8gdXNlIChzZWUgUkZDNDg4MCA5LjIpXG4gICAqIEByZXR1cm4ge1N0cmluZ30gUmFuZG9tIGJ5dGVzIHdpdGggbGVuZ3RoIGVxdWFsIHRvIHRoZSBibG9ja1xuICAgKiBzaXplIG9mIHRoZSBjaXBoZXJcbiAgICovXG4gIGdldFByZWZpeFJhbmRvbTogZnVuY3Rpb24oYWxnbykge1xuICAgIHJldHVybiByYW5kb20uZ2V0UmFuZG9tQnl0ZXMoY2lwaGVyW2FsZ29dLmJsb2NrU2l6ZSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdlbmVyYXRpbmcgYSBzZXNzaW9uIGtleSBmb3IgdGhlIHNwZWNpZmllZCBzeW1tZXRyaWMgYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBbGdvcml0aG0gdG8gdXNlIChzZWUgUkZDNDg4MCA5LjIpXG4gICAqIEByZXR1cm4ge1N0cmluZ30gUmFuZG9tIGJ5dGVzIGFzIGEgc3RyaW5nIHRvIGJlIHVzZWQgYXMgYSBrZXlcbiAgICovXG4gIGdlbmVyYXRlU2Vzc2lvbktleTogZnVuY3Rpb24oYWxnbykge1xuICAgIHJldHVybiByYW5kb20uZ2V0UmFuZG9tQnl0ZXMoY2lwaGVyW2FsZ29dLmtleVNpemUpO1xuICB9LFxuXG59O1xuIiwidmFyIHNoYSA9IHJlcXVpcmUoJy4vc2hhLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtZDU6IHJlcXVpcmUoJy4vbWQ1LmpzJyksXG4gIHNoYTE6IHNoYS5zaGExLFxuICBzaGEyNTY6IHNoYS5zaGEyNTYsXG4gIHNoYTIyNDogc2hhLnNoYTIyNCxcbiAgc2hhMzg0OiBzaGEuc2hhMzg0LFxuICBzaGE1MTI6IHNoYS5zaGE1MTIsXG4gIHJpcGVtZDogcmVxdWlyZSgnLi9yaXBlLW1kLmpzJyksXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGhhc2ggb24gdGhlIHNwZWNpZmllZCBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBIYXNoIGFsZ29yaXRobSB0eXBlIChzZWUgUkZDNDg4MCA5LjQpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgaGFzaGVkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gaGFzaCB2YWx1ZVxuICAgKi9cbiAgZGlnZXN0OiBmdW5jdGlvbihhbGdvLCBkYXRhKSB7XG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIC8vIC0gTUQ1IFtIQUNdXG4gICAgICAgIHJldHVybiB0aGlzLm1kNShkYXRhKTtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gLSBTSEEtMSBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2hhMShkYXRhKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgLy8gLSBSSVBFLU1ELzE2MCBbSEFDXVxuICAgICAgICByZXR1cm4gdGhpcy5yaXBlbWQoZGF0YSk7XG4gICAgICBjYXNlIDg6XG4gICAgICAgIC8vIC0gU0hBMjU2IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gdGhpcy5zaGEyNTYoZGF0YSk7XG4gICAgICBjYXNlIDk6XG4gICAgICAgIC8vIC0gU0hBMzg0IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gdGhpcy5zaGEzODQoZGF0YSk7XG4gICAgICBjYXNlIDEwOlxuICAgICAgICAvLyAtIFNIQTUxMiBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2hhNTEyKGRhdGEpO1xuICAgICAgY2FzZSAxMTpcbiAgICAgICAgLy8gLSBTSEEyMjQgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiB0aGlzLnNoYTIyNChkYXRhKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoYXNoIGZ1bmN0aW9uLicpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgaGFzaCBzaXplIGluIGJ5dGVzIG9mIHRoZSBzcGVjaWZpZWQgaGFzaCBhbGdvcml0aG0gdHlwZVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gSGFzaCBhbGdvcml0aG0gdHlwZSAoU2VlIFJGQzQ4ODAgOS40KVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBTaXplIGluIGJ5dGVzIG9mIHRoZSByZXN1bHRpbmcgaGFzaFxuICAgKi9cbiAgZ2V0SGFzaEJ5dGVMZW5ndGg6IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgLy8gLSBNRDUgW0hBQ11cbiAgICAgICAgcmV0dXJuIDE2O1xuICAgICAgY2FzZSAyOlxuICAgICAgICAvLyAtIFNIQS0xIFtGSVBTMTgwXVxuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyAtIFJJUEUtTUQvMTYwIFtIQUNdXG4gICAgICAgIHJldHVybiAyMDtcbiAgICAgIGNhc2UgODpcbiAgICAgICAgLy8gLSBTSEEyNTYgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiAzMjtcbiAgICAgIGNhc2UgOTpcbiAgICAgICAgLy8gLSBTSEEzODQgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiA0OFxuICAgICAgY2FzZSAxMDpcbiAgICAgICAgLy8gLSBTSEE1MTIgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiA2NDtcbiAgICAgIGNhc2UgMTE6XG4gICAgICAgIC8vIC0gU0hBMjI0IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gMjg7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGFzaCBhbGdvcml0aG0uJyk7XG4gICAgfVxuICB9XG5cbn1cbiIsIi8qKlxuICogQSBmYXN0IE1ENSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTIgSm9zZXBoIE15ZXJzXG4gKiBodHRwOi8vd3d3Lm15ZXJzZGFpbHkub3JnL2pvc2VwaC9qYXZhc2NyaXB0L21kNS10ZXh0Lmh0bWxcbiAqXG4gKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlXG4gKiBhbmQgaXRzIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlcyBhbmQgd2l0aG91dFxuICogZmVlIGlzIGhlcmVieSBncmFudGVkIHByb3ZpZGVkIHRoYXQgdGhpcyBjb3B5cmlnaHQgbm90aWNlXG4gKiBhcHBlYXJzIGluIGFsbCBjb3BpZXMuXG4gKlxuICogT2YgY291cnNlLCB0aGlzIHNvZnQgaXMgcHJvdmlkZWQgXCJhcyBpc1wiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkXG4gKiB3YXJyYW50eSBvZiBhbnkga2luZC5cbiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvdXRpbC5qcycpO1xuXG5mdW5jdGlvbiBNRDUoZW50cmVlKSB7XG4gIHZhciBoZXggPSBtZDUoZW50cmVlKTtcbiAgdmFyIGJpbiA9IHV0aWwuaGV4MmJpbihoZXgpO1xuICByZXR1cm4gYmluO1xufVxuXG5mdW5jdGlvbiBtZDVjeWNsZSh4LCBrKSB7XG4gIHZhciBhID0geFswXSxcbiAgICBiID0geFsxXSxcbiAgICBjID0geFsyXSxcbiAgICBkID0geFszXTtcblxuICBhID0gZmYoYSwgYiwgYywgZCwga1swXSwgNywgLTY4MDg3NjkzNik7XG4gIGQgPSBmZihkLCBhLCBiLCBjLCBrWzFdLCAxMiwgLTM4OTU2NDU4Nik7XG4gIGMgPSBmZihjLCBkLCBhLCBiLCBrWzJdLCAxNywgNjA2MTA1ODE5KTtcbiAgYiA9IGZmKGIsIGMsIGQsIGEsIGtbM10sIDIyLCAtMTA0NDUyNTMzMCk7XG4gIGEgPSBmZihhLCBiLCBjLCBkLCBrWzRdLCA3LCAtMTc2NDE4ODk3KTtcbiAgZCA9IGZmKGQsIGEsIGIsIGMsIGtbNV0sIDEyLCAxMjAwMDgwNDI2KTtcbiAgYyA9IGZmKGMsIGQsIGEsIGIsIGtbNl0sIDE3LCAtMTQ3MzIzMTM0MSk7XG4gIGIgPSBmZihiLCBjLCBkLCBhLCBrWzddLCAyMiwgLTQ1NzA1OTgzKTtcbiAgYSA9IGZmKGEsIGIsIGMsIGQsIGtbOF0sIDcsIDE3NzAwMzU0MTYpO1xuICBkID0gZmYoZCwgYSwgYiwgYywga1s5XSwgMTIsIC0xOTU4NDE0NDE3KTtcbiAgYyA9IGZmKGMsIGQsIGEsIGIsIGtbMTBdLCAxNywgLTQyMDYzKTtcbiAgYiA9IGZmKGIsIGMsIGQsIGEsIGtbMTFdLCAyMiwgLTE5OTA0MDQxNjIpO1xuICBhID0gZmYoYSwgYiwgYywgZCwga1sxMl0sIDcsIDE4MDQ2MDM2ODIpO1xuICBkID0gZmYoZCwgYSwgYiwgYywga1sxM10sIDEyLCAtNDAzNDExMDEpO1xuICBjID0gZmYoYywgZCwgYSwgYiwga1sxNF0sIDE3LCAtMTUwMjAwMjI5MCk7XG4gIGIgPSBmZihiLCBjLCBkLCBhLCBrWzE1XSwgMjIsIDEyMzY1MzUzMjkpO1xuXG4gIGEgPSBnZyhhLCBiLCBjLCBkLCBrWzFdLCA1LCAtMTY1Nzk2NTEwKTtcbiAgZCA9IGdnKGQsIGEsIGIsIGMsIGtbNl0sIDksIC0xMDY5NTAxNjMyKTtcbiAgYyA9IGdnKGMsIGQsIGEsIGIsIGtbMTFdLCAxNCwgNjQzNzE3NzEzKTtcbiAgYiA9IGdnKGIsIGMsIGQsIGEsIGtbMF0sIDIwLCAtMzczODk3MzAyKTtcbiAgYSA9IGdnKGEsIGIsIGMsIGQsIGtbNV0sIDUsIC03MDE1NTg2OTEpO1xuICBkID0gZ2coZCwgYSwgYiwgYywga1sxMF0sIDksIDM4MDE2MDgzKTtcbiAgYyA9IGdnKGMsIGQsIGEsIGIsIGtbMTVdLCAxNCwgLTY2MDQ3ODMzNSk7XG4gIGIgPSBnZyhiLCBjLCBkLCBhLCBrWzRdLCAyMCwgLTQwNTUzNzg0OCk7XG4gIGEgPSBnZyhhLCBiLCBjLCBkLCBrWzldLCA1LCA1Njg0NDY0MzgpO1xuICBkID0gZ2coZCwgYSwgYiwgYywga1sxNF0sIDksIC0xMDE5ODAzNjkwKTtcbiAgYyA9IGdnKGMsIGQsIGEsIGIsIGtbM10sIDE0LCAtMTg3MzYzOTYxKTtcbiAgYiA9IGdnKGIsIGMsIGQsIGEsIGtbOF0sIDIwLCAxMTYzNTMxNTAxKTtcbiAgYSA9IGdnKGEsIGIsIGMsIGQsIGtbMTNdLCA1LCAtMTQ0NDY4MTQ2Nyk7XG4gIGQgPSBnZyhkLCBhLCBiLCBjLCBrWzJdLCA5LCAtNTE0MDM3ODQpO1xuICBjID0gZ2coYywgZCwgYSwgYiwga1s3XSwgMTQsIDE3MzUzMjg0NzMpO1xuICBiID0gZ2coYiwgYywgZCwgYSwga1sxMl0sIDIwLCAtMTkyNjYwNzczNCk7XG5cbiAgYSA9IGhoKGEsIGIsIGMsIGQsIGtbNV0sIDQsIC0zNzg1NTgpO1xuICBkID0gaGgoZCwgYSwgYiwgYywga1s4XSwgMTEsIC0yMDIyNTc0NDYzKTtcbiAgYyA9IGhoKGMsIGQsIGEsIGIsIGtbMTFdLCAxNiwgMTgzOTAzMDU2Mik7XG4gIGIgPSBoaChiLCBjLCBkLCBhLCBrWzE0XSwgMjMsIC0zNTMwOTU1Nik7XG4gIGEgPSBoaChhLCBiLCBjLCBkLCBrWzFdLCA0LCAtMTUzMDk5MjA2MCk7XG4gIGQgPSBoaChkLCBhLCBiLCBjLCBrWzRdLCAxMSwgMTI3Mjg5MzM1Myk7XG4gIGMgPSBoaChjLCBkLCBhLCBiLCBrWzddLCAxNiwgLTE1NTQ5NzYzMik7XG4gIGIgPSBoaChiLCBjLCBkLCBhLCBrWzEwXSwgMjMsIC0xMDk0NzMwNjQwKTtcbiAgYSA9IGhoKGEsIGIsIGMsIGQsIGtbMTNdLCA0LCA2ODEyNzkxNzQpO1xuICBkID0gaGgoZCwgYSwgYiwgYywga1swXSwgMTEsIC0zNTg1MzcyMjIpO1xuICBjID0gaGgoYywgZCwgYSwgYiwga1szXSwgMTYsIC03MjI1MjE5NzkpO1xuICBiID0gaGgoYiwgYywgZCwgYSwga1s2XSwgMjMsIDc2MDI5MTg5KTtcbiAgYSA9IGhoKGEsIGIsIGMsIGQsIGtbOV0sIDQsIC02NDAzNjQ0ODcpO1xuICBkID0gaGgoZCwgYSwgYiwgYywga1sxMl0sIDExLCAtNDIxODE1ODM1KTtcbiAgYyA9IGhoKGMsIGQsIGEsIGIsIGtbMTVdLCAxNiwgNTMwNzQyNTIwKTtcbiAgYiA9IGhoKGIsIGMsIGQsIGEsIGtbMl0sIDIzLCAtOTk1MzM4NjUxKTtcblxuICBhID0gaWkoYSwgYiwgYywgZCwga1swXSwgNiwgLTE5ODYzMDg0NCk7XG4gIGQgPSBpaShkLCBhLCBiLCBjLCBrWzddLCAxMCwgMTEyNjg5MTQxNSk7XG4gIGMgPSBpaShjLCBkLCBhLCBiLCBrWzE0XSwgMTUsIC0xNDE2MzU0OTA1KTtcbiAgYiA9IGlpKGIsIGMsIGQsIGEsIGtbNV0sIDIxLCAtNTc0MzQwNTUpO1xuICBhID0gaWkoYSwgYiwgYywgZCwga1sxMl0sIDYsIDE3MDA0ODU1NzEpO1xuICBkID0gaWkoZCwgYSwgYiwgYywga1szXSwgMTAsIC0xODk0OTg2NjA2KTtcbiAgYyA9IGlpKGMsIGQsIGEsIGIsIGtbMTBdLCAxNSwgLTEwNTE1MjMpO1xuICBiID0gaWkoYiwgYywgZCwgYSwga1sxXSwgMjEsIC0yMDU0OTIyNzk5KTtcbiAgYSA9IGlpKGEsIGIsIGMsIGQsIGtbOF0sIDYsIDE4NzMzMTMzNTkpO1xuICBkID0gaWkoZCwgYSwgYiwgYywga1sxNV0sIDEwLCAtMzA2MTE3NDQpO1xuICBjID0gaWkoYywgZCwgYSwgYiwga1s2XSwgMTUsIC0xNTYwMTk4MzgwKTtcbiAgYiA9IGlpKGIsIGMsIGQsIGEsIGtbMTNdLCAyMSwgMTMwOTE1MTY0OSk7XG4gIGEgPSBpaShhLCBiLCBjLCBkLCBrWzRdLCA2LCAtMTQ1NTIzMDcwKTtcbiAgZCA9IGlpKGQsIGEsIGIsIGMsIGtbMTFdLCAxMCwgLTExMjAyMTAzNzkpO1xuICBjID0gaWkoYywgZCwgYSwgYiwga1syXSwgMTUsIDcxODc4NzI1OSk7XG4gIGIgPSBpaShiLCBjLCBkLCBhLCBrWzldLCAyMSwgLTM0MzQ4NTU1MSk7XG5cbiAgeFswXSA9IGFkZDMyKGEsIHhbMF0pO1xuICB4WzFdID0gYWRkMzIoYiwgeFsxXSk7XG4gIHhbMl0gPSBhZGQzMihjLCB4WzJdKTtcbiAgeFszXSA9IGFkZDMyKGQsIHhbM10pO1xuXG59XG5cbmZ1bmN0aW9uIGNtbihxLCBhLCBiLCB4LCBzLCB0KSB7XG4gIGEgPSBhZGQzMihhZGQzMihhLCBxKSwgYWRkMzIoeCwgdCkpO1xuICByZXR1cm4gYWRkMzIoKGEgPDwgcykgfCAoYSA+Pj4gKDMyIC0gcykpLCBiKTtcbn1cblxuZnVuY3Rpb24gZmYoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gY21uKChiICYgYykgfCAoKH5iKSAmIGQpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gZ2coYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gY21uKChiICYgZCkgfCAoYyAmICh+ZCkpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gaGgoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gY21uKGIgXiBjIF4gZCwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIGlpKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIGNtbihjIF4gKGIgfCAofmQpKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIG1kNTEocykge1xuICB0eHQgPSAnJztcbiAgdmFyIG4gPSBzLmxlbmd0aCxcbiAgICBzdGF0ZSA9IFsxNzMyNTg0MTkzLCAtMjcxNzMzODc5LCAtMTczMjU4NDE5NCwgMjcxNzMzODc4XSxcbiAgICBpO1xuICBmb3IgKGkgPSA2NDsgaSA8PSBzLmxlbmd0aDsgaSArPSA2NCkge1xuICAgIG1kNWN5Y2xlKHN0YXRlLCBtZDVibGsocy5zdWJzdHJpbmcoaSAtIDY0LCBpKSkpO1xuICB9XG4gIHMgPSBzLnN1YnN0cmluZyhpIC0gNjQpO1xuICB2YXIgdGFpbCA9IFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXTtcbiAgZm9yIChpID0gMDsgaSA8IHMubGVuZ3RoOyBpKyspXG4gICAgdGFpbFtpID4+IDJdIHw9IHMuY2hhckNvZGVBdChpKSA8PCAoKGkgJSA0KSA8PCAzKTtcbiAgdGFpbFtpID4+IDJdIHw9IDB4ODAgPDwgKChpICUgNCkgPDwgMyk7XG4gIGlmIChpID4gNTUpIHtcbiAgICBtZDVjeWNsZShzdGF0ZSwgdGFpbCk7XG4gICAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIHRhaWxbaV0gPSAwO1xuICB9XG4gIHRhaWxbMTRdID0gbiAqIDg7XG4gIG1kNWN5Y2xlKHN0YXRlLCB0YWlsKTtcbiAgcmV0dXJuIHN0YXRlO1xufVxuXG4vKiB0aGVyZSBuZWVkcyB0byBiZSBzdXBwb3J0IGZvciBVbmljb2RlIGhlcmUsXG4gKiB1bmxlc3Mgd2UgcHJldGVuZCB0aGF0IHdlIGNhbiByZWRlZmluZSB0aGUgTUQtNVxuICogYWxnb3JpdGhtIGZvciBtdWx0aS1ieXRlIGNoYXJhY3RlcnMgKHBlcmhhcHNcbiAqIGJ5IGFkZGluZyBldmVyeSBmb3VyIDE2LWJpdCBjaGFyYWN0ZXJzIGFuZFxuICogc2hvcnRlbmluZyB0aGUgc3VtIHRvIDMyIGJpdHMpLiBPdGhlcndpc2VcbiAqIEkgc3VnZ2VzdCBwZXJmb3JtaW5nIE1ELTUgYXMgaWYgZXZlcnkgY2hhcmFjdGVyXG4gKiB3YXMgdHdvIGJ5dGVzLS1lLmcuLCAwMDQwIDAwMjUgPSBAJS0tYnV0IHRoZW5cbiAqIGhvdyB3aWxsIGFuIG9yZGluYXJ5IE1ELTUgc3VtIGJlIG1hdGNoZWQ/XG4gKiBUaGVyZSBpcyBubyB3YXkgdG8gc3RhbmRhcmRpemUgdGV4dCB0byBzb21ldGhpbmdcbiAqIGxpa2UgVVRGLTggYmVmb3JlIHRyYW5zZm9ybWF0aW9uOyBzcGVlZCBjb3N0IGlzXG4gKiB1dHRlcmx5IHByb2hpYml0aXZlLiBUaGUgSmF2YVNjcmlwdCBzdGFuZGFyZFxuICogaXRzZWxmIG5lZWRzIHRvIGxvb2sgYXQgdGhpczogaXQgc2hvdWxkIHN0YXJ0XG4gKiBwcm92aWRpbmcgYWNjZXNzIHRvIHN0cmluZ3MgYXMgcHJlZm9ybWVkIFVURi04XG4gKiA4LWJpdCB1bnNpZ25lZCB2YWx1ZSBhcnJheXMuXG4gKi9cbmZ1bmN0aW9uIG1kNWJsayhzKSB7IC8qIEkgZmlndXJlZCBnbG9iYWwgd2FzIGZhc3Rlci4gICAqL1xuICB2YXIgbWQ1YmxrcyA9IFtdLFxuICAgIGk7IC8qIEFuZHkgS2luZyBzYWlkIGRvIGl0IHRoaXMgd2F5LiAqL1xuICBmb3IgKGkgPSAwOyBpIDwgNjQ7IGkgKz0gNCkge1xuICAgIG1kNWJsa3NbaSA+PiAyXSA9IHMuY2hhckNvZGVBdChpKSArIChzLmNoYXJDb2RlQXQoaSArIDEpIDw8IDgpICsgKHMuY2hhckNvZGVBdChpICsgMikgPDwgMTYpICsgKHMuY2hhckNvZGVBdChpICsgMykgPDxcbiAgICAgIDI0KTtcbiAgfVxuICByZXR1cm4gbWQ1Ymxrcztcbn1cblxudmFyIGhleF9jaHIgPSAnMDEyMzQ1Njc4OWFiY2RlZicuc3BsaXQoJycpO1xuXG5mdW5jdGlvbiByaGV4KG4pIHtcbiAgdmFyIHMgPSAnJyxcbiAgICBqID0gMDtcbiAgZm9yICg7IGogPCA0OyBqKyspXG4gICAgcyArPSBoZXhfY2hyWyhuID4+IChqICogOCArIDQpKSAmIDB4MEZdICsgaGV4X2NoclsobiA+PiAoaiAqIDgpKSAmIDB4MEZdO1xuICByZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gaGV4KHgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKVxuICAgIHhbaV0gPSByaGV4KHhbaV0pO1xuICByZXR1cm4geC5qb2luKCcnKTtcbn1cblxuZnVuY3Rpb24gbWQ1KHMpIHtcbiAgcmV0dXJuIGhleChtZDUxKHMpKTtcbn1cblxuLyogdGhpcyBmdW5jdGlvbiBpcyBtdWNoIGZhc3RlcixcbnNvIGlmIHBvc3NpYmxlIHdlIHVzZSBpdC4gU29tZSBJRXNcbmFyZSB0aGUgb25seSBvbmVzIEkga25vdyBvZiB0aGF0XG5uZWVkIHRoZSBpZGlvdGljIHNlY29uZCBmdW5jdGlvbixcbmdlbmVyYXRlZCBieSBhbiBpZiBjbGF1c2UuICAqL1xuXG5mdW5jdGlvbiBhZGQzMihhLCBiKSB7XG4gIHJldHVybiAoYSArIGIpICYgMHhGRkZGRkZGRjtcbn1cblxuaWYgKG1kNSgnaGVsbG8nKSAhPSAnNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTInKSB7XG4gIGZ1bmN0aW9uIGFkZDMyKHgsIHkpIHtcbiAgICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpLFxuICAgICAgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG4gICAgcmV0dXJuIChtc3cgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBNRDVcbiIsIi8qXG4gKiBDcnlwdG9NWCBUb29sc1xuICogQ29weXJpZ2h0IChDKSAyMDA0IC0gMjAwNiBEZXJlayBCdWl0ZW5odWlzXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyXG4gKiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3LCBVU0EuXG4gKi9cblxuLyogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIXG4gKi9cblxudmFyIFJNRHNpemUgPSAxNjA7XG52YXIgWCA9IG5ldyBBcnJheSgpO1xuXG5mdW5jdGlvbiBST0woeCwgbikge1xuICByZXR1cm4gbmV3IE51bWJlcigoeCA8PCBuKSB8ICh4ID4+PiAoMzIgLSBuKSkpO1xufVxuXG5mdW5jdGlvbiBGKHgsIHksIHopIHtcbiAgcmV0dXJuIG5ldyBOdW1iZXIoeCBeIHkgXiB6KTtcbn1cblxuZnVuY3Rpb24gRyh4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgTnVtYmVyKCh4ICYgeSkgfCAofnggJiB6KSk7XG59XG5cbmZ1bmN0aW9uIEgoeCwgeSwgeikge1xuICByZXR1cm4gbmV3IE51bWJlcigoeCB8IH55KSBeIHopO1xufVxuXG5mdW5jdGlvbiBJKHgsIHksIHopIHtcbiAgcmV0dXJuIG5ldyBOdW1iZXIoKHggJiB6KSB8ICh5ICYgfnopKTtcbn1cblxuZnVuY3Rpb24gSih4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgTnVtYmVyKHggXiAoeSB8IH56KSk7XG59XG5cbmZ1bmN0aW9uIG1peE9uZVJvdW5kKGEsIGIsIGMsIGQsIGUsIHgsIHMsIHJvdW5kTnVtYmVyKSB7XG4gIHN3aXRjaCAocm91bmROdW1iZXIpIHtcbiAgICBjYXNlIDA6XG4gICAgICBhICs9IEYoYiwgYywgZCkgKyB4ICsgMHgwMDAwMDAwMDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMTpcbiAgICAgIGEgKz0gRyhiLCBjLCBkKSArIHggKyAweDVhODI3OTk5O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAyOlxuICAgICAgYSArPSBIKGIsIGMsIGQpICsgeCArIDB4NmVkOWViYTE7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDM6XG4gICAgICBhICs9IEkoYiwgYywgZCkgKyB4ICsgMHg4ZjFiYmNkYztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNDpcbiAgICAgIGEgKz0gSihiLCBjLCBkKSArIHggKyAweGE5NTNmZDRlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA1OlxuICAgICAgYSArPSBKKGIsIGMsIGQpICsgeCArIDB4NTBhMjhiZTY7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDY6XG4gICAgICBhICs9IEkoYiwgYywgZCkgKyB4ICsgMHg1YzRkZDEyNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNzpcbiAgICAgIGEgKz0gSChiLCBjLCBkKSArIHggKyAweDZkNzAzZWYzO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA4OlxuICAgICAgYSArPSBHKGIsIGMsIGQpICsgeCArIDB4N2E2ZDc2ZTk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDk6XG4gICAgICBhICs9IEYoYiwgYywgZCkgKyB4ICsgMHgwMDAwMDAwMDtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGRvY3VtZW50LndyaXRlKFwiQm9ndXMgcm91bmQgbnVtYmVyXCIpO1xuICAgICAgYnJlYWs7XG4gIH1cblxuICBhID0gUk9MKGEsIHMpICsgZTtcbiAgYyA9IFJPTChjLCAxMCk7XG5cbiAgYSAmPSAweGZmZmZmZmZmO1xuICBiICY9IDB4ZmZmZmZmZmY7XG4gIGMgJj0gMHhmZmZmZmZmZjtcbiAgZCAmPSAweGZmZmZmZmZmO1xuICBlICY9IDB4ZmZmZmZmZmY7XG5cbiAgdmFyIHJldEJsb2NrID0gbmV3IEFycmF5KCk7XG4gIHJldEJsb2NrWzBdID0gYTtcbiAgcmV0QmxvY2tbMV0gPSBiO1xuICByZXRCbG9ja1syXSA9IGM7XG4gIHJldEJsb2NrWzNdID0gZDtcbiAgcmV0QmxvY2tbNF0gPSBlO1xuICByZXRCbG9ja1s1XSA9IHg7XG4gIHJldEJsb2NrWzZdID0gcztcblxuICByZXR1cm4gcmV0QmxvY2s7XG59XG5cbmZ1bmN0aW9uIE1EaW5pdChNRGJ1Zikge1xuICBNRGJ1ZlswXSA9IDB4Njc0NTIzMDE7XG4gIE1EYnVmWzFdID0gMHhlZmNkYWI4OTtcbiAgTURidWZbMl0gPSAweDk4YmFkY2ZlO1xuICBNRGJ1ZlszXSA9IDB4MTAzMjU0NzY7XG4gIE1EYnVmWzRdID0gMHhjM2QyZTFmMDtcbn1cblxudmFyIFJPTHMgPSBbXG4gIFsxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDhdLFxuICBbNywgNiwgOCwgMTMsIDExLCA5LCA3LCAxNSwgNywgMTIsIDE1LCA5LCAxMSwgNywgMTMsIDEyXSxcbiAgWzExLCAxMywgNiwgNywgMTQsIDksIDEzLCAxNSwgMTQsIDgsIDEzLCA2LCA1LCAxMiwgNywgNV0sXG4gIFsxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTJdLFxuICBbOSwgMTUsIDUsIDExLCA2LCA4LCAxMywgMTIsIDUsIDEyLCAxMywgMTQsIDExLCA4LCA1LCA2XSxcbiAgWzgsIDksIDksIDExLCAxMywgMTUsIDE1LCA1LCA3LCA3LCA4LCAxMSwgMTQsIDE0LCAxMiwgNl0sXG4gIFs5LCAxMywgMTUsIDcsIDEyLCA4LCA5LCAxMSwgNywgNywgMTIsIDcsIDYsIDE1LCAxMywgMTFdLFxuICBbOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1XSxcbiAgWzE1LCA1LCA4LCAxMSwgMTQsIDE0LCA2LCAxNCwgNiwgOSwgMTIsIDksIDEyLCA1LCAxNSwgOF0sXG4gIFs4LCA1LCAxMiwgOSwgMTIsIDUsIDE0LCA2LCA4LCAxMywgNiwgNSwgMTUsIDEzLCAxMSwgMTFdXG5dO1xuXG52YXIgaW5kZXhlcyA9IFtcbiAgWzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTVdLFxuICBbNywgNCwgMTMsIDEsIDEwLCA2LCAxNSwgMywgMTIsIDAsIDksIDUsIDIsIDE0LCAxMSwgOF0sXG4gIFszLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyXSxcbiAgWzEsIDksIDExLCAxMCwgMCwgOCwgMTIsIDQsIDEzLCAzLCA3LCAxNSwgMTQsIDUsIDYsIDJdLFxuICBbNCwgMCwgNSwgOSwgNywgMTIsIDIsIDEwLCAxNCwgMSwgMywgOCwgMTEsIDYsIDE1LCAxM10sXG4gIFs1LCAxNCwgNywgMCwgOSwgMiwgMTEsIDQsIDEzLCA2LCAxNSwgOCwgMSwgMTAsIDMsIDEyXSxcbiAgWzYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDJdLFxuICBbMTUsIDUsIDEsIDMsIDcsIDE0LCA2LCA5LCAxMSwgOCwgMTIsIDIsIDEwLCAwLCA0LCAxM10sXG4gIFs4LCA2LCA0LCAxLCAzLCAxMSwgMTUsIDAsIDUsIDEyLCAyLCAxMywgOSwgNywgMTAsIDE0XSxcbiAgWzEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFdXG5dO1xuXG5mdW5jdGlvbiBjb21wcmVzcyhNRGJ1ZiwgWCkge1xuICBibG9ja0EgPSBuZXcgQXJyYXkoKTtcbiAgYmxvY2tCID0gbmV3IEFycmF5KCk7XG5cbiAgdmFyIHJldEJsb2NrO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgNTsgaSsrKSB7XG4gICAgYmxvY2tBW2ldID0gbmV3IE51bWJlcihNRGJ1ZltpXSk7XG4gICAgYmxvY2tCW2ldID0gbmV3IE51bWJlcihNRGJ1ZltpXSk7XG4gIH1cblxuICB2YXIgc3RlcCA9IDA7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgNTsgaisrKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgICByZXRCbG9jayA9IG1peE9uZVJvdW5kKFxuICAgICAgICBibG9ja0FbKHN0ZXAgKyAwKSAlIDVdLFxuICAgICAgICBibG9ja0FbKHN0ZXAgKyAxKSAlIDVdLFxuICAgICAgICBibG9ja0FbKHN0ZXAgKyAyKSAlIDVdLFxuICAgICAgICBibG9ja0FbKHN0ZXAgKyAzKSAlIDVdLFxuICAgICAgICBibG9ja0FbKHN0ZXAgKyA0KSAlIDVdLFxuICAgICAgICBYW2luZGV4ZXNbal1baV1dLFxuICAgICAgICBST0xzW2pdW2ldLFxuICAgICAgICBqKTtcblxuICAgICAgYmxvY2tBWyhzdGVwICsgMCkgJSA1XSA9IHJldEJsb2NrWzBdO1xuICAgICAgYmxvY2tBWyhzdGVwICsgMSkgJSA1XSA9IHJldEJsb2NrWzFdO1xuICAgICAgYmxvY2tBWyhzdGVwICsgMikgJSA1XSA9IHJldEJsb2NrWzJdO1xuICAgICAgYmxvY2tBWyhzdGVwICsgMykgJSA1XSA9IHJldEJsb2NrWzNdO1xuICAgICAgYmxvY2tBWyhzdGVwICsgNCkgJSA1XSA9IHJldEJsb2NrWzRdO1xuXG4gICAgICBzdGVwICs9IDQ7XG4gICAgfVxuICB9XG5cbiAgc3RlcCA9IDA7XG4gIGZvciAodmFyIGogPSA1OyBqIDwgMTA7IGorKykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgcmV0QmxvY2sgPSBtaXhPbmVSb3VuZChcbiAgICAgICAgYmxvY2tCWyhzdGVwICsgMCkgJSA1XSxcbiAgICAgICAgYmxvY2tCWyhzdGVwICsgMSkgJSA1XSxcbiAgICAgICAgYmxvY2tCWyhzdGVwICsgMikgJSA1XSxcbiAgICAgICAgYmxvY2tCWyhzdGVwICsgMykgJSA1XSxcbiAgICAgICAgYmxvY2tCWyhzdGVwICsgNCkgJSA1XSxcbiAgICAgICAgWFtpbmRleGVzW2pdW2ldXSxcbiAgICAgICAgUk9Mc1tqXVtpXSxcbiAgICAgICAgaik7XG5cbiAgICAgIGJsb2NrQlsoc3RlcCArIDApICUgNV0gPSByZXRCbG9ja1swXTtcbiAgICAgIGJsb2NrQlsoc3RlcCArIDEpICUgNV0gPSByZXRCbG9ja1sxXTtcbiAgICAgIGJsb2NrQlsoc3RlcCArIDIpICUgNV0gPSByZXRCbG9ja1syXTtcbiAgICAgIGJsb2NrQlsoc3RlcCArIDMpICUgNV0gPSByZXRCbG9ja1szXTtcbiAgICAgIGJsb2NrQlsoc3RlcCArIDQpICUgNV0gPSByZXRCbG9ja1s0XTtcblxuICAgICAgc3RlcCArPSA0O1xuICAgIH1cbiAgfVxuXG4gIGJsb2NrQlszXSArPSBibG9ja0FbMl0gKyBNRGJ1ZlsxXTtcbiAgTURidWZbMV0gPSBNRGJ1ZlsyXSArIGJsb2NrQVszXSArIGJsb2NrQls0XTtcbiAgTURidWZbMl0gPSBNRGJ1ZlszXSArIGJsb2NrQVs0XSArIGJsb2NrQlswXTtcbiAgTURidWZbM10gPSBNRGJ1Zls0XSArIGJsb2NrQVswXSArIGJsb2NrQlsxXTtcbiAgTURidWZbNF0gPSBNRGJ1ZlswXSArIGJsb2NrQVsxXSArIGJsb2NrQlsyXTtcbiAgTURidWZbMF0gPSBibG9ja0JbM107XG59XG5cbmZ1bmN0aW9uIHplcm9YKFgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgWFtpXSA9IDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gTURmaW5pc2goTURidWYsIHN0cnB0ciwgbHN3bGVuLCBtc3dsZW4pIHtcbiAgdmFyIFggPSBuZXcgQXJyYXkoMTYpO1xuICB6ZXJvWChYKTtcblxuICB2YXIgaiA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgKGxzd2xlbiAmIDYzKTsgaSsrKSB7XG4gICAgWFtpID4+PiAyXSBePSAoc3RycHRyLmNoYXJDb2RlQXQoaisrKSAmIDI1NSkgPDwgKDggKiAoaSAmIDMpKTtcbiAgfVxuXG4gIFhbKGxzd2xlbiA+Pj4gMikgJiAxNV0gXj0gMSA8PCAoOCAqIChsc3dsZW4gJiAzKSArIDcpO1xuXG4gIGlmICgobHN3bGVuICYgNjMpID4gNTUpIHtcbiAgICBjb21wcmVzcyhNRGJ1ZiwgWCk7XG4gICAgdmFyIFggPSBuZXcgQXJyYXkoMTYpO1xuICAgIHplcm9YKFgpO1xuICB9XG5cbiAgWFsxNF0gPSBsc3dsZW4gPDwgMztcbiAgWFsxNV0gPSAobHN3bGVuID4+PiAyOSkgfCAobXN3bGVuIDw8IDMpO1xuXG4gIGNvbXByZXNzKE1EYnVmLCBYKTtcbn1cblxuZnVuY3Rpb24gQllURVNfVE9fRFdPUkQoZm91ckNoYXJzKSB7XG4gIHZhciB0bXAgPSAoZm91ckNoYXJzLmNoYXJDb2RlQXQoMykgJiAyNTUpIDw8IDI0O1xuICB0bXAgfD0gKGZvdXJDaGFycy5jaGFyQ29kZUF0KDIpICYgMjU1KSA8PCAxNjtcbiAgdG1wIHw9IChmb3VyQ2hhcnMuY2hhckNvZGVBdCgxKSAmIDI1NSkgPDwgODtcbiAgdG1wIHw9IChmb3VyQ2hhcnMuY2hhckNvZGVBdCgwKSAmIDI1NSk7XG5cbiAgcmV0dXJuIHRtcDtcbn1cblxuZnVuY3Rpb24gUk1EKG1lc3NhZ2UpIHtcbiAgdmFyIE1EYnVmID0gbmV3IEFycmF5KFJNRHNpemUgLyAzMik7XG4gIHZhciBoYXNoY29kZSA9IG5ldyBBcnJheShSTURzaXplIC8gOCk7XG4gIHZhciBsZW5ndGg7XG4gIHZhciBuYnl0ZXM7XG5cbiAgTURpbml0KE1EYnVmKTtcbiAgbGVuZ3RoID0gbWVzc2FnZS5sZW5ndGg7XG5cbiAgdmFyIFggPSBuZXcgQXJyYXkoMTYpO1xuICB6ZXJvWChYKTtcblxuICB2YXIgaiA9IDA7XG4gIGZvciAodmFyIG5ieXRlcyA9IGxlbmd0aDsgbmJ5dGVzID4gNjM7IG5ieXRlcyAtPSA2NCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgWFtpXSA9IEJZVEVTX1RPX0RXT1JEKG1lc3NhZ2Uuc3Vic3RyKGosIDQpKTtcbiAgICAgIGogKz0gNDtcbiAgICB9XG4gICAgY29tcHJlc3MoTURidWYsIFgpO1xuICB9XG5cbiAgTURmaW5pc2goTURidWYsIG1lc3NhZ2Uuc3Vic3RyKGopLCBsZW5ndGgsIDApO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgUk1Ec2l6ZSAvIDg7IGkgKz0gNCkge1xuICAgIGhhc2hjb2RlW2ldID0gTURidWZbaSA+Pj4gMl0gJiAyNTU7XG4gICAgaGFzaGNvZGVbaSArIDFdID0gKE1EYnVmW2kgPj4+IDJdID4+PiA4KSAmIDI1NTtcbiAgICBoYXNoY29kZVtpICsgMl0gPSAoTURidWZbaSA+Pj4gMl0gPj4+IDE2KSAmIDI1NTtcbiAgICBoYXNoY29kZVtpICsgM10gPSAoTURidWZbaSA+Pj4gMl0gPj4+IDI0KSAmIDI1NTtcbiAgfVxuXG4gIHJldHVybiBoYXNoY29kZTtcbn1cblxuXG5mdW5jdGlvbiBSTURzdHJpbmcobWVzc2FnZSkge1xuICB2YXIgaGFzaGNvZGUgPSBSTUQobWVzc2FnZSk7XG4gIHZhciByZXRTdHJpbmcgPSBcIlwiO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgUk1Ec2l6ZSAvIDg7IGkrKykge1xuICAgIHJldFN0cmluZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGhhc2hjb2RlW2ldKTtcbiAgfVxuXG4gIHJldHVybiByZXRTdHJpbmc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUk1Ec3RyaW5nO1xuIiwiLyogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTSEEgZmFtaWx5IG9mIGhhc2hlcywgYXMgZGVmaW5lZCBpbiBGSVBTIFxuICogUFVCIDE4MC0yIGFzIHdlbGwgYXMgdGhlIGNvcnJlc3BvbmRpbmcgSE1BQyBpbXBsZW1lbnRhdGlvbiBhcyBkZWZpbmVkIGluXG4gKiBGSVBTIFBVQiAxOThhXG4gKlxuICogVmVyc2lvbiAxLjMgQ29weXJpZ2h0IEJyaWFuIFR1cmVrIDIwMDgtMjAxMFxuICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlXG4gKiBTZWUgaHR0cDovL2pzc2hhLnNvdXJjZWZvcmdlLm5ldC8gZm9yIG1vcmUgaW5mb3JtYXRpb25cbiAqXG4gKiBTZXZlcmFsIGZ1bmN0aW9ucyB0YWtlbiBmcm9tIFBhdWwgSm9obnNvblxuICovXG5cbi8qIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSFxuICogXG4gKiBUaGlzIGNvZGUgaGFzIGJlZW4gc2xpZ2h0bHkgbW9kaWZpZWQgZGlyZWN0IHN0cmluZyBvdXRwdXQ6XG4gKiAtIGJpbjJic3RyIGhhcyBiZWVuIGFkZGVkXG4gKiAtIGZvbGxvd2luZyB3cmFwcGVycyBvZiB0aGlzIGxpYnJhcnkgaGF2ZSBiZWVuIGFkZGVkOlxuICogICAtIHN0cl9zaGExXG4gKiAgIC0gc3RyX3NoYTI1NlxuICogICAtIHN0cl9zaGEyMjRcbiAqICAgLSBzdHJfc2hhMzg0XG4gKiAgIC0gc3RyX3NoYTUxMlxuICovXG5cbnZhciBqc1NIQSA9IChmdW5jdGlvbigpIHtcblxuICAvKlxuICAgKiBDb25maWd1cmFibGUgdmFyaWFibGVzLiBEZWZhdWx0cyB0eXBpY2FsbHkgd29ya1xuICAgKi9cbiAgLyogTnVtYmVyIG9mIEJpdHMgUGVyIGNoYXJhY3RlciAoOCBmb3IgQVNDSUksIDE2IGZvciBVbmljb2RlKSAqL1xuICB2YXIgY2hhclNpemUgPSA4LFxuICAgIC8qIGJhc2UtNjQgcGFkIGNoYXJhY3Rlci4gXCI9XCIgZm9yIHN0cmljdCBSRkMgY29tcGxpYW5jZSAqL1xuICAgIGI2NHBhZCA9IFwiXCIsXG4gICAgLyogaGV4IG91dHB1dCBmb3JtYXQuIDAgLSBsb3dlcmNhc2U7IDEgLSB1cHBlcmNhc2UgKi9cbiAgICBoZXhDYXNlID0gMCxcblxuICAgIC8qXG4gICAgICogSW50XzY0IGlzIGEgb2JqZWN0IGZvciAyIDMyLWJpdCBudW1iZXJzIGVtdWxhdGluZyBhIDY0LWJpdCBudW1iZXJcbiAgICAgKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtc2ludF8zMiBUaGUgbW9zdCBzaWduaWZpY2FudCAzMi1iaXRzIG9mIGEgNjQtYml0IG51bWJlclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBsc2ludF8zMiBUaGUgbGVhc3Qgc2lnbmlmaWNhbnQgMzItYml0cyBvZiBhIDY0LWJpdCBudW1iZXJcbiAgICAgKi9cbiAgICBJbnRfNjQgPSBmdW5jdGlvbihtc2ludF8zMiwgbHNpbnRfMzIpIHtcbiAgICAgIHRoaXMuaGlnaE9yZGVyID0gbXNpbnRfMzI7XG4gICAgICB0aGlzLmxvd09yZGVyID0gbHNpbnRfMzI7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ29udmVydCBhIHN0cmluZyB0byBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzXG4gICAgICogSWYgY2hhclNpemUgaXMgQVNDSUksIGNoYXJhY3RlcnMgPjI1NSBoYXZlIHRoZWlyIGhpLWJ5dGUgc2lsZW50bHlcbiAgICAgKiBpZ25vcmVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gYmUgY29udmVydGVkIHRvIGJpbmFyeSByZXByZXNlbnRhdGlvblxuICAgICAqIEByZXR1cm4gSW50ZWdlciBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyXG4gICAgICovXG4gICAgc3RyMmJpbmIgPSBmdW5jdGlvbihzdHIpIHtcbiAgICAgIHZhciBiaW4gPSBbXSxcbiAgICAgICAgbWFzayA9ICgxIDw8IGNoYXJTaXplKSAtIDEsXG4gICAgICAgIGxlbmd0aCA9IHN0ci5sZW5ndGggKiBjaGFyU2l6ZSxcbiAgICAgICAgaTtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSArPSBjaGFyU2l6ZSkge1xuICAgICAgICBiaW5baSA+PiA1XSB8PSAoc3RyLmNoYXJDb2RlQXQoaSAvIGNoYXJTaXplKSAmIG1hc2spIDw8XG4gICAgICAgICAgKDMyIC0gY2hhclNpemUgLSAoaSAlIDMyKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBiaW47XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ29udmVydCBhIGhleCBzdHJpbmcgdG8gYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3Jkc1xuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gYmUgY29udmVydGVkIHRvIGJpbmFyeSByZXByZXNlbnRhdGlvblxuICAgICAqIEByZXR1cm4gSW50ZWdlciBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyXG4gICAgICovXG4gICAgaGV4MmJpbmIgPSBmdW5jdGlvbihzdHIpIHtcbiAgICAgIHZhciBiaW4gPSBbXSxcbiAgICAgICAgbGVuZ3RoID0gc3RyLmxlbmd0aCxcbiAgICAgICAgaSwgbnVtO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDIpIHtcbiAgICAgICAgbnVtID0gcGFyc2VJbnQoc3RyLnN1YnN0cihpLCAyKSwgMTYpO1xuICAgICAgICBpZiAoIWlzTmFOKG51bSkpIHtcbiAgICAgICAgICBiaW5baSA+PiAzXSB8PSBudW0gPDwgKDI0IC0gKDQgKiAoaSAlIDgpKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIFwiSU5WQUxJRCBIRVggU1RSSU5HXCI7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGJpbjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMgdG8gYSBoZXggc3RyaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBiaW5hcnJheSBBcnJheSBvZiBpbnRlZ2VycyB0byBiZSBjb252ZXJ0ZWQgdG8gaGV4aWRlY2ltYWxcbiAgICAgKlx0IHJlcHJlc2VudGF0aW9uXG4gICAgICogQHJldHVybiBIZXhpZGVjaW1hbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyIGluIFN0cmluZyBmb3JtXG4gICAgICovXG4gICAgYmluYjJoZXggPSBmdW5jdGlvbihiaW5hcnJheSkge1xuICAgICAgdmFyIGhleF90YWIgPSAoaGV4Q2FzZSkgPyBcIjAxMjM0NTY3ODlBQkNERUZcIiA6IFwiMDEyMzQ1Njc4OWFiY2RlZlwiLFxuICAgICAgICBzdHIgPSBcIlwiLFxuICAgICAgICBsZW5ndGggPSBiaW5hcnJheS5sZW5ndGggKiA0LFxuICAgICAgICBpLCBzcmNCeXRlO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgc3JjQnl0ZSA9IGJpbmFycmF5W2kgPj4gMl0gPj4gKCgzIC0gKGkgJSA0KSkgKiA4KTtcbiAgICAgICAgc3RyICs9IGhleF90YWIuY2hhckF0KChzcmNCeXRlID4+IDQpICYgMHhGKSArXG4gICAgICAgICAgaGV4X3RhYi5jaGFyQXQoc3JjQnl0ZSAmIDB4Rik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzdHI7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ29udmVydCBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzIHRvIGEgYmFzZS02NCBzdHJpbmdcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYmluYXJyYXkgQXJyYXkgb2YgaW50ZWdlcnMgdG8gYmUgY29udmVydGVkIHRvIGJhc2UtNjRcbiAgICAgKlx0IHJlcHJlc2VudGF0aW9uXG4gICAgICogQHJldHVybiBCYXNlLTY0IGVuY29kZWQgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhcmFtZXRlciBpbiBTdHJpbmcgZm9ybVxuICAgICAqL1xuICAgIGJpbmIyYjY0ID0gZnVuY3Rpb24oYmluYXJyYXkpIHtcbiAgICAgIHZhciB0YWIgPSBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIiArXG4gICAgICAgIFwiMDEyMzQ1Njc4OSsvXCIsXG4gICAgICAgIHN0ciA9IFwiXCIsXG4gICAgICAgIGxlbmd0aCA9IGJpbmFycmF5Lmxlbmd0aCAqIDQsXG4gICAgICAgIGksIGosXG4gICAgICAgIHRyaXBsZXQ7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuICAgICAgICB0cmlwbGV0ID0gKCgoYmluYXJyYXlbaSA+PiAyXSA+PiA4ICogKDMgLSBpICUgNCkpICYgMHhGRikgPDwgMTYpIHxcbiAgICAgICAgICAoKChiaW5hcnJheVtpICsgMSA+PiAyXSA+PiA4ICogKDMgLSAoaSArIDEpICUgNCkpICYgMHhGRikgPDwgOCkgfFxuICAgICAgICAgICgoYmluYXJyYXlbaSArIDIgPj4gMl0gPj4gOCAqICgzIC0gKGkgKyAyKSAlIDQpKSAmIDB4RkYpO1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgNDsgaiArPSAxKSB7XG4gICAgICAgICAgaWYgKGkgKiA4ICsgaiAqIDYgPD0gYmluYXJyYXkubGVuZ3RoICogMzIpIHtcbiAgICAgICAgICAgIHN0ciArPSB0YWIuY2hhckF0KCh0cmlwbGV0ID4+IDYgKiAoMyAtIGopKSAmIDB4M0YpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHIgKz0gYjY0cGFkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMgdG8gYSBzdHJpbmdcbiAgICAgKi9cbiAgICBiaW5iMnN0ciA9IGZ1bmN0aW9uKGJpbikge1xuICAgICAgdmFyIHN0ciA9IFwiXCI7XG4gICAgICB2YXIgbWFzayA9ICgxIDw8IDgpIC0gMTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmluLmxlbmd0aCAqIDMyOyBpICs9IDgpXG4gICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChiaW5baSA+PiA1XSA+Pj4gKDI0IC0gaSAlIDMyKSkgJiBtYXNrKTtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfSxcbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgY2lyY3VsYXIgcm90YXRlIGxlZnRcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG4gICAgICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGNpcmN1bGFybHkgYnkgbiBiaXRzXG4gICAgICovXG4gICAgcm90bF8zMiA9IGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgIHJldHVybiAoeCA8PCBuKSB8ICh4ID4+PiAoMzIgLSBuKSk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBjaXJjdWxhciByb3RhdGUgcmlnaHRcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG4gICAgICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGNpcmN1bGFybHkgYnkgbiBiaXRzXG4gICAgICovXG4gICAgcm90cl8zMiA9IGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgIHJldHVybiAoeCA+Pj4gbikgfCAoeCA8PCAoMzIgLSBuKSk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBjaXJjdWxhciByb3RhdGUgcmlnaHRcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG4gICAgICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGNpcmN1bGFybHkgYnkgbiBiaXRzXG4gICAgICovXG4gICAgcm90cl82NCA9IGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgIGlmIChuIDw9IDMyKSB7XG4gICAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICAoeC5oaWdoT3JkZXIgPj4+IG4pIHwgKHgubG93T3JkZXIgPDwgKDMyIC0gbikpLCAoeC5sb3dPcmRlciA+Pj4gbikgfCAoeC5oaWdoT3JkZXIgPDwgKDMyIC0gbikpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICAoeC5sb3dPcmRlciA+Pj4gbikgfCAoeC5oaWdoT3JkZXIgPDwgKDMyIC0gbikpLCAoeC5oaWdoT3JkZXIgPj4+IG4pIHwgKHgubG93T3JkZXIgPDwgKDMyIC0gbikpKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHNoaWZ0IHJpZ2h0XG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdFxuICAgICAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBieSBuIGJpdHNcbiAgICAgKi9cbiAgICBzaHJfMzIgPSBmdW5jdGlvbih4LCBuKSB7XG4gICAgICByZXR1cm4geCA+Pj4gbjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHNoaWZ0IHJpZ2h0XG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdFxuICAgICAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBieSBuIGJpdHNcbiAgICAgKi9cbiAgICBzaHJfNjQgPSBmdW5jdGlvbih4LCBuKSB7XG4gICAgICBpZiAobiA8PSAzMikge1xuICAgICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgICB4LmhpZ2hPcmRlciA+Pj4gbixcbiAgICAgICAgICB4Lmxvd09yZGVyID4+PiBuIHwgKHguaGlnaE9yZGVyIDw8ICgzMiAtIG4pKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgICAwLFxuICAgICAgICAgIHguaGlnaE9yZGVyIDw8ICgzMiAtIG4pKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBQYXJpdHkgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB6IFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBwYXJpdHlfMzIgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4geCBeIHkgXiB6O1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIENoIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geiBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgY2hfMzIgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4gKHggJiB5KSBeICh+eCAmIHopO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIENoIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSBmaXJzdCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB5IFRoZSBzZWNvbmQgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geiBUaGUgdGhpcmQgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgY2hfNjQgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICh4LmhpZ2hPcmRlciAmIHkuaGlnaE9yZGVyKSBeICh+eC5oaWdoT3JkZXIgJiB6LmhpZ2hPcmRlciksICh4Lmxvd09yZGVyICYgeS5sb3dPcmRlcikgXiAofngubG93T3JkZXIgJiB6Lmxvd09yZGVyKSk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgTWFqIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geiBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgbWFqXzMyID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICAgICAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBNYWogZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIGZpcnN0IDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHkgVGhlIHNlY29uZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB6IFRoZSB0aGlyZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBtYWpfNjQgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICh4LmhpZ2hPcmRlciAmIHkuaGlnaE9yZGVyKSBeXG4gICAgICAgICh4LmhpZ2hPcmRlciAmIHouaGlnaE9yZGVyKSBeXG4gICAgICAgICh5LmhpZ2hPcmRlciAmIHouaGlnaE9yZGVyKSwgKHgubG93T3JkZXIgJiB5Lmxvd09yZGVyKSBeXG4gICAgICAgICh4Lmxvd09yZGVyICYgei5sb3dPcmRlcikgXlxuICAgICAgICAoeS5sb3dPcmRlciAmIHoubG93T3JkZXIpKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBTaWdtYTAgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIHNpZ21hMF8zMiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiByb3RyXzMyKHgsIDIpIF4gcm90cl8zMih4LCAxMykgXiByb3RyXzMyKHgsIDIyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBTaWdtYTAgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIHNpZ21hMF82NCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHZhciByb3RyMjggPSByb3RyXzY0KHgsIDI4KSxcbiAgICAgICAgcm90cjM0ID0gcm90cl82NCh4LCAzNCksXG4gICAgICAgIHJvdHIzOSA9IHJvdHJfNjQoeCwgMzkpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgcm90cjI4LmhpZ2hPcmRlciBeIHJvdHIzNC5oaWdoT3JkZXIgXiByb3RyMzkuaGlnaE9yZGVyLFxuICAgICAgICByb3RyMjgubG93T3JkZXIgXiByb3RyMzQubG93T3JkZXIgXiByb3RyMzkubG93T3JkZXIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIFNpZ21hMSBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgc2lnbWExXzMyID0gZnVuY3Rpb24oeCkge1xuICAgICAgcmV0dXJuIHJvdHJfMzIoeCwgNikgXiByb3RyXzMyKHgsIDExKSBeIHJvdHJfMzIoeCwgMjUpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIFNpZ21hMSBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgc2lnbWExXzY0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgdmFyIHJvdHIxNCA9IHJvdHJfNjQoeCwgMTQpLFxuICAgICAgICByb3RyMTggPSByb3RyXzY0KHgsIDE4KSxcbiAgICAgICAgcm90cjQxID0gcm90cl82NCh4LCA0MSk7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICByb3RyMTQuaGlnaE9yZGVyIF4gcm90cjE4LmhpZ2hPcmRlciBeIHJvdHI0MS5oaWdoT3JkZXIsXG4gICAgICAgIHJvdHIxNC5sb3dPcmRlciBeIHJvdHIxOC5sb3dPcmRlciBeIHJvdHI0MS5sb3dPcmRlcik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgR2FtbWEwIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBnYW1tYTBfMzIgPSBmdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4gcm90cl8zMih4LCA3KSBeIHJvdHJfMzIoeCwgMTgpIF4gc2hyXzMyKHgsIDMpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIEdhbW1hMCBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgZ2FtbWEwXzY0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgdmFyIHJvdHIxID0gcm90cl82NCh4LCAxKSxcbiAgICAgICAgcm90cjggPSByb3RyXzY0KHgsIDgpLFxuICAgICAgICBzaHI3ID0gc2hyXzY0KHgsIDcpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgcm90cjEuaGlnaE9yZGVyIF4gcm90cjguaGlnaE9yZGVyIF4gc2hyNy5oaWdoT3JkZXIsXG4gICAgICAgIHJvdHIxLmxvd09yZGVyIF4gcm90cjgubG93T3JkZXIgXiBzaHI3Lmxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTEgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIGdhbW1hMV8zMiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiByb3RyXzMyKHgsIDE3KSBeIHJvdHJfMzIoeCwgMTkpIF4gc2hyXzMyKHgsIDEwKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTEgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIGdhbW1hMV82NCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHZhciByb3RyMTkgPSByb3RyXzY0KHgsIDE5KSxcbiAgICAgICAgcm90cjYxID0gcm90cl82NCh4LCA2MSksXG4gICAgICAgIHNocjYgPSBzaHJfNjQoeCwgNik7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICByb3RyMTkuaGlnaE9yZGVyIF4gcm90cjYxLmhpZ2hPcmRlciBeIHNocjYuaGlnaE9yZGVyLFxuICAgICAgICByb3RyMTkubG93T3JkZXIgXiByb3RyNjEubG93T3JkZXIgXiBzaHI2Lmxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgdHdvIDMyLWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgZmlyc3QgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIHggKyB5XG4gICAgICovXG4gICAgc2FmZUFkZF8zMl8yID0gZnVuY3Rpb24oeCwgeSkge1xuICAgICAgdmFyIGxzdyA9ICh4ICYgMHhGRkZGKSArICh5ICYgMHhGRkZGKSxcbiAgICAgICAgbXN3ID0gKHggPj4+IDE2KSArICh5ID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG5cbiAgICAgIHJldHVybiAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQWRkIGZvdXIgMzItYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjMyLiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcbiAgICAgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhIFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBiIFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYyBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZCBUaGUgZm91cnRoIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGRcbiAgICAgKi9cbiAgICBzYWZlQWRkXzMyXzQgPSBmdW5jdGlvbihhLCBiLCBjLCBkKSB7XG4gICAgICB2YXIgbHN3ID0gKGEgJiAweEZGRkYpICsgKGIgJiAweEZGRkYpICsgKGMgJiAweEZGRkYpICsgKGQgJiAweEZGRkYpLFxuICAgICAgICBtc3cgPSAoYSA+Pj4gMTYpICsgKGIgPj4+IDE2KSArIChjID4+PiAxNikgKyAoZCA+Pj4gMTYpICtcbiAgICAgICAgICAobHN3ID4+PiAxNik7XG5cbiAgICAgIHJldHVybiAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQWRkIGZpdmUgMzItYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjMyLiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcbiAgICAgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhIFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBiIFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYyBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZCBUaGUgZm91cnRoIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGUgVGhlIGZpZnRoIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGQgKyBlXG4gICAgICovXG4gICAgc2FmZUFkZF8zMl81ID0gZnVuY3Rpb24oYSwgYiwgYywgZCwgZSkge1xuICAgICAgdmFyIGxzdyA9IChhICYgMHhGRkZGKSArIChiICYgMHhGRkZGKSArIChjICYgMHhGRkZGKSArIChkICYgMHhGRkZGKSArXG4gICAgICAgIChlICYgMHhGRkZGKSxcbiAgICAgICAgbXN3ID0gKGEgPj4+IDE2KSArIChiID4+PiAxNikgKyAoYyA+Pj4gMTYpICsgKGQgPj4+IDE2KSArXG4gICAgICAgICAgKGUgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcblxuICAgICAgcmV0dXJuICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgdHdvIDY0LWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl42NC4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geSBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIHggKyB5XG4gICAgICovXG4gICAgc2FmZUFkZF82NF8yID0gZnVuY3Rpb24oeCwgeSkge1xuICAgICAgdmFyIGxzdywgbXN3LCBsb3dPcmRlciwgaGlnaE9yZGVyO1xuXG4gICAgICBsc3cgPSAoeC5sb3dPcmRlciAmIDB4RkZGRikgKyAoeS5sb3dPcmRlciAmIDB4RkZGRik7XG4gICAgICBtc3cgPSAoeC5sb3dPcmRlciA+Pj4gMTYpICsgKHkubG93T3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcbiAgICAgIGxvd09yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICBsc3cgPSAoeC5oaWdoT3JkZXIgJiAweEZGRkYpICsgKHkuaGlnaE9yZGVyICYgMHhGRkZGKSArIChtc3cgPj4+IDE2KTtcbiAgICAgIG1zdyA9ICh4LmhpZ2hPcmRlciA+Pj4gMTYpICsgKHkuaGlnaE9yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG4gICAgICBoaWdoT3JkZXIgPSAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KGhpZ2hPcmRlciwgbG93T3JkZXIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIEFkZCBmb3VyIDY0LWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl42NC4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gYSBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gYiBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGMgVGhlIHRoaXJkIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGQgVGhlIGZvdXRoIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGRcbiAgICAgKi9cbiAgICBzYWZlQWRkXzY0XzQgPSBmdW5jdGlvbihhLCBiLCBjLCBkKSB7XG4gICAgICB2YXIgbHN3LCBtc3csIGxvd09yZGVyLCBoaWdoT3JkZXI7XG5cbiAgICAgIGxzdyA9IChhLmxvd09yZGVyICYgMHhGRkZGKSArIChiLmxvd09yZGVyICYgMHhGRkZGKSArXG4gICAgICAgIChjLmxvd09yZGVyICYgMHhGRkZGKSArIChkLmxvd09yZGVyICYgMHhGRkZGKTtcbiAgICAgIG1zdyA9IChhLmxvd09yZGVyID4+PiAxNikgKyAoYi5sb3dPcmRlciA+Pj4gMTYpICtcbiAgICAgICAgKGMubG93T3JkZXIgPj4+IDE2KSArIChkLmxvd09yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG4gICAgICBsb3dPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuICAgICAgbHN3ID0gKGEuaGlnaE9yZGVyICYgMHhGRkZGKSArIChiLmhpZ2hPcmRlciAmIDB4RkZGRikgK1xuICAgICAgICAoYy5oaWdoT3JkZXIgJiAweEZGRkYpICsgKGQuaGlnaE9yZGVyICYgMHhGRkZGKSArIChtc3cgPj4+IDE2KTtcbiAgICAgIG1zdyA9IChhLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGIuaGlnaE9yZGVyID4+PiAxNikgK1xuICAgICAgICAoYy5oaWdoT3JkZXIgPj4+IDE2KSArIChkLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuICAgICAgaGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChoaWdoT3JkZXIsIGxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgZml2ZSA2NC1iaXQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeNjQuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9uc1xuICAgICAqIGludGVybmFsbHkgdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGEgVGhlIGZpcnN0IDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGIgVGhlIHNlY29uZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBjIFRoZSB0aGlyZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBkIFRoZSBmb3V0aCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBlIFRoZSBmb3V0aCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEByZXR1cm4gVGhlIHN1bSBvZiBhICsgYiArIGMgKyBkICsgZVxuICAgICAqL1xuICAgIHNhZmVBZGRfNjRfNSA9IGZ1bmN0aW9uKGEsIGIsIGMsIGQsIGUpIHtcbiAgICAgIHZhciBsc3csIG1zdywgbG93T3JkZXIsIGhpZ2hPcmRlcjtcblxuICAgICAgbHN3ID0gKGEubG93T3JkZXIgJiAweEZGRkYpICsgKGIubG93T3JkZXIgJiAweEZGRkYpICtcbiAgICAgICAgKGMubG93T3JkZXIgJiAweEZGRkYpICsgKGQubG93T3JkZXIgJiAweEZGRkYpICtcbiAgICAgICAgKGUubG93T3JkZXIgJiAweEZGRkYpO1xuICAgICAgbXN3ID0gKGEubG93T3JkZXIgPj4+IDE2KSArIChiLmxvd09yZGVyID4+PiAxNikgK1xuICAgICAgICAoYy5sb3dPcmRlciA+Pj4gMTYpICsgKGQubG93T3JkZXIgPj4+IDE2KSArIChlLmxvd09yZGVyID4+PiAxNikgK1xuICAgICAgICAobHN3ID4+PiAxNik7XG4gICAgICBsb3dPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuICAgICAgbHN3ID0gKGEuaGlnaE9yZGVyICYgMHhGRkZGKSArIChiLmhpZ2hPcmRlciAmIDB4RkZGRikgK1xuICAgICAgICAoYy5oaWdoT3JkZXIgJiAweEZGRkYpICsgKGQuaGlnaE9yZGVyICYgMHhGRkZGKSArXG4gICAgICAgIChlLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAobXN3ID4+PiAxNik7XG4gICAgICBtc3cgPSAoYS5oaWdoT3JkZXIgPj4+IDE2KSArIChiLmhpZ2hPcmRlciA+Pj4gMTYpICtcbiAgICAgICAgKGMuaGlnaE9yZGVyID4+PiAxNikgKyAoZC5oaWdoT3JkZXIgPj4+IDE2KSArXG4gICAgICAgIChlLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuICAgICAgaGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChoaWdoT3JkZXIsIGxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSBTSEEtMSBoYXNoIG9mIHRoZSBzdHJpbmcgc2V0IGF0IGluc3RhbnRpYXRpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gbWVzc2FnZSBUaGUgYmluYXJ5IGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdHJpbmcgdG9cbiAgICAgKlx0IGhhc2hcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbWVzc2FnZUxlbiBUaGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIG1lc3NhZ2VcbiAgICAgKiBAcmV0dXJuIFRoZSBhcnJheSBvZiBpbnRlZ2VycyByZXByZXNlbnRpbmcgdGhlIFNIQS0xIGhhc2ggb2YgbWVzc2FnZVxuICAgICAqL1xuICAgIGNvcmVTSEExID0gZnVuY3Rpb24obWVzc2FnZSwgbWVzc2FnZUxlbikge1xuICAgICAgdmFyIFcgPSBbXSxcbiAgICAgICAgYSwgYiwgYywgZCwgZSwgVCwgY2ggPSBjaF8zMixcbiAgICAgICAgcGFyaXR5ID0gcGFyaXR5XzMyLFxuICAgICAgICBtYWogPSBtYWpfMzIsXG4gICAgICAgIHJvdGwgPSByb3RsXzMyLFxuICAgICAgICBzYWZlQWRkXzIgPSBzYWZlQWRkXzMyXzIsXG4gICAgICAgIGksIHQsXG4gICAgICAgIHNhZmVBZGRfNSA9IHNhZmVBZGRfMzJfNSxcbiAgICAgICAgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoLFxuICAgICAgICBIID0gW1xuICAgICAgICAgICAgMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSwgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3NiwgMHhjM2QyZTFmMFxuICAgICAgICBdLFxuICAgICAgICBLID0gW1xuICAgICAgICAgICAgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcbiAgICAgICAgICAgIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksXG4gICAgICAgICAgICAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LFxuICAgICAgICAgICAgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcbiAgICAgICAgICAgIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksXG4gICAgICAgICAgICAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLFxuICAgICAgICAgICAgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcbiAgICAgICAgICAgIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsXG4gICAgICAgICAgICAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLFxuICAgICAgICAgICAgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcbiAgICAgICAgICAgIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsXG4gICAgICAgICAgICAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLFxuICAgICAgICAgICAgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcbiAgICAgICAgICAgIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsXG4gICAgICAgICAgICAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLFxuICAgICAgICAgICAgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcbiAgICAgICAgICAgIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsXG4gICAgICAgICAgICAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LFxuICAgICAgICAgICAgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcbiAgICAgICAgICAgIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDZcbiAgICAgICAgXTtcblxuICAgICAgLyogQXBwZW5kICcxJyBhdCB0aGUgZW5kIG9mIHRoZSBiaW5hcnkgc3RyaW5nICovXG4gICAgICBtZXNzYWdlW21lc3NhZ2VMZW4gPj4gNV0gfD0gMHg4MCA8PCAoMjQgLSAobWVzc2FnZUxlbiAlIDMyKSk7XG4gICAgICAvKiBBcHBlbmQgbGVuZ3RoIG9mIGJpbmFyeSBzdHJpbmcgaW4gdGhlIHBvc2l0aW9uIHN1Y2ggdGhhdCB0aGUgbmV3XG5cdFx0bGVuZ3RoIGlzIGEgbXVsdGlwbGUgb2YgNTEyLiAgTG9naWMgZG9lcyBub3Qgd29yayBmb3IgZXZlbiBtdWx0aXBsZXNcblx0XHRvZiA1MTIgYnV0IHRoZXJlIGNhbiBuZXZlciBiZSBldmVuIG11bHRpcGxlcyBvZiA1MTIgKi9cbiAgICAgIG1lc3NhZ2VbKCgobWVzc2FnZUxlbiArIDY1KSA+PiA5KSA8PCA0KSArIDE1XSA9IG1lc3NhZ2VMZW47XG5cbiAgICAgIGFwcGVuZGVkTWVzc2FnZUxlbmd0aCA9IG1lc3NhZ2UubGVuZ3RoO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoOyBpICs9IDE2KSB7XG4gICAgICAgIGEgPSBIWzBdO1xuICAgICAgICBiID0gSFsxXTtcbiAgICAgICAgYyA9IEhbMl07XG4gICAgICAgIGQgPSBIWzNdO1xuICAgICAgICBlID0gSFs0XTtcblxuICAgICAgICBmb3IgKHQgPSAwOyB0IDwgODA7IHQgKz0gMSkge1xuICAgICAgICAgIGlmICh0IDwgMTYpIHtcbiAgICAgICAgICAgIFdbdF0gPSBtZXNzYWdlW3QgKyBpXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgV1t0XSA9IHJvdGwoV1t0IC0gM10gXiBXW3QgLSA4XSBeIFdbdCAtIDE0XSBeIFdbdCAtIDE2XSwgMSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHQgPCAyMCkge1xuICAgICAgICAgICAgVCA9IHNhZmVBZGRfNShyb3RsKGEsIDUpLCBjaChiLCBjLCBkKSwgZSwgS1t0XSwgV1t0XSk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0IDwgNDApIHtcbiAgICAgICAgICAgIFQgPSBzYWZlQWRkXzUocm90bChhLCA1KSwgcGFyaXR5KGIsIGMsIGQpLCBlLCBLW3RdLCBXW3RdKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHQgPCA2MCkge1xuICAgICAgICAgICAgVCA9IHNhZmVBZGRfNShyb3RsKGEsIDUpLCBtYWooYiwgYywgZCksIGUsIEtbdF0sIFdbdF0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBUID0gc2FmZUFkZF81KHJvdGwoYSwgNSksIHBhcml0eShiLCBjLCBkKSwgZSwgS1t0XSwgV1t0XSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZSA9IGQ7XG4gICAgICAgICAgZCA9IGM7XG4gICAgICAgICAgYyA9IHJvdGwoYiwgMzApO1xuICAgICAgICAgIGIgPSBhO1xuICAgICAgICAgIGEgPSBUO1xuICAgICAgICB9XG5cbiAgICAgICAgSFswXSA9IHNhZmVBZGRfMihhLCBIWzBdKTtcbiAgICAgICAgSFsxXSA9IHNhZmVBZGRfMihiLCBIWzFdKTtcbiAgICAgICAgSFsyXSA9IHNhZmVBZGRfMihjLCBIWzJdKTtcbiAgICAgICAgSFszXSA9IHNhZmVBZGRfMihkLCBIWzNdKTtcbiAgICAgICAgSFs0XSA9IHNhZmVBZGRfMihlLCBIWzRdKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEg7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgZGVzaXJlZCBTSEEtMiBoYXNoIG9mIHRoZSBzdHJpbmcgc2V0IGF0IGluc3RhbnRpYXRpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gVGhlIGJpbmFyeSBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3RyaW5nIHRvIGhhc2hcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gVGhlIG51bWJlciBvZiBiaXRzIGluIG1lc3NhZ2VcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdmFyaWFudCBUaGUgZGVzaXJlZCBTSEEtMiB2YXJpYW50XG4gICAgICogQHJldHVybiBUaGUgYXJyYXkgb2YgaW50ZWdlcnMgcmVwcmVzZW50aW5nIHRoZSBTSEEtMiBoYXNoIG9mIG1lc3NhZ2VcbiAgICAgKi9cbiAgICBjb3JlU0hBMiA9IGZ1bmN0aW9uKG1lc3NhZ2UsIG1lc3NhZ2VMZW4sIHZhcmlhbnQpIHtcbiAgICAgIHZhciBhLCBiLCBjLCBkLCBlLCBmLCBnLCBoLCBUMSwgVDIsIEgsIG51bVJvdW5kcywgbGVuZ3RoUG9zaXRpb24sIGksIHQsXG4gICAgICAgIGJpbmFyeVN0cmluZ0luYywgYmluYXJ5U3RyaW5nTXVsdCwgc2FmZUFkZF8yLCBzYWZlQWRkXzQsIHNhZmVBZGRfNSxcbiAgICAgICAgZ2FtbWEwLCBnYW1tYTEsIHNpZ21hMCwgc2lnbWExLCBjaCwgbWFqLCBJbnQsIEssIFcgPSBbXSxcbiAgICAgICAgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoO1xuXG4gICAgICAvKiBTZXQgdXAgdGhlIHZhcmlvdXMgZnVuY3Rpb24gaGFuZGxlcyBhbmQgdmFyaWFibGUgZm9yIHRoZSBzcGVjaWZpYyBcbiAgICAgICAqIHZhcmlhbnQgKi9cbiAgICAgIGlmICh2YXJpYW50ID09PSBcIlNIQS0yMjRcIiB8fCB2YXJpYW50ID09PSBcIlNIQS0yNTZcIikge1xuICAgICAgICAvKiAzMi1iaXQgdmFyaWFudCAqL1xuICAgICAgICBudW1Sb3VuZHMgPSA2NDtcbiAgICAgICAgbGVuZ3RoUG9zaXRpb24gPSAoKChtZXNzYWdlTGVuICsgNjUpID4+IDkpIDw8IDQpICsgMTU7XG4gICAgICAgIGJpbmFyeVN0cmluZ0luYyA9IDE2O1xuICAgICAgICBiaW5hcnlTdHJpbmdNdWx0ID0gMTtcbiAgICAgICAgSW50ID0gTnVtYmVyO1xuICAgICAgICBzYWZlQWRkXzIgPSBzYWZlQWRkXzMyXzI7XG4gICAgICAgIHNhZmVBZGRfNCA9IHNhZmVBZGRfMzJfNDtcbiAgICAgICAgc2FmZUFkZF81ID0gc2FmZUFkZF8zMl81O1xuICAgICAgICBnYW1tYTAgPSBnYW1tYTBfMzI7XG4gICAgICAgIGdhbW1hMSA9IGdhbW1hMV8zMjtcbiAgICAgICAgc2lnbWEwID0gc2lnbWEwXzMyO1xuICAgICAgICBzaWdtYTEgPSBzaWdtYTFfMzI7XG4gICAgICAgIG1haiA9IG1hal8zMjtcbiAgICAgICAgY2ggPSBjaF8zMjtcbiAgICAgICAgSyA9IFtcbiAgICAgICAgICAgIDB4NDI4QTJGOTgsIDB4NzEzNzQ0OTEsIDB4QjVDMEZCQ0YsIDB4RTlCNURCQTUsXG4gICAgICAgICAgICAweDM5NTZDMjVCLCAweDU5RjExMUYxLCAweDkyM0Y4MkE0LCAweEFCMUM1RUQ1LFxuICAgICAgICAgICAgMHhEODA3QUE5OCwgMHgxMjgzNUIwMSwgMHgyNDMxODVCRSwgMHg1NTBDN0RDMyxcbiAgICAgICAgICAgIDB4NzJCRTVENzQsIDB4ODBERUIxRkUsIDB4OUJEQzA2QTcsIDB4QzE5QkYxNzQsXG4gICAgICAgICAgICAweEU0OUI2OUMxLCAweEVGQkU0Nzg2LCAweDBGQzE5REM2LCAweDI0MENBMUNDLFxuICAgICAgICAgICAgMHgyREU5MkM2RiwgMHg0QTc0ODRBQSwgMHg1Q0IwQTlEQywgMHg3NkY5ODhEQSxcbiAgICAgICAgICAgIDB4OTgzRTUxNTIsIDB4QTgzMUM2NkQsIDB4QjAwMzI3QzgsIDB4QkY1OTdGQzcsXG4gICAgICAgICAgICAweEM2RTAwQkYzLCAweEQ1QTc5MTQ3LCAweDA2Q0E2MzUxLCAweDE0MjkyOTY3LFxuICAgICAgICAgICAgMHgyN0I3MEE4NSwgMHgyRTFCMjEzOCwgMHg0RDJDNkRGQywgMHg1MzM4MEQxMyxcbiAgICAgICAgICAgIDB4NjUwQTczNTQsIDB4NzY2QTBBQkIsIDB4ODFDMkM5MkUsIDB4OTI3MjJDODUsXG4gICAgICAgICAgICAweEEyQkZFOEExLCAweEE4MUE2NjRCLCAweEMyNEI4QjcwLCAweEM3NkM1MUEzLFxuICAgICAgICAgICAgMHhEMTkyRTgxOSwgMHhENjk5MDYyNCwgMHhGNDBFMzU4NSwgMHgxMDZBQTA3MCxcbiAgICAgICAgICAgIDB4MTlBNEMxMTYsIDB4MUUzNzZDMDgsIDB4Mjc0ODc3NEMsIDB4MzRCMEJDQjUsXG4gICAgICAgICAgICAweDM5MUMwQ0IzLCAweDRFRDhBQTRBLCAweDVCOUNDQTRGLCAweDY4MkU2RkYzLFxuICAgICAgICAgICAgMHg3NDhGODJFRSwgMHg3OEE1NjM2RiwgMHg4NEM4NzgxNCwgMHg4Q0M3MDIwOCxcbiAgICAgICAgICAgIDB4OTBCRUZGRkEsIDB4QTQ1MDZDRUIsIDB4QkVGOUEzRjcsIDB4QzY3MTc4RjJcbiAgICAgICAgXTtcblxuICAgICAgICBpZiAodmFyaWFudCA9PT0gXCJTSEEtMjI0XCIpIHtcbiAgICAgICAgICBIID0gW1xuICAgICAgICAgICAgICAweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuICAgICAgICAgICAgICAweGZmYzAwYjMxLCAweDY4NTgxNTExLCAweDY0Zjk4ZmE3LCAweGJlZmE0ZmE0XG4gICAgICAgICAgXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBIID0gW1xuICAgICAgICAgICAgICAweDZBMDlFNjY3LCAweEJCNjdBRTg1LCAweDNDNkVGMzcyLCAweEE1NEZGNTNBLFxuICAgICAgICAgICAgICAweDUxMEU1MjdGLCAweDlCMDU2ODhDLCAweDFGODNEOUFCLCAweDVCRTBDRDE5XG4gICAgICAgICAgXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh2YXJpYW50ID09PSBcIlNIQS0zODRcIiB8fCB2YXJpYW50ID09PSBcIlNIQS01MTJcIikge1xuICAgICAgICAvKiA2NC1iaXQgdmFyaWFudCAqL1xuICAgICAgICBudW1Sb3VuZHMgPSA4MDtcbiAgICAgICAgbGVuZ3RoUG9zaXRpb24gPSAoKChtZXNzYWdlTGVuICsgMTI4KSA+PiAxMCkgPDwgNSkgKyAzMTtcbiAgICAgICAgYmluYXJ5U3RyaW5nSW5jID0gMzI7XG4gICAgICAgIGJpbmFyeVN0cmluZ011bHQgPSAyO1xuICAgICAgICBJbnQgPSBJbnRfNjQ7XG4gICAgICAgIHNhZmVBZGRfMiA9IHNhZmVBZGRfNjRfMjtcbiAgICAgICAgc2FmZUFkZF80ID0gc2FmZUFkZF82NF80O1xuICAgICAgICBzYWZlQWRkXzUgPSBzYWZlQWRkXzY0XzU7XG4gICAgICAgIGdhbW1hMCA9IGdhbW1hMF82NDtcbiAgICAgICAgZ2FtbWExID0gZ2FtbWExXzY0O1xuICAgICAgICBzaWdtYTAgPSBzaWdtYTBfNjQ7XG4gICAgICAgIHNpZ21hMSA9IHNpZ21hMV82NDtcbiAgICAgICAgbWFqID0gbWFqXzY0O1xuICAgICAgICBjaCA9IGNoXzY0O1xuXG4gICAgICAgIEsgPSBbXG4gICAgICAgICAgICBuZXcgSW50KDB4NDI4YTJmOTgsIDB4ZDcyOGFlMjIpLCBuZXcgSW50KDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QpLFxuICAgICAgICAgICAgbmV3IEludCgweGI1YzBmYmNmLCAweGVjNGQzYjJmKSwgbmV3IEludCgweGU5YjVkYmE1LCAweDgxODlkYmJjKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCksIG5ldyBJbnQoMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSksXG4gICAgICAgICAgICBuZXcgSW50KDB4OTIzZjgyYTQsIDB4YWYxOTRmOWIpLCBuZXcgSW50KDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgpLFxuICAgICAgICAgICAgbmV3IEludCgweGQ4MDdhYTk4LCAweGEzMDMwMjQyKSwgbmV3IEludCgweDEyODM1YjAxLCAweDQ1NzA2ZmJlKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgyNDMxODViZSwgMHg0ZWU0YjI4YyksIG5ldyBJbnQoMHg1NTBjN2RjMywgMHhkNWZmYjRlMiksXG4gICAgICAgICAgICBuZXcgSW50KDB4NzJiZTVkNzQsIDB4ZjI3Yjg5NmYpLCBuZXcgSW50KDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEpLFxuICAgICAgICAgICAgbmV3IEludCgweDliZGMwNmE3LCAweDI1YzcxMjM1KSwgbmV3IEludCgweGMxOWJmMTc0LCAweGNmNjkyNjk0KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhlNDliNjljMSwgMHg5ZWYxNGFkMiksIG5ldyBJbnQoMHhlZmJlNDc4NiwgMHgzODRmMjVlMyksXG4gICAgICAgICAgICBuZXcgSW50KDB4MGZjMTlkYzYsIDB4OGI4Y2Q1YjUpLCBuZXcgSW50KDB4MjQwY2ExY2MsIDB4NzdhYzljNjUpLFxuICAgICAgICAgICAgbmV3IEludCgweDJkZTkyYzZmLCAweDU5MmIwMjc1KSwgbmV3IEludCgweDRhNzQ4NGFhLCAweDZlYTZlNDgzKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCksIG5ldyBJbnQoMHg3NmY5ODhkYSwgMHg4MzExNTNiNSksXG4gICAgICAgICAgICBuZXcgSW50KDB4OTgzZTUxNTIsIDB4ZWU2NmRmYWIpLCBuZXcgSW50KDB4YTgzMWM2NmQsIDB4MmRiNDMyMTApLFxuICAgICAgICAgICAgbmV3IEludCgweGIwMDMyN2M4LCAweDk4ZmIyMTNmKSwgbmV3IEludCgweGJmNTk3ZmM3LCAweGJlZWYwZWU0KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhjNmUwMGJmMywgMHgzZGE4OGZjMiksIG5ldyBJbnQoMHhkNWE3OTE0NywgMHg5MzBhYTcyNSksXG4gICAgICAgICAgICBuZXcgSW50KDB4MDZjYTYzNTEsIDB4ZTAwMzgyNmYpLCBuZXcgSW50KDB4MTQyOTI5NjcsIDB4MGEwZTZlNzApLFxuICAgICAgICAgICAgbmV3IEludCgweDI3YjcwYTg1LCAweDQ2ZDIyZmZjKSwgbmV3IEludCgweDJlMWIyMTM4LCAweDVjMjZjOTI2KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCksIG5ldyBJbnQoMHg1MzM4MGQxMywgMHg5ZDk1YjNkZiksXG4gICAgICAgICAgICBuZXcgSW50KDB4NjUwYTczNTQsIDB4OGJhZjYzZGUpLCBuZXcgSW50KDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgpLFxuICAgICAgICAgICAgbmV3IEludCgweDgxYzJjOTJlLCAweDQ3ZWRhZWU2KSwgbmV3IEludCgweDkyNzIyYzg1LCAweDE0ODIzNTNiKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCksIG5ldyBJbnQoMHhhODFhNjY0YiwgMHhiYzQyMzAwMSksXG4gICAgICAgICAgICBuZXcgSW50KDB4YzI0YjhiNzAsIDB4ZDBmODk3OTEpLCBuZXcgSW50KDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzApLFxuICAgICAgICAgICAgbmV3IEludCgweGQxOTJlODE5LCAweGQ2ZWY1MjE4KSwgbmV3IEludCgweGQ2OTkwNjI0LCAweDU1NjVhOTEwKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSksIG5ldyBJbnQoMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCksXG4gICAgICAgICAgICBuZXcgSW50KDB4MTlhNGMxMTYsIDB4YjhkMmQwYzgpLCBuZXcgSW50KDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMpLFxuICAgICAgICAgICAgbmV3IEludCgweDI3NDg3NzRjLCAweGRmOGVlYjk5KSwgbmV3IEludCgweDM0YjBiY2I1LCAweGUxOWI0OGE4KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgzOTFjMGNiMywgMHhjNWM5NWE2MyksIG5ldyBJbnQoMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYiksXG4gICAgICAgICAgICBuZXcgSW50KDB4NWI5Y2NhNGYsIDB4Nzc2M2UzNzMpLCBuZXcgSW50KDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMpLFxuICAgICAgICAgICAgbmV3IEludCgweDc0OGY4MmVlLCAweDVkZWZiMmZjKSwgbmV3IEludCgweDc4YTU2MzZmLCAweDQzMTcyZjYwKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiksIG5ldyBJbnQoMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyksXG4gICAgICAgICAgICBuZXcgSW50KDB4OTBiZWZmZmEsIDB4MjM2MzFlMjgpLCBuZXcgSW50KDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTkpLFxuICAgICAgICAgICAgbmV3IEludCgweGJlZjlhM2Y3LCAweGIyYzY3OTE1KSwgbmV3IEludCgweGM2NzE3OGYyLCAweGUzNzI1MzJiKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhjYTI3M2VjZSwgMHhlYTI2NjE5YyksIG5ldyBJbnQoMHhkMTg2YjhjNywgMHgyMWMwYzIwNyksXG4gICAgICAgICAgICBuZXcgSW50KDB4ZWFkYTdkZDYsIDB4Y2RlMGViMWUpLCBuZXcgSW50KDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgpLFxuICAgICAgICAgICAgbmV3IEludCgweDA2ZjA2N2FhLCAweDcyMTc2ZmJhKSwgbmV3IEludCgweDBhNjM3ZGM1LCAweGEyYzg5OGE2KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSksIG5ldyBJbnQoMHgxYjcxMGIzNSwgMHgxMzFjNDcxYiksXG4gICAgICAgICAgICBuZXcgSW50KDB4MjhkYjc3ZjUsIDB4MjMwNDdkODQpLCBuZXcgSW50KDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMpLFxuICAgICAgICAgICAgbmV3IEludCgweDNjOWViZTBhLCAweDE1YzliZWJjKSwgbmV3IEludCgweDQzMWQ2N2M0LCAweDljMTAwZDRjKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiksIG5ldyBJbnQoMHg1OTdmMjk5YywgMHhmYzY1N2UyYSksXG4gICAgICAgICAgICBuZXcgSW50KDB4NWZjYjZmYWIsIDB4M2FkNmZhZWMpLCBuZXcgSW50KDB4NmM0NDE5OGMsIDB4NGE0NzU4MTcpXG4gICAgICAgIF07XG5cbiAgICAgICAgaWYgKHZhcmlhbnQgPT09IFwiU0hBLTM4NFwiKSB7XG4gICAgICAgICAgSCA9IFtcbiAgICAgICAgICAgICAgbmV3IEludCgweGNiYmI5ZDVkLCAweGMxMDU5ZWQ4KSwgbmV3IEludCgweDA2MjlhMjkyYSwgMHgzNjdjZDUwNyksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHg5MTU5MDE1YSwgMHgzMDcwZGQxNyksIG5ldyBJbnQoMHgwMTUyZmVjZDgsIDB4ZjcwZTU5MzkpLFxuICAgICAgICAgICAgICBuZXcgSW50KDB4NjczMzI2NjcsIDB4ZmZjMDBiMzEpLCBuZXcgSW50KDB4OThlYjQ0YTg3LCAweDY4NTgxNTExKSxcbiAgICAgICAgICAgICAgbmV3IEludCgweGRiMGMyZTBkLCAweDY0Zjk4ZmE3KSwgbmV3IEludCgweDA0N2I1NDgxZCwgMHhiZWZhNGZhNClcbiAgICAgICAgICBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIEggPSBbXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCksIG5ldyBJbnQoMHhiYjY3YWU4NSwgMHg4NGNhYTczYiksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHgzYzZlZjM3MiwgMHhmZTk0ZjgyYiksIG5ldyBJbnQoMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHg1MTBlNTI3ZiwgMHhhZGU2ODJkMSksIG5ldyBJbnQoMHg5YjA1Njg4YywgMHgyYjNlNmMxZiksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YiksIG5ldyBJbnQoMHg1YmUwY2QxOSwgMHgxMzdlMjE3OSlcbiAgICAgICAgICBdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8qIEFwcGVuZCAnMScgYXQgdGhlIGVuZCBvZiB0aGUgYmluYXJ5IHN0cmluZyAqL1xuICAgICAgbWVzc2FnZVttZXNzYWdlTGVuID4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gbWVzc2FnZUxlbiAlIDMyKTtcbiAgICAgIC8qIEFwcGVuZCBsZW5ndGggb2YgYmluYXJ5IHN0cmluZyBpbiB0aGUgcG9zaXRpb24gc3VjaCB0aGF0IHRoZSBuZXdcbiAgICAgICAqIGxlbmd0aCBpcyBjb3JyZWN0ICovXG4gICAgICBtZXNzYWdlW2xlbmd0aFBvc2l0aW9uXSA9IG1lc3NhZ2VMZW47XG5cbiAgICAgIGFwcGVuZGVkTWVzc2FnZUxlbmd0aCA9IG1lc3NhZ2UubGVuZ3RoO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoOyBpICs9IGJpbmFyeVN0cmluZ0luYykge1xuICAgICAgICBhID0gSFswXTtcbiAgICAgICAgYiA9IEhbMV07XG4gICAgICAgIGMgPSBIWzJdO1xuICAgICAgICBkID0gSFszXTtcbiAgICAgICAgZSA9IEhbNF07XG4gICAgICAgIGYgPSBIWzVdO1xuICAgICAgICBnID0gSFs2XTtcbiAgICAgICAgaCA9IEhbN107XG5cbiAgICAgICAgZm9yICh0ID0gMDsgdCA8IG51bVJvdW5kczsgdCArPSAxKSB7XG4gICAgICAgICAgaWYgKHQgPCAxNikge1xuICAgICAgICAgICAgLyogQml0IG9mIGEgaGFjayAtIGZvciAzMi1iaXQsIHRoZSBzZWNvbmQgdGVybSBpcyBpZ25vcmVkICovXG4gICAgICAgICAgICBXW3RdID0gbmV3IEludChtZXNzYWdlW3QgKiBiaW5hcnlTdHJpbmdNdWx0ICsgaV0sXG4gICAgICAgICAgICAgIG1lc3NhZ2VbdCAqIGJpbmFyeVN0cmluZ011bHQgKyBpICsgMV0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBXW3RdID0gc2FmZUFkZF80KFxuICAgICAgICAgICAgICBnYW1tYTEoV1t0IC0gMl0pLCBXW3QgLSA3XSxcbiAgICAgICAgICAgICAgZ2FtbWEwKFdbdCAtIDE1XSksIFdbdCAtIDE2XSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgVDEgPSBzYWZlQWRkXzUoaCwgc2lnbWExKGUpLCBjaChlLCBmLCBnKSwgS1t0XSwgV1t0XSk7XG4gICAgICAgICAgVDIgPSBzYWZlQWRkXzIoc2lnbWEwKGEpLCBtYWooYSwgYiwgYykpO1xuICAgICAgICAgIGggPSBnO1xuICAgICAgICAgIGcgPSBmO1xuICAgICAgICAgIGYgPSBlO1xuICAgICAgICAgIGUgPSBzYWZlQWRkXzIoZCwgVDEpO1xuICAgICAgICAgIGQgPSBjO1xuICAgICAgICAgIGMgPSBiO1xuICAgICAgICAgIGIgPSBhO1xuICAgICAgICAgIGEgPSBzYWZlQWRkXzIoVDEsIFQyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIEhbMF0gPSBzYWZlQWRkXzIoYSwgSFswXSk7XG4gICAgICAgIEhbMV0gPSBzYWZlQWRkXzIoYiwgSFsxXSk7XG4gICAgICAgIEhbMl0gPSBzYWZlQWRkXzIoYywgSFsyXSk7XG4gICAgICAgIEhbM10gPSBzYWZlQWRkXzIoZCwgSFszXSk7XG4gICAgICAgIEhbNF0gPSBzYWZlQWRkXzIoZSwgSFs0XSk7XG4gICAgICAgIEhbNV0gPSBzYWZlQWRkXzIoZiwgSFs1XSk7XG4gICAgICAgIEhbNl0gPSBzYWZlQWRkXzIoZywgSFs2XSk7XG4gICAgICAgIEhbN10gPSBzYWZlQWRkXzIoaCwgSFs3XSk7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAodmFyaWFudCkge1xuICAgICAgICBjYXNlIFwiU0hBLTIyNFwiOlxuICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBIWzBdLCBIWzFdLCBIWzJdLCBIWzNdLFxuICAgICAgICAgICAgSFs0XSwgSFs1XSwgSFs2XV07XG4gICAgICAgIGNhc2UgXCJTSEEtMjU2XCI6XG4gICAgICAgICAgcmV0dXJuIEg7XG4gICAgICAgIGNhc2UgXCJTSEEtMzg0XCI6XG4gICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIEhbMF0uaGlnaE9yZGVyLCBIWzBdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFsxXS5oaWdoT3JkZXIsIEhbMV0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzJdLmhpZ2hPcmRlciwgSFsyXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbM10uaGlnaE9yZGVyLCBIWzNdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs0XS5oaWdoT3JkZXIsIEhbNF0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzVdLmhpZ2hPcmRlciwgSFs1XS5sb3dPcmRlcl07XG4gICAgICAgIGNhc2UgXCJTSEEtNTEyXCI6XG4gICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIEhbMF0uaGlnaE9yZGVyLCBIWzBdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFsxXS5oaWdoT3JkZXIsIEhbMV0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzJdLmhpZ2hPcmRlciwgSFsyXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbM10uaGlnaE9yZGVyLCBIWzNdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs0XS5oaWdoT3JkZXIsIEhbNF0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzVdLmhpZ2hPcmRlciwgSFs1XS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbNl0uaGlnaE9yZGVyLCBIWzZdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs3XS5oaWdoT3JkZXIsIEhbN10ubG93T3JkZXJdO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8qIFRoaXMgc2hvdWxkIG5ldmVyIGJlIHJlYWNoZWQgKi9cbiAgICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qXG4gICAgICoganNTSEEgaXMgdGhlIHdvcmtob3JzZSBvZiB0aGUgbGlicmFyeS4gIEluc3RhbnRpYXRlIGl0IHdpdGggdGhlIHN0cmluZyB0b1xuICAgICAqIGJlIGhhc2hlZCBhcyB0aGUgcGFyYW1ldGVyXG4gICAgICpcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gc3JjU3RyaW5nIFRoZSBzdHJpbmcgdG8gYmUgaGFzaGVkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0Rm9ybWF0IFRoZSBmb3JtYXQgb2Ygc3JjU3RyaW5nLCBBU0NJSSBvciBIRVhcbiAgICAgKi9cbiAgICBqc1NIQSA9IGZ1bmN0aW9uKHNyY1N0cmluZywgaW5wdXRGb3JtYXQpIHtcblxuICAgICAgdGhpcy5zaGExID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhMjI0ID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhMjU2ID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhMzg0ID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhNTEyID0gbnVsbDtcblxuICAgICAgdGhpcy5zdHJCaW5MZW4gPSBudWxsO1xuICAgICAgdGhpcy5zdHJUb0hhc2ggPSBudWxsO1xuXG4gICAgICAvKiBDb252ZXJ0IHRoZSBpbnB1dCBzdHJpbmcgaW50byB0aGUgY29ycmVjdCB0eXBlICovXG4gICAgICBpZiAoXCJIRVhcIiA9PT0gaW5wdXRGb3JtYXQpIHtcbiAgICAgICAgaWYgKDAgIT09IChzcmNTdHJpbmcubGVuZ3RoICUgMikpIHtcbiAgICAgICAgICByZXR1cm4gXCJURVhUIE1VU1QgQkUgSU4gQllURSBJTkNSRU1FTlRTXCI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdHJCaW5MZW4gPSBzcmNTdHJpbmcubGVuZ3RoICogNDtcbiAgICAgICAgdGhpcy5zdHJUb0hhc2ggPSBoZXgyYmluYihzcmNTdHJpbmcpO1xuICAgICAgfSBlbHNlIGlmICgoXCJBU0NJSVwiID09PSBpbnB1dEZvcm1hdCkgfHxcbiAgICAgICAgKCd1bmRlZmluZWQnID09PSB0eXBlb2YoaW5wdXRGb3JtYXQpKSkge1xuICAgICAgICB0aGlzLnN0ckJpbkxlbiA9IHNyY1N0cmluZy5sZW5ndGggKiBjaGFyU2l6ZTtcbiAgICAgICAgdGhpcy5zdHJUb0hhc2ggPSBzdHIyYmluYihzcmNTdHJpbmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFwiVU5LTk9XTiBURVhUIElOUFVUIFRZUEVcIjtcbiAgICAgIH1cbiAgICB9O1xuXG4gIGpzU0hBLnByb3RvdHlwZSA9IHtcbiAgICAvKlxuICAgICAqIFJldHVybnMgdGhlIGRlc2lyZWQgU0hBIGhhc2ggb2YgdGhlIHN0cmluZyBzcGVjaWZpZWQgYXQgaW5zdGFudGlhdGlvblxuICAgICAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyc1xuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHZhcmlhbnQgVGhlIGRlc2lyZWQgU0hBIHZhcmlhbnQgKFNIQS0xLCBTSEEtMjI0LFxuICAgICAqXHQgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMilcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZm9ybWF0IFRoZSBkZXNpcmVkIG91dHB1dCBmb3JtYXR0aW5nIChCNjQgb3IgSEVYKVxuICAgICAqIEByZXR1cm4gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaGFzaCBpbiB0aGUgZm9ybWF0IHNwZWNpZmllZFxuICAgICAqL1xuICAgIGdldEhhc2g6IGZ1bmN0aW9uKHZhcmlhbnQsIGZvcm1hdCkge1xuICAgICAgdmFyIGZvcm1hdEZ1bmMgPSBudWxsLFxuICAgICAgICBtZXNzYWdlID0gdGhpcy5zdHJUb0hhc2guc2xpY2UoKTtcblxuICAgICAgc3dpdGNoIChmb3JtYXQpIHtcbiAgICAgICAgY2FzZSBcIkhFWFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmhleDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkI2NFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmI2NDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkFTQ0lJXCI6XG4gICAgICAgICAgZm9ybWF0RnVuYyA9IGJpbmIyc3RyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBcIkZPUk1BVCBOT1QgUkVDT0dOSVpFRFwiO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHZhcmlhbnQpIHtcbiAgICAgICAgY2FzZSBcIlNIQS0xXCI6XG4gICAgICAgICAgaWYgKG51bGwgPT09IHRoaXMuc2hhMSkge1xuICAgICAgICAgICAgdGhpcy5zaGExID0gY29yZVNIQTEobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTEpO1xuICAgICAgICBjYXNlIFwiU0hBLTIyNFwiOlxuICAgICAgICAgIGlmIChudWxsID09PSB0aGlzLnNoYTIyNCkge1xuICAgICAgICAgICAgdGhpcy5zaGEyMjQgPSBjb3JlU0hBMihtZXNzYWdlLCB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmb3JtYXRGdW5jKHRoaXMuc2hhMjI0KTtcbiAgICAgICAgY2FzZSBcIlNIQS0yNTZcIjpcbiAgICAgICAgICBpZiAobnVsbCA9PT0gdGhpcy5zaGEyNTYpIHtcbiAgICAgICAgICAgIHRoaXMuc2hhMjU2ID0gY29yZVNIQTIobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4sIHZhcmlhbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTI1Nik7XG4gICAgICAgIGNhc2UgXCJTSEEtMzg0XCI6XG4gICAgICAgICAgaWYgKG51bGwgPT09IHRoaXMuc2hhMzg0KSB7XG4gICAgICAgICAgICB0aGlzLnNoYTM4NCA9IGNvcmVTSEEyKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGZvcm1hdEZ1bmModGhpcy5zaGEzODQpO1xuICAgICAgICBjYXNlIFwiU0hBLTUxMlwiOlxuICAgICAgICAgIGlmIChudWxsID09PSB0aGlzLnNoYTUxMikge1xuICAgICAgICAgICAgdGhpcy5zaGE1MTIgPSBjb3JlU0hBMihtZXNzYWdlLCB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmb3JtYXRGdW5jKHRoaXMuc2hhNTEyKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gXCJIQVNIIE5PVCBSRUNPR05JWkVEXCI7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBITUFDIG9mIHRoZSBzdHJpbmcgc3BlY2lmaWVkIGF0IGluc3RhbnRpYXRpb25cbiAgICAgKiB1c2luZyB0aGUga2V5IGFuZCB2YXJpYW50IHBhcmFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGtleSBUaGUga2V5IHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBITUFDXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0Rm9ybWF0IFRoZSBmb3JtYXQgb2Yga2V5LCBBU0NJSSBvciBIRVhcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdmFyaWFudCBUaGUgZGVzaXJlZCBTSEEgdmFyaWFudCAoU0hBLTEsIFNIQS0yMjQsXG4gICAgICpcdCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyKVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBvdXRwdXRGb3JtYXQgVGhlIGRlc2lyZWQgb3V0cHV0IGZvcm1hdHRpbmdcbiAgICAgKlx0IChCNjQgb3IgSEVYKVxuICAgICAqIEByZXR1cm4gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaGFzaCBpbiB0aGUgZm9ybWF0IHNwZWNpZmllZFxuICAgICAqL1xuICAgIGdldEhNQUM6IGZ1bmN0aW9uKGtleSwgaW5wdXRGb3JtYXQsIHZhcmlhbnQsIG91dHB1dEZvcm1hdCkge1xuICAgICAgdmFyIGZvcm1hdEZ1bmMsIGtleVRvVXNlLCBibG9ja0J5dGVTaXplLCBibG9ja0JpdFNpemUsIGksXG4gICAgICAgIHJldFZhbCwgbGFzdEFycmF5SW5kZXgsIGtleUJpbkxlbiwgaGFzaEJpdFNpemUsXG4gICAgICAgIGtleVdpdGhJUGFkID0gW10sXG4gICAgICAgIGtleVdpdGhPUGFkID0gW107XG5cbiAgICAgIC8qIFZhbGlkYXRlIHRoZSBvdXRwdXQgZm9ybWF0IHNlbGVjdGlvbiAqL1xuICAgICAgc3dpdGNoIChvdXRwdXRGb3JtYXQpIHtcbiAgICAgICAgY2FzZSBcIkhFWFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmhleDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkI2NFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmI2NDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkFTQ0lJXCI6XG4gICAgICAgICAgZm9ybWF0RnVuYyA9IGJpbmIyc3RyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBcIkZPUk1BVCBOT1QgUkVDT0dOSVpFRFwiO1xuICAgICAgfVxuXG4gICAgICAvKiBWYWxpZGF0ZSB0aGUgaGFzaCB2YXJpYW50IHNlbGVjdGlvbiBhbmQgc2V0IG5lZWRlZCB2YXJpYWJsZXMgKi9cbiAgICAgIHN3aXRjaCAodmFyaWFudCkge1xuICAgICAgICBjYXNlIFwiU0hBLTFcIjpcbiAgICAgICAgICBibG9ja0J5dGVTaXplID0gNjQ7XG4gICAgICAgICAgaGFzaEJpdFNpemUgPSAxNjA7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJTSEEtMjI0XCI6XG4gICAgICAgICAgYmxvY2tCeXRlU2l6ZSA9IDY0O1xuICAgICAgICAgIGhhc2hCaXRTaXplID0gMjI0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiU0hBLTI1NlwiOlxuICAgICAgICAgIGJsb2NrQnl0ZVNpemUgPSA2NDtcbiAgICAgICAgICBoYXNoQml0U2l6ZSA9IDI1NjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIlNIQS0zODRcIjpcbiAgICAgICAgICBibG9ja0J5dGVTaXplID0gMTI4O1xuICAgICAgICAgIGhhc2hCaXRTaXplID0gMzg0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiU0hBLTUxMlwiOlxuICAgICAgICAgIGJsb2NrQnl0ZVNpemUgPSAxMjg7XG4gICAgICAgICAgaGFzaEJpdFNpemUgPSA1MTI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIFwiSEFTSCBOT1QgUkVDT0dOSVpFRFwiO1xuICAgICAgfVxuXG4gICAgICAvKiBWYWxpZGF0ZSBpbnB1dCBmb3JtYXQgc2VsZWN0aW9uICovXG4gICAgICBpZiAoXCJIRVhcIiA9PT0gaW5wdXRGb3JtYXQpIHtcbiAgICAgICAgLyogTmliYmxlcyBtdXN0IGNvbWUgaW4gcGFpcnMgKi9cbiAgICAgICAgaWYgKDAgIT09IChrZXkubGVuZ3RoICUgMikpIHtcbiAgICAgICAgICByZXR1cm4gXCJLRVkgTVVTVCBCRSBJTiBCWVRFIElOQ1JFTUVOVFNcIjtcbiAgICAgICAgfVxuICAgICAgICBrZXlUb1VzZSA9IGhleDJiaW5iKGtleSk7XG4gICAgICAgIGtleUJpbkxlbiA9IGtleS5sZW5ndGggKiA0O1xuICAgICAgfSBlbHNlIGlmIChcIkFTQ0lJXCIgPT09IGlucHV0Rm9ybWF0KSB7XG4gICAgICAgIGtleVRvVXNlID0gc3RyMmJpbmIoa2V5KTtcbiAgICAgICAga2V5QmluTGVuID0ga2V5Lmxlbmd0aCAqIGNoYXJTaXplO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFwiVU5LTk9XTiBLRVkgSU5QVVQgVFlQRVwiO1xuICAgICAgfVxuXG4gICAgICAvKiBUaGVzZSBhcmUgdXNlZCBtdWx0aXBsZSB0aW1lcywgY2FsY3VsYXRlIGFuZCBzdG9yZSB0aGVtICovXG4gICAgICBibG9ja0JpdFNpemUgPSBibG9ja0J5dGVTaXplICogODtcbiAgICAgIGxhc3RBcnJheUluZGV4ID0gKGJsb2NrQnl0ZVNpemUgLyA0KSAtIDE7XG5cbiAgICAgIC8qIEZpZ3VyZSBvdXQgd2hhdCB0byBkbyB3aXRoIHRoZSBrZXkgYmFzZWQgb24gaXRzIHNpemUgcmVsYXRpdmUgdG9cbiAgICAgICAqIHRoZSBoYXNoJ3MgYmxvY2sgc2l6ZSAqL1xuICAgICAgaWYgKGJsb2NrQnl0ZVNpemUgPCAoa2V5QmluTGVuIC8gOCkpIHtcbiAgICAgICAgaWYgKFwiU0hBLTFcIiA9PT0gdmFyaWFudCkge1xuICAgICAgICAgIGtleVRvVXNlID0gY29yZVNIQTEoa2V5VG9Vc2UsIGtleUJpbkxlbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2V5VG9Vc2UgPSBjb3JlU0hBMihrZXlUb1VzZSwga2V5QmluTGVuLCB2YXJpYW50KTtcbiAgICAgICAgfVxuICAgICAgICAvKiBGb3IgYWxsIHZhcmlhbnRzLCB0aGUgYmxvY2sgc2l6ZSBpcyBiaWdnZXIgdGhhbiB0aGUgb3V0cHV0XG4gICAgICAgICAqIHNpemUgc28gdGhlcmUgd2lsbCBuZXZlciBiZSBhIHVzZWZ1bCBieXRlIGF0IHRoZSBlbmQgb2YgdGhlXG4gICAgICAgICAqIHN0cmluZyAqL1xuICAgICAgICBrZXlUb1VzZVtsYXN0QXJyYXlJbmRleF0gJj0gMHhGRkZGRkYwMDtcbiAgICAgIH0gZWxzZSBpZiAoYmxvY2tCeXRlU2l6ZSA+IChrZXlCaW5MZW4gLyA4KSkge1xuICAgICAgICAvKiBJZiB0aGUgYmxvY2tCeXRlU2l6ZSBpcyBncmVhdGVyIHRoYW4gdGhlIGtleSBsZW5ndGgsIHRoZXJlXG4gICAgICAgICAqIHdpbGwgYWx3YXlzIGJlIGF0IExFQVNUIG9uZSBcInVzZWxlc3NcIiBieXRlIGF0IHRoZSBlbmQgb2YgdGhlXG4gICAgICAgICAqIHN0cmluZyAqL1xuICAgICAgICBrZXlUb1VzZVtsYXN0QXJyYXlJbmRleF0gJj0gMHhGRkZGRkYwMDtcbiAgICAgIH1cblxuICAgICAgLyogQ3JlYXRlIGlwYWQgYW5kIG9wYWQgKi9cbiAgICAgIGZvciAoaSA9IDA7IGkgPD0gbGFzdEFycmF5SW5kZXg7IGkgKz0gMSkge1xuICAgICAgICBrZXlXaXRoSVBhZFtpXSA9IGtleVRvVXNlW2ldIF4gMHgzNjM2MzYzNjtcbiAgICAgICAga2V5V2l0aE9QYWRbaV0gPSBrZXlUb1VzZVtpXSBeIDB4NUM1QzVDNUM7XG4gICAgICB9XG5cbiAgICAgIC8qIENhbGN1bGF0ZSB0aGUgSE1BQyAqL1xuICAgICAgaWYgKFwiU0hBLTFcIiA9PT0gdmFyaWFudCkge1xuICAgICAgICByZXRWYWwgPSBjb3JlU0hBMShcbiAgICAgICAgICBrZXlXaXRoSVBhZC5jb25jYXQodGhpcy5zdHJUb0hhc2gpLFxuICAgICAgICAgIGJsb2NrQml0U2l6ZSArIHRoaXMuc3RyQmluTGVuKTtcbiAgICAgICAgcmV0VmFsID0gY29yZVNIQTEoXG4gICAgICAgICAga2V5V2l0aE9QYWQuY29uY2F0KHJldFZhbCksXG4gICAgICAgICAgYmxvY2tCaXRTaXplICsgaGFzaEJpdFNpemUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0VmFsID0gY29yZVNIQTIoXG4gICAgICAgICAga2V5V2l0aElQYWQuY29uY2F0KHRoaXMuc3RyVG9IYXNoKSxcbiAgICAgICAgICBibG9ja0JpdFNpemUgKyB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgIHJldFZhbCA9IGNvcmVTSEEyKFxuICAgICAgICAgIGtleVdpdGhPUGFkLmNvbmNhdChyZXRWYWwpLFxuICAgICAgICAgIGJsb2NrQml0U2l6ZSArIGhhc2hCaXRTaXplLCB2YXJpYW50KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIChmb3JtYXRGdW5jKHJldFZhbCkpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4ganNTSEE7XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2hhMTogZnVuY3Rpb24oc3RyKSB7XG4gICAgdmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsIFwiQVNDSUlcIik7XG4gICAgcmV0dXJuIHNoYU9iai5nZXRIYXNoKFwiU0hBLTFcIiwgXCJBU0NJSVwiKTtcbiAgfSxcbiAgc2hhMjI0OiBmdW5jdGlvbihzdHIpIHtcbiAgICB2YXIgc2hhT2JqID0gbmV3IGpzU0hBKHN0ciwgXCJBU0NJSVwiKTtcbiAgICByZXR1cm4gc2hhT2JqLmdldEhhc2goXCJTSEEtMjI0XCIsIFwiQVNDSUlcIik7XG4gIH0sXG4gIHNoYTI1NjogZnVuY3Rpb24oc3RyKSB7XG4gICAgdmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsIFwiQVNDSUlcIik7XG4gICAgcmV0dXJuIHNoYU9iai5nZXRIYXNoKFwiU0hBLTI1NlwiLCBcIkFTQ0lJXCIpO1xuICB9LFxuICBzaGEzODQ6IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCBcIkFTQ0lJXCIpO1xuICAgIHJldHVybiBzaGFPYmouZ2V0SGFzaChcIlNIQS0zODRcIiwgXCJBU0NJSVwiKTtcblxuICB9LFxuICBzaGE1MTI6IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCBcIkFTQ0lJXCIpO1xuICAgIHJldHVybiBzaGFPYmouZ2V0SGFzaChcIlNIQS01MTJcIiwgXCJBU0NJSVwiKTtcbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIGNpcGhlcjogcmVxdWlyZSgnLi9jaXBoZXInKSxcbiAgaGFzaDogcmVxdWlyZSgnLi9oYXNoJyksXG4gIGNmYjogcmVxdWlyZSgnLi9jZmIuanMnKSxcbiAgcHVibGljS2V5OiByZXF1aXJlKCcuL3B1YmxpY19rZXknKSxcbiAgc2lnbmF0dXJlOiByZXF1aXJlKCcuL3NpZ25hdHVyZS5qcycpLFxuICByYW5kb206IHJlcXVpcmUoJy4vcmFuZG9tLmpzJyksXG4gIHBrY3MxOiByZXF1aXJlKCcuL3BrY3MxLmpzJylcblxufVxuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnLi9jcnlwdG8uanMnKTtcblxuZm9yICh2YXIgaSBpbiBjcnlwdG8pXG4gIG1vZHVsZS5leHBvcnRzW2ldID0gY3J5cHRvW2ldO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBBU04xIG9iamVjdCBpZGVudGlmaWVycyBmb3IgaGFzaGVzIChTZWUgUkZDNDg4MCA1LjIuMilcbiAqL1xuaGFzaF9oZWFkZXJzID0gbmV3IEFycmF5KCk7XG5oYXNoX2hlYWRlcnNbMV0gPSBbMHgzMCwgMHgyMCwgMHgzMCwgMHgwYywgMHgwNiwgMHgwOCwgMHgyYSwgMHg4NiwgMHg0OCwgMHg4NiwgMHhmNywgMHgwZCwgMHgwMiwgMHgwNSwgMHgwNSwgMHgwMCwgMHgwNCxcbiAgICAweDEwXG5dO1xuaGFzaF9oZWFkZXJzWzNdID0gWzB4MzAsIDB4MjEsIDB4MzAsIDB4MDksIDB4MDYsIDB4MDUsIDB4MkIsIDB4MjQsIDB4MDMsIDB4MDIsIDB4MDEsIDB4MDUsIDB4MDAsIDB4MDQsIDB4MTRdO1xuaGFzaF9oZWFkZXJzWzJdID0gWzB4MzAsIDB4MjEsIDB4MzAsIDB4MDksIDB4MDYsIDB4MDUsIDB4MmIsIDB4MGUsIDB4MDMsIDB4MDIsIDB4MWEsIDB4MDUsIDB4MDAsIDB4MDQsIDB4MTRdO1xuaGFzaF9oZWFkZXJzWzhdID0gWzB4MzAsIDB4MzEsIDB4MzAsIDB4MGQsIDB4MDYsIDB4MDksIDB4NjAsIDB4ODYsIDB4NDgsIDB4MDEsIDB4NjUsIDB4MDMsIDB4MDQsIDB4MDIsIDB4MDEsIDB4MDUsIDB4MDAsXG4gICAgMHgwNCwgMHgyMFxuXTtcbmhhc2hfaGVhZGVyc1s5XSA9IFsweDMwLCAweDQxLCAweDMwLCAweDBkLCAweDA2LCAweDA5LCAweDYwLCAweDg2LCAweDQ4LCAweDAxLCAweDY1LCAweDAzLCAweDA0LCAweDAyLCAweDAyLCAweDA1LCAweDAwLFxuICAgIDB4MDQsIDB4MzBcbl07XG5oYXNoX2hlYWRlcnNbMTBdID0gWzB4MzAsIDB4NTEsIDB4MzAsIDB4MGQsIDB4MDYsIDB4MDksIDB4NjAsIDB4ODYsIDB4NDgsIDB4MDEsIDB4NjUsIDB4MDMsIDB4MDQsIDB4MDIsIDB4MDMsIDB4MDUsXG4gICAgMHgwMCwgMHgwNCwgMHg0MFxuXTtcbmhhc2hfaGVhZGVyc1sxMV0gPSBbMHgzMCwgMHgzMSwgMHgzMCwgMHgwZCwgMHgwNiwgMHgwOSwgMHg2MCwgMHg4NiwgMHg0OCwgMHgwMSwgMHg2NSwgMHgwMywgMHgwNCwgMHgwMiwgMHgwNCwgMHgwNSxcbiAgICAweDAwLCAweDA0LCAweDFDXG5dO1xuXG5cbnZhciBjcnlwdG8gPSByZXF1aXJlKCcuL2NyeXB0by5qcycpLFxuICByYW5kb20gPSByZXF1aXJlKCcuL3JhbmRvbS5qcycpLFxuICB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5L2pzYm4uanMnKSxcbiAgaGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZW1lOiB7XG4gICAgLyoqXG4gICAgICogY3JlYXRlIGEgRU1FLVBLQ1MxLXYxXzUgcGFkZGluZyAoU2VlIFJGQzQ4ODAgMTMuMS4xKVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIG1lc3NhZ2UgdG8gYmUgcGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIHRvIHRoZSByZXN1bHRpbmcgbWVzc2FnZVxuICAgICAqIEByZXR1cm4ge1N0cmluZ30gRU1FLVBLQ1MxIHBhZGRlZCBtZXNzYWdlXG4gICAgICovXG4gICAgZW5jb2RlOiBmdW5jdGlvbihtZXNzYWdlLCBsZW5ndGgpIHtcbiAgICAgIGlmIChtZXNzYWdlLmxlbmd0aCA+IGxlbmd0aCAtIDExKVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMik7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aCAtIG1lc3NhZ2UubGVuZ3RoIC0gMzsgaSsrKSB7XG4gICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHJhbmRvbS5nZXRQc2V1ZG9SYW5kb20oMSwgMjU1KSk7XG4gICAgICB9XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICAgIHJlc3VsdCArPSBtZXNzYWdlO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogZGVjb2RlcyBhIEVNRS1QS0NTMS12MV81IHBhZGRpbmcgKFNlZSBSRkM0ODgwIDEzLjEuMilcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBFTUUtUEtDUzEgcGFkZGVkIG1lc3NhZ2VcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IGRlY29kZWQgbWVzc2FnZSBcbiAgICAgKi9cbiAgICBkZWNvZGU6IGZ1bmN0aW9uKG1lc3NhZ2UsIGxlbikge1xuICAgICAgaWYgKG1lc3NhZ2UubGVuZ3RoIDwgbGVuKVxuICAgICAgICBtZXNzYWdlID0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKSArIG1lc3NhZ2U7XG4gICAgICBpZiAobWVzc2FnZS5sZW5ndGggPCAxMiB8fCBtZXNzYWdlLmNoYXJDb2RlQXQoMCkgIT0gMCB8fCBtZXNzYWdlLmNoYXJDb2RlQXQoMSkgIT0gMilcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgdmFyIGkgPSAyO1xuICAgICAgd2hpbGUgKG1lc3NhZ2UuY2hhckNvZGVBdChpKSAhPSAwICYmIG1lc3NhZ2UubGVuZ3RoID4gaSlcbiAgICAgICAgaSsrO1xuICAgICAgcmV0dXJuIG1lc3NhZ2Uuc3Vic3RyaW5nKGkgKyAxLCBtZXNzYWdlLmxlbmd0aCk7XG4gICAgfSxcbiAgfSxcblxuICBlbXNhOiB7XG5cbiAgICAvKipcbiAgICAgKiBjcmVhdGUgYSBFTVNBLVBLQ1MxLXYxXzUgcGFkZGluZyAoU2VlIFJGQzQ4ODAgMTMuMS4zKVxuICAgICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBIYXNoIGFsZ29yaXRobSB0eXBlIHVzZWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGJlIGhhc2hlZFxuICAgICAqIEBwYXJhbSB7SW50ZWdlcn0ga2V5bGVuZ3RoIEtleSBzaXplIG9mIHRoZSBwdWJsaWMgbXBpIGluIGJ5dGVzXG4gICAgICogQHJldHVybnMge1N0cmluZ30gSGFzaGNvZGUgd2l0aCBwa2NzMXBhZGRpbmcgYXMgc3RyaW5nXG4gICAgICovXG4gICAgZW5jb2RlOiBmdW5jdGlvbihhbGdvLCBkYXRhLCBrZXlsZW5ndGgpIHtcbiAgICAgIHZhciBkYXRhMiA9IFwiXCI7XG4gICAgICBkYXRhMiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApO1xuICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAxKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgKGtleWxlbmd0aCAtIGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGggLSAzIC1cbiAgICAgICAgaGFzaC5nZXRIYXNoQnl0ZUxlbmd0aChhbGdvKSk7IGkrKylcblxuICAgICAgICBkYXRhMiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ZmYpO1xuXG4gICAgICBkYXRhMiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGg7IGkrKylcbiAgICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShoYXNoX2hlYWRlcnNbYWxnb11baV0pO1xuXG4gICAgICBkYXRhMiArPSBoYXNoLmRpZ2VzdChhbGdvLCBkYXRhKTtcbiAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcih1dGlsLmhleHN0cmR1bXAoZGF0YTIpLCAxNik7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGV4dHJhY3QgdGhlIGhhc2ggb3V0IG9mIGFuIEVNU0EtUEtDUzEtdjEuNSBwYWRkaW5nIChTZWUgUkZDNDg4MCAxMy4xLjMpIFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIEhhc2ggaW4gcGtjczEgZW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgaGFzaCBhcyBzdHJpbmdcbiAgICAgKi9cbiAgICBkZWNvZGU6IGZ1bmN0aW9uKGFsZ28sIGRhdGEpIHtcbiAgICAgIHZhciBpID0gMDtcbiAgICAgIGlmIChkYXRhLmNoYXJDb2RlQXQoMCkgPT0gMCkgaSsrO1xuICAgICAgZWxzZSBpZiAoZGF0YS5jaGFyQ29kZUF0KDApICE9IDEpIHJldHVybiAtMTtcbiAgICAgIGVsc2UgaSsrO1xuXG4gICAgICB3aGlsZSAoZGF0YS5jaGFyQ29kZUF0KGkpID09IDB4RkYpIGkrKztcbiAgICAgIGlmIChkYXRhLmNoYXJDb2RlQXQoaSsrKSAhPSAwKSByZXR1cm4gLTE7XG4gICAgICB2YXIgaiA9IDA7XG4gICAgICBmb3IgKGogPSAwOyBqIDwgaGFzaF9oZWFkZXJzW2FsZ29dLmxlbmd0aCAmJiBqICsgaSA8IGRhdGEubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKGRhdGEuY2hhckNvZGVBdChqICsgaSkgIT0gaGFzaF9oZWFkZXJzW2FsZ29dW2pdKSByZXR1cm4gLTE7XG4gICAgICB9XG4gICAgICBpICs9IGo7XG4gICAgICBpZiAoZGF0YS5zdWJzdHJpbmcoaSkubGVuZ3RoIDwgaGFzaC5nZXRIYXNoQnl0ZUxlbmd0aChhbGdvKSkgcmV0dXJuIC0xO1xuICAgICAgcmV0dXJuIGRhdGEuc3Vic3RyaW5nKGkpO1xuICAgIH1cbiAgfVxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0Fcbi8vXG4vLyBBIERpZ2l0YWwgc2lnbmF0dXJlIGFsZ29yaXRobSBpbXBsZW1lbnRhdGlvblxuXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vanNibi5qcycpLFxuICByYW5kb20gPSByZXF1aXJlKCcuLi9yYW5kb20uanMnKSxcbiAgaGFzaE1vZHVsZSA9IHJlcXVpcmUoJy4uL2hhc2gnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuZnVuY3Rpb24gRFNBKCkge1xuICAvLyBzMSA9ICgoZyoqcykgbW9kIHApIG1vZCBxXG4gIC8vIHMxID0gKChzKiotMSkqKHNoYS0xKG0pKyhzMSp4KSBtb2QgcSlcbiAgZnVuY3Rpb24gc2lnbihoYXNoYWxnbywgbSwgZywgcCwgcSwgeCkge1xuICAgIC8vIElmIHRoZSBvdXRwdXQgc2l6ZSBvZiB0aGUgY2hvc2VuIGhhc2ggaXMgbGFyZ2VyIHRoYW4gdGhlIG51bWJlciBvZlxuICAgIC8vIGJpdHMgb2YgcSwgdGhlIGhhc2ggcmVzdWx0IGlzIHRydW5jYXRlZCB0byBmaXQgYnkgdGFraW5nIHRoZSBudW1iZXJcbiAgICAvLyBvZiBsZWZ0bW9zdCBiaXRzIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgYml0cyBvZiBxLiAgVGhpcyAocG9zc2libHlcbiAgICAvLyB0cnVuY2F0ZWQpIGhhc2ggZnVuY3Rpb24gcmVzdWx0IGlzIHRyZWF0ZWQgYXMgYSBudW1iZXIgYW5kIHVzZWRcbiAgICAvLyBkaXJlY3RseSBpbiB0aGUgRFNBIHNpZ25hdHVyZSBhbGdvcml0aG0uXG4gICAgdmFyIGhhc2hlZF9kYXRhID0gdXRpbC5nZXRMZWZ0TkJpdHMoaGFzaE1vZHVsZS5kaWdlc3QoaGFzaGFsZ28sIG0pLCBxLmJpdExlbmd0aCgpKTtcbiAgICB2YXIgaGFzaCA9IG5ldyBCaWdJbnRlZ2VyKHV0aWwuaGV4c3RyZHVtcChoYXNoZWRfZGF0YSksIDE2KTtcbiAgICB2YXIgayA9IHJhbmRvbS5nZXRSYW5kb21CaWdJbnRlZ2VySW5SYW5nZShCaWdJbnRlZ2VyLk9ORS5hZGQoQmlnSW50ZWdlci5PTkUpLCBxLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKSk7XG4gICAgdmFyIHMxID0gKGcubW9kUG93KGssIHApKS5tb2QocSk7XG4gICAgdmFyIHMyID0gKGsubW9kSW52ZXJzZShxKS5tdWx0aXBseShoYXNoLmFkZCh4Lm11bHRpcGx5KHMxKSkpKS5tb2QocSk7XG4gICAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheSgpO1xuICAgIHJlc3VsdFswXSA9IHMxLnRvTVBJKCk7XG4gICAgcmVzdWx0WzFdID0gczIudG9NUEkoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gc2VsZWN0X2hhc2hfYWxnb3JpdGhtKHEpIHtcbiAgICB2YXIgdXNlcnNldHRpbmcgPSBvcGVucGdwLmNvbmZpZy5jb25maWcucHJlZmVyX2hhc2hfYWxnb3JpdGhtO1xuICAgIC8qXG4gICAgICogMTAyNC1iaXQga2V5LCAxNjAtYml0IHEsIFNIQS0xLCBTSEEtMjI0LCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyIGhhc2hcbiAgICAgKiAyMDQ4LWJpdCBrZXksIDIyNC1iaXQgcSwgU0hBLTIyNCwgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMiBoYXNoXG4gICAgICogMjA0OC1iaXQga2V5LCAyNTYtYml0IHEsIFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIgaGFzaFxuICAgICAqIDMwNzItYml0IGtleSwgMjU2LWJpdCBxLCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyIGhhc2hcbiAgICAgKi9cbiAgICBzd2l0Y2ggKE1hdGgucm91bmQocS5iaXRMZW5ndGgoKSAvIDgpKSB7XG4gICAgICBjYXNlIDIwOlxuICAgICAgICAvLyAxMDI0IGJpdFxuICAgICAgICBpZiAodXNlcnNldHRpbmcgIT0gMiAmJlxuICAgICAgICAgIHVzZXJzZXR0aW5nID4gMTEgJiZcbiAgICAgICAgICB1c2Vyc2V0dGluZyAhPSAxMCAmJlxuICAgICAgICAgIHVzZXJzZXR0aW5nIDwgOClcbiAgICAgICAgICByZXR1cm4gMjsgLy8gcHJlZmVyIHNoYTFcbiAgICAgICAgcmV0dXJuIHVzZXJzZXR0aW5nO1xuICAgICAgY2FzZSAyODpcbiAgICAgICAgLy8gMjA0OCBiaXRcbiAgICAgICAgaWYgKHVzZXJzZXR0aW5nID4gMTEgJiZcbiAgICAgICAgICB1c2Vyc2V0dGluZyA8IDgpXG4gICAgICAgICAgcmV0dXJuIDExO1xuICAgICAgICByZXR1cm4gdXNlcnNldHRpbmc7XG4gICAgICBjYXNlIDMyOlxuICAgICAgICAvLyA0MDk2IGJpdCAvLyBwcmVmZXIgc2hhMjI0XG4gICAgICAgIGlmICh1c2Vyc2V0dGluZyA+IDEwICYmXG4gICAgICAgICAgdXNlcnNldHRpbmcgPCA4KVxuICAgICAgICAgIHJldHVybiA4OyAvLyBwcmVmZXIgc2hhMjU2XG4gICAgICAgIHJldHVybiB1c2Vyc2V0dGluZztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCJEU0Egc2VsZWN0IGhhc2ggYWxnb3JpdGhtOiByZXR1cm5pbmcgbnVsbCBmb3IgYW4gdW5rbm93biBsZW5ndGggb2YgcVwiKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICB9XG4gIH1cbiAgdGhpcy5zZWxlY3RfaGFzaF9hbGdvcml0aG0gPSBzZWxlY3RfaGFzaF9hbGdvcml0aG07XG5cbiAgZnVuY3Rpb24gdmVyaWZ5KGhhc2hhbGdvLCBzMSwgczIsIG0sIHAsIHEsIGcsIHkpIHtcbiAgICB2YXIgaGFzaGVkX2RhdGEgPSB1dGlsLmdldExlZnROQml0cyhoYXNoTW9kdWxlLmRpZ2VzdChoYXNoYWxnbywgbSksIHEuYml0TGVuZ3RoKCkpO1xuICAgIHZhciBoYXNoID0gbmV3IEJpZ0ludGVnZXIodXRpbC5oZXhzdHJkdW1wKGhhc2hlZF9kYXRhKSwgMTYpO1xuICAgIGlmIChCaWdJbnRlZ2VyLlpFUk8uY29tcGFyZVRvKHMxKSA+IDAgfHxcbiAgICAgIHMxLmNvbXBhcmVUbyhxKSA+IDAgfHxcbiAgICAgIEJpZ0ludGVnZXIuWkVSTy5jb21wYXJlVG8oczIpID4gMCB8fFxuICAgICAgczIuY29tcGFyZVRvKHEpID4gMCkge1xuICAgICAgdXRpbC5wcmludF9lcnJvcihcImludmFsaWQgRFNBIFNpZ25hdHVyZVwiKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgdyA9IHMyLm1vZEludmVyc2UocSk7XG4gICAgdmFyIHUxID0gaGFzaC5tdWx0aXBseSh3KS5tb2QocSk7XG4gICAgdmFyIHUyID0gczEubXVsdGlwbHkodykubW9kKHEpO1xuICAgIHJldHVybiBnLm1vZFBvdyh1MSwgcCkubXVsdGlwbHkoeS5tb2RQb3codTIsIHApKS5tb2QocCkubW9kKHEpO1xuICB9XG5cbiAgLypcblx0ICogdW51c2VkIGNvZGUuIFRoaXMgY2FuIGJlIHVzZWQgYXMgYSBzdGFydCB0byB3cml0ZSBhIGtleSBnZW5lcmF0b3Jcblx0ICogZnVuY3Rpb24uXG5cdFxuXHRmdW5jdGlvbiBnZW5lcmF0ZUtleShiaXRjb3VudCkge1xuXHQgICAgdmFyIHFpID0gbmV3IEJpZ0ludGVnZXIoYml0Y291bnQsIHByaW1lQ2VudGVyaWUpO1xuXHQgICAgdmFyIHBpID0gZ2VuZXJhdGVQKHEsIDUxMik7XG5cdCAgICB2YXIgZ2kgPSBnZW5lcmF0ZUcocCwgcSwgYml0Y291bnQpO1xuXHQgICAgdmFyIHhpO1xuXHQgICAgZG8ge1xuXHQgICAgICAgIHhpID0gbmV3IEJpZ0ludGVnZXIocS5iaXRDb3VudCgpLCByYW5kKTtcblx0ICAgIH0gd2hpbGUgKHguY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgIT0gMSAmJiB4LmNvbXBhcmVUbyhxKSAhPSAtMSk7XG5cdCAgICB2YXIgeWkgPSBnLm1vZFBvdyh4LCBwKTtcblx0ICAgIHJldHVybiB7eDogeGksIHE6IHFpLCBwOiBwaSwgZzogZ2ksIHk6IHlpfTtcblx0fVxuXG5cdGZ1bmN0aW9uIGdlbmVyYXRlUChxLCBiaXRsZW5ndGgsIHJhbmRvbWZuKSB7XG5cdCAgICBpZiAoYml0bGVuZ3RoICUgNjQgIT0gMCkge1xuXHQgICAgXHRyZXR1cm4gZmFsc2U7XG5cdCAgICB9XG5cdCAgICB2YXIgcFRlbXA7XG5cdCAgICB2YXIgcFRlbXAyO1xuXHQgICAgZG8ge1xuXHQgICAgICAgIHBUZW1wID0gcmFuZG9tZm4oYml0Y291bnQsIHRydWUpO1xuXHQgICAgICAgIHBUZW1wMiA9IHBUZW1wLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTtcblx0ICAgICAgICBwVGVtcCA9IHBUZW1wLnN1YnRyYWN0KHBUZW1wMi5yZW1haW5kZXIocSkpO1xuXHQgICAgfSB3aGlsZSAoIXBUZW1wLmlzUHJvYmFibGVQcmltZShwcmltZUNlbnRlcmllKSB8fCBwVGVtcC5iaXRMZW5ndGgoKSAhPSBsKTtcblx0ICAgIHJldHVybiBwVGVtcDtcblx0fVxuXHRcblx0ZnVuY3Rpb24gZ2VuZXJhdGVHKHAsIHEsIGJpdGxlbmd0aCwgcmFuZG9tZm4pIHtcblx0ICAgIHZhciBhdXggPSBwLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTtcblx0ICAgIHZhciBwb3cgPSBhdXguZGl2aWRlKHEpO1xuXHQgICAgdmFyIGdUZW1wO1xuXHQgICAgZG8ge1xuXHQgICAgICAgIGdUZW1wID0gcmFuZG9tZm4oYml0bGVuZ3RoKTtcblx0ICAgIH0gd2hpbGUgKGdUZW1wLmNvbXBhcmVUbyhhdXgpICE9IC0xICYmIGdUZW1wLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMSk7XG5cdCAgICByZXR1cm4gZ1RlbXAubW9kUG93KHBvdywgcCk7XG5cdH1cblxuXHRmdW5jdGlvbiBnZW5lcmF0ZUsocSwgYml0bGVuZ3RoLCByYW5kb21mbikge1xuXHQgICAgdmFyIHRlbXBLO1xuXHQgICAgZG8ge1xuXHQgICAgICAgIHRlbXBLID0gcmFuZG9tZm4oYml0bGVuZ3RoLCBmYWxzZSk7XG5cdCAgICB9IHdoaWxlICh0ZW1wSy5jb21wYXJlVG8ocSkgIT0gLTEgJiYgdGVtcEsuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgIT0gMSk7XG5cdCAgICByZXR1cm4gdGVtcEs7XG5cdH1cblxuXHRmdW5jdGlvbiBnZW5lcmF0ZVIocSxwKSB7XG5cdCAgICBrID0gZ2VuZXJhdGVLKHEpO1xuXHQgICAgdmFyIHIgPSBnLm1vZFBvdyhrLCBwKS5tb2QocSk7XG5cdCAgICByZXR1cm4gcjtcblx0fVxuXG5cdGZ1bmN0aW9uIGdlbmVyYXRlUyhoYXNoZm4sayxyLG0scSx4KSB7XG4gICAgICAgIHZhciBoYXNoID0gaGFzaGZuKG0pO1xuICAgICAgICBzID0gKGsubW9kSW52ZXJzZShxKS5tdWx0aXBseShoYXNoLmFkZCh4Lm11bHRpcGx5KHIpKSkpLm1vZChxKTtcblx0ICAgIHJldHVybiBzO1xuXHR9ICovXG4gIHRoaXMuc2lnbiA9IHNpZ247XG4gIHRoaXMudmVyaWZ5ID0gdmVyaWZ5O1xuICAvLyB0aGlzLmdlbmVyYXRlID0gZ2VuZXJhdGVLZXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRFNBO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0Fcbi8vXG4vLyBFbEdhbWFsIGltcGxlbWVudGF0aW9uXG5cbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9qc2JuLmpzJyksXG4gIHJhbmRvbSA9IHJlcXVpcmUoJy4uL3JhbmRvbS5qcycpLFxuICB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG5mdW5jdGlvbiBFbGdhbWFsKCkge1xuXG4gIGZ1bmN0aW9uIGVuY3J5cHQobSwgZywgcCwgeSkge1xuICAgIC8vICBjaG9vc2UgayBpbiB7MiwuLi4scC0yfVxuICAgIHZhciB0d28gPSBCaWdJbnRlZ2VyLk9ORS5hZGQoQmlnSW50ZWdlci5PTkUpO1xuICAgIHZhciBwTWludXMyID0gcC5zdWJ0cmFjdCh0d28pO1xuICAgIHZhciBrID0gcmFuZG9tLmdldFJhbmRvbUJpZ0ludGVnZXJJblJhbmdlKHR3bywgcE1pbnVzMik7XG4gICAgayA9IGsubW9kKHBNaW51czIpLmFkZChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgdmFyIGMgPSBbXTtcbiAgICBjWzBdID0gZy5tb2RQb3coaywgcCk7XG4gICAgY1sxXSA9IHkubW9kUG93KGssIHApLm11bHRpcGx5KG0pLm1vZChwKTtcbiAgICByZXR1cm4gYztcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlY3J5cHQoYzEsIGMyLCBwLCB4KSB7XG4gICAgdXRpbC5wcmludF9kZWJ1ZyhcIkVsZ2FtYWwgRGVjcnlwdDpcXG5jMTpcIiArIHV0aWwuaGV4c3RyZHVtcChjMS50b01QSSgpKSArIFwiXFxuXCIgK1xuICAgICAgXCJjMjpcIiArIHV0aWwuaGV4c3RyZHVtcChjMi50b01QSSgpKSArIFwiXFxuXCIgK1xuICAgICAgXCJwOlwiICsgdXRpbC5oZXhzdHJkdW1wKHAudG9NUEkoKSkgKyBcIlxcblwiICtcbiAgICAgIFwieDpcIiArIHV0aWwuaGV4c3RyZHVtcCh4LnRvTVBJKCkpKTtcbiAgICByZXR1cm4gKGMxLm1vZFBvdyh4LCBwKS5tb2RJbnZlcnNlKHApKS5tdWx0aXBseShjMikubW9kKHApO1xuICAgIC8vdmFyIGMgPSBjMS5wb3coeCkubW9kSW52ZXJzZShwKTsgLy8gYzBeLWEgbW9kIHBcbiAgICAvL3JldHVybiBjLm11bHRpcGx5KGMyKS5tb2QocCk7XG4gIH1cblxuICAvLyBzaWduaW5nIGFuZCBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIHVzaW5nIEVsZ2FtYWwgaXMgbm90IHJlcXVpcmVkIGJ5IE9wZW5QR1AuXG4gIHRoaXMuZW5jcnlwdCA9IGVuY3J5cHQ7XG4gIHRoaXMuZGVjcnlwdCA9IGRlY3J5cHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRWxnYW1hbDtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICByc2E6IHJlcXVpcmUoJy4vcnNhLmpzJyksXG4gIGVsZ2FtYWw6IHJlcXVpcmUoJy4vZWxnYW1hbC5qcycpLFxuICBkc2E6IHJlcXVpcmUoJy4vZHNhLmpzJylcbn1cbiIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMDMtMjAwNSAgVG9tIFd1ICh0andAY3MuU3RhbmZvcmQuRURVKSBcbiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIIFxuICogXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmdcbiAqIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuICogXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4gKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4gKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG9cbiAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0b1xuICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlXG4gKiBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUy1JU1wiIEFORCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBcbiAqIEVYUFJFU1MsIElNUExJRUQgT1IgT1RIRVJXSVNFLCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkgXG4gKiBXQVJSQU5UWSBPRiBNRVJDSEFOVEFCSUxJVFkgT1IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBcbiAqXG4gKiBJTiBOTyBFVkVOVCBTSEFMTCBUT00gV1UgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5DSURFTlRBTCxcbiAqIElORElSRUNUIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPRiBBTlkgS0lORCwgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUlxuICogUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBPUiBOT1QgQURWSVNFRCBPRlxuICogVEhFIFBPU1NJQklMSVRZIE9GIERBTUFHRSwgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBBUklTSU5HIE9VVFxuICogT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cbiAqXG4gKiBJbiBhZGRpdGlvbiwgdGhlIGZvbGxvd2luZyBjb25kaXRpb24gYXBwbGllczpcbiAqXG4gKiBBbGwgcmVkaXN0cmlidXRpb25zIG11c3QgcmV0YWluIGFuIGludGFjdCBjb3B5IG9mIHRoaXMgY29weXJpZ2h0IG5vdGljZVxuICogYW5kIGRpc2NsYWltZXIuXG4gKi9cblxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuLy8gQmFzaWMgSmF2YVNjcmlwdCBCTiBsaWJyYXJ5IC0gc3Vic2V0IHVzZWZ1bCBmb3IgUlNBIGVuY3J5cHRpb24uXG5cbi8vIEJpdHMgcGVyIGRpZ2l0XG52YXIgZGJpdHM7XG5cbi8vIEphdmFTY3JpcHQgZW5naW5lIGFuYWx5c2lzXG52YXIgY2FuYXJ5ID0gMHhkZWFkYmVlZmNhZmU7XG52YXIgal9sbSA9ICgoY2FuYXJ5ICYgMHhmZmZmZmYpID09IDB4ZWZjYWZlKTtcblxuLy8gKHB1YmxpYykgQ29uc3RydWN0b3JcblxuZnVuY3Rpb24gQmlnSW50ZWdlcihhLCBiLCBjKSB7XG4gIGlmIChhICE9IG51bGwpXG4gICAgaWYgKFwibnVtYmVyXCIgPT0gdHlwZW9mIGEpIHRoaXMuZnJvbU51bWJlcihhLCBiLCBjKTtcbiAgICBlbHNlIGlmIChiID09IG51bGwgJiYgXCJzdHJpbmdcIiAhPSB0eXBlb2YgYSkgdGhpcy5mcm9tU3RyaW5nKGEsIDI1Nik7XG4gIGVsc2UgdGhpcy5mcm9tU3RyaW5nKGEsIGIpO1xufVxuXG4vLyByZXR1cm4gbmV3LCB1bnNldCBCaWdJbnRlZ2VyXG5cbmZ1bmN0aW9uIG5iaSgpIHtcbiAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKG51bGwpO1xufVxuXG4vLyBhbTogQ29tcHV0ZSB3X2ogKz0gKHgqdGhpc19pKSwgcHJvcGFnYXRlIGNhcnJpZXMsXG4vLyBjIGlzIGluaXRpYWwgY2FycnksIHJldHVybnMgZmluYWwgY2FycnkuXG4vLyBjIDwgMypkdmFsdWUsIHggPCAyKmR2YWx1ZSwgdGhpc19pIDwgZHZhbHVlXG4vLyBXZSBuZWVkIHRvIHNlbGVjdCB0aGUgZmFzdGVzdCBvbmUgdGhhdCB3b3JrcyBpbiB0aGlzIGVudmlyb25tZW50LlxuXG4vLyBhbTE6IHVzZSBhIHNpbmdsZSBtdWx0IGFuZCBkaXZpZGUgdG8gZ2V0IHRoZSBoaWdoIGJpdHMsXG4vLyBtYXggZGlnaXQgYml0cyBzaG91bGQgYmUgMjYgYmVjYXVzZVxuLy8gbWF4IGludGVybmFsIHZhbHVlID0gMipkdmFsdWVeMi0yKmR2YWx1ZSAoPCAyXjUzKVxuXG5mdW5jdGlvbiBhbTEoaSwgeCwgdywgaiwgYywgbikge1xuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICB2YXIgdiA9IHggKiB0aGlzW2krK10gKyB3W2pdICsgYztcbiAgICBjID0gTWF0aC5mbG9vcih2IC8gMHg0MDAwMDAwKTtcbiAgICB3W2orK10gPSB2ICYgMHgzZmZmZmZmO1xuICB9XG4gIHJldHVybiBjO1xufVxuLy8gYW0yIGF2b2lkcyBhIGJpZyBtdWx0LWFuZC1leHRyYWN0IGNvbXBsZXRlbHkuXG4vLyBNYXggZGlnaXQgYml0cyBzaG91bGQgYmUgPD0gMzAgYmVjYXVzZSB3ZSBkbyBiaXR3aXNlIG9wc1xuLy8gb24gdmFsdWVzIHVwIHRvIDIqaGR2YWx1ZV4yLWhkdmFsdWUtMSAoPCAyXjMxKVxuXG5mdW5jdGlvbiBhbTIoaSwgeCwgdywgaiwgYywgbikge1xuICB2YXIgeGwgPSB4ICYgMHg3ZmZmLFxuICAgIHhoID0geCA+PiAxNTtcbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgdmFyIGwgPSB0aGlzW2ldICYgMHg3ZmZmO1xuICAgIHZhciBoID0gdGhpc1tpKytdID4+IDE1O1xuICAgIHZhciBtID0geGggKiBsICsgaCAqIHhsO1xuICAgIGwgPSB4bCAqIGwgKyAoKG0gJiAweDdmZmYpIDw8IDE1KSArIHdbal0gKyAoYyAmIDB4M2ZmZmZmZmYpO1xuICAgIGMgPSAobCA+Pj4gMzApICsgKG0gPj4+IDE1KSArIHhoICogaCArIChjID4+PiAzMCk7XG4gICAgd1tqKytdID0gbCAmIDB4M2ZmZmZmZmY7XG4gIH1cbiAgcmV0dXJuIGM7XG59XG4vLyBBbHRlcm5hdGVseSwgc2V0IG1heCBkaWdpdCBiaXRzIHRvIDI4IHNpbmNlIHNvbWVcbi8vIGJyb3dzZXJzIHNsb3cgZG93biB3aGVuIGRlYWxpbmcgd2l0aCAzMi1iaXQgbnVtYmVycy5cblxuZnVuY3Rpb24gYW0zKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgdmFyIHhsID0geCAmIDB4M2ZmZixcbiAgICB4aCA9IHggPj4gMTQ7XG4gIHdoaWxlICgtLW4gPj0gMCkge1xuICAgIHZhciBsID0gdGhpc1tpXSAmIDB4M2ZmZjtcbiAgICB2YXIgaCA9IHRoaXNbaSsrXSA+PiAxNDtcbiAgICB2YXIgbSA9IHhoICogbCArIGggKiB4bDtcbiAgICBsID0geGwgKiBsICsgKChtICYgMHgzZmZmKSA8PCAxNCkgKyB3W2pdICsgYztcbiAgICBjID0gKGwgPj4gMjgpICsgKG0gPj4gMTQpICsgeGggKiBoO1xuICAgIHdbaisrXSA9IGwgJiAweGZmZmZmZmY7XG4gIH1cbiAgcmV0dXJuIGM7XG59XG4vKmlmKGpfbG0gJiYgKG5hdmlnYXRvciAhPSB1bmRlZmluZWQgJiYgXG5cdG5hdmlnYXRvci5hcHBOYW1lID09IFwiTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyXCIpKSB7XG4gIEJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0yO1xuICBkYml0cyA9IDMwO1xufVxuZWxzZSBpZihqX2xtICYmIChuYXZpZ2F0b3IgIT0gdW5kZWZpbmVkICYmIG5hdmlnYXRvci5hcHBOYW1lICE9IFwiTmV0c2NhcGVcIikpIHsqL1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTE7XG5kYml0cyA9IDI2O1xuLyp9XG5lbHNlIHsgLy8gTW96aWxsYS9OZXRzY2FwZSBzZWVtcyB0byBwcmVmZXIgYW0zXG4gIEJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0zO1xuICBkYml0cyA9IDI4O1xufSovXG5cbkJpZ0ludGVnZXIucHJvdG90eXBlLkRCID0gZGJpdHM7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5ETSA9ICgoMSA8PCBkYml0cykgLSAxKTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLkRWID0gKDEgPDwgZGJpdHMpO1xuXG52YXIgQklfRlAgPSA1MjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLkZWID0gTWF0aC5wb3coMiwgQklfRlApO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuRjEgPSBCSV9GUCAtIGRiaXRzO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuRjIgPSAyICogZGJpdHMgLSBCSV9GUDtcblxuLy8gRGlnaXQgY29udmVyc2lvbnNcbnZhciBCSV9STSA9IFwiMDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6XCI7XG52YXIgQklfUkMgPSBuZXcgQXJyYXkoKTtcbnZhciByciwgdnY7XG5yciA9IFwiMFwiLmNoYXJDb2RlQXQoMCk7XG5mb3IgKHZ2ID0gMDsgdnYgPD0gOTsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcbnJyID0gXCJhXCIuY2hhckNvZGVBdCgwKTtcbmZvciAodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcbnJyID0gXCJBXCIuY2hhckNvZGVBdCgwKTtcbmZvciAodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcblxuZnVuY3Rpb24gaW50MmNoYXIobikge1xuICByZXR1cm4gQklfUk0uY2hhckF0KG4pO1xufVxuXG5mdW5jdGlvbiBpbnRBdChzLCBpKSB7XG4gIHZhciBjID0gQklfUkNbcy5jaGFyQ29kZUF0KGkpXTtcbiAgcmV0dXJuIChjID09IG51bGwpID8gLTEgOiBjO1xufVxuXG4vLyAocHJvdGVjdGVkKSBjb3B5IHRoaXMgdG8gclxuXG5mdW5jdGlvbiBibnBDb3B5VG8ocikge1xuICBmb3IgKHZhciBpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSB0aGlzW2ldO1xuICByLnQgPSB0aGlzLnQ7XG4gIHIucyA9IHRoaXMucztcbn1cblxuLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gaW50ZWdlciB2YWx1ZSB4LCAtRFYgPD0geCA8IERWXG5cbmZ1bmN0aW9uIGJucEZyb21JbnQoeCkge1xuICB0aGlzLnQgPSAxO1xuICB0aGlzLnMgPSAoeCA8IDApID8gLTEgOiAwO1xuICBpZiAoeCA+IDApIHRoaXNbMF0gPSB4O1xuICBlbHNlIGlmICh4IDwgLTEpIHRoaXNbMF0gPSB4ICsgRFY7XG4gIGVsc2UgdGhpcy50ID0gMDtcbn1cblxuLy8gcmV0dXJuIGJpZ2ludCBpbml0aWFsaXplZCB0byB2YWx1ZVxuXG5mdW5jdGlvbiBuYnYoaSkge1xuICB2YXIgciA9IG5iaSgpO1xuICByLmZyb21JbnQoaSk7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHJvdGVjdGVkKSBzZXQgZnJvbSBzdHJpbmcgYW5kIHJhZGl4XG5cbmZ1bmN0aW9uIGJucEZyb21TdHJpbmcocywgYikge1xuICB2YXIgaztcbiAgaWYgKGIgPT0gMTYpIGsgPSA0O1xuICBlbHNlIGlmIChiID09IDgpIGsgPSAzO1xuICBlbHNlIGlmIChiID09IDI1NikgayA9IDg7IC8vIGJ5dGUgYXJyYXlcbiAgZWxzZSBpZiAoYiA9PSAyKSBrID0gMTtcbiAgZWxzZSBpZiAoYiA9PSAzMikgayA9IDU7XG4gIGVsc2UgaWYgKGIgPT0gNCkgayA9IDI7XG4gIGVsc2Uge1xuICAgIHRoaXMuZnJvbVJhZGl4KHMsIGIpO1xuICAgIHJldHVybjtcbiAgfVxuICB0aGlzLnQgPSAwO1xuICB0aGlzLnMgPSAwO1xuICB2YXIgaSA9IHMubGVuZ3RoLFxuICAgIG1pID0gZmFsc2UsXG4gICAgc2ggPSAwO1xuICB3aGlsZSAoLS1pID49IDApIHtcbiAgICB2YXIgeCA9IChrID09IDgpID8gc1tpXSAmIDB4ZmYgOiBpbnRBdChzLCBpKTtcbiAgICBpZiAoeCA8IDApIHtcbiAgICAgIGlmIChzLmNoYXJBdChpKSA9PSBcIi1cIikgbWkgPSB0cnVlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIG1pID0gZmFsc2U7XG4gICAgaWYgKHNoID09IDApXG4gICAgICB0aGlzW3RoaXMudCsrXSA9IHg7XG4gICAgZWxzZSBpZiAoc2ggKyBrID4gdGhpcy5EQikge1xuICAgICAgdGhpc1t0aGlzLnQgLSAxXSB8PSAoeCAmICgoMSA8PCAodGhpcy5EQiAtIHNoKSkgLSAxKSkgPDwgc2g7XG4gICAgICB0aGlzW3RoaXMudCsrXSA9ICh4ID4+ICh0aGlzLkRCIC0gc2gpKTtcbiAgICB9IGVsc2VcbiAgICAgIHRoaXNbdGhpcy50IC0gMV0gfD0geCA8PCBzaDtcbiAgICBzaCArPSBrO1xuICAgIGlmIChzaCA+PSB0aGlzLkRCKSBzaCAtPSB0aGlzLkRCO1xuICB9XG4gIGlmIChrID09IDggJiYgKHNbMF0gJiAweDgwKSAhPSAwKSB7XG4gICAgdGhpcy5zID0gLTE7XG4gICAgaWYgKHNoID4gMCkgdGhpc1t0aGlzLnQgLSAxXSB8PSAoKDEgPDwgKHRoaXMuREIgLSBzaCkpIC0gMSkgPDwgc2g7XG4gIH1cbiAgdGhpcy5jbGFtcCgpO1xuICBpZiAobWkpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLCB0aGlzKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgY2xhbXAgb2ZmIGV4Y2VzcyBoaWdoIHdvcmRzXG5cbmZ1bmN0aW9uIGJucENsYW1wKCkge1xuICB2YXIgYyA9IHRoaXMucyAmIHRoaXMuRE07XG4gIHdoaWxlICh0aGlzLnQgPiAwICYmIHRoaXNbdGhpcy50IC0gMV0gPT0gYyktLXRoaXMudDtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHN0cmluZyByZXByZXNlbnRhdGlvbiBpbiBnaXZlbiByYWRpeFxuXG5mdW5jdGlvbiBiblRvU3RyaW5nKGIpIHtcbiAgaWYgKHRoaXMucyA8IDApIHJldHVybiBcIi1cIiArIHRoaXMubmVnYXRlKCkudG9TdHJpbmcoYik7XG4gIHZhciBrO1xuICBpZiAoYiA9PSAxNikgayA9IDQ7XG4gIGVsc2UgaWYgKGIgPT0gOCkgayA9IDM7XG4gIGVsc2UgaWYgKGIgPT0gMikgayA9IDE7XG4gIGVsc2UgaWYgKGIgPT0gMzIpIGsgPSA1O1xuICBlbHNlIGlmIChiID09IDQpIGsgPSAyO1xuICBlbHNlIHJldHVybiB0aGlzLnRvUmFkaXgoYik7XG4gIHZhciBrbSA9ICgxIDw8IGspIC0gMSxcbiAgICBkLCBtID0gZmFsc2UsXG4gICAgciA9IFwiXCIsXG4gICAgaSA9IHRoaXMudDtcbiAgdmFyIHAgPSB0aGlzLkRCIC0gKGkgKiB0aGlzLkRCKSAlIGs7XG4gIGlmIChpLS0gPiAwKSB7XG4gICAgaWYgKHAgPCB0aGlzLkRCICYmIChkID0gdGhpc1tpXSA+PiBwKSA+IDApIHtcbiAgICAgIG0gPSB0cnVlO1xuICAgICAgciA9IGludDJjaGFyKGQpO1xuICAgIH1cbiAgICB3aGlsZSAoaSA+PSAwKSB7XG4gICAgICBpZiAocCA8IGspIHtcbiAgICAgICAgZCA9ICh0aGlzW2ldICYgKCgxIDw8IHApIC0gMSkpIDw8IChrIC0gcCk7XG4gICAgICAgIGQgfD0gdGhpc1stLWldID4+IChwICs9IHRoaXMuREIgLSBrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGQgPSAodGhpc1tpXSA+PiAocCAtPSBrKSkgJiBrbTtcbiAgICAgICAgaWYgKHAgPD0gMCkge1xuICAgICAgICAgIHAgKz0gdGhpcy5EQjtcbiAgICAgICAgICAtLWk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChkID4gMCkgbSA9IHRydWU7XG4gICAgICBpZiAobSkgciArPSBpbnQyY2hhcihkKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG0gPyByIDogXCIwXCI7XG59XG5cbi8vIChwdWJsaWMpIC10aGlzXG5cbmZ1bmN0aW9uIGJuTmVnYXRlKCkge1xuICB2YXIgciA9IG5iaSgpO1xuICBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcywgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB8dGhpc3xcblxuZnVuY3Rpb24gYm5BYnMoKSB7XG4gIHJldHVybiAodGhpcy5zIDwgMCkgPyB0aGlzLm5lZ2F0ZSgpIDogdGhpcztcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuICsgaWYgdGhpcyA+IGEsIC0gaWYgdGhpcyA8IGEsIDAgaWYgZXF1YWxcblxuZnVuY3Rpb24gYm5Db21wYXJlVG8oYSkge1xuICB2YXIgciA9IHRoaXMucyAtIGEucztcbiAgaWYgKHIgIT0gMCkgcmV0dXJuIHI7XG4gIHZhciBpID0gdGhpcy50O1xuICByID0gaSAtIGEudDtcbiAgaWYgKHIgIT0gMCkgcmV0dXJuIHI7XG4gIHdoaWxlICgtLWkgPj0gMCkgaWYgKChyID0gdGhpc1tpXSAtIGFbaV0pICE9IDApIHJldHVybiByO1xuICByZXR1cm4gMDtcbn1cblxuLy8gcmV0dXJucyBiaXQgbGVuZ3RoIG9mIHRoZSBpbnRlZ2VyIHhcblxuZnVuY3Rpb24gbmJpdHMoeCkge1xuICB2YXIgciA9IDEsXG4gICAgdDtcbiAgaWYgKCh0ID0geCA+Pj4gMTYpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICByICs9IDE2O1xuICB9XG4gIGlmICgodCA9IHggPj4gOCkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIHIgKz0gODtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDQpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICByICs9IDQ7XG4gIH1cbiAgaWYgKCh0ID0geCA+PiAyKSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgciArPSAyO1xuICB9XG4gIGlmICgodCA9IHggPj4gMSkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIHIgKz0gMTtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHRoZSBudW1iZXIgb2YgYml0cyBpbiBcInRoaXNcIlxuXG5mdW5jdGlvbiBibkJpdExlbmd0aCgpIHtcbiAgaWYgKHRoaXMudCA8PSAwKSByZXR1cm4gMDtcbiAgcmV0dXJuIHRoaXMuREIgKiAodGhpcy50IC0gMSkgKyBuYml0cyh0aGlzW3RoaXMudCAtIDFdIF4gKHRoaXMucyAmIHRoaXMuRE0pKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPDwgbipEQlxuXG5mdW5jdGlvbiBibnBETFNoaWZ0VG8obiwgcikge1xuICB2YXIgaTtcbiAgZm9yIChpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHJbaSArIG5dID0gdGhpc1tpXTtcbiAgZm9yIChpID0gbiAtIDE7IGkgPj0gMDsgLS1pKSByW2ldID0gMDtcbiAgci50ID0gdGhpcy50ICsgbjtcbiAgci5zID0gdGhpcy5zO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuKkRCXG5cbmZ1bmN0aW9uIGJucERSU2hpZnRUbyhuLCByKSB7XG4gIGZvciAodmFyIGkgPSBuOyBpIDwgdGhpcy50OyArK2kpIHJbaSAtIG5dID0gdGhpc1tpXTtcbiAgci50ID0gTWF0aC5tYXgodGhpcy50IC0gbiwgMCk7XG4gIHIucyA9IHRoaXMucztcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPDwgblxuXG5mdW5jdGlvbiBibnBMU2hpZnRUbyhuLCByKSB7XG4gIHZhciBicyA9IG4gJSB0aGlzLkRCO1xuICB2YXIgY2JzID0gdGhpcy5EQiAtIGJzO1xuICB2YXIgYm0gPSAoMSA8PCBjYnMpIC0gMTtcbiAgdmFyIGRzID0gTWF0aC5mbG9vcihuIC8gdGhpcy5EQiksXG4gICAgYyA9ICh0aGlzLnMgPDwgYnMpICYgdGhpcy5ETSxcbiAgICBpO1xuICBmb3IgKGkgPSB0aGlzLnQgLSAxOyBpID49IDA7IC0taSkge1xuICAgIHJbaSArIGRzICsgMV0gPSAodGhpc1tpXSA+PiBjYnMpIHwgYztcbiAgICBjID0gKHRoaXNbaV0gJiBibSkgPDwgYnM7XG4gIH1cbiAgZm9yIChpID0gZHMgLSAxOyBpID49IDA7IC0taSkgcltpXSA9IDA7XG4gIHJbZHNdID0gYztcbiAgci50ID0gdGhpcy50ICsgZHMgKyAxO1xuICByLnMgPSB0aGlzLnM7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gblxuXG5mdW5jdGlvbiBibnBSU2hpZnRUbyhuLCByKSB7XG4gIHIucyA9IHRoaXMucztcbiAgdmFyIGRzID0gTWF0aC5mbG9vcihuIC8gdGhpcy5EQik7XG4gIGlmIChkcyA+PSB0aGlzLnQpIHtcbiAgICByLnQgPSAwO1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgYnMgPSBuICUgdGhpcy5EQjtcbiAgdmFyIGNicyA9IHRoaXMuREIgLSBicztcbiAgdmFyIGJtID0gKDEgPDwgYnMpIC0gMTtcbiAgclswXSA9IHRoaXNbZHNdID4+IGJzO1xuICBmb3IgKHZhciBpID0gZHMgKyAxOyBpIDwgdGhpcy50OyArK2kpIHtcbiAgICByW2kgLSBkcyAtIDFdIHw9ICh0aGlzW2ldICYgYm0pIDw8IGNicztcbiAgICByW2kgLSBkc10gPSB0aGlzW2ldID4+IGJzO1xuICB9XG4gIGlmIChicyA+IDApIHJbdGhpcy50IC0gZHMgLSAxXSB8PSAodGhpcy5zICYgYm0pIDw8IGNicztcbiAgci50ID0gdGhpcy50IC0gZHM7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgLSBhXG5cbmZ1bmN0aW9uIGJucFN1YlRvKGEsIHIpIHtcbiAgdmFyIGkgPSAwLFxuICAgIGMgPSAwLFxuICAgIG0gPSBNYXRoLm1pbihhLnQsIHRoaXMudCk7XG4gIHdoaWxlIChpIDwgbSkge1xuICAgIGMgKz0gdGhpc1tpXSAtIGFbaV07XG4gICAgcltpKytdID0gYyAmIHRoaXMuRE07XG4gICAgYyA+Pj0gdGhpcy5EQjtcbiAgfVxuICBpZiAoYS50IDwgdGhpcy50KSB7XG4gICAgYyAtPSBhLnM7XG4gICAgd2hpbGUgKGkgPCB0aGlzLnQpIHtcbiAgICAgIGMgKz0gdGhpc1tpXTtcbiAgICAgIHJbaSsrXSA9IGMgJiB0aGlzLkRNO1xuICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICB9XG4gICAgYyArPSB0aGlzLnM7XG4gIH0gZWxzZSB7XG4gICAgYyArPSB0aGlzLnM7XG4gICAgd2hpbGUgKGkgPCBhLnQpIHtcbiAgICAgIGMgLT0gYVtpXTtcbiAgICAgIHJbaSsrXSA9IGMgJiB0aGlzLkRNO1xuICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICB9XG4gICAgYyAtPSBhLnM7XG4gIH1cbiAgci5zID0gKGMgPCAwKSA/IC0xIDogMDtcbiAgaWYgKGMgPCAtMSkgcltpKytdID0gdGhpcy5EViArIGM7XG4gIGVsc2UgaWYgKGMgPiAwKSByW2krK10gPSBjO1xuICByLnQgPSBpO1xuICByLmNsYW1wKCk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICogYSwgciAhPSB0aGlzLGEgKEhBQyAxNC4xMilcbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cblxuZnVuY3Rpb24gYm5wTXVsdGlwbHlUbyhhLCByKSB7XG4gIHZhciB4ID0gdGhpcy5hYnMoKSxcbiAgICB5ID0gYS5hYnMoKTtcbiAgdmFyIGkgPSB4LnQ7XG4gIHIudCA9IGkgKyB5LnQ7XG4gIHdoaWxlICgtLWkgPj0gMCkgcltpXSA9IDA7XG4gIGZvciAoaSA9IDA7IGkgPCB5LnQ7ICsraSkgcltpICsgeC50XSA9IHguYW0oMCwgeVtpXSwgciwgaSwgMCwgeC50KTtcbiAgci5zID0gMDtcbiAgci5jbGFtcCgpO1xuICBpZiAodGhpcy5zICE9IGEucykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIsIHIpO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpc14yLCByICE9IHRoaXMgKEhBQyAxNC4xNilcblxuZnVuY3Rpb24gYm5wU3F1YXJlVG8ocikge1xuICB2YXIgeCA9IHRoaXMuYWJzKCk7XG4gIHZhciBpID0gci50ID0gMiAqIHgudDtcbiAgd2hpbGUgKC0taSA+PSAwKSByW2ldID0gMDtcbiAgZm9yIChpID0gMDsgaSA8IHgudCAtIDE7ICsraSkge1xuICAgIHZhciBjID0geC5hbShpLCB4W2ldLCByLCAyICogaSwgMCwgMSk7XG4gICAgaWYgKChyW2kgKyB4LnRdICs9IHguYW0oaSArIDEsIDIgKiB4W2ldLCByLCAyICogaSArIDEsIGMsIHgudCAtIGkgLSAxKSkgPj0geC5EVikge1xuICAgICAgcltpICsgeC50XSAtPSB4LkRWO1xuICAgICAgcltpICsgeC50ICsgMV0gPSAxO1xuICAgIH1cbiAgfVxuICBpZiAoci50ID4gMCkgcltyLnQgLSAxXSArPSB4LmFtKGksIHhbaV0sIHIsIDIgKiBpLCAwLCAxKTtcbiAgci5zID0gMDtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHJvdGVjdGVkKSBkaXZpZGUgdGhpcyBieSBtLCBxdW90aWVudCBhbmQgcmVtYWluZGVyIHRvIHEsIHIgKEhBQyAxNC4yMClcbi8vIHIgIT0gcSwgdGhpcyAhPSBtLiAgcSBvciByIG1heSBiZSBudWxsLlxuXG5mdW5jdGlvbiBibnBEaXZSZW1UbyhtLCBxLCByKSB7XG4gIHZhciBwbSA9IG0uYWJzKCk7XG4gIGlmIChwbS50IDw9IDApIHJldHVybjtcbiAgdmFyIHB0ID0gdGhpcy5hYnMoKTtcbiAgaWYgKHB0LnQgPCBwbS50KSB7XG4gICAgaWYgKHEgIT0gbnVsbCkgcS5mcm9tSW50KDApO1xuICAgIGlmIChyICE9IG51bGwpIHRoaXMuY29weVRvKHIpO1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAociA9PSBudWxsKSByID0gbmJpKCk7XG4gIHZhciB5ID0gbmJpKCksXG4gICAgdHMgPSB0aGlzLnMsXG4gICAgbXMgPSBtLnM7XG4gIHZhciBuc2ggPSB0aGlzLkRCIC0gbmJpdHMocG1bcG0udCAtIDFdKTsgLy8gbm9ybWFsaXplIG1vZHVsdXNcbiAgaWYgKG5zaCA+IDApIHtcbiAgICBwbS5sU2hpZnRUbyhuc2gsIHkpO1xuICAgIHB0LmxTaGlmdFRvKG5zaCwgcik7XG4gIH0gZWxzZSB7XG4gICAgcG0uY29weVRvKHkpO1xuICAgIHB0LmNvcHlUbyhyKTtcbiAgfVxuICB2YXIgeXMgPSB5LnQ7XG4gIHZhciB5MCA9IHlbeXMgLSAxXTtcbiAgaWYgKHkwID09IDApIHJldHVybjtcbiAgdmFyIHl0ID0geTAgKiAoMSA8PCB0aGlzLkYxKSArICgoeXMgPiAxKSA/IHlbeXMgLSAyXSA+PiB0aGlzLkYyIDogMCk7XG4gIHZhciBkMSA9IHRoaXMuRlYgLyB5dCxcbiAgICBkMiA9ICgxIDw8IHRoaXMuRjEpIC8geXQsXG4gICAgZSA9IDEgPDwgdGhpcy5GMjtcbiAgdmFyIGkgPSByLnQsXG4gICAgaiA9IGkgLSB5cyxcbiAgICB0ID0gKHEgPT0gbnVsbCkgPyBuYmkoKSA6IHE7XG4gIHkuZGxTaGlmdFRvKGosIHQpO1xuICBpZiAoci5jb21wYXJlVG8odCkgPj0gMCkge1xuICAgIHJbci50KytdID0gMTtcbiAgICByLnN1YlRvKHQsIHIpO1xuICB9XG4gIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbyh5cywgdCk7XG4gIHQuc3ViVG8oeSwgeSk7IC8vIFwibmVnYXRpdmVcIiB5IHNvIHdlIGNhbiByZXBsYWNlIHN1YiB3aXRoIGFtIGxhdGVyXG4gIHdoaWxlICh5LnQgPCB5cykgeVt5LnQrK10gPSAwO1xuICB3aGlsZSAoLS1qID49IDApIHtcbiAgICAvLyBFc3RpbWF0ZSBxdW90aWVudCBkaWdpdFxuICAgIHZhciBxZCA9IChyWy0taV0gPT0geTApID8gdGhpcy5ETSA6IE1hdGguZmxvb3IocltpXSAqIGQxICsgKHJbaSAtIDFdICsgZSkgKiBkMik7XG4gICAgaWYgKChyW2ldICs9IHkuYW0oMCwgcWQsIHIsIGosIDAsIHlzKSkgPCBxZCkgeyAvLyBUcnkgaXQgb3V0XG4gICAgICB5LmRsU2hpZnRUbyhqLCB0KTtcbiAgICAgIHIuc3ViVG8odCwgcik7XG4gICAgICB3aGlsZSAocltpXSA8IC0tcWQpIHIuc3ViVG8odCwgcik7XG4gICAgfVxuICB9XG4gIGlmIChxICE9IG51bGwpIHtcbiAgICByLmRyU2hpZnRUbyh5cywgcSk7XG4gICAgaWYgKHRzICE9IG1zKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ocSwgcSk7XG4gIH1cbiAgci50ID0geXM7XG4gIHIuY2xhbXAoKTtcbiAgaWYgKG5zaCA+IDApIHIuclNoaWZ0VG8obnNoLCByKTsgLy8gRGVub3JtYWxpemUgcmVtYWluZGVyXG4gIGlmICh0cyA8IDApIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhyLCByKTtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBtb2QgYVxuXG5mdW5jdGlvbiBibk1vZChhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYWJzKCkuZGl2UmVtVG8oYSwgbnVsbCwgcik7XG4gIGlmICh0aGlzLnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSBhLnN1YlRvKHIsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gTW9kdWxhciByZWR1Y3Rpb24gdXNpbmcgXCJjbGFzc2ljXCIgYWxnb3JpdGhtXG5cbmZ1bmN0aW9uIENsYXNzaWMobSkge1xuICB0aGlzLm0gPSBtO1xufVxuXG5mdW5jdGlvbiBjQ29udmVydCh4KSB7XG4gIGlmICh4LnMgPCAwIHx8IHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgcmV0dXJuIHgubW9kKHRoaXMubSk7XG4gIGVsc2UgcmV0dXJuIHg7XG59XG5cbmZ1bmN0aW9uIGNSZXZlcnQoeCkge1xuICByZXR1cm4geDtcbn1cblxuZnVuY3Rpb24gY1JlZHVjZSh4KSB7XG4gIHguZGl2UmVtVG8odGhpcy5tLCBudWxsLCB4KTtcbn1cblxuZnVuY3Rpb24gY011bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuZnVuY3Rpb24gY1NxclRvKHgsIHIpIHtcbiAgeC5zcXVhcmVUbyhyKTtcbiAgdGhpcy5yZWR1Y2Uocik7XG59XG5cbkNsYXNzaWMucHJvdG90eXBlLmNvbnZlcnQgPSBjQ29udmVydDtcbkNsYXNzaWMucHJvdG90eXBlLnJldmVydCA9IGNSZXZlcnQ7XG5DbGFzc2ljLnByb3RvdHlwZS5yZWR1Y2UgPSBjUmVkdWNlO1xuQ2xhc3NpYy5wcm90b3R5cGUubXVsVG8gPSBjTXVsVG87XG5DbGFzc2ljLnByb3RvdHlwZS5zcXJUbyA9IGNTcXJUbztcblxuLy8gKHByb3RlY3RlZCkgcmV0dXJuIFwiLTEvdGhpcyAlIDJeREJcIjsgdXNlZnVsIGZvciBNb250LiByZWR1Y3Rpb25cbi8vIGp1c3RpZmljYXRpb246XG4vLyAgICAgICAgIHh5ID09IDEgKG1vZCBtKVxuLy8gICAgICAgICB4eSA9ICAxK2ttXG4vLyAgIHh5KDIteHkpID0gKDEra20pKDEta20pXG4vLyB4W3koMi14eSldID0gMS1rXjJtXjJcbi8vIHhbeSgyLXh5KV0gPT0gMSAobW9kIG1eMilcbi8vIGlmIHkgaXMgMS94IG1vZCBtLCB0aGVuIHkoMi14eSkgaXMgMS94IG1vZCBtXjJcbi8vIHNob3VsZCByZWR1Y2UgeCBhbmQgeSgyLXh5KSBieSBtXjIgYXQgZWFjaCBzdGVwIHRvIGtlZXAgc2l6ZSBib3VuZGVkLlxuLy8gSlMgbXVsdGlwbHkgXCJvdmVyZmxvd3NcIiBkaWZmZXJlbnRseSBmcm9tIEMvQysrLCBzbyBjYXJlIGlzIG5lZWRlZCBoZXJlLlxuXG5mdW5jdGlvbiBibnBJbnZEaWdpdCgpIHtcbiAgaWYgKHRoaXMudCA8IDEpIHJldHVybiAwO1xuICB2YXIgeCA9IHRoaXNbMF07XG4gIGlmICgoeCAmIDEpID09IDApIHJldHVybiAwO1xuICB2YXIgeSA9IHggJiAzOyAvLyB5ID09IDEveCBtb2QgMl4yXG4gIHkgPSAoeSAqICgyIC0gKHggJiAweGYpICogeSkpICYgMHhmOyAvLyB5ID09IDEveCBtb2QgMl40XG4gIHkgPSAoeSAqICgyIC0gKHggJiAweGZmKSAqIHkpKSAmIDB4ZmY7IC8vIHkgPT0gMS94IG1vZCAyXjhcbiAgeSA9ICh5ICogKDIgLSAoKCh4ICYgMHhmZmZmKSAqIHkpICYgMHhmZmZmKSkpICYgMHhmZmZmOyAvLyB5ID09IDEveCBtb2QgMl4xNlxuICAvLyBsYXN0IHN0ZXAgLSBjYWxjdWxhdGUgaW52ZXJzZSBtb2QgRFYgZGlyZWN0bHk7XG4gIC8vIGFzc3VtZXMgMTYgPCBEQiA8PSAzMiBhbmQgYXNzdW1lcyBhYmlsaXR5IHRvIGhhbmRsZSA0OC1iaXQgaW50c1xuICB5ID0gKHkgKiAoMiAtIHggKiB5ICUgdGhpcy5EVikpICUgdGhpcy5EVjsgLy8geSA9PSAxL3ggbW9kIDJeZGJpdHNcbiAgLy8gd2UgcmVhbGx5IHdhbnQgdGhlIG5lZ2F0aXZlIGludmVyc2UsIGFuZCAtRFYgPCB5IDwgRFZcbiAgcmV0dXJuICh5ID4gMCkgPyB0aGlzLkRWIC0geSA6IC15O1xufVxuXG4vLyBNb250Z29tZXJ5IHJlZHVjdGlvblxuXG5mdW5jdGlvbiBNb250Z29tZXJ5KG0pIHtcbiAgdGhpcy5tID0gbTtcbiAgdGhpcy5tcCA9IG0uaW52RGlnaXQoKTtcbiAgdGhpcy5tcGwgPSB0aGlzLm1wICYgMHg3ZmZmO1xuICB0aGlzLm1waCA9IHRoaXMubXAgPj4gMTU7XG4gIHRoaXMudW0gPSAoMSA8PCAobS5EQiAtIDE1KSkgLSAxO1xuICB0aGlzLm10MiA9IDIgKiBtLnQ7XG59XG5cbi8vIHhSIG1vZCBtXG5cbmZ1bmN0aW9uIG1vbnRDb252ZXJ0KHgpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgeC5hYnMoKS5kbFNoaWZ0VG8odGhpcy5tLnQsIHIpO1xuICByLmRpdlJlbVRvKHRoaXMubSwgbnVsbCwgcik7XG4gIGlmICh4LnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSB0aGlzLm0uc3ViVG8ociwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyB4L1IgbW9kIG1cblxuZnVuY3Rpb24gbW9udFJldmVydCh4KSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHguY29weVRvKHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIHggPSB4L1IgbW9kIG0gKEhBQyAxNC4zMilcblxuZnVuY3Rpb24gbW9udFJlZHVjZSh4KSB7XG4gIHdoaWxlICh4LnQgPD0gdGhpcy5tdDIpIC8vIHBhZCB4IHNvIGFtIGhhcyBlbm91Z2ggcm9vbSBsYXRlclxuICAgIHhbeC50KytdID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm0udDsgKytpKSB7XG4gICAgLy8gZmFzdGVyIHdheSBvZiBjYWxjdWxhdGluZyB1MCA9IHhbaV0qbXAgbW9kIERWXG4gICAgdmFyIGogPSB4W2ldICYgMHg3ZmZmO1xuICAgIHZhciB1MCA9IChqICogdGhpcy5tcGwgKyAoKChqICogdGhpcy5tcGggKyAoeFtpXSA+PiAxNSkgKiB0aGlzLm1wbCkgJiB0aGlzLnVtKSA8PCAxNSkpICYgeC5ETTtcbiAgICAvLyB1c2UgYW0gdG8gY29tYmluZSB0aGUgbXVsdGlwbHktc2hpZnQtYWRkIGludG8gb25lIGNhbGxcbiAgICBqID0gaSArIHRoaXMubS50O1xuICAgIHhbal0gKz0gdGhpcy5tLmFtKDAsIHUwLCB4LCBpLCAwLCB0aGlzLm0udCk7XG4gICAgLy8gcHJvcGFnYXRlIGNhcnJ5XG4gICAgd2hpbGUgKHhbal0gPj0geC5EVikge1xuICAgICAgeFtqXSAtPSB4LkRWO1xuICAgICAgeFsrK2pdKys7XG4gICAgfVxuICB9XG4gIHguY2xhbXAoKTtcbiAgeC5kclNoaWZ0VG8odGhpcy5tLnQsIHgpO1xuICBpZiAoeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSB4LnN1YlRvKHRoaXMubSwgeCk7XG59XG5cbi8vIHIgPSBcInheMi9SIG1vZCBtXCI7IHggIT0gclxuXG5mdW5jdGlvbiBtb250U3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuLy8gciA9IFwieHkvUiBtb2QgbVwiOyB4LHkgIT0gclxuXG5mdW5jdGlvbiBtb250TXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcik7XG4gIHRoaXMucmVkdWNlKHIpO1xufVxuXG5Nb250Z29tZXJ5LnByb3RvdHlwZS5jb252ZXJ0ID0gbW9udENvbnZlcnQ7XG5Nb250Z29tZXJ5LnByb3RvdHlwZS5yZXZlcnQgPSBtb250UmV2ZXJ0O1xuTW9udGdvbWVyeS5wcm90b3R5cGUucmVkdWNlID0gbW9udFJlZHVjZTtcbk1vbnRnb21lcnkucHJvdG90eXBlLm11bFRvID0gbW9udE11bFRvO1xuTW9udGdvbWVyeS5wcm90b3R5cGUuc3FyVG8gPSBtb250U3FyVG87XG5cbi8vIChwcm90ZWN0ZWQpIHRydWUgaWZmIHRoaXMgaXMgZXZlblxuXG5mdW5jdGlvbiBibnBJc0V2ZW4oKSB7XG4gIHJldHVybiAoKHRoaXMudCA+IDApID8gKHRoaXNbMF0gJiAxKSA6IHRoaXMucykgPT0gMDtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpc15lLCBlIDwgMl4zMiwgZG9pbmcgc3FyIGFuZCBtdWwgd2l0aCBcInJcIiAoSEFDIDE0Ljc5KVxuXG5mdW5jdGlvbiBibnBFeHAoZSwgeikge1xuICBpZiAoZSA+IDB4ZmZmZmZmZmYgfHwgZSA8IDEpIHJldHVybiBCaWdJbnRlZ2VyLk9ORTtcbiAgdmFyIHIgPSBuYmkoKSxcbiAgICByMiA9IG5iaSgpLFxuICAgIGcgPSB6LmNvbnZlcnQodGhpcyksXG4gICAgaSA9IG5iaXRzKGUpIC0gMTtcbiAgZy5jb3B5VG8ocik7XG4gIHdoaWxlICgtLWkgPj0gMCkge1xuICAgIHouc3FyVG8ociwgcjIpO1xuICAgIGlmICgoZSAmICgxIDw8IGkpKSA+IDApIHoubXVsVG8ocjIsIGcsIHIpO1xuICAgIGVsc2Uge1xuICAgICAgdmFyIHQgPSByO1xuICAgICAgciA9IHIyO1xuICAgICAgcjIgPSB0O1xuICAgIH1cbiAgfVxuICByZXR1cm4gei5yZXZlcnQocik7XG59XG5cbi8vIChwdWJsaWMpIHRoaXNeZSAlIG0sIDAgPD0gZSA8IDJeMzJcblxuZnVuY3Rpb24gYm5Nb2RQb3dJbnQoZSwgbSkge1xuICB2YXIgejtcbiAgaWYgKGUgPCAyNTYgfHwgbS5pc0V2ZW4oKSkgeiA9IG5ldyBDbGFzc2ljKG0pO1xuICBlbHNlIHogPSBuZXcgTW9udGdvbWVyeShtKTtcbiAgcmV0dXJuIHRoaXMuZXhwKGUsIHopO1xufVxuXG4vLyBwcm90ZWN0ZWRcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNvcHlUbyA9IGJucENvcHlUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21JbnQgPSBibnBGcm9tSW50O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbVN0cmluZyA9IGJucEZyb21TdHJpbmc7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGFtcCA9IGJucENsYW1wO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZGxTaGlmdFRvID0gYm5wRExTaGlmdFRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZHJTaGlmdFRvID0gYm5wRFJTaGlmdFRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubFNoaWZ0VG8gPSBibnBMU2hpZnRUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLnJTaGlmdFRvID0gYm5wUlNoaWZ0VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zdWJUbyA9IGJucFN1YlRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlUbyA9IGJucE11bHRpcGx5VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmVUbyA9IGJucFNxdWFyZVRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2UmVtVG8gPSBibnBEaXZSZW1UbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmludkRpZ2l0ID0gYm5wSW52RGlnaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5pc0V2ZW4gPSBibnBJc0V2ZW47XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5leHAgPSBibnBFeHA7XG5cbi8vIHB1YmxpY1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9TdHJpbmcgPSBiblRvU3RyaW5nO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubmVnYXRlID0gYm5OZWdhdGU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hYnMgPSBibkFicztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNvbXBhcmVUbyA9IGJuQ29tcGFyZVRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYml0TGVuZ3RoID0gYm5CaXRMZW5ndGg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2QgPSBibk1vZDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZFBvd0ludCA9IGJuTW9kUG93SW50O1xuXG4vLyBcImNvbnN0YW50c1wiXG5CaWdJbnRlZ2VyLlpFUk8gPSBuYnYoMCk7XG5CaWdJbnRlZ2VyLk9ORSA9IG5idigxKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCaWdJbnRlZ2VyO1xuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDAzLTIwMDUgIFRvbSBXdSAodGp3QGNzLlN0YW5mb3JkLkVEVSkgXG4gKiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSFxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZ1xuICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4gKiBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbiAqIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0b1xuICogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvXG4gKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmVcbiAqIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTLUlTXCIgQU5EIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIFxuICogRVhQUkVTUywgSU1QTElFRCBPUiBPVEhFUldJU0UsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04sIEFOWSBcbiAqIFdBUlJBTlRZIE9GIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFxuICpcbiAqIElOIE5PIEVWRU5UIFNIQUxMIFRPTSBXVSBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkNJREVOVEFMLFxuICogSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9GIEFOWSBLSU5ELCBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSXG4gKiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIE9SIE5PVCBBRFZJU0VEIE9GXG4gKiBUSEUgUE9TU0lCSUxJVFkgT0YgREFNQUdFLCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIEFSSVNJTkcgT1VUXG4gKiBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxuICpcbiAqIEluIGFkZGl0aW9uLCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbiBhcHBsaWVzOlxuICpcbiAqIEFsbCByZWRpc3RyaWJ1dGlvbnMgbXVzdCByZXRhaW4gYW4gaW50YWN0IGNvcHkgb2YgdGhpcyBjb3B5cmlnaHQgbm90aWNlXG4gKiBhbmQgZGlzY2xhaW1lci5cbiAqL1xuXG5cbi8vIEV4dGVuZGVkIEphdmFTY3JpcHQgQk4gZnVuY3Rpb25zLCByZXF1aXJlZCBmb3IgUlNBIHByaXZhdGUgb3BzLlxuXG4vLyBWZXJzaW9uIDEuMTogbmV3IEJpZ0ludGVnZXIoXCIwXCIsIDEwKSByZXR1cm5zIFwicHJvcGVyXCIgemVyb1xuLy8gVmVyc2lvbiAxLjI6IHNxdWFyZSgpIEFQSSwgaXNQcm9iYWJsZVByaW1lIGZpeFxuXG4vLyAocHVibGljKVxuZnVuY3Rpb24gYm5DbG9uZSgpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5jb3B5VG8ocik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgaW50ZWdlclxuXG5mdW5jdGlvbiBibkludFZhbHVlKCkge1xuICBpZiAodGhpcy5zIDwgMCkge1xuICAgIGlmICh0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXNbMF0gLSB0aGlzLkRWO1xuICAgIGVsc2UgaWYgKHRoaXMudCA9PSAwKSByZXR1cm4gLTE7XG4gIH0gZWxzZSBpZiAodGhpcy50ID09IDEpIHJldHVybiB0aGlzWzBdO1xuICBlbHNlIGlmICh0aGlzLnQgPT0gMCkgcmV0dXJuIDA7XG4gIC8vIGFzc3VtZXMgMTYgPCBEQiA8IDMyXG4gIHJldHVybiAoKHRoaXNbMV0gJiAoKDEgPDwgKDMyIC0gdGhpcy5EQikpIC0gMSkpIDw8IHRoaXMuREIpIHwgdGhpc1swXTtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGJ5dGVcblxuZnVuY3Rpb24gYm5CeXRlVmFsdWUoKSB7XG4gIHJldHVybiAodGhpcy50ID09IDApID8gdGhpcy5zIDogKHRoaXNbMF0gPDwgMjQpID4+IDI0O1xufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgc2hvcnQgKGFzc3VtZXMgREI+PTE2KVxuXG5mdW5jdGlvbiBiblNob3J0VmFsdWUoKSB7XG4gIHJldHVybiAodGhpcy50ID09IDApID8gdGhpcy5zIDogKHRoaXNbMF0gPDwgMTYpID4+IDE2O1xufVxuXG4vLyAocHJvdGVjdGVkKSByZXR1cm4geCBzLnQuIHJeeCA8IERWXG5cbmZ1bmN0aW9uIGJucENodW5rU2l6ZShyKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKE1hdGguTE4yICogdGhpcy5EQiAvIE1hdGgubG9nKHIpKTtcbn1cblxuLy8gKHB1YmxpYykgMCBpZiB0aGlzID09IDAsIDEgaWYgdGhpcyA+IDBcblxuZnVuY3Rpb24gYm5TaWdOdW0oKSB7XG4gIGlmICh0aGlzLnMgPCAwKSByZXR1cm4gLTE7XG4gIGVsc2UgaWYgKHRoaXMudCA8PSAwIHx8ICh0aGlzLnQgPT0gMSAmJiB0aGlzWzBdIDw9IDApKSByZXR1cm4gMDtcbiAgZWxzZSByZXR1cm4gMTtcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCB0byByYWRpeCBzdHJpbmdcblxuZnVuY3Rpb24gYm5wVG9SYWRpeChiKSB7XG4gIGlmIChiID09IG51bGwpIGIgPSAxMDtcbiAgaWYgKHRoaXMuc2lnbnVtKCkgPT0gMCB8fCBiIDwgMiB8fCBiID4gMzYpIHJldHVybiBcIjBcIjtcbiAgdmFyIGNzID0gdGhpcy5jaHVua1NpemUoYik7XG4gIHZhciBhID0gTWF0aC5wb3coYiwgY3MpO1xuICB2YXIgZCA9IG5idihhKSxcbiAgICB5ID0gbmJpKCksXG4gICAgeiA9IG5iaSgpLFxuICAgIHIgPSBcIlwiO1xuICB0aGlzLmRpdlJlbVRvKGQsIHksIHopO1xuICB3aGlsZSAoeS5zaWdudW0oKSA+IDApIHtcbiAgICByID0gKGEgKyB6LmludFZhbHVlKCkpLnRvU3RyaW5nKGIpLnN1YnN0cigxKSArIHI7XG4gICAgeS5kaXZSZW1UbyhkLCB5LCB6KTtcbiAgfVxuICByZXR1cm4gei5pbnRWYWx1ZSgpLnRvU3RyaW5nKGIpICsgcjtcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCBmcm9tIHJhZGl4IHN0cmluZ1xuXG5mdW5jdGlvbiBibnBGcm9tUmFkaXgocywgYikge1xuICB0aGlzLmZyb21JbnQoMCk7XG4gIGlmIChiID09IG51bGwpIGIgPSAxMDtcbiAgdmFyIGNzID0gdGhpcy5jaHVua1NpemUoYik7XG4gIHZhciBkID0gTWF0aC5wb3coYiwgY3MpLFxuICAgIG1pID0gZmFsc2UsXG4gICAgaiA9IDAsXG4gICAgdyA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcy5sZW5ndGg7ICsraSkge1xuICAgIHZhciB4ID0gaW50QXQocywgaSk7XG4gICAgaWYgKHggPCAwKSB7XG4gICAgICBpZiAocy5jaGFyQXQoaSkgPT0gXCItXCIgJiYgdGhpcy5zaWdudW0oKSA9PSAwKSBtaSA9IHRydWU7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdyA9IGIgKiB3ICsgeDtcbiAgICBpZiAoKytqID49IGNzKSB7XG4gICAgICB0aGlzLmRNdWx0aXBseShkKTtcbiAgICAgIHRoaXMuZEFkZE9mZnNldCh3LCAwKTtcbiAgICAgIGogPSAwO1xuICAgICAgdyA9IDA7XG4gICAgfVxuICB9XG4gIGlmIChqID4gMCkge1xuICAgIHRoaXMuZE11bHRpcGx5KE1hdGgucG93KGIsIGopKTtcbiAgICB0aGlzLmRBZGRPZmZzZXQodywgMCk7XG4gIH1cbiAgaWYgKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcywgdGhpcyk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIGFsdGVybmF0ZSBjb25zdHJ1Y3RvclxuXG5mdW5jdGlvbiBibnBGcm9tTnVtYmVyKGEsIGIsIGMpIHtcbiAgaWYgKFwibnVtYmVyXCIgPT0gdHlwZW9mIGIpIHtcbiAgICAvLyBuZXcgQmlnSW50ZWdlcihpbnQsaW50LFJORylcbiAgICBpZiAoYSA8IDIpIHRoaXMuZnJvbUludCgxKTtcbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuZnJvbU51bWJlcihhLCBjKTtcbiAgICAgIGlmICghdGhpcy50ZXN0Qml0KGEgLSAxKSkgLy8gZm9yY2UgTVNCIHNldFxuICAgICAgICB0aGlzLmJpdHdpc2VUbyhCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoYSAtIDEpLCBvcF9vciwgdGhpcyk7XG4gICAgICBpZiAodGhpcy5pc0V2ZW4oKSkgdGhpcy5kQWRkT2Zmc2V0KDEsIDApOyAvLyBmb3JjZSBvZGRcbiAgICAgIHdoaWxlICghdGhpcy5pc1Byb2JhYmxlUHJpbWUoYikpIHtcbiAgICAgICAgdGhpcy5kQWRkT2Zmc2V0KDIsIDApO1xuICAgICAgICBpZiAodGhpcy5iaXRMZW5ndGgoKSA+IGEpIHRoaXMuc3ViVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGEgLSAxKSwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxSTkcpXG4gICAgdmFyIHggPSBuZXcgQXJyYXkoKSxcbiAgICAgIHQgPSBhICYgNztcbiAgICB4Lmxlbmd0aCA9IChhID4+IDMpICsgMTtcbiAgICBiLm5leHRCeXRlcyh4KTtcbiAgICBpZiAodCA+IDApIHhbMF0gJj0gKCgxIDw8IHQpIC0gMSk7XG4gICAgZWxzZSB4WzBdID0gMDtcbiAgICB0aGlzLmZyb21TdHJpbmcoeCwgMjU2KTtcbiAgfVxufVxuXG4vLyAocHVibGljKSBjb252ZXJ0IHRvIGJpZ2VuZGlhbiBieXRlIGFycmF5XG5cbmZ1bmN0aW9uIGJuVG9CeXRlQXJyYXkoKSB7XG4gIHZhciBpID0gdGhpcy50LFxuICAgIHIgPSBuZXcgQXJyYXkoKTtcbiAgclswXSA9IHRoaXMucztcbiAgdmFyIHAgPSB0aGlzLkRCIC0gKGkgKiB0aGlzLkRCKSAlIDgsXG4gICAgZCwgayA9IDA7XG4gIGlmIChpLS0gPiAwKSB7XG4gICAgaWYgKHAgPCB0aGlzLkRCICYmIChkID0gdGhpc1tpXSA+PiBwKSAhPSAodGhpcy5zICYgdGhpcy5ETSkgPj4gcClcbiAgICAgIHJbaysrXSA9IGQgfCAodGhpcy5zIDw8ICh0aGlzLkRCIC0gcCkpO1xuICAgIHdoaWxlIChpID49IDApIHtcbiAgICAgIGlmIChwIDwgOCkge1xuICAgICAgICBkID0gKHRoaXNbaV0gJiAoKDEgPDwgcCkgLSAxKSkgPDwgKDggLSBwKTtcbiAgICAgICAgZCB8PSB0aGlzWy0taV0gPj4gKHAgKz0gdGhpcy5EQiAtIDgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZCA9ICh0aGlzW2ldID4+IChwIC09IDgpKSAmIDB4ZmY7XG4gICAgICAgIGlmIChwIDw9IDApIHtcbiAgICAgICAgICBwICs9IHRoaXMuREI7XG4gICAgICAgICAgLS1pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvL2lmKChkJjB4ODApICE9IDApIGQgfD0gLTI1NjtcbiAgICAgIC8vaWYoayA9PSAwICYmICh0aGlzLnMmMHg4MCkgIT0gKGQmMHg4MCkpICsraztcbiAgICAgIGlmIChrID4gMCB8fCBkICE9IHRoaXMucykgcltrKytdID0gZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGJuRXF1YWxzKGEpIHtcbiAgcmV0dXJuICh0aGlzLmNvbXBhcmVUbyhhKSA9PSAwKTtcbn1cblxuZnVuY3Rpb24gYm5NaW4oYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpIDwgMCkgPyB0aGlzIDogYTtcbn1cblxuZnVuY3Rpb24gYm5NYXgoYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpID4gMCkgPyB0aGlzIDogYTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgb3AgYSAoYml0d2lzZSlcblxuZnVuY3Rpb24gYm5wQml0d2lzZVRvKGEsIG9wLCByKSB7XG4gIHZhciBpLCBmLCBtID0gTWF0aC5taW4oYS50LCB0aGlzLnQpO1xuICBmb3IgKGkgPSAwOyBpIDwgbTsgKytpKSByW2ldID0gb3AodGhpc1tpXSwgYVtpXSk7XG4gIGlmIChhLnQgPCB0aGlzLnQpIHtcbiAgICBmID0gYS5zICYgdGhpcy5ETTtcbiAgICBmb3IgKGkgPSBtOyBpIDwgdGhpcy50OyArK2kpIHJbaV0gPSBvcCh0aGlzW2ldLCBmKTtcbiAgICByLnQgPSB0aGlzLnQ7XG4gIH0gZWxzZSB7XG4gICAgZiA9IHRoaXMucyAmIHRoaXMuRE07XG4gICAgZm9yIChpID0gbTsgaSA8IGEudDsgKytpKSByW2ldID0gb3AoZiwgYVtpXSk7XG4gICAgci50ID0gYS50O1xuICB9XG4gIHIucyA9IG9wKHRoaXMucywgYS5zKTtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHVibGljKSB0aGlzICYgYVxuXG5mdW5jdGlvbiBvcF9hbmQoeCwgeSkge1xuICByZXR1cm4geCAmIHk7XG59XG5cbmZ1bmN0aW9uIGJuQW5kKGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3BfYW5kLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgfCBhXG5cbmZ1bmN0aW9uIG9wX29yKHgsIHkpIHtcbiAgcmV0dXJuIHggfCB5O1xufVxuXG5mdW5jdGlvbiBibk9yKGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3Bfb3IsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBeIGFcblxuZnVuY3Rpb24gb3BfeG9yKHgsIHkpIHtcbiAgcmV0dXJuIHggXiB5O1xufVxuXG5mdW5jdGlvbiBiblhvcihhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYml0d2lzZVRvKGEsIG9wX3hvciwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzICYgfmFcblxuZnVuY3Rpb24gb3BfYW5kbm90KHgsIHkpIHtcbiAgcmV0dXJuIHggJiB+eTtcbn1cblxuZnVuY3Rpb24gYm5BbmROb3QoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmJpdHdpc2VUbyhhLCBvcF9hbmRub3QsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgfnRoaXNcblxuZnVuY3Rpb24gYm5Ob3QoKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHJbaV0gPSB0aGlzLkRNICYgfnRoaXNbaV07XG4gIHIudCA9IHRoaXMudDtcbiAgci5zID0gfnRoaXMucztcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgPDwgblxuXG5mdW5jdGlvbiBiblNoaWZ0TGVmdChuKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIGlmIChuIDwgMCkgdGhpcy5yU2hpZnRUbygtbiwgcik7XG4gIGVsc2UgdGhpcy5sU2hpZnRUbyhuLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgPj4gblxuXG5mdW5jdGlvbiBiblNoaWZ0UmlnaHQobikge1xuICB2YXIgciA9IG5iaSgpO1xuICBpZiAobiA8IDApIHRoaXMubFNoaWZ0VG8oLW4sIHIpO1xuICBlbHNlIHRoaXMuclNoaWZ0VG8obiwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyByZXR1cm4gaW5kZXggb2YgbG93ZXN0IDEtYml0IGluIHgsIHggPCAyXjMxXG5cbmZ1bmN0aW9uIGxiaXQoeCkge1xuICBpZiAoeCA9PSAwKSByZXR1cm4gLTE7XG4gIHZhciByID0gMDtcbiAgaWYgKCh4ICYgMHhmZmZmKSA9PSAwKSB7XG4gICAgeCA+Pj0gMTY7XG4gICAgciArPSAxNjtcbiAgfVxuICBpZiAoKHggJiAweGZmKSA9PSAwKSB7XG4gICAgeCA+Pj0gODtcbiAgICByICs9IDg7XG4gIH1cbiAgaWYgKCh4ICYgMHhmKSA9PSAwKSB7XG4gICAgeCA+Pj0gNDtcbiAgICByICs9IDQ7XG4gIH1cbiAgaWYgKCh4ICYgMykgPT0gMCkge1xuICAgIHggPj49IDI7XG4gICAgciArPSAyO1xuICB9XG4gIGlmICgoeCAmIDEpID09IDApKytyO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJucyBpbmRleCBvZiBsb3dlc3QgMS1iaXQgKG9yIC0xIGlmIG5vbmUpXG5cbmZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKVxuICAgIGlmICh0aGlzW2ldICE9IDApIHJldHVybiBpICogdGhpcy5EQiArIGxiaXQodGhpc1tpXSk7XG4gIGlmICh0aGlzLnMgPCAwKSByZXR1cm4gdGhpcy50ICogdGhpcy5EQjtcbiAgcmV0dXJuIC0xO1xufVxuXG4vLyByZXR1cm4gbnVtYmVyIG9mIDEgYml0cyBpbiB4XG5cbmZ1bmN0aW9uIGNiaXQoeCkge1xuICB2YXIgciA9IDA7XG4gIHdoaWxlICh4ICE9IDApIHtcbiAgICB4ICY9IHggLSAxO1xuICAgICsrcjtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIG51bWJlciBvZiBzZXQgYml0c1xuXG5mdW5jdGlvbiBibkJpdENvdW50KCkge1xuICB2YXIgciA9IDAsXG4gICAgeCA9IHRoaXMucyAmIHRoaXMuRE07XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHIgKz0gY2JpdCh0aGlzW2ldIF4geCk7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0cnVlIGlmZiBudGggYml0IGlzIHNldFxuXG5mdW5jdGlvbiBiblRlc3RCaXQobikge1xuICB2YXIgaiA9IE1hdGguZmxvb3IobiAvIHRoaXMuREIpO1xuICBpZiAoaiA+PSB0aGlzLnQpIHJldHVybiAodGhpcy5zICE9IDApO1xuICByZXR1cm4gKCh0aGlzW2pdICYgKDEgPDwgKG4gJSB0aGlzLkRCKSkpICE9IDApO1xufVxuXG4vLyAocHJvdGVjdGVkKSB0aGlzIG9wICgxPDxuKVxuXG5mdW5jdGlvbiBibnBDaGFuZ2VCaXQobiwgb3ApIHtcbiAgdmFyIHIgPSBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQobik7XG4gIHRoaXMuYml0d2lzZVRvKHIsIG9wLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgfCAoMTw8bilcblxuZnVuY3Rpb24gYm5TZXRCaXQobikge1xuICByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobiwgb3Bfb3IpO1xufVxuXG4vLyAocHVibGljKSB0aGlzICYgfigxPDxuKVxuXG5mdW5jdGlvbiBibkNsZWFyQml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX2FuZG5vdCk7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgXiAoMTw8bilcblxuZnVuY3Rpb24gYm5GbGlwQml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX3hvcik7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICsgYVxuXG5mdW5jdGlvbiBibnBBZGRUbyhhLCByKSB7XG4gIHZhciBpID0gMCxcbiAgICBjID0gMCxcbiAgICBtID0gTWF0aC5taW4oYS50LCB0aGlzLnQpO1xuICB3aGlsZSAoaSA8IG0pIHtcbiAgICBjICs9IHRoaXNbaV0gKyBhW2ldO1xuICAgIHJbaSsrXSA9IGMgJiB0aGlzLkRNO1xuICAgIGMgPj49IHRoaXMuREI7XG4gIH1cbiAgaWYgKGEudCA8IHRoaXMudCkge1xuICAgIGMgKz0gYS5zO1xuICAgIHdoaWxlIChpIDwgdGhpcy50KSB7XG4gICAgICBjICs9IHRoaXNbaV07XG4gICAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgKz0gdGhpcy5zO1xuICB9IGVsc2Uge1xuICAgIGMgKz0gdGhpcy5zO1xuICAgIHdoaWxlIChpIDwgYS50KSB7XG4gICAgICBjICs9IGFbaV07XG4gICAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgKz0gYS5zO1xuICB9XG4gIHIucyA9IChjIDwgMCkgPyAtMSA6IDA7XG4gIGlmIChjID4gMCkgcltpKytdID0gYztcbiAgZWxzZSBpZiAoYyA8IC0xKSByW2krK10gPSB0aGlzLkRWICsgYztcbiAgci50ID0gaTtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHVibGljKSB0aGlzICsgYVxuXG5mdW5jdGlvbiBibkFkZChhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYWRkVG8oYSwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIC0gYVxuXG5mdW5jdGlvbiBiblN1YnRyYWN0KGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5zdWJUbyhhLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgKiBhXG5cbmZ1bmN0aW9uIGJuTXVsdGlwbHkoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLm11bHRpcGx5VG8oYSwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzXjJcblxuZnVuY3Rpb24gYm5TcXVhcmUoKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuc3F1YXJlVG8ocik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIC8gYVxuXG5mdW5jdGlvbiBibkRpdmlkZShhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuZGl2UmVtVG8oYSwgciwgbnVsbCk7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzICUgYVxuXG5mdW5jdGlvbiBiblJlbWFpbmRlcihhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuZGl2UmVtVG8oYSwgbnVsbCwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSBbdGhpcy9hLHRoaXMlYV1cblxuZnVuY3Rpb24gYm5EaXZpZGVBbmRSZW1haW5kZXIoYSkge1xuICB2YXIgcSA9IG5iaSgpLFxuICAgIHIgPSBuYmkoKTtcbiAgdGhpcy5kaXZSZW1UbyhhLCBxLCByKTtcbiAgcmV0dXJuIG5ldyBBcnJheShxLCByKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyAqPSBuLCB0aGlzID49IDAsIDEgPCBuIDwgRFZcblxuZnVuY3Rpb24gYm5wRE11bHRpcGx5KG4pIHtcbiAgdGhpc1t0aGlzLnRdID0gdGhpcy5hbSgwLCBuIC0gMSwgdGhpcywgMCwgMCwgdGhpcy50KTtcbiAgKyt0aGlzLnQ7XG4gIHRoaXMuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyArPSBuIDw8IHcgd29yZHMsIHRoaXMgPj0gMFxuXG5mdW5jdGlvbiBibnBEQWRkT2Zmc2V0KG4sIHcpIHtcbiAgaWYgKG4gPT0gMCkgcmV0dXJuO1xuICB3aGlsZSAodGhpcy50IDw9IHcpIHRoaXNbdGhpcy50KytdID0gMDtcbiAgdGhpc1t3XSArPSBuO1xuICB3aGlsZSAodGhpc1t3XSA+PSB0aGlzLkRWKSB7XG4gICAgdGhpc1t3XSAtPSB0aGlzLkRWO1xuICAgIGlmICgrK3cgPj0gdGhpcy50KSB0aGlzW3RoaXMudCsrXSA9IDA7XG4gICAgKyt0aGlzW3ddO1xuICB9XG59XG5cbi8vIEEgXCJudWxsXCIgcmVkdWNlclxuXG5mdW5jdGlvbiBOdWxsRXhwKCkge31cblxuZnVuY3Rpb24gbk5vcCh4KSB7XG4gIHJldHVybiB4O1xufVxuXG5mdW5jdGlvbiBuTXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcik7XG59XG5cbmZ1bmN0aW9uIG5TcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocik7XG59XG5cbk51bGxFeHAucHJvdG90eXBlLmNvbnZlcnQgPSBuTm9wO1xuTnVsbEV4cC5wcm90b3R5cGUucmV2ZXJ0ID0gbk5vcDtcbk51bGxFeHAucHJvdG90eXBlLm11bFRvID0gbk11bFRvO1xuTnVsbEV4cC5wcm90b3R5cGUuc3FyVG8gPSBuU3FyVG87XG5cbi8vIChwdWJsaWMpIHRoaXNeZVxuXG5mdW5jdGlvbiBiblBvdyhlKSB7XG4gIHJldHVybiB0aGlzLmV4cChlLCBuZXcgTnVsbEV4cCgpKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IGxvd2VyIG4gd29yZHMgb2YgXCJ0aGlzICogYVwiLCBhLnQgPD0gblxuLy8gXCJ0aGlzXCIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLlxuXG5mdW5jdGlvbiBibnBNdWx0aXBseUxvd2VyVG8oYSwgbiwgcikge1xuICB2YXIgaSA9IE1hdGgubWluKHRoaXMudCArIGEudCwgbik7XG4gIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDBcbiAgci50ID0gaTtcbiAgd2hpbGUgKGkgPiAwKSByWy0taV0gPSAwO1xuICB2YXIgajtcbiAgZm9yIChqID0gci50IC0gdGhpcy50OyBpIDwgajsgKytpKSByW2kgKyB0aGlzLnRdID0gdGhpcy5hbSgwLCBhW2ldLCByLCBpLCAwLCB0aGlzLnQpO1xuICBmb3IgKGogPSBNYXRoLm1pbihhLnQsIG4pOyBpIDwgajsgKytpKSB0aGlzLmFtKDAsIGFbaV0sIHIsIGksIDAsIG4gLSBpKTtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gXCJ0aGlzICogYVwiIHdpdGhvdXQgbG93ZXIgbiB3b3JkcywgbiA+IDBcbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cblxuZnVuY3Rpb24gYm5wTXVsdGlwbHlVcHBlclRvKGEsIG4sIHIpIHtcbiAgLS1uO1xuICB2YXIgaSA9IHIudCA9IHRoaXMudCArIGEudCAtIG47XG4gIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDBcbiAgd2hpbGUgKC0taSA+PSAwKSByW2ldID0gMDtcbiAgZm9yIChpID0gTWF0aC5tYXgobiAtIHRoaXMudCwgMCk7IGkgPCBhLnQ7ICsraSlcbiAgICByW3RoaXMudCArIGkgLSBuXSA9IHRoaXMuYW0obiAtIGksIGFbaV0sIHIsIDAsIDAsIHRoaXMudCArIGkgLSBuKTtcbiAgci5jbGFtcCgpO1xuICByLmRyU2hpZnRUbygxLCByKTtcbn1cblxuLy8gQmFycmV0dCBtb2R1bGFyIHJlZHVjdGlvblxuXG5mdW5jdGlvbiBCYXJyZXR0KG0pIHtcbiAgLy8gc2V0dXAgQmFycmV0dFxuICB0aGlzLnIyID0gbmJpKCk7XG4gIHRoaXMucTMgPSBuYmkoKTtcbiAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKDIgKiBtLnQsIHRoaXMucjIpO1xuICB0aGlzLm11ID0gdGhpcy5yMi5kaXZpZGUobSk7XG4gIHRoaXMubSA9IG07XG59XG5cbmZ1bmN0aW9uIGJhcnJldHRDb252ZXJ0KHgpIHtcbiAgaWYgKHgucyA8IDAgfHwgeC50ID4gMiAqIHRoaXMubS50KSByZXR1cm4geC5tb2QodGhpcy5tKTtcbiAgZWxzZSBpZiAoeC5jb21wYXJlVG8odGhpcy5tKSA8IDApIHJldHVybiB4O1xuICBlbHNlIHtcbiAgICB2YXIgciA9IG5iaSgpO1xuICAgIHguY29weVRvKHIpO1xuICAgIHRoaXMucmVkdWNlKHIpO1xuICAgIHJldHVybiByO1xuICB9XG59XG5cbmZ1bmN0aW9uIGJhcnJldHRSZXZlcnQoeCkge1xuICByZXR1cm4geDtcbn1cblxuLy8geCA9IHggbW9kIG0gKEhBQyAxNC40MilcblxuZnVuY3Rpb24gYmFycmV0dFJlZHVjZSh4KSB7XG4gIHguZHJTaGlmdFRvKHRoaXMubS50IC0gMSwgdGhpcy5yMik7XG4gIGlmICh4LnQgPiB0aGlzLm0udCArIDEpIHtcbiAgICB4LnQgPSB0aGlzLm0udCArIDE7XG4gICAgeC5jbGFtcCgpO1xuICB9XG4gIHRoaXMubXUubXVsdGlwbHlVcHBlclRvKHRoaXMucjIsIHRoaXMubS50ICsgMSwgdGhpcy5xMyk7XG4gIHRoaXMubS5tdWx0aXBseUxvd2VyVG8odGhpcy5xMywgdGhpcy5tLnQgKyAxLCB0aGlzLnIyKTtcbiAgd2hpbGUgKHguY29tcGFyZVRvKHRoaXMucjIpIDwgMCkgeC5kQWRkT2Zmc2V0KDEsIHRoaXMubS50ICsgMSk7XG4gIHguc3ViVG8odGhpcy5yMiwgeCk7XG4gIHdoaWxlICh4LmNvbXBhcmVUbyh0aGlzLm0pID49IDApIHguc3ViVG8odGhpcy5tLCB4KTtcbn1cblxuLy8gciA9IHheMiBtb2QgbTsgeCAhPSByXG5cbmZ1bmN0aW9uIGJhcnJldHRTcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocik7XG4gIHRoaXMucmVkdWNlKHIpO1xufVxuXG4vLyByID0geCp5IG1vZCBtOyB4LHkgIT0gclxuXG5mdW5jdGlvbiBiYXJyZXR0TXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcik7XG4gIHRoaXMucmVkdWNlKHIpO1xufVxuXG5CYXJyZXR0LnByb3RvdHlwZS5jb252ZXJ0ID0gYmFycmV0dENvbnZlcnQ7XG5CYXJyZXR0LnByb3RvdHlwZS5yZXZlcnQgPSBiYXJyZXR0UmV2ZXJ0O1xuQmFycmV0dC5wcm90b3R5cGUucmVkdWNlID0gYmFycmV0dFJlZHVjZTtcbkJhcnJldHQucHJvdG90eXBlLm11bFRvID0gYmFycmV0dE11bFRvO1xuQmFycmV0dC5wcm90b3R5cGUuc3FyVG8gPSBiYXJyZXR0U3FyVG87XG5cbi8vIChwdWJsaWMpIHRoaXNeZSAlIG0gKEhBQyAxNC44NSlcblxuZnVuY3Rpb24gYm5Nb2RQb3coZSwgbSkge1xuICB2YXIgaSA9IGUuYml0TGVuZ3RoKCksXG4gICAgaywgciA9IG5idigxKSxcbiAgICB6O1xuICBpZiAoaSA8PSAwKSByZXR1cm4gcjtcbiAgZWxzZSBpZiAoaSA8IDE4KSBrID0gMTtcbiAgZWxzZSBpZiAoaSA8IDQ4KSBrID0gMztcbiAgZWxzZSBpZiAoaSA8IDE0NCkgayA9IDQ7XG4gIGVsc2UgaWYgKGkgPCA3NjgpIGsgPSA1O1xuICBlbHNlIGsgPSA2O1xuICBpZiAoaSA8IDgpXG4gICAgeiA9IG5ldyBDbGFzc2ljKG0pO1xuICBlbHNlIGlmIChtLmlzRXZlbigpKVxuICAgIHogPSBuZXcgQmFycmV0dChtKTtcbiAgZWxzZVxuICAgIHogPSBuZXcgTW9udGdvbWVyeShtKTtcblxuICAvLyBwcmVjb21wdXRhdGlvblxuICB2YXIgZyA9IG5ldyBBcnJheSgpLFxuICAgIG4gPSAzLFxuICAgIGsxID0gayAtIDEsXG4gICAga20gPSAoMSA8PCBrKSAtIDE7XG4gIGdbMV0gPSB6LmNvbnZlcnQodGhpcyk7XG4gIGlmIChrID4gMSkge1xuICAgIHZhciBnMiA9IG5iaSgpO1xuICAgIHouc3FyVG8oZ1sxXSwgZzIpO1xuICAgIHdoaWxlIChuIDw9IGttKSB7XG4gICAgICBnW25dID0gbmJpKCk7XG4gICAgICB6Lm11bFRvKGcyLCBnW24gLSAyXSwgZ1tuXSk7XG4gICAgICBuICs9IDI7XG4gICAgfVxuICB9XG5cbiAgdmFyIGogPSBlLnQgLSAxLFxuICAgIHcsIGlzMSA9IHRydWUsXG4gICAgcjIgPSBuYmkoKSxcbiAgICB0O1xuICBpID0gbmJpdHMoZVtqXSkgLSAxO1xuICB3aGlsZSAoaiA+PSAwKSB7XG4gICAgaWYgKGkgPj0gazEpIHcgPSAoZVtqXSA+PiAoaSAtIGsxKSkgJiBrbTtcbiAgICBlbHNlIHtcbiAgICAgIHcgPSAoZVtqXSAmICgoMSA8PCAoaSArIDEpKSAtIDEpKSA8PCAoazEgLSBpKTtcbiAgICAgIGlmIChqID4gMCkgdyB8PSBlW2ogLSAxXSA+PiAodGhpcy5EQiArIGkgLSBrMSk7XG4gICAgfVxuXG4gICAgbiA9IGs7XG4gICAgd2hpbGUgKCh3ICYgMSkgPT0gMCkge1xuICAgICAgdyA+Pj0gMTtcbiAgICAgIC0tbjtcbiAgICB9XG4gICAgaWYgKChpIC09IG4pIDwgMCkge1xuICAgICAgaSArPSB0aGlzLkRCO1xuICAgICAgLS1qO1xuICAgIH1cbiAgICBpZiAoaXMxKSB7IC8vIHJldCA9PSAxLCBkb24ndCBib3RoZXIgc3F1YXJpbmcgb3IgbXVsdGlwbHlpbmcgaXRcbiAgICAgIGdbd10uY29weVRvKHIpO1xuICAgICAgaXMxID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoaWxlIChuID4gMSkge1xuICAgICAgICB6LnNxclRvKHIsIHIyKTtcbiAgICAgICAgei5zcXJUbyhyMiwgcik7XG4gICAgICAgIG4gLT0gMjtcbiAgICAgIH1cbiAgICAgIGlmIChuID4gMCkgei5zcXJUbyhyLCByMik7XG4gICAgICBlbHNlIHtcbiAgICAgICAgdCA9IHI7XG4gICAgICAgIHIgPSByMjtcbiAgICAgICAgcjIgPSB0O1xuICAgICAgfVxuICAgICAgei5tdWxUbyhyMiwgZ1t3XSwgcik7XG4gICAgfVxuXG4gICAgd2hpbGUgKGogPj0gMCAmJiAoZVtqXSAmICgxIDw8IGkpKSA9PSAwKSB7XG4gICAgICB6LnNxclRvKHIsIHIyKTtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IHIyO1xuICAgICAgcjIgPSB0O1xuICAgICAgaWYgKC0taSA8IDApIHtcbiAgICAgICAgaSA9IHRoaXMuREIgLSAxO1xuICAgICAgICAtLWo7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB6LnJldmVydChyKTtcbn1cblxuLy8gKHB1YmxpYykgZ2NkKHRoaXMsYSkgKEhBQyAxNC41NClcblxuZnVuY3Rpb24gYm5HQ0QoYSkge1xuICB2YXIgeCA9ICh0aGlzLnMgPCAwKSA/IHRoaXMubmVnYXRlKCkgOiB0aGlzLmNsb25lKCk7XG4gIHZhciB5ID0gKGEucyA8IDApID8gYS5uZWdhdGUoKSA6IGEuY2xvbmUoKTtcbiAgaWYgKHguY29tcGFyZVRvKHkpIDwgMCkge1xuICAgIHZhciB0ID0geDtcbiAgICB4ID0geTtcbiAgICB5ID0gdDtcbiAgfVxuICB2YXIgaSA9IHguZ2V0TG93ZXN0U2V0Qml0KCksXG4gICAgZyA9IHkuZ2V0TG93ZXN0U2V0Qml0KCk7XG4gIGlmIChnIDwgMCkgcmV0dXJuIHg7XG4gIGlmIChpIDwgZykgZyA9IGk7XG4gIGlmIChnID4gMCkge1xuICAgIHguclNoaWZ0VG8oZywgeCk7XG4gICAgeS5yU2hpZnRUbyhnLCB5KTtcbiAgfVxuICB3aGlsZSAoeC5zaWdudW0oKSA+IDApIHtcbiAgICBpZiAoKGkgPSB4LmdldExvd2VzdFNldEJpdCgpKSA+IDApIHguclNoaWZ0VG8oaSwgeCk7XG4gICAgaWYgKChpID0geS5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB5LnJTaGlmdFRvKGksIHkpO1xuICAgIGlmICh4LmNvbXBhcmVUbyh5KSA+PSAwKSB7XG4gICAgICB4LnN1YlRvKHksIHgpO1xuICAgICAgeC5yU2hpZnRUbygxLCB4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgeS5zdWJUbyh4LCB5KTtcbiAgICAgIHkuclNoaWZ0VG8oMSwgeSk7XG4gICAgfVxuICB9XG4gIGlmIChnID4gMCkgeS5sU2hpZnRUbyhnLCB5KTtcbiAgcmV0dXJuIHk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgJSBuLCBuIDwgMl4yNlxuXG5mdW5jdGlvbiBibnBNb2RJbnQobikge1xuICBpZiAobiA8PSAwKSByZXR1cm4gMDtcbiAgdmFyIGQgPSB0aGlzLkRWICUgbixcbiAgICByID0gKHRoaXMucyA8IDApID8gbiAtIDEgOiAwO1xuICBpZiAodGhpcy50ID4gMClcbiAgICBpZiAoZCA9PSAwKSByID0gdGhpc1swXSAlIG47XG4gICAgZWxzZSBmb3IgKHZhciBpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHIgPSAoZCAqIHIgKyB0aGlzW2ldKSAlIG47XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSAxL3RoaXMgJSBtIChIQUMgMTQuNjEpXG5cbmZ1bmN0aW9uIGJuTW9kSW52ZXJzZShtKSB7XG4gIHZhciBhYyA9IG0uaXNFdmVuKCk7XG4gIGlmICgodGhpcy5pc0V2ZW4oKSAmJiBhYykgfHwgbS5zaWdudW0oKSA9PSAwKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPO1xuICB2YXIgdSA9IG0uY2xvbmUoKSxcbiAgICB2ID0gdGhpcy5jbG9uZSgpO1xuICB2YXIgYSA9IG5idigxKSxcbiAgICBiID0gbmJ2KDApLFxuICAgIGMgPSBuYnYoMCksXG4gICAgZCA9IG5idigxKTtcbiAgd2hpbGUgKHUuc2lnbnVtKCkgIT0gMCkge1xuICAgIHdoaWxlICh1LmlzRXZlbigpKSB7XG4gICAgICB1LnJTaGlmdFRvKDEsIHUpO1xuICAgICAgaWYgKGFjKSB7XG4gICAgICAgIGlmICghYS5pc0V2ZW4oKSB8fCAhYi5pc0V2ZW4oKSkge1xuICAgICAgICAgIGEuYWRkVG8odGhpcywgYSk7XG4gICAgICAgICAgYi5zdWJUbyhtLCBiKTtcbiAgICAgICAgfVxuICAgICAgICBhLnJTaGlmdFRvKDEsIGEpO1xuICAgICAgfSBlbHNlIGlmICghYi5pc0V2ZW4oKSkgYi5zdWJUbyhtLCBiKTtcbiAgICAgIGIuclNoaWZ0VG8oMSwgYik7XG4gICAgfVxuICAgIHdoaWxlICh2LmlzRXZlbigpKSB7XG4gICAgICB2LnJTaGlmdFRvKDEsIHYpO1xuICAgICAgaWYgKGFjKSB7XG4gICAgICAgIGlmICghYy5pc0V2ZW4oKSB8fCAhZC5pc0V2ZW4oKSkge1xuICAgICAgICAgIGMuYWRkVG8odGhpcywgYyk7XG4gICAgICAgICAgZC5zdWJUbyhtLCBkKTtcbiAgICAgICAgfVxuICAgICAgICBjLnJTaGlmdFRvKDEsIGMpO1xuICAgICAgfSBlbHNlIGlmICghZC5pc0V2ZW4oKSkgZC5zdWJUbyhtLCBkKTtcbiAgICAgIGQuclNoaWZ0VG8oMSwgZCk7XG4gICAgfVxuICAgIGlmICh1LmNvbXBhcmVUbyh2KSA+PSAwKSB7XG4gICAgICB1LnN1YlRvKHYsIHUpO1xuICAgICAgaWYgKGFjKSBhLnN1YlRvKGMsIGEpO1xuICAgICAgYi5zdWJUbyhkLCBiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdi5zdWJUbyh1LCB2KTtcbiAgICAgIGlmIChhYykgYy5zdWJUbyhhLCBjKTtcbiAgICAgIGQuc3ViVG8oYiwgZCk7XG4gICAgfVxuICB9XG4gIGlmICh2LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVSTztcbiAgaWYgKGQuY29tcGFyZVRvKG0pID49IDApIHJldHVybiBkLnN1YnRyYWN0KG0pO1xuICBpZiAoZC5zaWdudW0oKSA8IDApIGQuYWRkVG8obSwgZCk7XG4gIGVsc2UgcmV0dXJuIGQ7XG4gIGlmIChkLnNpZ251bSgpIDwgMCkgcmV0dXJuIGQuYWRkKG0pO1xuICBlbHNlIHJldHVybiBkO1xufVxuXG52YXIgbG93cHJpbWVzID0gWzIsIDMsIDUsIDcsIDExLCAxMywgMTcsIDE5LCAyMywgMjksIDMxLCAzNywgNDEsIDQzLCA0NywgNTMsIDU5LCA2MSwgNjcsIDcxLCA3MywgNzksIDgzLCA4OSwgOTcsIDEwMSxcbiAgICAxMDMsIDEwNywgMTA5LCAxMTMsIDEyNywgMTMxLCAxMzcsIDEzOSwgMTQ5LCAxNTEsIDE1NywgMTYzLCAxNjcsIDE3MywgMTc5LCAxODEsIDE5MSwgMTkzLCAxOTcsIDE5OSwgMjExLCAyMjMsIDIyNyxcbiAgICAyMjksIDIzMywgMjM5LCAyNDEsIDI1MSwgMjU3LCAyNjMsIDI2OSwgMjcxLCAyNzcsIDI4MSwgMjgzLCAyOTMsIDMwNywgMzExLCAzMTMsIDMxNywgMzMxLCAzMzcsIDM0NywgMzQ5LCAzNTMsIDM1OSxcbiAgICAzNjcsIDM3MywgMzc5LCAzODMsIDM4OSwgMzk3LCA0MDEsIDQwOSwgNDE5LCA0MjEsIDQzMSwgNDMzLCA0MzksIDQ0MywgNDQ5LCA0NTcsIDQ2MSwgNDYzLCA0NjcsIDQ3OSwgNDg3LCA0OTEsIDQ5OSxcbiAgICA1MDMsIDUwOSwgNTIxLCA1MjMsIDU0MSwgNTQ3LCA1NTcsIDU2MywgNTY5LCA1NzEsIDU3NywgNTg3LCA1OTMsIDU5OSwgNjAxLCA2MDcsIDYxMywgNjE3LCA2MTksIDYzMSwgNjQxLCA2NDMsIDY0NyxcbiAgICA2NTMsIDY1OSwgNjYxLCA2NzMsIDY3NywgNjgzLCA2OTEsIDcwMSwgNzA5LCA3MTksIDcyNywgNzMzLCA3MzksIDc0MywgNzUxLCA3NTcsIDc2MSwgNzY5LCA3NzMsIDc4NywgNzk3LCA4MDksIDgxMSxcbiAgICA4MjEsIDgyMywgODI3LCA4MjksIDgzOSwgODUzLCA4NTcsIDg1OSwgODYzLCA4NzcsIDg4MSwgODgzLCA4ODcsIDkwNywgOTExLCA5MTksIDkyOSwgOTM3LCA5NDEsIDk0NywgOTUzLCA5NjcsIDk3MSxcbiAgICA5NzcsIDk4MywgOTkxLCA5OTdcbl07XG52YXIgbHBsaW0gPSAoMSA8PCAyNikgLyBsb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aCAtIDFdO1xuXG4vLyAocHVibGljKSB0ZXN0IHByaW1hbGl0eSB3aXRoIGNlcnRhaW50eSA+PSAxLS41XnRcblxuZnVuY3Rpb24gYm5Jc1Byb2JhYmxlUHJpbWUodCkge1xuICB2YXIgaSwgeCA9IHRoaXMuYWJzKCk7XG4gIGlmICh4LnQgPT0gMSAmJiB4WzBdIDw9IGxvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoIC0gMV0pIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKVxuICAgICAgaWYgKHhbMF0gPT0gbG93cHJpbWVzW2ldKSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHguaXNFdmVuKCkpIHJldHVybiBmYWxzZTtcbiAgaSA9IDE7XG4gIHdoaWxlIChpIDwgbG93cHJpbWVzLmxlbmd0aCkge1xuICAgIHZhciBtID0gbG93cHJpbWVzW2ldLFxuICAgICAgaiA9IGkgKyAxO1xuICAgIHdoaWxlIChqIDwgbG93cHJpbWVzLmxlbmd0aCAmJiBtIDwgbHBsaW0pIG0gKj0gbG93cHJpbWVzW2orK107XG4gICAgbSA9IHgubW9kSW50KG0pO1xuICAgIHdoaWxlIChpIDwgaikgaWYgKG0gJSBsb3dwcmltZXNbaSsrXSA9PSAwKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHgubWlsbGVyUmFiaW4odCk7XG59XG5cbi8qIGFkZGVkIGJ5IFJlY3VyaXR5IExhYnMgKi9cblxuZnVuY3Rpb24gbmJpdHMoeCkge1xuICB2YXIgbiA9IDEsXG4gICAgdDtcbiAgaWYgKCh0ID0geCA+Pj4gMTYpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICBuICs9IDE2O1xuICB9XG4gIGlmICgodCA9IHggPj4gOCkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIG4gKz0gODtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDQpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICBuICs9IDQ7XG4gIH1cbiAgaWYgKCh0ID0geCA+PiAyKSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgbiArPSAyO1xuICB9XG4gIGlmICgodCA9IHggPj4gMSkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIG4gKz0gMTtcbiAgfVxuICByZXR1cm4gbjtcbn1cblxuZnVuY3Rpb24gYm5Ub01QSSgpIHtcbiAgdmFyIGJhID0gdGhpcy50b0J5dGVBcnJheSgpO1xuICB2YXIgc2l6ZSA9IChiYS5sZW5ndGggLSAxKSAqIDggKyBuYml0cyhiYVswXSk7XG4gIHZhciByZXN1bHQgPSBcIlwiO1xuICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoc2l6ZSAmIDB4RkYwMCkgPj4gOCk7XG4gIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHNpemUgJiAweEZGKTtcbiAgcmVzdWx0ICs9IHV0aWwuYmluMnN0cihiYSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG4vKiBFTkQgb2YgYWRkaXRpb24gKi9cblxuLy8gKHByb3RlY3RlZCkgdHJ1ZSBpZiBwcm9iYWJseSBwcmltZSAoSEFDIDQuMjQsIE1pbGxlci1SYWJpbilcbmZ1bmN0aW9uIGJucE1pbGxlclJhYmluKHQpIHtcbiAgdmFyIG4xID0gdGhpcy5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gIHZhciBrID0gbjEuZ2V0TG93ZXN0U2V0Qml0KCk7XG4gIGlmIChrIDw9IDApIHJldHVybiBmYWxzZTtcbiAgdmFyIHIgPSBuMS5zaGlmdFJpZ2h0KGspO1xuICB0ID0gKHQgKyAxKSA+PiAxO1xuICBpZiAodCA+IGxvd3ByaW1lcy5sZW5ndGgpIHQgPSBsb3dwcmltZXMubGVuZ3RoO1xuICB2YXIgYSA9IG5iaSgpO1xuICB2YXIgaiwgYmFzZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0OyArK2kpIHtcbiAgICAvL1BpY2sgYmFzZXMgYXQgcmFuZG9tLCBpbnN0ZWFkIG9mIHN0YXJ0aW5nIGF0IDJcbiAgICBmb3IgKDs7KSB7XG4gICAgICBqID0gbG93cHJpbWVzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGxvd3ByaW1lcy5sZW5ndGgpXTtcbiAgICAgIGlmIChiYXNlcy5pbmRleE9mKGopID09IC0xKSBicmVhaztcbiAgICB9XG4gICAgYmFzZXMucHVzaChqKTtcbiAgICBhLmZyb21JbnQoaik7XG4gICAgdmFyIHkgPSBhLm1vZFBvdyhyLCB0aGlzKTtcbiAgICBpZiAoeS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDAgJiYgeS5jb21wYXJlVG8objEpICE9IDApIHtcbiAgICAgIHZhciBqID0gMTtcbiAgICAgIHdoaWxlIChqKysgPCBrICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7XG4gICAgICAgIHkgPSB5Lm1vZFBvd0ludCgyLCB0aGlzKTtcbiAgICAgICAgaWYgKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoeS5jb21wYXJlVG8objEpICE9IDApIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9qc2JuLmpzJyk7XG5cbi8vIHByb3RlY3RlZFxuQmlnSW50ZWdlci5wcm90b3R5cGUuY2h1bmtTaXplID0gYm5wQ2h1bmtTaXplO1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9SYWRpeCA9IGJucFRvUmFkaXg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tUmFkaXggPSBibnBGcm9tUmFkaXg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tTnVtYmVyID0gYm5wRnJvbU51bWJlcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmJpdHdpc2VUbyA9IGJucEJpdHdpc2VUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNoYW5nZUJpdCA9IGJucENoYW5nZUJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmFkZFRvID0gYm5wQWRkVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kTXVsdGlwbHkgPSBibnBETXVsdGlwbHk7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kQWRkT2Zmc2V0ID0gYm5wREFkZE9mZnNldDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5TG93ZXJUbyA9IGJucE11bHRpcGx5TG93ZXJUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VXBwZXJUbyA9IGJucE11bHRpcGx5VXBwZXJUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludCA9IGJucE1vZEludDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1pbGxlclJhYmluID0gYm5wTWlsbGVyUmFiaW47XG5cbi8vIHB1YmxpY1xuQmlnSW50ZWdlci5wcm90b3R5cGUuY2xvbmUgPSBibkNsb25lO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuaW50VmFsdWUgPSBibkludFZhbHVlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYnl0ZVZhbHVlID0gYm5CeXRlVmFsdWU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zaG9ydFZhbHVlID0gYm5TaG9ydFZhbHVlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc2lnbnVtID0gYm5TaWdOdW07XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b0J5dGVBcnJheSA9IGJuVG9CeXRlQXJyYXk7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5lcXVhbHMgPSBibkVxdWFscztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1pbiA9IGJuTWluO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubWF4ID0gYm5NYXg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hbmQgPSBibkFuZDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm9yID0gYm5PcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnhvciA9IGJuWG9yO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kTm90ID0gYm5BbmROb3Q7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5ub3QgPSBibk5vdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0TGVmdCA9IGJuU2hpZnRMZWZ0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRSaWdodCA9IGJuU2hpZnRSaWdodDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmdldExvd2VzdFNldEJpdCA9IGJuR2V0TG93ZXN0U2V0Qml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYml0Q291bnQgPSBibkJpdENvdW50O1xuQmlnSW50ZWdlci5wcm90b3R5cGUudGVzdEJpdCA9IGJuVGVzdEJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNldEJpdCA9IGJuU2V0Qml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuY2xlYXJCaXQgPSBibkNsZWFyQml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZmxpcEJpdCA9IGJuRmxpcEJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmFkZCA9IGJuQWRkO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc3VidHJhY3QgPSBiblN1YnRyYWN0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHkgPSBibk11bHRpcGx5O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2aWRlID0gYm5EaXZpZGU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5yZW1haW5kZXIgPSBiblJlbWFpbmRlcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZUFuZFJlbWFpbmRlciA9IGJuRGl2aWRlQW5kUmVtYWluZGVyO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93ID0gYm5Nb2RQb3c7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RJbnZlcnNlID0gYm5Nb2RJbnZlcnNlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUucG93ID0gYm5Qb3c7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5nY2QgPSBibkdDRDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmlzUHJvYmFibGVQcmltZSA9IGJuSXNQcm9iYWJsZVByaW1lO1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9NUEkgPSBiblRvTVBJO1xuXG4vLyBKU0JOLXNwZWNpZmljIGV4dGVuc2lvblxuQmlnSW50ZWdlci5wcm90b3R5cGUuc3F1YXJlID0gYm5TcXVhcmU7XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuLy9cbi8vIFJTQSBpbXBsZW1lbnRhdGlvblxuXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vanNibi5qcycpLFxuICB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpLFxuICByYW5kb20gPSByZXF1aXJlKCcuLi9yYW5kb20uanMnKTtcblxuZnVuY3Rpb24gU2VjdXJlUmFuZG9tKCkge1xuICBmdW5jdGlvbiBuZXh0Qnl0ZXMoYnl0ZUFycmF5KSB7XG4gICAgZm9yICh2YXIgbiA9IDA7IG4gPCBieXRlQXJyYXkubGVuZ3RoOyBuKyspIHtcbiAgICAgIGJ5dGVBcnJheVtuXSA9IHJhbmRvbS5nZXRTZWN1cmVSYW5kb21PY3RldCgpO1xuICAgIH1cbiAgfVxuICB0aGlzLm5leHRCeXRlcyA9IG5leHRCeXRlcztcbn1cblxuZnVuY3Rpb24gUlNBKCkge1xuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiB1c2VzIGpzYm4gQmlnIE51bSBsaWJyYXJ5IHRvIGRlY3J5cHQgUlNBXG4gICAqIEBwYXJhbSBtXG4gICAqICAgICAgICAgICAgbWVzc2FnZVxuICAgKiBAcGFyYW0gZFxuICAgKiAgICAgICAgICAgIFJTQSBkIGFzIEJpZ0ludGVnZXJcbiAgICogQHBhcmFtIHBcbiAgICogICAgICAgICAgICBSU0EgcCBhcyBCaWdJbnRlZ2VyXG4gICAqIEBwYXJhbSBxXG4gICAqICAgICAgICAgICAgUlNBIHEgYXMgQmlnSW50ZWdlclxuICAgKiBAcGFyYW0gdVxuICAgKiAgICAgICAgICAgIFJTQSB1IGFzIEJpZ0ludGVnZXJcbiAgICogQHJldHVybiB7QmlnSW50ZWdlcn0gVGhlIGRlY3J5cHRlZCB2YWx1ZSBvZiB0aGUgbWVzc2FnZVxuICAgKi9cbiAgZnVuY3Rpb24gZGVjcnlwdChtLCBkLCBwLCBxLCB1KSB7XG4gICAgdmFyIHhwID0gbS5tb2QocCkubW9kUG93KGQubW9kKHAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKSwgcCk7XG4gICAgdmFyIHhxID0gbS5tb2QocSkubW9kUG93KGQubW9kKHEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKSwgcSk7XG4gICAgdXRpbC5wcmludF9kZWJ1ZyhcInJzYS5qcyBkZWNyeXB0XFxueHBuOlwiICsgdXRpbC5oZXhzdHJkdW1wKHhwLnRvTVBJKCkpICsgXCJcXG54cW46XCIgKyB1dGlsLmhleHN0cmR1bXAoeHEudG9NUEkoKSkpO1xuXG4gICAgdmFyIHQgPSB4cS5zdWJ0cmFjdCh4cCk7XG4gICAgaWYgKHRbMF0gPT0gMCkge1xuICAgICAgdCA9IHhwLnN1YnRyYWN0KHhxKTtcbiAgICAgIHQgPSB0Lm11bHRpcGx5KHUpLm1vZChxKTtcbiAgICAgIHQgPSBxLnN1YnRyYWN0KHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0ID0gdC5tdWx0aXBseSh1KS5tb2QocSk7XG4gICAgfVxuICAgIHJldHVybiB0Lm11bHRpcGx5KHApLmFkZCh4cCk7XG4gIH1cblxuICAvKipcbiAgICogZW5jcnlwdCBtZXNzYWdlXG4gICAqIEBwYXJhbSBtIG1lc3NhZ2UgYXMgQmlnSW50ZWdlclxuICAgKiBAcGFyYW0gZSBwdWJsaWMgTVBJIHBhcnQgYXMgQmlnSW50ZWdlclxuICAgKiBAcGFyYW0gbiBwdWJsaWMgTVBJIHBhcnQgYXMgQmlnSW50ZWdlclxuICAgKiBAcmV0dXJuIEJpZ0ludGVnZXJcbiAgICovXG4gIGZ1bmN0aW9uIGVuY3J5cHQobSwgZSwgbikge1xuICAgIHJldHVybiBtLm1vZFBvd0ludChlLCBuKTtcbiAgfVxuXG4gIC8qIFNpZ24gYW5kIFZlcmlmeSAqL1xuICBmdW5jdGlvbiBzaWduKG0sIGQsIG4pIHtcbiAgICByZXR1cm4gbS5tb2RQb3coZCwgbik7XG4gIH1cblxuICBmdW5jdGlvbiB2ZXJpZnkoeCwgZSwgbikge1xuICAgIHJldHVybiB4Lm1vZFBvd0ludChlLCBuKTtcbiAgfVxuXG4gIC8vIFwiZW1wdHlcIiBSU0Ega2V5IGNvbnN0cnVjdG9yXG5cbiAgZnVuY3Rpb24ga2V5T2JqZWN0KCkge1xuICAgIHRoaXMubiA9IG51bGw7XG4gICAgdGhpcy5lID0gMDtcbiAgICB0aGlzLmVlID0gbnVsbDtcbiAgICB0aGlzLmQgPSBudWxsO1xuICAgIHRoaXMucCA9IG51bGw7XG4gICAgdGhpcy5xID0gbnVsbDtcbiAgICB0aGlzLmRtcDEgPSBudWxsO1xuICAgIHRoaXMuZG1xMSA9IG51bGw7XG4gICAgdGhpcy51ID0gbnVsbDtcbiAgfVxuXG4gIC8vIEdlbmVyYXRlIGEgbmV3IHJhbmRvbSBwcml2YXRlIGtleSBCIGJpdHMgbG9uZywgdXNpbmcgcHVibGljIGV4cHQgRVxuXG4gIGZ1bmN0aW9uIGdlbmVyYXRlKEIsIEUpIHtcbiAgICB2YXIga2V5ID0gbmV3IGtleU9iamVjdCgpO1xuICAgIHZhciBybmcgPSBuZXcgU2VjdXJlUmFuZG9tKCk7XG4gICAgdmFyIHFzID0gQiA+PiAxO1xuICAgIGtleS5lID0gcGFyc2VJbnQoRSwgMTYpO1xuICAgIGtleS5lZSA9IG5ldyBCaWdJbnRlZ2VyKEUsIDE2KTtcbiAgICBmb3IgKDs7KSB7XG4gICAgICBmb3IgKDs7KSB7XG4gICAgICAgIGtleS5wID0gbmV3IEJpZ0ludGVnZXIoQiAtIHFzLCAxLCBybmcpO1xuICAgICAgICBpZiAoa2V5LnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChrZXkuZWUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCAmJiBrZXkucC5pc1Byb2JhYmxlUHJpbWUoMTApKVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZm9yICg7Oykge1xuICAgICAgICBrZXkucSA9IG5ldyBCaWdJbnRlZ2VyKHFzLCAxLCBybmcpO1xuICAgICAgICBpZiAoa2V5LnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChrZXkuZWUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCAmJiBrZXkucS5pc1Byb2JhYmxlUHJpbWUoMTApKVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKGtleS5wLmNvbXBhcmVUbyhrZXkucSkgPD0gMCkge1xuICAgICAgICB2YXIgdCA9IGtleS5wO1xuICAgICAgICBrZXkucCA9IGtleS5xO1xuICAgICAgICBrZXkucSA9IHQ7XG4gICAgICB9XG4gICAgICB2YXIgcDEgPSBrZXkucC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgICB2YXIgcTEgPSBrZXkucS5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgICB2YXIgcGhpID0gcDEubXVsdGlwbHkocTEpO1xuICAgICAgaWYgKHBoaS5nY2Qoa2V5LmVlKS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpID09IDApIHtcbiAgICAgICAga2V5Lm4gPSBrZXkucC5tdWx0aXBseShrZXkucSk7XG4gICAgICAgIGtleS5kID0ga2V5LmVlLm1vZEludmVyc2UocGhpKTtcbiAgICAgICAga2V5LmRtcDEgPSBrZXkuZC5tb2QocDEpO1xuICAgICAgICBrZXkuZG1xMSA9IGtleS5kLm1vZChxMSk7XG4gICAgICAgIGtleS51ID0ga2V5LnAubW9kSW52ZXJzZShrZXkucSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ga2V5O1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZW5jcnlwdDtcbiAgdGhpcy5kZWNyeXB0ID0gZGVjcnlwdDtcbiAgdGhpcy52ZXJpZnkgPSB2ZXJpZnk7XG4gIHRoaXMuc2lnbiA9IHNpZ247XG4gIHRoaXMuZ2VuZXJhdGUgPSBnZW5lcmF0ZTtcbiAgdGhpcy5rZXlPYmplY3QgPSBrZXlPYmplY3Q7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUlNBO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0EgXG5cbi8vIFRoZSBHUEc0QnJvd3NlcnMgY3J5cHRvIGludGVyZmFjZVxuXG52YXIgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgLyoqXG4gICAqIFJldHJpZXZlIHNlY3VyZSByYW5kb20gYnl0ZSBzdHJpbmcgb2YgdGhlIHNwZWNpZmllZCBsZW5ndGhcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIGluIGJ5dGVzIHRvIGdlbmVyYXRlXG4gICAqIEByZXR1cm4ge1N0cmluZ30gUmFuZG9tIGJ5dGUgc3RyaW5nXG4gICAqL1xuICBnZXRSYW5kb21CeXRlczogZnVuY3Rpb24obGVuZ3RoKSB7XG4gICAgdmFyIHJlc3VsdCA9ICcnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZ2V0U2VjdXJlUmFuZG9tT2N0ZXQoKSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHBzZXVkby1yYW5kb20gbnVtYmVyIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2VcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBmcm9tIE1pbiBvZiB0aGUgcmFuZG9tIG51bWJlclxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRvIE1heCBvZiB0aGUgcmFuZG9tIG51bWJlciAobWF4IDMyYml0KVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBIHBzZXVkbyByYW5kb20gbnVtYmVyXG4gICAqL1xuICBnZXRQc2V1ZG9SYW5kb206IGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqICh0byAtIGZyb20pKSArIGZyb207XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHNlY3VyZSByYW5kb20gbnVtYmVyIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2VcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBmcm9tIE1pbiBvZiB0aGUgcmFuZG9tIG51bWJlclxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRvIE1heCBvZiB0aGUgcmFuZG9tIG51bWJlciAobWF4IDMyYml0KVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBIHNlY3VyZSByYW5kb20gbnVtYmVyXG4gICAqL1xuICBnZXRTZWN1cmVSYW5kb206IGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBVaW50MzJBcnJheSgxKTtcbiAgICB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpO1xuICAgIHZhciBiaXRzID0gKCh0byAtIGZyb20pKS50b1N0cmluZygyKS5sZW5ndGg7XG4gICAgd2hpbGUgKChidWZbMF0gJiAoTWF0aC5wb3coMiwgYml0cykgLSAxKSkgPiAodG8gLSBmcm9tKSlcbiAgICAgIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGJ1Zik7XG4gICAgcmV0dXJuIGZyb20gKyAoTWF0aC5hYnMoYnVmWzBdICYgKE1hdGgucG93KDIsIGJpdHMpIC0gMSkpKTtcbiAgfSxcblxuICBnZXRTZWN1cmVSYW5kb21PY3RldDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBVaW50MzJBcnJheSgxKTtcbiAgICB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpO1xuICAgIHJldHVybiBidWZbMF0gJiAweEZGO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBzZWN1cmUgcmFuZG9tIGJpZyBpbnRlZ2VyIG9mIGJpdHMgbGVuZ3RoXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYml0cyBCaXQgbGVuZ3RoIG9mIHRoZSBNUEkgdG8gY3JlYXRlXG4gICAqIEByZXR1cm4ge0JpZ0ludGVnZXJ9IFJlc3VsdGluZyBiaWcgaW50ZWdlclxuICAgKi9cbiAgZ2V0UmFuZG9tQmlnSW50ZWdlcjogZnVuY3Rpb24oYml0cykge1xuICAgIGlmIChiaXRzIDwgMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHZhciBudW1CeXRlcyA9IE1hdGguZmxvb3IoKGJpdHMgKyA3KSAvIDgpO1xuXG4gICAgdmFyIHJhbmRvbUJpdHMgPSB0aGlzLmdldFJhbmRvbUJ5dGVzKG51bUJ5dGVzKTtcbiAgICBpZiAoYml0cyAlIDggPiAwKSB7XG5cbiAgICAgIHJhbmRvbUJpdHMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuICAgICAgKE1hdGgucG93KDIsIGJpdHMgJSA4KSAtIDEpICZcbiAgICAgICAgcmFuZG9tQml0cy5jaGFyQ29kZUF0KDApKSArXG4gICAgICAgIHJhbmRvbUJpdHMuc3Vic3RyaW5nKDEpO1xuICAgIH1cbiAgICB2YXIgbXBpID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgbXBpLmZyb21CeXRlcyhyYW5kb21CaXRzKTtcbiAgICByZXR1cm4gbXBpLnRvQmlnSW50ZWdlcigpO1xuICB9LFxuXG4gIGdldFJhbmRvbUJpZ0ludGVnZXJJblJhbmdlOiBmdW5jdGlvbihtaW4sIG1heCkge1xuICAgIGlmIChtYXguY29tcGFyZVRvKG1pbikgPD0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciByYW5nZSA9IG1heC5zdWJ0cmFjdChtaW4pO1xuICAgIHZhciByID0gdGhpcy5nZXRSYW5kb21CaWdJbnRlZ2VyKHJhbmdlLmJpdExlbmd0aCgpKTtcbiAgICB3aGlsZSAociA+IHJhbmdlKSB7XG4gICAgICByID0gdGhpcy5nZXRSYW5kb21CaWdJbnRlZ2VyKHJhbmdlLmJpdExlbmd0aCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIG1pbi5hZGQocik7XG4gIH1cblxufTtcbiIsInZhciBwdWJsaWNLZXkgPSByZXF1aXJlKCcuL3B1YmxpY19rZXknKSxcbiAgcGtjczEgPSByZXF1aXJlKCcuL3BrY3MxLmpzJyksXG4gIGhhc2hNb2R1bGUgPSByZXF1aXJlKCcuL2hhc2gnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIC8qKlxuICAgKiBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIHB1YmxpYyBLZXkgYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaGFzaF9hbGdvIEhhc2ggYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBtc2dfTVBJcyBTaWduYXR1cmUgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnNcbiAgICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpW119IHB1YmxpY2tleV9NUElzIFB1YmxpYyBrZXkgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgb24gd2hlcmUgdGhlIHNpZ25hdHVyZSB3YXMgY29tcHV0ZWQgb24uXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgc2lnbmF0dXJlIChzaWdfZGF0YSB3YXMgZXF1YWwgdG8gZGF0YSBvdmVyIGhhc2gpXG4gICAqL1xuICB2ZXJpZnk6IGZ1bmN0aW9uKGFsZ28sIGhhc2hfYWxnbywgbXNnX01QSXMsIHB1YmxpY2tleV9NUElzLCBkYXRhKSB7XG4gICAgdmFyIGNhbGNfaGFzaCA9IGhhc2hNb2R1bGUuZGlnZXN0KGhhc2hfYWxnbywgZGF0YSk7XG5cbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgLy8gUlNBIChFbmNyeXB0IG9yIFNpZ24pIFtIQUNdICBcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gUlNBIEVuY3J5cHQtT25seSBbSEFDXVxuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyBSU0EgU2lnbi1Pbmx5IFtIQUNdXG4gICAgICAgIHZhciByc2EgPSBuZXcgcHVibGljS2V5LnJzYSgpO1xuICAgICAgICB2YXIgbiA9IHB1YmxpY2tleV9NUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgZSA9IHB1YmxpY2tleV9NUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgeCA9IG1zZ19NUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgZG9wdWJsaWMgPSByc2EudmVyaWZ5KHgsIGUsIG4pO1xuICAgICAgICB2YXIgaGFzaCA9IHBrY3MxLmVtc2EuZGVjb2RlKGhhc2hfYWxnbywgZG9wdWJsaWMudG9NUEkoKS5zdWJzdHJpbmcoMikpO1xuICAgICAgICBpZiAoaGFzaCA9PSAtMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUzEgcGFkZGluZyBpbiBtZXNzYWdlIG9yIGtleSBpbmNvcnJlY3QuIEFib3J0aW5nLi4uJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhc2ggPT0gY2FsY19oYXNoO1xuXG4gICAgICBjYXNlIDE2OlxuICAgICAgICAvLyBFbGdhbWFsIChFbmNyeXB0LU9ubHkpIFtFTEdBTUFMXSBbSEFDXVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJzaWduaW5nIHdpdGggRWxnYW1hbCBpcyBub3QgZGVmaW5lZCBpbiB0aGUgT3BlblBHUCBzdGFuZGFyZC5cIik7XG4gICAgICBjYXNlIDE3OlxuICAgICAgICAvLyBEU0EgKERpZ2l0YWwgU2lnbmF0dXJlIEFsZ29yaXRobSkgW0ZJUFMxODZdIFtIQUNdXG4gICAgICAgIHZhciBkc2EgPSBuZXcgcHVibGljS2V5LmRzYSgpO1xuICAgICAgICB2YXIgczEgPSBtc2dfTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIHMyID0gbXNnX01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBwID0gcHVibGlja2V5X01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBxID0gcHVibGlja2V5X01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBnID0gcHVibGlja2V5X01QSXNbMl0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciB5ID0gcHVibGlja2V5X01QSXNbM10udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBtID0gZGF0YTtcbiAgICAgICAgdmFyIGRvcHVibGljID0gZHNhLnZlcmlmeShoYXNoX2FsZ28sIHMxLCBzMiwgbSwgcCwgcSwgZywgeSk7XG4gICAgICAgIHJldHVybiBkb3B1YmxpYy5jb21wYXJlVG8oczEpID09IDA7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2lnbmF0dXJlIGFsZ29yaXRobS4nKTtcbiAgICB9XG5cbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlIGEgc2lnbmF0dXJlIG9uIGRhdGEgdXNpbmcgdGhlIHNwZWNpZmllZCBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBoYXNoX2FsZ28gaGFzaCBBbGdvcml0aG0gdG8gdXNlIChTZWUgUkZDNDg4MCA5LjQpXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBc3ltbWV0cmljIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlIChTZWUgUkZDNDg4MCA5LjEpXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBwdWJsaWNNUElzIFB1YmxpYyBrZXkgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG4gICAqIG9mIHRoZSBwcml2YXRlIGtleSBcbiAgICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpW119IHNlY3JldE1QSXMgUHJpdmF0ZSBrZXkgbXVsdGlwcmVjaXNpb24gXG4gICAqIGludGVnZXJzIHdoaWNoIGlzIHVzZWQgdG8gc2lnbiB0aGUgZGF0YVxuICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGJlIHNpZ25lZFxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3R5cGVfbXBpW119XG4gICAqL1xuICBzaWduOiBmdW5jdGlvbihoYXNoX2FsZ28sIGFsZ28sIGtleUludGVnZXJzLCBkYXRhKSB7XG5cbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgLy8gUlNBIChFbmNyeXB0IG9yIFNpZ24pIFtIQUNdICBcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gUlNBIEVuY3J5cHQtT25seSBbSEFDXVxuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyBSU0EgU2lnbi1Pbmx5IFtIQUNdXG4gICAgICAgIHZhciByc2EgPSBuZXcgcHVibGljS2V5LnJzYSgpO1xuICAgICAgICB2YXIgZCA9IGtleUludGVnZXJzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgbiA9IGtleUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgbSA9IHBrY3MxLmVtc2EuZW5jb2RlKGhhc2hfYWxnbyxcbiAgICAgICAgICBkYXRhLCBrZXlJbnRlZ2Vyc1swXS5ieXRlTGVuZ3RoKCkpO1xuXG4gICAgICAgIHJldHVybiByc2Euc2lnbihtLCBkLCBuKS50b01QSSgpO1xuXG4gICAgICBjYXNlIDE3OlxuICAgICAgICAvLyBEU0EgKERpZ2l0YWwgU2lnbmF0dXJlIEFsZ29yaXRobSkgW0ZJUFMxODZdIFtIQUNdXG4gICAgICAgIHZhciBkc2EgPSBuZXcgcHVibGljS2V5LmRzYSgpO1xuXG4gICAgICAgIHZhciBwID0ga2V5SW50ZWdlcnNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBxID0ga2V5SW50ZWdlcnNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBnID0ga2V5SW50ZWdlcnNbMl0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciB5ID0ga2V5SW50ZWdlcnNbM10udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciB4ID0ga2V5SW50ZWdlcnNbNF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBtID0gZGF0YTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGRzYS5zaWduKGhhc2hfYWxnbywgbSwgZywgcCwgcSwgeCk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdFswXS50b1N0cmluZygpICsgcmVzdWx0WzFdLnRvU3RyaW5nKCk7XG4gICAgICBjYXNlIDE2OlxuICAgICAgICAvLyBFbGdhbWFsIChFbmNyeXB0LU9ubHkpIFtFTEdBTUFMXSBbSEFDXVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NpZ25pbmcgd2l0aCBFbGdhbWFsIGlzIG5vdCBkZWZpbmVkIGluIHRoZSBPcGVuUEdQIHN0YW5kYXJkLicpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZSBhbGdvcml0aG0uJyk7XG4gICAgfVxuICB9XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy9cbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy9cbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnLi9iYXNlNjQuanMnKTtcbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyk7XG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG5cbi8qKlxuICogRmluZHMgb3V0IHdoaWNoIEFzY2lpIEFybW9yaW5nIHR5cGUgaXMgdXNlZC4gVGhpcyBpcyBhbiBpbnRlcm5hbCBmdW5jdGlvblxuICogQHBhcmFtIHtTdHJpbmd9IHRleHQgW1N0cmluZ10gYXNjaWkgYXJtb3JlZCB0ZXh0XG4gKiBAcmV0dXJucyB7SW50ZWdlcn0gMCA9IE1FU1NBR0UgUEFSVCBuIG9mIG1cbiAqICAgICAgICAgMSA9IE1FU1NBR0UgUEFSVCBuXG4gKiAgICAgICAgIDIgPSBTSUdORUQgTUVTU0FHRVxuICogICAgICAgICAzID0gUEdQIE1FU1NBR0VcbiAqICAgICAgICAgNCA9IFBVQkxJQyBLRVkgQkxPQ0tcbiAqICAgICAgICAgNSA9IFBSSVZBVEUgS0VZIEJMT0NLXG4gKiAgICAgICAgIG51bGwgPSB1bmtub3duXG4gKi9cbmZ1bmN0aW9uIGdldF90eXBlKHRleHQpIHtcbiAgdmFyIHJlSGVhZGVyID0gL14tLS0tLShbXi1dKyktLS0tLSRcXG4vbTtcblxuICB2YXIgaGVhZGVyID0gdGV4dC5tYXRjaChyZUhlYWRlcik7XG5cbiAgLy8gQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgWC9ZXG4gIC8vIFVzZWQgZm9yIG11bHRpLXBhcnQgbWVzc2FnZXMsIHdoZXJlIHRoZSBhcm1vciBpcyBzcGxpdCBhbW9uZ3N0IFlcbiAgLy8gcGFydHMsIGFuZCB0aGlzIGlzIHRoZSBYdGggcGFydCBvdXQgb2YgWS5cbiAgaWYgKGhlYWRlclsxXS5tYXRjaCgvQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgXFxkK1xcL1xcZCsvKSkge1xuICAgIHJldHVybiBlbnVtcy5hcm1vci5tdWx0aXBhcnRfc2VjdGlvbjtcbiAgfSBlbHNlXG4gIC8vIEJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFhcbiAgLy8gVXNlZCBmb3IgbXVsdGktcGFydCBtZXNzYWdlcywgd2hlcmUgdGhpcyBpcyB0aGUgWHRoIHBhcnQgb2YgYW5cbiAgLy8gdW5zcGVjaWZpZWQgbnVtYmVyIG9mIHBhcnRzLiBSZXF1aXJlcyB0aGUgTUVTU0FHRS1JRCBBcm1vclxuICAvLyBIZWFkZXIgdG8gYmUgdXNlZC5cbiAgaWYgKGhlYWRlclsxXS5tYXRjaCgvQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgXFxkKy8pKSB7XG4gICAgcmV0dXJuIGVudW1zLmFybW9yLm11bHRpcGFydF9sYXN0O1xuXG4gIH0gZWxzZVxuICAvLyBCRUdJTiBQR1AgU0lHTkFUVVJFXG4gIC8vIFVzZWQgZm9yIGRldGFjaGVkIHNpZ25hdHVyZXMsIE9wZW5QR1AvTUlNRSBzaWduYXR1cmVzLCBhbmRcbiAgLy8gY2xlYXJ0ZXh0IHNpZ25hdHVyZXMuIE5vdGUgdGhhdCBQR1AgMi54IHVzZXMgQkVHSU4gUEdQIE1FU1NBR0VcbiAgLy8gZm9yIGRldGFjaGVkIHNpZ25hdHVyZXMuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBTSUdORUQgTUVTU0FHRS8pKSB7XG4gICAgcmV0dXJuIGVudW1zLmFybW9yLnNpZ25lZDtcblxuICB9IGVsc2VcbiAgLy8gQkVHSU4gUEdQIE1FU1NBR0VcbiAgLy8gVXNlZCBmb3Igc2lnbmVkLCBlbmNyeXB0ZWQsIG9yIGNvbXByZXNzZWQgZmlsZXMuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBNRVNTQUdFLykpIHtcbiAgICByZXR1cm4gZW51bXMuYXJtb3IubWVzc2FnZTtcblxuICB9IGVsc2VcbiAgLy8gQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0tcbiAgLy8gVXNlZCBmb3IgYXJtb3JpbmcgcHVibGljIGtleXMuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLykpIHtcbiAgICByZXR1cm4gZW51bXMuYXJtb3IucHVibGljX2tleTtcblxuICB9IGVsc2VcbiAgLy8gQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLXG4gIC8vIFVzZWQgZm9yIGFybW9yaW5nIHByaXZhdGUga2V5cy5cbiAgaWYgKGhlYWRlclsxXS5tYXRjaCgvQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLykpIHtcbiAgICByZXR1cm4gZW51bXMuYXJtb3IucHJpdmF0ZV9rZXk7XG4gIH1cbn1cblxuLyoqXG4gKiBBZGQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0byB0aGUgYXJtb3IgdmVyc2lvbiBvZiBhbiBPcGVuUEdQIGJpbmFyeVxuICogcGFja2V0IGJsb2NrLlxuICogQGF1dGhvciAgQWxleFxuICogQHZlcnNpb24gMjAxMS0xMi0xNlxuICogQHJldHVybnMge1N0cmluZ30gVGhlIGhlYWRlciBpbmZvcm1hdGlvblxuICovXG5mdW5jdGlvbiBhcm1vcl9hZGRoZWFkZXIoKSB7XG4gIHZhciByZXN1bHQgPSBcIlwiO1xuICBpZiAoY29uZmlnLnNob3dfdmVyc2lvbikge1xuICAgIHJlc3VsdCArPSBcIlZlcnNpb246IFwiICsgY29uZmlnLnZlcnNpb25zdHJpbmcgKyAnXFxyXFxuJztcbiAgfVxuICBpZiAoY29uZmlnLnNob3dfY29tbWVudCkge1xuICAgIHJlc3VsdCArPSBcIkNvbW1lbnQ6IFwiICsgY29uZmlnLmNvbW1lbnRzdHJpbmcgKyAnXFxyXFxuJztcbiAgfVxuICByZXN1bHQgKz0gJ1xcclxcbic7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuXG4vKipcbiAqIENhbGN1bGF0ZXMgYSBjaGVja3N1bSBvdmVyIHRoZSBnaXZlbiBkYXRhIGFuZCByZXR1cm5zIGl0IGJhc2U2NCBlbmNvZGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGNyZWF0ZSBhIENSQy0yNCBjaGVja3N1bSBmb3JcbiAqIEByZXR1cm4ge1N0cmluZ30gQmFzZTY0IGVuY29kZWQgY2hlY2tzdW1cbiAqL1xuZnVuY3Rpb24gZ2V0Q2hlY2tTdW0oZGF0YSkge1xuICB2YXIgYyA9IGNyZWF0ZWNyYzI0KGRhdGEpO1xuICB2YXIgc3RyID0gXCJcIiArIFN0cmluZy5mcm9tQ2hhckNvZGUoYyA+PiAxNikgK1xuICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoKGMgPj4gOCkgJiAweEZGKSArXG4gICAgU3RyaW5nLmZyb21DaGFyQ29kZShjICYgMHhGRik7XG4gIHJldHVybiBiYXNlNjQuZW5jb2RlKHN0cik7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgY2hlY2tzdW0gb3ZlciB0aGUgZ2l2ZW4gZGF0YSBhbmQgY29tcGFyZXMgaXQgd2l0aCB0aGVcbiAqIGdpdmVuIGJhc2U2NCBlbmNvZGVkIGNoZWNrc3VtXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGNyZWF0ZSBhIENSQy0yNCBjaGVja3N1bSBmb3JcbiAqIEBwYXJhbSB7U3RyaW5nfSBjaGVja3N1bSBCYXNlNjQgZW5jb2RlZCBjaGVja3N1bVxuICogQHJldHVybiB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hlY2tzdW0gaXMgY29ycmVjdDsgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIHZlcmlmeUNoZWNrU3VtKGRhdGEsIGNoZWNrc3VtKSB7XG4gIHZhciBjID0gZ2V0Q2hlY2tTdW0oZGF0YSk7XG4gIHZhciBkID0gY2hlY2tzdW07XG4gIHJldHVybiBjWzBdID09IGRbMF0gJiYgY1sxXSA9PSBkWzFdICYmIGNbMl0gPT0gZFsyXTtcbn1cbi8qKlxuICogSW50ZXJuYWwgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIGEgQ1JDLTI0IGNoZWNrc3VtIG92ZXIgYSBnaXZlbiBzdHJpbmcgKGRhdGEpXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGNyZWF0ZSBhIENSQy0yNCBjaGVja3N1bSBmb3JcbiAqIEByZXR1cm4ge0ludGVnZXJ9IFRoZSBDUkMtMjQgY2hlY2tzdW0gYXMgbnVtYmVyXG4gKi9cbnZhciBjcmNfdGFibGUgPSBbXG4gICAgMHgwMDAwMDAwMCwgMHgwMDg2NGNmYiwgMHgwMThhZDUwZCwgMHgwMTBjOTlmNiwgMHgwMzkzZTZlMSwgMHgwMzE1YWExYSwgMHgwMjE5MzNlYywgMHgwMjlmN2YxNywgMHgwN2ExODEzOSxcbiAgICAweDA3MjdjZGMyLCAweDA2MmI1NDM0LCAweDA2YWQxOGNmLCAweDA0MzI2N2Q4LCAweDA0YjQyYjIzLCAweDA1YjhiMmQ1LCAweDA1M2VmZTJlLCAweDBmYzU0ZTg5LCAweDBmNDMwMjcyLFxuICAgIDB4MGU0ZjliODQsIDB4MGVjOWQ3N2YsIDB4MGM1NmE4NjgsIDB4MGNkMGU0OTMsIDB4MGRkYzdkNjUsIDB4MGQ1YTMxOWUsIDB4MDg2NGNmYjAsIDB4MDhlMjgzNGIsIDB4MDllZTFhYmQsXG4gICAgMHgwOTY4NTY0NiwgMHgwYmY3Mjk1MSwgMHgwYjcxNjVhYSwgMHgwYTdkZmM1YywgMHgwYWZiYjBhNywgMHgxZjBjZDFlOSwgMHgxZjhhOWQxMiwgMHgxZTg2MDRlNCwgMHgxZTAwNDgxZixcbiAgICAweDFjOWYzNzA4LCAweDFjMTk3YmYzLCAweDFkMTVlMjA1LCAweDFkOTNhZWZlLCAweDE4YWQ1MGQwLCAweDE4MmIxYzJiLCAweDE5Mjc4NWRkLCAweDE5YTFjOTI2LCAweDFiM2ViNjMxLFxuICAgIDB4MWJiOGZhY2EsIDB4MWFiNDYzM2MsIDB4MWEzMjJmYzcsIDB4MTBjOTlmNjAsIDB4MTA0ZmQzOWIsIDB4MTE0MzRhNmQsIDB4MTFjNTA2OTYsIDB4MTM1YTc5ODEsIDB4MTNkYzM1N2EsXG4gICAgMHgxMmQwYWM4YywgMHgxMjU2ZTA3NywgMHgxNzY4MWU1OSwgMHgxN2VlNTJhMiwgMHgxNmUyY2I1NCwgMHgxNjY0ODdhZiwgMHgxNGZiZjhiOCwgMHgxNDdkYjQ0MywgMHgxNTcxMmRiNSxcbiAgICAweDE1Zjc2MTRlLCAweDNlMTlhM2QyLCAweDNlOWZlZjI5LCAweDNmOTM3NmRmLCAweDNmMTUzYTI0LCAweDNkOGE0NTMzLCAweDNkMGMwOWM4LCAweDNjMDA5MDNlLCAweDNjODZkY2M1LFxuICAgIDB4MzliODIyZWIsIDB4MzkzZTZlMTAsIDB4MzgzMmY3ZTYsIDB4MzhiNGJiMWQsIDB4M2EyYmM0MGEsIDB4M2FhZDg4ZjEsIDB4M2JhMTExMDcsIDB4M2IyNzVkZmMsIDB4MzFkY2VkNWIsXG4gICAgMHgzMTVhYTFhMCxcbiAgICAweDMwNTYzODU2LCAweDMwZDA3NGFkLCAweDMyNGYwYmJhLCAweDMyYzk0NzQxLCAweDMzYzVkZWI3LCAweDMzNDM5MjRjLCAweDM2N2Q2YzYyLCAweDM2ZmIyMDk5LCAweDM3ZjdiOTZmLFxuICAgIDB4Mzc3MWY1OTQsIDB4MzVlZThhODMsIDB4MzU2OGM2NzgsIDB4MzQ2NDVmOGUsIDB4MzRlMjEzNzUsIDB4MjExNTcyM2IsIDB4MjE5MzNlYzAsIDB4MjA5ZmE3MzYsIDB4MjAxOWViY2QsXG4gICAgMHgyMjg2OTRkYSwgMHgyMjAwZDgyMSwgMHgyMzBjNDFkNywgMHgyMzhhMGQyYywgMHgyNmI0ZjMwMiwgMHgyNjMyYmZmOSwgMHgyNzNlMjYwZiwgMHgyN2I4NmFmNCwgMHgyNTI3MTVlMyxcbiAgICAweDI1YTE1OTE4LCAweDI0YWRjMGVlLCAweDI0MmI4YzE1LCAweDJlZDAzY2IyLCAweDJlNTY3MDQ5LCAweDJmNWFlOWJmLCAweDJmZGNhNTQ0LCAweDJkNDNkYTUzLCAweDJkYzU5NmE4LFxuICAgIDB4MmNjOTBmNWUsIDB4MmM0ZjQzYTUsIDB4Mjk3MWJkOGIsIDB4MjlmN2YxNzAsIDB4MjhmYjY4ODYsIDB4Mjg3ZDI0N2QsIDB4MmFlMjViNmEsIDB4MmE2NDE3OTEsIDB4MmI2ODhlNjcsXG4gICAgMHgyYmVlYzI5YywgMHg3YzMzNDdhNCwgMHg3Y2I1MGI1ZiwgMHg3ZGI5OTJhOSwgMHg3ZDNmZGU1MiwgMHg3ZmEwYTE0NSwgMHg3ZjI2ZWRiZSwgMHg3ZTJhNzQ0OCwgMHg3ZWFjMzhiMyxcbiAgICAweDdiOTJjNjlkLCAweDdiMTQ4YTY2LCAweDdhMTgxMzkwLCAweDdhOWU1ZjZiLCAweDc4MDEyMDdjLCAweDc4ODc2Yzg3LCAweDc5OGJmNTcxLCAweDc5MGRiOThhLCAweDczZjYwOTJkLFxuICAgIDB4NzM3MDQ1ZDYsIDB4NzI3Y2RjMjAsIDB4NzJmYTkwZGIsIDB4NzA2NWVmY2MsIDB4NzBlM2EzMzcsIDB4NzFlZjNhYzEsIDB4NzE2OTc2M2EsIDB4NzQ1Nzg4MTQsIDB4NzRkMWM0ZWYsXG4gICAgMHg3NWRkNWQxOSwgMHg3NTViMTFlMiwgMHg3N2M0NmVmNSwgMHg3NzQyMjIwZSwgMHg3NjRlYmJmOCwgMHg3NmM4ZjcwMywgMHg2MzNmOTY0ZCwgMHg2M2I5ZGFiNiwgMHg2MmI1NDM0MCxcbiAgICAweDYyMzMwZmJiLFxuICAgIDB4NjBhYzcwYWMsIDB4NjAyYTNjNTcsIDB4NjEyNmE1YTEsIDB4NjFhMGU5NWEsIDB4NjQ5ZTE3NzQsIDB4NjQxODViOGYsIDB4NjUxNGMyNzksIDB4NjU5MjhlODIsIDB4NjcwZGYxOTUsXG4gICAgMHg2NzhiYmQ2ZSwgMHg2Njg3MjQ5OCwgMHg2NjAxNjg2MywgMHg2Y2ZhZDhjNCwgMHg2YzdjOTQzZiwgMHg2ZDcwMGRjOSwgMHg2ZGY2NDEzMiwgMHg2ZjY5M2UyNSwgMHg2ZmVmNzJkZSxcbiAgICAweDZlZTNlYjI4LCAweDZlNjVhN2QzLCAweDZiNWI1OWZkLCAweDZiZGQxNTA2LCAweDZhZDE4Y2YwLCAweDZhNTdjMDBiLCAweDY4YzhiZjFjLCAweDY4NGVmM2U3LCAweDY5NDI2YTExLFxuICAgIDB4NjljNDI2ZWEsIDB4NDIyYWU0NzYsIDB4NDJhY2E4OGQsIDB4NDNhMDMxN2IsIDB4NDMyNjdkODAsIDB4NDFiOTAyOTcsIDB4NDEzZjRlNmMsIDB4NDAzM2Q3OWEsIDB4NDBiNTliNjEsXG4gICAgMHg0NThiNjU0ZiwgMHg0NTBkMjliNCwgMHg0NDAxYjA0MiwgMHg0NDg3ZmNiOSwgMHg0NjE4ODNhZSwgMHg0NjllY2Y1NSwgMHg0NzkyNTZhMywgMHg0NzE0MWE1OCwgMHg0ZGVmYWFmZixcbiAgICAweDRkNjllNjA0LCAweDRjNjU3ZmYyLCAweDRjZTMzMzA5LCAweDRlN2M0YzFlLCAweDRlZmEwMGU1LCAweDRmZjY5OTEzLCAweDRmNzBkNWU4LCAweDRhNGUyYmM2LCAweDRhYzg2NzNkLFxuICAgIDB4NGJjNGZlY2IsIDB4NGI0MmIyMzAsIDB4NDlkZGNkMjcsIDB4NDk1YjgxZGMsIDB4NDg1NzE4MmEsIDB4NDhkMTU0ZDEsIDB4NWQyNjM1OWYsIDB4NWRhMDc5NjQsIDB4NWNhY2UwOTIsXG4gICAgMHg1YzJhYWM2OSwgMHg1ZWI1ZDM3ZSwgMHg1ZTMzOWY4NSwgMHg1ZjNmMDY3MywgMHg1ZmI5NGE4OCwgMHg1YTg3YjRhNiwgMHg1YTAxZjg1ZCwgMHg1YjBkNjFhYiwgMHg1YjhiMmQ1MCxcbiAgICAweDU5MTQ1MjQ3LCAweDU5OTIxZWJjLCAweDU4OWU4NzRhLCAweDU4MThjYmIxLCAweDUyZTM3YjE2LCAweDUyNjUzN2VkLCAweDUzNjlhZTFiLCAweDUzZWZlMmUwLCAweDUxNzA5ZGY3LFxuICAgIDB4NTFmNmQxMGMsXG4gICAgMHg1MGZhNDhmYSwgMHg1MDdjMDQwMSwgMHg1NTQyZmEyZiwgMHg1NWM0YjZkNCwgMHg1NGM4MmYyMiwgMHg1NDRlNjNkOSwgMHg1NmQxMWNjZSwgMHg1NjU3NTAzNSwgMHg1NzViYzljMyxcbiAgICAweDU3ZGQ4NTM4XG5dO1xuXG5mdW5jdGlvbiBjcmVhdGVjcmMyNChpbnB1dCkge1xuICB2YXIgY3JjID0gMHhCNzA0Q0U7XG4gIHZhciBpbmRleCA9IDA7XG5cbiAgd2hpbGUgKChpbnB1dC5sZW5ndGggLSBpbmRleCkgPiAxNikge1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMSkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMikpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMykpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgNCkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgNSkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgNikpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgNykpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgOCkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgOSkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMTApKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDExKSkgJiAweGZmXTtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXggKyAxMikpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMTMpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDE0KSkgJiAweGZmXTtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXggKyAxNSkpICYgMHhmZl07XG4gICAgaW5kZXggKz0gMTY7XG4gIH1cblxuICBmb3IgKHZhciBqID0gaW5kZXg7IGogPCBpbnB1dC5sZW5ndGg7IGorKykge1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCsrKSkgJiAweGZmXTtcbiAgfVxuICByZXR1cm4gY3JjICYgMHhmZmZmZmY7XG59XG5cbi8qKlxuICogU3BsaXRzIGEgbWVzc2FnZSBpbnRvIHR3byBwYXJ0cywgdGhlIGhlYWRlcnMgYW5kIHRoZSBib2R5LiBUaGlzIGlzIGFuIGludGVybmFsIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1N0cmluZ30gdGV4dCBPcGVuUEdQIGFybW9yZWQgbWVzc2FnZSBwYXJ0XG4gKiBAcmV0dXJucyB7KEJvb2xlYW58T2JqZWN0KX0gRWl0aGVyIGZhbHNlIGluIGNhc2Ugb2YgYW4gZXJyb3JcbiAqIG9yIGFuIG9iamVjdCB3aXRoIGF0dHJpYnV0ZSBcImhlYWRlcnNcIiBjb250YWluaW5nIHRoZSBoZWFkZXJzIGFuZFxuICogYW5kIGFuIGF0dHJpYnV0ZSBcImJvZHlcIiBjb250YWluaW5nIHRoZSBib2R5LlxuICovXG5mdW5jdGlvbiBzcGxpdF9oZWFkZXJzKHRleHQpIHtcbiAgdmFyIHJlRW1wdHlMaW5lID0gL15bXFx0IF0qXFxuL207XG4gIHZhciBoZWFkZXJzID0gXCJcIjtcbiAgdmFyIGJvZHkgPSB0ZXh0O1xuXG4gIHZhciBtYXRjaFJlc3VsdCA9IHJlRW1wdHlMaW5lLmV4ZWModGV4dCk7XG5cbiAgaWYgKG1hdGNoUmVzdWx0ICE9IG51bGwpIHtcbiAgICBoZWFkZXJzID0gdGV4dC5zbGljZSgwLCBtYXRjaFJlc3VsdC5pbmRleCk7XG4gICAgYm9keSA9IHRleHQuc2xpY2UobWF0Y2hSZXN1bHQuaW5kZXggKyBtYXRjaFJlc3VsdFswXS5sZW5ndGgpO1xuICB9XG5cbiAgcmV0dXJuIHsgaGVhZGVyczogaGVhZGVycywgYm9keTogYm9keSB9O1xufVxuXG4vKipcbiAqIFNwbGl0cyBhIG1lc3NhZ2UgaW50byB0d28gcGFydHMsIHRoZSBib2R5IGFuZCB0aGUgY2hlY2tzdW0uIFRoaXMgaXMgYW4gaW50ZXJuYWwgZnVuY3Rpb25cbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IE9wZW5QR1AgYXJtb3JlZCBtZXNzYWdlIHBhcnRcbiAqIEByZXR1cm5zIHsoQm9vbGVhbnxPYmplY3QpfSBFaXRoZXIgZmFsc2UgaW4gY2FzZSBvZiBhbiBlcnJvclxuICogb3IgYW4gb2JqZWN0IHdpdGggYXR0cmlidXRlIFwiYm9keVwiIGNvbnRhaW5pbmcgdGhlIGJvZHlcbiAqIGFuZCBhbiBhdHRyaWJ1dGUgXCJjaGVja3N1bVwiIGNvbnRhaW5pbmcgdGhlIGNoZWNrc3VtLlxuICovXG5mdW5jdGlvbiBzcGxpdF9jaGVja3N1bSh0ZXh0KSB7XG4gIHZhciByZUNoZWNrc3VtU3RhcnQgPSAvXj0vbTtcbiAgdmFyIGJvZHkgPSB0ZXh0O1xuICB2YXIgY2hlY2tzdW0gPSBcIlwiO1xuXG4gIHZhciBtYXRjaFJlc3VsdCA9IHJlQ2hlY2tzdW1TdGFydC5leGVjKHRleHQpO1xuXG4gIGlmIChtYXRjaFJlc3VsdCAhPSBudWxsKSB7XG4gICAgYm9keSA9IHRleHQuc2xpY2UoMCwgbWF0Y2hSZXN1bHQuaW5kZXgpO1xuICAgIGNoZWNrc3VtID0gdGV4dC5zbGljZShtYXRjaFJlc3VsdC5pbmRleCArIDEpO1xuICB9XG5cbiAgcmV0dXJuIHsgYm9keTogYm9keSwgY2hlY2tzdW06IGNoZWNrc3VtIH07XG59XG5cbi8qKlxuICogRGVBcm1vciBhbiBPcGVuUEdQIGFybW9yZWQgbWVzc2FnZTsgdmVyaWZ5IHRoZSBjaGVja3N1bSBhbmQgcmV0dXJuXG4gKiB0aGUgZW5jb2RlZCBieXRlc1xuICogQHBhcmFtIHtTdHJpbmd9IHRleHQgT3BlblBHUCBhcm1vcmVkIG1lc3NhZ2VcbiAqIEByZXR1cm5zIHsoQm9vbGVhbnxPYmplY3QpfSBFaXRoZXIgZmFsc2UgaW4gY2FzZSBvZiBhbiBlcnJvclxuICogb3IgYW4gb2JqZWN0IHdpdGggYXR0cmlidXRlIFwidGV4dFwiIGNvbnRhaW5pbmcgdGhlIG1lc3NhZ2UgdGV4dFxuICogYW5kIGFuIGF0dHJpYnV0ZSBcImRhdGFcIiBjb250YWluaW5nIHRoZSBieXRlcy5cbiAqL1xuZnVuY3Rpb24gZGVhcm1vcih0ZXh0KSB7XG4gIHZhciByZVNwbGl0ID0gL14tLS0tLVteLV0rLS0tLS0kXFxuL207XG5cbiAgdGV4dCA9IHRleHQucmVwbGFjZSgvXFxyL2csICcnKTtcblxuICB2YXIgdHlwZSA9IGdldF90eXBlKHRleHQpO1xuXG4gIHZhciBzcGxpdHRleHQgPSB0ZXh0LnNwbGl0KHJlU3BsaXQpO1xuXG4gIC8vIElFIGhhcyBhIGJ1ZyBpbiBzcGxpdCB3aXRoIGEgcmUuIElmIHRoZSBwYXR0ZXJuIG1hdGNoZXMgdGhlIGJlZ2lubmluZyBvZiB0aGVcbiAgLy8gc3RyaW5nIGl0IGRvZXNuJ3QgY3JlYXRlIGFuIGVtcHR5IGFycmF5IGVsZW1lbnQgMC4gU28gd2UgbmVlZCB0byBkZXRlY3QgdGhpc1xuICAvLyBzbyB3ZSBrbm93IHRoZSBpbmRleCBvZiB0aGUgZGF0YSB3ZSBhcmUgaW50ZXJlc3RlZCBpbi5cbiAgdmFyIGluZGV4QmFzZSA9IDE7XG5cbiAgdmFyIHJlc3VsdCwgY2hlY2tzdW07XG5cbiAgaWYgKHRleHQuc2VhcmNoKHJlU3BsaXQpICE9IHNwbGl0dGV4dFswXS5sZW5ndGgpIHtcbiAgICBpbmRleEJhc2UgPSAwO1xuICB9XG5cbiAgaWYgKHR5cGUgIT0gMikge1xuICAgIHZhciBtc2cgPSBzcGxpdF9oZWFkZXJzKHNwbGl0dGV4dFtpbmRleEJhc2VdKTtcbiAgICB2YXIgbXNnX3N1bSA9IHNwbGl0X2NoZWNrc3VtKG1zZy5ib2R5KTtcblxuICAgIHJlc3VsdCA9IHtcbiAgICAgIGRhdGE6IGJhc2U2NC5kZWNvZGUobXNnX3N1bS5ib2R5KSxcbiAgICAgIHR5cGU6IHR5cGVcbiAgICB9O1xuXG4gICAgY2hlY2tzdW0gPSBtc2dfc3VtLmNoZWNrc3VtO1xuICB9IGVsc2Uge1xuICAgIC8vIFJldmVyc2UgZGFzaC1lc2NhcGluZyBmb3IgbXNnIGFuZCByZW1vdmUgdHJhaWxpbmcgd2hpdGVzcGFjZSBhdCBlbmQgb2YgbGluZVxuICAgIHZhciBtc2cgPSBzcGxpdF9oZWFkZXJzKHNwbGl0dGV4dFtpbmRleEJhc2VdLnJlcGxhY2UoL14tIC9tZywgJycpLnJlcGxhY2UoL1tcXHQgXStcXG4vZywgXCJcXG5cIikpO1xuICAgIHZhciBzaWcgPSBzcGxpdF9oZWFkZXJzKHNwbGl0dGV4dFtpbmRleEJhc2UgKyAxXS5yZXBsYWNlKC9eLSAvbWcsICcnKSk7XG4gICAgdmFyIHNpZ19zdW0gPSBzcGxpdF9jaGVja3N1bShzaWcuYm9keSk7XG5cbiAgICByZXN1bHQgPSB7XG4gICAgICB0ZXh0OiAgbXNnLmJvZHkucmVwbGFjZSgvXFxuJC8sICcnKS5yZXBsYWNlKC9cXG4vZywgXCJcXHJcXG5cIiksXG4gICAgICBkYXRhOiBiYXNlNjQuZGVjb2RlKHNpZ19zdW0uYm9keSksXG4gICAgICB0eXBlOiB0eXBlXG4gICAgfTtcblxuICAgIGNoZWNrc3VtID0gc2lnX3N1bS5jaGVja3N1bTtcbiAgfVxuXG4gIGlmICghdmVyaWZ5Q2hlY2tTdW0ocmVzdWx0LmRhdGEsIGNoZWNrc3VtKSkge1xuICAgIHV0aWwucHJpbnRfZXJyb3IoXCJBc2NpaSBhcm1vciBpbnRlZ3JpdHkgY2hlY2sgb24gbWVzc2FnZSBmYWlsZWQ6ICdcIlxuICAgICAgKyBjaGVja3N1bVxuICAgICAgKyBcIicgc2hvdWxkIGJlICdcIlxuICAgICAgKyBnZXRDaGVja1N1bShyZXN1bHQpICsgXCInXCIpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG5cblxuLyoqXG4gKiBBcm1vciBhbiBPcGVuUEdQIGJpbmFyeSBwYWNrZXQgYmxvY2tcbiAqIEBwYXJhbSB7SW50ZWdlcn0gbWVzc2FnZXR5cGUgdHlwZSBvZiB0aGUgbWVzc2FnZVxuICogQHBhcmFtIGJvZHlcbiAqIEBwYXJhbSB7SW50ZWdlcn0gcGFydGluZGV4XG4gKiBAcGFyYW0ge0ludGVnZXJ9IHBhcnR0b3RhbFxuICogQHJldHVybnMge1N0cmluZ30gQXJtb3JlZCB0ZXh0XG4gKi9cbmZ1bmN0aW9uIGFybW9yKG1lc3NhZ2V0eXBlLCBib2R5LCBwYXJ0aW5kZXgsIHBhcnR0b3RhbCkge1xuICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgc3dpdGNoIChtZXNzYWdldHlwZSkge1xuICAgIGNhc2UgZW51bXMuYXJtb3IubXVsdGlwYXJ0X3NlY3Rpb246XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFwiICsgcGFydGluZGV4ICsgXCIvXCIgKyBwYXJ0dG90YWwgKyBcIi0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG4gICAgICByZXN1bHQgKz0gYmFzZTY0LmVuY29kZShib2R5KTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbj1cIiArIGdldENoZWNrU3VtKGJvZHkpICsgXCJcXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tRU5EIFBHUCBNRVNTQUdFLCBQQVJUIFwiICsgcGFydGluZGV4ICsgXCIvXCIgKyBwYXJ0dG90YWwgKyBcIi0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgICBjYXNlIGVudW1zLmFybW9yLm11dGxpcGFydF9sYXN0OlxuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1CRUdJTiBQR1AgTUVTU0FHRSwgUEFSVCBcIiArIHBhcnRpbmRleCArIFwiLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhcm1vcl9hZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGJvZHkpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIE1FU1NBR0UsIFBBUlQgXCIgKyBwYXJ0aW5kZXggKyBcIi0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgICBjYXNlIGVudW1zLmFybW9yLnNpZ25lZDpcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbi0tLS0tQkVHSU4gUEdQIFNJR05FRCBNRVNTQUdFLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBcIkhhc2g6IFwiICsgYm9keS5oYXNoICsgXCJcXHJcXG5cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBib2R5LnRleHQucmVwbGFjZSgvXFxuLS9nLCBcIlxcbi0gLVwiKTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbi0tLS0tQkVHSU4gUEdQIFNJR05BVFVSRS0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG4gICAgICByZXN1bHQgKz0gYmFzZTY0LmVuY29kZShib2R5LmRhdGEpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keS5kYXRhKSArIFwiXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUVORCBQR1AgU0lHTkFUVVJFLS0tLS1cXHJcXG5cIjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgZW51bXMuYXJtb3IubWVzc2FnZTpcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IGFybW9yX2FkZGhlYWRlcigpO1xuICAgICAgcmVzdWx0ICs9IGJhc2U2NC5lbmNvZGUoYm9keSk7XG4gICAgICByZXN1bHQgKz0gXCJcXHJcXG49XCIgKyBnZXRDaGVja1N1bShib2R5KSArIFwiXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgICBjYXNlIGVudW1zLmFybW9yLnB1YmxpY19rZXk6XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhcm1vcl9hZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGJvZHkpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcclxcblxcclxcblwiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBlbnVtcy5hcm1vci5wcml2YXRlX2tleTpcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhcm1vcl9hZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGJvZHkpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGVuY29kZTogYXJtb3IsXG4gIGRlY29kZTogZGVhcm1vclxufTtcbiIsIi8qIE9wZW5QR1AgcmFkaXgtNjQvYmFzZTY0IHN0cmluZyBlbmNvZGluZy9kZWNvZGluZ1xuICogQ29weXJpZ2h0IDIwMDUgSGVyYmVydCBIYW5ld2lua2VsLCB3d3cuaGFuZVdJTi5kZVxuICogdmVyc2lvbiAxLjAsIGNoZWNrIHd3dy5oYW5lV0lOLmRlIGZvciB0aGUgbGF0ZXN0IHZlcnNpb25cbiAqXG4gKiBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkIGFzLWlzLCB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4gIFxuICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSBvciBzZWxsIHRoaXMgc29mdHdhcmUsIHdpdGggb3JcbiAqIHdpdGhvdXQgZmVlLCBmb3IgYW55IHB1cnBvc2UgYW5kIGJ5IGFueSBpbmRpdmlkdWFsIG9yIG9yZ2FuaXphdGlvbiwgaXMgaGVyZWJ5XG4gKiBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBhcmFncmFwaCBhcHBlYXIgXG4gKiBpbiBhbGwgY29waWVzLiBEaXN0cmlidXRpb24gYXMgYSBwYXJ0IG9mIGFuIGFwcGxpY2F0aW9uIG9yIGJpbmFyeSBtdXN0XG4gKiBpbmNsdWRlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHNcbiAqIHByb3ZpZGVkIHdpdGggdGhlIGFwcGxpY2F0aW9uIG9yIGRpc3RyaWJ1dGlvbi5cbiAqL1xuXG52YXIgYjY0cyA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuZnVuY3Rpb24gczJyKHQpIHtcbiAgdmFyIGEsIGMsIG47XG4gIHZhciByID0gJycsXG4gICAgbCA9IDAsXG4gICAgcyA9IDA7XG4gIHZhciB0bCA9IHQubGVuZ3RoO1xuXG4gIGZvciAobiA9IDA7IG4gPCB0bDsgbisrKSB7XG4gICAgYyA9IHQuY2hhckNvZGVBdChuKTtcbiAgICBpZiAocyA9PSAwKSB7XG4gICAgICByICs9IGI2NHMuY2hhckF0KChjID4+IDIpICYgNjMpO1xuICAgICAgYSA9IChjICYgMykgPDwgNDtcbiAgICB9IGVsc2UgaWYgKHMgPT0gMSkge1xuICAgICAgciArPSBiNjRzLmNoYXJBdCgoYSB8IChjID4+IDQpICYgMTUpKTtcbiAgICAgIGEgPSAoYyAmIDE1KSA8PCAyO1xuICAgIH0gZWxzZSBpZiAocyA9PSAyKSB7XG4gICAgICByICs9IGI2NHMuY2hhckF0KGEgfCAoKGMgPj4gNikgJiAzKSk7XG4gICAgICBsICs9IDE7XG4gICAgICBpZiAoKGwgJSA2MCkgPT0gMClcbiAgICAgICAgciArPSBcIlxcblwiO1xuICAgICAgciArPSBiNjRzLmNoYXJBdChjICYgNjMpO1xuICAgIH1cbiAgICBsICs9IDE7XG4gICAgaWYgKChsICUgNjApID09IDApXG4gICAgICByICs9IFwiXFxuXCI7XG5cbiAgICBzICs9IDE7XG4gICAgaWYgKHMgPT0gMylcbiAgICAgIHMgPSAwO1xuICB9XG4gIGlmIChzID4gMCkge1xuICAgIHIgKz0gYjY0cy5jaGFyQXQoYSk7XG4gICAgbCArPSAxO1xuICAgIGlmICgobCAlIDYwKSA9PSAwKVxuICAgICAgciArPSBcIlxcblwiO1xuICAgIHIgKz0gJz0nO1xuICAgIGwgKz0gMTtcbiAgfVxuICBpZiAocyA9PSAxKSB7XG4gICAgaWYgKChsICUgNjApID09IDApXG4gICAgICByICs9IFwiXFxuXCI7XG4gICAgciArPSAnPSc7XG4gIH1cblxuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gcjJzKHQpIHtcbiAgdmFyIGMsIG47XG4gIHZhciByID0gJycsXG4gICAgcyA9IDAsXG4gICAgYSA9IDA7XG4gIHZhciB0bCA9IHQubGVuZ3RoO1xuXG4gIGZvciAobiA9IDA7IG4gPCB0bDsgbisrKSB7XG4gICAgYyA9IGI2NHMuaW5kZXhPZih0LmNoYXJBdChuKSk7XG4gICAgaWYgKGMgPj0gMCkge1xuICAgICAgaWYgKHMpXG4gICAgICAgIHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShhIHwgKGMgPj4gKDYgLSBzKSkgJiAyNTUpO1xuICAgICAgcyA9IChzICsgMikgJiA3O1xuICAgICAgYSA9IChjIDw8IHMpICYgMjU1O1xuICAgIH1cbiAgfVxuICByZXR1cm4gcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGVuY29kZTogczJyLFxuICBkZWNvZGU6IHIyc1xufVxuIiwidmFyIGVudW1zID0ge1xuXG4gIC8qKiBBIHN0cmluZyB0byBrZXkgc3BlY2lmaWVyIHR5cGVcbiAgICogQGVudW0ge0ludGVnZXJ9XG4gICAqL1xuICBzMms6IHtcbiAgICBzaW1wbGU6IDAsXG4gICAgc2FsdGVkOiAxLFxuICAgIGl0ZXJhdGVkOiAzLFxuICAgIGdudTogMTAxXG4gIH0sXG5cbiAgLyoqIFJGQzQ4ODAsIHNlY3Rpb24gOS4xIFxuICAgKiBAZW51bSB7U3RyaW5nfVxuICAgKi9cbiAgcHVibGljS2V5OiB7XG4gICAgcnNhX2VuY3J5cHRfc2lnbjogMSxcbiAgICByc2FfZW5jcnlwdDogMixcbiAgICByc2Ffc2lnbjogMyxcbiAgICBlbGdhbWFsOiAxNixcbiAgICBkc2E6IDE3XG4gIH0sXG5cbiAgLyoqIFJGQzQ4ODAsIHNlY3Rpb24gOS4yIFxuICAgKiBAZW51bSB7U3RyaW5nfVxuICAgKi9cbiAgc3ltbWV0cmljOiB7XG4gICAgcGxhaW50ZXh0OiAwLFxuICAgIC8qKiBOb3QgaW1wbGVtZW50ZWQhICovXG4gICAgaWRlYTogMSxcbiAgICB0cmlwbGVkZXM6IDIsXG4gICAgY2FzdDU6IDMsXG4gICAgYmxvd2Zpc2g6IDQsXG4gICAgYWVzMTI4OiA3LFxuICAgIGFlczE5MjogOCxcbiAgICBhZXMyNTY6IDksXG4gICAgdHdvZmlzaDogMTBcbiAgfSxcblxuICAvKiogUkZDNDg4MCwgc2VjdGlvbiA5LjNcbiAgICogQGVudW0ge1N0cmluZ31cbiAgICovXG4gIGNvbXByZXNzaW9uOiB7XG4gICAgdW5jb21wcmVzc2VkOiAwLFxuICAgIC8qKiBSRkMxOTUxICovXG4gICAgemlwOiAxLFxuICAgIC8qKiBSRkMxOTUwICovXG4gICAgemxpYjogMixcbiAgICBiemlwMjogM1xuICB9LFxuXG4gIC8qKiBSRkM0ODgwLCBzZWN0aW9uIDkuNFxuICAgKiBAZW51bSB7U3RyaW5nfVxuICAgKi9cbiAgaGFzaDoge1xuICAgIG1kNTogMSxcbiAgICBzaGExOiAyLFxuICAgIHJpcGVtZDogMyxcbiAgICBzaGEyNTY6IDgsXG4gICAgc2hhMzg0OiA5LFxuICAgIHNoYTUxMjogMTAsXG4gICAgc2hhMjI0OiAxMVxuICB9LFxuXG5cbiAgLyoqXG4gICAqIEBlbnVtIHtTdHJpbmd9XG4gICAqIEEgbGlzdCBvZiBwYWNrZXQgdHlwZXMgYW5kIG51bWVyaWMgdGFncyBhc3NvY2lhdGVkIHdpdGggdGhlbS5cbiAgICovXG4gIHBhY2tldDoge1xuICAgIHB1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5OiAxLFxuICAgIHNpZ25hdHVyZTogMixcbiAgICBzeW1fZW5jcnlwdGVkX3Nlc3Npb25fa2V5OiAzLFxuICAgIG9uZV9wYXNzX3NpZ25hdHVyZTogNCxcbiAgICBzZWNyZXRfa2V5OiA1LFxuICAgIHB1YmxpY19rZXk6IDYsXG4gICAgc2VjcmV0X3N1YmtleTogNyxcbiAgICBjb21wcmVzc2VkOiA4LFxuICAgIHN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkOiA5LFxuICAgIG1hcmtlcjogMTAsXG4gICAgbGl0ZXJhbDogMTEsXG4gICAgdHJ1c3Q6IDEyLFxuICAgIHVzZXJpZDogMTMsXG4gICAgcHVibGljX3N1YmtleTogMTQsXG4gICAgdXNlcl9hdHRyaWJ1dGU6IDE3LFxuICAgIHN5bV9lbmNyeXB0ZWRfaW50ZWdyaXR5X3Byb3RlY3RlZDogMTgsXG4gICAgbW9kaWZpY2F0aW9uX2RldGVjdGlvbl9jb2RlOiAxOVxuICB9LFxuXG5cbiAgLyoqXG4gICAqIERhdGEgdHlwZXMgaW4gdGhlIGxpdGVyYWwgcGFja2V0XG4gICAqIEByZWFkb25seVxuICAgKiBAZW51bSB7U3RyaW5nfVxuICAgKi9cbiAgbGl0ZXJhbDoge1xuICAgIC8qKiBCaW5hcnkgZGF0YSAqL1xuICAgIGJpbmFyeTogJ2InLmNoYXJDb2RlQXQoKSxcbiAgICAvKiogVGV4dCBkYXRhICovXG4gICAgdGV4dDogJ3QnLmNoYXJDb2RlQXQoKSxcbiAgICAvKiogVXRmOCBkYXRhICovXG4gICAgdXRmODogJ3UnLmNoYXJDb2RlQXQoKVxuICB9LFxuXG5cbiAgLyoqIE9uZSBwYXNzIHNpZ25hdHVyZSBwYWNrZXQgdHlwZVxuICAgKiBAZW51bSB7U3RyaW5nfSAqL1xuICBzaWduYXR1cmU6IHtcbiAgICAvKiogMHgwMDogU2lnbmF0dXJlIG9mIGEgYmluYXJ5IGRvY3VtZW50LiAqL1xuICAgIGJpbmFyeTogMCxcbiAgICAvKiogMHgwMTogU2lnbmF0dXJlIG9mIGEgY2Fub25pY2FsIHRleHQgZG9jdW1lbnQuXG4gICAgICogQ2Fub25pY2FseXppbmcgdGhlIGRvY3VtZW50IGJ5IGNvbnZlcnRpbmcgbGluZSBlbmRpbmdzLiAqL1xuICAgIHRleHQ6IDEsXG4gICAgLyoqIDB4MDI6IFN0YW5kYWxvbmUgc2lnbmF0dXJlLlxuICAgICAqIFRoaXMgc2lnbmF0dXJlIGlzIGEgc2lnbmF0dXJlIG9mIG9ubHkgaXRzIG93biBzdWJwYWNrZXQgY29udGVudHMuXG4gICAgICogSXQgaXMgY2FsY3VsYXRlZCBpZGVudGljYWxseSB0byBhIHNpZ25hdHVyZSBvdmVyIGEgemVyby1sZW5naFxuICAgICAqIGJpbmFyeSBkb2N1bWVudC4gIE5vdGUgdGhhdCBpdCBkb2Vzbid0IG1ha2Ugc2Vuc2UgdG8gaGF2ZSBhIFYzXG4gICAgICogc3RhbmRhbG9uZSBzaWduYXR1cmUuICovXG4gICAgc3RhbmRhbG9uZTogMixcbiAgICAvKiogMHgxMDogR2VuZXJpYyBjZXJ0aWZpY2F0aW9uIG9mIGEgVXNlciBJRCBhbmQgUHVibGljLUtleSBwYWNrZXQuXG4gICAgICogVGhlIGlzc3VlciBvZiB0aGlzIGNlcnRpZmljYXRpb24gZG9lcyBub3QgbWFrZSBhbnkgcGFydGljdWxhclxuICAgICAqIGFzc2VydGlvbiBhcyB0byBob3cgd2VsbCB0aGUgY2VydGlmaWVyIGhhcyBjaGVja2VkIHRoYXQgdGhlIG93bmVyXG4gICAgICogb2YgdGhlIGtleSBpcyBpbiBmYWN0IHRoZSBwZXJzb24gZGVzY3JpYmVkIGJ5IHRoZSBVc2VyIElELiAqL1xuICAgIGNlcnRfZ2VuZXJpYzogMTYsXG4gICAgLyoqIDB4MTE6IFBlcnNvbmEgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQgYW5kIFB1YmxpYy1LZXkgcGFja2V0LlxuICAgICAqIFRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIGhhcyBub3QgZG9uZSBhbnkgdmVyaWZpY2F0aW9uIG9mXG4gICAgICogdGhlIGNsYWltIHRoYXQgdGhlIG93bmVyIG9mIHRoaXMga2V5IGlzIHRoZSBVc2VyIElEIHNwZWNpZmllZC4gKi9cbiAgICBjZXJ0X3BlcnNvbmE6IDE3LFxuICAgIC8qKiAweDEyOiBDYXN1YWwgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQgYW5kIFB1YmxpYy1LZXkgcGFja2V0LlxuICAgICAqIFRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIGhhcyBkb25lIHNvbWUgY2FzdWFsXG4gICAgICogdmVyaWZpY2F0aW9uIG9mIHRoZSBjbGFpbSBvZiBpZGVudGl0eS4gKi9cbiAgICBjZXJ0X2Nhc3VhbDogMTgsXG4gICAgLyoqIDB4MTM6IFBvc2l0aXZlIGNlcnRpZmljYXRpb24gb2YgYSBVc2VyIElEIGFuZCBQdWJsaWMtS2V5IHBhY2tldC5cbiAgICAgKiBUaGUgaXNzdWVyIG9mIHRoaXMgY2VydGlmaWNhdGlvbiBoYXMgZG9uZSBzdWJzdGFudGlhbFxuICAgICAqIHZlcmlmaWNhdGlvbiBvZiB0aGUgY2xhaW0gb2YgaWRlbnRpdHkuXG4gICAgICogXG4gICAgICogTW9zdCBPcGVuUEdQIGltcGxlbWVudGF0aW9ucyBtYWtlIHRoZWlyIFwia2V5IHNpZ25hdHVyZXNcIiBhcyAweDEwXG4gICAgICogY2VydGlmaWNhdGlvbnMuICBTb21lIGltcGxlbWVudGF0aW9ucyBjYW4gaXNzdWUgMHgxMS0weDEzXG4gICAgICogY2VydGlmaWNhdGlvbnMsIGJ1dCBmZXcgZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIHRoZSB0eXBlcy4gKi9cbiAgICBjZXJ0X3Bvc2l0aXZlOiAxOSxcbiAgICAvKiogMHgzMDogQ2VydGlmaWNhdGlvbiByZXZvY2F0aW9uIHNpZ25hdHVyZVxuICAgICAqIFRoaXMgc2lnbmF0dXJlIHJldm9rZXMgYW4gZWFybGllciBVc2VyIElEIGNlcnRpZmljYXRpb24gc2lnbmF0dXJlXG4gICAgICogKHNpZ25hdHVyZSBjbGFzcyAweDEwIHRocm91Z2ggMHgxMykgb3IgZGlyZWN0LWtleSBzaWduYXR1cmVcbiAgICAgKiAoMHgxRikuICBJdCBzaG91bGQgYmUgaXNzdWVkIGJ5IHRoZSBzYW1lIGtleSB0aGF0IGlzc3VlZCB0aGVcbiAgICAgKiByZXZva2VkIHNpZ25hdHVyZSBvciBhbiBhdXRob3JpemVkIHJldm9jYXRpb24ga2V5LiAgVGhlIHNpZ25hdHVyZVxuICAgICAqIGlzIGNvbXB1dGVkIG92ZXIgdGhlIHNhbWUgZGF0YSBhcyB0aGUgY2VydGlmaWNhdGUgdGhhdCBpdFxuICAgICAqIHJldm9rZXMsIGFuZCBzaG91bGQgaGF2ZSBhIGxhdGVyIGNyZWF0aW9uIGRhdGUgdGhhbiB0aGF0XG4gICAgICogY2VydGlmaWNhdGUuICovXG4gICAgY2VydF9yZXZvY2F0aW9uOiA0OCxcbiAgICAvKiogMHgxODogU3Via2V5IEJpbmRpbmcgU2lnbmF0dXJlXG4gICAgICogVGhpcyBzaWduYXR1cmUgaXMgYSBzdGF0ZW1lbnQgYnkgdGhlIHRvcC1sZXZlbCBzaWduaW5nIGtleSB0aGF0XG4gICAgICogaW5kaWNhdGVzIHRoYXQgaXQgb3ducyB0aGUgc3Via2V5LiAgVGhpcyBzaWduYXR1cmUgaXMgY2FsY3VsYXRlZFxuICAgICAqIGRpcmVjdGx5IG9uIHRoZSBwcmltYXJ5IGtleSBhbmQgc3Via2V5LCBhbmQgbm90IG9uIGFueSBVc2VyIElEIG9yXG4gICAgICogb3RoZXIgcGFja2V0cy4gIEEgc2lnbmF0dXJlIHRoYXQgYmluZHMgYSBzaWduaW5nIHN1YmtleSBNVVNUIGhhdmVcbiAgICAgKiBhbiBFbWJlZGRlZCBTaWduYXR1cmUgc3VicGFja2V0IGluIHRoaXMgYmluZGluZyBzaWduYXR1cmUgdGhhdFxuICAgICAqIGNvbnRhaW5zIGEgMHgxOSBzaWduYXR1cmUgbWFkZSBieSB0aGUgc2lnbmluZyBzdWJrZXkgb24gdGhlXG4gICAgICogcHJpbWFyeSBrZXkgYW5kIHN1YmtleS4gKi9cbiAgICBzdWJrZXlfYmluZGluZzogMjQsXG4gICAgLyoqIDB4MTk6IFByaW1hcnkgS2V5IEJpbmRpbmcgU2lnbmF0dXJlXG5cdFx0KiBUaGlzIHNpZ25hdHVyZSBpcyBhIHN0YXRlbWVudCBieSBhIHNpZ25pbmcgc3Via2V5LCBpbmRpY2F0aW5nXG5cdFx0KiB0aGF0IGl0IGlzIG93bmVkIGJ5IHRoZSBwcmltYXJ5IGtleSBhbmQgc3Via2V5LiAgVGhpcyBzaWduYXR1cmVcblx0XHQqIGlzIGNhbGN1bGF0ZWQgdGhlIHNhbWUgd2F5IGFzIGEgMHgxOCBzaWduYXR1cmU6IGRpcmVjdGx5IG9uIHRoZVxuXHRcdCogcHJpbWFyeSBrZXkgYW5kIHN1YmtleSwgYW5kIG5vdCBvbiBhbnkgVXNlciBJRCBvciBvdGhlciBwYWNrZXRzLlxuXHRcdFxuXHRcdCogV2hlbiBhIHNpZ25hdHVyZSBpcyBtYWRlIG92ZXIgYSBrZXksIHRoZSBoYXNoIGRhdGEgc3RhcnRzIHdpdGggdGhlXG5cdFx0KiBvY3RldCAweDk5LCBmb2xsb3dlZCBieSBhIHR3by1vY3RldCBsZW5ndGggb2YgdGhlIGtleSwgYW5kIHRoZW4gYm9keVxuXHRcdCogb2YgdGhlIGtleSBwYWNrZXQuICAoTm90ZSB0aGF0IHRoaXMgaXMgYW4gb2xkLXN0eWxlIHBhY2tldCBoZWFkZXIgZm9yXG5cdFx0KiBhIGtleSBwYWNrZXQgd2l0aCB0d28tb2N0ZXQgbGVuZ3RoLikgIEEgc3Via2V5IGJpbmRpbmcgc2lnbmF0dXJlXG5cdFx0KiAodHlwZSAweDE4KSBvciBwcmltYXJ5IGtleSBiaW5kaW5nIHNpZ25hdHVyZSAodHlwZSAweDE5KSB0aGVuIGhhc2hlc1xuXHRcdCogdGhlIHN1YmtleSB1c2luZyB0aGUgc2FtZSBmb3JtYXQgYXMgdGhlIG1haW4ga2V5IChhbHNvIHVzaW5nIDB4OTkgYXNcblx0XHQqIHRoZSBmaXJzdCBvY3RldCkuICovXG4gICAga2V5X2JpbmRpbmc6IDI1LFxuICAgIC8qKiAweDFGOiBTaWduYXR1cmUgZGlyZWN0bHkgb24gYSBrZXlcbiAgICAgKiBUaGlzIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkIGRpcmVjdGx5IG9uIGEga2V5LiAgSXQgYmluZHMgdGhlXG4gICAgICogaW5mb3JtYXRpb24gaW4gdGhlIFNpZ25hdHVyZSBzdWJwYWNrZXRzIHRvIHRoZSBrZXksIGFuZCBpc1xuICAgICAqIGFwcHJvcHJpYXRlIHRvIGJlIHVzZWQgZm9yIHN1YnBhY2tldHMgdGhhdCBwcm92aWRlIGluZm9ybWF0aW9uXG4gICAgICogYWJvdXQgdGhlIGtleSwgc3VjaCBhcyB0aGUgUmV2b2NhdGlvbiBLZXkgc3VicGFja2V0LiAgSXQgaXMgYWxzb1xuICAgICAqIGFwcHJvcHJpYXRlIGZvciBzdGF0ZW1lbnRzIHRoYXQgbm9uLXNlbGYgY2VydGlmaWVycyB3YW50IHRvIG1ha2VcbiAgICAgKiBhYm91dCB0aGUga2V5IGl0c2VsZiwgcmF0aGVyIHRoYW4gdGhlIGJpbmRpbmcgYmV0d2VlbiBhIGtleSBhbmQgYVxuICAgICAqIG5hbWUuICovXG4gICAga2V5OiAzMSxcbiAgICAvKiogMHgyMDogS2V5IHJldm9jYXRpb24gc2lnbmF0dXJlXG4gICAgICogVGhlIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkIGRpcmVjdGx5IG9uIHRoZSBrZXkgYmVpbmcgcmV2b2tlZC4gIEFcbiAgICAgKiByZXZva2VkIGtleSBpcyBub3QgdG8gYmUgdXNlZC4gIE9ubHkgcmV2b2NhdGlvbiBzaWduYXR1cmVzIGJ5IHRoZVxuICAgICAqIGtleSBiZWluZyByZXZva2VkLCBvciBieSBhbiBhdXRob3JpemVkIHJldm9jYXRpb24ga2V5LCBzaG91bGQgYmVcbiAgICAgKiBjb25zaWRlcmVkIHZhbGlkIHJldm9jYXRpb24gc2lnbmF0dXJlcy5hICovXG4gICAga2V5X3Jldm9jYXRpb246IDMyLFxuICAgIC8qKiAweDI4OiBTdWJrZXkgcmV2b2NhdGlvbiBzaWduYXR1cmVcbiAgICAgKiBUaGUgc2lnbmF0dXJlIGlzIGNhbGN1bGF0ZWQgZGlyZWN0bHkgb24gdGhlIHN1YmtleSBiZWluZyByZXZva2VkLlxuICAgICAqIEEgcmV2b2tlZCBzdWJrZXkgaXMgbm90IHRvIGJlIHVzZWQuICBPbmx5IHJldm9jYXRpb24gc2lnbmF0dXJlc1xuICAgICAqIGJ5IHRoZSB0b3AtbGV2ZWwgc2lnbmF0dXJlIGtleSB0aGF0IGlzIGJvdW5kIHRvIHRoaXMgc3Via2V5LCBvclxuICAgICAqIGJ5IGFuIGF1dGhvcml6ZWQgcmV2b2NhdGlvbiBrZXksIHNob3VsZCBiZSBjb25zaWRlcmVkIHZhbGlkXG4gICAgICogcmV2b2NhdGlvbiBzaWduYXR1cmVzLlxuICAgICAqIEtleSByZXZvY2F0aW9uIHNpZ25hdHVyZXMgKHR5cGVzIDB4MjAgYW5kIDB4MjgpXG4gICAgICogaGFzaCBvbmx5IHRoZSBrZXkgYmVpbmcgcmV2b2tlZC4gKi9cbiAgICBzdWJrZXlfcmV2b2NhdGlvbjogNDAsXG4gICAgLyoqIDB4NDA6IFRpbWVzdGFtcCBzaWduYXR1cmUuXG4gICAgICogVGhpcyBzaWduYXR1cmUgaXMgb25seSBtZWFuaW5nZnVsIGZvciB0aGUgdGltZXN0YW1wIGNvbnRhaW5lZCBpblxuICAgICAqIGl0LiAqL1xuICAgIHRpbWVzdGFtcDogNjQsXG4gICAgLyoqICAgIDB4NTA6IFRoaXJkLVBhcnR5IENvbmZpcm1hdGlvbiBzaWduYXR1cmUuXG4gICAgICogVGhpcyBzaWduYXR1cmUgaXMgYSBzaWduYXR1cmUgb3ZlciBzb21lIG90aGVyIE9wZW5QR1AgU2lnbmF0dXJlXG4gICAgICogcGFja2V0KHMpLiAgSXQgaXMgYW5hbG9nb3VzIHRvIGEgbm90YXJ5IHNlYWwgb24gdGhlIHNpZ25lZCBkYXRhLlxuICAgICAqIEEgdGhpcmQtcGFydHkgc2lnbmF0dXJlIFNIT1VMRCBpbmNsdWRlIFNpZ25hdHVyZSBUYXJnZXRcbiAgICAgKiBzdWJwYWNrZXQocykgdG8gZ2l2ZSBlYXN5IGlkZW50aWZpY2F0aW9uLiAgTm90ZSB0aGF0IHdlIHJlYWxseSBkb1xuICAgICAqIG1lYW4gU0hPVUxELiAgVGhlcmUgYXJlIHBsYXVzaWJsZSB1c2VzIGZvciB0aGlzIChzdWNoIGFzIGEgYmxpbmRcbiAgICAgKiBwYXJ0eSB0aGF0IG9ubHkgc2VlcyB0aGUgc2lnbmF0dXJlLCBub3QgdGhlIGtleSBvciBzb3VyY2VcbiAgICAgKiBkb2N1bWVudCkgdGhhdCBjYW5ub3QgaW5jbHVkZSBhIHRhcmdldCBzdWJwYWNrZXQuICovXG4gICAgdGhpcmRfcGFydHk6IDgwXG4gIH0sXG5cbiAgc2lnbmF0dXJlU3VicGFja2V0OiB7XG4gICAgc2lnbmF0dXJlX2NyZWF0aW9uX3RpbWU6IDIsXG4gICAgc2lnbmF0dXJlX2V4cGlyYXRpb25fdGltZTogMyxcbiAgICBleHBvcnRhYmxlX2NlcnRpZmljYXRpb246IDQsXG4gICAgdHJ1c3Rfc2lnbmF0dXJlOiA1LFxuICAgIHJlZ3VsYXJfZXhwcmVzc2lvbjogNixcbiAgICByZXZvY2FibGU6IDcsXG4gICAga2V5X2V4cGlyYXRpb25fdGltZTogOSxcbiAgICBwbGFjZWhvbGRlcl9iYWNrd2FyZHNfY29tcGF0aWJpbGl0eTogMTAsXG4gICAgcHJlZmVycmVkX3N5bW1ldHJpY19hbGdvcml0aG1zOiAxMSxcbiAgICByZXZvY2F0aW9uX2tleTogMTIsXG4gICAgaXNzdWVyOiAxNixcbiAgICBub3RhdGlvbl9kYXRhOiAyMCxcbiAgICBwcmVmZXJyZWRfaGFzaF9hbGdvcml0aG1zOiAyMSxcbiAgICBwcmVmZXJyZWRfY29tcHJlc3Npb25fYWxnb3JpdGhtczogMjIsXG4gICAga2V5X3NlcnZlcl9wcmVmZXJlbmNlczogMjMsXG4gICAgcHJlZmVycmVkX2tleV9zZXJ2ZXI6IDI0LFxuICAgIHByaW1hcnlfdXNlcl9pZDogMjUsXG4gICAgcG9saWN5X3VyaTogMjYsXG4gICAga2V5X2ZsYWdzOiAyNyxcbiAgICBzaWduZXJzX3VzZXJfaWQ6IDI4LFxuICAgIHJlYXNvbl9mb3JfcmV2b2NhdGlvbjogMjksXG4gICAgZmVhdHVyZXM6IDMwLFxuICAgIHNpZ25hdHVyZV90YXJnZXQ6IDMxLFxuICAgIGVtYmVkZGVkX3NpZ25hdHVyZTogMzJcbiAgfSxcblxuICBrZXlGbGFnczoge1xuICAgIC8vIDB4MDEgLSBUaGlzIGtleSBtYXkgYmUgdXNlZCB0byBjZXJ0aWZ5IG90aGVyIGtleXMuXG4gICAgY2VydGlmeV9rZXlzOiAxLFxuICAgIC8vIDB4MDIgLSBUaGlzIGtleSBtYXkgYmUgdXNlZCB0byBzaWduIGRhdGEuXG4gICAgc2lnbl9kYXRhOiAyLFxuICAgIC8vIDB4MDQgLSBUaGlzIGtleSBtYXkgYmUgdXNlZCB0byBlbmNyeXB0IGNvbW11bmljYXRpb25zLlxuICAgIGVuY3J5cHRfY29tbXVuaWNhdGlvbjogNCxcbiAgICAvLyAweDA4IC0gVGhpcyBrZXkgbWF5IGJlIHVzZWQgdG8gZW5jcnlwdCBzdG9yYWdlLlxuICAgIGVuY3J5cHRfc3RvcmFnZTogOCxcbiAgICAvLyAweDEwIC0gVGhlIHByaXZhdGUgY29tcG9uZW50IG9mIHRoaXMga2V5IG1heSBoYXZlIGJlZW4gc3BsaXRcbiAgICAvLyAgICAgICAgYnkgYSBzZWNyZXQtc2hhcmluZyBtZWNoYW5pc20uXG4gICAgc3BsaXRfcHJpdmF0ZV9rZXk6IDE2LFxuICAgIC8vIDB4MjAgLSBUaGlzIGtleSBtYXkgYmUgdXNlZCBmb3IgYXV0aGVudGljYXRpb24uXG4gICAgYXV0aGVudGljYXRpb246IDMyLFxuICAgIC8vIDB4ODAgLSBUaGUgcHJpdmF0ZSBjb21wb25lbnQgb2YgdGhpcyBrZXkgbWF5IGJlIGluIHRoZVxuICAgIC8vICAgICAgICBwb3NzZXNzaW9uIG9mIG1vcmUgdGhhbiBvbmUgcGVyc29uLlxuICAgIHNoYXJlZF9wcml2YXRlX2tleTogMTI4XG4gIH0sXG5cbiAgYXJtb3I6IHtcbiAgICBtdWx0aXBhcnRfc2VjdGlvbjogMCxcbiAgICBtdWx0aXBhcnRfbGFzdDogMSxcbiAgICBzaWduZWQ6IDIsXG4gICAgbWVzc2FnZTogMyxcbiAgICBwdWJsaWNfa2V5OiA0LFxuICAgIHByaXZhdGVfa2V5OiA1XG4gIH0sXG5cbiAgLy8gQXNzZXJ0cyB2YWxpZGl0eSBhbmQgY29udmVydHMgZnJvbSBzdHJpbmcvaW50ZWdlciB0byBpbnRlZ2VyLlxuICB3cml0ZTogZnVuY3Rpb24odHlwZSwgZSkge1xuICAgIGlmICh0eXBlb2YgZSA9PSAnbnVtYmVyJykge1xuICAgICAgZSA9IHRoaXMucmVhZCh0eXBlLCBlKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZVtlXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdHlwZVtlXTtcbiAgICB9IGVsc2UgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGVudW0gdmFsdWUuJyk7XG4gIH0sXG4gIC8vIENvbnZlcnRzIGZyb20gYW4gaW50ZWdlciB0byBzdHJpbmcuXG4gIHJlYWQ6IGZ1bmN0aW9uKHR5cGUsIGUpIHtcbiAgICBmb3IgKHZhciBpIGluIHR5cGUpXG4gICAgICBpZiAodHlwZVtpXSA9PSBlKSByZXR1cm4gaTtcblxuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBlbnVtIHZhbHVlLicpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZW51bXM7XG4iLCJcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9vcGVucGdwLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5rZXkgPSByZXF1aXJlKCcuL2tleS5qcycpO1xubW9kdWxlLmV4cG9ydHMubWVzc2FnZSA9IHJlcXVpcmUoJy4vbWVzc2FnZS5qcycpO1xubW9kdWxlLmV4cG9ydHMuY2xlYXJ0ZXh0ID0gcmVxdWlyZSgnLi9jbGVhcnRleHQuanMnKTtcbm1vZHVsZS5leHBvcnRzLnV0aWwgPSByZXF1aXJlKCcuL3V0aWwnKTtcbm1vZHVsZS5leHBvcnRzLnBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0Jyk7XG5tb2R1bGUuZXhwb3J0cy5tcGkgPSByZXF1aXJlKCcuL3R5cGUvbXBpLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5zMmsgPSByZXF1aXJlKCcuL3R5cGUvczJrLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5rZXlpZCA9IHJlcXVpcmUoJy4vdHlwZS9rZXlpZC5qcycpO1xubW9kdWxlLmV4cG9ydHMuYXJtb3IgPSByZXF1aXJlKCcuL2VuY29kaW5nL2FybW9yLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5lbnVtcyA9IHJlcXVpcmUoJy4vZW51bXMuanMnKTtcbm1vZHVsZS5leHBvcnRzLmNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7XG5tb2R1bGUuZXhwb3J0cy5jcnlwdG8gPSByZXF1aXJlKCcuL2NyeXB0bycpO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0Jyk7XG52YXIgZW51bXMgPSByZXF1aXJlKCcuL2VudW1zLmpzJyk7XG52YXIgYXJtb3IgPSByZXF1aXJlKCcuL2VuY29kaW5nL2FybW9yLmpzJyk7XG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgQ2xhc3MgdGhhdCByZXByZXNlbnRzIGFuIE9wZW5QR1Aga2V5LiBNdXN0IGNvbnRhaW4gYSBwcmltYXJ5IGtleS5cbiAqIENhbiBjb250YWluIGFkZGl0aW9uYWwgc3Via2V5cywgc2lnbmF0dXJlcywgdXNlciBpZHMsIHVzZXIgYXR0cmlidXRlcy5cbiAqIEBwYXJhbSAge3BhY2tldGxpc3R9IHBhY2tldGxpc3QgVGhlIHBhY2tldHMgdGhhdCBmb3JtIHRoaXMga2V5XG4gKi9cblxuZnVuY3Rpb24gS2V5KHBhY2tldGxpc3QpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEtleSkpIHtcbiAgICByZXR1cm4gbmV3IEtleShwYWNrZXRsaXN0KTtcbiAgfVxuICB0aGlzLnBhY2tldHMgPSBwYWNrZXRsaXN0IHx8IG5ldyBwYWNrZXQubGlzdCgpO1xufVxuXG4vKiogXG4gKiBSZXR1cm5zIHRoZSBwcmltYXJ5IGtleSBwYWNrZXQgKHNlY3JldCBvciBwdWJsaWMpXG4gKiBAcmV0dXJucyB7cGFja2V0X3NlY3JldF9rZXl8cGFja2V0X3B1YmxpY19rZXl8bnVsbH0gXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0S2V5UGFja2V0ID0gZnVuY3Rpb24oKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYWNrZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHRoaXMucGFja2V0c1tpXS50YWcgPT0gZW51bXMucGFja2V0LnB1YmxpY19rZXkgfHxcbiAgICAgIHRoaXMucGFja2V0c1tpXS50YWcgPT0gZW51bXMucGFja2V0LnNlY3JldF9rZXkpIHtcbiAgICAgIHJldHVybiB0aGlzLnBhY2tldHNbaV07XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuLyoqIFxuICogUmV0dXJucyBhbGwgdGhlIHByaXZhdGUgYW5kIHB1YmxpYyBzdWJrZXkgcGFja2V0c1xuICogQHJldHVybnMge1twdWJsaWNfc3Via2V5fHNlY3JldF9zdWJrZXldfSBcbiAqL1xuS2V5LnByb3RvdHlwZS5nZXRTdWJrZXlQYWNrZXRzID0gZnVuY3Rpb24oKSB7XG5cbiAgdmFyIHN1YmtleXMgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFja2V0cy5sZW5ndGg7IGkrKykge1xuICAgIGlmICh0aGlzLnBhY2tldHNbaV0udGFnID09IGVudW1zLnBhY2tldC5wdWJsaWNfc3Via2V5IHx8XG4gICAgICB0aGlzLnBhY2tldHNbaV0udGFnID09IGVudW1zLnBhY2tldC5zZWNyZXRfc3Via2V5KSB7XG4gICAgICBzdWJrZXlzLnB1c2godGhpcy5wYWNrZXRzW2ldKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3Via2V5cztcbn07XG5cbi8qKiBcbiAqIFJldHVybnMgYWxsIHRoZSBwcml2YXRlIGFuZCBwdWJsaWMga2V5IGFuZCBzdWJrZXkgcGFja2V0c1xuICogQHJldHVybnMge1twdWJsaWNfc3Via2V5fHNlY3JldF9zdWJrZXl8cGFja2V0X3NlY3JldF9rZXl8cGFja2V0X3B1YmxpY19rZXldfSBcbiAqL1xuS2V5LnByb3RvdHlwZS5nZXRBbGxLZXlQYWNrZXRzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBbdGhpcy5nZXRLZXlQYWNrZXQoKV0uY29uY2F0KHRoaXMuZ2V0U3Via2V5UGFja2V0cygpKTtcbn07XG5cbi8qKiBcbiAqIFJldHVybnMga2V5IElEcyBvZiBhbGwga2V5IHBhY2tldHNcbiAqIEByZXR1cm5zIHtba2V5aWRdfSBcbiAqL1xuS2V5LnByb3RvdHlwZS5nZXRLZXlJZHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGtleUlkcyA9IFtdO1xuICB2YXIga2V5cyA9IHRoaXMuZ2V0QWxsS2V5UGFja2V0cygpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICBrZXlJZHMucHVzaChrZXlzW2ldLmdldEtleUlkKCkpO1xuICB9XG4gIHJldHVybiBrZXlJZHM7XG59O1xuXG5mdW5jdGlvbiBmaW5kS2V5KGtleXMsIGtleUlkcykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIga2V5SWQgPSBrZXlzW2ldLmdldEtleUlkKCk7IFxuICAgIGZvciAodmFyIGogPSAwOyBqIDwga2V5SWRzLmxlbmd0aDsgaisrKSB7XG4gICAgICBpZiAoa2V5SWQuZXF1YWxzKGtleUlkc1tqXSkpIHtcbiAgICAgICAgcmV0dXJuIGtleXNbaV07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIFJldHVybnMgZmlyc3QgcHVibGljIGtleSBwYWNrZXQgZm9yIGdpdmVuIGFycmF5IG9mIGtleSBJRHNcbiAqIEBwYXJhbSAge1trZXlpZF19IGtleUlkcyBcbiAqIEByZXR1cm4ge3B1YmxpY19zdWJrZXl8cGFja2V0X3B1YmxpY19rZXl8bnVsbH0gICAgICAgXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0UHVibGljS2V5UGFja2V0ID0gZnVuY3Rpb24oa2V5SWRzKSB7XG4gIHZhciBrZXlzID0gdGhpcy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5wdWJsaWNfa2V5LCBlbnVtcy5wYWNrZXQucHVibGljX3N1YmtleSk7XG4gIHJldHVybiBmaW5kS2V5KGtleXMsIGtleUlkcyk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgZmlyc3QgcHJpdmF0ZSBrZXkgcGFja2V0IGZvciBnaXZlbiBhcnJheSBvZiBrZXkgSURzXG4gKiBAcGFyYW0gIHtba2V5aWRdfSBrZXlJZHNcbiAqIEByZXR1cm4ge3NlY3JldF9zdWJrZXl8cGFja2V0X3NlY3JldF9rZXl8bnVsbH0gICAgICAgXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0UHJpdmF0ZUtleVBhY2tldCA9IGZ1bmN0aW9uKGtleUlkcykge1xuICB2YXIga2V5cyA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuc2VjcmV0X2tleSwgZW51bXMucGFja2V0LnNlY3JldF9zdWJrZXkpO1xuICByZXR1cm4gZmluZEtleShrZXlzLCBrZXlJZHMpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIHB1YmxpYyBrZXlcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbktleS5wcm90b3R5cGUuaXNQdWJsaWMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHB1YmxpY0tleVBhY2tldHMgPSB0aGlzLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnB1YmxpY19rZXkpO1xuICByZXR1cm4gcHVibGljS2V5UGFja2V0cy5sZW5ndGggPyB0cnVlIDogZmFsc2U7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIGEgcHJpdmF0ZSBrZXlcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbktleS5wcm90b3R5cGUuaXNQcml2YXRlID0gZnVuY3Rpb24oKSB7XG4gIHZhciBwcml2YXRlS2V5UGFja2V0cyA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQucHJpdmF0ZV9rZXkpO1xuICByZXR1cm4gcHJpdmF0ZUtleVBhY2tldHMubGVuZ3RoID8gdHJ1ZSA6IGZhbHNlO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGtleSBhcyBwdWJsaWMga2V5XG4gKiBAcmV0dXJuIHtrZXl9IHB1YmxpYyBrZXlcbiAqL1xuS2V5LnByb3RvdHlwZS50b1B1YmxpYyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFja2V0cy5sZW5ndGg7IGkrKykge1xuICAgIHN3aXRjaCAodGhpcy5wYWNrZXRzW2ldLnRhZykge1xuICAgICAgY2FzZSBlbnVtcy5wYWNrZXQuc2VjcmV0X2tleTpcbiAgICAgICAgdmFyIGJ5dGVzID0gdGhpcy5wYWNrZXRzW2ldLndyaXRlUHVibGljS2V5KCk7XG4gICAgICAgIHZhciBwdWJLZXlQYWNrZXQgPSBuZXcgcGFja2V0LnB1YmxpY19rZXkoKTtcbiAgICAgICAgcHViS2V5UGFja2V0LnJlYWQoYnl0ZXMpO1xuICAgICAgICBwYWNrZXRsaXN0LnB1c2gocHViS2V5UGFja2V0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGVudW1zLnBhY2tldC5zZWNyZXRfc3Via2V5OlxuICAgICAgICB2YXIgYnl0ZXMgPSB0aGlzLnBhY2tldHNbaV0ud3JpdGVQdWJsaWNLZXkoKTtcbiAgICAgICAgdmFyIHB1YlN1YmtleVBhY2tldCA9IG5ldyBwYWNrZXQucHVibGljX3N1YmtleSgpO1xuICAgICAgICBwdWJTdWJrZXlQYWNrZXQucmVhZChieXRlcyk7XG4gICAgICAgIHBhY2tldGxpc3QucHVzaChwdWJTdWJrZXlQYWNrZXQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHBhY2tldGxpc3QucHVzaCh0aGlzLnBhY2tldHNbaV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmV3IEtleShwYWNrZXRsaXN0KTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBBU0NJSSBhcm1vcmVkIHRleHQgb2Yga2V5XG4gKiBAcmV0dXJuIHtTdHJpbmd9IEFTQ0lJIGFybW9yXG4gKi9cbktleS5wcm90b3R5cGUuYXJtb3IgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHR5cGUgPSB0aGlzLmlzUHVibGljKCkgPyBlbnVtcy5hcm1vci5wdWJsaWNfa2V5IDogZW51bXMuYXJtb3IucHJpdmF0ZV9rZXk7XG4gIHJldHVybiBhcm1vci5lbmNvZGUodHlwZSwgdGhpcy5wYWNrZXRzLndyaXRlKCkpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGZpcnN0IGtleSBwYWNrZXQgdGhhdCBpcyBhdmFpbGFibGUgZm9yIHNpZ25pbmdcbiAqIEByZXR1cm4ge3B1YmxpY19zdWJrZXl8c2VjcmV0X3N1YmtleXxwYWNrZXRfc2VjcmV0X2tleXxwYWNrZXRfcHVibGljX2tleXxudWxsfVxuICovXG5LZXkucHJvdG90eXBlLmdldFNpZ25pbmdLZXlQYWNrZXQgPSBmdW5jdGlvbigpIHtcblxuICB2YXIgc2lnbmluZyA9IFsgZW51bXMucHVibGljS2V5LnJzYV9lbmNyeXB0X3NpZ24sIGVudW1zLnB1YmxpY0tleS5yc2Ffc2lnbiwgZW51bXMucHVibGljS2V5LmRzYV07XG5cbiAgc2lnbmluZyA9IHNpZ25pbmcubWFwKGZ1bmN0aW9uKHMpIHtcbiAgICByZXR1cm4gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIHMpO1xuICB9KTtcblxuICB2YXIga2V5cyA9IHRoaXMuZ2V0QWxsS2V5UGFja2V0cygpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChzaWduaW5nLmluZGV4T2Yoa2V5c1tpXS5hbGdvcml0aG0pICE9PSAtMSkge1xuICAgICAgcmV0dXJuIGtleXNbaV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIFJldHVybnMgcHJlZmVycmVkIHNpZ25hdHVyZSBoYXNoIGFsZ29yaXRobSBvZiB0aGlzIGtleVxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5LZXkucHJvdG90eXBlLmdldFByZWZlcnJlZFNpZ25hdHVyZUhhc2hBbGdvcml0aG0gPSBmdW5jdGlvbigpIHtcbiAgLy9UT0RPIGltcGxlbWVudDogaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQ4ODAjc2VjdGlvbi01LjIuMy44XG4gIC8vc2VwYXJhdGUgcHJpdmF0ZSBrZXkgcHJlZmVyZW5jZSBmcm9tIGRpZ2VzdCBwcmVmZXJlbmNlc1xuICByZXR1cm4gY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgdmFsaWQgZW5jcnlwdGlvbiBrZXkgcGFja2V0IGZvciB0aGlzIGtleVxuICogQHJldHVybnMge3B1YmxpY19zdWJrZXl8c2VjcmV0X3N1YmtleXxwYWNrZXRfc2VjcmV0X2tleXxwYWNrZXRfcHVibGljX2tleXxudWxsfSBrZXkgcGFja2V0IG9yIG51bGwgaWYgbm8gZW5jcnlwdGlvbiBrZXkgaGFzIGJlZW4gZm91bmRcbiAqL1xuS2V5LnByb3RvdHlwZS5nZXRFbmNyeXB0aW9uS2V5UGFja2V0ID0gZnVuY3Rpb24oKSB7XG4gIC8vIFY0OiBieSBjb252ZW50aW9uIHN1YmtleXMgYXJlIHByZWZlcmVkIGZvciBlbmNyeXB0aW9uIHNlcnZpY2VcbiAgLy8gVjM6IGtleXMgTVVTVCBOT1QgaGF2ZSBzdWJrZXlzXG4gIHZhciBpc1ZhbGlkRW5jcnlwdGlvbktleSA9IGZ1bmN0aW9uKGtleSkge1xuICAgIC8vVE9ETyBldmFsdWF0ZSBrZXkgZmxhZ3M6IGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQ4ODAjc2VjdGlvbi01LjIuMy4yMVxuICAgIHJldHVybiBrZXkuYWxnb3JpdGhtICE9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBlbnVtcy5wdWJsaWNLZXkuZHNhKSAmJiBrZXkuYWxnb3JpdGhtICE9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LFxuICAgICAgZW51bXMucHVibGljS2V5LnJzYV9zaWduKTtcbiAgICAvL1RPRE8gdmVyaWZ5IGtleVxuICAgIC8vJiYga2V5cy52ZXJpZnlLZXkoKVxuICB9O1xuXG4gIHZhciBzdWJrZXlzID0gdGhpcy5nZXRTdWJrZXlQYWNrZXRzKCk7XG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCBzdWJrZXlzLmxlbmd0aDsgaisrKSB7XG4gICAgaWYgKGlzVmFsaWRFbmNyeXB0aW9uS2V5KHN1YmtleXNbal0pKSB7XG4gICAgICByZXR1cm4gc3Via2V5c1tqXTtcbiAgICB9XG4gIH1cbiAgLy8gaWYgbm8gdmFsaWQgc3Via2V5IGZvciBlbmNyeXB0aW9uLCB1c2UgcHJpbWFyeSBrZXlcbiAgdmFyIHByaW1hcnlLZXkgPSB0aGlzLmdldEtleVBhY2tldCgpO1xuICBpZiAoaXNWYWxpZEVuY3J5cHRpb25LZXkocHJpbWFyeUtleSkpIHtcbiAgICByZXR1cm4gcHJpbWFyeUtleTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn07XG5cbi8qKlxuICogRGVjcnlwdHMgYWxsIHNlY3JldCBrZXkgYW5kIHN1YmtleSBwYWNrZXRzXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHBhc3NwaHJhc2UgXG4gKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIGFsbCBrZXkgYW5kIHN1YmtleSBwYWNrZXRzIGRlY3J5cHRlZCBzdWNjZXNzZnVsbHlcbiAqL1xuS2V5LnByb3RvdHlwZS5kZWNyeXB0ID0gZnVuY3Rpb24ocGFzc3BocmFzZSkge1xuICB2YXIga2V5cyA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuc2VjcmV0X2tleSwgZW51bXMucGFja2V0LnNlY3JldF9zdWJrZXkpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc3VjY2VzcyA9IGtleXNbaV0uZGVjcnlwdChwYXNzcGhyYXNlKTtcbiAgICBpZiAoIXN1Y2Nlc3MpIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogRGVjcnlwdHMgc3BlY2lmaWMga2V5IHBhY2tldHMgYnkga2V5IElEXG4gKiBAcGFyYW0gIHtba2V5aWRdfSBrZXlJZHNcbiAqIEBwYXJhbSAge1N0cmluZ30gcGFzc3BocmFzZSBcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgYWxsIGtleSBwYWNrZXRzIGRlY3J5cHRlZCBzdWNjZXNzZnVsbHlcbiAqL1xuS2V5LnByb3RvdHlwZS5kZWNyeXB0S2V5UGFja2V0ID0gZnVuY3Rpb24oa2V5SWRzLCBwYXNzcGhyYXNlKSB7XG4gIC8vVE9ETyByZXR1cm4gdmFsdWVcbiAgdmFyIGtleXMgPSB0aGlzLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnNlY3JldF9rZXksIGVudW1zLnBhY2tldC5zZWNyZXRfc3Via2V5KTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGtleUlkID0ga2V5c1tpXS5nZXRLZXlJZCgpOyBcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleUlkcy5sZW5ndGg7IGorKykge1xuICAgICAgaWYgKGtleUlkLmVxdWFscyhrZXlJZHNbal0pKSB7XG4gICAgICAgIHZhciBzdWNjZXNzID0ga2V5c1tpXS5kZWNyeXB0KHBhc3NwaHJhc2UpO1xuICAgICAgICBpZiAoIXN1Y2Nlc3MpIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vLyBUT0RPXG5LZXkucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uKCkge1xuXG59O1xuLy8gVE9ET1xuS2V5LnByb3RvdHlwZS5yZXZva2UgPSBmdW5jdGlvbigpIHtcblxufTtcblxuLyoqXG4gKiBSZWFkcyBhbiBPcGVuUEdQIGFybW9yZWQgdGV4dCBhbmQgcmV0dXJucyBhIGtleSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBhcm1vcmVkVGV4dCB0ZXh0IHRvIGJlIHBhcnNlZFxuICogQHJldHVybiB7a2V5fSBuZXcga2V5IG9iamVjdFxuICovXG5mdW5jdGlvbiByZWFkQXJtb3JlZChhcm1vcmVkVGV4dCkge1xuICB2YXIgaW5wdXQgPSBhcm1vci5kZWNvZGUoYXJtb3JlZFRleHQpO1xuICBpZiAoIShpbnB1dC50eXBlID09IGVudW1zLmFybW9yLnB1YmxpY19rZXkgfHwgaW5wdXQudHlwZSA9PSBlbnVtcy5hcm1vci5wcml2YXRlX2tleSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0FybW9yZWQgdGV4dCBub3Qgb2YgdHlwZSBrZXknKTtcbiAgfVxuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICBwYWNrZXRsaXN0LnJlYWQoaW5wdXQuZGF0YSk7XG4gIHZhciBuZXdLZXkgPSBuZXcgS2V5KHBhY2tldGxpc3QpO1xuICByZXR1cm4gbmV3S2V5O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIG5ldyBPcGVuUEdQIGtleS4gQ3VycmVudGx5IG9ubHkgc3VwcG9ydHMgUlNBIGtleXMuXG4gKiBQcmltYXJ5IGFuZCBzdWJrZXkgd2lsbCBiZSBvZiBzYW1lIHR5cGUuXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGtleVR5cGUgICAgdG8gaW5kaWNhdGUgd2hhdCB0eXBlIG9mIGtleSB0byBtYWtlLiBcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSU0EgaXMgMS4gU2VlIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQ4ODAjc2VjdGlvbi05LjFcbiAqIEBwYXJhbSB7SW50ZWdlcn0gbnVtQml0cyAgICBudW1iZXIgb2YgYml0cyBmb3IgdGhlIGtleSBjcmVhdGlvbi5cbiAqIEBwYXJhbSB7U3RyaW5nfSAgdXNlcklkICAgICBhc3N1bWVzIGFscmVhZHkgaW4gZm9ybSBvZiBcIlVzZXIgTmFtZSA8dXNlcm5hbWVAZW1haWwuY29tPlwiXG4gKiBAcGFyYW0ge1N0cmluZ30gIHBhc3NwaHJhc2UgVGhlIHBhc3NwaHJhc2UgdXNlZCB0byBlbmNyeXB0IHRoZSByZXN1bHRpbmcgcHJpdmF0ZSBrZXlcbiAqIEByZXR1cm4ge0tleX1cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGUoa2V5VHlwZSwgbnVtQml0cywgdXNlcklkLCBwYXNzcGhyYXNlKSB7XG4gIHZhciBwYWNrZXRsaXN0ID0gbmV3IHBhY2tldC5saXN0KCk7XG5cbiAgdmFyIHNlY3JldEtleVBhY2tldCA9IG5ldyBwYWNrZXQuc2VjcmV0X2tleSgpO1xuICBzZWNyZXRLZXlQYWNrZXQuYWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIGtleVR5cGUpO1xuICBzZWNyZXRLZXlQYWNrZXQuZ2VuZXJhdGUobnVtQml0cyk7XG4gIHNlY3JldEtleVBhY2tldC5lbmNyeXB0KHBhc3NwaHJhc2UpO1xuXG4gIHZhciB1c2VySWRQYWNrZXQgPSBuZXcgcGFja2V0LnVzZXJpZCgpO1xuICB1c2VySWRQYWNrZXQucmVhZCh1c2VySWQpO1xuXG4gIHZhciBkYXRhVG9TaWduID0ge307XG4gIGRhdGFUb1NpZ24udXNlcmlkID0gdXNlcklkUGFja2V0O1xuICBkYXRhVG9TaWduLmtleSA9IHNlY3JldEtleVBhY2tldDtcbiAgdmFyIHNpZ25hdHVyZVBhY2tldCA9IG5ldyBwYWNrZXQuc2lnbmF0dXJlKCk7XG4gIHNpZ25hdHVyZVBhY2tldC5zaWduYXR1cmVUeXBlID0gZW51bXMuc2lnbmF0dXJlLmNlcnRfZ2VuZXJpYztcbiAgc2lnbmF0dXJlUGFja2V0LnB1YmxpY0tleUFsZ29yaXRobSA9IGtleVR5cGU7XG4gIC8vVE9ETyB3ZSBzaG91bGQgbG9hZCBwcmVmZXJyZWQgaGFzaCBmcm9tIGNvbmZpZywgb3IgYXMgaW5wdXQgdG8gdGhpcyBmdW5jdGlvblxuICBzaWduYXR1cmVQYWNrZXQuaGFzaEFsZ29yaXRobSA9IGVudW1zLmhhc2guc2hhMjU2O1xuICBzaWduYXR1cmVQYWNrZXQua2V5RmxhZ3MgPSBbZW51bXMua2V5RmxhZ3MuY2VydGlmeV9rZXlzIHwgZW51bXMua2V5RmxhZ3Muc2lnbl9kYXRhXTtcbiAgc2lnbmF0dXJlUGFja2V0LnNpZ24oc2VjcmV0S2V5UGFja2V0LCBkYXRhVG9TaWduKTtcblxuICB2YXIgc2VjcmV0U3Via2V5UGFja2V0ID0gbmV3IHBhY2tldC5zZWNyZXRfc3Via2V5KCk7XG4gIHNlY3JldFN1YmtleVBhY2tldC5hbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSwga2V5VHlwZSk7XG4gIHNlY3JldFN1YmtleVBhY2tldC5nZW5lcmF0ZShudW1CaXRzKTtcbiAgc2VjcmV0U3Via2V5UGFja2V0LmVuY3J5cHQocGFzc3BocmFzZSk7XG5cbiAgZGF0YVRvU2lnbiA9IHt9O1xuICBkYXRhVG9TaWduLmtleSA9IHNlY3JldEtleVBhY2tldDtcbiAgZGF0YVRvU2lnbi5iaW5kID0gc2VjcmV0U3Via2V5UGFja2V0O1xuICB2YXIgc3Via2V5U2lnbmF0dXJlUGFja2V0ID0gbmV3IHBhY2tldC5zaWduYXR1cmUoKTtcbiAgc3Via2V5U2lnbmF0dXJlUGFja2V0LnNpZ25hdHVyZVR5cGUgPSBlbnVtcy5zaWduYXR1cmUuc3Via2V5X2JpbmRpbmc7XG4gIHN1YmtleVNpZ25hdHVyZVBhY2tldC5wdWJsaWNLZXlBbGdvcml0aG0gPSBrZXlUeXBlO1xuICAvL1RPRE8gd2Ugc2hvdWxkIGxvYWQgcHJlZmVycmVkIGhhc2ggZnJvbSBjb25maWcsIG9yIGFzIGlucHV0IHRvIHRoaXMgZnVuY3Rpb25cbiAgc3Via2V5U2lnbmF0dXJlUGFja2V0Lmhhc2hBbGdvcml0aG0gPSBlbnVtcy5oYXNoLnNoYTI1NjtcbiAgc3Via2V5U2lnbmF0dXJlUGFja2V0LmtleUZsYWdzID0gW2VudW1zLmtleUZsYWdzLmVuY3J5cHRfY29tbXVuaWNhdGlvbiB8IGVudW1zLmtleUZsYWdzLmVuY3J5cHRfc3RvcmFnZV07XG4gIHN1YmtleVNpZ25hdHVyZVBhY2tldC5zaWduKHNlY3JldEtleVBhY2tldCwgZGF0YVRvU2lnbik7XG5cbiAgcGFja2V0bGlzdC5wdXNoKHNlY3JldEtleVBhY2tldCk7XG4gIHBhY2tldGxpc3QucHVzaCh1c2VySWRQYWNrZXQpO1xuICBwYWNrZXRsaXN0LnB1c2goc2lnbmF0dXJlUGFja2V0KTtcbiAgcGFja2V0bGlzdC5wdXNoKHNlY3JldFN1YmtleVBhY2tldCk7XG4gIHBhY2tldGxpc3QucHVzaChzdWJrZXlTaWduYXR1cmVQYWNrZXQpO1xuXG4gIHJldHVybiBuZXcgS2V5KHBhY2tldGxpc3QpO1xufVxuXG5leHBvcnRzLktleSA9IEtleTtcbmV4cG9ydHMucmVhZEFybW9yZWQgPSByZWFkQXJtb3JlZDtcbmV4cG9ydHMuZ2VuZXJhdGUgPSBnZW5lcmF0ZTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBwYWNrZXQgPSByZXF1aXJlKCcuL3BhY2tldCcpO1xudmFyIGVudW1zID0gcmVxdWlyZSgnLi9lbnVtcy5qcycpO1xudmFyIGFybW9yID0gcmVxdWlyZSgnLi9lbmNvZGluZy9hcm1vci5qcycpO1xudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnLi9jcnlwdG8nKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi91dGlsJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhbiBPcGVuUEdQIG1lc3NhZ2UuXG4gKiBDYW4gYmUgYW4gZW5jcnlwdGVkIG1lc3NhZ2UsIHNpZ25lZCBtZXNzYWdlLCBjb21wcmVzc2VkIG1lc3NhZ2Ugb3IgbGl0ZXJhbCBtZXNzYWdlXG4gKiBAcGFyYW0gIHtwYWNrZXRsaXN0fSBwYWNrZXRsaXN0IFRoZSBwYWNrZXRzIHRoYXQgZm9ybSB0aGlzIG1lc3NhZ2VcbiAqIFNlZSBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0ODgwI3NlY3Rpb24tMTEuM1xuICovXG5cbmZ1bmN0aW9uIE1lc3NhZ2UocGFja2V0bGlzdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTWVzc2FnZSkpIHtcbiAgICByZXR1cm4gbmV3IE1lc3NhZ2UocGFja2V0bGlzdCk7XG4gIH1cbiAgdGhpcy5wYWNrZXRzID0gcGFja2V0bGlzdCB8fCBuZXcgcGFja2V0Lmxpc3QoKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBrZXkgSURzIG9mIHRoZSBrZXlzIHRvIHdoaWNoIHRoZSBzZXNzaW9uIGtleSBpcyBlbmNyeXB0ZWRcbiAqIEByZXR1cm4ge1trZXlJZF19IGFycmF5IG9mIGtleWlkIG9iamVjdHNcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUuZ2V0RW5jcnlwdGlvbktleUlkcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIga2V5SWRzID0gW107XG4gIHZhciBwa0VTS2V5UGFja2V0bGlzdCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQucHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkpO1xuICBwa0VTS2V5UGFja2V0bGlzdC5mb3JFYWNoKGZ1bmN0aW9uKHBhY2tldCkge1xuICAgIGtleUlkcy5wdXNoKHBhY2tldC5wdWJsaWNLZXlJZCk7XG4gIH0pO1xuICByZXR1cm4ga2V5SWRzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBrZXkgSURzIG9mIHRoZSBrZXlzIHRoYXQgc2lnbmVkIHRoZSBtZXNzYWdlXG4gKiBAcmV0dXJuIHtba2V5SWRdfSBhcnJheSBvZiBrZXlpZCBvYmplY3RzXG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLmdldFNpZ25pbmdLZXlJZHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGtleUlkcyA9IFtdO1xuICB2YXIgbXNnID0gdGhpcy51bndyYXBDb21wcmVzc2VkKCk7XG4gIC8vIHNlYXJjaCBmb3Igb25lIHBhc3Mgc2lnbmF0dXJlc1xuICB2YXIgb25lUGFzc1NpZ0xpc3QgPSBtc2cucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQub25lX3Bhc3Nfc2lnbmF0dXJlKTtcbiAgb25lUGFzc1NpZ0xpc3QuZm9yRWFjaChmdW5jdGlvbihwYWNrZXQpIHtcbiAgICBrZXlJZHMucHVzaChwYWNrZXQuc2lnbmluZ0tleUlkKTtcbiAgfSk7XG4gIC8vIGlmIG5vdGhpbmcgZm91bmQgbG9vayBmb3Igc2lnbmF0dXJlIHBhY2tldHNcbiAgaWYgKCFrZXlJZHMubGVuZ3RoKSB7XG4gICAgdmFyIHNpZ25hdHVyZUxpc3QgPSBtc2cucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuc2lnbmF0dXJlKTtcbiAgICBzaWduYXR1cmVMaXN0LmZvckVhY2goZnVuY3Rpb24ocGFja2V0KSB7XG4gICAgICBrZXlJZHMucHVzaChwYWNrZXQuaXNzdWVyS2V5SWQpO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBrZXlJZHM7XG59O1xuXG4vKipcbiAqIERlY3J5cHQgdGhlIG1lc3NhZ2VcbiAqIEBwYXJhbSB7a2V5fSBwcml2YXRlS2V5IHByaXZhdGUga2V5IHdpdGggZGVjcnlwdGVkIHNlY3JldCBkYXRhICAgICAgICAgICBcbiAqIEByZXR1cm4ge1ttZXNzYWdlXX0gbmV3IG1lc3NhZ2Ugd2l0aCBkZWNyeXB0ZWQgY29udGVudFxuICovXG5NZXNzYWdlLnByb3RvdHlwZS5kZWNyeXB0ID0gZnVuY3Rpb24ocHJpdmF0ZUtleSkge1xuICB2YXIgZW5jcnlwdGlvbktleUlkcyA9IHRoaXMuZ2V0RW5jcnlwdGlvbktleUlkcygpO1xuICBpZiAoIWVuY3J5cHRpb25LZXlJZHMubGVuZ3RoKSB7XG4gICAgLy8gbm90aGluZyB0byBkZWNyeXB0IHJldHVybiB1bm1vZGlmaWVkIG1lc3NhZ2VcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB2YXIgcHJpdmF0ZUtleVBhY2tldCA9IHByaXZhdGVLZXkuZ2V0UHJpdmF0ZUtleVBhY2tldChlbmNyeXB0aW9uS2V5SWRzKTtcbiAgaWYgKCFwcml2YXRlS2V5UGFja2V0LmlzRGVjcnlwdGVkKSB0aHJvdyBuZXcgRXJyb3IoJ1ByaXZhdGUga2V5IGlzIG5vdCBkZWNyeXB0ZWQuJyk7XG4gIHZhciBwa0VTS2V5UGFja2V0bGlzdCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQucHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkpO1xuICB2YXIgcGtFU0tleVBhY2tldDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwa0VTS2V5UGFja2V0bGlzdC5sZW5ndGg7IGkrKykge1xuICAgIGlmIChwa0VTS2V5UGFja2V0bGlzdFtpXS5wdWJsaWNLZXlJZC5lcXVhbHMocHJpdmF0ZUtleVBhY2tldC5nZXRLZXlJZCgpKSkge1xuICAgICAgcGtFU0tleVBhY2tldCA9IHBrRVNLZXlQYWNrZXRsaXN0W2ldO1xuICAgICAgcGtFU0tleVBhY2tldC5kZWNyeXB0KHByaXZhdGVLZXlQYWNrZXQpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChwa0VTS2V5UGFja2V0KSB7XG4gICAgdmFyIHN5bUVuY3J5cHRlZFBhY2tldGxpc3QgPSB0aGlzLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkLCBlbnVtcy5wYWNrZXQuc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkKTtcbiAgICBpZiAoc3ltRW5jcnlwdGVkUGFja2V0bGlzdC5sZW5ndGggIT09IDApIHtcbiAgICAgIHZhciBzeW1FbmNyeXB0ZWRQYWNrZXQgPSBzeW1FbmNyeXB0ZWRQYWNrZXRsaXN0WzBdO1xuICAgICAgc3ltRW5jcnlwdGVkUGFja2V0LmRlY3J5cHQocGtFU0tleVBhY2tldC5zZXNzaW9uS2V5QWxnb3JpdGhtLCBwa0VTS2V5UGFja2V0LnNlc3Npb25LZXkpO1xuICAgICAgcmV0dXJuIG5ldyBNZXNzYWdlKHN5bUVuY3J5cHRlZFBhY2tldC5wYWNrZXRzKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IGxpdGVyYWwgZGF0YSB0aGF0IGlzIHRoZSBib2R5IG9mIHRoZSBtZXNzYWdlXG4gKiBAcmV0dXJuIHtTdHJpbmd8bnVsbH0gbGl0ZXJhbCBib2R5IG9mIHRoZSBtZXNzYWdlIGFzIHN0cmluZ1xuICovXG5NZXNzYWdlLnByb3RvdHlwZS5nZXRMaXRlcmFsRGF0YSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbGl0ZXJhbCA9IHRoaXMucGFja2V0cy5maW5kUGFja2V0KGVudW1zLnBhY2tldC5saXRlcmFsKTtcbiAgcmV0dXJuIGxpdGVyYWwgJiYgbGl0ZXJhbC5kYXRhIHx8IG51bGw7XG59O1xuXG4vKipcbiAqIEdldCBsaXRlcmFsIGRhdGEgYXMgdGV4dFxuICogQHJldHVybiB7U3RyaW5nfG51bGx9IGxpdGVyYWwgYm9keSBvZiB0aGUgbWVzc2FnZSBpbnRlcnByZXRlZCBhcyB0ZXh0XG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLmdldFRleHQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGxpdGVyYWwgPSB0aGlzLnBhY2tldHMuZmluZFBhY2tldChlbnVtcy5wYWNrZXQubGl0ZXJhbCk7XG4gIGlmIChsaXRlcmFsKSB7XG4gICAgcmV0dXJuIGxpdGVyYWwuZ2V0VGV4dCgpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59O1xuXG4vKipcbiAqIEVuY3J5cHQgdGhlIG1lc3NhZ2VcbiAqIEBwYXJhbSAge1trZXldfSBrZXlzIGFycmF5IG9mIGtleXMsIHVzZWQgdG8gZW5jcnlwdCB0aGUgbWVzc2FnZVxuICogQHJldHVybiB7W21lc3NhZ2VdfSBuZXcgbWVzc2FnZSB3aXRoIGVuY3J5cHRlZCBjb250ZW50XG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLmVuY3J5cHQgPSBmdW5jdGlvbihrZXlzKSB7XG4gIHZhciBwYWNrZXRsaXN0ID0gbmV3IHBhY2tldC5saXN0KCk7XG4gIC8vVE9ETyBnZXQgcHJlZmVycmVkIGFsZ28gZnJvbSBzaWduYXR1cmVcbiAgdmFyIHNlc3Npb25LZXkgPSBjcnlwdG8uZ2VuZXJhdGVTZXNzaW9uS2V5KGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBjb25maWcuZW5jcnlwdGlvbl9jaXBoZXIpKTtcbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciBlbmNyeXB0aW9uS2V5UGFja2V0ID0ga2V5LmdldEVuY3J5cHRpb25LZXlQYWNrZXQoKTtcbiAgICBpZiAoZW5jcnlwdGlvbktleVBhY2tldCkge1xuICAgICAgdmFyIHBrRVNLZXlQYWNrZXQgPSBuZXcgcGFja2V0LnB1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5KCk7XG4gICAgICBwa0VTS2V5UGFja2V0LnB1YmxpY0tleUlkID0gZW5jcnlwdGlvbktleVBhY2tldC5nZXRLZXlJZCgpO1xuICAgICAgcGtFU0tleVBhY2tldC5wdWJsaWNLZXlBbGdvcml0aG0gPSBlbmNyeXB0aW9uS2V5UGFja2V0LmFsZ29yaXRobTtcbiAgICAgIHBrRVNLZXlQYWNrZXQuc2Vzc2lvbktleSA9IHNlc3Npb25LZXk7XG4gICAgICAvL1RPRE8gZ2V0IHByZWZlcnJlZCBhbGdvIGZyb20gc2lnbmF0dXJlXG4gICAgICBwa0VTS2V5UGFja2V0LnNlc3Npb25LZXlBbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYywgY29uZmlnLmVuY3J5cHRpb25fY2lwaGVyKTtcbiAgICAgIHBrRVNLZXlQYWNrZXQuZW5jcnlwdChlbmNyeXB0aW9uS2V5UGFja2V0KTtcbiAgICAgIHBhY2tldGxpc3QucHVzaChwa0VTS2V5UGFja2V0KTtcbiAgICB9XG4gIH0pO1xuICB2YXIgc3ltRW5jcnlwdGVkUGFja2V0O1xuICBpZiAoY29uZmlnLmludGVncml0eV9wcm90ZWN0KSB7XG4gICAgc3ltRW5jcnlwdGVkUGFja2V0ID0gbmV3IHBhY2tldC5zeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQoKTtcbiAgfSBlbHNlIHtcbiAgICBzeW1FbmNyeXB0ZWRQYWNrZXQgPSBuZXcgcGFja2V0LnN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkKCk7XG4gIH1cbiAgc3ltRW5jcnlwdGVkUGFja2V0LnBhY2tldHMgPSB0aGlzLnBhY2tldHM7XG4gIC8vVE9ETyBnZXQgcHJlZmVycmVkIGFsZ28gZnJvbSBzaWduYXR1cmVcbiAgc3ltRW5jcnlwdGVkUGFja2V0LmVuY3J5cHQoZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIGNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlciksIHNlc3Npb25LZXkpO1xuICBwYWNrZXRsaXN0LnB1c2goc3ltRW5jcnlwdGVkUGFja2V0KTtcbiAgcmV0dXJuIG5ldyBNZXNzYWdlKHBhY2tldGxpc3QpO1xufTtcblxuLyoqXG4gKiBTaWduIHRoZSBtZXNzYWdlICh0aGUgbGl0ZXJhbCBkYXRhIHBhY2tldCBvZiB0aGUgbWVzc2FnZSlcbiAqIEBwYXJhbSAge1trZXldfSBwcml2YXRlS2V5IHByaXZhdGUga2V5cyB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGEgZm9yIHNpZ25pbmdcbiAqIEByZXR1cm4ge21lc3NhZ2V9ICAgICAgbmV3IG1lc3NhZ2Ugd2l0aCBzaWduZWQgY29udGVudFxuICovXG5NZXNzYWdlLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24ocHJpdmF0ZUtleXMpIHtcblxuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuXG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldCA9IHRoaXMucGFja2V0cy5maW5kUGFja2V0KGVudW1zLnBhY2tldC5saXRlcmFsKTtcbiAgaWYgKCFsaXRlcmFsRGF0YVBhY2tldCkgdGhyb3cgbmV3IEVycm9yKCdObyBsaXRlcmFsIGRhdGEgcGFja2V0IHRvIHNpZ24uJyk7XG4gIFxuICB2YXIgbGl0ZXJhbEZvcm1hdCA9IGVudW1zLndyaXRlKGVudW1zLmxpdGVyYWwsIGxpdGVyYWxEYXRhUGFja2V0LmZvcm1hdCk7XG4gIHZhciBzaWduYXR1cmVUeXBlID0gbGl0ZXJhbEZvcm1hdCA9PSBlbnVtcy5saXRlcmFsLmJpbmFyeSBcbiAgICAgICAgICAgICAgICAgICAgICA/IGVudW1zLnNpZ25hdHVyZS5iaW5hcnkgOiBlbnVtcy5zaWduYXR1cmUudGV4dDsgXG4gIFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHByaXZhdGVLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG9uZVBhc3NTaWcgPSBuZXcgcGFja2V0Lm9uZV9wYXNzX3NpZ25hdHVyZSgpO1xuICAgIG9uZVBhc3NTaWcudHlwZSA9IHNpZ25hdHVyZVR5cGU7XG4gICAgLy9UT0RPIGdldCBwcmVmZXJyZWQgaGFzaGcgYWxnbyBmcm9tIGtleSBzaWduYXR1cmVcbiAgICBvbmVQYXNzU2lnLmhhc2hBbGdvcml0aG0gPSBjb25maWcucHJlZmVyX2hhc2hfYWxnb3JpdGhtO1xuICAgIHZhciBzaWduaW5nS2V5UGFja2V0ID0gcHJpdmF0ZUtleXNbaV0uZ2V0U2lnbmluZ0tleVBhY2tldCgpO1xuICAgIG9uZVBhc3NTaWcucHVibGljS2V5QWxnb3JpdGhtID0gc2lnbmluZ0tleVBhY2tldC5hbGdvcml0aG07XG4gICAgb25lUGFzc1NpZy5zaWduaW5nS2V5SWQgPSBzaWduaW5nS2V5UGFja2V0LmdldEtleUlkKCk7XG4gICAgcGFja2V0bGlzdC5wdXNoKG9uZVBhc3NTaWcpO1xuICB9XG5cbiAgcGFja2V0bGlzdC5wdXNoKGxpdGVyYWxEYXRhUGFja2V0KTtcbiAgXG4gIGZvciAodmFyIGkgPSBwcml2YXRlS2V5cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIHZhciBzaWduYXR1cmVQYWNrZXQgPSBuZXcgcGFja2V0LnNpZ25hdHVyZSgpO1xuICAgIHNpZ25hdHVyZVBhY2tldC5zaWduYXR1cmVUeXBlID0gc2lnbmF0dXJlVHlwZTtcbiAgICBzaWduYXR1cmVQYWNrZXQuaGFzaEFsZ29yaXRobSA9IGNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG07XG4gICAgc2lnbmF0dXJlUGFja2V0LnB1YmxpY0tleUFsZ29yaXRobSA9IHNpZ25pbmdLZXlQYWNrZXQuYWxnb3JpdGhtO1xuICAgIGlmICghc2lnbmluZ0tleVBhY2tldC5pc0RlY3J5cHRlZCkgdGhyb3cgbmV3IEVycm9yKCdQcml2YXRlIGtleSBpcyBub3QgZGVjcnlwdGVkLicpO1xuICAgIHNpZ25hdHVyZVBhY2tldC5zaWduKHNpZ25pbmdLZXlQYWNrZXQsIGxpdGVyYWxEYXRhUGFja2V0KTtcbiAgICBwYWNrZXRsaXN0LnB1c2goc2lnbmF0dXJlUGFja2V0KTtcbiAgfVxuXG4gIHJldHVybiBuZXcgTWVzc2FnZShwYWNrZXRsaXN0KTtcbn07XG5cbi8qKlxuICogVmVyaWZ5IG1lc3NhZ2Ugc2lnbmF0dXJlc1xuICogQHBhcmFtIHtba2V5XX0gcHVibGljS2V5cyBwdWJsaWMga2V5cyB0byB2ZXJpZnkgc2lnbmF0dXJlc1xuICogQHJldHVybiB7W3sna2V5aWQnOiBrZXlpZCwgJ3ZhbGlkJzogQm9vbGVhbn1dfSBsaXN0IG9mIHNpZ25lcidzIGtleWlkIGFuZCB2YWxpZGl0eSBvZiBzaWduYXR1cmVcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24ocHVibGljS2V5cykge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBtc2cgPSB0aGlzLnVud3JhcENvbXByZXNzZWQoKTtcbiAgdmFyIGxpdGVyYWxEYXRhTGlzdCA9IG1zZy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5saXRlcmFsKTtcbiAgaWYgKGxpdGVyYWxEYXRhTGlzdC5sZW5ndGggIT09IDEpIHRocm93IG5ldyBFcnJvcignQ2FuIG9ubHkgdmVyaWZ5IG1lc3NhZ2Ugd2l0aCBvbmUgbGl0ZXJhbCBkYXRhIHBhY2tldC4nKTtcbiAgdmFyIHNpZ25hdHVyZUxpc3QgPSBtc2cucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuc2lnbmF0dXJlKTtcbiAgcHVibGljS2V5cy5mb3JFYWNoKGZ1bmN0aW9uKHB1YktleSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnbmF0dXJlTGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHB1YmxpY0tleVBhY2tldCA9IHB1YktleS5nZXRQdWJsaWNLZXlQYWNrZXQoW3NpZ25hdHVyZUxpc3RbaV0uaXNzdWVyS2V5SWRdKTtcbiAgICAgIGlmIChwdWJsaWNLZXlQYWNrZXQpIHtcbiAgICAgICAgdmFyIHZlcmlmaWVkU2lnID0ge307XG4gICAgICAgIHZlcmlmaWVkU2lnLmtleWlkID0gc2lnbmF0dXJlTGlzdFtpXS5pc3N1ZXJLZXlJZDtcbiAgICAgICAgdmVyaWZpZWRTaWcuc3RhdHVzID0gc2lnbmF0dXJlTGlzdFtpXS52ZXJpZnkocHVibGljS2V5UGFja2V0LCBsaXRlcmFsRGF0YUxpc3RbMF0pO1xuICAgICAgICByZXN1bHQucHVzaCh2ZXJpZmllZFNpZyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIFVud3JhcCBjb21wcmVzc2VkIG1lc3NhZ2VcbiAqIEByZXR1cm4ge21lc3NhZ2V9IG1lc3NhZ2UgQ29udGVudCBvZiBjb21wcmVzc2VkIG1lc3NhZ2VcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUudW53cmFwQ29tcHJlc3NlZCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29tcHJlc3NlZCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuY29tcHJlc3NlZCk7XG4gIGlmIChjb21wcmVzc2VkLmxlbmd0aCkge1xuICAgIHJldHVybiBuZXcgTWVzc2FnZShjb21wcmVzc2VkWzBdLnBhY2tldHMpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59O1xuXG4vKipcbiAqIFJldHVybnMgQVNDSUkgYXJtb3JlZCB0ZXh0IG9mIG1lc3NhZ2VcbiAqIEByZXR1cm4ge1N0cmluZ30gQVNDSUkgYXJtb3JcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUuYXJtb3IgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGFybW9yLmVuY29kZShlbnVtcy5hcm1vci5tZXNzYWdlLCB0aGlzLnBhY2tldHMud3JpdGUoKSk7XG59O1xuXG4vKipcbiAqIHJlYWRzIGFuIE9wZW5QR1AgYXJtb3JlZCBtZXNzYWdlIGFuZCByZXR1cm5zIGEgbWVzc2FnZSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBhcm1vcmVkVGV4dCB0ZXh0IHRvIGJlIHBhcnNlZFxuICogQHJldHVybiB7bWVzc2FnZX0gbmV3IG1lc3NhZ2Ugb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIHJlYWRBcm1vcmVkKGFybW9yZWRUZXh0KSB7XG4gIC8vVE9ETyBob3cgZG8gd2Ugd2FudCB0byBoYW5kbGUgYmFkIHRleHQ/IEV4Y2VwdGlvbiB0aHJvd2luZ1xuICAvL1RPRE8gZG9uJ3QgYWNjZXB0IG5vbi1tZXNzYWdlIGFybW9yZWQgdGV4dHNcbiAgdmFyIGlucHV0ID0gYXJtb3IuZGVjb2RlKGFybW9yZWRUZXh0KS5kYXRhO1xuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICBwYWNrZXRsaXN0LnJlYWQoaW5wdXQpO1xuICB2YXIgbmV3TWVzc2FnZSA9IG5ldyBNZXNzYWdlKHBhY2tldGxpc3QpO1xuICByZXR1cm4gbmV3TWVzc2FnZTtcbn1cblxuLyoqXG4gKiBjcmVhdGVzIG5ldyBtZXNzYWdlIG9iamVjdCBmcm9tIHRleHRcbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0XG4gKiBAcmV0dXJuIHttZXNzYWdlfSBuZXcgbWVzc2FnZSBvYmplY3RcbiAqL1xuZnVuY3Rpb24gZnJvbVRleHQodGV4dCkge1xuICB2YXIgbGl0ZXJhbERhdGFQYWNrZXQgPSBuZXcgcGFja2V0LmxpdGVyYWwoKTtcbiAgLy8gdGV4dCB3aWxsIGJlIGNvbnZlcnRlZCB0byBVVEY4XG4gIGxpdGVyYWxEYXRhUGFja2V0LnNldFRleHQodGV4dCk7XG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgbGl0ZXJhbERhdGFQYWNrZXRsaXN0LnB1c2gobGl0ZXJhbERhdGFQYWNrZXQpO1xuICB2YXIgbmV3TWVzc2FnZSA9IG5ldyBNZXNzYWdlKGxpdGVyYWxEYXRhUGFja2V0bGlzdCk7XG4gIHJldHVybiBuZXdNZXNzYWdlO1xufVxuXG4vKipcbiAqIGNyZWF0ZXMgbmV3IG1lc3NhZ2Ugb2JqZWN0IGZyb20gYmluYXJ5IGRhdGFcbiAqIEBwYXJhbSB7U3RyaW5nfSBieXRlc1xuICogQHJldHVybiB7bWVzc2FnZX0gbmV3IG1lc3NhZ2Ugb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIGZyb21CaW5hcnkoYnl0ZXMpIHtcbiAgdmFyIGxpdGVyYWxEYXRhUGFja2V0ID0gbmV3IHBhY2tldC5saXRlcmFsKCk7XG4gIGxpdGVyYWxEYXRhUGFja2V0LnNldEJ5dGVzKGJ5dGVzLCBlbnVtcy5yZWFkKGVudW1zLmxpdGVyYWwsIGVudW1zLmxpdGVyYWwuYmluYXJ5KSk7XG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgbGl0ZXJhbERhdGFQYWNrZXRsaXN0LnB1c2gobGl0ZXJhbERhdGFQYWNrZXQpO1xuICB2YXIgbmV3TWVzc2FnZSA9IG5ldyBNZXNzYWdlKGxpdGVyYWxEYXRhUGFja2V0bGlzdCk7XG4gIHJldHVybiBuZXdNZXNzYWdlO1xufVxuXG5leHBvcnRzLk1lc3NhZ2UgPSBNZXNzYWdlO1xuZXhwb3J0cy5yZWFkQXJtb3JlZCA9IHJlYWRBcm1vcmVkO1xuZXhwb3J0cy5mcm9tVGV4dCA9IGZyb21UZXh0O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IFRoZSBvcGVucGdwIGJhc2UgbW9kdWxlIHNob3VsZCBwcm92aWRlIGFsbCBvZiB0aGUgZnVuY3Rpb25hbGl0eSBcbiAqIHRvIGNvbnN1bWUgdGhlIG9wZW5wZ3AuanMgbGlicmFyeS4gQWxsIGFkZGl0aW9uYWwgY2xhc3NlcyBhcmUgZG9jdW1lbnRlZCBcbiAqIGZvciBleHRlbmRpbmcgYW5kIGRldmVsb3Bpbmcgb24gdG9wIG9mIHRoZSBiYXNlIGxpYnJhcnkuXG4gKi9cblxudmFyIGFybW9yID0gcmVxdWlyZSgnLi9lbmNvZGluZy9hcm1vci5qcycpO1xudmFyIHBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0Jyk7XG52YXIgZW51bXMgPSByZXF1aXJlKCcuL2VudW1zLmpzJyk7XG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKTtcbnZhciBtZXNzYWdlID0gcmVxdWlyZSgnLi9tZXNzYWdlLmpzJyk7XG52YXIgY2xlYXJ0ZXh0ID0gcmVxdWlyZSgnLi9jbGVhcnRleHQuanMnKTtcbnZhciBrZXkgPSByZXF1aXJlKCcuL2tleS5qcycpO1xuXG5cbi8qKlxuICogRW5jcnlwdHMgbWVzc2FnZSB0ZXh0IHdpdGgga2V5c1xuICogQHBhcmFtICB7W2tleV19ICBrZXlzIGFycmF5IG9mIGtleXMsIHVzZWQgdG8gZW5jcnlwdCB0aGUgbWVzc2FnZVxuICogQHBhcmFtICB7U3RyaW5nfSB0ZXh0IG1lc3NhZ2UgYXMgbmF0aXZlIEphdmFTY3JpcHQgc3RyaW5nXG4gKiBAcmV0dXJuIHtTdHJpbmd9ICAgICAgZW5jcnlwdGVkIEFTQ0lJIGFybW9yZWQgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBlbmNyeXB0TWVzc2FnZShrZXlzLCB0ZXh0KSB7XG4gIHZhciBtc2cgPSBtZXNzYWdlLmZyb21UZXh0KHRleHQpO1xuICBtc2cgPSBtc2cuZW5jcnlwdChrZXlzKTtcbiAgdmFyIGFybW9yZWQgPSBhcm1vci5lbmNvZGUoZW51bXMuYXJtb3IubWVzc2FnZSwgbXNnLnBhY2tldHMud3JpdGUoKSk7XG4gIHJldHVybiBhcm1vcmVkO1xufVxuXG4vKipcbiAqIFNpZ25zIG1lc3NhZ2UgdGV4dCBhbmQgZW5jcnlwdHMgaXRcbiAqIEBwYXJhbSAge1trZXldfSAgcHVibGljS2V5cyBhcnJheSBvZiBrZXlzLCB1c2VkIHRvIGVuY3J5cHQgdGhlIG1lc3NhZ2VcbiAqIEBwYXJhbSAge2tleX0gICAgcHJpdmF0ZUtleSBwcml2YXRlIGtleSB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGEgZm9yIHNpZ25pbmdcbiAqIEBwYXJhbSAge1N0cmluZ30gdGV4dCAgICAgICBtZXNzYWdlIGFzIG5hdGl2ZSBKYXZhU2NyaXB0IHN0cmluZ1xuICogQHJldHVybiB7U3RyaW5nfSAgICAgICAgICAgIGVuY3J5cHRlZCBBU0NJSSBhcm1vcmVkIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gc2lnbkFuZEVuY3J5cHRNZXNzYWdlKHB1YmxpY0tleXMsIHByaXZhdGVLZXksIHRleHQpIHtcbiAgdmFyIG1zZyA9IG1lc3NhZ2UuZnJvbVRleHQodGV4dCk7XG4gIG1zZyA9IG1zZy5zaWduKFtwcml2YXRlS2V5XSk7XG4gIG1zZyA9IG1zZy5lbmNyeXB0KHB1YmxpY0tleXMpO1xuICB2YXIgYXJtb3JlZCA9IGFybW9yLmVuY29kZShlbnVtcy5hcm1vci5tZXNzYWdlLCBtc2cucGFja2V0cy53cml0ZSgpKTtcbiAgcmV0dXJuIGFybW9yZWQ7XG59XG5cbi8qKlxuICogRGVjcnlwdHMgbWVzc2FnZVxuICogQHBhcmFtICB7a2V5fSAgICAgcHJpdmF0ZUtleSBwcml2YXRlIGtleSB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGFcbiAqIEBwYXJhbSAge21lc3NhZ2V9IG1lc3NhZ2UgICAgdGhlIG1lc3NhZ2Ugb2JqZWN0IHdpdGggdGhlIGVuY3J5cHRlZCBkYXRhXG4gKiBAcmV0dXJuIHtTdHJpbmd8bnVsbH0gICAgICAgIGRlY3J5cHRlZCBtZXNzYWdlIGFzIGFzIG5hdGl2ZSBKYXZhU2NyaXB0IHN0cmluZ1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciBudWxsIGlmIG5vIGxpdGVyYWwgZGF0YSBmb3VuZFxuICovXG5mdW5jdGlvbiBkZWNyeXB0TWVzc2FnZShwcml2YXRlS2V5LCBtZXNzYWdlKSB7XG4gIG1lc3NhZ2UgPSBtZXNzYWdlLmRlY3J5cHQocHJpdmF0ZUtleSk7XG4gIHJldHVybiBtZXNzYWdlLmdldFRleHQoKTtcbn1cblxuLyoqXG4gKiBEZWNyeXB0cyBtZXNzYWdlIGFuZCB2ZXJpZmllcyBzaWduYXR1cmVzXG4gKiBAcGFyYW0gIHtrZXl9ICAgICBwcml2YXRlS2V5IHByaXZhdGUga2V5IHdpdGggZGVjcnlwdGVkIHNlY3JldCBrZXkgZGF0YVxuICogQHBhcmFtICB7W2tleV19ICAgcHVibGljS2V5cyBwdWJsaWMga2V5cyB0byB2ZXJpZnkgc2lnbmF0dXJlc1xuICogQHBhcmFtICB7bWVzc2FnZX0gbWVzc2FnZSAgICB0aGUgbWVzc2FnZSBvYmplY3Qgd2l0aCBzaWduZWQgYW5kIGVuY3J5cHRlZCBkYXRhXG4gKiBAcmV0dXJuIHt7J3RleHQnOiBTdHJpbmcsIHNpZ25hdHVyZXM6IFt7J2tleWlkJzoga2V5aWQsICdzdGF0dXMnOiBCb29sZWFufV19fVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNyeXB0ZWQgbWVzc2FnZSBhcyBhcyBuYXRpdmUgSmF2YVNjcmlwdCBzdHJpbmdcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCB2ZXJpZmllZCBzaWduYXR1cmVzIG9yIG51bGwgaWYgbm8gbGl0ZXJhbCBkYXRhIGZvdW5kXG4gKi9cbmZ1bmN0aW9uIGRlY3J5cHRBbmRWZXJpZnlNZXNzYWdlKHByaXZhdGVLZXksIHB1YmxpY0tleXMsIG1lc3NhZ2UpIHtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuICBtZXNzYWdlID0gbWVzc2FnZS5kZWNyeXB0KHByaXZhdGVLZXkpO1xuICByZXN1bHQudGV4dCA9IG1lc3NhZ2UuZ2V0VGV4dCgpO1xuICBpZiAocmVzdWx0LnRleHQpIHtcbiAgICByZXN1bHQuc2lnbmF0dXJlcyA9IG1lc3NhZ2UudmVyaWZ5KHB1YmxpY0tleXMpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogU2lnbnMgYSBjbGVhcnRleHQgbWVzc2FnZVxuICogQHBhcmFtICB7W0tleV19ICBwcml2YXRlS2V5cyBwcml2YXRlIGtleSB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGEgdG8gc2lnbiBjbGVhcnRleHRcbiAqIEBwYXJhbSAge1N0cmluZ30gdGV4dCAgICAgICAgY2xlYXJ0ZXh0XG4gKiBAcmV0dXJuIHtTdHJpbmd9ICAgICAgICAgICAgIEFTQ0lJIGFybW9yZWQgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBzaWduQ2xlYXJNZXNzYWdlKHByaXZhdGVLZXlzLCB0ZXh0KSB7XG4gIHZhciBjbGVhcnRleHRNZXNzYWdlID0gbmV3IGNsZWFydGV4dC5DbGVhcnRleHRNZXNzYWdlKHRleHQpO1xuICBjbGVhcnRleHRNZXNzYWdlLnNpZ24ocHJpdmF0ZUtleXMpO1xuICByZXR1cm4gY2xlYXJ0ZXh0TWVzc2FnZS5hcm1vcigpO1xufVxuXG4vKipcbiAqIFZlcmlmaWVzIHNpZ25hdHVyZXMgb2YgY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlXG4gKiBAcGFyYW0gIHtbS2V5XX0gICAgICAgICAgICBwdWJsaWNLZXlzIHB1YmxpYyBrZXlzIHRvIHZlcmlmeSBzaWduYXR1cmVzXG4gKiBAcGFyYW0gIHtDbGVhcnRleHRNZXNzYWdlfSBtZXNzYWdlICAgIGNsZWFydGV4dCBtZXNzYWdlIG9iamVjdCB3aXRoIHNpZ25hdHVyZXNcbiAqIEByZXR1cm4ge3sndGV4dCc6IFN0cmluZywgc2lnbmF0dXJlczogW3sna2V5aWQnOiBrZXlpZCwgJ3N0YXR1cyc6IEJvb2xlYW59XX19XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFydGV4dCB3aXRoIHN0YXR1cyBvZiB2ZXJpZmllZCBzaWduYXR1cmVzXG4gKi9cbmZ1bmN0aW9uIHZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZShwdWJsaWNLZXlzLCBtZXNzYWdlKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcbiAgaWYgKCEobWVzc2FnZSBpbnN0YW5jZW9mIGNsZWFydGV4dC5DbGVhcnRleHRNZXNzYWdlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGFyYW1ldGVyIFttZXNzYWdlXSBuZWVkcyB0byBiZSBvZiB0eXBlIENsZWFydGV4dE1lc3NhZ2UuJyk7XG4gIH1cbiAgcmVzdWx0LnRleHQgPSBtZXNzYWdlLmdldFRleHQoKTtcbiAgcmVzdWx0LnNpZ25hdHVyZXMgPSBtZXNzYWdlLnZlcmlmeShwdWJsaWNLZXlzKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBuZXcgT3BlblBHUCBrZXkgcGFpci4gQ3VycmVudGx5IG9ubHkgc3VwcG9ydHMgUlNBIGtleXMuXG4gKiBQcmltYXJ5IGFuZCBzdWJrZXkgd2lsbCBiZSBvZiBzYW1lIHR5cGUuXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGtleVR5cGUgICAgdG8gaW5kaWNhdGUgd2hhdCB0eXBlIG9mIGtleSB0byBtYWtlLiBcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSU0EgaXMgMS4gU2VlIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQ4ODAjc2VjdGlvbi05LjFcbiAqIEBwYXJhbSB7SW50ZWdlcn0gbnVtQml0cyAgICBudW1iZXIgb2YgYml0cyBmb3IgdGhlIGtleSBjcmVhdGlvbi4gKHNob3VsZCBiZSAxMDI0KywgZ2VuZXJhbGx5KVxuICogQHBhcmFtIHtTdHJpbmd9ICB1c2VySWQgICAgIGFzc3VtZXMgYWxyZWFkeSBpbiBmb3JtIG9mIFwiVXNlciBOYW1lIDx1c2VybmFtZUBlbWFpbC5jb20+XCJcbiAqIEBwYXJhbSB7U3RyaW5nfSAgcGFzc3BocmFzZSBUaGUgcGFzc3BocmFzZSB1c2VkIHRvIGVuY3J5cHQgdGhlIHJlc3VsdGluZyBwcml2YXRlIGtleVxuICogQHJldHVybiB7T2JqZWN0fSB7a2V5OiBbS2V5XSwgcHJpdmF0ZUtleUFybW9yZWQ6IFtTdHJpbmddLCBwdWJsaWNLZXlBcm1vcmVkOiBbU3RyaW5nXX1cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVLZXlQYWlyKGtleVR5cGUsIG51bUJpdHMsIHVzZXJJZCwgcGFzc3BocmFzZSkge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIHZhciBuZXdLZXkgPSBrZXkuZ2VuZXJhdGUoa2V5VHlwZSwgbnVtQml0cywgdXNlcklkLCBwYXNzcGhyYXNlKTtcbiAgcmVzdWx0LmtleSA9IG5ld0tleTtcbiAgcmVzdWx0LnByaXZhdGVLZXlBcm1vcmVkID0gbmV3S2V5LmFybW9yKCk7XG4gIHJlc3VsdC5wdWJsaWNLZXlBcm1vcmVkID0gbmV3S2V5LnRvUHVibGljKCkuYXJtb3IoKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0cy5lbmNyeXB0TWVzc2FnZSA9IGVuY3J5cHRNZXNzYWdlO1xuZXhwb3J0cy5zaWduQW5kRW5jcnlwdE1lc3NhZ2UgPSBzaWduQW5kRW5jcnlwdE1lc3NhZ2U7XG5leHBvcnRzLmRlY3J5cHRNZXNzYWdlID0gZGVjcnlwdE1lc3NhZ2U7XG5leHBvcnRzLmRlY3J5cHRBbmRWZXJpZnlNZXNzYWdlID0gZGVjcnlwdEFuZFZlcmlmeU1lc3NhZ2VcbmV4cG9ydHMuc2lnbkNsZWFyTWVzc2FnZSA9IHNpZ25DbGVhck1lc3NhZ2U7XG5leHBvcnRzLnZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZSA9IHZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZTtcbmV4cG9ydHMuZ2VuZXJhdGVLZXlQYWlyID0gZ2VuZXJhdGVLZXlQYWlyO1xuIiwidmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxuLy8gVGhpcyBpcyBwcmV0dHkgdWdseSwgYnV0IGJyb3dzZXJpZnkgbmVlZHMgdG8gaGF2ZSB0aGUgcmVxdWlyZXMgZXhwbGljaXRseSB3cml0dGVuLlxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGNvbXByZXNzZWQ6IHJlcXVpcmUoJy4vY29tcHJlc3NlZC5qcycpLFxuICBzeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQ6IHJlcXVpcmUoJy4vc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkLmpzJyksXG4gIHB1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5OiByZXF1aXJlKCcuL3B1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5LmpzJyksXG4gIHN5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXk6IHJlcXVpcmUoJy4vc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleS5qcycpLFxuICBsaXRlcmFsOiByZXF1aXJlKCcuL2xpdGVyYWwuanMnKSxcbiAgcHVibGljX2tleTogcmVxdWlyZSgnLi9wdWJsaWNfa2V5LmpzJyksXG4gIHN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkOiByZXF1aXJlKCcuL3N5bW1ldHJpY2FsbHlfZW5jcnlwdGVkLmpzJyksXG4gIG1hcmtlcjogcmVxdWlyZSgnLi9tYXJrZXIuanMnKSxcbiAgcHVibGljX3N1YmtleTogcmVxdWlyZSgnLi9wdWJsaWNfc3Via2V5LmpzJyksXG4gIHVzZXJfYXR0cmlidXRlOiByZXF1aXJlKCcuL3VzZXJfYXR0cmlidXRlLmpzJyksXG4gIG9uZV9wYXNzX3NpZ25hdHVyZTogcmVxdWlyZSgnLi9vbmVfcGFzc19zaWduYXR1cmUuanMnKSxcbiAgc2VjcmV0X2tleTogcmVxdWlyZSgnLi9zZWNyZXRfa2V5LmpzJyksXG4gIHVzZXJpZDogcmVxdWlyZSgnLi91c2VyaWQuanMnKSxcbiAgc2VjcmV0X3N1YmtleTogcmVxdWlyZSgnLi9zZWNyZXRfc3Via2V5LmpzJyksXG4gIHNpZ25hdHVyZTogcmVxdWlyZSgnLi9zaWduYXR1cmUuanMnKSxcbiAgdHJ1c3Q6IHJlcXVpcmUoJy4vdHJ1c3QuanMnKVxufVxuXG5mb3IgKHZhciBpIGluIGVudW1zLnBhY2tldCkge1xuICB2YXIgcGFja2V0Q2xhc3MgPSBtb2R1bGUuZXhwb3J0c1tpXTtcblxuICBpZiAocGFja2V0Q2xhc3MgIT0gdW5kZWZpbmVkKVxuICAgIHBhY2tldENsYXNzLnByb3RvdHlwZS50YWcgPSBlbnVtcy5wYWNrZXRbaV07XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBKWEcgPSByZXF1aXJlKCcuLi9jb21wcmVzc2lvbi9qeGcuanMnKSxcbiAgYmFzZTY0ID0gcmVxdWlyZSgnLi4vZW5jb2RpbmcvYmFzZTY0LmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBDb21wcmVzc2VkIERhdGEgUGFja2V0IChUYWcgOClcbiAqIFxuICogUkZDNDg4MCA1LjY6XG4gKiBUaGUgQ29tcHJlc3NlZCBEYXRhIHBhY2tldCBjb250YWlucyBjb21wcmVzc2VkIGRhdGEuICBUeXBpY2FsbHksIHRoaXNcbiAqIHBhY2tldCBpcyBmb3VuZCBhcyB0aGUgY29udGVudHMgb2YgYW4gZW5jcnlwdGVkIHBhY2tldCwgb3IgZm9sbG93aW5nXG4gKiBhIFNpZ25hdHVyZSBvciBPbmUtUGFzcyBTaWduYXR1cmUgcGFja2V0LCBhbmQgY29udGFpbnMgYSBsaXRlcmFsIGRhdGFcbiAqIHBhY2tldC5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfY29tcHJlc3NlZCgpIHtcbiAgLyoqIEB0eXBlIHtwYWNrZXRsaXN0fSAqL1xuICB0aGlzLnBhY2tldHM7XG4gIC8qKiBAdHlwZSB7Y29tcHJlc3Npb259ICovXG4gIHRoaXMuYWxnb3JpdGhtID0gJ3VuY29tcHJlc3NlZCc7XG5cbiAgdGhpcy5jb21wcmVzc2VkID0gbnVsbDtcblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciB0aGUgcGFja2V0LlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyA4IHBhY2tldFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJBTSB7aU5URUdFUn0gTEVOIGxFTkdUSCBPRiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mIFxuICAgKiBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9jb21wcmVzc2VkfSBPYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgLy8gT25lIG9jdGV0IHRoYXQgZ2l2ZXMgdGhlIGFsZ29yaXRobSB1c2VkIHRvIGNvbXByZXNzIHRoZSBwYWNrZXQuXG4gICAgdGhpcy5hbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLmNvbXByZXNzaW9uLCBieXRlcy5jaGFyQ29kZUF0KDApKTtcblxuICAgIC8vIENvbXByZXNzZWQgZGF0YSwgd2hpY2ggbWFrZXMgdXAgdGhlIHJlbWFpbmRlciBvZiB0aGUgcGFja2V0LlxuICAgIHRoaXMuY29tcHJlc3NlZCA9IGJ5dGVzLnN1YnN0cigxKTtcblxuICAgIHRoaXMuZGVjb21wcmVzcygpO1xuICB9XG5cblxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5jb21wcmVzc2VkID09IG51bGwpXG4gICAgICB0aGlzLmNvbXByZXNzKCk7XG5cbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5jb21wcmVzc2lvbiwgdGhpcy5hbGdvcml0aG0pKSArIHRoaXMuY29tcHJlc3NlZDtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIERlY29tcHJlc3Npb24gbWV0aG9kIGZvciBkZWNvbXByZXNzaW5nIHRoZSBjb21wcmVzc2VkIGRhdGFcbiAgICogcmVhZCBieSByZWFkX3BhY2tldFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBkZWNvbXByZXNzZWQgZGF0YVxuICAgKi9cbiAgdGhpcy5kZWNvbXByZXNzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGRlY29tcHJlc3NlZDtcblxuICAgIHN3aXRjaCAodGhpcy5hbGdvcml0aG0pIHtcbiAgICAgIGNhc2UgJ3VuY29tcHJlc3NlZCc6XG4gICAgICAgIGRlY29tcHJlc3NlZCA9IHRoaXMuY29tcHJlc3NlZDtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3ppcCc6XG4gICAgICAgIHZhciBjb21wRGF0YSA9IHRoaXMuY29tcHJlc3NlZDtcblxuICAgICAgICB2YXIgcmFkaXggPSBiYXNlNjQuZW5jb2RlKGNvbXBEYXRhKS5yZXBsYWNlKC9cXG4vZywgXCJcIik7XG4gICAgICAgIC8vIG5vIGhlYWRlciBpbiB0aGlzIGNhc2UsIGRpcmVjdGx5IGNhbGwgZGVmbGF0ZVxuICAgICAgICB2YXIganhnX29iaiA9IG5ldyBKWEcuVXRpbC5VbnppcChKWEcuVXRpbC5CYXNlNjQuZGVjb2RlQXNBcnJheShyYWRpeCkpO1xuXG4gICAgICAgIGRlY29tcHJlc3NlZCA9IHVuZXNjYXBlKGp4Z19vYmouZGVmbGF0ZSgpWzBdWzBdKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3psaWInOlxuICAgICAgICAvL1JGQyAxOTUwLiBCaXRzIDAtMyBDb21wcmVzc2lvbiBNZXRob2RcbiAgICAgICAgdmFyIGNvbXByZXNzaW9uTWV0aG9kID0gdGhpcy5jb21wcmVzc2VkLmNoYXJDb2RlQXQoMCkgJSAweDEwO1xuXG4gICAgICAgIC8vQml0cyA0LTcgUkZDIDE5NTAgYXJlIExaNzcgV2luZG93LiBHZW5lcmFsbHkgdGhpcyB2YWx1ZSBpcyA3ID09IDMyayB3aW5kb3cgc2l6ZS5cbiAgICAgICAgLy8gMm5kIEJ5dGUgaW4gUkZDIDE5NTAgaXMgZm9yIFwiRkxBR3NcIiBBbGxvd3MgZm9yIGEgRGljdGlvbmFyeSBcbiAgICAgICAgLy8gKGhvdyBpcyB0aGlzIGRlZmluZWQpLiBCYXNpYyBjaGVja3N1bSwgYW5kIGNvbXByZXNzaW9uIGxldmVsLlxuXG4gICAgICAgIGlmIChjb21wcmVzc2lvbk1ldGhvZCA9PSA4KSB7IC8vQ00gOCBpcyBmb3IgREVGTEFURSwgUkZDIDE5NTFcbiAgICAgICAgICAvLyByZW1vdmUgNCBieXRlcyBBRExFUjMyIGNoZWNrc3VtIGZyb20gdGhlIGVuZFxuICAgICAgICAgIHZhciBjb21wRGF0YSA9IHRoaXMuY29tcHJlc3NlZC5zdWJzdHJpbmcoMCwgdGhpcy5jb21wcmVzc2VkLmxlbmd0aCAtIDQpO1xuICAgICAgICAgIHZhciByYWRpeCA9IGJhc2U2NC5lbmNvZGUoY29tcERhdGEpLnJlcGxhY2UoL1xcbi9nLCBcIlwiKTtcbiAgICAgICAgICAvL1RPRE8gY2hlY2sgQURMRVIzMiBjaGVja3N1bVxuICAgICAgICAgIGRlY29tcHJlc3NlZCA9IEpYRy5kZWNvbXByZXNzKHJhZGl4KTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHV0aWwucHJpbnRfZXJyb3IoXCJDb21wcmVzc2lvbiBhbGdvcml0aG0gWkxJQiBvbmx5IHN1cHBvcnRzIFwiICtcbiAgICAgICAgICAgIFwiREVGTEFURSBjb21wcmVzc2lvbiBtZXRob2QuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdiemlwMic6XG4gICAgICAgIC8vIFRPRE86IG5lZWQgdG8gaW1wbGVtZW50IHRoaXNcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb21wcmVzc2lvbiBhbGdvcml0aG0gQlppcDIgW0JaMl0gaXMgbm90IGltcGxlbWVudGVkLicpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIHVua25vd24gOlwiICsgdGhpcy5hbG9ncml0aG0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLnBhY2tldHMucmVhZChkZWNvbXByZXNzZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXByZXNzIHRoZSBwYWNrZXQgZGF0YSAobWVtYmVyIGRlY29tcHJlc3NlZERhdGEpXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gdHlwZSBBbGdvcml0aG0gdG8gYmUgdXNlZCAvLyBTZWUgUkZDIDQ4ODAgOS4zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgY29tcHJlc3NlZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBjb21wcmVzc2VkIGRhdGEgc3RvcmVkIGluIGF0dHJpYnV0ZSBjb21wcmVzc2VkRGF0YVxuICAgKi9cbiAgdGhpcy5jb21wcmVzcyA9IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5hbGdvcml0aG0pIHtcblxuICAgICAgY2FzZSAndW5jb21wcmVzc2VkJzpcbiAgICAgICAgLy8gLSBVbmNvbXByZXNzZWRcbiAgICAgICAgdGhpcy5jb21wcmVzc2VkID0gdGhpcy5wYWNrZXRzLndyaXRlKCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd6aXAnOlxuICAgICAgICAvLyAtIFpJUCBbUkZDMTk1MV1cbiAgICAgICAgdXRpbC5wcmludF9lcnJvcihcIkNvbXByZXNzaW9uIGFsZ29yaXRobSBaSVAgW1JGQzE5NTFdIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd6bGliJzpcbiAgICAgICAgLy8gLSBaTElCIFtSRkMxOTUwXVxuICAgICAgICAvLyBUT0RPOiBuZWVkIHRvIGltcGxlbWVudCB0aGlzXG4gICAgICAgIHV0aWwucHJpbnRfZXJyb3IoXCJDb21wcmVzc2lvbiBhbGdvcml0aG0gWkxJQiBbUkZDMTk1MF0gaXMgbm90IGltcGxlbWVudGVkLlwiKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2J6aXAyJzpcbiAgICAgICAgLy8gIC0gQlppcDIgW0JaMl1cbiAgICAgICAgLy8gVE9ETzogbmVlZCB0byBpbXBsZW1lbnQgdGhpc1xuICAgICAgICB1dGlsLnByaW50X2Vycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIEJaaXAyIFtCWjJdIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB1dGlsLnByaW50X2Vycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIHVua25vd24gOlwiICsgdGhpcy50eXBlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59O1xuIiwidmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGxpc3Q6IHJlcXVpcmUoJy4vcGFja2V0bGlzdC5qcycpLFxufTtcblxudmFyIHBhY2tldHMgPSByZXF1aXJlKCcuL2FsbF9wYWNrZXRzLmpzJyk7XG5cbmZvciAodmFyIGkgaW4gcGFja2V0cylcbiAgbW9kdWxlLmV4cG9ydHNbaV0gPSBwYWNrZXRzW2ldO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIExpdGVyYWwgRGF0YSBQYWNrZXQgKFRhZyAxMSlcbiAqIFxuICogUkZDNDg4MCA1Ljk6IEEgTGl0ZXJhbCBEYXRhIHBhY2tldCBjb250YWlucyB0aGUgYm9keSBvZiBhIG1lc3NhZ2U7IGRhdGEgdGhhdFxuICogaXMgbm90IHRvIGJlIGZ1cnRoZXIgaW50ZXJwcmV0ZWQuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X2xpdGVyYWwoKSB7XG4gIHRoaXMuZm9ybWF0ID0gJ3V0ZjgnOyAvLyBkZWZhdWx0IGZvcm1hdCBmb3IgbGl0ZXJhbCBkYXRhIHBhY2tldHNcbiAgdGhpcy5kYXRhID0gJyc7IC8vIGxpdGVyYWwgZGF0YSByZXByZXNlbnRhdGlvbiBhcyBuYXRpdmUgSmF2YVNjcmlwdCBzdHJpbmcgb3IgYnl0ZXNcbiAgdGhpcy5kYXRlID0gbmV3IERhdGUoKTtcblxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHBhY2tldCBkYXRhIHRvIGEgamF2YXNjcmlwdCBuYXRpdmUgc3RyaW5nLCBlbmQgb2YgbGluZSBcbiAgICogd2lsbCBiZSBub3JtYWxpemVkIHRvIFxcclxcbiBhbmQgYnkgZGVmYXVsdCB0ZXh0IGlzIGNvbnZlcnRlZCB0byBVVEY4XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IEFueSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmdcbiAgICovXG4gIHRoaXMuc2V0VGV4dCA9IGZ1bmN0aW9uKHRleHQpIHtcbiAgICAvLyBub3JtYWxpemUgRU9MIHRvIFxcclxcblxuICAgIHRleHQgPSB0ZXh0LnJlcGxhY2UoL1xcci9nLCAnJykucmVwbGFjZSgvXFxuL2csICdcXHJcXG4nKTtcbiAgICAvLyBlbmNvZGUgVVRGOFxuICAgIHRoaXMuZGF0YSA9IHRoaXMuZm9ybWF0ID09ICd1dGY4JyA/IHV0aWwuZW5jb2RlX3V0ZjgodGV4dCkgOiB0ZXh0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgbGl0ZXJhbCBkYXRhIHBhY2tldHMgYXMgbmF0aXZlIEphdmFTY3JpcHQgc3RyaW5nXG4gICAqIHdpdGggbm9ybWFsaXplZCBlbmQgb2YgbGluZSB0byBcXG5cbiAgICogQHJldHVybiB7U3RyaW5nfSBsaXRlcmFsIGRhdGEgYXMgdGV4dFxuICAgKi9cbiAgdGhpcy5nZXRUZXh0ID0gZnVuY3Rpb24oKSB7XG4gICAgLy8gZGVjb2RlIFVURjhcbiAgICB2YXIgdGV4dCA9IHV0aWwuZGVjb2RlX3V0ZjgodGhpcy5kYXRhKTtcbiAgICAvLyBub3JtYWxpemUgRU9MIHRvIFxcblxuICAgIHJldHVybiB0ZXh0LnJlcGxhY2UoL1xcclxcbi9nLCAnXFxuJyk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBwYWNrZXQgZGF0YSB0byB2YWx1ZSByZXByZXNlbnRlZCBieSB0aGUgcHJvdmlkZWQgc3RyaW5nIG9mIGJ5dGVzLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gYnl0ZXMgVGhlIHN0cmluZyBvZiBieXRlc1xuICAgKiBAcGFyYW0geyd1dGY4fCdiaW5hcnknfCd0ZXh0J30gZm9ybWF0IFRoZSBmb3JtYXQgb2YgdGhlIHN0cmluZyBvZiBieXRlc1xuICAgKi9cbiAgdGhpcy5zZXRCeXRlcyA9IGZ1bmN0aW9uKGJ5dGVzLCBmb3JtYXQpIHtcbiAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICB0aGlzLmRhdGEgPSBieXRlcztcbiAgfVxuXG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYnl0ZSBzZXF1ZW5jZSByZXByZXNlbnRpbmcgdGhlIGxpdGVyYWwgcGFja2V0IGRhdGFcbiAgICogQHJldHVybnMge1N0cmluZ30gQSBzZXF1ZW5jZSBvZiBieXRlc1xuICAgKi9cbiAgdGhpcy5nZXRCeXRlcyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGE7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgKHRhZyAxMSkuXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxMSBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvblxuICAgKiAgICAgICAgICAgIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuXG4gICAqICAgICAgICAgICAgTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2ZcbiAgICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBvYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgLy8gLSBBIG9uZS1vY3RldCBmaWVsZCB0aGF0IGRlc2NyaWJlcyBob3cgdGhlIGRhdGEgaXMgZm9ybWF0dGVkLlxuXG4gICAgdmFyIGZvcm1hdCA9IGVudW1zLnJlYWQoZW51bXMubGl0ZXJhbCwgYnl0ZXMuY2hhckNvZGVBdCgwKSk7XG5cbiAgICB2YXIgZmlsZW5hbWVfbGVuID0gYnl0ZXMuY2hhckNvZGVBdCgxKTtcbiAgICB0aGlzLmZpbGVuYW1lID0gdXRpbC5kZWNvZGVfdXRmOChieXRlcy5zdWJzdHIoMiwgZmlsZW5hbWVfbGVuKSk7XG5cbiAgICB0aGlzLmRhdGUgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cigyICsgZmlsZW5hbWVfbGVuLCA0KSk7XG5cbiAgICB2YXIgZGF0YSA9IGJ5dGVzLnN1YnN0cmluZyg2ICsgZmlsZW5hbWVfbGVuKTtcblxuICAgIHRoaXMuc2V0Qnl0ZXMoZGF0YSwgZm9ybWF0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYWNrZXRcbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIGJlIGluc2VydGVkIGFzIGJvZHlcbiAgICogQHJldHVybiB7U3RyaW5nfSBzdHJpbmctcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhY2tldFxuICAgKi9cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBmaWxlbmFtZSA9IHV0aWwuZW5jb2RlX3V0ZjgoXCJtc2cudHh0XCIpO1xuXG4gICAgdmFyIGRhdGEgPSB0aGlzLmdldEJ5dGVzKCk7XG5cbiAgICB2YXIgcmVzdWx0ID0gJyc7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMubGl0ZXJhbCwgdGhpcy5mb3JtYXQpKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShmaWxlbmFtZS5sZW5ndGgpO1xuICAgIHJlc3VsdCArPSBmaWxlbmFtZTtcbiAgICByZXN1bHQgKz0gdXRpbC53cml0ZURhdGUodGhpcy5kYXRlKTtcbiAgICByZXN1bHQgKz0gZGF0YTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgc3RyYW5nZSBcIk1hcmtlciBwYWNrZXRcIiAoVGFnIDEwKVxuICogXG4gKiBSRkM0ODgwIDUuODogQW4gZXhwZXJpbWVudGFsIHZlcnNpb24gb2YgUEdQIHVzZWQgdGhpcyBwYWNrZXQgYXMgdGhlIExpdGVyYWxcbiAqIHBhY2tldCwgYnV0IG5vIHJlbGVhc2VkIHZlcnNpb24gb2YgUEdQIGdlbmVyYXRlZCBMaXRlcmFsIHBhY2tldHMgd2l0aCB0aGlzXG4gKiB0YWcuIFdpdGggUEdQIDUueCwgdGhpcyBwYWNrZXQgaGFzIGJlZW4gcmVhc3NpZ25lZCBhbmQgaXMgcmVzZXJ2ZWQgZm9yIHVzZSBhc1xuICogdGhlIE1hcmtlciBwYWNrZXQuXG4gKiBcbiAqIFN1Y2ggYSBwYWNrZXQgTVVTVCBiZSBpZ25vcmVkIHdoZW4gcmVjZWl2ZWQuXG4gKi9cbmZ1bmN0aW9uIHBhY2tldF9tYXJrZXIoKSB7XG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgKHRhZyAxMCkuXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxMCBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvblxuICAgKiAgICAgICAgICAgIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuXG4gICAqICAgICAgICAgICAgTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2ZcbiAgICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBPYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgaWYgKGJ5dGVzLmNoYXJDb2RlQXQoMCkgPT0gMHg1MCAmJiAvLyBQXG4gICAgYnl0ZXMuY2hhckNvZGVBdCgxKSA9PSAweDQ3ICYmIC8vIEdcbiAgICBieXRlcy5jaGFyQ29kZUF0KDIpID09IDB4NTApIC8vIFBcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIC8vIG1hcmtlciBwYWNrZXQgZG9lcyBub3QgY29udGFpbiBcIlBHUFwiXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcGFja2V0X21hcmtlcjtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBPbmUtUGFzcyBTaWduYXR1cmUgUGFja2V0cyAoVGFnIDQpXG4gKiBcbiAqIFJGQzQ4ODAgNS40OlxuICogVGhlIE9uZS1QYXNzIFNpZ25hdHVyZSBwYWNrZXQgcHJlY2VkZXMgdGhlIHNpZ25lZCBkYXRhIGFuZCBjb250YWluc1xuICogZW5vdWdoIGluZm9ybWF0aW9uIHRvIGFsbG93IHRoZSByZWNlaXZlciB0byBiZWdpbiBjYWxjdWxhdGluZyBhbnlcbiAqIGhhc2hlcyBuZWVkZWQgdG8gdmVyaWZ5IHRoZSBzaWduYXR1cmUuICBJdCBhbGxvd3MgdGhlIFNpZ25hdHVyZVxuICogcGFja2V0IHRvIGJlIHBsYWNlZCBhdCB0aGUgZW5kIG9mIHRoZSBtZXNzYWdlLCBzbyB0aGF0IHRoZSBzaWduZXJcbiAqIGNhbiBjb21wdXRlIHRoZSBlbnRpcmUgc2lnbmVkIG1lc3NhZ2UgaW4gb25lIHBhc3MuXG4gKi9cblxudmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKSxcbiAgdHlwZV9rZXlpZCA9IHJlcXVpcmUoJy4uL3R5cGUva2V5aWQuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfb25lX3Bhc3Nfc2lnbmF0dXJlKCkge1xuICB0aGlzLnZlcnNpb24gPSBudWxsOyAvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gIFRoZSBjdXJyZW50IHZlcnNpb24gaXMgMy5cbiAgdGhpcy50eXBlID0gbnVsbDsgLy8gQSBvbmUtb2N0ZXQgc2lnbmF0dXJlIHR5cGUuICBTaWduYXR1cmUgdHlwZXMgYXJlIGRlc2NyaWJlZCBpbiBSRkM0ODgwIFNlY3Rpb24gNS4yLjEuXG4gIHRoaXMuaGFzaEFsZ29yaXRobSA9IG51bGw7IC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBoYXNoIGFsZ29yaXRobSB1c2VkLiAoU2VlIFJGQzQ4ODAgOS40KVxuICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IG51bGw7IC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBwdWJsaWMta2V5IGFsZ29yaXRobSB1c2VkLiAoU2VlIFJGQzQ4ODAgOS4xKVxuICB0aGlzLnNpZ25pbmdLZXlJZCA9IG51bGw7IC8vIEFuIGVpZ2h0LW9jdGV0IG51bWJlciBob2xkaW5nIHRoZSBLZXkgSUQgb2YgdGhlIHNpZ25pbmcga2V5LlxuICB0aGlzLmZsYWdzID0gbnVsbDsgLy8gIEEgb25lLW9jdGV0IG51bWJlciBob2xkaW5nIGEgZmxhZyBzaG93aW5nIHdoZXRoZXIgdGhlIHNpZ25hdHVyZSBpcyBuZXN0ZWQuICBBIHplcm8gdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcGFja2V0IGlzIGFub3RoZXIgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCB0aGF0IGRlc2NyaWJlcyBhbm90aGVyIHNpZ25hdHVyZSB0byBiZSBhcHBsaWVkIHRvIHRoZSBzYW1lIG1lc3NhZ2UgZGF0YS5cblxuICAvKipcbiAgICogcGFyc2luZyBmdW5jdGlvbiBmb3IgYSBvbmUtcGFzcyBzaWduYXR1cmUgcGFja2V0ICh0YWcgNCkuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBwYXlsb2FkIG9mIGEgdGFnIDQgcGFja2V0XG4gICAqIEByZXR1cm4ge3BhY2tldF9vbmVfcGFzc19zaWduYXR1cmV9IG9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgbXlwb3MgPSAwO1xuICAgIC8vIEEgb25lLW9jdGV0IHZlcnNpb24gbnVtYmVyLiAgVGhlIGN1cnJlbnQgdmVyc2lvbiBpcyAzLlxuICAgIHRoaXMudmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBzaWduYXR1cmUgdHlwZS4gIFNpZ25hdHVyZSB0eXBlcyBhcmUgZGVzY3JpYmVkIGluXG4gICAgLy8gICBTZWN0aW9uIDUuMi4xLlxuICAgIHRoaXMudHlwZSA9IGVudW1zLnJlYWQoZW51bXMuc2lnbmF0dXJlLCBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspKTtcblxuICAgIC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBoYXNoIGFsZ29yaXRobSB1c2VkLlxuICAgIHRoaXMuaGFzaEFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMuaGFzaCwgYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKSk7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgcHVibGljLWtleSBhbGdvcml0aG0gdXNlZC5cbiAgICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspKTtcblxuICAgIC8vIEFuIGVpZ2h0LW9jdGV0IG51bWJlciBob2xkaW5nIHRoZSBLZXkgSUQgb2YgdGhlIHNpZ25pbmcga2V5LlxuICAgIHRoaXMuc2lnbmluZ0tleUlkID0gbmV3IHR5cGVfa2V5aWQoKTtcbiAgICB0aGlzLnNpZ25pbmdLZXlJZC5yZWFkKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgIG15cG9zICs9IDg7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgaG9sZGluZyBhIGZsYWcgc2hvd2luZyB3aGV0aGVyIHRoZSBzaWduYXR1cmVcbiAgICAvLyAgIGlzIG5lc3RlZC4gIEEgemVybyB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCB0aGUgbmV4dCBwYWNrZXQgaXNcbiAgICAvLyAgIGFub3RoZXIgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCB0aGF0IGRlc2NyaWJlcyBhbm90aGVyXG4gICAgLy8gICBzaWduYXR1cmUgdG8gYmUgYXBwbGllZCB0byB0aGUgc2FtZSBtZXNzYWdlIGRhdGEuXG4gICAgdGhpcy5mbGFncyA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogY3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIG9uZS1wYXNzIHNpZ25hdHVyZSBwYWNrZXRcbiAgICogQHJldHVybiB7U3RyaW5nfSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIG9uZS1wYXNzIHNpZ25hdHVyZSBwYWNrZXRcbiAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcblxuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDMpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnNpZ25hdHVyZSwgdGhpcy50eXBlKSk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMuaGFzaCwgdGhpcy5oYXNoQWxnb3JpdGhtKSk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMucHVibGljS2V5LCB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSkpO1xuICAgIHJlc3VsdCArPSB0aGlzLnNpZ25pbmdLZXlJZC53cml0ZSgpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZmxhZ3MpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJlYWRTaW1wbGVMZW5ndGg6IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIGxlbiA9IDAsXG4gICAgICBvZmZzZXQsXG4gICAgICB0eXBlID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcblxuXG4gICAgaWYgKHR5cGUgPCAxOTIpIHtcbiAgICAgIGxlbiA9IGJ5dGVzLmNoYXJDb2RlQXQoMCk7XG4gICAgICBvZmZzZXQgPSAxO1xuICAgIH0gZWxzZSBpZiAodHlwZSA8IDI1NSkge1xuICAgICAgbGVuID0gKChieXRlcy5jaGFyQ29kZUF0KDApIC0gMTkyKSA8PCA4KSArIChieXRlcy5jaGFyQ29kZUF0KDEpKSArIDE5MjtcbiAgICAgIG9mZnNldCA9IDI7XG4gICAgfSBlbHNlIGlmICh0eXBlID09IDI1NSkge1xuICAgICAgbGVuID0gdXRpbC5yZWFkTnVtYmVyKGJ5dGVzLnN1YnN0cigxLCA0KSk7XG4gICAgICBvZmZzZXQgPSA1O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBsZW46IGxlbixcbiAgICAgIG9mZnNldDogb2Zmc2V0XG4gICAgfTtcbiAgfSxcblxuICAvKipcbiAgICogRW5jb2RlcyBhIGdpdmVuIGludGVnZXIgb2YgbGVuZ3RoIHRvIHRoZSBvcGVucGdwIGxlbmd0aCBzcGVjaWZpZXIgdG8gYVxuICAgKiBzdHJpbmdcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIFRoZSBsZW5ndGggdG8gZW5jb2RlXG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIHdpdGggb3BlbnBncCBsZW5ndGggcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHdyaXRlU2ltcGxlTGVuZ3RoOiBmdW5jdGlvbihsZW5ndGgpIHtcbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICBpZiAobGVuZ3RoIDwgMTkyKSB7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW5ndGgpO1xuICAgIH0gZWxzZSBpZiAobGVuZ3RoID4gMTkxICYmIGxlbmd0aCA8IDgzODQpIHtcbiAgICAgIC8qXG4gICAgICAgKiBsZXQgYSA9ICh0b3RhbCBkYXRhIHBhY2tldCBsZW5ndGgpIC0gMTkyIGxldCBiYyA9IHR3byBvY3RldFxuICAgICAgICogcmVwcmVzZW50YXRpb24gb2YgYSBsZXQgZCA9IGIgKyAxOTJcbiAgICAgICAqL1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChsZW5ndGggLSAxOTIpID4+IDgpICsgMTkyKTtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChsZW5ndGggLSAxOTIpICYgMHhGRik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDI1NSk7XG4gICAgICByZXN1bHQgKz0gdXRpbC53cml0ZU51bWJlcihsZW5ndGgsIDQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LFxuXG4gIC8qKlxuICAgKiBXcml0ZXMgYSBwYWNrZXQgaGVhZGVyIHZlcnNpb24gNCB3aXRoIHRoZSBnaXZlbiB0YWdfdHlwZSBhbmQgbGVuZ3RoIHRvIGFcbiAgICogc3RyaW5nXG4gICAqIFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRhZ190eXBlIFRhZyB0eXBlXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIExlbmd0aCBvZiB0aGUgcGF5bG9hZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyBvZiB0aGUgaGVhZGVyXG4gICAqL1xuICB3cml0ZUhlYWRlcjogZnVuY3Rpb24odGFnX3R5cGUsIGxlbmd0aCkge1xuICAgIC8qIHdlJ3JlIG9ubHkgZ2VuZXJhdGluZyB2NCBwYWNrZXQgaGVhZGVycyBoZXJlICovXG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHhDMCB8IHRhZ190eXBlKTtcbiAgICByZXN1bHQgKz0gdGhpcy53cml0ZVNpbXBsZUxlbmd0aChsZW5ndGgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHBhY2tldCBoZWFkZXIgVmVyc2lvbiAzIHdpdGggdGhlIGdpdmVuIHRhZ190eXBlIGFuZCBsZW5ndGggdG8gYVxuICAgKiBzdHJpbmdcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gdGFnX3R5cGUgVGFnIHR5cGVcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIG9mIHRoZSBwYXlsb2FkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIG9mIHRoZSBoZWFkZXJcbiAgICovXG4gIHdyaXRlT2xkSGVhZGVyOiBmdW5jdGlvbih0YWdfdHlwZSwgbGVuZ3RoKSB7XG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgaWYgKGxlbmd0aCA8IDI1Nikge1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg4MCB8ICh0YWdfdHlwZSA8PCAyKSk7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW5ndGgpO1xuICAgIH0gZWxzZSBpZiAobGVuZ3RoIDwgNjU1MzYpIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ODAgfCAodGFnX3R5cGUgPDwgMikgfCAxKTtcbiAgICAgIHJlc3VsdCArPSB1dGlsLndyaXRlTnVtYmVyKGxlbmd0aCwgMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ODAgfCAodGFnX3R5cGUgPDwgMikgfCAyKTtcbiAgICAgIHJlc3VsdCArPSB1dGlsLndyaXRlTnVtYmVyKGxlbmd0aCwgNCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdlbmVyaWMgc3RhdGljIFBhY2tldCBQYXJzZXIgZnVuY3Rpb25cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCBzdHJlYW0gYXMgc3RyaW5nXG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcGFyc2luZ1xuICAgKiBAcGFyYW0ge2ludGVnZXJ9IGxlbiBMZW5ndGggb2YgdGhlIGlucHV0IGZyb20gcG9zaXRpb24gb25cbiAgICogQHJldHVybiB7T2JqZWN0fSBSZXR1cm5zIGEgcGFyc2VkIG9wZW5wZ3BfcGFja2V0XG4gICAqL1xuICByZWFkOiBmdW5jdGlvbihpbnB1dCwgcG9zaXRpb24sIGxlbikge1xuICAgIC8vIHNvbWUgc2FuaXR5IGNoZWNrc1xuICAgIGlmIChpbnB1dCA9PSBudWxsIHx8IGlucHV0Lmxlbmd0aCA8PSBwb3NpdGlvbiB8fCBpbnB1dC5zdWJzdHJpbmcocG9zaXRpb24pLmxlbmd0aCA8IDIgfHwgKGlucHV0LmNoYXJDb2RlQXQocG9zaXRpb24pICZcbiAgICAgIDB4ODApID09IDApIHtcbiAgICAgIHV0aWxcbiAgICAgICAgLnByaW50X2Vycm9yKFwiRXJyb3IgZHVyaW5nIHBhcnNpbmcuIFRoaXMgbWVzc2FnZSAvIGtleSBpcyBwcm9iYWJseSBub3QgY29udGFpbmluZyBhIHZhbGlkIE9wZW5QR1AgZm9ybWF0LlwiKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgbXlwb3MgPSBwb3NpdGlvbjtcbiAgICB2YXIgdGFnID0gLTE7XG4gICAgdmFyIGZvcm1hdCA9IC0xO1xuICAgIHZhciBwYWNrZXRfbGVuZ3RoO1xuXG4gICAgZm9ybWF0ID0gMDsgLy8gMCA9IG9sZCBmb3JtYXQ7IDEgPSBuZXcgZm9ybWF0XG4gICAgaWYgKChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSAmIDB4NDApICE9IDApIHtcbiAgICAgIGZvcm1hdCA9IDE7XG4gICAgfVxuXG4gICAgdmFyIHBhY2tldF9sZW5ndGhfdHlwZTtcbiAgICBpZiAoZm9ybWF0KSB7XG4gICAgICAvLyBuZXcgZm9ybWF0IGhlYWRlclxuICAgICAgdGFnID0gaW5wdXQuY2hhckNvZGVBdChteXBvcykgJiAweDNGOyAvLyBiaXQgNS0wXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG9sZCBmb3JtYXQgaGVhZGVyXG4gICAgICB0YWcgPSAoaW5wdXQuY2hhckNvZGVBdChteXBvcykgJiAweDNGKSA+PiAyOyAvLyBiaXQgNS0yXG4gICAgICBwYWNrZXRfbGVuZ3RoX3R5cGUgPSBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSAmIDB4MDM7IC8vIGJpdCAxLTBcbiAgICB9XG5cbiAgICAvLyBoZWFkZXIgb2N0ZXQgcGFyc2luZyBkb25lXG4gICAgbXlwb3MrKztcblxuICAgIC8vIHBhcnNlZCBsZW5ndGggZnJvbSBsZW5ndGggZmllbGRcbiAgICB2YXIgYm9keWRhdGEgPSBudWxsO1xuXG4gICAgLy8gdXNlZCBmb3IgcGFydGlhbCBib2R5IGxlbmd0aHNcbiAgICB2YXIgcmVhbF9wYWNrZXRfbGVuZ3RoID0gLTE7XG4gICAgaWYgKCFmb3JtYXQpIHtcbiAgICAgIC8vIDQuMi4xLiBPbGQgRm9ybWF0IFBhY2tldCBMZW5ndGhzXG4gICAgICBzd2l0Y2ggKHBhY2tldF9sZW5ndGhfdHlwZSkge1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgLy8gVGhlIHBhY2tldCBoYXMgYSBvbmUtb2N0ZXQgbGVuZ3RoLiBUaGUgaGVhZGVyIGlzIDIgb2N0ZXRzXG4gICAgICAgICAgLy8gbG9uZy5cbiAgICAgICAgICBwYWNrZXRfbGVuZ3RoID0gaW5wdXQuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIC8vIFRoZSBwYWNrZXQgaGFzIGEgdHdvLW9jdGV0IGxlbmd0aC4gVGhlIGhlYWRlciBpcyAzIG9jdGV0c1xuICAgICAgICAgIC8vIGxvbmcuXG4gICAgICAgICAgcGFja2V0X2xlbmd0aCA9IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspIDw8IDgpIHwgaW5wdXQuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIC8vIFRoZSBwYWNrZXQgaGFzIGEgZm91ci1vY3RldCBsZW5ndGguIFRoZSBoZWFkZXIgaXMgNVxuICAgICAgICAgIC8vIG9jdGV0cyBsb25nLlxuICAgICAgICAgIHBhY2tldF9sZW5ndGggPSAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSA8PCAyNCkgfCAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSA8PCAxNikgfCAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSA8PFxuICAgICAgICAgICAgOCkgfCBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8vIDMgLSBUaGUgcGFja2V0IGlzIG9mIGluZGV0ZXJtaW5hdGUgbGVuZ3RoLiBUaGUgaGVhZGVyIGlzIDFcbiAgICAgICAgICAvLyBvY3RldCBsb25nLCBhbmQgdGhlIGltcGxlbWVudGF0aW9uIG11c3QgZGV0ZXJtaW5lIGhvdyBsb25nXG4gICAgICAgICAgLy8gdGhlIHBhY2tldCBpcy4gSWYgdGhlIHBhY2tldCBpcyBpbiBhIGZpbGUsIHRoaXMgbWVhbnMgdGhhdFxuICAgICAgICAgIC8vIHRoZSBwYWNrZXQgZXh0ZW5kcyB1bnRpbCB0aGUgZW5kIG9mIHRoZSBmaWxlLiBJbiBnZW5lcmFsLCBcbiAgICAgICAgICAvLyBhbiBpbXBsZW1lbnRhdGlvbiBTSE9VTEQgTk9UIHVzZSBpbmRldGVybWluYXRlLWxlbmd0aCBcbiAgICAgICAgICAvLyBwYWNrZXRzIGV4Y2VwdCB3aGVyZSB0aGUgZW5kIG9mIHRoZSBkYXRhIHdpbGwgYmUgY2xlYXIgXG4gICAgICAgICAgLy8gZnJvbSB0aGUgY29udGV4dCwgYW5kIGV2ZW4gdGhlbiBpdCBpcyBiZXR0ZXIgdG8gdXNlIGEgXG4gICAgICAgICAgLy8gZGVmaW5pdGUgbGVuZ3RoLCBvciBhIG5ldyBmb3JtYXQgaGVhZGVyLiBUaGUgbmV3IGZvcm1hdCBcbiAgICAgICAgICAvLyBoZWFkZXJzIGRlc2NyaWJlZCBiZWxvdyBoYXZlIGEgbWVjaGFuaXNtIGZvciBwcmVjaXNlbHlcbiAgICAgICAgICAvLyBlbmNvZGluZyBkYXRhIG9mIGluZGV0ZXJtaW5hdGUgbGVuZ3RoLlxuICAgICAgICAgIHBhY2tldF9sZW5ndGggPSBsZW47XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgLy8gNC4yLjIuIE5ldyBGb3JtYXQgUGFja2V0IExlbmd0aHNcbiAgICB7XG5cbiAgICAgIC8vIDQuMi4yLjEuIE9uZS1PY3RldCBMZW5ndGhzXG4gICAgICBpZiAoaW5wdXQuY2hhckNvZGVBdChteXBvcykgPCAxOTIpIHtcbiAgICAgICAgcGFja2V0X2xlbmd0aCA9IGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCIxIGJ5dGUgbGVuZ3RoOlwiICsgcGFja2V0X2xlbmd0aCk7XG4gICAgICAgIC8vIDQuMi4yLjIuIFR3by1PY3RldCBMZW5ndGhzXG4gICAgICB9IGVsc2UgaWYgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MpID49IDE5MiAmJiBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSA8IDIyNCkge1xuICAgICAgICBwYWNrZXRfbGVuZ3RoID0gKChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspIC0gMTkyKSA8PCA4KSArIChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspKSArIDE5MjtcbiAgICAgICAgdXRpbC5wcmludF9kZWJ1ZyhcIjIgYnl0ZSBsZW5ndGg6XCIgKyBwYWNrZXRfbGVuZ3RoKTtcbiAgICAgICAgLy8gNC4yLjIuNC4gUGFydGlhbCBCb2R5IExlbmd0aHNcbiAgICAgIH0gZWxzZSBpZiAoaW5wdXQuY2hhckNvZGVBdChteXBvcykgPiAyMjMgJiYgaW5wdXQuY2hhckNvZGVBdChteXBvcykgPCAyNTUpIHtcbiAgICAgICAgcGFja2V0X2xlbmd0aCA9IDEgPDwgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgJiAweDFGKTtcbiAgICAgICAgdXRpbC5wcmludF9kZWJ1ZyhcIjQgYnl0ZSBsZW5ndGg6XCIgKyBwYWNrZXRfbGVuZ3RoKTtcbiAgICAgICAgLy8gRUVFSywgd2UncmUgcmVhZGluZyB0aGUgZnVsbCBkYXRhIGhlcmUuLi5cbiAgICAgICAgdmFyIG15cG9zMiA9IG15cG9zICsgcGFja2V0X2xlbmd0aDtcbiAgICAgICAgYm9keWRhdGEgPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MsIG15cG9zICsgcGFja2V0X2xlbmd0aCk7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgaWYgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKSA8IDE5Mikge1xuICAgICAgICAgICAgdmFyIHRtcGxlbiA9IGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKyspO1xuICAgICAgICAgICAgcGFja2V0X2xlbmd0aCArPSB0bXBsZW47XG4gICAgICAgICAgICBib2R5ZGF0YSArPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MyLCBteXBvczIgKyB0bXBsZW4pO1xuICAgICAgICAgICAgbXlwb3MyICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaW5wdXQuY2hhckNvZGVBdChteXBvczIpID49IDE5MiAmJiBpbnB1dC5jaGFyQ29kZUF0KG15cG9zMikgPCAyMjQpIHtcbiAgICAgICAgICAgIHZhciB0bXBsZW4gPSAoKGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKyspIC0gMTkyKSA8PCA4KSArIChpbnB1dC5jaGFyQ29kZUF0KG15cG9zMisrKSkgKyAxOTI7XG4gICAgICAgICAgICBwYWNrZXRfbGVuZ3RoICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJvZHlkYXRhICs9IGlucHV0LnN1YnN0cmluZyhteXBvczIsIG15cG9zMiArIHRtcGxlbik7XG4gICAgICAgICAgICBteXBvczIgKz0gdG1wbGVuO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfSBlbHNlIGlmIChpbnB1dC5jaGFyQ29kZUF0KG15cG9zMikgPiAyMjMgJiYgaW5wdXQuY2hhckNvZGVBdChteXBvczIpIDwgMjU1KSB7XG4gICAgICAgICAgICB2YXIgdG1wbGVuID0gMSA8PCAoaW5wdXQuY2hhckNvZGVBdChteXBvczIrKykgJiAweDFGKTtcbiAgICAgICAgICAgIHBhY2tldF9sZW5ndGggKz0gdG1wbGVuO1xuICAgICAgICAgICAgYm9keWRhdGEgKz0gaW5wdXQuc3Vic3RyaW5nKG15cG9zMiwgbXlwb3MyICsgdG1wbGVuKTtcbiAgICAgICAgICAgIG15cG9zMiArPSB0bXBsZW47XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG15cG9zMisrO1xuICAgICAgICAgICAgdmFyIHRtcGxlbiA9IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zMisrKSA8PCAyNCkgfCAoaW5wdXQuY2hhckNvZGVBdChteXBvczIrKykgPDwgMTYpIHwgKGlucHV0W215cG9zMisrXVxuICAgICAgICAgICAgICAuY2hhckNvZGVBdCgpIDw8IDgpIHwgaW5wdXQuY2hhckNvZGVBdChteXBvczIrKyk7XG4gICAgICAgICAgICBib2R5ZGF0YSArPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MyLCBteXBvczIgKyB0bXBsZW4pO1xuICAgICAgICAgICAgcGFja2V0X2xlbmd0aCArPSB0bXBsZW47XG4gICAgICAgICAgICBteXBvczIgKz0gdG1wbGVuO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJlYWxfcGFja2V0X2xlbmd0aCA9IG15cG9zMjtcbiAgICAgICAgLy8gNC4yLjIuMy4gRml2ZS1PY3RldCBMZW5ndGhzXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBteXBvcysrO1xuICAgICAgICBwYWNrZXRfbGVuZ3RoID0gKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgPDwgMjQpIHwgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgPDwgMTYpIHwgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgPDxcbiAgICAgICAgICA4KSB8IGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gaWYgdGhlcmUgd2FzJ250IGEgcGFydGlhbCBib2R5IGxlbmd0aDogdXNlIHRoZSBzcGVjaWZpZWRcbiAgICAvLyBwYWNrZXRfbGVuZ3RoXG4gICAgaWYgKHJlYWxfcGFja2V0X2xlbmd0aCA9PSAtMSkge1xuICAgICAgcmVhbF9wYWNrZXRfbGVuZ3RoID0gcGFja2V0X2xlbmd0aDtcbiAgICB9XG5cbiAgICBpZiAoYm9keWRhdGEgPT0gbnVsbCkge1xuICAgICAgYm9keWRhdGEgPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MsIG15cG9zICsgcmVhbF9wYWNrZXRfbGVuZ3RoKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdGFnOiB0YWcsXG4gICAgICBwYWNrZXQ6IGJvZHlkYXRhLFxuICAgICAgb2Zmc2V0OiBteXBvcyArIHJlYWxfcGFja2V0X2xlbmd0aFxuICAgIH07XG4gIH1cbn1cbiIsInZhciBwYWNrZXRQYXJzZXIgPSByZXF1aXJlKCcuL3BhY2tldC5qcycpLFxuICBwYWNrZXRzID0gcmVxdWlyZSgnLi9hbGxfcGFja2V0cy5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIGxpc3Qgb2Ygb3BlbnBncCBwYWNrZXRzLlxuICogVGFrZSBjYXJlIHdoZW4gaXRlcmF0aW5nIG92ZXIgaXQgLSB0aGUgcGFja2V0cyB0aGVtc2VsdmVzXG4gKiBhcmUgc3RvcmVkIGFzIG51bWVyaWNhbCBpbmRpY2VzLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldGxpc3QoKSB7XG4gIC8qKiBUaGUgbnVtYmVyIG9mIHBhY2tldHMgY29udGFpbmVkIHdpdGhpbiB0aGUgbGlzdC5cbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtJbnRlZ2VyfSAqL1xuICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgLyoqXG4gICAqIFJlYWRzIGEgc3RyZWFtIG9mIGJpbmFyeSBkYXRhIGFuZCBpbnRlcnByZW50cyBpdCBhcyBhIGxpc3Qgb2YgcGFja2V0cy5cbiAgICogQHBhcmFtIHtvcGVucGdwX2J5dGVhcnJheX0gQW4gYXJyYXkgb2YgYnl0ZXMuXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBpID0gMDtcblxuICAgIHdoaWxlIChpIDwgYnl0ZXMubGVuZ3RoKSB7XG4gICAgICB2YXIgcGFyc2VkID0gcGFja2V0UGFyc2VyLnJlYWQoYnl0ZXMsIGksIGJ5dGVzLmxlbmd0aCAtIGkpO1xuICAgICAgaSA9IHBhcnNlZC5vZmZzZXQ7XG5cbiAgICAgIHZhciB0YWcgPSBlbnVtcy5yZWFkKGVudW1zLnBhY2tldCwgcGFyc2VkLnRhZyk7XG4gICAgICB2YXIgcGFja2V0ID0gbmV3IHBhY2tldHNbdGFnXSgpO1xuXG4gICAgICB0aGlzLnB1c2gocGFja2V0KTtcblxuICAgICAgcGFja2V0LnJlYWQocGFyc2VkLnBhY2tldCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBiaW5hcnkgcmVwcmVzZW50YXRpb24gb2Ygb3BlbnBncCBvYmplY3RzIGNvbnRhaW5lZCB3aXRoaW4gdGhlXG4gICAqIGNsYXNzIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7b3BlbnBncF9ieXRlYXJyYXl9IEFuIGFycmF5IG9mIGJ5dGVzIGNvbnRhaW5pbmcgdmFsaWQgb3BlbnBncCBwYWNrZXRzLlxuICAgKi9cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBieXRlcyA9ICcnO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcGFja2V0Ynl0ZXMgPSB0aGlzW2ldLndyaXRlKCk7XG4gICAgICBieXRlcyArPSBwYWNrZXRQYXJzZXIud3JpdGVIZWFkZXIodGhpc1tpXS50YWcsIHBhY2tldGJ5dGVzLmxlbmd0aCk7XG4gICAgICBieXRlcyArPSBwYWNrZXRieXRlcztcbiAgICB9XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHBhY2tldCB0byB0aGUgbGlzdC4gVGhpcyBpcyB0aGUgb25seSBzdXBwb3J0ZWQgbWV0aG9kIG9mIGRvaW5nIHNvO1xuICAgKiB3cml0aW5nIHRvIHBhY2tldGxpc3RbaV0gZGlyZWN0bHkgd2lsbCByZXN1bHQgaW4gYW4gZXJyb3IuXG4gICAqL1xuICB0aGlzLnB1c2ggPSBmdW5jdGlvbihwYWNrZXQpIHtcbiAgICBwYWNrZXQucGFja2V0cyA9IHBhY2tldC5wYWNrZXRzIHx8IG5ldyBwYWNrZXRsaXN0KCk7XG5cbiAgICB0aGlzW3RoaXMubGVuZ3RoXSA9IHBhY2tldDtcbiAgICB0aGlzLmxlbmd0aCsrO1xuICB9XG5cbiAgLyoqXG4gICogQ3JlYXRlcyBhIG5ldyBwYWNrZXRMaXN0IHdpdGggYWxsIHBhY2tldHMgdGhhdCBwYXNzIHRoZSB0ZXN0IGltcGxlbWVudGVkIGJ5IHRoZSBwcm92aWRlZCBmdW5jdGlvbi5cbiAgKi9cbiAgdGhpcy5maWx0ZXIgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuXG4gICAgdmFyIGZpbHRlcmVkID0gbmV3IHBhY2tldGxpc3QoKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGNhbGxiYWNrKHRoaXNbaV0sIGksIHRoaXMpKSB7XG4gICAgICAgIGZpbHRlcmVkLnB1c2godGhpc1tpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbHRlcmVkO1xuICB9XG5cbiAgLyoqXG4gICogQ3JlYXRlcyBhIG5ldyBwYWNrZXRMaXN0IHdpdGggYWxsIHBhY2tldHMgZnJvbSB0aGUgZ2l2ZW4gdHlwZXNcbiAgKi9cbiAgdGhpcy5maWx0ZXJCeVRhZyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICB2YXIgZmlsdGVyZWQgPSBuZXcgcGFja2V0bGlzdCgpO1xuICAgIHZhciB0aGF0ID0gdGhpcztcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFyZ3Muc29tZShmdW5jdGlvbihwYWNrZXRUeXBlKSB7cmV0dXJuIHRoYXRbaV0udGFnID09IHBhY2tldFR5cGV9KSkge1xuICAgICAgICBmaWx0ZXJlZC5wdXNoKHRoaXNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXJlZDtcbiAgfSBcblxuICAvKipcbiAgKiBFeGVjdXRlcyB0aGUgcHJvdmlkZWQgY2FsbGJhY2sgb25jZSBmb3IgZWFjaCBlbGVtZW50XG4gICovXG4gIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjYWxsYmFjayh0aGlzW2ldKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVHJhdmVyc2VzIHBhY2tldCB0cmVlIGFuZCByZXR1cm5zIGZpcnN0IG1hdGNoaW5nIHBhY2tldFxuICAgKiBAcGFyYW0gIHtlbnVtcy5wYWNrZXR9IHR5cGUgVGhlIHBhY2tldCB0eXBlXG4gICAqIEByZXR1cm4ge3BhY2tldHxudWxsfSAgICAgIFxuICAgKi9cbiAgdGhpcy5maW5kUGFja2V0ID0gZnVuY3Rpb24odHlwZSkge1xuICAgIHZhciBwYWNrZXRsaXN0ID0gdGhpcy5maWx0ZXJCeVRhZyh0eXBlKTtcbiAgICBpZiAocGFja2V0bGlzdC5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBwYWNrZXRsaXN0WzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZm91bmQgPSBudWxsO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzW2ldLnBhY2tldHMubGVuZ3RoKSB7XG4gICAgICAgICAgZm91bmQgPSB0aGlzW2ldLnBhY2tldHMuZmluZFBhY2tldCh0eXBlKTtcbiAgICAgICAgICBpZiAoZm91bmQpIHJldHVybiBmb3VuZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpLFxuICB0eXBlX2tleWlkID0gcmVxdWlyZSgnLi4vdHlwZS9rZXlpZC5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgS2V5IE1hdGVyaWFsIFBhY2tldCAoVGFnIDUsNiw3LDE0KVxuICogICBcbiAqIFJGQzQ0ODAgNS41OlxuICogQSBrZXkgbWF0ZXJpYWwgcGFja2V0IGNvbnRhaW5zIGFsbCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgYSBwdWJsaWMgb3JcbiAqIHByaXZhdGUga2V5LiAgVGhlcmUgYXJlIGZvdXIgdmFyaWFudHMgb2YgdGhpcyBwYWNrZXQgdHlwZSwgYW5kIHR3b1xuICogbWFqb3IgdmVyc2lvbnMuICBDb25zZXF1ZW50bHksIHRoaXMgc2VjdGlvbiBpcyBjb21wbGV4LlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9wdWJsaWNfa2V5KCkge1xuICAvKiogS2V5IGNyZWF0aW9uIGRhdGUuXG4gICAqIEB0eXBlIHtEYXRlfSAqL1xuICB0aGlzLmNyZWF0ZWQgPSBuZXcgRGF0ZSgpO1xuICAvKiogQSBsaXN0IG9mIG11bHRpcHJlY2lzaW9uIGludGVnZXJzXG4gICAqIEB0eXBlIHtvcGVucGdwX3R5cGVfbXBpfSAqL1xuICB0aGlzLm1waSA9IFtdO1xuICAvKiogUHVibGljIGtleSBhbGdvcml0aG1cbiAgICogQHR5cGUge29wZW5wZ3AucHVibGlja2V5fSAqL1xuICB0aGlzLmFsZ29yaXRobSA9ICdyc2Ffc2lnbic7XG5cblxuICAvKipcbiAgICogSW50ZXJuYWwgUGFyc2VyIGZvciBwdWJsaWMga2V5cyBhcyBzcGVjaWZpZWQgaW4gUkZDIDQ4ODAgc2VjdGlvbiBcbiAgICogNS41LjIgUHVibGljLUtleSBQYWNrZXQgRm9ybWF0c1xuICAgKiBjYWxsZWQgYnkgcmVhZF90YWcmbHQ7bnVtJmd0O1xuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgSW5wdXQgc3RyaW5nIHRvIHJlYWQgdGhlIHBhY2tldCBmcm9tXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gU3RhcnQgcG9zaXRpb24gZm9yIHRoZSBwYXJzZXJcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoaXMgb2JqZWN0IHdpdGggYXR0cmlidXRlcyBzZXQgYnkgdGhlIHBhcnNlclxuICAgKi9cbiAgdGhpcy5yZWFkUHVibGljS2V5ID0gdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlciAoMyBvciA0KS5cbiAgICB2YXIgdmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQoMCk7XG5cbiAgICBpZiAodmVyc2lvbiA9PSA0KSB7XG4gICAgICAvLyAtIEEgZm91ci1vY3RldCBudW1iZXIgZGVub3RpbmcgdGhlIHRpbWUgdGhhdCB0aGUga2V5IHdhcyBjcmVhdGVkLlxuICAgICAgdGhpcy5jcmVhdGVkID0gdXRpbC5yZWFkRGF0ZShieXRlcy5zdWJzdHIoMSwgNCkpO1xuXG4gICAgICAvLyAtIEEgb25lLW9jdGV0IG51bWJlciBkZW5vdGluZyB0aGUgcHVibGljLWtleSBhbGdvcml0aG0gb2YgdGhpcyBrZXkuXG4gICAgICB0aGlzLmFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBieXRlcy5jaGFyQ29kZUF0KDUpKTtcblxuICAgICAgdmFyIG1waWNvdW50ID0gY3J5cHRvLmdldFB1YmxpY01waUNvdW50KHRoaXMuYWxnb3JpdGhtKTtcbiAgICAgIHRoaXMubXBpID0gW107XG5cbiAgICAgIHZhciBibXBpID0gYnl0ZXMuc3Vic3RyKDYpO1xuICAgICAgdmFyIHAgPSAwO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1waWNvdW50ICYmIHAgPCBibXBpLmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgdGhpcy5tcGlbaV0gPSBuZXcgdHlwZV9tcGkoKTtcblxuICAgICAgICBwICs9IHRoaXMubXBpW2ldLnJlYWQoYm1waS5zdWJzdHIocCkpXG5cbiAgICAgICAgaWYgKHAgPiBibXBpLmxlbmd0aClcbiAgICAgICAgICB1dGlsLnByaW50X2Vycm9yKFwib3BlbnBncC5wYWNrZXQua2V5bWF0ZXJpYWwuanNcXG5cIiArICdlcnJvciByZWFkaW5nIE1QSSBAOicgKyBwKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHAgKyA2O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZlcnNpb24gJyArIHZlcnNpb24gKyAnIG9mIHRoZSBrZXkgcGFja2V0IGlzIHVuc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICAqIFNhbWUgYXMgd3JpdGVfcHJpdmF0ZV9rZXksIGJ1dCBoYXMgbGVzcyBpbmZvcm1hdGlvbiBiZWNhdXNlIG9mIFxuICAgKiBwdWJsaWMga2V5LlxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGtleVR5cGUgRm9sbG93cyB0aGUgT3BlblBHUCBhbGdvcml0aG0gc3RhbmRhcmQsIFxuICAgKiBJRSAxIGNvcnJlc3BvbmRzIHRvIFJTQS5cbiAgICogQHBhcmFtIHtSU0Eua2V5T2JqZWN0fSBrZXlcbiAgICogQHBhcmFtIHRpbWVQYWNrZXRcbiAgICogQHJldHVybiB7T2JqZWN0fSB7Ym9keTogW3N0cmluZ11PcGVuUEdQIHBhY2tldCBib2R5IGNvbnRlbnRzLCBcbiAgICogaGVhZGVyOiBbc3RyaW5nXSBPcGVuUEdQIHBhY2tldCBoZWFkZXIsIHN0cmluZzogW3N0cmluZ10gaGVhZGVyK2JvZHl9XG4gICAqL1xuICB0aGlzLndyaXRlUHVibGljS2V5ID0gdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIC8vIFZlcnNpb25cbiAgICB2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSg0KTtcbiAgICByZXN1bHQgKz0gdXRpbC53cml0ZURhdGUodGhpcy5jcmVhdGVkKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMuYWxnb3JpdGhtKSk7XG5cbiAgICB2YXIgbXBpY291bnQgPSBjcnlwdG8uZ2V0UHVibGljTXBpQ291bnQodGhpcy5hbGdvcml0aG0pO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtcGljb3VudDsgaSsrKSB7XG4gICAgICByZXN1bHQgKz0gdGhpcy5tcGlbaV0ud3JpdGUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gV3JpdGUgYW4gb2xkIHZlcnNpb24gcGFja2V0IC0gaXQncyB1c2VkIGJ5IHNvbWUgb2YgdGhlIGludGVybmFsIHJvdXRpbmVzLlxuICB0aGlzLndyaXRlT2xkID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy53cml0ZVB1YmxpY0tleSgpO1xuXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoMHg5OSkgK1xuICAgICAgdXRpbC53cml0ZU51bWJlcihieXRlcy5sZW5ndGgsIDIpICtcbiAgICAgIGJ5dGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIGtleSBpZCBvZiB0aGUga2V5IFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEEgOCBieXRlIGtleSBpZFxuICAgKi9cbiAgdGhpcy5nZXRLZXlJZCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBrZXlpZCA9IG5ldyB0eXBlX2tleWlkKCk7XG4gICAga2V5aWQucmVhZCh0aGlzLmdldEZpbmdlcnByaW50KCkuc3Vic3RyKDEyLCA4KSk7XG4gICAgcmV0dXJuIGtleWlkO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIGZpbmdlcnByaW50IG9mIHRoZSBrZXlcbiAgICogQHJldHVybiB7U3RyaW5nfSBBIHN0cmluZyBjb250YWluaW5nIHRoZSBmaW5nZXJwcmludFxuICAgKi9cbiAgdGhpcy5nZXRGaW5nZXJwcmludCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0b0hhc2ggPSB0aGlzLndyaXRlT2xkKCk7XG4gICAgcmV0dXJuIGNyeXB0by5oYXNoLnNoYTEodG9IYXNoLCB0b0hhc2gubGVuZ3RoKTtcbiAgfVxuXG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdHlwZV9rZXlpZCA9IHJlcXVpcmUoJy4uL3R5cGUva2V5aWQuanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IFBhY2tldHMgKFRhZyAxKVxuICogXG4gKiBSRkM0ODgwIDUuMTogQSBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXQgaG9sZHMgdGhlIHNlc3Npb24ga2V5XG4gKiB1c2VkIHRvIGVuY3J5cHQgYSBtZXNzYWdlLiBaZXJvIG9yIG1vcmUgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXlcbiAqIHBhY2tldHMgYW5kL29yIFN5bW1ldHJpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldHMgbWF5IHByZWNlZGUgYVxuICogU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQsIHdoaWNoIGhvbGRzIGFuIGVuY3J5cHRlZCBtZXNzYWdlLiBUaGVcbiAqIG1lc3NhZ2UgaXMgZW5jcnlwdGVkIHdpdGggdGhlIHNlc3Npb24ga2V5LCBhbmQgdGhlIHNlc3Npb24ga2V5IGlzIGl0c2VsZlxuICogZW5jcnlwdGVkIGFuZCBzdG9yZWQgaW4gdGhlIEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXQocykuIFRoZVxuICogU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQgaXMgcHJlY2VkZWQgYnkgb25lIFB1YmxpYy1LZXkgRW5jcnlwdGVkXG4gKiBTZXNzaW9uIEtleSBwYWNrZXQgZm9yIGVhY2ggT3BlblBHUCBrZXkgdG8gd2hpY2ggdGhlIG1lc3NhZ2UgaXMgZW5jcnlwdGVkLlxuICogVGhlIHJlY2lwaWVudCBvZiB0aGUgbWVzc2FnZSBmaW5kcyBhIHNlc3Npb24ga2V5IHRoYXQgaXMgZW5jcnlwdGVkIHRvIHRoZWlyXG4gKiBwdWJsaWMga2V5LCBkZWNyeXB0cyB0aGUgc2Vzc2lvbiBrZXksIGFuZCB0aGVuIHVzZXMgdGhlIHNlc3Npb24ga2V5IHRvXG4gKiBkZWNyeXB0IHRoZSBtZXNzYWdlLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9wdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleSgpIHtcbiAgdGhpcy52ZXJzaW9uID0gMztcblxuICB0aGlzLnB1YmxpY0tleUlkID0gbmV3IHR5cGVfa2V5aWQoKTtcbiAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSAncnNhX2VuY3J5cHQnO1xuXG4gIHRoaXMuc2Vzc2lvbktleSA9IG51bGw7XG4gIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9ICdhZXMyNTYnO1xuXG4gIC8qKiBAdHlwZSB7b3BlbnBncF90eXBlX21waVtdfSAqL1xuICB0aGlzLmVuY3J5cHRlZCA9IFtdO1xuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHB1YmxpY2tleSBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXkgcGFja2V0ICh0YWcgMSkuXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxIHBhY2tldFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mXG4gICAqICAgICAgICAgICAgaW5wdXQgYXQgcG9zaXRpb25cbiAgICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YX0gT2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuXG4gICAgdGhpcy52ZXJzaW9uID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcbiAgICB0aGlzLnB1YmxpY0tleUlkLnJlYWQoYnl0ZXMuc3Vic3RyKDEpKTtcbiAgICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBieXRlcy5jaGFyQ29kZUF0KDkpKTtcblxuICAgIHZhciBpID0gMTA7XG5cbiAgICB2YXIgaW50ZWdlckNvdW50ID0gKGZ1bmN0aW9uKGFsZ28pIHtcbiAgICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgICBjYXNlICdyc2FfZW5jcnlwdCc6XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0X3NpZ24nOlxuICAgICAgICAgIHJldHVybiAxO1xuXG4gICAgICAgIGNhc2UgJ2VsZ2FtYWwnOlxuICAgICAgICAgIHJldHVybiAyO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBhbGdvcml0aG0uXCIpO1xuICAgICAgfVxuICAgIH0pKHRoaXMucHVibGljS2V5QWxnb3JpdGhtKTtcblxuICAgIHRoaXMuZW5jcnlwdGVkID0gW107XG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGludGVnZXJDb3VudDsgaisrKSB7XG4gICAgICB2YXIgbXBpID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgICBpICs9IG1waS5yZWFkKGJ5dGVzLnN1YnN0cihpKSk7XG4gICAgICB0aGlzLmVuY3J5cHRlZC5wdXNoKG1waSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHRhZyAxIHBhY2tldFxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IHB1YmxpY0tleUlkXG4gICAqICAgICAgICAgICAgIFRoZSBwdWJsaWMga2V5IGlkIGNvcnJlc3BvbmRpbmcgdG8gcHVibGljTVBJcyBrZXkgYXMgc3RyaW5nXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBwdWJsaWNNUElzXG4gICAqICAgICAgICAgICAgTXVsdGlwcmVjaXNpb24gaW50ZWdlciBvYmplY3RzIGRlc2NyaWJpbmcgdGhlIHB1YmxpYyBrZXlcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwdWJhbGdvXG4gICAqICAgICAgICAgICAgVGhlIGNvcnJlc3BvbmRpbmcgcHVibGljIGtleSBhbGdvcml0aG0gLy8gU2VlIFJGQzQ4ODAgOS4xXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gc3ltbWFsZ29cbiAgICogICAgICAgICAgICBUaGUgc3ltbWV0cmljIGNpcGhlciBhbGdvcml0aG0gdXNlZCB0byBlbmNyeXB0IHRoZSBkYXRhIFxuICAgKiAgICAgICAgICAgIHdpdGhpbiBhbiBlbmNyeXB0ZWRkYXRhcGFja2V0IG9yIGVuY3J5cHRlZGludGVncml0eS1cbiAgICogICAgICAgICAgICBwcm90ZWN0ZWRkYXRhcGFja2V0IFxuICAgKiAgICAgICAgICAgIGZvbGxvd2luZyB0aGlzIHBhY2tldCAvL1NlZSBSRkM0ODgwIDkuMlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc2Vzc2lvbmtleVxuICAgKiAgICAgICAgICAgIEEgc3RyaW5nIG9mIHJhbmRvbWJ5dGVzIHJlcHJlc2VudGluZyB0aGUgc2Vzc2lvbiBrZXlcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG5cbiAgICB2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnZlcnNpb24pO1xuICAgIHJlc3VsdCArPSB0aGlzLnB1YmxpY0tleUlkLndyaXRlKCk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICBlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMucHVibGljS2V5QWxnb3JpdGhtKSk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZW5jcnlwdGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHQgKz0gdGhpcy5lbmNyeXB0ZWRbaV0ud3JpdGUoKVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihrZXkpIHtcbiAgICB2YXIgZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICBlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSkpO1xuXG4gICAgZGF0YSArPSB0aGlzLnNlc3Npb25LZXk7XG4gICAgdmFyIGNoZWNrc3VtID0gdXRpbC5jYWxjX2NoZWNrc3VtKHRoaXMuc2Vzc2lvbktleSk7XG4gICAgZGF0YSArPSB1dGlsLndyaXRlTnVtYmVyKGNoZWNrc3VtLCAyKTtcblxuICAgIHZhciBtcGkgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICBtcGkuZnJvbUJ5dGVzKGNyeXB0by5wa2NzMS5lbWUuZW5jb2RlKFxuICAgICAgZGF0YSxcbiAgICAgIGtleS5tcGlbMF0uYnl0ZUxlbmd0aCgpKSk7XG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5wdWJsaWNLZXlFbmNyeXB0KFxuICAgICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0sXG4gICAgICBrZXkubXBpLFxuICAgICAgbXBpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNyeXB0cyB0aGUgc2Vzc2lvbiBrZXkgKG9ubHkgZm9yIHB1YmxpYyBrZXkgZW5jcnlwdGVkIHNlc3Npb24ga2V5XG4gICAqIHBhY2tldHMgKHRhZyAxKVxuICAgKiBcbiAgICogQHBhcmFtIHtvcGVucGdwX21zZ19tZXNzYWdlfSBtc2dcbiAgICogICAgICAgICAgICBUaGUgbWVzc2FnZSBvYmplY3QgKHdpdGggbWVtYmVyIGVuY3J5cHRlZERhdGFcbiAgICogQHBhcmFtIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBrZXlcbiAgICogICAgICAgICAgICBQcml2YXRlIGtleSB3aXRoIHNlY01QSXMgdW5sb2NrZWRcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgdW5lbmNyeXB0ZWQgc2Vzc2lvbiBrZXlcbiAgICovXG4gIHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciByZXN1bHQgPSBjcnlwdG8ucHVibGljS2V5RGVjcnlwdChcbiAgICAgIHRoaXMucHVibGljS2V5QWxnb3JpdGhtLFxuICAgICAga2V5Lm1waSxcbiAgICAgIHRoaXMuZW5jcnlwdGVkKS50b0J5dGVzKCk7XG5cbiAgICB2YXIgY2hlY2tzdW0gPSB1dGlsLnJlYWROdW1iZXIocmVzdWx0LnN1YnN0cihyZXN1bHQubGVuZ3RoIC0gMikpO1xuXG4gICAgdmFyIGRlY29kZWQgPSBjcnlwdG8ucGtjczEuZW1lLmRlY29kZShcbiAgICAgIHJlc3VsdCxcbiAgICAgIGtleS5tcGlbMF0uYnl0ZUxlbmd0aCgpKTtcblxuICAgIHZhciBrZXkgPSBkZWNvZGVkLnN1YnN0cmluZygxLCBkZWNvZGVkLmxlbmd0aCAtIDIpO1xuXG4gICAgaWYgKGNoZWNrc3VtICE9IHV0aWwuY2FsY19jaGVja3N1bShrZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NoZWNrc3VtIG1pc21hdGNoJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2Vzc2lvbktleSA9IGtleTtcbiAgICAgIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9XG4gICAgICAgIGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBkZWNvZGVkLmNoYXJDb2RlQXQoMCkpO1xuICAgIH1cbiAgfVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBwdWJsaWNfa2V5ID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5LmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcHVibGljX3N1YmtleSgpIHtcbiAgcHVibGljX2tleS5jYWxsKHRoaXMpO1xufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHB1YmxpY0tleSA9IHJlcXVpcmUoJy4vcHVibGljX2tleS5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpLFxuICB0eXBlX21waSA9IHJlcXVpcmUoJy4uL3R5cGUvbXBpLmpzJyksXG4gIHR5cGVfczJrID0gcmVxdWlyZSgnLi4vdHlwZS9zMmsuanMnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIEtleSBNYXRlcmlhbCBQYWNrZXQgKFRhZyA1LDYsNywxNClcbiAqICAgXG4gKiBSRkM0NDgwIDUuNTpcbiAqIEEga2V5IG1hdGVyaWFsIHBhY2tldCBjb250YWlucyBhbGwgdGhlIGluZm9ybWF0aW9uIGFib3V0IGEgcHVibGljIG9yXG4gKiBwcml2YXRlIGtleS4gIFRoZXJlIGFyZSBmb3VyIHZhcmlhbnRzIG9mIHRoaXMgcGFja2V0IHR5cGUsIGFuZCB0d29cbiAqIG1ham9yIHZlcnNpb25zLiAgQ29uc2VxdWVudGx5LCB0aGlzIHNlY3Rpb24gaXMgY29tcGxleC5cbiAqL1xuZnVuY3Rpb24gcGFja2V0X3NlY3JldF9rZXkoKSB7XG4gIHB1YmxpY0tleS5jYWxsKHRoaXMpO1xuICAvLyBlbmNyeXB0ZWQgc2VjcmV0LWtleSBkYXRhXG4gIHRoaXMuZW5jcnlwdGVkID0gbnVsbDtcbiAgLy8gaW5kaWNhdG9yIGlmIHNlY3JldC1rZXkgZGF0YSBpcyBhdmFpbGFibGUgaW4gZGVjcnlwdGVkIGZvcm1cbiAgdGhpcy5pc0RlY3J5cHRlZCA9IGZhbHNlO1xuXG5cbiAgZnVuY3Rpb24gZ2V0X2hhc2hfbGVuKGhhc2gpIHtcbiAgICBpZiAoaGFzaCA9PSAnc2hhMScpXG4gICAgICByZXR1cm4gMjA7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIDI7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRfaGFzaF9mbihoYXNoKSB7XG4gICAgaWYgKGhhc2ggPT0gJ3NoYTEnKVxuICAgICAgcmV0dXJuIGNyeXB0by5oYXNoLnNoYTE7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGMpIHtcbiAgICAgICAgcmV0dXJuIHV0aWwud3JpdGVOdW1iZXIodXRpbC5jYWxjX2NoZWNrc3VtKGMpLCAyKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gSGVscGVyIGZ1bmN0aW9uXG5cbiAgZnVuY3Rpb24gcGFyc2VfY2xlYXJ0ZXh0X21waShoYXNoX2FsZ29yaXRobSwgY2xlYXJ0ZXh0LCBhbGdvcml0aG0pIHtcbiAgICB2YXIgaGFzaGxlbiA9IGdldF9oYXNoX2xlbihoYXNoX2FsZ29yaXRobSksXG4gICAgICBoYXNoZm4gPSBnZXRfaGFzaF9mbihoYXNoX2FsZ29yaXRobSk7XG5cbiAgICB2YXIgaGFzaHRleHQgPSBjbGVhcnRleHQuc3Vic3RyKGNsZWFydGV4dC5sZW5ndGggLSBoYXNobGVuKTtcbiAgICBjbGVhcnRleHQgPSBjbGVhcnRleHQuc3Vic3RyKDAsIGNsZWFydGV4dC5sZW5ndGggLSBoYXNobGVuKTtcblxuICAgIHZhciBoYXNoID0gaGFzaGZuKGNsZWFydGV4dCk7XG5cbiAgICBpZiAoaGFzaCAhPSBoYXNodGV4dClcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoXCJIYXNoIG1pc21hdGNoLlwiKTtcblxuICAgIHZhciBtcGlzID0gY3J5cHRvLmdldFByaXZhdGVNcGlDb3VudChhbGdvcml0aG0pO1xuXG4gICAgdmFyIGogPSAwO1xuICAgIHZhciBtcGkgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXBpcyAmJiBqIDwgY2xlYXJ0ZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBtcGlbaV0gPSBuZXcgdHlwZV9tcGkoKTtcbiAgICAgIGogKz0gbXBpW2ldLnJlYWQoY2xlYXJ0ZXh0LnN1YnN0cihqKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1waTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdyaXRlX2NsZWFydGV4dF9tcGkoaGFzaF9hbGdvcml0aG0sIGFsZ29yaXRobSwgbXBpKSB7XG4gICAgdmFyIGJ5dGVzID0gJyc7XG4gICAgdmFyIGRpc2NhcmQgPSBjcnlwdG8uZ2V0UHVibGljTXBpQ291bnQoYWxnb3JpdGhtKTtcblxuICAgIGZvciAodmFyIGkgPSBkaXNjYXJkOyBpIDwgbXBpLmxlbmd0aDsgaSsrKSB7XG4gICAgICBieXRlcyArPSBtcGlbaV0ud3JpdGUoKTtcbiAgICB9XG5cblxuICAgIGJ5dGVzICs9IGdldF9oYXNoX2ZuKGhhc2hfYWxnb3JpdGhtKShieXRlcyk7XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuXG4gIC8vIDUuNS4zLiAgU2VjcmV0LUtleSBQYWNrZXQgRm9ybWF0c1xuXG4gIC8qKlxuICAgKiBJbnRlcm5hbCBwYXJzZXIgZm9yIHByaXZhdGUga2V5cyBhcyBzcGVjaWZpZWQgaW4gUkZDIDQ4ODAgc2VjdGlvbiA1LjUuM1xuICAgKiBAcGFyYW0ge1N0cmluZ30gYnl0ZXMgSW5wdXQgc3RyaW5nIHRvIHJlYWQgdGhlIHBhY2tldCBmcm9tXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIC8vIC0gQSBQdWJsaWMtS2V5IG9yIFB1YmxpYy1TdWJrZXkgcGFja2V0LCBhcyBkZXNjcmliZWQgYWJvdmUuXG4gICAgdmFyIGxlbiA9IHRoaXMucmVhZFB1YmxpY0tleShieXRlcyk7XG5cbiAgICBieXRlcyA9IGJ5dGVzLnN1YnN0cihsZW4pO1xuXG5cbiAgICAvLyAtIE9uZSBvY3RldCBpbmRpY2F0aW5nIHN0cmluZy10by1rZXkgdXNhZ2UgY29udmVudGlvbnMuICBaZXJvXG4gICAgLy8gICBpbmRpY2F0ZXMgdGhhdCB0aGUgc2VjcmV0LWtleSBkYXRhIGlzIG5vdCBlbmNyeXB0ZWQuICAyNTUgb3IgMjU0XG4gICAgLy8gICBpbmRpY2F0ZXMgdGhhdCBhIHN0cmluZy10by1rZXkgc3BlY2lmaWVyIGlzIGJlaW5nIGdpdmVuLiAgQW55XG4gICAgLy8gICBvdGhlciB2YWx1ZSBpcyBhIHN5bW1ldHJpYy1rZXkgZW5jcnlwdGlvbiBhbGdvcml0aG0gaWRlbnRpZmllci5cbiAgICB2YXIgaXNFbmNyeXB0ZWQgPSBieXRlcy5jaGFyQ29kZUF0KDApO1xuXG4gICAgaWYgKGlzRW5jcnlwdGVkKSB7XG4gICAgICB0aGlzLmVuY3J5cHRlZCA9IGJ5dGVzO1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIC8vIC0gUGxhaW4gb3IgZW5jcnlwdGVkIG11bHRpcHJlY2lzaW9uIGludGVnZXJzIGNvbXByaXNpbmcgdGhlIHNlY3JldFxuICAgICAgLy8gICBrZXkgZGF0YS4gIFRoZXNlIGFsZ29yaXRobS1zcGVjaWZpYyBmaWVsZHMgYXJlIGFzIGRlc2NyaWJlZFxuICAgICAgLy8gICBiZWxvdy5cbiAgICAgIHZhciBwYXJzZWRNUEkgPSBwYXJzZV9jbGVhcnRleHRfbXBpKCdtb2QnLCBieXRlcy5zdWJzdHIoMSksIHRoaXMuYWxnb3JpdGhtKTtcbiAgICAgIGlmIChwYXJzZWRNUEkgaW5zdGFuY2VvZiBFcnJvcilcbiAgICAgICAgdGhyb3cgcGFyc2VkTVBJO1xuICAgICAgdGhpcy5tcGkgPSB0aGlzLm1waS5jb25jYXQocGFyc2VkTVBJKTtcbiAgICAgIHRoaXMuaXNEZWNyeXB0ZWQgPSB0cnVlO1xuICAgIH1cblxuICB9O1xuXG4gIC8qKiBDcmVhdGVzIGFuIE9wZW5QR1Aga2V5IHBhY2tldCBmb3IgdGhlIGdpdmVuIGtleS5cbiAgICAqIEByZXR1cm4ge1N0cmluZ30gQSBzdHJpbmcgb2YgYnl0ZXMgY29udGFpbmluZyB0aGUgc2VjcmV0IGtleSBPcGVuUEdQIHBhY2tldFxuICAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYnl0ZXMgPSB0aGlzLndyaXRlUHVibGljS2V5KCk7XG5cbiAgICBpZiAoIXRoaXMuZW5jcnlwdGVkKSB7XG4gICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuXG4gICAgICBieXRlcyArPSB3cml0ZV9jbGVhcnRleHRfbXBpKCdtb2QnLCB0aGlzLmFsZ29yaXRobSwgdGhpcy5tcGkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBieXRlcyArPSB0aGlzLmVuY3J5cHRlZDtcbiAgICB9XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH07XG5cblxuXG5cbiAgLyoqIEVuY3J5cHQgdGhlIHBheWxvYWQuIEJ5IGRlZmF1bHQsIHdlIHVzZSBhZXMyNTYgYW5kIGl0ZXJhdGVkLCBzYWx0ZWQgc3RyaW5nXG4gICAqIHRvIGtleSBzcGVjaWZpZXJcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhc3NwaHJhc2VcbiAgICovXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UpIHtcblxuICAgIHZhciBzMmsgPSBuZXcgdHlwZV9zMmsoKSxcbiAgICAgIHN5bW1ldHJpYyA9ICdhZXMyNTYnLFxuICAgICAgY2xlYXJ0ZXh0ID0gd3JpdGVfY2xlYXJ0ZXh0X21waSgnc2hhMScsIHRoaXMuYWxnb3JpdGhtLCB0aGlzLm1waSksXG4gICAgICBrZXkgPSBwcm9kdWNlRW5jcnlwdGlvbktleShzMmssIHBhc3NwaHJhc2UsIHN5bW1ldHJpYyksXG4gICAgICBibG9ja0xlbiA9IGNyeXB0by5jaXBoZXJbc3ltbWV0cmljXS5ibG9ja1NpemUsXG4gICAgICBpdiA9IGNyeXB0by5yYW5kb20uZ2V0UmFuZG9tQnl0ZXMoYmxvY2tMZW4pO1xuXG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9ICcnO1xuICAgIHRoaXMuZW5jcnlwdGVkICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMjU0KTtcbiAgICB0aGlzLmVuY3J5cHRlZCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnN5bW1ldHJpYywgc3ltbWV0cmljKSk7XG4gICAgdGhpcy5lbmNyeXB0ZWQgKz0gczJrLndyaXRlKCk7XG4gICAgdGhpcy5lbmNyeXB0ZWQgKz0gaXY7XG5cbiAgICB0aGlzLmVuY3J5cHRlZCArPSBjcnlwdG8uY2ZiLm5vcm1hbEVuY3J5cHQoc3ltbWV0cmljLCBrZXksIGNsZWFydGV4dCwgaXYpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHByb2R1Y2VFbmNyeXB0aW9uS2V5KHMyaywgcGFzc3BocmFzZSwgYWxnb3JpdGhtKSB7XG4gICAgcmV0dXJuIHMyay5wcm9kdWNlX2tleShwYXNzcGhyYXNlLFxuICAgICAgY3J5cHRvLmNpcGhlclthbGdvcml0aG1dLmtleVNpemUpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBwcml2YXRlIGtleSBNUElzIHdoaWNoIGFyZSBuZWVkZWQgdG8gdXNlIHRoZSBrZXkuXG4gICAqIG9wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsLmhhc1VuZW5jcnlwdGVkU2VjcmV0S2V5RGF0YSBzaG91bGQgYmUgXG4gICAqIGZhbHNlIG90aGVyd2lzZVxuICAgKiBhIGNhbGwgdG8gdGhpcyBmdW5jdGlvbiBpcyBub3QgbmVlZGVkXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyX3Bhc3NwaHJhc2UgVGhlIHBhc3NwaHJhc2UgZm9yIHRoaXMgcHJpdmF0ZSBrZXkgXG4gICAqIGFzIHN0cmluZ1xuICAgKiBAcmV0dXJuIHtCb29sZWFufSBUcnVlIGlmIHRoZSBwYXNzcGhyYXNlIHdhcyBjb3JyZWN0IG9yIE1QSSBhbHJlYWR5XG4gICAqICAgICAgICAgICAgICAgICAgIGRlY3J5cHRlZDsgZmFsc2UgaWYgbm90XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihwYXNzcGhyYXNlKSB7XG4gICAgaWYgKHRoaXMuaXNEZWNyeXB0ZWQpXG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIHZhciBpID0gMCxcbiAgICAgIHN5bW1ldHJpYyxcbiAgICAgIGtleTtcblxuICAgIHZhciBzMmtfdXNhZ2UgPSB0aGlzLmVuY3J5cHRlZC5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAvLyAtIFtPcHRpb25hbF0gSWYgc3RyaW5nLXRvLWtleSB1c2FnZSBvY3RldCB3YXMgMjU1IG9yIDI1NCwgYSBvbmUtXG4gICAgLy8gICBvY3RldCBzeW1tZXRyaWMgZW5jcnlwdGlvbiBhbGdvcml0aG0uXG4gICAgaWYgKHMya191c2FnZSA9PSAyNTUgfHwgczJrX3VzYWdlID09IDI1NCkge1xuICAgICAgc3ltbWV0cmljID0gdGhpcy5lbmNyeXB0ZWQuY2hhckNvZGVBdChpKyspO1xuICAgICAgc3ltbWV0cmljID0gZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIHN5bW1ldHJpYyk7XG5cbiAgICAgIC8vIC0gW09wdGlvbmFsXSBJZiBzdHJpbmctdG8ta2V5IHVzYWdlIG9jdGV0IHdhcyAyNTUgb3IgMjU0LCBhXG4gICAgICAvLyAgIHN0cmluZy10by1rZXkgc3BlY2lmaWVyLiAgVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nLXRvLWtleVxuICAgICAgLy8gICBzcGVjaWZpZXIgaXMgaW1wbGllZCBieSBpdHMgdHlwZSwgYXMgZGVzY3JpYmVkIGFib3ZlLlxuICAgICAgdmFyIHMyayA9IG5ldyB0eXBlX3MyaygpO1xuICAgICAgaSArPSBzMmsucmVhZCh0aGlzLmVuY3J5cHRlZC5zdWJzdHIoaSkpO1xuXG4gICAgICBrZXkgPSBwcm9kdWNlRW5jcnlwdGlvbktleShzMmssIHBhc3NwaHJhc2UsIHN5bW1ldHJpYyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN5bW1ldHJpYyA9IHMya191c2FnZTtcbiAgICAgIHN5bW1ldHJpYyA9IGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBzeW1tZXRyaWMpO1xuICAgICAga2V5ID0gY3J5cHRvLmhhc2gubWQ1KHBhc3NwaHJhc2UpO1xuICAgIH1cblxuXG4gICAgLy8gLSBbT3B0aW9uYWxdIElmIHNlY3JldCBkYXRhIGlzIGVuY3J5cHRlZCAoc3RyaW5nLXRvLWtleSB1c2FnZSBvY3RldFxuICAgIC8vICAgbm90IHplcm8pLCBhbiBJbml0aWFsIFZlY3RvciAoSVYpIG9mIHRoZSBzYW1lIGxlbmd0aCBhcyB0aGVcbiAgICAvLyAgIGNpcGhlcidzIGJsb2NrIHNpemUuXG4gICAgdmFyIGl2ID0gdGhpcy5lbmNyeXB0ZWQuc3Vic3RyKGksXG4gICAgICBjcnlwdG8uY2lwaGVyW3N5bW1ldHJpY10uYmxvY2tTaXplKTtcblxuICAgIGkgKz0gaXYubGVuZ3RoO1xuXG4gICAgdmFyIGNsZWFydGV4dCxcbiAgICAgIGNpcGhlcnRleHQgPSB0aGlzLmVuY3J5cHRlZC5zdWJzdHIoaSk7XG5cbiAgICBjbGVhcnRleHQgPSBjcnlwdG8uY2ZiLm5vcm1hbERlY3J5cHQoc3ltbWV0cmljLCBrZXksIGNpcGhlcnRleHQsIGl2KTtcblxuICAgIHZhciBoYXNoID0gczJrX3VzYWdlID09IDI1NCA/XG4gICAgICAnc2hhMScgOlxuICAgICAgJ21vZCc7XG5cbiAgICB2YXIgcGFyc2VkTVBJID0gcGFyc2VfY2xlYXJ0ZXh0X21waShoYXNoLCBjbGVhcnRleHQsIHRoaXMuYWxnb3JpdGhtKTtcbiAgICBpZiAocGFyc2VkTVBJIGluc3RhbmNlb2YgRXJyb3IpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgdGhpcy5tcGkgPSB0aGlzLm1waS5jb25jYXQocGFyc2VkTVBJKTtcbiAgICB0aGlzLmlzRGVjcnlwdGVkID0gdHJ1ZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICB0aGlzLmdlbmVyYXRlID0gZnVuY3Rpb24oYml0cykge1xuICAgIHRoaXMubXBpID0gY3J5cHRvLmdlbmVyYXRlTXBpKHRoaXMuYWxnb3JpdGhtLCBiaXRzKTtcbiAgICB0aGlzLmlzRGVjcnlwdGVkID0gdHJ1ZTtcbiAgfTtcblxufVxuXG5wYWNrZXRfc2VjcmV0X2tleS5wcm90b3R5cGUgPSBuZXcgcHVibGljS2V5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHBhY2tldF9zZWNyZXRfa2V5O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHNlY3JldF9rZXkgPSByZXF1aXJlKCcuL3NlY3JldF9rZXkuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzZWNyZXRfc3Via2V5KCkge1xuICBzZWNyZXRfa2V5LmNhbGwodGhpcyk7XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgcGFja2V0ID0gcmVxdWlyZSgnLi9wYWNrZXQuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKSxcbiAgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpLFxuICB0eXBlX2tleWlkID0gcmVxdWlyZSgnLi4vdHlwZS9rZXlpZC5qcycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2lnbmF0dXJlIFBhY2tldCAoVGFnIDIpXG4gKiBcbiAqIFJGQzQ0ODAgNS4yOlxuICogQSBTaWduYXR1cmUgcGFja2V0IGRlc2NyaWJlcyBhIGJpbmRpbmcgYmV0d2VlbiBzb21lIHB1YmxpYyBrZXkgYW5kXG4gKiBzb21lIGRhdGEuICBUaGUgbW9zdCBjb21tb24gc2lnbmF0dXJlcyBhcmUgYSBzaWduYXR1cmUgb2YgYSBmaWxlIG9yIGFcbiAqIGJsb2NrIG9mIHRleHQsIGFuZCBhIHNpZ25hdHVyZSB0aGF0IGlzIGEgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3NpZ25hdHVyZSgpIHtcblxuICB0aGlzLnZlcnNpb24gPSBudWxsO1xuICB0aGlzLnNpZ25hdHVyZVR5cGUgPSBudWxsO1xuICB0aGlzLmhhc2hBbGdvcml0aG0gPSBudWxsO1xuICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IG51bGw7XG5cbiAgdGhpcy5zaWduYXR1cmVEYXRhID0gbnVsbDtcbiAgdGhpcy5zaWduZWRIYXNoVmFsdWUgPSBudWxsO1xuICB0aGlzLm1waSA9IG51bGw7XG5cbiAgdGhpcy5jcmVhdGVkID0gbmV3IERhdGUoKTtcbiAgdGhpcy5zaWduYXR1cmVFeHBpcmF0aW9uVGltZSA9IG51bGw7XG4gIHRoaXMuc2lnbmF0dXJlTmV2ZXJFeHBpcmVzID0gbnVsbDtcbiAgdGhpcy5leHBvcnRhYmxlID0gbnVsbDtcbiAgdGhpcy50cnVzdExldmVsID0gbnVsbDtcbiAgdGhpcy50cnVzdEFtb3VudCA9IG51bGw7XG4gIHRoaXMucmVndWxhckV4cHJlc3Npb24gPSBudWxsO1xuICB0aGlzLnJldm9jYWJsZSA9IG51bGw7XG4gIHRoaXMua2V5RXhwaXJhdGlvblRpbWUgPSBudWxsO1xuICB0aGlzLmtleU5ldmVyRXhwaXJlcyA9IG51bGw7XG4gIHRoaXMucHJlZmVycmVkU3ltbWV0cmljQWxnb3JpdGhtcyA9IG51bGw7XG4gIHRoaXMucmV2b2NhdGlvbktleUNsYXNzID0gbnVsbDtcbiAgdGhpcy5yZXZvY2F0aW9uS2V5QWxnb3JpdGhtID0gbnVsbDtcbiAgdGhpcy5yZXZvY2F0aW9uS2V5RmluZ2VycHJpbnQgPSBudWxsO1xuICB0aGlzLmlzc3VlcktleUlkID0gbmV3IHR5cGVfa2V5aWQoKTtcbiAgdGhpcy5ub3RhdGlvbiA9IG51bGw7XG4gIHRoaXMucHJlZmVycmVkSGFzaEFsZ29yaXRobXMgPSBudWxsO1xuICB0aGlzLnByZWZlcnJlZENvbXByZXNzaW9uQWxnb3JpdGhtcyA9IG51bGw7XG4gIHRoaXMua2V5U2VydmVyUHJlZmVyZW5jZXMgPSBudWxsO1xuICB0aGlzLnByZWZlcnJlZEtleVNlcnZlciA9IG51bGw7XG4gIHRoaXMuaXNQcmltYXJ5VXNlcklEID0gbnVsbDtcbiAgdGhpcy5wb2xpY3lVUkkgPSBudWxsO1xuICB0aGlzLmtleUZsYWdzID0gbnVsbDtcbiAgdGhpcy5zaWduZXJzVXNlcklkID0gbnVsbDtcbiAgdGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uRmxhZyA9IG51bGw7XG4gIHRoaXMucmVhc29uRm9yUmV2b2NhdGlvblN0cmluZyA9IG51bGw7XG4gIHRoaXMuZmVhdHVyZXMgPSBudWxsO1xuICB0aGlzLnNpZ25hdHVyZVRhcmdldFB1YmxpY0tleUFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaCA9IG51bGw7XG4gIHRoaXMuZW1iZWRkZWRTaWduYXR1cmUgPSBudWxsO1xuXG4gIHRoaXMudmVyaWZpZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogcGFyc2luZyBmdW5jdGlvbiBmb3IgYSBzaWduYXR1cmUgcGFja2V0ICh0YWcgMikuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBwYXlsb2FkIG9mIGEgdGFnIDIgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gcG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBieXRlcyBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gbGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2YgYnl0ZXMgYXQgcG9zaXRpb25cbiAgICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YX0gb2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBpID0gMDtcblxuICAgIHRoaXMudmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAvLyBzd2l0Y2ggb24gdmVyc2lvbiAoMyBhbmQgNClcbiAgICBzd2l0Y2ggKHRoaXMudmVyc2lvbikge1xuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyBPbmUtb2N0ZXQgbGVuZ3RoIG9mIGZvbGxvd2luZyBoYXNoZWQgbWF0ZXJpYWwuIE1VU1QgYmUgNS5cbiAgICAgICAgaWYgKGJ5dGVzLmNoYXJDb2RlQXQoaSsrKSAhPSA1KVxuICAgICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCJvcGVucGdwLnBhY2tldC5zaWduYXR1cmUuanNcXG5cIiArXG4gICAgICAgICAgICAnaW52YWxpZCBPbmUtb2N0ZXQgbGVuZ3RoIG9mIGZvbGxvd2luZyBoYXNoZWQgbWF0ZXJpYWwuJyArXG4gICAgICAgICAgICAnTVVTVCBiZSA1LiBAOicgKyAoaSAtIDEpKTtcblxuICAgICAgICB2YXIgc2lncG9zID0gaTtcbiAgICAgICAgLy8gT25lLW9jdGV0IHNpZ25hdHVyZSB0eXBlLlxuICAgICAgICB0aGlzLnNpZ25hdHVyZVR5cGUgPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgICAgLy8gRm91ci1vY3RldCBjcmVhdGlvbiB0aW1lLlxuICAgICAgICB0aGlzLmNyZWF0ZWQgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihpLCA0KSk7XG4gICAgICAgIGkgKz0gNDtcblxuICAgICAgICAvLyBzdG9yaW5nIGRhdGEgYXBwZW5kZWQgdG8gZGF0YSB3aGljaCBnZXRzIHZlcmlmaWVkXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlRGF0YSA9IGJ5dGVzLnN1YnN0cmluZyhzaWdwb3MsIGkpO1xuXG4gICAgICAgIC8vIEVpZ2h0LW9jdGV0IEtleSBJRCBvZiBzaWduZXIuXG4gICAgICAgIHRoaXMuaXNzdWVyS2V5SWQucmVhZChieXRlcy5zdWJzdHJpbmcoaSwgaSArIDgpKTtcbiAgICAgICAgaSArPSA4O1xuXG4gICAgICAgIC8vIE9uZS1vY3RldCBwdWJsaWMta2V5IGFsZ29yaXRobS5cbiAgICAgICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgICAgLy8gT25lLW9jdGV0IGhhc2ggYWxnb3JpdGhtLlxuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA0OlxuICAgICAgICB0aGlzLnNpZ25hdHVyZVR5cGUgPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICAgIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gYnl0ZXMuY2hhckNvZGVBdChpKyspO1xuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgICAgZnVuY3Rpb24gc3VicGFja2V0cyhieXRlcykge1xuICAgICAgICAgIC8vIFR3by1vY3RldCBzY2FsYXIgb2N0ZXQgY291bnQgZm9yIGZvbGxvd2luZyBzdWJwYWNrZXQgZGF0YS5cbiAgICAgICAgICB2YXIgc3VicGFja2V0X2xlbmd0aCA9IHV0aWwucmVhZE51bWJlcihcbiAgICAgICAgICAgIGJ5dGVzLnN1YnN0cigwLCAyKSk7XG5cbiAgICAgICAgICB2YXIgaSA9IDI7XG5cbiAgICAgICAgICAvLyBzdWJwYWNrZXQgZGF0YSBzZXQgKHplcm8gb3IgbW9yZSBzdWJwYWNrZXRzKVxuICAgICAgICAgIHZhciBzdWJwYWNrZWRfcmVhZCA9IDA7XG4gICAgICAgICAgd2hpbGUgKGkgPCAyICsgc3VicGFja2V0X2xlbmd0aCkge1xuXG4gICAgICAgICAgICB2YXIgbGVuID0gcGFja2V0LnJlYWRTaW1wbGVMZW5ndGgoYnl0ZXMuc3Vic3RyKGkpKTtcbiAgICAgICAgICAgIGkgKz0gbGVuLm9mZnNldDtcblxuICAgICAgICAgICAgdGhpcy5yZWFkX3N1Yl9wYWNrZXQoYnl0ZXMuc3Vic3RyKGksIGxlbi5sZW4pKTtcblxuICAgICAgICAgICAgaSArPSBsZW4ubGVuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaGFzaGVkIHN1YnBhY2tldHNcbiAgICAgICAgaSArPSBzdWJwYWNrZXRzLmNhbGwodGhpcywgYnl0ZXMuc3Vic3RyKGkpLCB0cnVlKTtcblxuICAgICAgICAvLyBBIFY0IHNpZ25hdHVyZSBoYXNoZXMgdGhlIHBhY2tldCBib2R5XG4gICAgICAgIC8vIHN0YXJ0aW5nIGZyb20gaXRzIGZpcnN0IGZpZWxkLCB0aGUgdmVyc2lvbiBudW1iZXIsIHRocm91Z2ggdGhlIGVuZFxuICAgICAgICAvLyBvZiB0aGUgaGFzaGVkIHN1YnBhY2tldCBkYXRhLiAgVGh1cywgdGhlIGZpZWxkcyBoYXNoZWQgYXJlIHRoZVxuICAgICAgICAvLyBzaWduYXR1cmUgdmVyc2lvbiwgdGhlIHNpZ25hdHVyZSB0eXBlLCB0aGUgcHVibGljLWtleSBhbGdvcml0aG0sIHRoZVxuICAgICAgICAvLyBoYXNoIGFsZ29yaXRobSwgdGhlIGhhc2hlZCBzdWJwYWNrZXQgbGVuZ3RoLCBhbmQgdGhlIGhhc2hlZFxuICAgICAgICAvLyBzdWJwYWNrZXQgYm9keS5cbiAgICAgICAgdGhpcy5zaWduYXR1cmVEYXRhID0gYnl0ZXMuc3Vic3RyKDAsIGkpO1xuXG4gICAgICAgIC8vIHVuaGFzaGVkIHN1YnBhY2tldHNcbiAgICAgICAgaSArPSBzdWJwYWNrZXRzLmNhbGwodGhpcywgYnl0ZXMuc3Vic3RyKGkpLCBmYWxzZSk7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZlcnNpb24gJyArIHZlcnNpb24gKyAnIG9mIHRoZSBzaWduYXR1cmUgaXMgdW5zdXBwb3J0ZWQuJyk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIFR3by1vY3RldCBmaWVsZCBob2xkaW5nIGxlZnQgMTYgYml0cyBvZiBzaWduZWQgaGFzaCB2YWx1ZS5cbiAgICB0aGlzLnNpZ25lZEhhc2hWYWx1ZSA9IGJ5dGVzLnN1YnN0cihpLCAyKTtcbiAgICBpICs9IDI7XG5cbiAgICB0aGlzLnNpZ25hdHVyZSA9IGJ5dGVzLnN1YnN0cihpKTtcbiAgfTtcblxuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuc2lnbmF0dXJlRGF0YSArXG4gICAgICB1dGlsLndyaXRlTnVtYmVyKDAsIDIpICsgLy8gTnVtYmVyIG9mIHVuc2lnbmVkIHN1YnBhY2tldHMuXG4gICAgdGhpcy5zaWduZWRIYXNoVmFsdWUgK1xuICAgICAgdGhpcy5zaWduYXR1cmU7XG4gIH07XG5cbiAgLyoqXG4gICAqIFNpZ25zIHByb3ZpZGVkIGRhdGEuIFRoaXMgbmVlZHMgdG8gYmUgZG9uZSBwcmlvciB0byBzZXJpYWxpemF0aW9uLlxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YSBDb250YWlucyBwYWNrZXRzIHRvIGJlIHNpZ25lZC5cbiAgICogQHBhcmFtIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBwcml2YXRla2V5IHByaXZhdGUga2V5IHVzZWQgdG8gc2lnbiB0aGUgbWVzc2FnZS4gXG4gICAqL1xuICB0aGlzLnNpZ24gPSBmdW5jdGlvbihrZXksIGRhdGEpIHtcbiAgICB2YXIgc2lnbmF0dXJlVHlwZSA9IGVudW1zLndyaXRlKGVudW1zLnNpZ25hdHVyZSwgdGhpcy5zaWduYXR1cmVUeXBlKSxcbiAgICAgIHB1YmxpY0tleUFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLnB1YmxpY0tleSwgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0pLFxuICAgICAgaGFzaEFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLmhhc2gsIHRoaXMuaGFzaEFsZ29yaXRobSk7XG5cbiAgICB2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSg0KTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShzaWduYXR1cmVUeXBlKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwdWJsaWNLZXlBbGdvcml0aG0pO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGhhc2hBbGdvcml0aG0pO1xuXG4gICAgdGhpcy5pc3N1ZXJLZXlJZCA9IGtleS5nZXRLZXlJZCgpO1xuXG4gICAgLy8gQWRkIGhhc2hlZCBzdWJwYWNrZXRzXG4gICAgcmVzdWx0ICs9IHRoaXMud3JpdGVfYWxsX3N1Yl9wYWNrZXRzKCk7XG5cbiAgICB0aGlzLnNpZ25hdHVyZURhdGEgPSByZXN1bHQ7XG5cbiAgICB2YXIgdHJhaWxlciA9IHRoaXMuY2FsY3VsYXRlVHJhaWxlcigpO1xuXG4gICAgdmFyIHRvSGFzaCA9IHRoaXMudG9TaWduKHNpZ25hdHVyZVR5cGUsIGRhdGEpICtcbiAgICAgIHRoaXMuc2lnbmF0dXJlRGF0YSArIHRyYWlsZXI7XG5cbiAgICB2YXIgaGFzaCA9IGNyeXB0by5oYXNoLmRpZ2VzdChoYXNoQWxnb3JpdGhtLCB0b0hhc2gpO1xuXG4gICAgdGhpcy5zaWduZWRIYXNoVmFsdWUgPSBoYXNoLnN1YnN0cigwLCAyKTtcblxuICAgIHRoaXMuc2lnbmF0dXJlID0gY3J5cHRvLnNpZ25hdHVyZS5zaWduKGhhc2hBbGdvcml0aG0sXG4gICAgICBwdWJsaWNLZXlBbGdvcml0aG0sIGtleS5tcGksIHRvSGFzaCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgc3RyaW5nIG9mIGJ5dGVzIHdpdGggYWxsIHN1YnBhY2tldCBkYXRhXG4gICAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmctcmVwcmVzZW50YXRpb24gb2YgYSBhbGwgc3VicGFja2V0IGRhdGFcbiAgICovXG4gIHRoaXMud3JpdGVfYWxsX3N1Yl9wYWNrZXRzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHN1YiA9IGVudW1zLnNpZ25hdHVyZVN1YnBhY2tldDtcbiAgICB2YXIgcmVzdWx0ID0gJyc7XG4gICAgdmFyIGJ5dGVzID0gJyc7XG4gICAgaWYgKHRoaXMuY3JlYXRlZCAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnNpZ25hdHVyZV9jcmVhdGlvbl90aW1lLCB1dGlsLndyaXRlRGF0ZSh0aGlzLmNyZWF0ZWQpKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2lnbmF0dXJlRXhwaXJhdGlvblRpbWUgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5zaWduYXR1cmVfZXhwaXJhdGlvbl90aW1lLCB1dGlsLndyaXRlRGF0ZSh0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmV4cG9ydGFibGUgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5leHBvcnRhYmxlX2NlcnRpZmljYXRpb24sIFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5leHBvcnRhYmxlID8gMSA6IDApKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudHJ1c3RMZXZlbCAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMudHJ1c3RMZXZlbCkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMudHJ1c3RBbW91bnQpO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnRydXN0X3NpZ25hdHVyZSwgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZWd1bGFyRXhwcmVzc2lvbiAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnJlZ3VsYXJfZXhwcmVzc2lvbiwgdGhpcy5yZWd1bGFyRXhwcmVzc2lvbik7XG4gICAgfVxuICAgIGlmICh0aGlzLnJldm9jYWJsZSAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnJldm9jYWJsZSwgU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnJldm9jYWJsZSA/IDEgOiAwKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmtleUV4cGlyYXRpb25UaW1lICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIua2V5X2V4cGlyYXRpb25fdGltZSwgdXRpbC53cml0ZURhdGUodGhpcy5rZXlFeHBpcmF0aW9uVGltZSkpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wcmVmZXJyZWRTeW1tZXRyaWNBbGdvcml0aG1zICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IHV0aWwuYmluMnN0cih0aGlzLnByZWZlcnJlZFN5bW1ldHJpY0FsZ29yaXRobXMpO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnByZWZlcnJlZF9zeW1tZXRyaWNfYWxnb3JpdGhtcywgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZXZvY2F0aW9uS2V5Q2xhc3MgIT09IG51bGwpIHtcbiAgICAgIGJ5dGVzID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnJldm9jYXRpb25LZXlDbGFzcyk7XG4gICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMucmV2b2NhdGlvbktleUFsZ29yaXRobSk7XG4gICAgICBieXRlcyArPSB0aGlzLnJldm9jYXRpb25LZXlGaW5nZXJwcmludDtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5yZXZvY2F0aW9uX2tleSwgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuaXNzdWVyS2V5SWQuaXNOdWxsKCkpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5pc3N1ZXIsIHRoaXMuaXNzdWVyS2V5SWQud3JpdGUoKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLm5vdGF0aW9uICE9PSBudWxsKSB7XG4gICAgICBmb3IgKHZhciBuYW1lIGluIHRoaXMubm90YXRpb24pIHtcbiAgICAgICAgaWYgKHRoaXMubm90YXRpb24uaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLm5vdGF0aW9uW25hbWVdO1xuICAgICAgICAgIGJ5dGVzID0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDgwKTtcbiAgICAgICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuICAgICAgICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG4gICAgICAgICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICAgICAgICAvLyAyIG9jdGV0cyBvZiBuYW1lIGxlbmd0aFxuICAgICAgICAgIGJ5dGVzICs9IHV0aWwud3JpdGVOdW1iZXIobmFtZS5sZW5ndGgsIDIpO1xuICAgICAgICAgIC8vIDIgb2N0ZXRzIG9mIHZhbHVlIGxlbmd0aFxuICAgICAgICAgIGJ5dGVzICs9IHV0aWwud3JpdGVOdW1iZXIodmFsdWUubGVuZ3RoLCAyKTtcbiAgICAgICAgICBieXRlcyArPSBuYW1lICsgdmFsdWU7XG4gICAgICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLm5vdGF0aW9uX2RhdGEsIGJ5dGVzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gXG4gICAgaWYgKHRoaXMucHJlZmVycmVkSGFzaEFsZ29yaXRobXMgIT09IG51bGwpIHtcbiAgICAgIGJ5dGVzID0gdXRpbC5iaW4yc3RyKHRoaXMucHJlZmVycmVkSGFzaEFsZ29yaXRobXMpO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnByZWZlcnJlZF9oYXNoX2FsZ29yaXRobXMsIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucHJlZmVycmVkQ29tcHJlc3Npb25BbGdvcml0aG1zICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IHV0aWwuYmluMnN0cih0aGlzLnByZWZlcnJlZENvbXByZXNzaW9uQWxnb3JpdGhtcyk7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIucHJlZmVycmVkX2hhc2hfYWxnb3JpdGhtcywgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5rZXlTZXJ2ZXJQcmVmZXJlbmNlcyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSB1dGlsLmJpbjJzdHIodGhpcy5rZXlTZXJ2ZXJQcmVmZXJlbmNlcyk7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIua2V5X3NlcnZlcl9wcmVmZXJlbmNlcywgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wcmVmZXJyZWRLZXlTZXJ2ZXIgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5wcmVmZXJyZWRfa2V5X3NlcnZlciwgdGhpcy5wcmVmZXJyZWRLZXlTZXJ2ZXIpO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc1ByaW1hcnlVc2VySUQgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5wcmltYXJ5X3VzZXJfaWQsIFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5pc1ByaW1hcnlVc2VySUQgPyAxIDogMCkpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wb2xpY3lVUkkgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5wb2xpY3lfdXJpLCB0aGlzLnBvbGljeVVSSSk7IFxuICAgIH1cbiAgICBpZiAodGhpcy5rZXlGbGFncyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSB1dGlsLmJpbjJzdHIodGhpcy5rZXlGbGFncyk7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIua2V5X2ZsYWdzLCBieXRlcyk7XG4gICAgfVxuICAgIGlmICh0aGlzLnNpZ25lcnNVc2VySWQgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5zaWduZXJzX3VzZXJfaWQsIHRoaXMuc2lnbmVyc1VzZXJJZCk7IFxuICAgIH1cbiAgICBpZiAodGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uRmxhZyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMucmVhc29uRm9yUmV2b2NhdGlvbkZsYWcpO1xuICAgICAgYnl0ZXMgKz0gdGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uU3RyaW5nO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnJlYXNvbl9mb3JfcmV2b2NhdGlvbiwgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5mZWF0dXJlcyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSB1dGlsLmJpbjJzdHIodGhpcy5mZWF0dXJlcyk7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIuZmVhdHVyZXMsIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2lnbmF0dXJlVGFyZ2V0UHVibGljS2V5QWxnb3JpdGhtICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5zaWduYXR1cmVUYXJnZXRQdWJsaWNLZXlBbGdvcml0aG0pO1xuICAgICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnNpZ25hdHVyZVRhcmdldEhhc2hBbGdvcml0aG0pO1xuICAgICAgYnl0ZXMgKz0gdGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnNpZ25hdHVyZV90YXJnZXQsIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZW1iZWRkZWRTaWduYXR1cmUgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5lbWJlZGRlZF9zaWduYXR1cmUsIHRoaXMuZW1iZWRkZWRTaWduYXR1cmUud3JpdGUoKSk7XG4gICAgfVxuICAgIHJlc3VsdCA9IHV0aWwud3JpdGVOdW1iZXIocmVzdWx0Lmxlbmd0aCwgMikgKyByZXN1bHQ7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvKipcbiAgICogY3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHN1YiBzaWduYXR1cmUgcGFja2V0IChTZWUgUkZDIDQ4ODAgNS4yLjMuMSlcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSB0eXBlIHN1YnBhY2tldCBzaWduYXR1cmUgdHlwZS4gU2lnbmF0dXJlIHR5cGVzIGFzIGRlc2NyaWJlZCBcbiAgICogaW4gUkZDNDg4MCBTZWN0aW9uIDUuMi4zLjJcbiAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgZGF0YSB0byBiZSBpbmNsdWRlZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGEgc3RyaW5nLXJlcHJlc2VudGF0aW9uIG9mIGEgc3ViIHNpZ25hdHVyZSBwYWNrZXQgKFNlZSBSRkMgNDg4MCA1LjIuMy4xKVxuICAgKi9cbiAgZnVuY3Rpb24gd3JpdGVfc3ViX3BhY2tldCh0eXBlLCBkYXRhKSB7XG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgcmVzdWx0ICs9IHBhY2tldC53cml0ZVNpbXBsZUxlbmd0aChkYXRhLmxlbmd0aCArIDEpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHR5cGUpO1xuICAgIHJlc3VsdCArPSBkYXRhO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBWNCBzaWduYXR1cmUgc3ViIHBhY2tldHNcblxuICB0aGlzLnJlYWRfc3ViX3BhY2tldCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIG15cG9zID0gMDtcblxuICAgIGZ1bmN0aW9uIHJlYWRfYXJyYXkocHJvcCwgYnl0ZXMpIHtcbiAgICAgIHRoaXNbcHJvcF0gPSBbXTtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzW3Byb3BdLnB1c2goYnl0ZXMuY2hhckNvZGVBdChpKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVGhlIGxlZnR3b3N0IGJpdCBkZW5vdGVzIGEgXCJjcml0aWNhbFwiIHBhY2tldCwgYnV0IHdlIGlnbm9yZSBpdC5cbiAgICB2YXIgdHlwZSA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKykgJiAweDdGO1xuXG4gICAgLy8gc3VicGFja2V0IHR5cGVcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gU2lnbmF0dXJlIENyZWF0aW9uIFRpbWVcbiAgICAgICAgdGhpcy5jcmVhdGVkID0gdXRpbC5yZWFkRGF0ZShieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIC8vIFNpZ25hdHVyZSBFeHBpcmF0aW9uIFRpbWVcbiAgICAgICAgdmFyIHRpbWUgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlTmV2ZXJFeHBpcmVzID0gdGltZS5nZXRUaW1lKCkgPT0gMDtcbiAgICAgICAgdGhpcy5zaWduYXR1cmVFeHBpcmF0aW9uVGltZSA9IHRpbWU7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIC8vIEV4cG9ydGFibGUgQ2VydGlmaWNhdGlvblxuICAgICAgICB0aGlzLmV4cG9ydGFibGUgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspID09IDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA1OlxuICAgICAgICAvLyBUcnVzdCBTaWduYXR1cmVcbiAgICAgICAgdGhpcy50cnVzdExldmVsID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgdGhpcy50cnVzdEFtb3VudCA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA2OlxuICAgICAgICAvLyBSZWd1bGFyIEV4cHJlc3Npb25cbiAgICAgICAgdGhpcy5yZWd1bGFyRXhwcmVzc2lvbiA9IGJ5dGVzLnN1YnN0cihteXBvcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA3OlxuICAgICAgICAvLyBSZXZvY2FibGVcbiAgICAgICAgdGhpcy5yZXZvY2FibGUgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspID09IDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA5OlxuICAgICAgICAvLyBLZXkgRXhwaXJhdGlvbiBUaW1lXG4gICAgICAgIHZhciB0aW1lID0gdXRpbC5yZWFkRGF0ZShieXRlcy5zdWJzdHIobXlwb3MpKTtcblxuICAgICAgICB0aGlzLmtleUV4cGlyYXRpb25UaW1lID0gdGltZTtcbiAgICAgICAgdGhpcy5rZXlOZXZlckV4cGlyZXMgPSB0aW1lLmdldFRpbWUoKSA9PSAwO1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMTpcbiAgICAgICAgLy8gUHJlZmVycmVkIFN5bW1ldHJpYyBBbGdvcml0aG1zXG4gICAgICAgIHRoaXMucHJlZmVycmVkU3ltbWV0cmljQWxnb3JpdGhtcyA9IFtdO1xuXG4gICAgICAgIHdoaWxlIChteXBvcyAhPSBieXRlcy5sZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLnByZWZlcnJlZFN5bW1ldHJpY0FsZ29yaXRobXMucHVzaChieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMjpcbiAgICAgICAgLy8gUmV2b2NhdGlvbiBLZXlcbiAgICAgICAgLy8gKDEgb2N0ZXQgb2YgY2xhc3MsIDEgb2N0ZXQgb2YgcHVibGljLWtleSBhbGdvcml0aG0gSUQsIDIwXG4gICAgICAgIC8vIG9jdGV0cyBvZlxuICAgICAgICAvLyBmaW5nZXJwcmludClcbiAgICAgICAgdGhpcy5yZXZvY2F0aW9uS2V5Q2xhc3MgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICB0aGlzLnJldm9jYXRpb25LZXlBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICB0aGlzLnJldm9jYXRpb25LZXlGaW5nZXJwcmludCA9IGJ5dGVzLnN1YnN0cihteXBvcywgMjApO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAxNjpcbiAgICAgICAgLy8gSXNzdWVyXG4gICAgICAgIHRoaXMuaXNzdWVyS2V5SWQucmVhZChieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgMjA6XG4gICAgICAgIC8vIE5vdGF0aW9uIERhdGFcbiAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyBob3cgdG8gaGFuZGxlIGFueXRoaW5nIGJ1dCBhIHRleHQgZmxhZ2dlZCBkYXRhLlxuICAgICAgICBpZiAoYnl0ZXMuY2hhckNvZGVBdChteXBvcykgPT0gMHg4MCkge1xuXG4gICAgICAgICAgLy8gV2UgZXh0cmFjdCBrZXkvdmFsdWUgdHVwbGUgZnJvbSB0aGUgYnl0ZSBzdHJlYW0uXG4gICAgICAgICAgbXlwb3MgKz0gNDtcbiAgICAgICAgICB2YXIgbSA9IHV0aWwucmVhZE51bWJlcihieXRlcy5zdWJzdHIobXlwb3MsIDIpKTtcbiAgICAgICAgICBteXBvcyArPSAyXG4gICAgICAgICAgdmFyIG4gPSB1dGlsLnJlYWROdW1iZXIoYnl0ZXMuc3Vic3RyKG15cG9zLCAyKSk7XG4gICAgICAgICAgbXlwb3MgKz0gMlxuXG4gICAgICAgICAgdmFyIG5hbWUgPSBieXRlcy5zdWJzdHIobXlwb3MsIG0pLFxuICAgICAgICAgICAgdmFsdWUgPSBieXRlcy5zdWJzdHIobXlwb3MgKyBtLCBuKTtcblxuICAgICAgICAgIHRoaXMubm90YXRpb24gPSB0aGlzLm5vdGF0aW9uIHx8IHt9O1xuICAgICAgICAgIHRoaXMubm90YXRpb25bbmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgfSBlbHNlIHRocm93IG5ldyBFcnJvcihcIlVuc3VwcG9ydGVkIG5vdGF0aW9uIGZsYWcuXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjE6XG4gICAgICAgIC8vIFByZWZlcnJlZCBIYXNoIEFsZ29yaXRobXNcbiAgICAgICAgcmVhZF9hcnJheS5jYWxsKHRoaXMsICdwcmVmZXJyZWRIYXNoQWxnb3JpdGhtcycsIGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjI6XG4gICAgICAgIC8vIFByZWZlcnJlZCBDb21wcmVzc2lvbiBBbGdvcml0aG1zXG4gICAgICAgIHJlYWRfYXJyYXkuY2FsbCh0aGlzLCAncHJlZmVycmVkQ29tcHJlc3Npb25BbGdvcml0aG1zICcsIGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjM6XG4gICAgICAgIC8vIEtleSBTZXJ2ZXIgUHJlZmVyZW5jZXNcbiAgICAgICAgcmVhZF9hcnJheS5jYWxsKHRoaXMsICdrZXlTZXJ2ZXJQcmVmZXJlbmNlc3MnLCBieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI0OlxuICAgICAgICAvLyBQcmVmZXJyZWQgS2V5IFNlcnZlclxuICAgICAgICB0aGlzLnByZWZlcnJlZEtleVNlcnZlciA9IGJ5dGVzLnN1YnN0cihteXBvcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyNTpcbiAgICAgICAgLy8gUHJpbWFyeSBVc2VyIElEXG4gICAgICAgIHRoaXMuaXNQcmltYXJ5VXNlcklEID0gYnl0ZXNbbXlwb3MrK10gIT0gMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI2OlxuICAgICAgICAvLyBQb2xpY3kgVVJJXG4gICAgICAgIHRoaXMucG9saWN5VVJJID0gYnl0ZXMuc3Vic3RyKG15cG9zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI3OlxuICAgICAgICAvLyBLZXkgRmxhZ3NcbiAgICAgICAgcmVhZF9hcnJheS5jYWxsKHRoaXMsICdrZXlGbGFncycsIGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjg6XG4gICAgICAgIC8vIFNpZ25lcidzIFVzZXIgSURcbiAgICAgICAgdGhpcy5zaWduZXJzVXNlcklkICs9IGJ5dGVzLnN1YnN0cihteXBvcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOTpcbiAgICAgICAgLy8gUmVhc29uIGZvciBSZXZvY2F0aW9uXG4gICAgICAgIHRoaXMucmVhc29uRm9yUmV2b2NhdGlvbkZsYWcgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICB0aGlzLnJlYXNvbkZvclJldm9jYXRpb25TdHJpbmcgPSBieXRlcy5zdWJzdHIobXlwb3MpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzA6XG4gICAgICAgIC8vIEZlYXR1cmVzXG4gICAgICAgIHJlYWRfYXJyYXkuY2FsbCh0aGlzLCAnZmVhdHVyZXMnLCBieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDMxOlxuICAgICAgICAvLyBTaWduYXR1cmUgVGFyZ2V0XG4gICAgICAgIC8vICgxIG9jdGV0IHB1YmxpYy1rZXkgYWxnb3JpdGhtLCAxIG9jdGV0IGhhc2ggYWxnb3JpdGhtLCBOIG9jdGV0cyBoYXNoKVxuICAgICAgICB0aGlzLnNpZ25hdHVyZVRhcmdldFB1YmxpY0tleUFsZ29yaXRobSA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgIHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG5cbiAgICAgICAgdmFyIGxlbiA9IGNyeXB0by5nZXRIYXNoQnl0ZUxlbmd0aCh0aGlzLnNpZ25hdHVyZVRhcmdldEhhc2hBbGdvcml0aG0pO1xuXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaCA9IGJ5dGVzLnN1YnN0cihteXBvcywgbGVuKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDMyOlxuICAgICAgICAvLyBFbWJlZGRlZCBTaWduYXR1cmVcbiAgICAgICAgdGhpcy5lbWJlZGRlZFNpZ25hdHVyZSA9IG5ldyBwYWNrZXRfc2lnbmF0dXJlKCk7XG4gICAgICAgIHRoaXMuZW1iZWRkZWRTaWduYXR1cmUucmVhZChieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB1dGlsLnByaW50X2Vycm9yKFwib3BlbnBncC5wYWNrZXQuc2lnbmF0dXJlLmpzXFxuXCIgK1xuICAgICAgICAgICd1bmtub3duIHNpZ25hdHVyZSBzdWJwYWNrZXQgdHlwZSAnICsgdHlwZSArIFwiIEA6XCIgKyBteXBvcyArXG4gICAgICAgICAgXCIgc3VicGxlbjpcIiArIHN1YnBsZW4gKyBcIiBsZW46XCIgKyBsZW4pO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH07XG5cbiAgLy8gUHJvZHVjZXMgZGF0YSB0byBwcm9kdWNlIHNpZ25hdHVyZSBvblxuICB0aGlzLnRvU2lnbiA9IGZ1bmN0aW9uKHR5cGUsIGRhdGEpIHtcbiAgICB2YXIgdCA9IGVudW1zLnNpZ25hdHVyZTtcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSB0LmJpbmFyeTpcbiAgICAgIGNhc2UgdC50ZXh0OlxuICAgICAgICByZXR1cm4gZGF0YS5nZXRCeXRlcygpO1xuXG4gICAgICBjYXNlIHQuc3RhbmRhbG9uZTpcbiAgICAgICAgcmV0dXJuICcnO1xuXG4gICAgICBjYXNlIHQuY2VydF9nZW5lcmljOlxuICAgICAgY2FzZSB0LmNlcnRfcGVyc29uYTpcbiAgICAgIGNhc2UgdC5jZXJ0X2Nhc3VhbDpcbiAgICAgIGNhc2UgdC5jZXJ0X3Bvc2l0aXZlOlxuICAgICAgY2FzZSB0LmNlcnRfcmV2b2NhdGlvbjpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBwYWNrZXQsIHRhZztcblxuICAgICAgICAgIGlmIChkYXRhLnVzZXJpZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0YWcgPSAweEI0O1xuICAgICAgICAgICAgcGFja2V0ID0gZGF0YS51c2VyaWQ7XG4gICAgICAgICAgfSBlbHNlIGlmIChkYXRhLnVzZXJhdHRyaWJ1dGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGFnID0gMHhEMTtcbiAgICAgICAgICAgIHBhY2tldCA9IGRhdGEudXNlcmF0dHJpYnV0ZTtcbiAgICAgICAgICB9IGVsc2UgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgYSB1c2VyaWQgb3IgdXNlcmF0dHJpYnV0ZSBwYWNrZXQgbmVlZHMgdG8gYmUgJyArXG4gICAgICAgICAgICAgICdzdXBwbGllZCBmb3IgY2VydGlmaWNhdGlvbi4nKTtcblxuICAgICAgICAgIHZhciBieXRlcyA9IHBhY2tldC53cml0ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIHRoaXMudG9TaWduKHQua2V5LCBkYXRhKSArXG4gICAgICAgICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKHRhZykgK1xuICAgICAgICAgICAgdXRpbC53cml0ZU51bWJlcihieXRlcy5sZW5ndGgsIDQpICtcbiAgICAgICAgICAgIGJ5dGVzO1xuICAgICAgICB9XG4gICAgICBjYXNlIHQuc3Via2V5X2JpbmRpbmc6XG4gICAgICBjYXNlIHQua2V5X2JpbmRpbmc6XG4gICAgICAgIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50b1NpZ24odC5rZXksIGRhdGEpICsgdGhpcy50b1NpZ24odC5rZXksIHtcbiAgICAgICAgICAgIGtleTogZGF0YS5iaW5kXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgdC5rZXk6XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoZGF0YS5rZXkgPT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdLZXkgcGFja2V0IGlzIHJlcXVpcmVkIGZvciB0aGlzIHNpZ3RhdHVyZS4nKTtcblxuICAgICAgICAgIHJldHVybiBkYXRhLmtleS53cml0ZU9sZCgpO1xuICAgICAgICB9XG4gICAgICBjYXNlIHQua2V5X3Jldm9jYXRpb246XG4gICAgICBjYXNlIHQuc3Via2V5X3Jldm9jYXRpb246XG4gICAgICAgIHJldHVybiB0aGlzLnRvU2lnbih0LmtleSwgZGF0YSk7XG4gICAgICBjYXNlIHQudGltZXN0YW1wOlxuICAgICAgICByZXR1cm4gJyc7XG4gICAgICBjYXNlIHQudGhpcmRfcGFydHk6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHNpZ25hdHVyZSB0eXBlLicpXG4gICAgfVxuICB9XG5cblxuICB0aGlzLmNhbGN1bGF0ZVRyYWlsZXIgPSBmdW5jdGlvbigpIHtcbiAgICAvLyBjYWxjdWxhdGluZyB0aGUgdHJhaWxlclxuICAgIHZhciB0cmFpbGVyID0gJyc7XG4gICAgLy8gVjMgc2lnbmF0dXJlcyBkb24ndCBoYXZlIGEgdHJhaWxlclxuICAgIGlmICh0aGlzLnZlcnNpb24gPT0gMykgcmV0dXJuIHRyYWlsZXI7XG4gICAgdHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDQpOyAvLyBWZXJzaW9uXG4gICAgdHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkYpO1xuICAgIHRyYWlsZXIgKz0gdXRpbC53cml0ZU51bWJlcih0aGlzLnNpZ25hdHVyZURhdGEubGVuZ3RoLCA0KTtcbiAgICByZXR1cm4gdHJhaWxlclxuICB9XG5cblxuICAvKipcbiAgICogdmVyaWZ5cyB0aGUgc2lnbmF0dXJlIHBhY2tldC4gTm90ZTogbm90IHNpZ25hdHVyZSB0eXBlcyBhcmUgaW1wbGVtZW50ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBkYXRhIGRhdGEgd2hpY2ggb24gdGhlIHNpZ25hdHVyZSBhcHBsaWVzXG4gICAqIEBwYXJhbSB7cHVibGljX3N1YmtleXxwYWNrZXRfcHVibGljX2tleX0ga2V5IHRoZSBwdWJsaWMga2V5IHRvIHZlcmlmeSB0aGUgc2lnbmF0dXJlXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgbWVzc2FnZSBpcyB2ZXJpZmllZCwgZWxzZSBmYWxzZS5cbiAgICovXG4gIHRoaXMudmVyaWZ5ID0gZnVuY3Rpb24oa2V5LCBkYXRhKSB7XG4gICAgdmFyIHNpZ25hdHVyZVR5cGUgPSBlbnVtcy53cml0ZShlbnVtcy5zaWduYXR1cmUsIHRoaXMuc2lnbmF0dXJlVHlwZSksXG4gICAgICBwdWJsaWNLZXlBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMucHVibGljS2V5QWxnb3JpdGhtKSxcbiAgICAgIGhhc2hBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG0pO1xuXG4gICAgdmFyIGJ5dGVzID0gdGhpcy50b1NpZ24oc2lnbmF0dXJlVHlwZSwgZGF0YSksXG4gICAgICB0cmFpbGVyID0gdGhpcy5jYWxjdWxhdGVUcmFpbGVyKCk7XG5cblxuICAgIHZhciBtcGljb3VudCA9IDA7XG4gICAgLy8gQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgUlNBIHNpZ25hdHVyZXM6XG4gICAgLy8gXHQgICAgLSBtdWx0aXByZWNpc2lvbiBudW1iZXIgKE1QSSkgb2YgUlNBIHNpZ25hdHVyZSB2YWx1ZSBtKipkIG1vZCBuLlxuICAgIGlmIChwdWJsaWNLZXlBbGdvcml0aG0gPiAwICYmIHB1YmxpY0tleUFsZ29yaXRobSA8IDQpXG4gICAgICBtcGljb3VudCA9IDE7XG4gICAgLy8gICAgQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRFNBIHNpZ25hdHVyZXM6XG4gICAgLy8gICAgICAtIE1QSSBvZiBEU0EgdmFsdWUgci5cbiAgICAvLyAgICAgIC0gTVBJIG9mIERTQSB2YWx1ZSBzLlxuICAgIGVsc2UgaWYgKHB1YmxpY0tleUFsZ29yaXRobSA9PSAxNylcbiAgICAgIG1waWNvdW50ID0gMjtcblxuICAgIHZhciBtcGkgPSBbXSxcbiAgICAgIGkgPSAwO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbXBpY291bnQ7IGorKykge1xuICAgICAgbXBpW2pdID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgICBpICs9IG1waVtqXS5yZWFkKHRoaXMuc2lnbmF0dXJlLnN1YnN0cihpKSk7XG4gICAgfVxuXG4gICAgdGhpcy52ZXJpZmllZCA9IGNyeXB0by5zaWduYXR1cmUudmVyaWZ5KHB1YmxpY0tleUFsZ29yaXRobSxcbiAgICAgIGhhc2hBbGdvcml0aG0sIG1waSwga2V5Lm1waSxcbiAgICAgIGJ5dGVzICsgdGhpcy5zaWduYXR1cmVEYXRhICsgdHJhaWxlcik7XG5cbiAgICByZXR1cm4gdGhpcy52ZXJpZmllZDtcbiAgfVxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3ltLiBFbmNyeXB0ZWQgSW50ZWdyaXR5IFByb3RlY3RlZCBEYXRhIFxuICogUGFja2V0IChUYWcgMTgpXG4gKiBcbiAqIFJGQzQ4ODAgNS4xMzogVGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQgRGF0YSBwYWNrZXQgaXNcbiAqIGEgdmFyaWFudCBvZiB0aGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXQuIEl0IGlzIGEgbmV3IGZlYXR1cmVcbiAqIGNyZWF0ZWQgZm9yIE9wZW5QR1AgdGhhdCBhZGRyZXNzZXMgdGhlIHByb2JsZW0gb2YgZGV0ZWN0aW5nIGEgbW9kaWZpY2F0aW9uIHRvXG4gKiBlbmNyeXB0ZWQgZGF0YS4gSXQgaXMgdXNlZCBpbiBjb21iaW5hdGlvbiB3aXRoIGEgTW9kaWZpY2F0aW9uIERldGVjdGlvbiBDb2RlXG4gKiBwYWNrZXQuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkKCkge1xuICAvKiogVGhlIGVuY3J5cHRlZCBwYXlsb2FkLiAqL1xuICB0aGlzLmVuY3J5cHRlZCA9IG51bGw7IC8vIHN0cmluZ1xuICAvKiogQHR5cGUge0Jvb2xlYW59XG4gICAqIElmIGFmdGVyIGRlY3J5cHRpbmcgdGhlIHBhY2tldCB0aGlzIGlzIHNldCB0byB0cnVlLFxuICAgKiBhIG1vZGlmaWNhdGlvbiBoYXMgYmVlbiBkZXRlY3RlZCBhbmQgdGh1cyB0aGUgY29udGVudHNcbiAgICogc2hvdWxkIGJlIGRpc2NhcmRlZC5cbiAgICovXG4gIHRoaXMubW9kaWZpY2F0aW9uID0gZmFsc2U7XG4gIHRoaXMucGFja2V0cztcblxuXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgLy8gLSBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gVGhlIG9ubHkgY3VycmVudGx5IGRlZmluZWQgdmFsdWUgaXNcbiAgICAvLyAxLlxuICAgIHZhciB2ZXJzaW9uID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcblxuICAgIGlmICh2ZXJzaW9uICE9IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBwYWNrZXQgdmVyc2lvbi4nKTtcbiAgICB9XG5cbiAgICAvLyAtIEVuY3J5cHRlZCBkYXRhLCB0aGUgb3V0cHV0IG9mIHRoZSBzZWxlY3RlZCBzeW1tZXRyaWMta2V5IGNpcGhlclxuICAgIC8vICAgb3BlcmF0aW5nIGluIENpcGhlciBGZWVkYmFjayBtb2RlIHdpdGggc2hpZnQgYW1vdW50IGVxdWFsIHRvIHRoZVxuICAgIC8vICAgYmxvY2sgc2l6ZSBvZiB0aGUgY2lwaGVyIChDRkItbiB3aGVyZSBuIGlzIHRoZSBibG9jayBzaXplKS5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGJ5dGVzLnN1YnN0cigxKTtcbiAgfVxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcblxuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDEpIC8vIFZlcnNpb25cbiAgICArIHRoaXMuZW5jcnlwdGVkO1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oc2Vzc2lvbktleUFsZ29yaXRobSwga2V5KSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy5wYWNrZXRzLndyaXRlKClcblxuICAgIHZhciBwcmVmaXhyYW5kb20gPSBjcnlwdG8uZ2V0UHJlZml4UmFuZG9tKHNlc3Npb25LZXlBbGdvcml0aG0pO1xuICAgIHZhciBwcmVmaXggPSBwcmVmaXhyYW5kb20gKyBwcmVmaXhyYW5kb20uY2hhckF0KHByZWZpeHJhbmRvbS5sZW5ndGggLSAyKSArIHByZWZpeHJhbmRvbS5jaGFyQXQocHJlZml4cmFuZG9tLmxlbmd0aCAtXG4gICAgICAxKVxuXG4gICAgdmFyIHRvaGFzaCA9IGJ5dGVzO1xuXG5cbiAgICAvLyBNb2RpZmljYXRpb24gZGV0ZWN0aW9uIGNvZGUgcGFja2V0LlxuICAgIHRvaGFzaCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RDMpO1xuICAgIHRvaGFzaCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MTQpO1xuXG5cbiAgICB0b2hhc2ggKz0gY3J5cHRvLmhhc2guc2hhMShwcmVmaXggKyB0b2hhc2gpO1xuXG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5jZmIuZW5jcnlwdChwcmVmaXhyYW5kb20sXG4gICAgICBzZXNzaW9uS2V5QWxnb3JpdGhtLCB0b2hhc2gsIGtleSwgZmFsc2UpLnN1YnN0cmluZygwLFxuICAgICAgcHJlZml4Lmxlbmd0aCArIHRvaGFzaC5sZW5ndGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBlbmNyeXB0ZWQgZGF0YSBjb250YWluZWQgaW4gdGhpcyBvYmplY3QgcmVhZF9wYWNrZXQgbXVzdFxuICAgKiBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZVxuICAgKiBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBzZXNzaW9uS2V5QWxnb3JpdGhtXG4gICAqICAgICAgICAgICAgVGhlIHNlbGVjdGVkIHN5bW1ldHJpYyBlbmNyeXB0aW9uIGFsZ29yaXRobSB0byBiZSB1c2VkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgVGhlIGtleSBvZiBjaXBoZXIgYmxvY2tzaXplIGxlbmd0aCB0byBiZSB1c2VkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gVGhlIGRlY3J5cHRlZCBkYXRhIG9mIHRoaXMgcGFja2V0XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihzZXNzaW9uS2V5QWxnb3JpdGhtLCBrZXkpIHtcbiAgICB2YXIgZGVjcnlwdGVkID0gY3J5cHRvLmNmYi5kZWNyeXB0KFxuICAgICAgc2Vzc2lvbktleUFsZ29yaXRobSwga2V5LCB0aGlzLmVuY3J5cHRlZCwgZmFsc2UpO1xuXG5cbiAgICAvLyB0aGVyZSBtdXN0IGJlIGEgbW9kaWZpY2F0aW9uIGRldGVjdGlvbiBjb2RlIHBhY2tldCBhcyB0aGVcbiAgICAvLyBsYXN0IHBhY2tldCBhbmQgZXZlcnl0aGluZyBnZXRzIGhhc2hlZCBleGNlcHQgdGhlIGhhc2ggaXRzZWxmXG4gICAgdGhpcy5oYXNoID0gY3J5cHRvLmhhc2guc2hhMShcbiAgICAgIGNyeXB0by5jZmIubWRjKHNlc3Npb25LZXlBbGdvcml0aG0sIGtleSwgdGhpcy5lbmNyeXB0ZWQpICsgZGVjcnlwdGVkLnN1YnN0cmluZygwLCBkZWNyeXB0ZWQubGVuZ3RoIC0gMjApKTtcblxuXG4gICAgdmFyIG1kYyA9IGRlY3J5cHRlZC5zdWJzdHIoZGVjcnlwdGVkLmxlbmd0aCAtIDIwLCAyMCk7XG5cbiAgICBpZiAodGhpcy5oYXNoICE9IG1kYykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2RpZmljYXRpb24gZGV0ZWN0ZWQuJyk7XG4gICAgfSBlbHNlXG4gICAgICB0aGlzLnBhY2tldHMucmVhZChkZWNyeXB0ZWQuc3Vic3RyKDAsIGRlY3J5cHRlZC5sZW5ndGggLSAyMikpO1xuICB9XG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHR5cGVfczJrID0gcmVxdWlyZSgnLi4vdHlwZS9zMmsuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgUGFja2V0cyAoVGFnIDEpXG4gKiBcbiAqIFJGQzQ4ODAgNS4xOiBBIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldCBob2xkcyB0aGUgc2Vzc2lvbiBrZXlcbiAqIHVzZWQgdG8gZW5jcnlwdCBhIG1lc3NhZ2UuIFplcm8gb3IgbW9yZSBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleVxuICogcGFja2V0cyBhbmQvb3IgU3ltbWV0cmljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgcGFja2V0cyBtYXkgcHJlY2VkZSBhXG4gKiBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCwgd2hpY2ggaG9sZHMgYW4gZW5jcnlwdGVkIG1lc3NhZ2UuIFRoZVxuICogbWVzc2FnZSBpcyBlbmNyeXB0ZWQgd2l0aCB0aGUgc2Vzc2lvbiBrZXksIGFuZCB0aGUgc2Vzc2lvbiBrZXkgaXMgaXRzZWxmXG4gKiBlbmNyeXB0ZWQgYW5kIHN0b3JlZCBpbiB0aGUgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldChzKS4gVGhlXG4gKiBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCBpcyBwcmVjZWRlZCBieSBvbmUgUHVibGljLUtleSBFbmNyeXB0ZWRcbiAqIFNlc3Npb24gS2V5IHBhY2tldCBmb3IgZWFjaCBPcGVuUEdQIGtleSB0byB3aGljaCB0aGUgbWVzc2FnZSBpcyBlbmNyeXB0ZWQuXG4gKiBUaGUgcmVjaXBpZW50IG9mIHRoZSBtZXNzYWdlIGZpbmRzIGEgc2Vzc2lvbiBrZXkgdGhhdCBpcyBlbmNyeXB0ZWQgdG8gdGhlaXJcbiAqIHB1YmxpYyBrZXksIGRlY3J5cHRzIHRoZSBzZXNzaW9uIGtleSwgYW5kIHRoZW4gdXNlcyB0aGUgc2Vzc2lvbiBrZXkgdG9cbiAqIGRlY3J5cHQgdGhlIG1lc3NhZ2UuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3N5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkoKSB7XG4gIHRoaXMudGFnID0gMztcbiAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9ICdhZXMyNTYnO1xuICB0aGlzLmVuY3J5cHRlZCA9IG51bGw7XG4gIHRoaXMuczJrID0gbmV3IHR5cGVfczJrKCk7XG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgc3ltbWV0cmljIGVuY3J5cHRlZCBzZXNzaW9uIGtleSBwYWNrZXQgKHRhZyAzKS5cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDEgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5cbiAgICogICAgICAgICAgICBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZlxuICAgKiAgICAgICAgICAgIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IE9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gVGhlIG9ubHkgY3VycmVudGx5IGRlZmluZWQgdmVyc2lvbiBpcyA0LlxuICAgIHRoaXMudmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQoMCk7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgc3ltbWV0cmljIGFsZ29yaXRobSB1c2VkLlxuICAgIHZhciBhbGdvID0gZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIGJ5dGVzLmNoYXJDb2RlQXQoMSkpO1xuXG4gICAgLy8gQSBzdHJpbmctdG8ta2V5IChTMkspIHNwZWNpZmllciwgbGVuZ3RoIGFzIGRlZmluZWQgYWJvdmUuXG4gICAgdmFyIHMya2xlbmd0aCA9IHRoaXMuczJrLnJlYWQoYnl0ZXMuc3Vic3RyKDIpKTtcblxuICAgIC8vIE9wdGlvbmFsbHksIHRoZSBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXkgaXRzZWxmLCB3aGljaCBpcyBkZWNyeXB0ZWRcbiAgICAvLyB3aXRoIHRoZSBzdHJpbmctdG8ta2V5IG9iamVjdC5cbiAgICB2YXIgZG9uZSA9IHMya2xlbmd0aCArIDI7XG5cbiAgICBpZiAoZG9uZSA8IGJ5dGVzLmxlbmd0aCkge1xuICAgICAgdGhpcy5lbmNyeXB0ZWQgPSBieXRlcy5zdWJzdHIoZG9uZSk7XG4gICAgICB0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtID0gYWxnb1xuICAgIH0gZWxzZVxuICAgICAgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtID0gYWxnbztcbiAgfVxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYWxnbyA9IHRoaXMuZW5jcnlwdGVkID09IG51bGwgP1xuICAgICAgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtIDpcbiAgICAgIHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG07XG5cbiAgICB2YXIgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMudmVyc2lvbikgK1xuICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIGFsZ28pKSArXG4gICAgICB0aGlzLnMyay53cml0ZSgpO1xuXG4gICAgaWYgKHRoaXMuZW5jcnlwdGVkICE9IG51bGwpXG4gICAgICBieXRlcyArPSB0aGlzLmVuY3J5cHRlZDtcbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuICAvKipcbiAgICogRGVjcnlwdHMgdGhlIHNlc3Npb24ga2V5IChvbmx5IGZvciBwdWJsaWMga2V5IGVuY3J5cHRlZCBzZXNzaW9uIGtleVxuICAgKiBwYWNrZXRzICh0YWcgMSlcbiAgICogXG4gICAqIEBwYXJhbSB7b3BlbnBncF9tc2dfbWVzc2FnZX0gbXNnXG4gICAqICAgICAgICAgICAgVGhlIG1lc3NhZ2Ugb2JqZWN0ICh3aXRoIG1lbWJlciBlbmNyeXB0ZWREYXRhXG4gICAqIEBwYXJhbSB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleX0ga2V5XG4gICAqICAgICAgICAgICAgUHJpdmF0ZSBrZXkgd2l0aCBzZWNNUElzIHVubG9ja2VkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gVGhlIHVuZW5jcnlwdGVkIHNlc3Npb24ga2V5XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihwYXNzcGhyYXNlKSB7XG4gICAgdmFyIGFsZ28gPSB0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtICE9IG51bGwgP1xuICAgICAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSA6XG4gICAgICB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG07XG5cblxuICAgIHZhciBsZW5ndGggPSBjcnlwdG8uY2lwaGVyW2FsZ29dLmtleVNpemU7XG4gICAgdmFyIGtleSA9IHRoaXMuczJrLnByb2R1Y2Vfa2V5KHBhc3NwaHJhc2UsIGxlbmd0aCk7XG5cbiAgICBpZiAodGhpcy5lbmNyeXB0ZWQgPT0gbnVsbCkge1xuICAgICAgdGhpcy5zZXNzaW9uS2V5ID0ga2V5O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBkZWNyeXB0ZWQgPSBjcnlwdG8uY2ZiLmRlY3J5cHQoXG4gICAgICAgIHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0sIGtleSwgdGhpcy5lbmNyeXB0ZWQsIHRydWUpO1xuXG4gICAgICB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYyxcbiAgICAgICAgZGVjcnlwdGVkWzBdLmtleUNvZGVBdCgpKTtcblxuICAgICAgdGhpcy5zZXNzaW9uS2V5ID0gZGVjcnlwdGVkLnN1YnN0cigxKTtcbiAgICB9XG4gIH1cblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihwYXNzcGhyYXNlKSB7XG4gICAgdmFyIGxlbmd0aCA9IGNyeXB0by5nZXRLZXlMZW5ndGgodGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSk7XG4gICAgdmFyIGtleSA9IHRoaXMuczJrLnByb2R1Y2Vfa2V5KHBhc3NwaHJhc2UsIGxlbmd0aCk7XG5cbiAgICB2YXIgcHJpdmF0ZV9rZXkgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuICAgICAgZW51bXMud3JpdGUoZW51bXMuc3ltbWV0cmljLCB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0pKSArXG5cbiAgICBjcnlwdG8uZ2V0UmFuZG9tQnl0ZXMoXG4gICAgICBjcnlwdG8uZ2V0S2V5TGVuZ3RoKHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSkpO1xuXG4gICAgdGhpcy5lbmNyeXB0ZWQgPSBjcnlwdG8uY2ZiLmVuY3J5cHQoXG4gICAgICBjcnlwdG8uZ2V0UHJlZml4UmFuZG9tKHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0pLFxuICAgICAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSwga2V5LCBwcml2YXRlX2tleSwgdHJ1ZSk7XG4gIH1cbn07XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnLi4vY3J5cHRvJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCAoVGFnIDkpXG4gKiBcbiAqIFJGQzQ4ODAgNS43OiBUaGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXQgY29udGFpbnMgZGF0YSBlbmNyeXB0ZWRcbiAqIHdpdGggYSBzeW1tZXRyaWMta2V5IGFsZ29yaXRobS4gV2hlbiBpdCBoYXMgYmVlbiBkZWNyeXB0ZWQsIGl0IGNvbnRhaW5zIG90aGVyXG4gKiBwYWNrZXRzICh1c3VhbGx5IGEgbGl0ZXJhbCBkYXRhIHBhY2tldCBvciBjb21wcmVzc2VkIGRhdGEgcGFja2V0LCBidXQgaW5cbiAqIHRoZW9yeSBvdGhlciBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIHBhY2tldHMgb3Igc2VxdWVuY2VzIG9mIHBhY2tldHNcbiAqIHRoYXQgZm9ybSB3aG9sZSBPcGVuUEdQIG1lc3NhZ2VzKS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9zeW1tZXRyaWNhbGx5X2VuY3J5cHRlZCgpIHtcbiAgdGhpcy5lbmNyeXB0ZWQgPSBudWxsO1xuICAvKiogRGVjcnlwdGVkIHBhY2tldHMgY29udGFpbmVkIHdpdGhpbi4gXG4gICAqIEB0eXBlIHtvcGVucGdwX3BhY2tldGxpc3R9ICovXG4gIHRoaXMucGFja2V0cztcblxuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHRoaXMuZW5jcnlwdGVkID0gYnl0ZXM7XG4gIH1cblxuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZW5jcnlwdGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFN5bW1ldHJpY2FsbHkgZGVjcnlwdCB0aGUgcGFja2V0IGRhdGFcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gc2Vzc2lvbktleUFsZ29yaXRobVxuICAgKiAgICAgICAgICAgICBTeW1tZXRyaWMga2V5IGFsZ29yaXRobSB0byB1c2UgLy8gU2VlIFJGQzQ4ODAgOS4yXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAgICogICAgICAgICAgICAgS2V5IGFzIHN0cmluZyB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIGxlbmd0aCB0byB0aGVcbiAgICogICAgICAgICAgICBhbGdvcml0aG1cbiAgICogQHJldHVybiBUaGUgZGVjcnlwdGVkIGRhdGE7XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihzZXNzaW9uS2V5QWxnb3JpdGhtLCBrZXkpIHtcbiAgICB2YXIgZGVjcnlwdGVkID0gY3J5cHRvLmNmYi5kZWNyeXB0KFxuICAgICAgc2Vzc2lvbktleUFsZ29yaXRobSwga2V5LCB0aGlzLmVuY3J5cHRlZCwgdHJ1ZSk7XG5cbiAgICB0aGlzLnBhY2tldHMucmVhZChkZWNyeXB0ZWQpO1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYWxnbywga2V5KSB7XG4gICAgdmFyIGRhdGEgPSB0aGlzLnBhY2tldHMud3JpdGUoKTtcblxuICAgIHRoaXMuZW5jcnlwdGVkID0gY3J5cHRvLmNmYi5lbmNyeXB0KFxuICAgICAgY3J5cHRvLmdldFByZWZpeFJhbmRvbShhbGdvKSwgYWxnbywgZGF0YSwga2V5LCB0cnVlKTtcbiAgfVxufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3RydXN0KCkge1xuXG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIFxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBVc2VyIEF0dHJpYnV0ZSBQYWNrZXQgKFRhZyAxNylcbiAqICBUaGUgVXNlciBBdHRyaWJ1dGUgcGFja2V0IGlzIGEgdmFyaWF0aW9uIG9mIHRoZSBVc2VyIElEIHBhY2tldC4gIEl0XG4gKiAgaXMgY2FwYWJsZSBvZiBzdG9yaW5nIG1vcmUgdHlwZXMgb2YgZGF0YSB0aGFuIHRoZSBVc2VyIElEIHBhY2tldCxcbiAqICB3aGljaCBpcyBsaW1pdGVkIHRvIHRleHQuICBMaWtlIHRoZSBVc2VyIElEIHBhY2tldCwgYSBVc2VyIEF0dHJpYnV0ZVxuICogIHBhY2tldCBtYXkgYmUgY2VydGlmaWVkIGJ5IHRoZSBrZXkgb3duZXIgKFwic2VsZi1zaWduZWRcIikgb3IgYW55IG90aGVyXG4gKiAga2V5IG93bmVyIHdobyBjYXJlcyB0byBjZXJ0aWZ5IGl0LiAgRXhjZXB0IGFzIG5vdGVkLCBhIFVzZXIgQXR0cmlidXRlXG4gKiAgcGFja2V0IG1heSBiZSB1c2VkIGFueXdoZXJlIHRoYXQgYSBVc2VyIElEIHBhY2tldCBtYXkgYmUgdXNlZC5cbiAqXG4gKiAgV2hpbGUgVXNlciBBdHRyaWJ1dGUgcGFja2V0cyBhcmUgbm90IGEgcmVxdWlyZWQgcGFydCBvZiB0aGUgT3BlblBHUFxuICogIHN0YW5kYXJkLCBpbXBsZW1lbnRhdGlvbnMgU0hPVUxEIHByb3ZpZGUgYXQgbGVhc3QgZW5vdWdoXG4gKiAgY29tcGF0aWJpbGl0eSB0byBwcm9wZXJseSBoYW5kbGUgYSBjZXJ0aWZpY2F0aW9uIHNpZ25hdHVyZSBvbiB0aGVcbiAqICBVc2VyIEF0dHJpYnV0ZSBwYWNrZXQuICBBIHNpbXBsZSB3YXkgdG8gZG8gdGhpcyBpcyBieSB0cmVhdGluZyB0aGVcbiAqICBVc2VyIEF0dHJpYnV0ZSBwYWNrZXQgYXMgYSBVc2VyIElEIHBhY2tldCB3aXRoIG9wYXF1ZSBjb250ZW50cywgYnV0XG4gKiAgYW4gaW1wbGVtZW50YXRpb24gbWF5IHVzZSBhbnkgbWV0aG9kIGRlc2lyZWQuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3VzZXJfYXR0cmlidXRlKCkge1xuICB0aGlzLnRhZyA9IDE3O1xuICB0aGlzLmF0dHJpYnV0ZXMgPSBbXTtcblxuICAvKipcbiAgICogcGFyc2luZyBmdW5jdGlvbiBmb3IgYSB1c2VyIGF0dHJpYnV0ZSBwYWNrZXQgKHRhZyAxNykuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBwYXlsb2FkIG9mIGEgdGFnIDE3IHBhY2tldFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIHBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIGxlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IG9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKGkgPCBieXRlcy5sZW5ndGgpIHtcbiAgICAgIHZhciBsZW4gPSBvcGVucGdwX3BhY2tldC5yZWFkX3NpbXBsZV9sZW5ndGgoYnl0ZXMpO1xuXG4gICAgICBpICs9IGxlbi5vZmZzZXQ7XG4gICAgICB0aGlzLmF0dHJpYnV0ZXMucHVzaChieXRlcy5zdWJzdHIoaSwgbGVuLmxlbikpO1xuICAgICAgaSArPSBsZW4ubGVuO1xuICAgIH1cbiAgfVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgVXNlciBJRCBQYWNrZXQgKFRhZyAxMylcbiAqIEEgVXNlciBJRCBwYWNrZXQgY29uc2lzdHMgb2YgVVRGLTggdGV4dCB0aGF0IGlzIGludGVuZGVkIHRvIHJlcHJlc2VudFxuICogdGhlIG5hbWUgYW5kIGVtYWlsIGFkZHJlc3Mgb2YgdGhlIGtleSBob2xkZXIuICBCeSBjb252ZW50aW9uLCBpdFxuICogaW5jbHVkZXMgYW4gUkZDIDI4MjIgW1JGQzI4MjJdIG1haWwgbmFtZS1hZGRyLCBidXQgdGhlcmUgYXJlIG5vXG4gKiByZXN0cmljdGlvbnMgb24gaXRzIGNvbnRlbnQuICBUaGUgcGFja2V0IGxlbmd0aCBpbiB0aGUgaGVhZGVyXG4gKiBzcGVjaWZpZXMgdGhlIGxlbmd0aCBvZiB0aGUgVXNlciBJRC4gXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3VzZXJpZCgpIHtcbiAgLyoqIEB0eXBlIHtTdHJpbmd9IEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHVzZXIgaWQuIFVzdWFsbHkgaW4gdGhlIGZvcm1cbiAgICogSm9obiBEb2UgPGpvaG5AZXhhbXBsZS5jb20+IFxuICAgKi9cbiAgdGhpcy51c2VyaWQgPSAnJztcblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHVzZXIgaWQgcGFja2V0ICh0YWcgMTMpLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgcGF5bG9hZCBvZiBhIHRhZyAxMyBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZ1xuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBsZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dCBcbiAgICogYXQgcG9zaXRpb25cbiAgICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YX0gb2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHRoaXMudXNlcmlkID0gdXRpbC5kZWNvZGVfdXRmOChieXRlcyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdXNlciBpZCBwYWNrZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHVzZXJfaWQgdGhlIHVzZXIgaWQgYXMgc3RyaW5nIChcIkpvaG4gRG9lIDxqb2huLmRvZUBtYWlsLnVzXCIpXG4gICAqIEByZXR1cm4ge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHV0aWwuZW5jb2RlX3V0ZjgodGhpcy51c2VyaWQpO1xuICB9XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdHlwZSBrZXkgaWQgKFJGQzQ4ODAgMy4zKVxuICogIEEgS2V5IElEIGlzIGFuIGVpZ2h0LW9jdGV0IHNjYWxhciB0aGF0IGlkZW50aWZpZXMgYSBrZXkuXG4gICBJbXBsZW1lbnRhdGlvbnMgU0hPVUxEIE5PVCBhc3N1bWUgdGhhdCBLZXkgSURzIGFyZSB1bmlxdWUuICBUaGVcbiAgIHNlY3Rpb24gXCJFbmhhbmNlZCBLZXkgRm9ybWF0c1wiIGJlbG93IGRlc2NyaWJlcyBob3cgS2V5IElEcyBhcmVcbiAgIGZvcm1lZC5cbiAqL1xuZnVuY3Rpb24ga2V5aWQoKSB7XG5cbiAgdGhpcy5ieXRlcyA9ICcnO1xuXG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgbWV0aG9kIGZvciBhIGtleSBpZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgSW5wdXQgdG8gcmVhZCB0aGUga2V5IGlkIGZyb20gXG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gd2hlcmUgdG8gc3RhcnQgcmVhZGluZyB0aGUga2V5IFxuICAgKiBpZCBmcm9tIGlucHV0XG4gICAqIEByZXR1cm4ge29wZW5wZ3BfdHlwZV9rZXlpZH0gVGhpcyBvYmplY3RcbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdGhpcy5ieXRlcyA9IGJ5dGVzLnN1YnN0cigwLCA4KTtcbiAgfVxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5ieXRlcztcbiAgfVxuXG4gIHRoaXMudG9IZXggPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdXRpbC5oZXhzdHJkdW1wKHRoaXMuYnl0ZXMpO1xuICB9XG5cbiAgdGhpcy5lcXVhbHMgPSBmdW5jdGlvbihrZXlpZCkge1xuICAgIHJldHVybiB0aGlzLmJ5dGVzID09IGtleWlkLmJ5dGVzO1xuICB9XG5cbiAgdGhpcy5pc051bGwgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5ieXRlcyA9PT0gJyc7XG4gIH1cbn1cblxua2V5aWQubWFwVG9IZXggPSBmdW5jdGlvbihrZXlpZCkge1xuICByZXR1cm4ga2V5aWQudG9IZXgoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBrZXlpZDtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8vIEhpbnQ6IFdlIGhvbGQgb3VyIE1QSXMgYXMgYW4gYXJyYXkgb2Ygb2N0ZXRzIGluIGJpZyBlbmRpYW4gZm9ybWF0IHByZWNlZWRpbmcgYSB0d29cbi8vIG9jdGV0IHNjYWxhcjogTVBJOiBbYSxiLGMsZCxlLGZdXG4vLyAtIE1QSSBzaXplOiAoYSA8PCA4KSB8IGIgXG4vLyAtIE1QSSA9IGMgfCBkIDw8IDggfCBlIDw8ICgoTVBJLmxlbmd0aCAtMikqOCkgfCBmICgoTVBJLmxlbmd0aCAtMikqOClcblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuLi9jcnlwdG8vcHVibGljX2tleS9qc2JuLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjSW1wbGVtZW50YXRpb24gb2YgdHlwZSBNUEkgKFJGQzQ4ODAgMy4yKVxuICogTXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgKGFsc28gY2FsbGVkIE1QSXMpIGFyZSB1bnNpZ25lZCBpbnRlZ2VycyB1c2VkXG4gKiB0byBob2xkIGxhcmdlIGludGVnZXJzIHN1Y2ggYXMgdGhlIG9uZXMgdXNlZCBpbiBjcnlwdG9ncmFwaGljXG4gKiBjYWxjdWxhdGlvbnMuXG4gKiBBbiBNUEkgY29uc2lzdHMgb2YgdHdvIHBpZWNlczogYSB0d28tb2N0ZXQgc2NhbGFyIHRoYXQgaXMgdGhlIGxlbmd0aFxuICogb2YgdGhlIE1QSSBpbiBiaXRzIGZvbGxvd2VkIGJ5IGEgc3RyaW5nIG9mIG9jdGV0cyB0aGF0IGNvbnRhaW4gdGhlXG4gKiBhY3R1YWwgaW50ZWdlci5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtcGkoKSB7XG4gIC8qKiBBbiBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQgaW50ZWdlciAqL1xuICB0aGlzLmRhdGEgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIG1waSAoUkZDIDQ4ODAgMy4yKS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFBheWxvYWQgb2YgbXBpIGRhdGFcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IFxuICAgKiBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2YgXG4gICAqIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfdHlwZV9tcGl9IE9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgYml0cyA9IChieXRlcy5jaGFyQ29kZUF0KDApIDw8IDgpIHwgYnl0ZXMuY2hhckNvZGVBdCgxKTtcblxuICAgIC8vIEFkZGl0aW9uYWwgcnVsZXM6XG4gICAgLy9cbiAgICAvLyAgICBUaGUgc2l6ZSBvZiBhbiBNUEkgaXMgKChNUEkubGVuZ3RoICsgNykgLyA4KSArIDIgb2N0ZXRzLlxuICAgIC8vXG4gICAgLy8gICAgVGhlIGxlbmd0aCBmaWVsZCBvZiBhbiBNUEkgZGVzY3JpYmVzIHRoZSBsZW5ndGggc3RhcnRpbmcgZnJvbSBpdHNcbiAgICAvL1x0ICBtb3N0IHNpZ25pZmljYW50IG5vbi16ZXJvIGJpdC4gIFRodXMsIHRoZSBNUEkgWzAwIDAyIDAxXSBpcyBub3RcbiAgICAvLyAgICBmb3JtZWQgY29ycmVjdGx5LiAgSXQgc2hvdWxkIGJlIFswMCAwMSAwMV0uXG5cbiAgICAvLyBUT0RPOiBWZXJpZmljYXRpb24gb2YgdGhpcyBzaXplIG1ldGhvZCEgVGhpcyBzaXplIGNhbGN1bGF0aW9uIGFzXG4gICAgLy8gXHRcdCBzcGVjaWZpZWQgYWJvdmUgaXMgbm90IGFwcGxpY2FibGUgaW4gSmF2YVNjcmlwdFxuICAgIHZhciBieXRlbGVuID0gTWF0aC5jZWlsKGJpdHMgLyA4KTtcblxuICAgIHZhciByYXcgPSBieXRlcy5zdWJzdHIoMiwgYnl0ZWxlbik7XG4gICAgdGhpcy5mcm9tQnl0ZXMocmF3KTtcblxuICAgIHJldHVybiAyICsgYnl0ZWxlbjtcbiAgfVxuXG4gIHRoaXMuZnJvbUJ5dGVzID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB0aGlzLmRhdGEgPSBuZXcgQmlnSW50ZWdlcih1dGlsLmhleHN0cmR1bXAoYnl0ZXMpLCAxNik7XG4gIH1cblxuICB0aGlzLnRvQnl0ZXMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy53cml0ZSgpLnN1YnN0cigyKTtcbiAgfVxuXG4gIHRoaXMuYnl0ZUxlbmd0aCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvQnl0ZXMoKS5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgdGhlIG1waSBvYmplY3QgdG8gYSBzdHJpbmcgYXMgc3BlY2lmaWVkIGluIFJGQzQ4ODAgMy4yXG4gICAqIEByZXR1cm4ge1N0cmluZ30gbXBpIEJ5dGUgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhLnRvTVBJKCk7XG4gIH1cblxuICB0aGlzLnRvQmlnSW50ZWdlciA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGEuY2xvbmUoKTtcbiAgfVxuXG4gIHRoaXMuZnJvbUJpZ0ludGVnZXIgPSBmdW5jdGlvbihibikge1xuICAgIHRoaXMuZGF0YSA9IGJuLmNsb25lKCk7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RyaW5nLXRvLWtleSBzcGVjaWZpZXIgKFJGQzQ4ODAgMy43KVxuICogU3RyaW5nLXRvLWtleSAoUzJLKSBzcGVjaWZpZXJzIGFyZSB1c2VkIHRvIGNvbnZlcnQgcGFzc3BocmFzZSBzdHJpbmdzXG4gICBpbnRvIHN5bW1ldHJpYy1rZXkgZW5jcnlwdGlvbi9kZWNyeXB0aW9uIGtleXMuICBUaGV5IGFyZSB1c2VkIGluIHR3b1xuICAgcGxhY2VzLCBjdXJyZW50bHk6IHRvIGVuY3J5cHQgdGhlIHNlY3JldCBwYXJ0IG9mIHByaXZhdGUga2V5cyBpbiB0aGVcbiAgIHByaXZhdGUga2V5cmluZywgYW5kIHRvIGNvbnZlcnQgcGFzc3BocmFzZXMgdG8gZW5jcnlwdGlvbiBrZXlzIGZvclxuICAgc3ltbWV0cmljYWxseSBlbmNyeXB0ZWQgbWVzc2FnZXMuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gczJrKCkge1xuICAvKiogQHR5cGUge29wZW5wZ3AuaGFzaH0gKi9cbiAgdGhpcy5hbGdvcml0aG0gPSAnc2hhMjU2JztcbiAgLyoqIEB0eXBlIHtvcGVucGdwX3R5cGVfczJrLnR5cGV9ICovXG4gIHRoaXMudHlwZSA9ICdpdGVyYXRlZCc7XG4gIHRoaXMuYyA9IDk2O1xuICAvKiogQHR5cGUge29wZW5wZ3BfYnl0ZWFycmF5fSBcbiAgICogRWlnaHQgYnl0ZXMgb2Ygc2FsdC4gKi9cbiAgdGhpcy5zYWx0ID0gY3J5cHRvLnJhbmRvbS5nZXRSYW5kb21CeXRlcyg4KTtcblxuXG4gIC8vIEV4cG9uZW4gYmlhcywgZGVmaW5lZCBpbiBSRkM0ODgwXG4gIHZhciBleHBiaWFzID0gNjtcblxuICB0aGlzLmdldF9jb3VudCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAoMTYgKyAodGhpcy5jICYgMTUpKSA8PCAoKHRoaXMuYyA+PiA0KSArIGV4cGJpYXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgc3RyaW5nLXRvLWtleSBzcGVjaWZpZXIgKFJGQyA0ODgwIDMuNykuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIHN0cmluZy10by1rZXkgc3BlY2lmaWVyXG4gICAqIEByZXR1cm4ge0ludGVnZXJ9IEFjdHVhbCBsZW5ndGggb2YgdGhlIG9iamVjdFxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgaSA9IDA7XG4gICAgdGhpcy50eXBlID0gZW51bXMucmVhZChlbnVtcy5zMmssIGJ5dGVzLmNoYXJDb2RlQXQoaSsrKSk7XG4gICAgdGhpcy5hbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLmhhc2gsIGJ5dGVzLmNoYXJDb2RlQXQoaSsrKSk7XG5cbiAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgY2FzZSAnc2ltcGxlJzpcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3NhbHRlZCc6XG4gICAgICAgIHRoaXMuc2FsdCA9IGJ5dGVzLnN1YnN0cihpLCA4KTtcbiAgICAgICAgaSArPSA4O1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnaXRlcmF0ZWQnOlxuICAgICAgICB0aGlzLnNhbHQgPSBieXRlcy5zdWJzdHIoaSwgOCk7XG4gICAgICAgIGkgKz0gODtcblxuICAgICAgICAvLyBPY3RldCAxMDogY291bnQsIGEgb25lLW9jdGV0LCBjb2RlZCB2YWx1ZVxuICAgICAgICB0aGlzLmMgPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdnbnUnOlxuICAgICAgICBpZiAoYnl0ZXMuc3Vic3RyKGksIDMpID09IFwiR05VXCIpIHtcbiAgICAgICAgICBpICs9IDM7IC8vIEdOVVxuICAgICAgICAgIHZhciBnbnVFeHRUeXBlID0gMTAwMCArIGJ5dGVzLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgICAgICBpZiAoZ251RXh0VHlwZSA9PSAxMDAxKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBnbnVFeHRUeXBlO1xuICAgICAgICAgICAgLy8gR251UEcgZXh0ZW5zaW9uIG1vZGUgMTAwMSAtLSBkb24ndCB3cml0ZSBzZWNyZXQga2V5IGF0IGFsbFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIHMyayBnbnUgcHJvdGVjdGlvbiBtb2RlLlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBzMmsgdHlwZS5cIik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gczJrIHR5cGUuXCIpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICByZXR1cm4gaTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIHdyaXRlcyBhbiBzMmsgaGFzaCBiYXNlZCBvbiB0aGUgaW5wdXRzLlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFByb2R1Y2VkIGtleSBvZiBoYXNoQWxnb3JpdGhtIGhhc2ggbGVuZ3RoXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ5dGVzID0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5zMmssIHRoaXMudHlwZSkpO1xuICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMuaGFzaCwgdGhpcy5hbGdvcml0aG0pKTtcblxuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICBjYXNlICdzaW1wbGUnOlxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3NhbHRlZCc6XG4gICAgICAgIGJ5dGVzICs9IHRoaXMuc2FsdDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpdGVyYXRlZCc6XG4gICAgICAgIGJ5dGVzICs9IHRoaXMuc2FsdDtcbiAgICAgICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmMpO1xuICAgICAgICBicmVhaztcbiAgICB9O1xuXG4gICAgcmV0dXJuIGJ5dGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2R1Y2VzIGEga2V5IHVzaW5nIHRoZSBzcGVjaWZpZWQgcGFzc3BocmFzZSBhbmQgdGhlIGRlZmluZWQgXG4gICAqIGhhc2hBbGdvcml0aG0gXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzcGhyYXNlIFBhc3NwaHJhc2UgY29udGFpbmluZyB1c2VyIGlucHV0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gUHJvZHVjZWQga2V5IHdpdGggYSBsZW5ndGggY29ycmVzcG9uZGluZyB0byBcbiAgICogaGFzaEFsZ29yaXRobSBoYXNoIGxlbmd0aFxuICAgKi9cbiAgdGhpcy5wcm9kdWNlX2tleSA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UsIG51bUJ5dGVzKSB7XG4gICAgcGFzc3BocmFzZSA9IHV0aWwuZW5jb2RlX3V0ZjgocGFzc3BocmFzZSk7XG5cbiAgICBmdW5jdGlvbiByb3VuZChwcmVmaXgsIHMyaykge1xuICAgICAgdmFyIGFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLmhhc2gsIHMyay5hbGdvcml0aG0pO1xuXG4gICAgICBzd2l0Y2ggKHMyay50eXBlKSB7XG4gICAgICAgIGNhc2UgJ3NpbXBsZSc6XG4gICAgICAgICAgcmV0dXJuIGNyeXB0by5oYXNoLmRpZ2VzdChhbGdvcml0aG0sIHByZWZpeCArIHBhc3NwaHJhc2UpO1xuXG4gICAgICAgIGNhc2UgJ3NhbHRlZCc6XG4gICAgICAgICAgcmV0dXJuIGNyeXB0by5oYXNoLmRpZ2VzdChhbGdvcml0aG0sXG4gICAgICAgICAgICBwcmVmaXggKyBzMmsuc2FsdCArIHBhc3NwaHJhc2UpO1xuXG4gICAgICAgIGNhc2UgJ2l0ZXJhdGVkJzpcbiAgICAgICAgICB2YXIgaXNwID0gW10sXG4gICAgICAgICAgICBjb3VudCA9IHMyay5nZXRfY291bnQoKTtcbiAgICAgICAgICBkYXRhID0gczJrLnNhbHQgKyBwYXNzcGhyYXNlO1xuXG4gICAgICAgICAgd2hpbGUgKGlzcC5sZW5ndGggKiBkYXRhLmxlbmd0aCA8IGNvdW50KVxuICAgICAgICAgICAgaXNwLnB1c2goZGF0YSk7XG5cbiAgICAgICAgICBpc3AgPSBpc3Auam9pbignJyk7XG5cbiAgICAgICAgICBpZiAoaXNwLmxlbmd0aCA+IGNvdW50KVxuICAgICAgICAgICAgaXNwID0gaXNwLnN1YnN0cigwLCBjb3VudCk7XG5cbiAgICAgICAgICByZXR1cm4gY3J5cHRvLmhhc2guZGlnZXN0KGFsZ29yaXRobSwgcHJlZml4ICsgaXNwKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHJlc3VsdCA9ICcnLFxuICAgICAgcHJlZml4ID0gJyc7XG5cbiAgICB3aGlsZSAocmVzdWx0Lmxlbmd0aCA8PSBudW1CeXRlcykge1xuICAgICAgcmVzdWx0ICs9IHJvdW5kKHByZWZpeCwgdGhpcyk7XG4gICAgICBwcmVmaXggKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0LnN1YnN0cigwLCBudW1CeXRlcyk7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxudmFyIFV0aWwgPSBmdW5jdGlvbigpIHtcblxuICB0aGlzLnJlYWROdW1iZXIgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBuID0gMDtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG4gPDw9IDg7XG4gICAgICBuICs9IGJ5dGVzLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG47XG4gIH07XG5cbiAgdGhpcy53cml0ZU51bWJlciA9IGZ1bmN0aW9uKG4sIGJ5dGVzKSB7XG4gICAgdmFyIGIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzOyBpKyspIHtcbiAgICAgIGIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgobiA+PiAoOCAqIChieXRlcyAtIGkgLSAxKSkpICYgMHhGRik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGI7XG4gIH07XG5cblxuXG4gIHRoaXMucmVhZERhdGUgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBuID0gdGhpcy5yZWFkTnVtYmVyKGJ5dGVzKTtcbiAgICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gICAgZC5zZXRUaW1lKG4gKiAxMDAwKTtcbiAgICByZXR1cm4gZDtcbiAgfTtcblxuICB0aGlzLndyaXRlRGF0ZSA9IGZ1bmN0aW9uKHRpbWUpIHtcbiAgICB2YXIgbnVtZXJpYyA9IE1hdGgucm91bmQodGltZS5nZXRUaW1lKCkgLyAxMDAwKTtcblxuICAgIHJldHVybiB0aGlzLndyaXRlTnVtYmVyKG51bWVyaWMsIDQpO1xuICB9O1xuXG4gIHRoaXMuZW1haWxSZWdFeCA9IC9eWythLXpBLVowLTlfLi1dK0AoW2EtekEtWjAtOS1dK1xcLikrW2EtekEtWjAtOV17Miw2fSQvO1xuXG4gIHRoaXMuZGVidWcgPSBmYWxzZTtcblxuICB0aGlzLmhleGR1bXAgPSBmdW5jdGlvbihzdHIpIHtcbiAgICB2YXIgciA9IFtdO1xuICAgIHZhciBlID0gc3RyLmxlbmd0aDtcbiAgICB2YXIgYyA9IDA7XG4gICAgdmFyIGg7XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChjIDwgZSkge1xuICAgICAgaCA9IHN0ci5jaGFyQ29kZUF0KGMrKykudG9TdHJpbmcoMTYpO1xuICAgICAgd2hpbGUgKGgubGVuZ3RoIDwgMikgaCA9IFwiMFwiICsgaDtcbiAgICAgIHIucHVzaChcIiBcIiArIGgpO1xuICAgICAgaSsrO1xuICAgICAgaWYgKGkgJSAzMiA9PSAwKVxuICAgICAgICByLnB1c2goXCJcXG4gICAgICAgICAgIFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHIuam9pbignJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBoZXhzdHJpbmcgZnJvbSBhIGJpbmFyeVxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGhleGFkZWNpbWFsIHZhbHVlc1xuICAgKi9cbiAgdGhpcy5oZXhzdHJkdW1wID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgaWYgKHN0ciA9PSBudWxsKVxuICAgICAgcmV0dXJuIFwiXCI7XG4gICAgdmFyIHIgPSBbXTtcbiAgICB2YXIgZSA9IHN0ci5sZW5ndGg7XG4gICAgdmFyIGMgPSAwO1xuICAgIHZhciBoO1xuICAgIHdoaWxlIChjIDwgZSkge1xuICAgICAgaCA9IHN0ci5jaGFyQ29kZUF0KGMrKykudG9TdHJpbmcoMTYpO1xuICAgICAgd2hpbGUgKGgubGVuZ3RoIDwgMikgaCA9IFwiMFwiICsgaDtcbiAgICAgIHIucHVzaChcIlwiICsgaCk7XG4gICAgfVxuICAgIHJldHVybiByLmpvaW4oJycpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYmluYXJ5IHN0cmluZyBmcm9tIGEgaGV4IGVuY29kZWQgc3RyaW5nXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgSGV4IHN0cmluZyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGJpbmFyeSB2YWx1ZXNcbiAgICovXG4gIHRoaXMuaGV4MmJpbiA9IGZ1bmN0aW9uKGhleCkge1xuICAgIHZhciBzdHIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhleC5sZW5ndGg7IGkgKz0gMilcbiAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGhleC5zdWJzdHIoaSwgMiksIDE2KSk7XG4gICAgcmV0dXJuIHN0cjtcbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRpbmcgYSBoZXggc3RyaW5nIGZyb20gYW4gYmluYXJ5IGFycmF5IG9mIGludGVnZXJzICgwLi4yNTUpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgQXJyYXkgb2YgYnl0ZXMgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcnJheVxuICAgKi9cbiAgdGhpcy5oZXhpZHVtcCA9IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciByID0gW107XG4gICAgdmFyIGUgPSBzdHIubGVuZ3RoO1xuICAgIHZhciBjID0gMDtcbiAgICB2YXIgaDtcbiAgICB3aGlsZSAoYyA8IGUpIHtcbiAgICAgIGggPSBzdHJbYysrXS50b1N0cmluZygxNik7XG4gICAgICB3aGlsZSAoaC5sZW5ndGggPCAyKSBoID0gXCIwXCIgKyBoO1xuICAgICAgci5wdXNoKFwiXCIgKyBoKTtcbiAgICB9XG4gICAgcmV0dXJuIHIuam9pbignJyk7XG4gIH07XG5cblxuICAvKipcbiAgICogQ29udmVydCBhIG5hdGl2ZSBqYXZhc2NyaXB0IHN0cmluZyB0byBhIHN0cmluZyBvZiB1dGY4IGJ5dGVzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgVGhlIHN0cmluZyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gQSB2YWxpZCBzcXVlbmNlIG9mIHV0ZjggYnl0ZXNcbiAgICovXG4gIHRoaXMuZW5jb2RlX3V0ZjggPSBmdW5jdGlvbihzdHIpIHtcbiAgICByZXR1cm4gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHN0cikpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgc3RyaW5nIG9mIHV0ZjggYnl0ZXMgdG8gYSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmdcbiAgICogQHBhcmFtIHtTdHJpbmd9IHV0ZjggQSB2YWxpZCBzcXVlbmNlIG9mIHV0ZjggYnl0ZXNcbiAgICogQHJldHVybiB7U3RyaW5nfSBBIG5hdGl2ZSBqYXZhc2NyaXB0IHN0cmluZ1xuICAgKi9cbiAgdGhpcy5kZWNvZGVfdXRmOCA9IGZ1bmN0aW9uKHV0ZjgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUodXRmOCkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB1dGY4O1xuICAgIH1cbiAgfTtcblxuICB2YXIgc3RyMmJpbiA9IGZ1bmN0aW9uKHN0ciwgcmVzdWx0KSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdFtpXSA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgdmFyIGJpbjJzdHIgPSBmdW5jdGlvbihiaW4pIHtcbiAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJpbi5sZW5ndGg7IGkrKykge1xuICAgICAgcmVzdWx0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShiaW5baV0pKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0LmpvaW4oJycpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGFuIGFycmF5IG9mIGludGVnZXJzKDAuMjU1KVxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge0ludGVnZXJbXX0gQW4gYXJyYXkgb2YgKGJpbmFyeSkgaW50ZWdlcnNcbiAgICovXG4gIHRoaXMuc3RyMmJpbiA9IGZ1bmN0aW9uKHN0cikge1xuICAgIHJldHVybiBzdHIyYmluKHN0ciwgbmV3IEFycmF5KHN0ci5sZW5ndGgpKTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGludGVnZXJzKDAuMjU1KSB0byBhIHN0cmluZyBcbiAgICogQHBhcmFtIHtJbnRlZ2VyW119IGJpbiBBbiBhcnJheSBvZiAoYmluYXJ5KSBpbnRlZ2VycyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgYXJyYXlcbiAgICovXG4gIHRoaXMuYmluMnN0ciA9IGJpbjJzdHI7XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBzdHJpbmcgdG8gYSBVaW50OEFycmF5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7VWludDhBcnJheX0gVGhlIGFycmF5IG9mIChiaW5hcnkpIGludGVnZXJzXG4gICAqL1xuICB0aGlzLnN0cjJVaW50OEFycmF5ID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgcmV0dXJuIHN0cjJiaW4oc3RyLCBuZXcgVWludDhBcnJheShuZXcgQXJyYXlCdWZmZXIoc3RyLmxlbmd0aCkpKTtcbiAgfTtcblxuICAvKipcbiAgICogQ29udmVydCBhIFVpbnQ4QXJyYXkgdG8gYSBzdHJpbmcuIFRoaXMgY3VycmVudGx5IGZ1bmN0aW9ucyBcbiAgICogdGhlIHNhbWUgYXMgYmluMnN0ci4gXG4gICAqIEBwYXJhbSB7VWludDhBcnJheX0gYmluIEFuIGFycmF5IG9mIChiaW5hcnkpIGludGVnZXJzIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFycmF5XG4gICAqL1xuICB0aGlzLlVpbnQ4QXJyYXkyc3RyID0gYmluMnN0cjtcblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyBhIDE2Yml0IHN1bSBvZiBhIHN0cmluZyBieSBhZGRpbmcgZWFjaCBjaGFyYWN0ZXIgXG4gICAqIGNvZGVzIG1vZHVsdXMgNjU1MzVcbiAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgU3RyaW5nIHRvIGNyZWF0ZSBhIHN1bSBvZlxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBbiBpbnRlZ2VyIGNvbnRhaW5pbmcgdGhlIHN1bSBvZiBhbGwgY2hhcmFjdGVyIFxuICAgKiBjb2RlcyAlIDY1NTM1XG4gICAqL1xuICB0aGlzLmNhbGNfY2hlY2tzdW0gPSBmdW5jdGlvbih0ZXh0KSB7XG4gICAgdmFyIGNoZWNrc3VtID0ge1xuICAgICAgczogMCxcbiAgICAgIGFkZDogZnVuY3Rpb24oc2FkZCkge1xuICAgICAgICB0aGlzLnMgPSAodGhpcy5zICsgc2FkZCkgJSA2NTUzNjtcbiAgICAgIH1cbiAgICB9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGV4dC5sZW5ndGg7IGkrKykge1xuICAgICAgY2hlY2tzdW0uYWRkKHRleHQuY2hhckNvZGVBdChpKSk7XG4gICAgfVxuICAgIHJldHVybiBjaGVja3N1bS5zO1xuICB9O1xuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gcHJpbnQgYSBkZWJ1ZyBtZXNzYWdlLiBEZWJ1ZyBcbiAgICogbWVzc2FnZXMgYXJlIG9ubHkgcHJpbnRlZCBpZlxuICAgKiBvcGVucGdwLmNvbmZpZy5kZWJ1ZyBpcyBzZXQgdG8gdHJ1ZS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgb2YgdGhlIGRlYnVnIG1lc3NhZ2VcbiAgICovXG4gIHRoaXMucHJpbnRfZGVidWcgPSBmdW5jdGlvbihzdHIpIHtcbiAgICBpZiAoY29uZmlnLmRlYnVnKSB7XG4gICAgICBjb25zb2xlLmxvZyhzdHIpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogSGVscGVyIGZ1bmN0aW9uIHRvIHByaW50IGEgZGVidWcgbWVzc2FnZS4gRGVidWcgXG4gICAqIG1lc3NhZ2VzIGFyZSBvbmx5IHByaW50ZWQgaWZcbiAgICogb3BlbnBncC5jb25maWcuZGVidWcgaXMgc2V0IHRvIHRydWUuXG4gICAqIERpZmZlcmVudCB0aGFuIHByaW50X2RlYnVnIGJlY2F1c2Ugd2lsbCBjYWxsIGhleHN0cmR1bXAgaWZmIG5lY2Vzc2FyeS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgb2YgdGhlIGRlYnVnIG1lc3NhZ2VcbiAgICovXG4gIHRoaXMucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAgPSBmdW5jdGlvbihzdHIsIHN0clRvSGV4KSB7XG4gICAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgICAgc3RyID0gc3RyICsgdGhpcy5oZXhzdHJkdW1wKHN0clRvSGV4KTtcbiAgICAgIGNvbnNvbGUubG9nKHN0cik7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gcHJpbnQgYW4gZXJyb3IgbWVzc2FnZS4gXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBlcnJvciBtZXNzYWdlXG4gICAqL1xuICB0aGlzLnByaW50X2Vycm9yID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgaWYgKGNvbmZpZy5kZWJ1ZylcbiAgICAgIHRocm93IHN0cjtcbiAgICBjb25zb2xlLmxvZyhzdHIpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gcHJpbnQgYW4gaW5mbyBtZXNzYWdlLiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgb2YgdGhlIGluZm8gbWVzc2FnZVxuICAgKi9cbiAgdGhpcy5wcmludF9pbmZvID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgaWYgKGNvbmZpZy5kZWJ1ZylcbiAgICAgIGNvbnNvbGUubG9nKHN0cik7XG4gIH07XG5cbiAgdGhpcy5wcmludF93YXJuaW5nID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgY29uc29sZS5sb2coc3RyKTtcbiAgfTtcblxuICB0aGlzLmdldExlZnROQml0cyA9IGZ1bmN0aW9uKHN0cmluZywgYml0Y291bnQpIHtcbiAgICB2YXIgcmVzdCA9IGJpdGNvdW50ICUgODtcbiAgICBpZiAocmVzdCA9PSAwKVxuICAgICAgcmV0dXJuIHN0cmluZy5zdWJzdHJpbmcoMCwgYml0Y291bnQgLyA4KTtcbiAgICB2YXIgYnl0ZXMgPSAoYml0Y291bnQgLSByZXN0KSAvIDggKyAxO1xuICAgIHZhciByZXN1bHQgPSBzdHJpbmcuc3Vic3RyaW5nKDAsIGJ5dGVzKTtcbiAgICByZXR1cm4gdGhpcy5zaGlmdFJpZ2h0KHJlc3VsdCwgOCAtIHJlc3QpOyAvLyArU3RyaW5nLmZyb21DaGFyQ29kZShzdHJpbmcuY2hhckNvZGVBdChieXRlcyAtMSkgPDwgKDgtcmVzdCkgJiAweEZGKTtcbiAgfTtcblxuICAvKipcbiAgICogU2hpZnRpbmcgYSBzdHJpbmcgdG8gbiBiaXRzIHJpZ2h0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZSBUaGUgc3RyaW5nIHRvIHNoaWZ0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYml0Y291bnQgQW1vdW50IG9mIGJpdHMgdG8gc2hpZnQgKE1VU1QgYmUgc21hbGxlciBcbiAgICogdGhhbiA5KVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFJlc3VsdGluZyBzdHJpbmcuIFxuICAgKi9cbiAgdGhpcy5zaGlmdFJpZ2h0ID0gZnVuY3Rpb24odmFsdWUsIGJpdGNvdW50KSB7XG4gICAgdmFyIHRlbXAgPSB1dGlsLnN0cjJiaW4odmFsdWUpO1xuICAgIGlmIChiaXRjb3VudCAlIDggIT0gMCkge1xuICAgICAgZm9yICh2YXIgaSA9IHRlbXAubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgdGVtcFtpXSA+Pj0gYml0Y291bnQgJSA4O1xuICAgICAgICBpZiAoaSA+IDApXG4gICAgICAgICAgdGVtcFtpXSB8PSAodGVtcFtpIC0gMV0gPDwgKDggLSAoYml0Y291bnQgJSA4KSkpICYgMHhGRjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gdXRpbC5iaW4yc3RyKHRlbXApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGFsZ29yaXRobSB0eXBlIGFzIHN0cmluZ1xuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyByZXByZXNlbnRpbmcgdGhlIG1lc3NhZ2UgdHlwZVxuICAgKi9cbiAgdGhpcy5nZXRfaGFzaEFsZ29yaXRobVN0cmluZyA9IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIFwiTUQ1XCI7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiBcIlNIQTFcIjtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIFwiUklQRU1EMTYwXCI7XG4gICAgICBjYXNlIDg6XG4gICAgICAgIHJldHVybiBcIlNIQTI1NlwiO1xuICAgICAgY2FzZSA5OlxuICAgICAgICByZXR1cm4gXCJTSEEzODRcIjtcbiAgICAgIGNhc2UgMTA6XG4gICAgICAgIHJldHVybiBcIlNIQTUxMlwiO1xuICAgICAgY2FzZSAxMTpcbiAgICAgICAgcmV0dXJuIFwiU0hBMjI0XCI7XG4gICAgfVxuICAgIHJldHVybiBcInVua25vd25cIjtcbiAgfTtcblxufTtcblxuLyoqXG4gKiBhbiBpbnN0YW5jZSB0aGF0IHNob3VsZCBiZSB1c2VkLiBcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBuZXcgVXRpbCgpO1xuIl19 ; \ No newline at end of file diff --git a/src/key.js b/src/key.js index a15a38f7..b20b8c4a 100644 --- a/src/key.js +++ b/src/key.js @@ -119,6 +119,19 @@ Key.prototype.getPrivateKeyPacket = function(keyIds) { return findKey(keys, keyIds); }; +/** + * Returns userids + * @return {string} userid[] + */ +Key.prototype.getUserIds = function() { + var userids = []; + var useridPackets = this.packets.filterByTag(enums.packet.userid); + for (var i = 0; i < useridPackets.length; i++) { + userids.push(useridPackets[i].write()); + } + return userids; +}; + /** * Returns true if this is a public key * @return {Boolean} diff --git a/src/keyring.js b/src/keyring.js index 3e1448e7..e569756b 100644 --- a/src/keyring.js +++ b/src/keyring.js @@ -15,17 +15,14 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); +var openpgp = require('openpgp'); /** * @class * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. */ var keyring = function() { - this.armoredPacketlists = []; - this.parsedPacketlists = []; + this.keys = []; /** * Initialization routine for the keyring. This method reads the @@ -33,17 +30,15 @@ var keyring = function() { * This method is called by openpgp.init(). */ function init() { - var armoredPacketlists = JSON.parse(window.localStorage.getItem("armoredPacketlists")); - if (armoredPacketlists === null || armoredPacketlists.length === 0) { - armoredPacketlists = []; - } - this.armoredPacketlists = armoredPacketlists; - - var packetlist; - for (var i = 0; i < armoredPacketlists.length; i++) { - packetlist = new packet.list(); - packetlist.read(armoredPacketlists[i]); - this.parsedPacketlists.push(packetlist); + var armoredKeys = JSON.parse(window.localStorage.getItem("armoredKeys")); + if (armoredKeys !== null && armoredKeys.length === 0) { + var key; + for (var i = 0; i < armoredKeys.length; i++) { + key = openpgp.key.readArmored(armoredKeys[i]); + this.keys.push(key); + } + } else { + this.keys = []; } } this.init = init; @@ -53,60 +48,50 @@ var keyring = function() { * The privateKeys array and publicKeys array gets Stringified using JSON */ function store() { - window.localStorage.setItem("armoredPacketlists", JSON.stringify(this.armoredPacketlists)); + var armoredKeys = []; + for (var i = 0; i < this.keys.length; i++) { + armoredKeys.push(this.keys[i].armor()); + } + window.localStorage.setItem("armoredKeys", JSON.stringify(armoredKeys)); } this.store = store; - function emailPacketCheck(packet, email) { - var emailMatch = false; - var packetEmail; + function emailKeyCheck(key, email) { email = email.toLowerCase(); - if (packet.tag == enums.packet.userid) { - packetEmail = packet.userid; - //we need to get just the email from the userid packet - packetEmail = packetEmail.split('<')[1].split('<')[0].trim.toLowerCase(); - if (packetEmail == email) { - emailMatch = true; - } - } - return emailMatch; - } - - function idPacketCheck(packet, id) { - if (packet.getKeyId && packet.getKeyId().write() == id) { - return true; - } - return false; - } - - function helperCheckIdentityAndPacketMatch(identityFunction, identityInput, packetType, packetlist) { - var packet; - for (var l = 0; l < packetlist.length; l++) { - packet = packetlist[l]; - identityMatch = identityFunction(packet, identityInput); - if (!packetType) { - packetMatch = true; - } else if (packet.tag == packetType) { - packetMatch = true; - } - if (packetMatch && identityMatch) { + var keyEmails = key.getUserIds(); + for (var i; i < keyEmails.length; i++) { + //we need to get just the email from the userid key + keyEmail = keyEmails[i].split('<')[1].split('>')[0].trim().toLowerCase(); + if (keyEmail == email) { return true; } } return false; } - function checkForIdentityAndPacketMatch(identityFunction, identityInput, packetType) { + function idKeyCheck(key, id) { + var keyid = key.getKeyId(); + if (keyid && keyid.write() == id) { + return true; + } + return false; + } + + function checkForIdentityAndPacketMatch(identityFunction, identityInput, keyType) { var results = []; - var packetlist; - var identityMatch; - var packetMatch; - for (var p = 0; p < this.parsedPacketlists.length; p++) { - identityMatch = false; - packetMatch = false; - packetlist = this.parsedPacketlists[p]; - if (helperCheckIdentityAndPacketMatch(identityFunction, identityInput, packetType, packetlist)) { - results.push(packetlist); + for (var p = 0; p < this.keys.length; p++) { + var key = this.keys[p]; + switch (keyType) { + case openpgp.enums.packet.public_key: + if (key.isPublic() && identityFunction(identityInput, key)) { + results.push(key); + } + break; + case openpgp.enums.packet.private_key: + if (key.isPrivate() && identityFunction(identityInput, key)) { + results.push(key); + } + break; } } return results; @@ -115,74 +100,76 @@ var keyring = function() { /** * searches all public keys in the keyring matching the address or address part of the user ids - * @param {String} email_address - * @return {openpgp_msg_publickey[]} The public keys associated with provided email address. + * @param {String} email email address to search for + * @return {openpgp.key.Key[]} The public keys associated with provided email address. */ function getPublicKeyForAddress(email) { - return checkForIdentityAndPacketMatch(emailPacketCheck, email, enums.packet.public_key); + return checkForIdentityAndPacketMatch(emailPacketCheck, email, openpgp.enums.packet.public_key); } this.getPublicKeyForAddress = getPublicKeyForAddress; /** * Searches the keyring for a private key containing the specified email address - * @param {String} email_address email address to search for - * @return {openpgp_msg_privatekey[]} private keys found + * @param {String} email email address to search for + * @return {openpgp.key.Key[]} private keys found */ - function getPrivateKeyForAddress(email_address) { - return checkForIdentityAndPacketMatch(emailPacketCheck, email, enums.packet.secret_key); + function getPrivateKeyForAddress(email) { + return checkForIdentityAndPacketMatch(emailPacketCheck, email, openpgp.enums.packet.secret_key); } this.getPrivateKeyForAddress = getPrivateKeyForAddress; /** * Searches the keyring for public keys having the specified key id * @param {String} keyId provided as string of hex number (lowercase) - * @return {openpgp_msg_privatekey[]} public keys found + * @return {openpgp.key.Key[]} public keys found */ - function getPacketlistsForKeyId(keyId) { + function getKeysForKeyId(keyId) { return this.checkForIdentityAndPacketMatch(idPacketCheck, keyId); } - this.getPacketlistsForKeyId = getPacketlistsForKeyId; + this.getKeysForKeyId = getKeysForKeyId; /** - * Imports a packet list (public or private key block) from an ascii armored message - * @param {String} armored message to read the packets/key from + * Imports a key from an ascii armored message + * @param {String} armored message to read the keys/key from */ - function importPacketlist(armored) { - this.armoredPacketlists.push(armored); - - var dearmored = armor.decode(armored.replace(/\r/g, '')).data; - - packetlist = new packet.list(); - packetlist.read(dearmored); - this.parsedPacketlists.push(packetlist); + function importKey(armored) { + this.keys.push(openpgp.key.readArmored(armored)); return true; } - this.importPacketlist = importPacketlist; + this.importKey = importKey; /** - * TODO - * returns the openpgp_msg_privatekey representation of the public key at public key ring index - * @param {Integer} index the index of the public key within the publicKeys array - * @return {openpgp_msg_privatekey} the public key object + * returns the armored message representation of the key at key ring index + * @param {Integer} index the index of the key within the array + * @return {String} armored message representing the key object */ - function exportPublicKey(index) { - return this.publicKey[index]; + function exportKey(index) { + return this.keys[index].armor(); } - this.exportPublicKey = exportPublicKey; + this.exportKey = exportKey; /** - * TODO * Removes a public key from the public key keyring at the specified index * @param {Integer} index the index of the public key within the publicKeys array - * @return {openpgp_msg_privatekey} The public key object which has been removed + * @return {openpgp.key.Key} The public key object which has been removed */ - function removePublicKey(index) { - var removed = this.publicKeys.splice(index, 1); - this.store(); + function removeKey(index) { + var removed = this.keys.splice(index, 1); + return removed; } - this.removePublicKey = removePublicKey; + this.removeKey = removeKey; + + /** + * returns the armored message representation of the public key portion of the key at key ring index + * @param {Integer} index the index of the key within the array + * @return {String} armored message representing the public key object + */ + function exportPublicKey(index) { + return this.keys[index].toPublic().armor(); + } + this.exportPublicKey = exportPublicKey; }; diff --git a/test/ci-quick.js b/test/ci-quick.js index 3918f513..5d84ef0d 100644 --- a/test/ci-quick.js +++ b/test/ci-quick.js @@ -1,5 +1,5 @@ -var openpgp = require('openpgp'); - //keyring = require('../../src/keyring.js'); +var openpgp = require('openpgp'), + keyring = require('../src/keyring.js'); 'use strict'; @@ -61,17 +61,17 @@ describe('Openpgp integration tests', function() { }); }); -// describe('Import key pair', function() { -// it('should work', function(done) { -// // clear any keypair already in the keychain -// keyring.init(); -// // import private key -// keyring.importPacketlist(privkey); -// // import public key -// keyring.importPacketlist(pubkey); -// done(); -// }); -// }); + describe('Import key pair', function() { + it('should work', function(done) { + // clear any keypair already in the keychain + keyring.init(); + // import private key + keyring.importKey(privkey); + // import public key + keyring.importKey(pubkey); + done(); + }); + }); describe('Encryption', function() { var message = 'asdfs\n\nThursday, Nov 21, 2013 7:38 PM asdf@example.com wrote:\n' + diff --git a/test/crypto/cipher/aes.js b/test/crypto/cipher/aes.js index d2fff50e..f1089fe7 100644 --- a/test/crypto/cipher/aes.js +++ b/test/crypto/cipher/aes.js @@ -1,7 +1,7 @@ var unit = require('../../unit.js'); unit.register("AES Rijndael cipher test with test vectors from ecb_tbl.txt", function() { - var openpgp = require('../../../'); + var openpgp = require('openpgp'); var util = openpgp.util; var result = new Array(); diff --git a/test/crypto/cipher/blowfish.js b/test/crypto/cipher/blowfish.js index 9a64e80d..93621767 100644 --- a/test/crypto/cipher/blowfish.js +++ b/test/crypto/cipher/blowfish.js @@ -1,7 +1,7 @@ var unit = require('../../unit.js'); unit.register("Blowfish cipher test with test vectors from http://www.schneier.com/code/vectors.txt", function() { - var openpgp = require('../../../'), + var openpgp = require('openpgp'), util = openpgp.util, BFencrypt = openpgp.crypto.cipher.blowfish; diff --git a/test/crypto/cipher/cast5.js b/test/crypto/cipher/cast5.js index 2e060675..98828d7a 100644 --- a/test/crypto/cipher/cast5.js +++ b/test/crypto/cipher/cast5.js @@ -1,7 +1,7 @@ var unit = require('../../unit.js'); unit.register("CAST-128 cipher test with test vectors from RFC2144", function() { - var openpgp = require('../../../'), + var openpgp = require('openpgp'), util = openpgp.util; var result = []; diff --git a/test/crypto/cipher/des.js b/test/crypto/cipher/des.js index 68521678..5a3ea465 100644 --- a/test/crypto/cipher/des.js +++ b/test/crypto/cipher/des.js @@ -1,7 +1,7 @@ var unit = require('../../unit.js'); unit.register("TripleDES (EDE) cipher test with test vectors from http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf", function() { - var openpgp = require('../../../'), + var openpgp = require('openpgp'), util = openpgp.util; var result = []; @@ -99,7 +99,7 @@ unit.register("TripleDES (EDE) cipher test with test vectors from http://csrc.ni unit.register("DES encrypt/decrypt padding tests", function () { - var openpgp = require('../../../'), + var openpgp = require('openpgp'), util = openpgp.util; var result = []; diff --git a/test/crypto/cipher/twofish.js b/test/crypto/cipher/twofish.js index 033464e5..ccbad52b 100644 --- a/test/crypto/cipher/twofish.js +++ b/test/crypto/cipher/twofish.js @@ -1,7 +1,7 @@ var unit = require('../../unit.js'); unit.register("Twofish test with test vectors from http://www.schneier.com/code/ecb_ival.txt", function() { - var openpgp = require('../../../'), + var openpgp = require('openpgp'), util = openpgp.util; function TFencrypt(block, key) { diff --git a/test/crypto/crypto.js b/test/crypto/crypto.js index bd3fb3cc..9d65e5e7 100644 --- a/test/crypto/crypto.js +++ b/test/crypto/crypto.js @@ -1,7 +1,7 @@ var unit = require('../unit.js'); unit.register("Functional testing of openpgp.crypto.* methods", function() { - var openpgp = require('../../'); + var openpgp = require('openpgp'); var util = openpgp.util; var result = []; var RSApubMPIstrs = [ diff --git a/test/crypto/hash/.md5.js.swp b/test/crypto/hash/.md5.js.swp deleted file mode 100644 index a8169620..00000000 Binary files a/test/crypto/hash/.md5.js.swp and /dev/null differ diff --git a/test/crypto/hash/md5.js b/test/crypto/hash/md5.js index e662dc6c..c5d2a318 100644 --- a/test/crypto/hash/md5.js +++ b/test/crypto/hash/md5.js @@ -1,7 +1,7 @@ var unit = require('../../unit.js'); unit.register("MD5 test with test vectors from RFC 1321", function() { - var openpgp = require('../../../'), + var openpgp = require('openpgp'), util = openpgp.util, MD5 = openpgp.crypto.hash.md5; diff --git a/test/crypto/hash/ripemd.js b/test/crypto/hash/ripemd.js index db87b1f9..25c3970c 100644 --- a/test/crypto/hash/ripemd.js +++ b/test/crypto/hash/ripemd.js @@ -2,7 +2,7 @@ var unit = require('../../unit.js'); unit.register("RIPE-MD 160 bits test with test vectors from http://homes.esat.kuleuven.be/~bosselae/ripemd160.html", function() { - var openpgp = require('../../../'), + var openpgp = require('openpgp'), util = openpgp.util, RMDstring = openpgp.crypto.hash.ripemd; diff --git a/test/crypto/hash/sha.js b/test/crypto/hash/sha.js index 3e0a7f57..52f0d304 100644 --- a/test/crypto/hash/sha.js +++ b/test/crypto/hash/sha.js @@ -2,7 +2,7 @@ var unit = require('../../unit.js'); unit.register("SHA* test with test vectors from NIST FIPS 180-2", function() { - var openpgp = require('../../../'), + var openpgp = require('openpgp'), util = openpgp.util, hash = openpgp.crypto.hash; diff --git a/test/general/basic.js b/test/general/basic.js index 180e63c1..06e91213 100644 --- a/test/general/basic.js +++ b/test/general/basic.js @@ -1,7 +1,7 @@ var unit = require('../unit.js'); unit.register("Key generation/encryption/decryption", function() { - var openpgp = require('../../'); + var openpgp = require('openpgp'); var result = []; var testHelper = function(passphrase, userid, message) { var key = openpgp.generateKeyPair(openpgp.enums.publicKey.rsa_encrypt_sign, 512, @@ -37,7 +37,7 @@ unit.register("Key generation/encryption/decryption", function() { }); unit.register("Message encryption/decryption", function() { - var openpgp = require('../../'); + var openpgp = require('openpgp'); var result = []; diff --git a/test/general/keyring.js b/test/general/keyring.js index 3394d6a3..420dae86 100644 --- a/test/general/keyring.js +++ b/test/general/keyring.js @@ -1,7 +1,7 @@ var unit = require('../unit.js'); unit.register("Keyring testing", function() { - var openpgp = require('../../'); + var openpgp = require('openpgp'); var keyring = require('../../src/keyring.js'); var result = []; diff --git a/test/general/packet.js b/test/general/packet.js index d6b7f446..e0d12509 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -2,7 +2,7 @@ var unit = require('../unit.js'); unit.register("Packet testing", function() { - var openpgp = require('../../'); + var openpgp = require('openpgp'); var armored_key = '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' + diff --git a/test/general/signature.js b/test/general/signature.js index 8dd5f747..80cf8036 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -1,7 +1,7 @@ var unit = require('../unit.js'); unit.register("Signature testing", function() { - var openpgp = require('../../'); + var openpgp = require('openpgp'); var priv_key_arm1 = [ '-----BEGIN PGP PRIVATE KEY BLOCK-----', @@ -459,4 +459,4 @@ var pub_key_arm3 = return results; -}); \ No newline at end of file +}); diff --git a/test/index.html b/test/index.html index ad44382c..21b7b488 100644 --- a/test/index.html +++ b/test/index.html @@ -56,10 +56,11 @@ </style> +<script src="lib/openpgp.debug.js"></script> +<script src="lib/test-bundle.js"></script> <script type="text/javascript"> - -var test = require('test-bundle.js'); +var test = require('unittests'); function unit_tests() { var table = document.getElementById('unittests'); diff --git a/test/test-bundle.js b/test/test-bundle.js deleted file mode 100644 index a5198e17..00000000 --- a/test/test-bundle.js +++ /dev/null @@ -1,15571 +0,0 @@ -require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; - -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; - - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; - } - - if (canPost) { - var queue = []; - window.addEventListener('message', function (ev) { - if (ev.source === window && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); - - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); - }; - } - - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); - -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -} - -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; - -},{}],2:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var config = require('./config'); -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); - -/** - * @class - * @classdesc Class that represents an OpenPGP cleartext signed message. - * See http://tools.ietf.org/html/rfc4880#section-7 - * @param {String} text The cleartext of the signed message - * @param {packetlist} packetlist The packetlist with signature packets or undefined - * if message not yet signed - */ - -function CleartextMessage(text, packetlist) { - if (!(this instanceof CleartextMessage)) { - return new CleartextMessage(packetlist); - } - // normalize EOL to canonical form <CR><LF> - this.text = text.replace(/\r/g, '').replace(/[\t ]+\n/g, "\n").replace(/\n/g,"\r\n"); - this.packets = packetlist || new packet.list(); -} - -/** - * Returns the key IDs of the keys that signed the cleartext message - * @return {[keyId]} array of keyid objects - */ -CleartextMessage.prototype.getSigningKeyIds = function() { - var keyIds = []; - var signatureList = this.packets.filterByTag(enums.packet.signature); - signatureList.forEach(function(packet) { - keyIds.push(packet.issuerKeyId); - }); - return keyIds; -}; - -/** - * Sign the cleartext message - * @param {[key]} privateKeys private keys with decrypted secret key data for signing - */ -CleartextMessage.prototype.sign = function(privateKeys) { - var packetlist = new packet.list(); - var literalDataPacket = new packet.literal(); - literalDataPacket.setText(this.text); - for (var i = 0; i < privateKeys.length; i++) { - var signaturePacket = new packet.signature(); - signaturePacket.signatureType = enums.signature.text; - signaturePacket.hashAlgorithm = config.prefer_hash_algorithm; - var signingKeyPacket = privateKeys[i].getSigningKeyPacket(); - signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm; - if (!signingKeyPacket.isDecrypted) throw new Error('Private key is not decrypted.'); - signaturePacket.sign(signingKeyPacket, literalDataPacket); - packetlist.push(signaturePacket); - } - this.packets = packetlist; -}; - -/** - * Verify signatures of cleartext signed message - * @param {[key]} publicKeys public keys to verify signatures - * @return {[{'keyid': keyid, 'valid': Boolean}]} list of signer's keyid and validity of signature - */ -CleartextMessage.prototype.verify = function(publicKeys) { - var result = []; - var signatureList = this.packets.filterByTag(enums.packet.signature); - var literalDataPacket = new packet.literal(); - // we assume that cleartext signature is generated based on UTF8 cleartext, - // fails for other encodings, see CP-1252 test case in test/signature.js - literalDataPacket.setText(this.text); - publicKeys.forEach(function(pubKey) { - for (var i = 0; i < signatureList.length; i++) { - var publicKeyPacket = pubKey.getPublicKeyPacket([signatureList[i].issuerKeyId]); - if (publicKeyPacket) { - var verifiedSig = {}; - verifiedSig.keyid = signatureList[i].issuerKeyId; - verifiedSig.status = signatureList[i].verify(publicKeyPacket, literalDataPacket); - result.push(verifiedSig); - break; - } - } - }); - return result; -}; - -/** - * Get cleartext - * @return {String} cleartext of message - */ -CleartextMessage.prototype.getText = function() { - // normalize end of line to \n - return this.text.replace(/\r\n/g,"\n"); -}; - -/** - * Returns ASCII armored text of cleartext signed message - * @return {String} ASCII armor - */ -CleartextMessage.prototype.armor = function() { - var body = { - hash: enums.read(enums.hash, config.prefer_hash_algorithm).toUpperCase(), - text: this.text, - data: this.packets.write() - } - return armor.encode(enums.armor.signed, body); -}; - - -/** - * reads an OpenPGP cleartext signed message and returns a CleartextMessage object - * @param {String} armoredText text to be parsed - * @return {CleartextMessage} new cleartext message object - */ -function readArmored(armoredText) { - var input = armor.decode(armoredText); - if (input.type !== enums.armor.signed) { - throw new Error('No cleartext signed message.'); - } - var packetlist = new packet.list(); - packetlist.read(input.data); - var newMessage = new CleartextMessage(input.text, packetlist); - return newMessage; -} - -exports.CleartextMessage = CleartextMessage; -exports.readArmored = readArmored; - -},{"./config":4,"./encoding/armor.js":26,"./enums.js":28,"./packet":36}],3:[function(require,module,exports){ -JXG = { - exists: (function(undefined) { - return function(v) { - return !(v === undefined || v === null); - } - })() -}; -JXG.decompress = function(str) { - return unescape((new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(str))).unzip()[0][0]); -}; -/* - Copyright 2008-2012 - Matthias Ehmann, - Michael Gerhaeuser, - Carsten Miller, - Bianca Valentin, - Alfred Wassermann, - Peter Wilfahrt - - This file is part of JSXGraph. - - Dual licensed under the Apache License Version 2.0, or LGPL Version 3 licenses. - - You should have received a copy of the GNU Lesser General Public License - along with JSXCompressor. If not, see <http://www.gnu.org/licenses/>. - - You should have received a copy of the Apache License along with JSXCompressor. - If not, see <http://www.apache.org/licenses/>. - -*/ - -/** - * @class Util class - * @classdesc Utilities for uncompressing and base64 decoding - * Class for gunzipping, unzipping and base64 decoding of files. - * It is used for reading GEONExT, Geogebra and Intergeo files. - * - * Only Huffman codes are decoded in gunzip. - * The code is based on the source code for gunzip.c by Pasi Ojala - * {@link http://www.cs.tut.fi/~albert/Dev/gunzip/gunzip.c} - * {@link http://www.cs.tut.fi/~albert} - */ -JXG.Util = {}; - -/** - * Unzip zip files - */ -JXG.Util.Unzip = function(barray) { - var outputArr = [], - output = "", - debug = false, - gpflags, - files = 0, - unzipped = [], - crc, - buf32k = new Array(32768), - bIdx = 0, - modeZIP = false, - - CRC, SIZE, - - bitReverse = [ - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff - ], - - cplens = [ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - ], - - cplext = [ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 - ], - /* 99==invalid */ - - cpdist = [ - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, - 0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, - 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, - 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001 - ], - - cpdext = [ - 0, 0, 0, 0, 1, 1, 2, 2, - 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, - 11, 11, 12, 12, 13, 13 - ], - - border = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15], - - bA = barray, - - bytepos = 0, - bitpos = 0, - bb = 1, - bits = 0, - - NAMEMAX = 256, - - nameBuf = [], - - fileout; - - function readByte() { - bits += 8; - if (bytepos < bA.length) { - //if (debug) - // document.write(bytepos+": "+bA[bytepos]+"<br>"); - return bA[bytepos++]; - } else - return -1; - }; - - function byteAlign() { - bb = 1; - }; - - function readBit() { - var carry; - bits++; - carry = (bb & 1); - bb >>= 1; - if (bb == 0) { - bb = readByte(); - carry = (bb & 1); - bb = (bb >> 1) | 0x80; - } - return carry; - }; - - function readBits(a) { - var res = 0, - i = a; - - while (i--) { - res = (res << 1) | readBit(); - } - if (a) { - res = bitReverse[res] >> (8 - a); - } - return res; - }; - - function flushBuffer() { - //document.write('FLUSHBUFFER:'+buf32k); - bIdx = 0; - }; - - function addBuffer(a) { - SIZE++; - //CRC=updcrc(a,crc); - buf32k[bIdx++] = a; - outputArr.push(String.fromCharCode(a)); - //output+=String.fromCharCode(a); - if (bIdx == 0x8000) { - //document.write('ADDBUFFER:'+buf32k); - bIdx = 0; - } - }; - - function HufNode() { - this.b0 = 0; - this.b1 = 0; - this.jump = null; - this.jumppos = -1; - }; - - var LITERALS = 288; - - var literalTree = new Array(LITERALS); - var distanceTree = new Array(32); - var treepos = 0; - var Places = null; - var Places2 = null; - - var impDistanceTree = new Array(64); - var impLengthTree = new Array(64); - - var len = 0; - var fpos = new Array(17); - fpos[0] = 0; - var flens; - var fmax; - - function IsPat() { - while (1) { - if (fpos[len] >= fmax) - return -1; - if (flens[fpos[len]] == len) - return fpos[len]++; - fpos[len]++; - } - }; - - function Rec() { - var curplace = Places[treepos]; - var tmp; - if (debug) - document.write("<br>len:" + len + " treepos:" + treepos); - if (len == 17) { //war 17 - return -1; - } - treepos++; - len++; - - tmp = IsPat(); - if (debug) - document.write("<br>IsPat " + tmp); - if (tmp >= 0) { - curplace.b0 = tmp; /* leaf cell for 0-bit */ - if (debug) - document.write("<br>b0 " + curplace.b0); - } else { - /* Not a Leaf cell */ - curplace.b0 = 0x8000; - if (debug) - document.write("<br>b0 " + curplace.b0); - if (Rec()) - return -1; - } - tmp = IsPat(); - if (tmp >= 0) { - curplace.b1 = tmp; /* leaf cell for 1-bit */ - if (debug) - document.write("<br>b1 " + curplace.b1); - curplace.jump = null; /* Just for the display routine */ - } else { - /* Not a Leaf cell */ - curplace.b1 = 0x8000; - if (debug) - document.write("<br>b1 " + curplace.b1); - curplace.jump = Places[treepos]; - curplace.jumppos = treepos; - if (Rec()) - return -1; - } - len--; - return 0; - }; - - function CreateTree(currentTree, numval, lengths, show) { - var i; - /* Create the Huffman decode tree/table */ - //document.write("<br>createtree<br>"); - if (debug) - document.write("currentTree " + currentTree + " numval " + numval + " lengths " + lengths + " show " + show); - Places = currentTree; - treepos = 0; - flens = lengths; - fmax = numval; - for (i = 0; i < 17; i++) - fpos[i] = 0; - len = 0; - if (Rec()) { - //fprintf(stderr, "invalid huffman tree\n"); - if (debug) - alert("invalid huffman tree\n"); - return -1; - } - if (debug) { - document.write('<br>Tree: ' + Places.length); - for (var a = 0; a < 32; a++) { - document.write("Places[" + a + "].b0=" + Places[a].b0 + "<br>"); - document.write("Places[" + a + "].b1=" + Places[a].b1 + "<br>"); - } - } - - /*if(show) { - var tmp; - for(tmp=currentTree;tmp<Places;tmp++) { - fprintf(stdout, "0x%03x 0x%03x (0x%04x)",tmp-currentTree, tmp->jump?tmp->jump-currentTree:0,(tmp->jump?tmp->jump-currentTree:0)*6+0xcf0); - if(!(tmp.b0 & 0x8000)) { - //fprintf(stdout, " 0x%03x (%c)", tmp->b0,(tmp->b0<256 && isprint(tmp->b0))?tmp->b0:'�'); - } - if(!(tmp.b1 & 0x8000)) { - if((tmp.b0 & 0x8000)) - fprintf(stdout, " "); - fprintf(stdout, " 0x%03x (%c)", tmp->b1,(tmp->b1<256 && isprint(tmp->b1))?tmp->b1:'�'); - } - fprintf(stdout, "\n"); - } - }*/ - return 0; - }; - - function DecodeValue(currentTree) { - var len, i, - xtreepos = 0, - X = currentTree[xtreepos], - b; - - /* decode one symbol of the data */ - while (1) { - b = readBit(); - if (debug) - document.write("b=" + b); - if (b) { - if (!(X.b1 & 0x8000)) { - if (debug) - document.write("ret1"); - return X.b1; /* If leaf node, return data */ - } - X = X.jump; - len = currentTree.length; - for (i = 0; i < len; i++) { - if (currentTree[i] === X) { - xtreepos = i; - break; - } - } - //xtreepos++; - } else { - if (!(X.b0 & 0x8000)) { - if (debug) - document.write("ret2"); - return X.b0; /* If leaf node, return data */ - } - //X++; //?????????????????? - xtreepos++; - X = currentTree[xtreepos]; - } - } - }; - - function DeflateLoop() { - var last, c, type, i, len; - - do { - /*if((last = readBit())){ - fprintf(errfp, "Last Block: "); - } else { - fprintf(errfp, "Not Last Block: "); - }*/ - last = readBit(); - type = readBits(2); - switch (type) { - case 0: - if (debug) - alert("Stored\n"); - break; - case 1: - if (debug) - alert("Fixed Huffman codes\n"); - break; - case 2: - if (debug) - alert("Dynamic Huffman codes\n"); - break; - case 3: - if (debug) - alert("Reserved block type!!\n"); - break; - default: - if (debug) - alert("Unexpected value %d!\n", type); - break; - } - - if (type == 0) { - var blockLen, cSum; - - // Stored - byteAlign(); - blockLen = readByte(); - blockLen |= (readByte() << 8); - - cSum = readByte(); - cSum |= (readByte() << 8); - - if (((blockLen ^ ~cSum) & 0xffff)) { - document.write("BlockLen checksum mismatch\n"); - } - while (blockLen--) { - c = readByte(); - addBuffer(c); - } - } else if (type == 1) { - var j; - - /* Fixed Huffman tables -- fixed decode routine */ - while (1) { - /* - 256 0000000 0 - : : : - 279 0010111 23 - 0 00110000 48 - : : : - 143 10111111 191 - 280 11000000 192 - : : : - 287 11000111 199 - 144 110010000 400 - : : : - 255 111111111 511 - - Note the bit order! - */ - - j = (bitReverse[readBits(7)] >> 1); - if (j > 23) { - j = (j << 1) | readBit(); /* 48..255 */ - - if (j > 199) { /* 200..255 */ - j -= 128; /* 72..127 */ - j = (j << 1) | readBit(); /* 144..255 << */ - } else { /* 48..199 */ - j -= 48; /* 0..151 */ - if (j > 143) { - j = j + 136; /* 280..287 << */ - /* 0..143 << */ - } - } - } else { /* 0..23 */ - j += 256; /* 256..279 << */ - } - if (j < 256) { - addBuffer(j); - //document.write("out:"+String.fromCharCode(j)); - /*fprintf(errfp, "@%d %02x\n", SIZE, j);*/ - } else if (j == 256) { - /* EOF */ - break; - } else { - var len, dist; - - j -= 256 + 1; /* bytes + EOF */ - len = readBits(cplext[j]) + cplens[j]; - - j = bitReverse[readBits(5)] >> 3; - if (cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j] - 8) << 8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; - - /*fprintf(errfp, "@%d (l%02x,d%04x)\n", SIZE, len, dist);*/ - for (j = 0; j < len; j++) { - var c = buf32k[(bIdx - dist) & 0x7fff]; - addBuffer(c); - } - } - } // while - } else if (type == 2) { - var j, n, literalCodes, distCodes, lenCodes; - var ll = new Array(288 + 32); // "static" just to preserve stack - - // Dynamic Huffman tables - - literalCodes = 257 + readBits(5); - distCodes = 1 + readBits(5); - lenCodes = 4 + readBits(4); - //document.write("<br>param: "+literalCodes+" "+distCodes+" "+lenCodes+"<br>"); - for (j = 0; j < 19; j++) { - ll[j] = 0; - } - - // Get the decode tree code lengths - - //document.write("<br>"); - for (j = 0; j < lenCodes; j++) { - ll[border[j]] = readBits(3); - //document.write(ll[border[j]]+" "); - } - //fprintf(errfp, "\n"); - //document.write('<br>ll:'+ll); - len = distanceTree.length; - for (i = 0; i < len; i++) - distanceTree[i] = new HufNode(); - if (CreateTree(distanceTree, 19, ll, 0)) { - flushBuffer(); - return 1; - } - if (debug) { - document.write("<br>distanceTree"); - for (var a = 0; a < distanceTree.length; a++) { - document.write("<br>" + distanceTree[a].b0 + " " + distanceTree[a].b1 + " " + distanceTree[a].jump + " " + - distanceTree[a].jumppos); - /*if (distanceTree[a].jumppos!=-1) - document.write(" "+distanceTree[a].jump.b0+" "+distanceTree[a].jump.b1); - */ - } - } - //document.write('<BR>tree created'); - - //read in literal and distance code lengths - n = literalCodes + distCodes; - i = 0; - var z = -1; - if (debug) - document.write("<br>n=" + n + " bits: " + bits + "<br>"); - while (i < n) { - z++; - j = DecodeValue(distanceTree); - if (debug) - document.write("<br>" + z + " i:" + i + " decode: " + j + " bits " + bits + "<br>"); - if (j < 16) { // length of code in bits (0..15) - ll[i++] = j; - } else if (j == 16) { // repeat last length 3 to 6 times - var l; - j = 3 + readBits(2); - if (i + j > n) { - flushBuffer(); - return 1; - } - l = i ? ll[i - 1] : 0; - while (j--) { - ll[i++] = l; - } - } else { - if (j == 17) { // 3 to 10 zero length codes - j = 3 + readBits(3); - } else { // j == 18: 11 to 138 zero length codes - j = 11 + readBits(7); - } - if (i + j > n) { - flushBuffer(); - return 1; - } - while (j--) { - ll[i++] = 0; - } - } - } - /*for(j=0; j<literalCodes+distCodes; j++) { - //fprintf(errfp, "%d ", ll[j]); - if ((j&7)==7) - fprintf(errfp, "\n"); - } - fprintf(errfp, "\n");*/ - // Can overwrite tree decode tree as it is not used anymore - len = literalTree.length; - for (i = 0; i < len; i++) - literalTree[i] = new HufNode(); - if (CreateTree(literalTree, literalCodes, ll, 0)) { - flushBuffer(); - return 1; - } - len = literalTree.length; - for (i = 0; i < len; i++) - distanceTree[i] = new HufNode(); - var ll2 = new Array(); - for (i = literalCodes; i < ll.length; i++) { - ll2[i - literalCodes] = ll[i]; - } - if (CreateTree(distanceTree, distCodes, ll2, 0)) { - flushBuffer(); - return 1; - } - if (debug) - document.write("<br>literalTree"); - outer: while (1) { - j = DecodeValue(literalTree); - if (j >= 256) { // In C64: if carry set - var len, dist; - j -= 256; - if (j == 0) { - // EOF - break; - } - j--; - len = readBits(cplext[j]) + cplens[j]; - - j = DecodeValue(distanceTree); - if (cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j] - 8) << 8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; - while (len--) { - if (bIdx - dist < 0) { - break outer; - } - var c = buf32k[(bIdx - dist) & 0x7fff]; - addBuffer(c); - } - } else { - addBuffer(j); - } - } - } - } while (!last); - flushBuffer(); - - byteAlign(); - return 0; - }; - - JXG.Util.Unzip.prototype.unzipFile = function(name) { - var i; - this.unzip(); - //alert(unzipped[0][1]); - for (i = 0; i < unzipped.length; i++) { - if (unzipped[i][1] == name) { - return unzipped[i][0]; - } - } - - }; - - JXG.Util.Unzip.prototype.deflate = function() { - outputArr = []; - var tmp = []; - modeZIP = false; - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "DEFLATE"; - files++; - return unzipped; - } - - JXG.Util.Unzip.prototype.unzip = function() { - //convertToByteArray(input); - if (debug) - alert(bA); - /*for (i=0;i<bA.length*8;i++){ - document.write(readBit()); - if ((i+1)%8==0) - document.write(" "); - }*/ - /*for (i=0;i<bA.length;i++){ - document.write(readByte()+" "); - if ((i+1)%8==0) - document.write(" "); - } - for (i=0;i<bA.length;i++){ - document.write(bA[i]+" "); - if ((i+1)%16==0) - document.write("<br>"); - } - */ - //alert(bA); - nextFile(); - return unzipped; - }; - - function nextFile() { - if (debug) - alert("NEXTFILE"); - outputArr = []; - var tmp = []; - modeZIP = false; - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("type: " + tmp[0] + " " + tmp[1]); - if (tmp[0] == parseInt("78", 16) && tmp[1] == parseInt("da", 16)) { //GZIP - if (debug) - alert("GEONExT-GZIP"); - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "geonext.gxt"; - files++; - } - if (tmp[0] == parseInt("78", 16) && tmp[1] == parseInt("9c", 16)) { //ZLIB - if (debug) - alert("ZLIB"); - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "ZLIB"; - files++; - } - if (tmp[0] == parseInt("1f", 16) && tmp[1] == parseInt("8b", 16)) { //GZIP - if (debug) - alert("GZIP"); - //DeflateLoop(); - skipdir(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "file"; - files++; - } - if (tmp[0] == parseInt("50", 16) && tmp[1] == parseInt("4b", 16)) { //ZIP - modeZIP = true; - tmp[2] = readByte(); - tmp[3] = readByte(); - if (tmp[2] == parseInt("3", 16) && tmp[3] == parseInt("4", 16)) { - //MODE_ZIP - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("ZIP-Version: " + tmp[1] + " " + tmp[0] / 10 + "." + tmp[0] % 10); - - gpflags = readByte(); - gpflags |= (readByte() << 8); - if (debug) - alert("gpflags: " + gpflags); - - var method = readByte(); - method |= (readByte() << 8); - if (debug) - alert("method: " + method); - - readByte(); - readByte(); - readByte(); - readByte(); - - var crc = readByte(); - crc |= (readByte() << 8); - crc |= (readByte() << 16); - crc |= (readByte() << 24); - - var compSize = readByte(); - compSize |= (readByte() << 8); - compSize |= (readByte() << 16); - compSize |= (readByte() << 24); - - var size = readByte(); - size |= (readByte() << 8); - size |= (readByte() << 16); - size |= (readByte() << 24); - - if (debug) - alert("local CRC: " + crc + "\nlocal Size: " + size + "\nlocal CompSize: " + compSize); - - var filelen = readByte(); - filelen |= (readByte() << 8); - - var extralen = readByte(); - extralen |= (readByte() << 8); - - if (debug) - alert("filelen " + filelen); - i = 0; - nameBuf = []; - while (filelen--) { - var c = readByte(); - if (c == "/" | c == ":") { - i = 0; - } else if (i < NAMEMAX - 1) - nameBuf[i++] = String.fromCharCode(c); - } - if (debug) - alert("nameBuf: " + nameBuf); - - //nameBuf[i] = "\0"; - if (!fileout) - fileout = nameBuf; - - var i = 0; - while (i < extralen) { - c = readByte(); - i++; - } - - CRC = 0xffffffff; - SIZE = 0; - - if (size == 0 && fileOut.charAt(fileout.length - 1) == "/") { - //skipdir - if (debug) - alert("skipdir"); - } - if (method == 8) { - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = nameBuf.join(''); - files++; - //return outputArr.join(''); - } - skipdir(); - } - } - }; - - function skipdir() { - var crc, - tmp = [], - compSize, size, os, i, c; - - if ((gpflags & 8)) { - tmp[0] = readByte(); - tmp[1] = readByte(); - tmp[2] = readByte(); - tmp[3] = readByte(); - - if (tmp[0] == parseInt("50", 16) && - tmp[1] == parseInt("4b", 16) && - tmp[2] == parseInt("07", 16) && - tmp[3] == parseInt("08", 16)) { - crc = readByte(); - crc |= (readByte() << 8); - crc |= (readByte() << 16); - crc |= (readByte() << 24); - } else { - crc = tmp[0] | (tmp[1] << 8) | (tmp[2] << 16) | (tmp[3] << 24); - } - - compSize = readByte(); - compSize |= (readByte() << 8); - compSize |= (readByte() << 16); - compSize |= (readByte() << 24); - - size = readByte(); - size |= (readByte() << 8); - size |= (readByte() << 16); - size |= (readByte() << 24); - - if (debug) - alert("CRC:"); - } - - if (modeZIP) - nextFile(); - - tmp[0] = readByte(); - if (tmp[0] != 8) { - if (debug) - alert("Unknown compression method!"); - return 0; - } - - gpflags = readByte(); - if (debug) { - if ((gpflags & ~(parseInt("1f", 16)))) - alert("Unknown flags set!"); - } - - readByte(); - readByte(); - readByte(); - readByte(); - - readByte(); - os = readByte(); - - if ((gpflags & 4)) { - tmp[0] = readByte(); - tmp[2] = readByte(); - len = tmp[0] + 256 * tmp[1]; - if (debug) - alert("Extra field size: " + len); - for (i = 0; i < len; i++) - readByte(); - } - - if ((gpflags & 8)) { - i = 0; - nameBuf = []; - while (c = readByte()) { - if (c == "7" || c == ":") - i = 0; - if (i < NAMEMAX - 1) - nameBuf[i++] = c; - } - //nameBuf[i] = "\0"; - if (debug) - alert("original file name: " + nameBuf); - } - - if ((gpflags & 16)) { - while (c = readByte()) { - //FILE COMMENT - } - } - - if ((gpflags & 2)) { - readByte(); - readByte(); - } - - DeflateLoop(); - - crc = readByte(); - crc |= (readByte() << 8); - crc |= (readByte() << 16); - crc |= (readByte() << 24); - - size = readByte(); - size |= (readByte() << 8); - size |= (readByte() << 16); - size |= (readByte() << 24); - - if (modeZIP) - nextFile(); - - }; - -}; - -/** - * Base64 encoding / decoding - * {@link http://www.webtoolkit.info/} - */ -JXG.Util.Base64 = { - - // private property - _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", - - // public method for encoding - encode: function(input) { - var output = [], - chr1, chr2, chr3, enc1, enc2, enc3, enc4, - i = 0; - - input = JXG.Util.Base64._utf8_encode(input); - - while (i < input.length) { - - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - output.push([this._keyStr.charAt(enc1), - this._keyStr.charAt(enc2), - this._keyStr.charAt(enc3), - this._keyStr.charAt(enc4) - ].join('')); - } - - return output.join(''); - }, - - // public method for decoding - decode: function(input, utf8) { - var output = [], - chr1, chr2, chr3, - enc1, enc2, enc3, enc4, - i = 0; - - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - - enc1 = this._keyStr.indexOf(input.charAt(i++)); - enc2 = this._keyStr.indexOf(input.charAt(i++)); - enc3 = this._keyStr.indexOf(input.charAt(i++)); - enc4 = this._keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output.push(String.fromCharCode(chr1)); - - if (enc3 != 64) { - output.push(String.fromCharCode(chr2)); - } - if (enc4 != 64) { - output.push(String.fromCharCode(chr3)); - } - } - - output = output.join(''); - - if (utf8) { - output = JXG.Util.Base64._utf8_decode(output); - } - return output; - - }, - - // private method for UTF-8 encoding - _utf8_encode: function(string) { - string = string.replace(/\r\n/g, "\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // private method for UTF-8 decoding - _utf8_decode: function(utftext) { - var string = [], - i = 0, - c = 0, - c2 = 0, - c3 = 0; - - while (i < utftext.length) { - c = utftext.charCodeAt(i); - if (c < 128) { - string.push(String.fromCharCode(c)); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i + 1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - i += 2; - } else { - c2 = utftext.charCodeAt(i + 1); - c3 = utftext.charCodeAt(i + 2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - i += 3; - } - } - return string.join(''); - }, - - _destrip: function(stripped, wrap) { - var lines = [], - lineno, i, - destripped = []; - - if (wrap == null) - wrap = 76; - - stripped.replace(/ /g, ""); - lineno = stripped.length / wrap; - for (i = 0; i < lineno; i++) - lines[i] = stripped.substr(i * wrap, wrap); - if (lineno != stripped.length / wrap) - lines[lines.length] = stripped.substr(lineno * wrap, stripped.length - (lineno * wrap)); - - for (i = 0; i < lines.length; i++) - destripped.push(lines[i]); - return destripped.join('\n'); - }, - - decodeAsArray: function(input) { - var dec = this.decode(input), - ar = [], - i; - for (i = 0; i < dec.length; i++) { - ar[i] = dec.charCodeAt(i); - } - return ar; - }, - - decodeGEONExT: function(input) { - return decodeAsArray(destrip(input), false); - } -}; - -/** - * @private - */ -JXG.Util.asciiCharCodeAt = function(str, i) { - var c = str.charCodeAt(i); - if (c > 255) { - switch (c) { - case 8364: - c = 128; - break; - case 8218: - c = 130; - break; - case 402: - c = 131; - break; - case 8222: - c = 132; - break; - case 8230: - c = 133; - break; - case 8224: - c = 134; - break; - case 8225: - c = 135; - break; - case 710: - c = 136; - break; - case 8240: - c = 137; - break; - case 352: - c = 138; - break; - case 8249: - c = 139; - break; - case 338: - c = 140; - break; - case 381: - c = 142; - break; - case 8216: - c = 145; - break; - case 8217: - c = 146; - break; - case 8220: - c = 147; - break; - case 8221: - c = 148; - break; - case 8226: - c = 149; - break; - case 8211: - c = 150; - break; - case 8212: - c = 151; - break; - case 732: - c = 152; - break; - case 8482: - c = 153; - break; - case 353: - c = 154; - break; - case 8250: - c = 155; - break; - case 339: - c = 156; - break; - case 382: - c = 158; - break; - case 376: - c = 159; - break; - default: - break; - } - } - return c; -}; - -/** - * Decoding string into utf-8 - * @param {String} string to decode - * @return {String} utf8 decoded string - */ -JXG.Util.utf8Decode = function(utftext) { - var string = []; - var i = 0; - var c = 0, - c1 = 0, - c2 = 0, - c3; - if (!JXG.exists(utftext)) return ''; - - while (i < utftext.length) { - c = utftext.charCodeAt(i); - - if (c < 128) { - string.push(String.fromCharCode(c)); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i + 1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - i += 2; - } else { - c2 = utftext.charCodeAt(i + 1); - c3 = utftext.charCodeAt(i + 2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - i += 3; - } - }; - return string.join(''); -}; - -/** - * Generate a random uuid. - * http://www.broofa.com - * mailto:robert@broofa.com - * - * Copyright (c) 2010 Robert Kieffer - * Dual licensed under the MIT and GPL licenses. - * - * EXAMPLES: - * >>> Math.uuid() - * "92329D39-6F5C-4520-ABFC-AAB64544E172" - */ -JXG.Util.genUUID = function() { - // Private array of chars to use - var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''), - uuid = new Array(36), - rnd = 0, - r; - - for (var i = 0; i < 36; i++) { - if (i == 8 || i == 13 || i == 18 || i == 23) { - uuid[i] = '-'; - } else if (i == 14) { - uuid[i] = '4'; - } else { - if (rnd <= 0x02) rnd = 0x2000000 + (Math.random() * 0x1000000) | 0; - r = rnd & 0xf; - rnd = rnd >> 4; - uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; - } - } - - return uuid.join(''); -}; - - -module.exports = JXG; - -},{}],4:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var enums = require('../enums.js'); - -/** - * - * This object contains configuration values and implements - * storing and retrieving configuration them from HTML5 local storage. - * - * This object can be accessed after calling openpgp.init() - * using openpgp.config - * Stored config parameters can be accessed using - * openpgp.config.config - * @class - * @classdesc Implementation of the GPG4Browsers config object - */ -var config = function() { - /** - * @property {Integer} prefer_hash_algorithm - * @property {Integer} encryption_cipher - * @property {Integer} compression - * @property {Boolean} show_version - * @property {Boolean} show_comment - * @property {Boolean} integrity_protect - * @property {String} keyserver - */ - this.prefer_hash_algorithm = enums.hash.sha256; - this.encryption_cipher = enums.symmetric.aes256; - this.compression = enums.compression.zip; - this.show_version = true; - this.show_comment = true; - this.integrity_protect = true; - this.keyserver = "keyserver.linux.it"; // "pgp.mit.edu:11371" - - this.versionstring = "OpenPGP.js VERSION"; - this.commentstring = "http://openpgpjs.org"; - - /** - * If enabled, debug messages will be printed - */ - this.debug = false; - -}; - -module.exports = new config(); - -},{"../enums.js":28}],5:[function(require,module,exports){ -// Modified by Recurity Labs GmbH - -// modified version of http://www.hanewin.net/encrypt/PGdecode.js: - -/* OpenPGP encryption using RSA/AES - * Copyright 2005-2006 Herbert Hanewinkel, www.haneWIN.de - * version 2.0, check www.haneWIN.de for the latest version - - * This software is provided as-is, without express or implied warranty. - * Permission to use, copy, modify, distribute or sell this software, with or - * without fee, for any purpose and by any individual or organization, is hereby - * granted, provided that the above copyright notice and this paragraph appear - * in all copies. Distribution as a part of an application or binary must - * include the above copyright notice in the documentation and/or other - * materials provided with the application or distribution. - */ - -var util = require('../util'), - cipher = require('./cipher'); - -module.exports = { - - /** - * An array of bytes, that is integers with values from 0 to 255 - * @typedef {(Array|Uint8Array)} openpgp_byte_array - */ - - /** - * Block cipher function - * @callback openpgp_cipher_block_fn - * @param {openpgp_byte_array} block A block to perform operations on - * @param {openpgp_byte_array} key to use in encryption/decryption - * @return {openpgp_byte_array} Encrypted/decrypted block - */ - - - // -------------------------------------- - /** - * This function encrypts a given with the specified prefixrandom - * using the specified blockcipher to encrypt a message - * @param {String} prefixrandom random bytes of block_size length provided - * as a string to be used in prefixing the data - * @param {openpgp_cipher_block_fn} blockcipherfn the algorithm encrypt function to encrypt - * data in one block_size encryption. - * @param {Integer} block_size the block size in bytes of the algorithm used - * @param {String} plaintext data to be encrypted provided as a string - * @param {openpgp_byte_array} key key to be used to encrypt the data. This will be passed to the - * blockcipherfn - * @param {Boolean} resync a boolean value specifying if a resync of the - * IV should be used or not. The encrypteddatapacket uses the - * "old" style with a resync. Encryption within an - * encryptedintegrityprotecteddata packet is not resyncing the IV. - * @return {String} a string with the encrypted data - */ - encrypt: function(prefixrandom, cipherfn, plaintext, key, resync) { - cipherfn = new cipher[cipherfn](key); - var block_size = cipherfn.blockSize; - - var FR = new Array(block_size); - var FRE = new Array(block_size); - - prefixrandom = prefixrandom + prefixrandom.charAt(block_size - 2) + prefixrandom.charAt(block_size - 1); - util.print_debug("prefixrandom:" + util.hexstrdump(prefixrandom)); - var ciphertext = ""; - // 1. The feedback register (FR) is set to the IV, which is all zeros. - for (var i = 0; i < block_size; i++) FR[i] = 0; - - // 2. FR is encrypted to produce FRE (FR Encrypted). This is the - // encryption of an all-zero value. - FRE = cipherfn.encrypt(FR); - // 3. FRE is xored with the first BS octets of random data prefixed to - // the plaintext to produce C[1] through C[BS], the first BS octets - // of ciphertext. - for (var i = 0; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ prefixrandom.charCodeAt(i)); - - // 4. FR is loaded with C[1] through C[BS]. - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i); - - // 5. FR is encrypted to produce FRE, the encryption of the first BS - // octets of ciphertext. - FRE = cipherfn.encrypt(FR); - - // 6. The left two octets of FRE get xored with the next two octets of - // data that were prefixed to the plaintext. This produces C[BS+1] - // and C[BS+2], the next two octets of ciphertext. - ciphertext += String.fromCharCode(FRE[0] ^ prefixrandom.charCodeAt(block_size)); - ciphertext += String.fromCharCode(FRE[1] ^ prefixrandom.charCodeAt(block_size + 1)); - - if (resync) { - // 7. (The resync step) FR is loaded with C3-C10. - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i + 2); - } else { - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i); - } - // 8. FR is encrypted to produce FRE. - FRE = cipherfn.encrypt(FR, key); - - if (resync) { - // 9. FRE is xored with the first 8 octets of the given plaintext, now - // that we have finished encrypting the 10 octets of prefixed data. - // This produces C11-C18, the next 8 octets of ciphertext. - for (var i = 0; i < block_size; i++) - ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(i)); - for (n = block_size + 2; n < plaintext.length; n += block_size) { - // 10. FR is loaded with C11-C18 - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(n + i); - - // 11. FR is encrypted to produce FRE. - FRE = cipherfn.encrypt(FR); - - // 12. FRE is xored with the next 8 octets of plaintext, to produce the - // next 8 octets of ciphertext. These are loaded into FR and the - // process is repeated until the plaintext is used up. - for (var i = 0; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt((n - 2) + - i)); - } - } else { - plaintext = " " + plaintext; - // 9. FRE is xored with the first 8 octets of the given plaintext, now - // that we have finished encrypting the 10 octets of prefixed data. - // This produces C11-C18, the next 8 octets of ciphertext. - for (var i = 2; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(i)); - var tempCiphertext = ciphertext.substring(0, 2 * block_size).split(''); - var tempCiphertextString = ciphertext.substring(block_size); - for (n = block_size; n < plaintext.length; n += block_size) { - // 10. FR is loaded with C11-C18 - for (var i = 0; i < block_size; i++) FR[i] = tempCiphertextString.charCodeAt(i); - tempCiphertextString = ''; - - // 11. FR is encrypted to produce FRE. - FRE = cipherfn.encrypt(FR); - - // 12. FRE is xored with the next 8 octets of plaintext, to produce the - // next 8 octets of ciphertext. These are loaded into FR and the - // process is repeated until the plaintext is used up. - for (var i = 0; i < block_size; i++) { - tempCiphertext.push(String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(n + i))); - tempCiphertextString += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(n + i)); - } - } - ciphertext = tempCiphertext.join(''); - - } - - ciphertext = ciphertext.substring(0, plaintext.length + 2 + block_size); - - return ciphertext; - }, - - /** - * Decrypts the prefixed data for the Modification Detection Code (MDC) computation - * @param {openpgp_block_cipher_fn} cipherfn.encrypt Cipher function to use - * @param {Integer} block_size Blocksize of the algorithm - * @param {openpgp_byte_array} key The key for encryption - * @param {String} ciphertext The encrypted data - * @return {String} plaintext Data of D(ciphertext) with blocksize length +2 - */ - mdc: function(cipherfn, key, ciphertext) { - cipherfn = new cipher[cipherfn](key); - var block_size = cipherfn.blockSize; - - var iblock = new Array(block_size); - var ablock = new Array(block_size); - var i; - - - // initialisation vector - for (i = 0; i < block_size; i++) iblock[i] = 0; - - iblock = cipherfn.encrypt(iblock); - for (i = 0; i < block_size; i++) { - ablock[i] = ciphertext.charCodeAt(i); - iblock[i] ^= ablock[i]; - } - - ablock = cipherfn.encrypt(ablock); - - return util.bin2str(iblock) + - String.fromCharCode(ablock[0] ^ ciphertext.charCodeAt(block_size)) + - String.fromCharCode(ablock[1] ^ ciphertext.charCodeAt(block_size + 1)); - }, - /** - * This function decrypts a given plaintext using the specified - * blockcipher to decrypt a message - * @param {openpgp_cipher_block_fn} blockcipherfn The algorithm _encrypt_ function to encrypt - * data in one block_size encryption. - * @param {Integer} block_size the block size in bytes of the algorithm used - * @param {String} plaintext ciphertext to be decrypted provided as a string - * @param {openpgp_byte_array} key key to be used to decrypt the ciphertext. This will be passed to the - * blockcipherfn - * @param {Boolean} resync a boolean value specifying if a resync of the - * IV should be used or not. The encrypteddatapacket uses the - * "old" style with a resync. Decryption within an - * encryptedintegrityprotecteddata packet is not resyncing the IV. - * @return {String} a string with the plaintext data - */ - - decrypt: function(cipherfn, key, ciphertext, resync) { - cipherfn = new cipher[cipherfn](key); - var block_size = cipherfn.blockSize; - - var iblock = new Array(block_size); - var ablock = new Array(block_size); - var i, n = ''; - var text = []; - - // initialisation vector - for (i = 0; i < block_size; i++) iblock[i] = 0; - - iblock = cipherfn.encrypt(iblock, key); - for (i = 0; i < block_size; i++) { - ablock[i] = ciphertext.charCodeAt(i); - iblock[i] ^= ablock[i]; - } - - ablock = cipherfn.encrypt(ablock, key); - - // test check octets - if (iblock[block_size - 2] != (ablock[0] ^ ciphertext.charCodeAt(block_size)) || iblock[block_size - 1] != (ablock[ - 1] ^ ciphertext.charCodeAt(block_size + 1))) { - throw new Error('Invalid data.'); - } - - /* RFC4880: Tag 18 and Resync: - * [...] Unlike the Symmetrically Encrypted Data Packet, no - * special CFB resynchronization is done after encrypting this prefix - * data. See "OpenPGP CFB Mode" below for more details. - - */ - - if (resync) { - for (i = 0; i < block_size; i++) iblock[i] = ciphertext.charCodeAt(i + 2); - for (n = block_size + 2; n < ciphertext.length; n += block_size) { - ablock = cipherfn.encrypt(iblock); - - for (i = 0; i < block_size && i + n < ciphertext.length; i++) { - iblock[i] = ciphertext.charCodeAt(n + i); - text.push(String.fromCharCode(ablock[i] ^ iblock[i])); - } - } - } else { - for (i = 0; i < block_size; i++) iblock[i] = ciphertext.charCodeAt(i); - for (n = block_size; n < ciphertext.length; n += block_size) { - ablock = cipherfn.encrypt(iblock); - for (i = 0; i < block_size && i + n < ciphertext.length; i++) { - iblock[i] = ciphertext.charCodeAt(n + i); - text.push(String.fromCharCode(ablock[i] ^ iblock[i])); - } - } - } - - var n = resync ? 0 : 2; - - text = text.join(''); - - text = text.substring(n, ciphertext.length - block_size - 2 + n); - - - return text; - }, - - - normalEncrypt: function(cipherfn, key, plaintext, iv) { - cipherfn = new cipher[cipherfn](key); - var block_size = cipherfn.blockSize; - - var blocki = ""; - var blockc = ""; - var pos = 0; - var cyphertext = []; - var tempBlock = []; - blockc = iv.substring(0, block_size); - while (plaintext.length > block_size * pos) { - var encblock = cipherfn.encrypt(util.str2bin(blockc)); - blocki = plaintext.substring((pos * block_size), (pos * block_size) + block_size); - for (var i = 0; i < blocki.length; i++) - tempBlock.push(String.fromCharCode(blocki.charCodeAt(i) ^ encblock[i])); - blockc = tempBlock.join(''); - tempBlock = []; - cyphertext.push(blockc); - pos++; - } - return cyphertext.join(''); - }, - - normalDecrypt: function(cipherfn, key, ciphertext, iv) { - cipherfn = new cipher[cipherfn](key); - var block_size = cipherfn.blockSize; - - var blockp = ""; - var pos = 0; - var plaintext = []; - var offset = 0; - if (iv == null) - for (var i = 0; i < block_size; i++) blockp += String.fromCharCode(0); - else - blockp = iv.substring(0, block_size); - while (ciphertext.length > (block_size * pos)) { - var decblock = cipherfn.encrypt(util.str2bin(blockp)); - blockp = ciphertext.substring((pos * (block_size)) + offset, (pos * (block_size)) + (block_size) + offset); - for (var i = 0; i < blockp.length; i++) { - plaintext.push(String.fromCharCode(blockp.charCodeAt(i) ^ decblock[i])); - } - pos++; - } - - return plaintext.join(''); - } -} - -},{"../util":57,"./cipher":10}],6:[function(require,module,exports){ -/* Rijndael (AES) Encryption - * Copyright 2005 Herbert Hanewinkel, www.haneWIN.de - * version 1.1, check www.haneWIN.de for the latest version - - * This software is provided as-is, without express or implied warranty. - * Permission to use, copy, modify, distribute or sell this software, with or - * without fee, for any purpose and by any individual or organization, is hereby - * granted, provided that the above copyright notice and this paragraph appear - * in all copies. Distribution as a part of an application or binary must - * include the above copyright notice in the documentation and/or other - * materials provided with the application or distribution. - */ - -var util = require('../../util'); - -// The round constants used in subkey expansion -var Rcon = [ - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, - 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, - 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 -]; - -// Precomputed lookup table for the SBox -var S = [ - 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, - 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, - 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, - 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, - 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, - 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, - 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, - 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, - 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, - 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, - 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, - 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, - 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, - 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, - 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, - 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, - 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, - 22 -]; - -var T1 = [ - 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, - 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, - 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, - 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, - 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, - 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, - 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, - 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, - 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, - 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, - 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, - 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, - 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, - 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, - 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, - 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, - 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, - 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, - 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, - 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, - 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, - 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, - 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, - 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, - 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, - 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, - 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, - 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, - 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, - 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, - 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, - 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, - 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, - 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, - 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, - 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, - 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, - 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, - 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, - 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, - 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, - 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, - 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, - 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, - 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, - 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, - 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, - 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, - 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, - 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, - 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, - 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, - 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, - 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, - 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, - 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, - 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, - 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, - 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, - 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, - 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, - 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, - 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, - 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c -]; - -var T2 = [ - 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, - 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, - 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, - 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, - 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, - 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, - 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, - 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, - 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, - 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, - 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, - 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, - 0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, - 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, - 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, - 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, - 0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, - 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, - 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, - 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, - 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, - 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, - 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, - 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, - 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, - 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, - 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, - 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, - 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, - 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, - 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, - 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, - 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, - 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, - 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, - 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, - 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, - 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, - 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, - 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, - 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, - 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, - 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, - 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, - 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, - 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, - 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, - 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, - 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, - 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, - 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, - 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, - 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, - 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, - 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, - 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, - 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, - 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, - 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, - 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, - 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, - 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, - 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, - 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a -]; - -var T3 = [ - 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, - 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, - 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, - 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, - 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, - 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, - 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, - 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, - 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, - 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, - 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, - 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, - 0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, - 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, - 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, - 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, - 0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, - 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, - 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, - 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, - 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, - 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, - 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, - 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, - 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, - 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, - 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, - 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, - 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, - 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, - 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, - 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, - 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, - 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, - 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, - 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, - 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, - 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, - 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, - 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, - 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, - 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, - 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, - 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, - 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, - 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, - 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, - 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, - 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, - 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, - 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, - 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, - 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, - 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, - 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, - 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, - 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, - 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, - 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, - 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, - 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, - 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, - 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, - 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16 -]; - -var T4 = [ - 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, - 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, - 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, - 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, - 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, - 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, - 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, - 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, - 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, - 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, - 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, - 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, - 0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, - 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, - 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, - 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, - 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, - 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, - 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, - 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, - 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, - 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, - 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, - 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, - 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, - 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, - 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, - 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, - 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, - 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, - 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, - 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, - 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, - 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, - 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, - 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, - 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, - 0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888, - 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, - 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, - 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, - 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, - 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, - 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, - 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, - 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, - 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, - 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, - 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, - 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, - 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, - 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, - 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, - 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, - 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, - 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, - 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, - 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, - 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, - 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, - 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, - 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, - 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, - 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616 -]; - -function B0(x) { - return (x & 255); -} - -function B1(x) { - return ((x >> 8) & 255); -} - -function B2(x) { - return ((x >> 16) & 255); -} - -function B3(x) { - return ((x >> 24) & 255); -} - -function F1(x0, x1, x2, x3) { - return B1(T1[x0 & 255]) | (B1(T1[(x1 >> 8) & 255]) << 8) | (B1(T1[(x2 >> 16) & 255]) << 16) | (B1(T1[x3 >>> 24]) << - 24); -} - -function packBytes(octets) { - var i, j; - var len = octets.length; - var b = new Array(len / 4); - - if (!octets || len % 4) return; - - for (i = 0, j = 0; j < len; j += 4) - b[i++] = octets[j] | (octets[j + 1] << 8) | (octets[j + 2] << 16) | (octets[j + 3] << 24); - - return b; -} - -function unpackBytes(packed) { - var j; - var i = 0, - l = packed.length; - var r = new Array(l * 4); - - for (j = 0; j < l; j++) { - r[i++] = B0(packed[j]); - r[i++] = B1(packed[j]); - r[i++] = B2(packed[j]); - r[i++] = B3(packed[j]); - } - return r; -} - -// ------------------------------------------------ - -var maxkc = 8; -var maxrk = 14; - -function keyExpansion(key) { - var kc, i, j, r, t; - var rounds; - var keySched = new Array(maxrk + 1); - var keylen = key.length; - var k = new Array(maxkc); - var tk = new Array(maxkc); - var rconpointer = 0; - - if (keylen == 16) { - rounds = 10; - kc = 4; - } else if (keylen == 24) { - rounds = 12; - kc = 6; - } else if (keylen == 32) { - rounds = 14; - kc = 8; - } else { - util.print_error('aes.js: Invalid key-length for AES key:' + keylen); - return; - } - - for (i = 0; i < maxrk + 1; i++) keySched[i] = new Array(4); - - for (i = 0, j = 0; j < keylen; j++, i += 4) - k[j] = key.charCodeAt(i) | (key.charCodeAt(i + 1) << 8) | (key.charCodeAt(i + 2) << 16) | (key.charCodeAt(i + 3) << - 24); - - for (j = kc - 1; j >= 0; j--) tk[j] = k[j]; - - r = 0; - t = 0; - for (j = 0; - (j < kc) && (r < rounds + 1);) { - for (; - (j < kc) && (t < 4); j++, t++) { - keySched[r][t] = tk[j]; - } - if (t == 4) { - r++; - t = 0; - } - } - - while (r < rounds + 1) { - var temp = tk[kc - 1]; - - tk[0] ^= S[B1(temp)] | (S[B2(temp)] << 8) | (S[B3(temp)] << 16) | (S[B0(temp)] << 24); - tk[0] ^= Rcon[rconpointer++]; - - if (kc != 8) { - for (j = 1; j < kc; j++) tk[j] ^= tk[j - 1]; - } else { - for (j = 1; j < kc / 2; j++) tk[j] ^= tk[j - 1]; - - temp = tk[kc / 2 - 1]; - tk[kc / 2] ^= S[B0(temp)] | (S[B1(temp)] << 8) | (S[B2(temp)] << 16) | (S[B3(temp)] << 24); - - for (j = kc / 2 + 1; j < kc; j++) tk[j] ^= tk[j - 1]; - } - - for (j = 0; - (j < kc) && (r < rounds + 1);) { - for (; - (j < kc) && (t < 4); j++, t++) { - keySched[r][t] = tk[j]; - } - if (t == 4) { - r++; - t = 0; - } - } - } - this.rounds = rounds; - this.rk = keySched; - return this; -} - -function AESencrypt(block, ctx) { - var r; - var t0, t1, t2, t3; - - var b = packBytes(block); - var rounds = ctx.rounds; - var b0 = b[0]; - var b1 = b[1]; - var b2 = b[2]; - var b3 = b[3]; - - for (r = 0; r < rounds - 1; r++) { - t0 = b0 ^ ctx.rk[r][0]; - t1 = b1 ^ ctx.rk[r][1]; - t2 = b2 ^ ctx.rk[r][2]; - t3 = b3 ^ ctx.rk[r][3]; - - b0 = T1[t0 & 255] ^ T2[(t1 >> 8) & 255] ^ T3[(t2 >> 16) & 255] ^ T4[t3 >>> 24]; - b1 = T1[t1 & 255] ^ T2[(t2 >> 8) & 255] ^ T3[(t3 >> 16) & 255] ^ T4[t0 >>> 24]; - b2 = T1[t2 & 255] ^ T2[(t3 >> 8) & 255] ^ T3[(t0 >> 16) & 255] ^ T4[t1 >>> 24]; - b3 = T1[t3 & 255] ^ T2[(t0 >> 8) & 255] ^ T3[(t1 >> 16) & 255] ^ T4[t2 >>> 24]; - } - - // last round is special - r = rounds - 1; - - t0 = b0 ^ ctx.rk[r][0]; - t1 = b1 ^ ctx.rk[r][1]; - t2 = b2 ^ ctx.rk[r][2]; - t3 = b3 ^ ctx.rk[r][3]; - - b[0] = F1(t0, t1, t2, t3) ^ ctx.rk[rounds][0]; - b[1] = F1(t1, t2, t3, t0) ^ ctx.rk[rounds][1]; - b[2] = F1(t2, t3, t0, t1) ^ ctx.rk[rounds][2]; - b[3] = F1(t3, t0, t1, t2) ^ ctx.rk[rounds][3]; - - return unpackBytes(b); -} - -function makeClass(length) { - - var c = function(key) { - this.key = keyExpansion(key); - - this.encrypt = function(block) { - return AESencrypt(block, this.key); - } - } - - c.blockSize = c.prototype.blockSize = 16; - c.keySize = c.prototype.keySize = length / 8; - - return c; -} - -module.exports = {} - -var types = [128, 192, 256]; - -for (var i in types) { - module.exports[types[i]] = makeClass(types[i]); -} - -},{"../../util":57}],7:[function(require,module,exports){ -/* Modified by Recurity Labs GmbH - * - * Originally written by nklein software (nklein.com) - */ - -/* - * Javascript implementation based on Bruce Schneier's reference implementation. - * - * - * The constructor doesn't do much of anything. It's just here - * so we can start defining properties and methods and such. - */ -function Blowfish() {}; - -/* - * Declare the block size so that protocols know what size - * Initialization Vector (IV) they will need. - */ -Blowfish.prototype.BLOCKSIZE = 8; - -/* - * These are the default SBOXES. - */ -Blowfish.prototype.SBOXES = [ - [ - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, - 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, - 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, - 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, - 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, - 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, - 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, - 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, - 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, - 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, - 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, - 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, - 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, - 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, - 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, - 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, - 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, - 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, - 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, - 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, - 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, - 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a - ], - [ - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, - 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, - 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, - 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, - 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, - 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, - 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, - 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, - 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, - 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, - 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, - 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, - 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, - 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, - 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, - 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, - 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, - 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, - 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, - 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, - 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, - 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 - ], - [ - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, - 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, - 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, - 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, - 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, - 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, - 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, - 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, - 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, - 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, - 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, - 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, - 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, - 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, - 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, - 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, - 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, - 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, - 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, - 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, - 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, - 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 - ], - [ - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, - 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, - 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, - 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, - 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, - 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, - 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, - 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, - 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, - 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, - 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, - 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, - 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, - 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, - 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, - 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, - 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, - 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, - 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, - 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, - 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, - 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 - ] -]; - -//* -//* This is the default PARRAY -//* -Blowfish.prototype.PARRAY = [ - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, - 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b -]; - -//* -//* This is the number of rounds the cipher will go -//* -Blowfish.prototype.NN = 16; - -//* -//* This function is needed to get rid of problems -//* with the high-bit getting set. If we don't do -//* this, then sometimes ( aa & 0x00FFFFFFFF ) is not -//* equal to ( bb & 0x00FFFFFFFF ) even when they -//* agree bit-for-bit for the first 32 bits. -//* -Blowfish.prototype._clean = function(xx) { - if (xx < 0) { - var yy = xx & 0x7FFFFFFF; - xx = yy + 0x80000000; - } - return xx; -}; - -//* -//* This is the mixing function that uses the sboxes -//* -Blowfish.prototype._F = function(xx) { - var aa; - var bb; - var cc; - var dd; - var yy; - - dd = xx & 0x00FF; - xx >>>= 8; - cc = xx & 0x00FF; - xx >>>= 8; - bb = xx & 0x00FF; - xx >>>= 8; - aa = xx & 0x00FF; - - yy = this.sboxes[0][aa] + this.sboxes[1][bb]; - yy = yy ^ this.sboxes[2][cc]; - yy = yy + this.sboxes[3][dd]; - - return yy; -}; - -//* -//* This method takes an array with two values, left and right -//* and does NN rounds of Blowfish on them. -//* -Blowfish.prototype._encrypt_block = function(vals) { - var dataL = vals[0]; - var dataR = vals[1]; - - var ii; - - for (ii = 0; ii < this.NN; ++ii) { - dataL = dataL ^ this.parray[ii]; - dataR = this._F(dataL) ^ dataR; - - var tmp = dataL; - dataL = dataR; - dataR = tmp; - } - - dataL = dataL ^ this.parray[this.NN + 0]; - dataR = dataR ^ this.parray[this.NN + 1]; - - vals[0] = this._clean(dataR); - vals[1] = this._clean(dataL); -}; - -//* -//* This method takes a vector of numbers and turns them -//* into long words so that they can be processed by the -//* real algorithm. -//* -//* Maybe I should make the real algorithm above take a vector -//* instead. That will involve more looping, but it won't require -//* the F() method to deconstruct the vector. -//* -Blowfish.prototype.encrypt_block = function(vector) { - var ii; - var vals = [0, 0]; - var off = this.BLOCKSIZE / 2; - for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) { - vals[0] = (vals[0] << 8) | (vector[ii + 0] & 0x00FF); - vals[1] = (vals[1] << 8) | (vector[ii + off] & 0x00FF); - } - - this._encrypt_block(vals); - - var ret = []; - for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) { - ret[ii + 0] = (vals[0] >>> (24 - 8 * (ii)) & 0x00FF); - ret[ii + off] = (vals[1] >>> (24 - 8 * (ii)) & 0x00FF); - // vals[ 0 ] = ( vals[ 0 ] >>> 8 ); - // vals[ 1 ] = ( vals[ 1 ] >>> 8 ); - } - - return ret; -}; - -//* -//* This method takes an array with two values, left and right -//* and undoes NN rounds of Blowfish on them. -//* -Blowfish.prototype._decrypt_block = function(vals) { - var dataL = vals[0]; - var dataR = vals[1]; - - var ii; - - for (ii = this.NN + 1; ii > 1; --ii) { - dataL = dataL ^ this.parray[ii]; - dataR = this._F(dataL) ^ dataR; - - var tmp = dataL; - dataL = dataR; - dataR = tmp; - } - - dataL = dataL ^ this.parray[1]; - dataR = dataR ^ this.parray[0]; - - vals[0] = this._clean(dataR); - vals[1] = this._clean(dataL); -}; - -//* -//* This method takes a key array and initializes the -//* sboxes and parray for this encryption. -//* -Blowfish.prototype.init = function(key) { - var ii; - var jj = 0; - - this.parray = []; - for (ii = 0; ii < this.NN + 2; ++ii) { - var data = 0x00000000; - var kk; - for (kk = 0; kk < 4; ++kk) { - data = (data << 8) | (key[jj] & 0x00FF); - if (++jj >= key.length) { - jj = 0; - } - } - this.parray[ii] = this.PARRAY[ii] ^ data; - } - - this.sboxes = []; - for (ii = 0; ii < 4; ++ii) { - this.sboxes[ii] = []; - for (jj = 0; jj < 256; ++jj) { - this.sboxes[ii][jj] = this.SBOXES[ii][jj]; - } - } - - var vals = [0x00000000, 0x00000000]; - - for (ii = 0; ii < this.NN + 2; ii += 2) { - this._encrypt_block(vals); - this.parray[ii + 0] = vals[0]; - this.parray[ii + 1] = vals[1]; - } - - for (ii = 0; ii < 4; ++ii) { - for (jj = 0; jj < 256; jj += 2) { - this._encrypt_block(vals); - this.sboxes[ii][jj + 0] = vals[0]; - this.sboxes[ii][jj + 1] = vals[1]; - } - } -}; - -var util = require('../../util'); - -// added by Recurity Labs - -function BFencrypt(block, key) { - var bf = new Blowfish(); - bf.init(util.str2bin(key)); - return bf.encrypt_block(block); -} - -function BF(key) { - this.bf = new Blowfish(); - this.bf.init(util.str2bin(key)); - - this.encrypt = function(block) { - return this.bf.encrypt_block(block); - } -} - - -module.exports = BF; -module.exports.keySize = BF.prototype.keySize = 16; -module.exports.blockSize = BF.prototype.blockSize = 16; - -},{"../../util":57}],8:[function(require,module,exports){ -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Copyright 2010 pjacobs@xeekr.com . All rights reserved. - -// Modified by Recurity Labs GmbH - -// fixed/modified by Herbert Hanewinkel, www.haneWIN.de -// check www.haneWIN.de for the latest version - -// cast5.js is a Javascript implementation of CAST-128, as defined in RFC 2144. -// CAST-128 is a common OpenPGP cipher. - - -// CAST5 constructor - - - -function openpgp_symenc_cast5() { - this.BlockSize = 8; - this.KeySize = 16; - - this.setKey = function(key) { - this.masking = new Array(16); - this.rotate = new Array(16); - - this.reset(); - - if (key.length == this.KeySize) { - this.keySchedule(key); - } else { - util.print_error('cast5.js: CAST-128: keys must be 16 bytes'); - return false; - } - return true; - }; - - this.reset = function() { - for (var i = 0; i < 16; i++) { - this.masking[i] = 0; - this.rotate[i] = 0; - } - }; - - this.getBlockSize = function() { - return BlockSize; - }; - - this.encrypt = function(src) { - var dst = new Array(src.length); - - for (var i = 0; i < src.length; i += 8) { - var l = src[i] << 24 | src[i + 1] << 16 | src[i + 2] << 8 | src[i + 3]; - var r = src[i + 4] << 24 | src[i + 5] << 16 | src[i + 6] << 8 | src[i + 7]; - var t; - - t = r; - r = l ^ f1(r, this.masking[0], this.rotate[0]); - l = t; - t = r; - r = l ^ f2(r, this.masking[1], this.rotate[1]); - l = t; - t = r; - r = l ^ f3(r, this.masking[2], this.rotate[2]); - l = t; - t = r; - r = l ^ f1(r, this.masking[3], this.rotate[3]); - l = t; - - t = r; - r = l ^ f2(r, this.masking[4], this.rotate[4]); - l = t; - t = r; - r = l ^ f3(r, this.masking[5], this.rotate[5]); - l = t; - t = r; - r = l ^ f1(r, this.masking[6], this.rotate[6]); - l = t; - t = r; - r = l ^ f2(r, this.masking[7], this.rotate[7]); - l = t; - - t = r; - r = l ^ f3(r, this.masking[8], this.rotate[8]); - l = t; - t = r; - r = l ^ f1(r, this.masking[9], this.rotate[9]); - l = t; - t = r; - r = l ^ f2(r, this.masking[10], this.rotate[10]); - l = t; - t = r; - r = l ^ f3(r, this.masking[11], this.rotate[11]); - l = t; - - t = r; - r = l ^ f1(r, this.masking[12], this.rotate[12]); - l = t; - t = r; - r = l ^ f2(r, this.masking[13], this.rotate[13]); - l = t; - t = r; - r = l ^ f3(r, this.masking[14], this.rotate[14]); - l = t; - t = r; - r = l ^ f1(r, this.masking[15], this.rotate[15]); - l = t; - - dst[i] = (r >>> 24) & 255; - dst[i + 1] = (r >>> 16) & 255; - dst[i + 2] = (r >>> 8) & 255; - dst[i + 3] = r & 255; - dst[i + 4] = (l >>> 24) & 255; - dst[i + 5] = (l >>> 16) & 255; - dst[i + 6] = (l >>> 8) & 255; - dst[i + 7] = l & 255; - } - - return dst; - }; - - this.decrypt = function(src) { - var dst = new Array(src.length); - - for (var i = 0; i < src.length; i += 8) { - var l = src[i] << 24 | src[i + 1] << 16 | src[i + 2] << 8 | src[i + 3]; - var r = src[i + 4] << 24 | src[i + 5] << 16 | src[i + 6] << 8 | src[i + 7]; - var t; - - t = r; - r = l ^ f1(r, this.masking[15], this.rotate[15]); - l = t; - t = r; - r = l ^ f3(r, this.masking[14], this.rotate[14]); - l = t; - t = r; - r = l ^ f2(r, this.masking[13], this.rotate[13]); - l = t; - t = r; - r = l ^ f1(r, this.masking[12], this.rotate[12]); - l = t; - - t = r; - r = l ^ f3(r, this.masking[11], this.rotate[11]); - l = t; - t = r; - r = l ^ f2(r, this.masking[10], this.rotate[10]); - l = t; - t = r; - r = l ^ f1(r, this.masking[9], this.rotate[9]); - l = t; - t = r; - r = l ^ f3(r, this.masking[8], this.rotate[8]); - l = t; - - t = r; - r = l ^ f2(r, this.masking[7], this.rotate[7]); - l = t; - t = r; - r = l ^ f1(r, this.masking[6], this.rotate[6]); - l = t; - t = r; - r = l ^ f3(r, this.masking[5], this.rotate[5]); - l = t; - t = r; - r = l ^ f2(r, this.masking[4], this.rotate[4]); - l = t; - - t = r; - r = l ^ f1(r, this.masking[3], this.rotate[3]); - l = t; - t = r; - r = l ^ f3(r, this.masking[2], this.rotate[2]); - l = t; - t = r; - r = l ^ f2(r, this.masking[1], this.rotate[1]); - l = t; - t = r; - r = l ^ f1(r, this.masking[0], this.rotate[0]); - l = t; - - dst[i] = (r >>> 24) & 255; - dst[i + 1] = (r >>> 16) & 255; - dst[i + 2] = (r >>> 8) & 255; - dst[i + 3] = r & 255; - dst[i + 4] = (l >>> 24) & 255; - dst[i + 5] = (l >> 16) & 255; - dst[i + 6] = (l >> 8) & 255; - dst[i + 7] = l & 255; - } - - return dst; - }; - var scheduleA = new Array(4); - - scheduleA[0] = new Array(4); - scheduleA[0][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 0x8); - scheduleA[0][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa); - scheduleA[0][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9); - scheduleA[0][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb); - - scheduleA[1] = new Array(4); - scheduleA[1][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0); - scheduleA[1][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2); - scheduleA[1][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1); - scheduleA[1][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3); - - scheduleA[2] = new Array(4); - scheduleA[2][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 8); - scheduleA[2][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa); - scheduleA[2][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9); - scheduleA[2][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb); - - - scheduleA[3] = new Array(4); - scheduleA[3][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0); - scheduleA[3][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2); - scheduleA[3][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1); - scheduleA[3][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3); - - var scheduleB = new Array(4); - - scheduleB[0] = new Array(4); - scheduleB[0][0] = new Array(16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2); - scheduleB[0][1] = new Array(16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6); - scheduleB[0][2] = new Array(16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9); - scheduleB[0][3] = new Array(16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc); - - scheduleB[1] = new Array(4); - scheduleB[1][0] = new Array(3, 2, 0xc, 0xd, 8); - scheduleB[1][1] = new Array(1, 0, 0xe, 0xf, 0xd); - scheduleB[1][2] = new Array(7, 6, 8, 9, 3); - scheduleB[1][3] = new Array(5, 4, 0xa, 0xb, 7); - - - scheduleB[2] = new Array(4); - scheduleB[2][0] = new Array(16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9); - scheduleB[2][1] = new Array(16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc); - scheduleB[2][2] = new Array(16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2); - scheduleB[2][3] = new Array(16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6); - - - scheduleB[3] = new Array(4); - scheduleB[3][0] = new Array(8, 9, 7, 6, 3); - scheduleB[3][1] = new Array(0xa, 0xb, 5, 4, 7); - scheduleB[3][2] = new Array(0xc, 0xd, 3, 2, 8); - scheduleB[3][3] = new Array(0xe, 0xf, 1, 0, 0xd); - - // changed 'in' to 'inn' (in javascript 'in' is a reserved word) - this.keySchedule = function(inn) { - var t = new Array(8); - var k = new Array(32); - - for (var i = 0; i < 4; i++) { - var j = i * 4; - t[i] = inn[j] << 24 | inn[j + 1] << 16 | inn[j + 2] << 8 | inn[j + 3]; - } - - var x = [6, 7, 4, 5]; - var ki = 0; - - for (var half = 0; half < 2; half++) { - for (var round = 0; round < 4; round++) { - for (var j = 0; j < 4; j++) { - var a = scheduleA[round][j]; - var w = t[a[1]]; - - w ^= sBox[4][(t[a[2] >>> 2] >>> (24 - 8 * (a[2] & 3))) & 0xff]; - w ^= sBox[5][(t[a[3] >>> 2] >>> (24 - 8 * (a[3] & 3))) & 0xff]; - w ^= sBox[6][(t[a[4] >>> 2] >>> (24 - 8 * (a[4] & 3))) & 0xff]; - w ^= sBox[7][(t[a[5] >>> 2] >>> (24 - 8 * (a[5] & 3))) & 0xff]; - w ^= sBox[x[j]][(t[a[6] >>> 2] >>> (24 - 8 * (a[6] & 3))) & 0xff]; - t[a[0]] = w; - } - - for (var j = 0; j < 4; j++) { - var b = scheduleB[round][j]; - var w = sBox[4][(t[b[0] >>> 2] >>> (24 - 8 * (b[0] & 3))) & 0xff]; - - w ^= sBox[5][(t[b[1] >>> 2] >>> (24 - 8 * (b[1] & 3))) & 0xff]; - w ^= sBox[6][(t[b[2] >>> 2] >>> (24 - 8 * (b[2] & 3))) & 0xff]; - w ^= sBox[7][(t[b[3] >>> 2] >>> (24 - 8 * (b[3] & 3))) & 0xff]; - w ^= sBox[4 + j][(t[b[4] >>> 2] >>> (24 - 8 * (b[4] & 3))) & 0xff]; - k[ki] = w; - ki++; - } - } - } - - for (var i = 0; i < 16; i++) { - this.masking[i] = k[i]; - this.rotate[i] = k[16 + i] & 0x1f; - } - }; - - // These are the three 'f' functions. See RFC 2144, section 2.2. - - function f1(d, m, r) { - var t = m + d; - var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I >>> 24] ^ sBox[1][(I >>> 16) & 255]) - sBox[2][(I >>> 8) & 255]) + sBox[3][I & 255]; - } - - function f2(d, m, r) { - var t = m ^ d; - var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I >>> 24] - sBox[1][(I >>> 16) & 255]) + sBox[2][(I >>> 8) & 255]) ^ sBox[3][I & 255]; - } - - function f3(d, m, r) { - var t = m - d; - var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I >>> 24] + sBox[1][(I >>> 16) & 255]) ^ sBox[2][(I >>> 8) & 255]) - sBox[3][I & 255]; - } - - var sBox = new Array(8); - sBox[0] = new Array( - 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, - 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, - 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, - 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, - 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, - 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, - 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, - 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, - 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, - 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, - 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, - 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, - 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, - 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, - 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, - 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, - 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, - 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, - 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, - 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, - 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, - 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, - 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, - 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, - 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, - 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, - 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, - 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, - 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, - 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, - 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, - 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf); - - sBox[1] = new Array( - 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, - 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, - 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, - 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, - 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, - 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, - 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, - 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, - 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, - 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, - 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, - 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, - 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, - 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, - 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, - 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, - 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, - 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, - 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, - 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, - 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, - 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, - 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, - 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, - 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, - 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, - 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, - 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, - 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, - 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, - 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, - 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1); - - sBox[2] = new Array( - 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, - 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, - 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, - 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, - 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, - 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, - 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, - 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, - 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, - 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, - 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, - 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, - 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, - 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, - 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, - 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, - 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, - 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, - 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, - 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, - 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, - 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, - 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, - 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, - 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, - 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, - 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, - 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, - 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, - 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, - 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, - 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783); - - sBox[3] = new Array( - 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, - 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, - 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, - 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, - 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, - 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, - 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, - 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, - 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, - 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, - 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, - 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, - 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, - 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, - 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, - 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, - 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, - 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, - 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, - 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, - 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, - 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, - 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, - 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, - 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, - 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, - 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, - 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, - 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, - 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, - 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, - 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2); - - sBox[4] = new Array( - 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, - 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, - 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, - 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, - 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, - 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, - 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, - 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, - 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, - 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, - 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, - 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, - 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, - 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, - 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, - 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, - 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, - 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, - 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, - 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, - 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, - 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, - 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, - 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, - 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, - 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, - 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, - 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, - 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, - 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, - 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, - 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4); - - sBox[5] = new Array( - 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, - 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, - 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, - 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, - 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, - 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, - 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, - 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, - 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, - 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, - 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, - 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, - 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, - 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, - 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, - 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, - 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, - 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, - 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, - 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, - 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, - 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, - 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, - 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, - 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, - 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, - 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, - 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, - 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, - 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, - 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, - 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f); - - sBox[6] = new Array( - 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, - 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, - 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, - 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, - 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, - 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, - 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, - 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, - 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, - 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, - 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, - 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, - 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, - 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, - 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, - 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, - 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, - 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, - 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, - 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, - 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, - 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, - 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, - 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, - 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, - 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, - 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, - 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, - 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, - 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, - 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, - 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3); - - sBox[7] = new Array( - 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, - 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, - 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, - 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, - 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, - 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, - 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, - 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, - 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, - 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, - 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, - 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, - 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, - 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, - 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, - 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, - 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, - 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, - 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, - 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, - 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, - 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, - 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, - 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, - 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, - 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, - 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, - 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, - 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, - 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, - 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, - 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e); - -}; - -var util = require('../../util'); - -function cast5(key) { - this.cast5 = new openpgp_symenc_cast5(); - this.cast5.setKey(util.str2bin(key)); - - this.encrypt = function(block) { - return this.cast5.encrypt(block); - } -} - -module.exports = cast5; -module.exports.blockSize = cast5.prototype.blockSize = 8; -module.exports.keySize = cast5.prototype.keySize = 16; - -},{"../../util":57}],9:[function(require,module,exports){ -//Paul Tero, July 2001 -//http://www.tero.co.uk/des/ -// -//Optimised for performance with large blocks by Michael Hayworth, November 2001 -//http://www.netdealing.com -// -// Modified by Recurity Labs GmbH - -//THIS SOFTWARE IS PROVIDED "AS IS" AND -//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -//SUCH DAMAGE. - -//des -//this takes the key, the message, and whether to encrypt or decrypt - - - - -function des(keys, message, encrypt, mode, iv, padding) { - //declaring this locally speeds things up a bit - var spfunction1 = new Array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400, - 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000, - 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4, - 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404, - 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400, - 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004); - var spfunction2 = new Array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, - - 0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, - - 0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, - - 0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, - - 0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0, - 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, - - 0x7fef7fe0, 0x108000); - var spfunction3 = new Array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008, - 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000, - 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000, - 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0, - 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208, - 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200); - var spfunction4 = new Array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000, - 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080, - 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0, - 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001, - 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080); - var spfunction5 = new Array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000, - 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000, - 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100, - 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100, - 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100, - 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0, - 0x40080000, 0x2080100, 0x40000100); - var spfunction6 = new Array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000, - 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010, - 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000, - 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000, - 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000, - 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010); - var spfunction7 = new Array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802, - 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, - 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000, - 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000, - 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0, - 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002); - var spfunction8 = new Array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000, - 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000, - 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040, - 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040, - 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000, - 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000); - - //create the 16 or 48 subkeys we will need - var m = 0, - i, j, temp, temp2, right1, right2, left, right, looping; - var cbcleft, cbcleft2, cbcright, cbcright2 - var endloop, loopinc; - var len = message.length; - var chunk = 0; - //set up the loops for single and triple des - var iterations = keys.length == 32 ? 3 : 9; //single or triple des - if (iterations == 3) { - looping = encrypt ? new Array(0, 32, 2) : new Array(30, -2, -2); - } else { - looping = encrypt ? new Array(0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array(94, 62, -2, 32, 64, 2, 30, -2, -2); - } - - //pad the message depending on the padding parameter - //only add padding if encrypting - note that you need to use the same padding option for both encrypt and decrypt - if (encrypt) { - message = des_addPadding(message, padding); - len = message.length; - } - - //store the result here - result = ""; - tempresult = ""; - - if (mode == 1) { //CBC mode - cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); - cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); - m = 0; - } - - //loop through each 64 bit chunk of the message - while (m < len) { - left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message - .charCodeAt(m++); - right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | - message.charCodeAt(m++); - - //for Cipher Block Chaining mode, xor the message with the previous result - if (mode == 1) { - if (encrypt) { - left ^= cbcleft; - right ^= cbcright; - } else { - cbcleft2 = cbcleft; - cbcright2 = cbcright; - cbcleft = left; - cbcright = right; - } - } - - //first each 64 but chunk of the message must be permuted according to IP - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; - right ^= temp; - left ^= (temp << 4); - temp = ((left >>> 16) ^ right) & 0x0000ffff; - right ^= temp; - left ^= (temp << 16); - temp = ((right >>> 2) ^ left) & 0x33333333; - left ^= temp; - right ^= (temp << 2); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; - left ^= temp; - right ^= (temp << 8); - temp = ((left >>> 1) ^ right) & 0x55555555; - right ^= temp; - left ^= (temp << 1); - - left = ((left << 1) | (left >>> 31)); - right = ((right << 1) | (right >>> 31)); - - //do this either 1 or 3 times for each chunk of the message - for (j = 0; j < iterations; j += 3) { - endloop = looping[j + 1]; - loopinc = looping[j + 2]; - //now go through and perform the encryption or decryption - for (i = looping[j]; i != endloop; i += loopinc) { //for efficiency - right1 = right ^ keys[i]; - right2 = ((right >>> 4) | (right << 28)) ^ keys[i + 1]; - //the result is attained by passing these bytes through the S selection functions - temp = left; - left = right; - right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] | spfunction6[(right1 >>> - 8) & 0x3f] | spfunction8[right1 & 0x3f] | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & - 0x3f] | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]); - } - temp = left; - left = right; - right = temp; //unreverse left and right - } //for either 1 or 3 iterations - - //move then each one bit to the right - left = ((left >>> 1) | (left << 31)); - right = ((right >>> 1) | (right << 31)); - - //now perform IP-1, which is IP in the opposite direction - temp = ((left >>> 1) ^ right) & 0x55555555; - right ^= temp; - left ^= (temp << 1); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; - left ^= temp; - right ^= (temp << 8); - temp = ((right >>> 2) ^ left) & 0x33333333; - left ^= temp; - right ^= (temp << 2); - temp = ((left >>> 16) ^ right) & 0x0000ffff; - right ^= temp; - left ^= (temp << 16); - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; - right ^= temp; - left ^= (temp << 4); - - //for Cipher Block Chaining mode, xor the message with the previous result - if (mode == 1) { - if (encrypt) { - cbcleft = left; - cbcright = right; - } else { - left ^= cbcleft2; - right ^= cbcright2; - } - } - tempresult += String.fromCharCode((left >>> 24), ((left >>> 16) & 0xff), ((left >>> 8) & 0xff), (left & 0xff), ( - right >>> 24), ((right >>> 16) & 0xff), ((right >>> 8) & 0xff), (right & 0xff)); - - chunk += 8; - if (chunk == 512) { - result += tempresult; - tempresult = ""; - chunk = 0; - } - } //for every 8 characters, or 64 bits in the message - - //return the result as an array - result += tempresult; - - //only remove padding if decrypting - note that you need to use the same padding option for both encrypt and decrypt - if (!encrypt) { - result = des_removePadding(result, padding); - } - - return result; -} //end of des - - - -//des_createKeys -//this takes as input a 64 bit key (even though only 56 bits are used) -//as an array of 2 integers, and returns 16 48 bit keys - -function des_createKeys(key) { - //declaring this locally speeds things up a bit - pc2bytes0 = new Array(0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204, - 0x20000200, 0x20000204, 0x10200, 0x10204, 0x20010200, 0x20010204); - pc2bytes1 = new Array(0, 0x1, 0x100000, 0x100001, 0x4000000, 0x4000001, 0x4100000, 0x4100001, 0x100, 0x101, 0x100100, - 0x100101, 0x4000100, 0x4000101, 0x4100100, 0x4100101); - pc2bytes2 = new Array(0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808, 0, 0x8, 0x800, 0x808, - 0x1000000, 0x1000008, 0x1000800, 0x1000808); - pc2bytes3 = new Array(0, 0x200000, 0x8000000, 0x8200000, 0x2000, 0x202000, 0x8002000, 0x8202000, 0x20000, 0x220000, - 0x8020000, 0x8220000, 0x22000, 0x222000, 0x8022000, 0x8222000); - pc2bytes4 = new Array(0, 0x40000, 0x10, 0x40010, 0, 0x40000, 0x10, 0x40010, 0x1000, 0x41000, 0x1010, 0x41010, 0x1000, - 0x41000, 0x1010, 0x41010); - pc2bytes5 = new Array(0, 0x400, 0x20, 0x420, 0, 0x400, 0x20, 0x420, 0x2000000, 0x2000400, 0x2000020, 0x2000420, - 0x2000000, 0x2000400, 0x2000020, 0x2000420); - pc2bytes6 = new Array(0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002, 0, 0x10000000, - 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002); - pc2bytes7 = new Array(0, 0x10000, 0x800, 0x10800, 0x20000000, 0x20010000, 0x20000800, 0x20010800, 0x20000, 0x30000, - 0x20800, 0x30800, 0x20020000, 0x20030000, 0x20020800, 0x20030800); - pc2bytes8 = new Array(0, 0x40000, 0, 0x40000, 0x2, 0x40002, 0x2, 0x40002, 0x2000000, 0x2040000, 0x2000000, 0x2040000, - 0x2000002, 0x2040002, 0x2000002, 0x2040002); - pc2bytes9 = new Array(0, 0x10000000, 0x8, 0x10000008, 0, 0x10000000, 0x8, 0x10000008, 0x400, 0x10000400, 0x408, - 0x10000408, 0x400, 0x10000400, 0x408, 0x10000408); - pc2bytes10 = new Array(0, 0x20, 0, 0x20, 0x100000, 0x100020, 0x100000, 0x100020, 0x2000, 0x2020, 0x2000, 0x2020, - 0x102000, 0x102020, 0x102000, 0x102020); - pc2bytes11 = new Array(0, 0x1000000, 0x200, 0x1000200, 0x200000, 0x1200000, 0x200200, 0x1200200, 0x4000000, 0x5000000, - 0x4000200, 0x5000200, 0x4200000, 0x5200000, 0x4200200, 0x5200200); - pc2bytes12 = new Array(0, 0x1000, 0x8000000, 0x8001000, 0x80000, 0x81000, 0x8080000, 0x8081000, 0x10, 0x1010, - 0x8000010, 0x8001010, 0x80010, 0x81010, 0x8080010, 0x8081010); - pc2bytes13 = new Array(0, 0x4, 0x100, 0x104, 0, 0x4, 0x100, 0x104, 0x1, 0x5, 0x101, 0x105, 0x1, 0x5, 0x101, 0x105); - - //how many iterations (1 for des, 3 for triple des) - var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys - //stores the return keys - var keys = new Array(32 * iterations); - //now define the left shifts which need to be done - var shifts = new Array(0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0); - //other variables - var lefttemp, righttemp, m = 0, - n = 0, - temp; - - for (var j = 0; j < iterations; j++) { //either 1 or 3 iterations - left = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++); - right = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++); - - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; - right ^= temp; - left ^= (temp << 4); - temp = ((right >>> -16) ^ left) & 0x0000ffff; - left ^= temp; - right ^= (temp << -16); - temp = ((left >>> 2) ^ right) & 0x33333333; - right ^= temp; - left ^= (temp << 2); - temp = ((right >>> -16) ^ left) & 0x0000ffff; - left ^= temp; - right ^= (temp << -16); - temp = ((left >>> 1) ^ right) & 0x55555555; - right ^= temp; - left ^= (temp << 1); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; - left ^= temp; - right ^= (temp << 8); - temp = ((left >>> 1) ^ right) & 0x55555555; - right ^= temp; - left ^= (temp << 1); - - //the right side needs to be shifted and to get the last four bits of the left side - temp = (left << 8) | ((right >>> 20) & 0x000000f0); - //left needs to be put upside down - left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0); - right = temp; - - //now go through and perform these shifts on the left and right keys - for (i = 0; i < shifts.length; i++) { - //shift the keys either one or two bits to the left - if (shifts[i]) { - left = (left << 2) | (left >>> 26); - right = (right << 2) | (right >>> 26); - } else { - left = (left << 1) | (left >>> 27); - right = (right << 1) | (right >>> 27); - } - left &= -0xf; - right &= -0xf; - - //now apply PC-2, in such a way that E is easier when encrypting or decrypting - //this conversion will look like PC-2 except only the last 6 bits of each byte are used - //rather than 48 consecutive bits and the order of lines will be according to - //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7 - lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[( - left >>> 16) & 0xf] | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] | pc2bytes6[(left >>> 4) & - 0xf]; - righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] | pc2bytes9[(right >>> 20) & 0xf] | - pc2bytes10[(right >>> 16) & 0xf] | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] | - pc2bytes13[(right >>> 4) & 0xf]; - temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff; - keys[n++] = lefttemp ^ temp; - keys[n++] = righttemp ^ (temp << 16); - } - } //for each iterations - //return the keys we've created - return keys; -} //end of des_createKeys - - -function des_addPadding(message, padding) { - var padLength = 8 - (message.length % 8); - if ((padding == 2) && (padLength < 8)) { //pad the message with spaces - message += " ".substr(0, padLength); - } else if (padding == 1) { //PKCS7 padding - message += String.fromCharCode(padLength, padLength, padLength, padLength, padLength, padLength, padLength, - padLength).substr(0, padLength); - } else if (!padding && (padLength < 8)) { //pad the message out with null bytes - message += "\0\0\0\0\0\0\0\0".substr(0, padLength); - } - return message; -} - -function des_removePadding(message, padding) { - if (padding == 2) { // space padded - message = message.replace(/ *$/g, ""); - } else if (padding == 1) { // PKCS7 - var padCount = message.charCodeAt(message.length - 1); - message = message.substr(0, message.length - padCount); - } else if (!padding) { // null padding - message = message.replace(/\0*$/g, ""); - } - return message; -} - - -var util = require('../../util'); - -// added by Recurity Labs - -function Des(key) { - this.key = []; - - for (var i = 0; i < 3; i++) { - this.key.push(key.substr(i * 8, 8)); - } - - this.encrypt = function(block) { - return util.str2bin(des(des_createKeys(this.key[2]), - des(des_createKeys(this.key[1]), - des(des_createKeys(this.key[0]), - util.bin2str(block), true, 0, null, null), - false, 0, null, null), true, 0, null, null)); - } -} - -Des.keySize = Des.prototype.keySize = 24; -Des.blockSize = Des.prototype.blockSize = 8; - -// This is "original" DES - Des is actually Triple DES. -// This is only exported so we can unit test. - -function OriginalDes(key) { - this.key = key; - - this.encrypt = function(block, padding) { - var keys = des_createKeys(this.key); - return util.str2bin(des(keys, util.bin2str(block), true, 0, null, padding)); - } - - this.decrypt = function(block, padding) { - var keys = des_createKeys(this.key); - return util.str2bin(des(keys, util.bin2str(block), false, 0, null, padding)); - } -} - -module.exports = { - des: Des, - originalDes: OriginalDes -} - -},{"../../util":57}],10:[function(require,module,exports){ -var desModule = require('./des.js'); - -module.exports = { - des: desModule['des'], - originalDes: desModule['originalDes'], - cast5: require('./cast5.js'), - twofish: require('./twofish.js'), - blowfish: require('./blowfish.js') -} - -var aes = require('./aes.js'); - -for (var i in aes) { - module.exports['aes' + i] = aes[i]; -} - -},{"./aes.js":6,"./blowfish.js":7,"./cast5.js":8,"./des.js":9,"./twofish.js":11}],11:[function(require,module,exports){ -/* Modified by Recurity Labs GmbH - * - * Cipher.js - * A block-cipher algorithm implementation on JavaScript - * See Cipher.readme.txt for further information. - * - * Copyright(c) 2009 Atsushi Oka [ http://oka.nu/ ] - * This script file is distributed under the LGPL - * - * ACKNOWLEDGMENT - * - * The main subroutines are written by Michiel van Everdingen. - * - * Michiel van Everdingen - * http://home.versatel.nl/MAvanEverdingen/index.html - * - * All rights for these routines are reserved to Michiel van Everdingen. - * - */ - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//Math -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -var MAXINT = 0xFFFFFFFF; - -function rotb(b, n) { - return (b << n | b >>> (8 - n)) & 0xFF; -} - -function rotw(w, n) { - return (w << n | w >>> (32 - n)) & MAXINT; -} - -function getW(a, i) { - return a[i] | a[i + 1] << 8 | a[i + 2] << 16 | a[i + 3] << 24; -} - -function setW(a, i, w) { - a.splice(i, 4, w & 0xFF, (w >>> 8) & 0xFF, (w >>> 16) & 0xFF, (w >>> 24) & 0xFF); -} - -function setWInv(a, i, w) { - a.splice(i, 4, (w >>> 24) & 0xFF, (w >>> 16) & 0xFF, (w >>> 8) & 0xFF, w & 0xFF); -} - -function getB(x, n) { - return (x >>> (n * 8)) & 0xFF; -} - -function getNrBits(i) { - var n = 0; - while (i > 0) { - n++; - i >>>= 1; - } - return n; -} - -function getMask(n) { - return (1 << n) - 1; -} - -//added 2008/11/13 XXX MUST USE ONE-WAY HASH FUNCTION FOR SECURITY REASON - -function randByte() { - return Math.floor(Math.random() * 256); -} -// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Twofish -// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -function createTwofish() { - // - var keyBytes = null; - var dataBytes = null; - var dataOffset = -1; - // var dataLength = -1; - var algorithmName = null; - // var idx2 = -1; - // - - algorithmName = "twofish"; - - var tfsKey = []; - var tfsM = [ - [], - [], - [], - [] - ]; - - function tfsInit(key) { - keyBytes = key; - var i, a, b, c, d, meKey = [], - moKey = [], - inKey = []; - var kLen; - var sKey = []; - var f01, f5b, fef; - - var q0 = [ - [8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4], - [2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5] - ]; - var q1 = [ - [14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13], - [1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8] - ]; - var q2 = [ - [11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1], - [4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15] - ]; - var q3 = [ - [13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10], - [11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10] - ]; - var ror4 = [0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15]; - var ashx = [0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7]; - var q = [ - [], - [] - ]; - var m = [ - [], - [], - [], - [] - ]; - - function ffm5b(x) { - return x ^ (x >> 2) ^ [0, 90, 180, 238][x & 3]; - } - - function ffmEf(x) { - return x ^ (x >> 1) ^ (x >> 2) ^ [0, 238, 180, 90][x & 3]; - } - - function mdsRem(p, q) { - var i, t, u; - for (i = 0; i < 8; i++) { - t = q >>> 24; - q = ((q << 8) & MAXINT) | p >>> 24; - p = (p << 8) & MAXINT; - u = t << 1; - if (t & 128) { - u ^= 333; - } - q ^= t ^ (u << 16); - u ^= t >>> 1; - if (t & 1) { - u ^= 166; - } - q ^= u << 24 | u << 8; - } - return q; - } - - function qp(n, x) { - var a, b, c, d; - a = x >> 4; - b = x & 15; - c = q0[n][a ^ b]; - d = q1[n][ror4[b] ^ ashx[a]]; - return q3[n][ror4[d] ^ ashx[c]] << 4 | q2[n][c ^ d]; - } - - function hFun(x, key) { - var a = getB(x, 0), - b = getB(x, 1), - c = getB(x, 2), - d = getB(x, 3); - switch (kLen) { - case 4: - a = q[1][a] ^ getB(key[3], 0); - b = q[0][b] ^ getB(key[3], 1); - c = q[0][c] ^ getB(key[3], 2); - d = q[1][d] ^ getB(key[3], 3); - case 3: - a = q[1][a] ^ getB(key[2], 0); - b = q[1][b] ^ getB(key[2], 1); - c = q[0][c] ^ getB(key[2], 2); - d = q[0][d] ^ getB(key[2], 3); - case 2: - a = q[0][q[0][a] ^ getB(key[1], 0)] ^ getB(key[0], 0); - b = q[0][q[1][b] ^ getB(key[1], 1)] ^ getB(key[0], 1); - c = q[1][q[0][c] ^ getB(key[1], 2)] ^ getB(key[0], 2); - d = q[1][q[1][d] ^ getB(key[1], 3)] ^ getB(key[0], 3); - } - return m[0][a] ^ m[1][b] ^ m[2][c] ^ m[3][d]; - } - - keyBytes = keyBytes.slice(0, 32); - i = keyBytes.length; - while (i != 16 && i != 24 && i != 32) - keyBytes[i++] = 0; - - for (i = 0; i < keyBytes.length; i += 4) { - inKey[i >> 2] = getW(keyBytes, i); - } - for (i = 0; i < 256; i++) { - q[0][i] = qp(0, i); - q[1][i] = qp(1, i); - } - for (i = 0; i < 256; i++) { - f01 = q[1][i]; - f5b = ffm5b(f01); - fef = ffmEf(f01); - m[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24); - m[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24); - f01 = q[0][i]; - f5b = ffm5b(f01); - fef = ffmEf(f01); - m[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24); - m[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24); - } - - kLen = inKey.length / 2; - for (i = 0; i < kLen; i++) { - a = inKey[i + i]; - meKey[i] = a; - b = inKey[i + i + 1]; - moKey[i] = b; - sKey[kLen - i - 1] = mdsRem(a, b); - } - for (i = 0; i < 40; i += 2) { - a = 0x1010101 * i; - b = a + 0x1010101; - a = hFun(a, meKey); - b = rotw(hFun(b, moKey), 8); - tfsKey[i] = (a + b) & MAXINT; - tfsKey[i + 1] = rotw(a + 2 * b, 9); - } - for (i = 0; i < 256; i++) { - a = b = c = d = i; - switch (kLen) { - case 4: - a = q[1][a] ^ getB(sKey[3], 0); - b = q[0][b] ^ getB(sKey[3], 1); - c = q[0][c] ^ getB(sKey[3], 2); - d = q[1][d] ^ getB(sKey[3], 3); - case 3: - a = q[1][a] ^ getB(sKey[2], 0); - b = q[1][b] ^ getB(sKey[2], 1); - c = q[0][c] ^ getB(sKey[2], 2); - d = q[0][d] ^ getB(sKey[2], 3); - case 2: - tfsM[0][i] = m[0][q[0][q[0][a] ^ getB(sKey[1], 0)] ^ getB(sKey[0], 0)]; - tfsM[1][i] = m[1][q[0][q[1][b] ^ getB(sKey[1], 1)] ^ getB(sKey[0], 1)]; - tfsM[2][i] = m[2][q[1][q[0][c] ^ getB(sKey[1], 2)] ^ getB(sKey[0], 2)]; - tfsM[3][i] = m[3][q[1][q[1][d] ^ getB(sKey[1], 3)] ^ getB(sKey[0], 3)]; - } - } - } - - function tfsG0(x) { - return tfsM[0][getB(x, 0)] ^ tfsM[1][getB(x, 1)] ^ tfsM[2][getB(x, 2)] ^ tfsM[3][getB(x, 3)]; - } - - function tfsG1(x) { - return tfsM[0][getB(x, 3)] ^ tfsM[1][getB(x, 0)] ^ tfsM[2][getB(x, 1)] ^ tfsM[3][getB(x, 2)]; - } - - function tfsFrnd(r, blk) { - var a = tfsG0(blk[0]); - var b = tfsG1(blk[1]); - blk[2] = rotw(blk[2] ^ (a + b + tfsKey[4 * r + 8]) & MAXINT, 31); - blk[3] = rotw(blk[3], 1) ^ (a + 2 * b + tfsKey[4 * r + 9]) & MAXINT; - a = tfsG0(blk[2]); - b = tfsG1(blk[3]); - blk[0] = rotw(blk[0] ^ (a + b + tfsKey[4 * r + 10]) & MAXINT, 31); - blk[1] = rotw(blk[1], 1) ^ (a + 2 * b + tfsKey[4 * r + 11]) & MAXINT; - } - - function tfsIrnd(i, blk) { - var a = tfsG0(blk[0]); - var b = tfsG1(blk[1]); - blk[2] = rotw(blk[2], 1) ^ (a + b + tfsKey[4 * i + 10]) & MAXINT; - blk[3] = rotw(blk[3] ^ (a + 2 * b + tfsKey[4 * i + 11]) & MAXINT, 31); - a = tfsG0(blk[2]); - b = tfsG1(blk[3]); - blk[0] = rotw(blk[0], 1) ^ (a + b + tfsKey[4 * i + 8]) & MAXINT; - blk[1] = rotw(blk[1] ^ (a + 2 * b + tfsKey[4 * i + 9]) & MAXINT, 31); - } - - function tfsClose() { - tfsKey = []; - tfsM = [ - [], - [], - [], - [] - ]; - } - - function tfsEncrypt(data, offset) { - dataBytes = data; - dataOffset = offset; - var blk = [getW(dataBytes, dataOffset) ^ tfsKey[0], - getW(dataBytes, dataOffset + 4) ^ tfsKey[1], - getW(dataBytes, dataOffset + 8) ^ tfsKey[2], - getW(dataBytes, dataOffset + 12) ^ tfsKey[3] - ]; - for (var j = 0; j < 8; j++) { - tfsFrnd(j, blk); - } - setW(dataBytes, dataOffset, blk[2] ^ tfsKey[4]); - setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[5]); - setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[6]); - setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[7]); - dataOffset += 16; - return dataBytes; - } - - function tfsDecrypt(data, offset) { - dataBytes = data; - dataOffset = offset; - var blk = [getW(dataBytes, dataOffset) ^ tfsKey[4], - getW(dataBytes, dataOffset + 4) ^ tfsKey[5], - getW(dataBytes, dataOffset + 8) ^ tfsKey[6], - getW(dataBytes, dataOffset + 12) ^ tfsKey[7] - ]; - for (var j = 7; j >= 0; j--) { - tfsIrnd(j, blk); - } - setW(dataBytes, dataOffset, blk[2] ^ tfsKey[0]); - setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[1]); - setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[2]); - setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[3]); - dataOffset += 16; - } - - // added by Recurity Labs - - function tfsFinal() { - return dataBytes; - } - - return { - name: "twofish", - blocksize: 128 / 8, - open: tfsInit, - close: tfsClose, - encrypt: tfsEncrypt, - decrypt: tfsDecrypt, - // added by Recurity Labs - finalize: tfsFinal - }; -} - -var util = require('../../util'); - -// added by Recurity Labs - -function TFencrypt(block, key) { - var block_copy = [].concat(block); - var tf = createTwofish(); - tf.open(util.str2bin(key), 0); - var result = tf.encrypt(block_copy, 0); - tf.close(); - return result; -} - -function TF(key) { - this.tf = createTwofish(); - this.tf.open(util.str2bin(key), 0); - - this.encrypt = function(block) { - return this.tf.encrypt([].concat(block), 0); - } -} - - -module.exports = TF; -module.exports.keySize = TF.prototype.keySize = 32; -module.exports.blockSize = TF.prototype.blockSize = 16; - -},{"../../util":57}],12:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -// The GPG4Browsers crypto interface - -var random = require('./random.js'), - cipher = require('./cipher'), - publicKey = require('./public_key'), - type_mpi = require('../type/mpi.js'); - -module.exports = { - /** - * Encrypts data using the specified public key multiprecision integers - * and the specified algorithm. - * @param {Integer} algo Algorithm to be used (See RFC4880 9.1) - * @param {openpgp_type_mpi[]} publicMPIs Algorithm dependent multiprecision integers - * @param {openpgp_type_mpi} data Data to be encrypted as MPI - * @return {openpgp_type_mpi[]} if RSA an openpgp_type_mpi; - * if elgamal encryption an array of two openpgp_type_mpi is returned; otherwise null - */ - publicKeyEncrypt: function(algo, publicMPIs, data) { - var result = (function() { - switch (algo) { - case 'rsa_encrypt': - case 'rsa_encrypt_sign': - var rsa = new publicKey.rsa(); - var n = publicMPIs[0].toBigInteger(); - var e = publicMPIs[1].toBigInteger(); - var m = data.toBigInteger(); - return [rsa.encrypt(m, e, n)]; - - case 'elgamal': - var elgamal = new publicKey.elgamal(); - var p = publicMPIs[0].toBigInteger(); - var g = publicMPIs[1].toBigInteger(); - var y = publicMPIs[2].toBigInteger(); - var m = data.toBigInteger(); - return elgamal.encrypt(m, g, p, y); - - default: - return []; - } - })(); - - return result.map(function(bn) { - var mpi = new type_mpi(); - mpi.fromBigInteger(bn); - return mpi; - }); - }, - - /** - * Decrypts data using the specified public key multiprecision integers of the private key, - * the specified secretMPIs of the private key and the specified algorithm. - * @param {Integer} algo Algorithm to be used (See RFC4880 9.1) - * @param {openpgp_type_mpi[]} publicMPIs Algorithm dependent multiprecision integers - * of the public key part of the private key - * @param {openpgp_type_mpi[]} secretMPIs Algorithm dependent multiprecision integers - * of the private key used - * @param {openpgp_type_mpi} data Data to be encrypted as MPI - * @return {openpgp_type_mpi} returns a big integer containing the decrypted data; otherwise null - */ - - publicKeyDecrypt: function(algo, keyIntegers, dataIntegers) { - var bn = (function() { - switch (algo) { - case 'rsa_encrypt_sign': - case 'rsa_encrypt': - var rsa = new publicKey.rsa(); - // 0 and 1 are the public key. - var d = keyIntegers[2].toBigInteger(); - var p = keyIntegers[3].toBigInteger(); - var q = keyIntegers[4].toBigInteger(); - var u = keyIntegers[5].toBigInteger(); - var m = dataIntegers[0].toBigInteger(); - return rsa.decrypt(m, d, p, q, u); - case 'elgamal': - var elgamal = new publicKey.elgamal(); - var x = keyIntegers[3].toBigInteger(); - var c1 = dataIntegers[0].toBigInteger(); - var c2 = dataIntegers[1].toBigInteger(); - var p = keyIntegers[0].toBigInteger(); - return elgamal.decrypt(c1, c2, p, x); - default: - return null; - } - })(); - - var result = new type_mpi(); - result.fromBigInteger(bn); - return result; - }, - - /** Returns the number of integers comprising the private key of an algorithm - * @param {openpgp.publickey} algo The public key algorithm - * @return {Integer} The number of integers. - */ - getPrivateMpiCount: function(algo) { - switch (algo) { - case 'rsa_encrypt': - case 'rsa_encrypt_sign': - case 'rsa_sign': - // Algorithm-Specific Fields for RSA secret keys: - // - multiprecision integer (MPI) of RSA secret exponent d. - // - MPI of RSA secret prime value p. - // - MPI of RSA secret prime value q (p < q). - // - MPI of u, the multiplicative inverse of p, mod q. - return 4; - case 'elgamal': - // Algorithm-Specific Fields for Elgamal secret keys: - // - MPI of Elgamal secret exponent x. - return 1; - case 'dsa': - // Algorithm-Specific Fields for DSA secret keys: - // - MPI of DSA secret exponent x. - return 1; - default: - throw new Error('Unknown algorithm'); - } - }, - - getPublicMpiCount: function(algo) { - // - A series of multiprecision integers comprising the key material: - // Algorithm-Specific Fields for RSA public keys: - // - a multiprecision integer (MPI) of RSA public modulus n; - // - an MPI of RSA public encryption exponent e. - switch (algo) { - case 'rsa_encrypt': - case 'rsa_encrypt_sign': - case 'rsa_sign': - return 2; - - // Algorithm-Specific Fields for Elgamal public keys: - // - MPI of Elgamal prime p; - // - MPI of Elgamal group generator g; - // - MPI of Elgamal public key value y (= g**x mod p where x is secret). - case 'elgamal': - return 3; - - // Algorithm-Specific Fields for DSA public keys: - // - MPI of DSA prime p; - // - MPI of DSA group order q (q is a prime divisor of p-1); - // - MPI of DSA group generator g; - // - MPI of DSA public-key value y (= g**x mod p where x is secret). - case 'dsa': - return 4; - - default: - throw new Error('Unknown algorithm.'); - } - }, - - generateMpi: function(algo, bits) { - var result = (function() { - switch (algo) { - case 'rsa_encrypt': - case 'rsa_encrypt_sign': - case 'rsa_sign': - //remember "publicKey" refers to the crypto/public_key dir - var rsa = new publicKey.rsa(); - var keyObject = rsa.generate(bits, "10001"); - var output = []; - output.push(keyObject.n); - output.push(keyObject.ee); - output.push(keyObject.d); - output.push(keyObject.p); - output.push(keyObject.q); - output.push(keyObject.u); - return output; - default: - throw new Error('Unsupported algorithm for key generation.'); - } - })(); - - return result.map(function(bn) { - var mpi = new type_mpi(); - mpi.fromBigInteger(bn); - return mpi; - }); - }, - - - /** - * generate random byte prefix as string for the specified algorithm - * @param {Integer} algo Algorithm to use (see RFC4880 9.2) - * @return {String} Random bytes with length equal to the block - * size of the cipher - */ - getPrefixRandom: function(algo) { - return random.getRandomBytes(cipher[algo].blockSize); - }, - - /** - * Generating a session key for the specified symmetric algorithm - * @param {Integer} algo Algorithm to use (see RFC4880 9.2) - * @return {String} Random bytes as a string to be used as a key - */ - generateSessionKey: function(algo) { - return random.getRandomBytes(cipher[algo].keySize); - }, - -}; - -},{"../type/mpi.js":55,"./cipher":10,"./public_key":21,"./random.js":24}],13:[function(require,module,exports){ -var sha = require('./sha.js'); - -module.exports = { - md5: require('./md5.js'), - sha1: sha.sha1, - sha256: sha.sha256, - sha224: sha.sha224, - sha384: sha.sha384, - sha512: sha.sha512, - ripemd: require('./ripe-md.js'), - - /** - * Create a hash on the specified data using the specified algorithm - * @param {Integer} algo Hash algorithm type (see RFC4880 9.4) - * @param {String} data Data to be hashed - * @return {String} hash value - */ - digest: function(algo, data) { - switch (algo) { - case 1: - // - MD5 [HAC] - return this.md5(data); - case 2: - // - SHA-1 [FIPS180] - return this.sha1(data); - case 3: - // - RIPE-MD/160 [HAC] - return this.ripemd(data); - case 8: - // - SHA256 [FIPS180] - return this.sha256(data); - case 9: - // - SHA384 [FIPS180] - return this.sha384(data); - case 10: - // - SHA512 [FIPS180] - return this.sha512(data); - case 11: - // - SHA224 [FIPS180] - return this.sha224(data); - default: - throw new Error('Invalid hash function.'); - } - }, - - /** - * Returns the hash size in bytes of the specified hash algorithm type - * @param {Integer} algo Hash algorithm type (See RFC4880 9.4) - * @return {Integer} Size in bytes of the resulting hash - */ - getHashByteLength: function(algo) { - switch (algo) { - case 1: - // - MD5 [HAC] - return 16; - case 2: - // - SHA-1 [FIPS180] - case 3: - // - RIPE-MD/160 [HAC] - return 20; - case 8: - // - SHA256 [FIPS180] - return 32; - case 9: - // - SHA384 [FIPS180] - return 48 - case 10: - // - SHA512 [FIPS180] - return 64; - case 11: - // - SHA224 [FIPS180] - return 28; - default: - throw new Error('Invalid hash algorithm.'); - } - } - -} - -},{"./md5.js":14,"./ripe-md.js":15,"./sha.js":16}],14:[function(require,module,exports){ -/** - * A fast MD5 JavaScript implementation - * Copyright (c) 2012 Joseph Myers - * http://www.myersdaily.org/joseph/javascript/md5-text.html - * - * Permission to use, copy, modify, and distribute this software - * and its documentation for any purposes and without - * fee is hereby granted provided that this copyright notice - * appears in all copies. - * - * Of course, this soft is provided "as is" without express or implied - * warranty of any kind. - */ - -var util = require('../../util/util.js'); - -function MD5(entree) { - var hex = md5(entree); - var bin = util.hex2bin(hex); - return bin; -} - -function md5cycle(x, k) { - var a = x[0], - b = x[1], - c = x[2], - d = x[3]; - - a = ff(a, b, c, d, k[0], 7, -680876936); - d = ff(d, a, b, c, k[1], 12, -389564586); - c = ff(c, d, a, b, k[2], 17, 606105819); - b = ff(b, c, d, a, k[3], 22, -1044525330); - a = ff(a, b, c, d, k[4], 7, -176418897); - d = ff(d, a, b, c, k[5], 12, 1200080426); - c = ff(c, d, a, b, k[6], 17, -1473231341); - b = ff(b, c, d, a, k[7], 22, -45705983); - a = ff(a, b, c, d, k[8], 7, 1770035416); - d = ff(d, a, b, c, k[9], 12, -1958414417); - c = ff(c, d, a, b, k[10], 17, -42063); - b = ff(b, c, d, a, k[11], 22, -1990404162); - a = ff(a, b, c, d, k[12], 7, 1804603682); - d = ff(d, a, b, c, k[13], 12, -40341101); - c = ff(c, d, a, b, k[14], 17, -1502002290); - b = ff(b, c, d, a, k[15], 22, 1236535329); - - a = gg(a, b, c, d, k[1], 5, -165796510); - d = gg(d, a, b, c, k[6], 9, -1069501632); - c = gg(c, d, a, b, k[11], 14, 643717713); - b = gg(b, c, d, a, k[0], 20, -373897302); - a = gg(a, b, c, d, k[5], 5, -701558691); - d = gg(d, a, b, c, k[10], 9, 38016083); - c = gg(c, d, a, b, k[15], 14, -660478335); - b = gg(b, c, d, a, k[4], 20, -405537848); - a = gg(a, b, c, d, k[9], 5, 568446438); - d = gg(d, a, b, c, k[14], 9, -1019803690); - c = gg(c, d, a, b, k[3], 14, -187363961); - b = gg(b, c, d, a, k[8], 20, 1163531501); - a = gg(a, b, c, d, k[13], 5, -1444681467); - d = gg(d, a, b, c, k[2], 9, -51403784); - c = gg(c, d, a, b, k[7], 14, 1735328473); - b = gg(b, c, d, a, k[12], 20, -1926607734); - - a = hh(a, b, c, d, k[5], 4, -378558); - d = hh(d, a, b, c, k[8], 11, -2022574463); - c = hh(c, d, a, b, k[11], 16, 1839030562); - b = hh(b, c, d, a, k[14], 23, -35309556); - a = hh(a, b, c, d, k[1], 4, -1530992060); - d = hh(d, a, b, c, k[4], 11, 1272893353); - c = hh(c, d, a, b, k[7], 16, -155497632); - b = hh(b, c, d, a, k[10], 23, -1094730640); - a = hh(a, b, c, d, k[13], 4, 681279174); - d = hh(d, a, b, c, k[0], 11, -358537222); - c = hh(c, d, a, b, k[3], 16, -722521979); - b = hh(b, c, d, a, k[6], 23, 76029189); - a = hh(a, b, c, d, k[9], 4, -640364487); - d = hh(d, a, b, c, k[12], 11, -421815835); - c = hh(c, d, a, b, k[15], 16, 530742520); - b = hh(b, c, d, a, k[2], 23, -995338651); - - a = ii(a, b, c, d, k[0], 6, -198630844); - d = ii(d, a, b, c, k[7], 10, 1126891415); - c = ii(c, d, a, b, k[14], 15, -1416354905); - b = ii(b, c, d, a, k[5], 21, -57434055); - a = ii(a, b, c, d, k[12], 6, 1700485571); - d = ii(d, a, b, c, k[3], 10, -1894986606); - c = ii(c, d, a, b, k[10], 15, -1051523); - b = ii(b, c, d, a, k[1], 21, -2054922799); - a = ii(a, b, c, d, k[8], 6, 1873313359); - d = ii(d, a, b, c, k[15], 10, -30611744); - c = ii(c, d, a, b, k[6], 15, -1560198380); - b = ii(b, c, d, a, k[13], 21, 1309151649); - a = ii(a, b, c, d, k[4], 6, -145523070); - d = ii(d, a, b, c, k[11], 10, -1120210379); - c = ii(c, d, a, b, k[2], 15, 718787259); - b = ii(b, c, d, a, k[9], 21, -343485551); - - x[0] = add32(a, x[0]); - x[1] = add32(b, x[1]); - x[2] = add32(c, x[2]); - x[3] = add32(d, x[3]); - -} - -function cmn(q, a, b, x, s, t) { - a = add32(add32(a, q), add32(x, t)); - return add32((a << s) | (a >>> (32 - s)), b); -} - -function ff(a, b, c, d, x, s, t) { - return cmn((b & c) | ((~b) & d), a, b, x, s, t); -} - -function gg(a, b, c, d, x, s, t) { - return cmn((b & d) | (c & (~d)), a, b, x, s, t); -} - -function hh(a, b, c, d, x, s, t) { - return cmn(b ^ c ^ d, a, b, x, s, t); -} - -function ii(a, b, c, d, x, s, t) { - return cmn(c ^ (b | (~d)), a, b, x, s, t); -} - -function md51(s) { - txt = ''; - var n = s.length, - state = [1732584193, -271733879, -1732584194, 271733878], - i; - for (i = 64; i <= s.length; i += 64) { - md5cycle(state, md5blk(s.substring(i - 64, i))); - } - s = s.substring(i - 64); - var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - for (i = 0; i < s.length; i++) - tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3); - tail[i >> 2] |= 0x80 << ((i % 4) << 3); - if (i > 55) { - md5cycle(state, tail); - for (i = 0; i < 16; i++) tail[i] = 0; - } - tail[14] = n * 8; - md5cycle(state, tail); - return state; -} - -/* there needs to be support for Unicode here, - * unless we pretend that we can redefine the MD-5 - * algorithm for multi-byte characters (perhaps - * by adding every four 16-bit characters and - * shortening the sum to 32 bits). Otherwise - * I suggest performing MD-5 as if every character - * was two bytes--e.g., 0040 0025 = @%--but then - * how will an ordinary MD-5 sum be matched? - * There is no way to standardize text to something - * like UTF-8 before transformation; speed cost is - * utterly prohibitive. The JavaScript standard - * itself needs to look at this: it should start - * providing access to strings as preformed UTF-8 - * 8-bit unsigned value arrays. - */ -function md5blk(s) { /* I figured global was faster. */ - var md5blks = [], - i; /* Andy King said do it this way. */ - for (i = 0; i < 64; i += 4) { - md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << - 24); - } - return md5blks; -} - -var hex_chr = '0123456789abcdef'.split(''); - -function rhex(n) { - var s = '', - j = 0; - for (; j < 4; j++) - s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F]; - return s; -} - -function hex(x) { - for (var i = 0; i < x.length; i++) - x[i] = rhex(x[i]); - return x.join(''); -} - -function md5(s) { - return hex(md51(s)); -} - -/* this function is much faster, -so if possible we use it. Some IEs -are the only ones I know of that -need the idiotic second function, -generated by an if clause. */ - -function add32(a, b) { - return (a + b) & 0xFFFFFFFF; -} - -if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') { - function add32(x, y) { - var lsw = (x & 0xFFFF) + (y & 0xFFFF), - msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); - } -} - -module.exports = MD5 - -},{"../../util/util.js":57}],15:[function(require,module,exports){ -/* - * CryptoMX Tools - * Copyright (C) 2004 - 2006 Derek Buitenhuis - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Modified by Recurity Labs GmbH - */ - -var RMDsize = 160; -var X = new Array(); - -function ROL(x, n) { - return new Number((x << n) | (x >>> (32 - n))); -} - -function F(x, y, z) { - return new Number(x ^ y ^ z); -} - -function G(x, y, z) { - return new Number((x & y) | (~x & z)); -} - -function H(x, y, z) { - return new Number((x | ~y) ^ z); -} - -function I(x, y, z) { - return new Number((x & z) | (y & ~z)); -} - -function J(x, y, z) { - return new Number(x ^ (y | ~z)); -} - -function mixOneRound(a, b, c, d, e, x, s, roundNumber) { - switch (roundNumber) { - case 0: - a += F(b, c, d) + x + 0x00000000; - break; - case 1: - a += G(b, c, d) + x + 0x5a827999; - break; - case 2: - a += H(b, c, d) + x + 0x6ed9eba1; - break; - case 3: - a += I(b, c, d) + x + 0x8f1bbcdc; - break; - case 4: - a += J(b, c, d) + x + 0xa953fd4e; - break; - case 5: - a += J(b, c, d) + x + 0x50a28be6; - break; - case 6: - a += I(b, c, d) + x + 0x5c4dd124; - break; - case 7: - a += H(b, c, d) + x + 0x6d703ef3; - break; - case 8: - a += G(b, c, d) + x + 0x7a6d76e9; - break; - case 9: - a += F(b, c, d) + x + 0x00000000; - break; - - default: - document.write("Bogus round number"); - break; - } - - a = ROL(a, s) + e; - c = ROL(c, 10); - - a &= 0xffffffff; - b &= 0xffffffff; - c &= 0xffffffff; - d &= 0xffffffff; - e &= 0xffffffff; - - var retBlock = new Array(); - retBlock[0] = a; - retBlock[1] = b; - retBlock[2] = c; - retBlock[3] = d; - retBlock[4] = e; - retBlock[5] = x; - retBlock[6] = s; - - return retBlock; -} - -function MDinit(MDbuf) { - MDbuf[0] = 0x67452301; - MDbuf[1] = 0xefcdab89; - MDbuf[2] = 0x98badcfe; - MDbuf[3] = 0x10325476; - MDbuf[4] = 0xc3d2e1f0; -} - -var ROLs = [ - [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8], - [7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12], - [11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5], - [11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12], - [9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6], - [8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6], - [9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11], - [9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5], - [15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8], - [8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11] -]; - -var indexes = [ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], - [7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8], - [3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12], - [1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2], - [4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13], - [5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12], - [6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2], - [15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13], - [8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14], - [12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11] -]; - -function compress(MDbuf, X) { - blockA = new Array(); - blockB = new Array(); - - var retBlock; - - for (var i = 0; i < 5; i++) { - blockA[i] = new Number(MDbuf[i]); - blockB[i] = new Number(MDbuf[i]); - } - - var step = 0; - for (var j = 0; j < 5; j++) { - for (var i = 0; i < 16; i++) { - retBlock = mixOneRound( - blockA[(step + 0) % 5], - blockA[(step + 1) % 5], - blockA[(step + 2) % 5], - blockA[(step + 3) % 5], - blockA[(step + 4) % 5], - X[indexes[j][i]], - ROLs[j][i], - j); - - blockA[(step + 0) % 5] = retBlock[0]; - blockA[(step + 1) % 5] = retBlock[1]; - blockA[(step + 2) % 5] = retBlock[2]; - blockA[(step + 3) % 5] = retBlock[3]; - blockA[(step + 4) % 5] = retBlock[4]; - - step += 4; - } - } - - step = 0; - for (var j = 5; j < 10; j++) { - for (var i = 0; i < 16; i++) { - retBlock = mixOneRound( - blockB[(step + 0) % 5], - blockB[(step + 1) % 5], - blockB[(step + 2) % 5], - blockB[(step + 3) % 5], - blockB[(step + 4) % 5], - X[indexes[j][i]], - ROLs[j][i], - j); - - blockB[(step + 0) % 5] = retBlock[0]; - blockB[(step + 1) % 5] = retBlock[1]; - blockB[(step + 2) % 5] = retBlock[2]; - blockB[(step + 3) % 5] = retBlock[3]; - blockB[(step + 4) % 5] = retBlock[4]; - - step += 4; - } - } - - blockB[3] += blockA[2] + MDbuf[1]; - MDbuf[1] = MDbuf[2] + blockA[3] + blockB[4]; - MDbuf[2] = MDbuf[3] + blockA[4] + blockB[0]; - MDbuf[3] = MDbuf[4] + blockA[0] + blockB[1]; - MDbuf[4] = MDbuf[0] + blockA[1] + blockB[2]; - MDbuf[0] = blockB[3]; -} - -function zeroX(X) { - for (var i = 0; i < 16; i++) { - X[i] = 0; - } -} - -function MDfinish(MDbuf, strptr, lswlen, mswlen) { - var X = new Array(16); - zeroX(X); - - var j = 0; - for (var i = 0; i < (lswlen & 63); i++) { - X[i >>> 2] ^= (strptr.charCodeAt(j++) & 255) << (8 * (i & 3)); - } - - X[(lswlen >>> 2) & 15] ^= 1 << (8 * (lswlen & 3) + 7); - - if ((lswlen & 63) > 55) { - compress(MDbuf, X); - var X = new Array(16); - zeroX(X); - } - - X[14] = lswlen << 3; - X[15] = (lswlen >>> 29) | (mswlen << 3); - - compress(MDbuf, X); -} - -function BYTES_TO_DWORD(fourChars) { - var tmp = (fourChars.charCodeAt(3) & 255) << 24; - tmp |= (fourChars.charCodeAt(2) & 255) << 16; - tmp |= (fourChars.charCodeAt(1) & 255) << 8; - tmp |= (fourChars.charCodeAt(0) & 255); - - return tmp; -} - -function RMD(message) { - var MDbuf = new Array(RMDsize / 32); - var hashcode = new Array(RMDsize / 8); - var length; - var nbytes; - - MDinit(MDbuf); - length = message.length; - - var X = new Array(16); - zeroX(X); - - var j = 0; - for (var nbytes = length; nbytes > 63; nbytes -= 64) { - for (var i = 0; i < 16; i++) { - X[i] = BYTES_TO_DWORD(message.substr(j, 4)); - j += 4; - } - compress(MDbuf, X); - } - - MDfinish(MDbuf, message.substr(j), length, 0); - - for (var i = 0; i < RMDsize / 8; i += 4) { - hashcode[i] = MDbuf[i >>> 2] & 255; - hashcode[i + 1] = (MDbuf[i >>> 2] >>> 8) & 255; - hashcode[i + 2] = (MDbuf[i >>> 2] >>> 16) & 255; - hashcode[i + 3] = (MDbuf[i >>> 2] >>> 24) & 255; - } - - return hashcode; -} - - -function RMDstring(message) { - var hashcode = RMD(message); - var retString = ""; - - for (var i = 0; i < RMDsize / 8; i++) { - retString += String.fromCharCode(hashcode[i]); - } - - return retString; -} - -module.exports = RMDstring; - -},{}],16:[function(require,module,exports){ -/* A JavaScript implementation of the SHA family of hashes, as defined in FIPS - * PUB 180-2 as well as the corresponding HMAC implementation as defined in - * FIPS PUB 198a - * - * Version 1.3 Copyright Brian Turek 2008-2010 - * Distributed under the BSD License - * See http://jssha.sourceforge.net/ for more information - * - * Several functions taken from Paul Johnson - */ - -/* Modified by Recurity Labs GmbH - * - * This code has been slightly modified direct string output: - * - bin2bstr has been added - * - following wrappers of this library have been added: - * - str_sha1 - * - str_sha256 - * - str_sha224 - * - str_sha384 - * - str_sha512 - */ - -var jsSHA = (function() { - - /* - * Configurable variables. Defaults typically work - */ - /* Number of Bits Per character (8 for ASCII, 16 for Unicode) */ - var charSize = 8, - /* base-64 pad character. "=" for strict RFC compliance */ - b64pad = "", - /* hex output format. 0 - lowercase; 1 - uppercase */ - hexCase = 0, - - /* - * Int_64 is a object for 2 32-bit numbers emulating a 64-bit number - * - * @constructor - * @param {Number} msint_32 The most significant 32-bits of a 64-bit number - * @param {Number} lsint_32 The least significant 32-bits of a 64-bit number - */ - Int_64 = function(msint_32, lsint_32) { - this.highOrder = msint_32; - this.lowOrder = lsint_32; - }, - - /* - * Convert a string to an array of big-endian words - * If charSize is ASCII, characters >255 have their hi-byte silently - * ignored. - * - * @param {String} str String to be converted to binary representation - * @return Integer array representation of the parameter - */ - str2binb = function(str) { - var bin = [], - mask = (1 << charSize) - 1, - length = str.length * charSize, - i; - - for (i = 0; i < length; i += charSize) { - bin[i >> 5] |= (str.charCodeAt(i / charSize) & mask) << - (32 - charSize - (i % 32)); - } - - return bin; - }, - - /* - * Convert a hex string to an array of big-endian words - * - * @param {String} str String to be converted to binary representation - * @return Integer array representation of the parameter - */ - hex2binb = function(str) { - var bin = [], - length = str.length, - i, num; - - for (i = 0; i < length; i += 2) { - num = parseInt(str.substr(i, 2), 16); - if (!isNaN(num)) { - bin[i >> 3] |= num << (24 - (4 * (i % 8))); - } else { - return "INVALID HEX STRING"; - } - } - - return bin; - }, - - /* - * Convert an array of big-endian words to a hex string. - * - * @private - * @param {Array} binarray Array of integers to be converted to hexidecimal - * representation - * @return Hexidecimal representation of the parameter in String form - */ - binb2hex = function(binarray) { - var hex_tab = (hexCase) ? "0123456789ABCDEF" : "0123456789abcdef", - str = "", - length = binarray.length * 4, - i, srcByte; - - for (i = 0; i < length; i += 1) { - srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8); - str += hex_tab.charAt((srcByte >> 4) & 0xF) + - hex_tab.charAt(srcByte & 0xF); - } - - return str; - }, - - /* - * Convert an array of big-endian words to a base-64 string - * - * @private - * @param {Array} binarray Array of integers to be converted to base-64 - * representation - * @return Base-64 encoded representation of the parameter in String form - */ - binb2b64 = function(binarray) { - var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + - "0123456789+/", - str = "", - length = binarray.length * 4, - i, j, - triplet; - - for (i = 0; i < length; i += 3) { - triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) | - (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) | - ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF); - for (j = 0; j < 4; j += 1) { - if (i * 8 + j * 6 <= binarray.length * 32) { - str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F); - } else { - str += b64pad; - } - } - } - return str; - }, - - /* - * Convert an array of big-endian words to a string - */ - binb2str = function(bin) { - var str = ""; - var mask = (1 << 8) - 1; - for (var i = 0; i < bin.length * 32; i += 8) - str += String.fromCharCode((bin[i >> 5] >>> (24 - i % 32)) & mask); - return str; - }, - /* - * The 32-bit implementation of circular rotate left - * - * @private - * @param {Number} x The 32-bit integer argument - * @param {Number} n The number of bits to shift - * @return The x shifted circularly by n bits - */ - rotl_32 = function(x, n) { - return (x << n) | (x >>> (32 - n)); - }, - - /* - * The 32-bit implementation of circular rotate right - * - * @private - * @param {Number} x The 32-bit integer argument - * @param {Number} n The number of bits to shift - * @return The x shifted circularly by n bits - */ - rotr_32 = function(x, n) { - return (x >>> n) | (x << (32 - n)); - }, - - /* - * The 64-bit implementation of circular rotate right - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @param {Number} n The number of bits to shift - * @return The x shifted circularly by n bits - */ - rotr_64 = function(x, n) { - if (n <= 32) { - return new Int_64( - (x.highOrder >>> n) | (x.lowOrder << (32 - n)), (x.lowOrder >>> n) | (x.highOrder << (32 - n))); - } else { - return new Int_64( - (x.lowOrder >>> n) | (x.highOrder << (32 - n)), (x.highOrder >>> n) | (x.lowOrder << (32 - n))); - } - }, - - /* - * The 32-bit implementation of shift right - * - * @private - * @param {Number} x The 32-bit integer argument - * @param {Number} n The number of bits to shift - * @return The x shifted by n bits - */ - shr_32 = function(x, n) { - return x >>> n; - }, - - /* - * The 64-bit implementation of shift right - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @param {Number} n The number of bits to shift - * @return The x shifted by n bits - */ - shr_64 = function(x, n) { - if (n <= 32) { - return new Int_64( - x.highOrder >>> n, - x.lowOrder >>> n | (x.highOrder << (32 - n))); - } else { - return new Int_64( - 0, - x.highOrder << (32 - n)); - } - }, - - /* - * The 32-bit implementation of the NIST specified Parity function - * - * @private - * @param {Number} x The first 32-bit integer argument - * @param {Number} y The second 32-bit integer argument - * @param {Number} z The third 32-bit integer argument - * @return The NIST specified output of the function - */ - parity_32 = function(x, y, z) { - return x ^ y ^ z; - }, - - /* - * The 32-bit implementation of the NIST specified Ch function - * - * @private - * @param {Number} x The first 32-bit integer argument - * @param {Number} y The second 32-bit integer argument - * @param {Number} z The third 32-bit integer argument - * @return The NIST specified output of the function - */ - ch_32 = function(x, y, z) { - return (x & y) ^ (~x & z); - }, - - /* - * The 64-bit implementation of the NIST specified Ch function - * - * @private - * @param {Int_64} x The first 64-bit integer argument - * @param {Int_64} y The second 64-bit integer argument - * @param {Int_64} z The third 64-bit integer argument - * @return The NIST specified output of the function - */ - ch_64 = function(x, y, z) { - return new Int_64( - (x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder), (x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder)); - }, - - /* - * The 32-bit implementation of the NIST specified Maj function - * - * @private - * @param {Number} x The first 32-bit integer argument - * @param {Number} y The second 32-bit integer argument - * @param {Number} z The third 32-bit integer argument - * @return The NIST specified output of the function - */ - maj_32 = function(x, y, z) { - return (x & y) ^ (x & z) ^ (y & z); - }, - - /* - * The 64-bit implementation of the NIST specified Maj function - * - * @private - * @param {Int_64} x The first 64-bit integer argument - * @param {Int_64} y The second 64-bit integer argument - * @param {Int_64} z The third 64-bit integer argument - * @return The NIST specified output of the function - */ - maj_64 = function(x, y, z) { - return new Int_64( - (x.highOrder & y.highOrder) ^ - (x.highOrder & z.highOrder) ^ - (y.highOrder & z.highOrder), (x.lowOrder & y.lowOrder) ^ - (x.lowOrder & z.lowOrder) ^ - (y.lowOrder & z.lowOrder)); - }, - - /* - * The 32-bit implementation of the NIST specified Sigma0 function - * - * @private - * @param {Number} x The 32-bit integer argument - * @return The NIST specified output of the function - */ - sigma0_32 = function(x) { - return rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22); - }, - - /* - * The 64-bit implementation of the NIST specified Sigma0 function - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @return The NIST specified output of the function - */ - sigma0_64 = function(x) { - var rotr28 = rotr_64(x, 28), - rotr34 = rotr_64(x, 34), - rotr39 = rotr_64(x, 39); - - return new Int_64( - rotr28.highOrder ^ rotr34.highOrder ^ rotr39.highOrder, - rotr28.lowOrder ^ rotr34.lowOrder ^ rotr39.lowOrder); - }, - - /* - * The 32-bit implementation of the NIST specified Sigma1 function - * - * @private - * @param {Number} x The 32-bit integer argument - * @return The NIST specified output of the function - */ - sigma1_32 = function(x) { - return rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25); - }, - - /* - * The 64-bit implementation of the NIST specified Sigma1 function - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @return The NIST specified output of the function - */ - sigma1_64 = function(x) { - var rotr14 = rotr_64(x, 14), - rotr18 = rotr_64(x, 18), - rotr41 = rotr_64(x, 41); - - return new Int_64( - rotr14.highOrder ^ rotr18.highOrder ^ rotr41.highOrder, - rotr14.lowOrder ^ rotr18.lowOrder ^ rotr41.lowOrder); - }, - - /* - * The 32-bit implementation of the NIST specified Gamma0 function - * - * @private - * @param {Number} x The 32-bit integer argument - * @return The NIST specified output of the function - */ - gamma0_32 = function(x) { - return rotr_32(x, 7) ^ rotr_32(x, 18) ^ shr_32(x, 3); - }, - - /* - * The 64-bit implementation of the NIST specified Gamma0 function - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @return The NIST specified output of the function - */ - gamma0_64 = function(x) { - var rotr1 = rotr_64(x, 1), - rotr8 = rotr_64(x, 8), - shr7 = shr_64(x, 7); - - return new Int_64( - rotr1.highOrder ^ rotr8.highOrder ^ shr7.highOrder, - rotr1.lowOrder ^ rotr8.lowOrder ^ shr7.lowOrder); - }, - - /* - * The 32-bit implementation of the NIST specified Gamma1 function - * - * @private - * @param {Number} x The 32-bit integer argument - * @return The NIST specified output of the function - */ - gamma1_32 = function(x) { - return rotr_32(x, 17) ^ rotr_32(x, 19) ^ shr_32(x, 10); - }, - - /* - * The 64-bit implementation of the NIST specified Gamma1 function - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @return The NIST specified output of the function - */ - gamma1_64 = function(x) { - var rotr19 = rotr_64(x, 19), - rotr61 = rotr_64(x, 61), - shr6 = shr_64(x, 6); - - return new Int_64( - rotr19.highOrder ^ rotr61.highOrder ^ shr6.highOrder, - rotr19.lowOrder ^ rotr61.lowOrder ^ shr6.lowOrder); - }, - - /* - * Add two 32-bit integers, wrapping at 2^32. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Number} x The first 32-bit integer argument to be added - * @param {Number} y The second 32-bit integer argument to be added - * @return The sum of x + y - */ - safeAdd_32_2 = function(x, y) { - var lsw = (x & 0xFFFF) + (y & 0xFFFF), - msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16); - - return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - }, - - /* - * Add four 32-bit integers, wrapping at 2^32. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Number} a The first 32-bit integer argument to be added - * @param {Number} b The second 32-bit integer argument to be added - * @param {Number} c The third 32-bit integer argument to be added - * @param {Number} d The fourth 32-bit integer argument to be added - * @return The sum of a + b + c + d - */ - safeAdd_32_4 = function(a, b, c, d) { - var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF), - msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + - (lsw >>> 16); - - return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - }, - - /* - * Add five 32-bit integers, wrapping at 2^32. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Number} a The first 32-bit integer argument to be added - * @param {Number} b The second 32-bit integer argument to be added - * @param {Number} c The third 32-bit integer argument to be added - * @param {Number} d The fourth 32-bit integer argument to be added - * @param {Number} e The fifth 32-bit integer argument to be added - * @return The sum of a + b + c + d + e - */ - safeAdd_32_5 = function(a, b, c, d, e) { - var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF) + - (e & 0xFFFF), - msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + - (e >>> 16) + (lsw >>> 16); - - return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - }, - - /* - * Add two 64-bit integers, wrapping at 2^64. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Int_64} x The first 64-bit integer argument to be added - * @param {Int_64} y The second 64-bit integer argument to be added - * @return The sum of x + y - */ - safeAdd_64_2 = function(x, y) { - var lsw, msw, lowOrder, highOrder; - - lsw = (x.lowOrder & 0xFFFF) + (y.lowOrder & 0xFFFF); - msw = (x.lowOrder >>> 16) + (y.lowOrder >>> 16) + (lsw >>> 16); - lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - - lsw = (x.highOrder & 0xFFFF) + (y.highOrder & 0xFFFF) + (msw >>> 16); - msw = (x.highOrder >>> 16) + (y.highOrder >>> 16) + (lsw >>> 16); - highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - - return new Int_64(highOrder, lowOrder); - }, - - /* - * Add four 64-bit integers, wrapping at 2^64. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Int_64} a The first 64-bit integer argument to be added - * @param {Int_64} b The second 64-bit integer argument to be added - * @param {Int_64} c The third 64-bit integer argument to be added - * @param {Int_64} d The fouth 64-bit integer argument to be added - * @return The sum of a + b + c + d - */ - safeAdd_64_4 = function(a, b, c, d) { - var lsw, msw, lowOrder, highOrder; - - lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + - (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF); - msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + - (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (lsw >>> 16); - lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - - lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + - (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + (msw >>> 16); - msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + - (c.highOrder >>> 16) + (d.highOrder >>> 16) + (lsw >>> 16); - highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - - return new Int_64(highOrder, lowOrder); - }, - - /* - * Add five 64-bit integers, wrapping at 2^64. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Int_64} a The first 64-bit integer argument to be added - * @param {Int_64} b The second 64-bit integer argument to be added - * @param {Int_64} c The third 64-bit integer argument to be added - * @param {Int_64} d The fouth 64-bit integer argument to be added - * @param {Int_64} e The fouth 64-bit integer argument to be added - * @return The sum of a + b + c + d + e - */ - safeAdd_64_5 = function(a, b, c, d, e) { - var lsw, msw, lowOrder, highOrder; - - lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + - (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF) + - (e.lowOrder & 0xFFFF); - msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + - (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (e.lowOrder >>> 16) + - (lsw >>> 16); - lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - - lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + - (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + - (e.highOrder & 0xFFFF) + (msw >>> 16); - msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + - (c.highOrder >>> 16) + (d.highOrder >>> 16) + - (e.highOrder >>> 16) + (lsw >>> 16); - highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - - return new Int_64(highOrder, lowOrder); - }, - - /* - * Calculates the SHA-1 hash of the string set at instantiation - * - * @private - * @param {Array} message The binary array representation of the string to - * hash - * @param {Number} messageLen The number of bits in the message - * @return The array of integers representing the SHA-1 hash of message - */ - coreSHA1 = function(message, messageLen) { - var W = [], - a, b, c, d, e, T, ch = ch_32, - parity = parity_32, - maj = maj_32, - rotl = rotl_32, - safeAdd_2 = safeAdd_32_2, - i, t, - safeAdd_5 = safeAdd_32_5, - appendedMessageLength, - H = [ - 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 - ], - K = [ - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6 - ]; - - /* Append '1' at the end of the binary string */ - message[messageLen >> 5] |= 0x80 << (24 - (messageLen % 32)); - /* Append length of binary string in the position such that the new - length is a multiple of 512. Logic does not work for even multiples - of 512 but there can never be even multiples of 512 */ - message[(((messageLen + 65) >> 9) << 4) + 15] = messageLen; - - appendedMessageLength = message.length; - - for (i = 0; i < appendedMessageLength; i += 16) { - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - - for (t = 0; t < 80; t += 1) { - if (t < 16) { - W[t] = message[t + i]; - } else { - W[t] = rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); - } - - if (t < 20) { - T = safeAdd_5(rotl(a, 5), ch(b, c, d), e, K[t], W[t]); - } else if (t < 40) { - T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]); - } else if (t < 60) { - T = safeAdd_5(rotl(a, 5), maj(b, c, d), e, K[t], W[t]); - } else { - T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]); - } - - e = d; - d = c; - c = rotl(b, 30); - b = a; - a = T; - } - - H[0] = safeAdd_2(a, H[0]); - H[1] = safeAdd_2(b, H[1]); - H[2] = safeAdd_2(c, H[2]); - H[3] = safeAdd_2(d, H[3]); - H[4] = safeAdd_2(e, H[4]); - } - - return H; - }, - - /* - * Calculates the desired SHA-2 hash of the string set at instantiation - * - * @private - * @param {Array} The binary array representation of the string to hash - * @param {Number} The number of bits in message - * @param {String} variant The desired SHA-2 variant - * @return The array of integers representing the SHA-2 hash of message - */ - coreSHA2 = function(message, messageLen, variant) { - var a, b, c, d, e, f, g, h, T1, T2, H, numRounds, lengthPosition, i, t, - binaryStringInc, binaryStringMult, safeAdd_2, safeAdd_4, safeAdd_5, - gamma0, gamma1, sigma0, sigma1, ch, maj, Int, K, W = [], - appendedMessageLength; - - /* Set up the various function handles and variable for the specific - * variant */ - if (variant === "SHA-224" || variant === "SHA-256") { - /* 32-bit variant */ - numRounds = 64; - lengthPosition = (((messageLen + 65) >> 9) << 4) + 15; - binaryStringInc = 16; - binaryStringMult = 1; - Int = Number; - safeAdd_2 = safeAdd_32_2; - safeAdd_4 = safeAdd_32_4; - safeAdd_5 = safeAdd_32_5; - gamma0 = gamma0_32; - gamma1 = gamma1_32; - sigma0 = sigma0_32; - sigma1 = sigma1_32; - maj = maj_32; - ch = ch_32; - K = [ - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, - 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, - 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, - 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, - 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, - 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, - 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, - 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 - ]; - - if (variant === "SHA-224") { - H = [ - 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, - 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 - ]; - } else { - H = [ - 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, - 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 - ]; - } - } else if (variant === "SHA-384" || variant === "SHA-512") { - /* 64-bit variant */ - numRounds = 80; - lengthPosition = (((messageLen + 128) >> 10) << 5) + 31; - binaryStringInc = 32; - binaryStringMult = 2; - Int = Int_64; - safeAdd_2 = safeAdd_64_2; - safeAdd_4 = safeAdd_64_4; - safeAdd_5 = safeAdd_64_5; - gamma0 = gamma0_64; - gamma1 = gamma1_64; - sigma0 = sigma0_64; - sigma1 = sigma1_64; - maj = maj_64; - ch = ch_64; - - K = [ - new Int(0x428a2f98, 0xd728ae22), new Int(0x71374491, 0x23ef65cd), - new Int(0xb5c0fbcf, 0xec4d3b2f), new Int(0xe9b5dba5, 0x8189dbbc), - new Int(0x3956c25b, 0xf348b538), new Int(0x59f111f1, 0xb605d019), - new Int(0x923f82a4, 0xaf194f9b), new Int(0xab1c5ed5, 0xda6d8118), - new Int(0xd807aa98, 0xa3030242), new Int(0x12835b01, 0x45706fbe), - new Int(0x243185be, 0x4ee4b28c), new Int(0x550c7dc3, 0xd5ffb4e2), - new Int(0x72be5d74, 0xf27b896f), new Int(0x80deb1fe, 0x3b1696b1), - new Int(0x9bdc06a7, 0x25c71235), new Int(0xc19bf174, 0xcf692694), - new Int(0xe49b69c1, 0x9ef14ad2), new Int(0xefbe4786, 0x384f25e3), - new Int(0x0fc19dc6, 0x8b8cd5b5), new Int(0x240ca1cc, 0x77ac9c65), - new Int(0x2de92c6f, 0x592b0275), new Int(0x4a7484aa, 0x6ea6e483), - new Int(0x5cb0a9dc, 0xbd41fbd4), new Int(0x76f988da, 0x831153b5), - new Int(0x983e5152, 0xee66dfab), new Int(0xa831c66d, 0x2db43210), - new Int(0xb00327c8, 0x98fb213f), new Int(0xbf597fc7, 0xbeef0ee4), - new Int(0xc6e00bf3, 0x3da88fc2), new Int(0xd5a79147, 0x930aa725), - new Int(0x06ca6351, 0xe003826f), new Int(0x14292967, 0x0a0e6e70), - new Int(0x27b70a85, 0x46d22ffc), new Int(0x2e1b2138, 0x5c26c926), - new Int(0x4d2c6dfc, 0x5ac42aed), new Int(0x53380d13, 0x9d95b3df), - new Int(0x650a7354, 0x8baf63de), new Int(0x766a0abb, 0x3c77b2a8), - new Int(0x81c2c92e, 0x47edaee6), new Int(0x92722c85, 0x1482353b), - new Int(0xa2bfe8a1, 0x4cf10364), new Int(0xa81a664b, 0xbc423001), - new Int(0xc24b8b70, 0xd0f89791), new Int(0xc76c51a3, 0x0654be30), - new Int(0xd192e819, 0xd6ef5218), new Int(0xd6990624, 0x5565a910), - new Int(0xf40e3585, 0x5771202a), new Int(0x106aa070, 0x32bbd1b8), - new Int(0x19a4c116, 0xb8d2d0c8), new Int(0x1e376c08, 0x5141ab53), - new Int(0x2748774c, 0xdf8eeb99), new Int(0x34b0bcb5, 0xe19b48a8), - new Int(0x391c0cb3, 0xc5c95a63), new Int(0x4ed8aa4a, 0xe3418acb), - new Int(0x5b9cca4f, 0x7763e373), new Int(0x682e6ff3, 0xd6b2b8a3), - new Int(0x748f82ee, 0x5defb2fc), new Int(0x78a5636f, 0x43172f60), - new Int(0x84c87814, 0xa1f0ab72), new Int(0x8cc70208, 0x1a6439ec), - new Int(0x90befffa, 0x23631e28), new Int(0xa4506ceb, 0xde82bde9), - new Int(0xbef9a3f7, 0xb2c67915), new Int(0xc67178f2, 0xe372532b), - new Int(0xca273ece, 0xea26619c), new Int(0xd186b8c7, 0x21c0c207), - new Int(0xeada7dd6, 0xcde0eb1e), new Int(0xf57d4f7f, 0xee6ed178), - new Int(0x06f067aa, 0x72176fba), new Int(0x0a637dc5, 0xa2c898a6), - new Int(0x113f9804, 0xbef90dae), new Int(0x1b710b35, 0x131c471b), - new Int(0x28db77f5, 0x23047d84), new Int(0x32caab7b, 0x40c72493), - new Int(0x3c9ebe0a, 0x15c9bebc), new Int(0x431d67c4, 0x9c100d4c), - new Int(0x4cc5d4be, 0xcb3e42b6), new Int(0x597f299c, 0xfc657e2a), - new Int(0x5fcb6fab, 0x3ad6faec), new Int(0x6c44198c, 0x4a475817) - ]; - - if (variant === "SHA-384") { - H = [ - new Int(0xcbbb9d5d, 0xc1059ed8), new Int(0x0629a292a, 0x367cd507), - new Int(0x9159015a, 0x3070dd17), new Int(0x0152fecd8, 0xf70e5939), - new Int(0x67332667, 0xffc00b31), new Int(0x98eb44a87, 0x68581511), - new Int(0xdb0c2e0d, 0x64f98fa7), new Int(0x047b5481d, 0xbefa4fa4) - ]; - } else { - H = [ - new Int(0x6a09e667, 0xf3bcc908), new Int(0xbb67ae85, 0x84caa73b), - new Int(0x3c6ef372, 0xfe94f82b), new Int(0xa54ff53a, 0x5f1d36f1), - new Int(0x510e527f, 0xade682d1), new Int(0x9b05688c, 0x2b3e6c1f), - new Int(0x1f83d9ab, 0xfb41bd6b), new Int(0x5be0cd19, 0x137e2179) - ]; - } - } - - /* Append '1' at the end of the binary string */ - message[messageLen >> 5] |= 0x80 << (24 - messageLen % 32); - /* Append length of binary string in the position such that the new - * length is correct */ - message[lengthPosition] = messageLen; - - appendedMessageLength = message.length; - - for (i = 0; i < appendedMessageLength; i += binaryStringInc) { - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - f = H[5]; - g = H[6]; - h = H[7]; - - for (t = 0; t < numRounds; t += 1) { - if (t < 16) { - /* Bit of a hack - for 32-bit, the second term is ignored */ - W[t] = new Int(message[t * binaryStringMult + i], - message[t * binaryStringMult + i + 1]); - } else { - W[t] = safeAdd_4( - gamma1(W[t - 2]), W[t - 7], - gamma0(W[t - 15]), W[t - 16]); - } - - T1 = safeAdd_5(h, sigma1(e), ch(e, f, g), K[t], W[t]); - T2 = safeAdd_2(sigma0(a), maj(a, b, c)); - h = g; - g = f; - f = e; - e = safeAdd_2(d, T1); - d = c; - c = b; - b = a; - a = safeAdd_2(T1, T2); - } - - H[0] = safeAdd_2(a, H[0]); - H[1] = safeAdd_2(b, H[1]); - H[2] = safeAdd_2(c, H[2]); - H[3] = safeAdd_2(d, H[3]); - H[4] = safeAdd_2(e, H[4]); - H[5] = safeAdd_2(f, H[5]); - H[6] = safeAdd_2(g, H[6]); - H[7] = safeAdd_2(h, H[7]); - } - - switch (variant) { - case "SHA-224": - return [ - H[0], H[1], H[2], H[3], - H[4], H[5], H[6]]; - case "SHA-256": - return H; - case "SHA-384": - return [ - H[0].highOrder, H[0].lowOrder, - H[1].highOrder, H[1].lowOrder, - H[2].highOrder, H[2].lowOrder, - H[3].highOrder, H[3].lowOrder, - H[4].highOrder, H[4].lowOrder, - H[5].highOrder, H[5].lowOrder]; - case "SHA-512": - return [ - H[0].highOrder, H[0].lowOrder, - H[1].highOrder, H[1].lowOrder, - H[2].highOrder, H[2].lowOrder, - H[3].highOrder, H[3].lowOrder, - H[4].highOrder, H[4].lowOrder, - H[5].highOrder, H[5].lowOrder, - H[6].highOrder, H[6].lowOrder, - H[7].highOrder, H[7].lowOrder]; - default: - /* This should never be reached */ - return []; - } - }, - - /* - * jsSHA is the workhorse of the library. Instantiate it with the string to - * be hashed as the parameter - * - * @constructor - * @param {String} srcString The string to be hashed - * @param {String} inputFormat The format of srcString, ASCII or HEX - */ - jsSHA = function(srcString, inputFormat) { - - this.sha1 = null; - this.sha224 = null; - this.sha256 = null; - this.sha384 = null; - this.sha512 = null; - - this.strBinLen = null; - this.strToHash = null; - - /* Convert the input string into the correct type */ - if ("HEX" === inputFormat) { - if (0 !== (srcString.length % 2)) { - return "TEXT MUST BE IN BYTE INCREMENTS"; - } - this.strBinLen = srcString.length * 4; - this.strToHash = hex2binb(srcString); - } else if (("ASCII" === inputFormat) || - ('undefined' === typeof(inputFormat))) { - this.strBinLen = srcString.length * charSize; - this.strToHash = str2binb(srcString); - } else { - return "UNKNOWN TEXT INPUT TYPE"; - } - }; - - jsSHA.prototype = { - /* - * Returns the desired SHA hash of the string specified at instantiation - * using the specified parameters - * - * @param {String} variant The desired SHA variant (SHA-1, SHA-224, - * SHA-256, SHA-384, or SHA-512) - * @param {String} format The desired output formatting (B64 or HEX) - * @return The string representation of the hash in the format specified - */ - getHash: function(variant, format) { - var formatFunc = null, - message = this.strToHash.slice(); - - switch (format) { - case "HEX": - formatFunc = binb2hex; - break; - case "B64": - formatFunc = binb2b64; - break; - case "ASCII": - formatFunc = binb2str; - break; - default: - return "FORMAT NOT RECOGNIZED"; - } - - switch (variant) { - case "SHA-1": - if (null === this.sha1) { - this.sha1 = coreSHA1(message, this.strBinLen); - } - return formatFunc(this.sha1); - case "SHA-224": - if (null === this.sha224) { - this.sha224 = coreSHA2(message, this.strBinLen, variant); - } - return formatFunc(this.sha224); - case "SHA-256": - if (null === this.sha256) { - this.sha256 = coreSHA2(message, this.strBinLen, variant); - } - return formatFunc(this.sha256); - case "SHA-384": - if (null === this.sha384) { - this.sha384 = coreSHA2(message, this.strBinLen, variant); - } - return formatFunc(this.sha384); - case "SHA-512": - if (null === this.sha512) { - this.sha512 = coreSHA2(message, this.strBinLen, variant); - } - return formatFunc(this.sha512); - default: - return "HASH NOT RECOGNIZED"; - } - }, - - /* - * Returns the desired HMAC of the string specified at instantiation - * using the key and variant param. - * - * @param {String} key The key used to calculate the HMAC - * @param {String} inputFormat The format of key, ASCII or HEX - * @param {String} variant The desired SHA variant (SHA-1, SHA-224, - * SHA-256, SHA-384, or SHA-512) - * @param {String} outputFormat The desired output formatting - * (B64 or HEX) - * @return The string representation of the hash in the format specified - */ - getHMAC: function(key, inputFormat, variant, outputFormat) { - var formatFunc, keyToUse, blockByteSize, blockBitSize, i, - retVal, lastArrayIndex, keyBinLen, hashBitSize, - keyWithIPad = [], - keyWithOPad = []; - - /* Validate the output format selection */ - switch (outputFormat) { - case "HEX": - formatFunc = binb2hex; - break; - case "B64": - formatFunc = binb2b64; - break; - case "ASCII": - formatFunc = binb2str; - break; - default: - return "FORMAT NOT RECOGNIZED"; - } - - /* Validate the hash variant selection and set needed variables */ - switch (variant) { - case "SHA-1": - blockByteSize = 64; - hashBitSize = 160; - break; - case "SHA-224": - blockByteSize = 64; - hashBitSize = 224; - break; - case "SHA-256": - blockByteSize = 64; - hashBitSize = 256; - break; - case "SHA-384": - blockByteSize = 128; - hashBitSize = 384; - break; - case "SHA-512": - blockByteSize = 128; - hashBitSize = 512; - break; - default: - return "HASH NOT RECOGNIZED"; - } - - /* Validate input format selection */ - if ("HEX" === inputFormat) { - /* Nibbles must come in pairs */ - if (0 !== (key.length % 2)) { - return "KEY MUST BE IN BYTE INCREMENTS"; - } - keyToUse = hex2binb(key); - keyBinLen = key.length * 4; - } else if ("ASCII" === inputFormat) { - keyToUse = str2binb(key); - keyBinLen = key.length * charSize; - } else { - return "UNKNOWN KEY INPUT TYPE"; - } - - /* These are used multiple times, calculate and store them */ - blockBitSize = blockByteSize * 8; - lastArrayIndex = (blockByteSize / 4) - 1; - - /* Figure out what to do with the key based on its size relative to - * the hash's block size */ - if (blockByteSize < (keyBinLen / 8)) { - if ("SHA-1" === variant) { - keyToUse = coreSHA1(keyToUse, keyBinLen); - } else { - keyToUse = coreSHA2(keyToUse, keyBinLen, variant); - } - /* For all variants, the block size is bigger than the output - * size so there will never be a useful byte at the end of the - * string */ - keyToUse[lastArrayIndex] &= 0xFFFFFF00; - } else if (blockByteSize > (keyBinLen / 8)) { - /* If the blockByteSize is greater than the key length, there - * will always be at LEAST one "useless" byte at the end of the - * string */ - keyToUse[lastArrayIndex] &= 0xFFFFFF00; - } - - /* Create ipad and opad */ - for (i = 0; i <= lastArrayIndex; i += 1) { - keyWithIPad[i] = keyToUse[i] ^ 0x36363636; - keyWithOPad[i] = keyToUse[i] ^ 0x5C5C5C5C; - } - - /* Calculate the HMAC */ - if ("SHA-1" === variant) { - retVal = coreSHA1( - keyWithIPad.concat(this.strToHash), - blockBitSize + this.strBinLen); - retVal = coreSHA1( - keyWithOPad.concat(retVal), - blockBitSize + hashBitSize); - } else { - retVal = coreSHA2( - keyWithIPad.concat(this.strToHash), - blockBitSize + this.strBinLen, variant); - retVal = coreSHA2( - keyWithOPad.concat(retVal), - blockBitSize + hashBitSize, variant); - } - - return (formatFunc(retVal)); - } - }; - - return jsSHA; -}()); - -module.exports = { - sha1: function(str) { - var shaObj = new jsSHA(str, "ASCII"); - return shaObj.getHash("SHA-1", "ASCII"); - }, - sha224: function(str) { - var shaObj = new jsSHA(str, "ASCII"); - return shaObj.getHash("SHA-224", "ASCII"); - }, - sha256: function(str) { - var shaObj = new jsSHA(str, "ASCII"); - return shaObj.getHash("SHA-256", "ASCII"); - }, - sha384: function(str) { - var shaObj = new jsSHA(str, "ASCII"); - return shaObj.getHash("SHA-384", "ASCII"); - - }, - sha512: function(str) { - var shaObj = new jsSHA(str, "ASCII"); - return shaObj.getHash("SHA-512", "ASCII"); - } -} - -},{}],17:[function(require,module,exports){ -module.exports = { - cipher: require('./cipher'), - hash: require('./hash'), - cfb: require('./cfb.js'), - publicKey: require('./public_key'), - signature: require('./signature.js'), - random: require('./random.js'), - pkcs1: require('./pkcs1.js') - -} - -var crypto = require('./crypto.js'); - -for (var i in crypto) - module.exports[i] = crypto[i]; - -},{"./cfb.js":5,"./cipher":10,"./crypto.js":12,"./hash":13,"./pkcs1.js":18,"./public_key":21,"./random.js":24,"./signature.js":25}],18:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * ASN1 object identifiers for hashes (See RFC4880 5.2.2) - */ -hash_headers = new Array(); -hash_headers[1] = [0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, - 0x10 -]; -hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14]; -hash_headers[2] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14]; -hash_headers[8] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, - 0x04, 0x20 -]; -hash_headers[9] = [0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, - 0x04, 0x30 -]; -hash_headers[10] = [0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, - 0x00, 0x04, 0x40 -]; -hash_headers[11] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, - 0x00, 0x04, 0x1C -]; - - -var crypto = require('./crypto.js'), - random = require('./random.js'), - util = require('../util'), - BigInteger = require('./public_key/jsbn.js'), - hash = require('./hash'); - -module.exports = { - eme: { - /** - * create a EME-PKCS1-v1_5 padding (See RFC4880 13.1.1) - * @param {String} message message to be padded - * @param {Integer} length Length to the resulting message - * @return {String} EME-PKCS1 padded message - */ - encode: function(message, length) { - if (message.length > length - 11) - return -1; - var result = ""; - result += String.fromCharCode(0); - result += String.fromCharCode(2); - for (var i = 0; i < length - message.length - 3; i++) { - result += String.fromCharCode(random.getPseudoRandom(1, 255)); - } - result += String.fromCharCode(0); - result += message; - return result; - }, - - /** - * decodes a EME-PKCS1-v1_5 padding (See RFC4880 13.1.2) - * @param {String} message EME-PKCS1 padded message - * @return {String} decoded message - */ - decode: function(message, len) { - if (message.length < len) - message = String.fromCharCode(0) + message; - if (message.length < 12 || message.charCodeAt(0) != 0 || message.charCodeAt(1) != 2) - return -1; - var i = 2; - while (message.charCodeAt(i) != 0 && message.length > i) - i++; - return message.substring(i + 1, message.length); - }, - }, - - emsa: { - - /** - * create a EMSA-PKCS1-v1_5 padding (See RFC4880 13.1.3) - * @param {Integer} algo Hash algorithm type used - * @param {String} data Data to be hashed - * @param {Integer} keylength Key size of the public mpi in bytes - * @returns {String} Hashcode with pkcs1padding as string - */ - encode: function(algo, data, keylength) { - var data2 = ""; - data2 += String.fromCharCode(0x00); - data2 += String.fromCharCode(0x01); - for (var i = 0; i < (keylength - hash_headers[algo].length - 3 - - hash.getHashByteLength(algo)); i++) - - data2 += String.fromCharCode(0xff); - - data2 += String.fromCharCode(0x00); - - for (var i = 0; i < hash_headers[algo].length; i++) - data2 += String.fromCharCode(hash_headers[algo][i]); - - data2 += hash.digest(algo, data); - return new BigInteger(util.hexstrdump(data2), 16); - }, - - /** - * extract the hash out of an EMSA-PKCS1-v1.5 padding (See RFC4880 13.1.3) - * @param {String} data Hash in pkcs1 encoding - * @returns {String} The hash as string - */ - decode: function(algo, data) { - var i = 0; - if (data.charCodeAt(0) == 0) i++; - else if (data.charCodeAt(0) != 1) return -1; - else i++; - - while (data.charCodeAt(i) == 0xFF) i++; - if (data.charCodeAt(i++) != 0) return -1; - var j = 0; - for (j = 0; j < hash_headers[algo].length && j + i < data.length; j++) { - if (data.charCodeAt(j + i) != hash_headers[algo][j]) return -1; - } - i += j; - if (data.substring(i).length < hash.getHashByteLength(algo)) return -1; - return data.substring(i); - } - } -} - -},{"../util":57,"./crypto.js":12,"./hash":13,"./public_key/jsbn.js":22,"./random.js":24}],19:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// -// A Digital signature algorithm implementation - -var BigInteger = require('./jsbn.js'), - random = require('../random.js'), - hashModule = require('../hash'), - util = require('../../util'); - -function DSA() { - // s1 = ((g**s) mod p) mod q - // s1 = ((s**-1)*(sha-1(m)+(s1*x) mod q) - function sign(hashalgo, m, g, p, q, x) { - // If the output size of the chosen hash is larger than the number of - // bits of q, the hash result is truncated to fit by taking the number - // of leftmost bits equal to the number of bits of q. This (possibly - // truncated) hash function result is treated as a number and used - // directly in the DSA signature algorithm. - var hashed_data = util.getLeftNBits(hashModule.digest(hashalgo, m), q.bitLength()); - var hash = new BigInteger(util.hexstrdump(hashed_data), 16); - var k = random.getRandomBigIntegerInRange(BigInteger.ONE.add(BigInteger.ONE), q.subtract(BigInteger.ONE)); - var s1 = (g.modPow(k, p)).mod(q); - var s2 = (k.modInverse(q).multiply(hash.add(x.multiply(s1)))).mod(q); - var result = new Array(); - result[0] = s1.toMPI(); - result[1] = s2.toMPI(); - return result; - } - - function select_hash_algorithm(q) { - var usersetting = openpgp.config.config.prefer_hash_algorithm; - /* - * 1024-bit key, 160-bit q, SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512 hash - * 2048-bit key, 224-bit q, SHA-224, SHA-256, SHA-384, or SHA-512 hash - * 2048-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash - * 3072-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash - */ - switch (Math.round(q.bitLength() / 8)) { - case 20: - // 1024 bit - if (usersetting != 2 && - usersetting > 11 && - usersetting != 10 && - usersetting < 8) - return 2; // prefer sha1 - return usersetting; - case 28: - // 2048 bit - if (usersetting > 11 && - usersetting < 8) - return 11; - return usersetting; - case 32: - // 4096 bit // prefer sha224 - if (usersetting > 10 && - usersetting < 8) - return 8; // prefer sha256 - return usersetting; - default: - util.print_debug("DSA select hash algorithm: returning null for an unknown length of q"); - return null; - - } - } - this.select_hash_algorithm = select_hash_algorithm; - - function verify(hashalgo, s1, s2, m, p, q, g, y) { - var hashed_data = util.getLeftNBits(hashModule.digest(hashalgo, m), q.bitLength()); - var hash = new BigInteger(util.hexstrdump(hashed_data), 16); - if (BigInteger.ZERO.compareTo(s1) > 0 || - s1.compareTo(q) > 0 || - BigInteger.ZERO.compareTo(s2) > 0 || - s2.compareTo(q) > 0) { - util.print_error("invalid DSA Signature"); - return null; - } - var w = s2.modInverse(q); - var u1 = hash.multiply(w).mod(q); - var u2 = s1.multiply(w).mod(q); - return g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q); - } - - /* - * unused code. This can be used as a start to write a key generator - * function. - - function generateKey(bitcount) { - var qi = new BigInteger(bitcount, primeCenterie); - var pi = generateP(q, 512); - var gi = generateG(p, q, bitcount); - var xi; - do { - xi = new BigInteger(q.bitCount(), rand); - } while (x.compareTo(BigInteger.ZERO) != 1 && x.compareTo(q) != -1); - var yi = g.modPow(x, p); - return {x: xi, q: qi, p: pi, g: gi, y: yi}; - } - - function generateP(q, bitlength, randomfn) { - if (bitlength % 64 != 0) { - return false; - } - var pTemp; - var pTemp2; - do { - pTemp = randomfn(bitcount, true); - pTemp2 = pTemp.subtract(BigInteger.ONE); - pTemp = pTemp.subtract(pTemp2.remainder(q)); - } while (!pTemp.isProbablePrime(primeCenterie) || pTemp.bitLength() != l); - return pTemp; - } - - function generateG(p, q, bitlength, randomfn) { - var aux = p.subtract(BigInteger.ONE); - var pow = aux.divide(q); - var gTemp; - do { - gTemp = randomfn(bitlength); - } while (gTemp.compareTo(aux) != -1 && gTemp.compareTo(BigInteger.ONE) != 1); - return gTemp.modPow(pow, p); - } - - function generateK(q, bitlength, randomfn) { - var tempK; - do { - tempK = randomfn(bitlength, false); - } while (tempK.compareTo(q) != -1 && tempK.compareTo(BigInteger.ZERO) != 1); - return tempK; - } - - function generateR(q,p) { - k = generateK(q); - var r = g.modPow(k, p).mod(q); - return r; - } - - function generateS(hashfn,k,r,m,q,x) { - var hash = hashfn(m); - s = (k.modInverse(q).multiply(hash.add(x.multiply(r)))).mod(q); - return s; - } */ - this.sign = sign; - this.verify = verify; - // this.generate = generateKey; -} - -module.exports = DSA; - -},{"../../util":57,"../hash":13,"../random.js":24,"./jsbn.js":22}],20:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// -// ElGamal implementation - -var BigInteger = require('./jsbn.js'), - random = require('../random.js'), - util = require('../../util'); - -function Elgamal() { - - function encrypt(m, g, p, y) { - // choose k in {2,...,p-2} - var two = BigInteger.ONE.add(BigInteger.ONE); - var pMinus2 = p.subtract(two); - var k = random.getRandomBigIntegerInRange(two, pMinus2); - k = k.mod(pMinus2).add(BigInteger.ONE); - var c = []; - c[0] = g.modPow(k, p); - c[1] = y.modPow(k, p).multiply(m).mod(p); - return c; - } - - function decrypt(c1, c2, p, x) { - util.print_debug("Elgamal Decrypt:\nc1:" + util.hexstrdump(c1.toMPI()) + "\n" + - "c2:" + util.hexstrdump(c2.toMPI()) + "\n" + - "p:" + util.hexstrdump(p.toMPI()) + "\n" + - "x:" + util.hexstrdump(x.toMPI())); - return (c1.modPow(x, p).modInverse(p)).multiply(c2).mod(p); - //var c = c1.pow(x).modInverse(p); // c0^-a mod p - //return c.multiply(c2).mod(p); - } - - // signing and signature verification using Elgamal is not required by OpenPGP. - this.encrypt = encrypt; - this.decrypt = decrypt; -} - -module.exports = Elgamal; - -},{"../../util":57,"../random.js":24,"./jsbn.js":22}],21:[function(require,module,exports){ -module.exports = { - rsa: require('./rsa.js'), - elgamal: require('./elgamal.js'), - dsa: require('./dsa.js') -} - -},{"./dsa.js":19,"./elgamal.js":20,"./rsa.js":23}],22:[function(require,module,exports){ -/* - * Copyright (c) 2003-2005 Tom Wu (tjw@cs.Stanford.EDU) - * All Rights Reserved. - * - * Modified by Recurity Labs GmbH - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF - * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * In addition, the following condition applies: - * - * All redistributions must retain an intact copy of this copyright notice - * and disclaimer. - */ - - -var util = require('../../util'); - -// Basic JavaScript BN library - subset useful for RSA encryption. - -// Bits per digit -var dbits; - -// JavaScript engine analysis -var canary = 0xdeadbeefcafe; -var j_lm = ((canary & 0xffffff) == 0xefcafe); - -// (public) Constructor - -function BigInteger(a, b, c) { - if (a != null) - if ("number" == typeof a) this.fromNumber(a, b, c); - else if (b == null && "string" != typeof a) this.fromString(a, 256); - else this.fromString(a, b); -} - -// return new, unset BigInteger - -function nbi() { - return new BigInteger(null); -} - -// am: Compute w_j += (x*this_i), propagate carries, -// c is initial carry, returns final carry. -// c < 3*dvalue, x < 2*dvalue, this_i < dvalue -// We need to select the fastest one that works in this environment. - -// am1: use a single mult and divide to get the high bits, -// max digit bits should be 26 because -// max internal value = 2*dvalue^2-2*dvalue (< 2^53) - -function am1(i, x, w, j, c, n) { - while (--n >= 0) { - var v = x * this[i++] + w[j] + c; - c = Math.floor(v / 0x4000000); - w[j++] = v & 0x3ffffff; - } - return c; -} -// am2 avoids a big mult-and-extract completely. -// Max digit bits should be <= 30 because we do bitwise ops -// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) - -function am2(i, x, w, j, c, n) { - var xl = x & 0x7fff, - xh = x >> 15; - while (--n >= 0) { - var l = this[i] & 0x7fff; - var h = this[i++] >> 15; - var m = xh * l + h * xl; - l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); - c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); - w[j++] = l & 0x3fffffff; - } - return c; -} -// Alternately, set max digit bits to 28 since some -// browsers slow down when dealing with 32-bit numbers. - -function am3(i, x, w, j, c, n) { - var xl = x & 0x3fff, - xh = x >> 14; - while (--n >= 0) { - var l = this[i] & 0x3fff; - var h = this[i++] >> 14; - var m = xh * l + h * xl; - l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; - c = (l >> 28) + (m >> 14) + xh * h; - w[j++] = l & 0xfffffff; - } - return c; -} -/*if(j_lm && (navigator != undefined && - navigator.appName == "Microsoft Internet Explorer")) { - BigInteger.prototype.am = am2; - dbits = 30; -} -else if(j_lm && (navigator != undefined && navigator.appName != "Netscape")) {*/ -BigInteger.prototype.am = am1; -dbits = 26; -/*} -else { // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; -}*/ - -BigInteger.prototype.DB = dbits; -BigInteger.prototype.DM = ((1 << dbits) - 1); -BigInteger.prototype.DV = (1 << dbits); - -var BI_FP = 52; -BigInteger.prototype.FV = Math.pow(2, BI_FP); -BigInteger.prototype.F1 = BI_FP - dbits; -BigInteger.prototype.F2 = 2 * dbits - BI_FP; - -// Digit conversions -var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; -var BI_RC = new Array(); -var rr, vv; -rr = "0".charCodeAt(0); -for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; -rr = "a".charCodeAt(0); -for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; -rr = "A".charCodeAt(0); -for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; - -function int2char(n) { - return BI_RM.charAt(n); -} - -function intAt(s, i) { - var c = BI_RC[s.charCodeAt(i)]; - return (c == null) ? -1 : c; -} - -// (protected) copy this to r - -function bnpCopyTo(r) { - for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; - r.t = this.t; - r.s = this.s; -} - -// (protected) set from integer value x, -DV <= x < DV - -function bnpFromInt(x) { - this.t = 1; - this.s = (x < 0) ? -1 : 0; - if (x > 0) this[0] = x; - else if (x < -1) this[0] = x + DV; - else this.t = 0; -} - -// return bigint initialized to value - -function nbv(i) { - var r = nbi(); - r.fromInt(i); - return r; -} - -// (protected) set from string and radix - -function bnpFromString(s, b) { - var k; - if (b == 16) k = 4; - else if (b == 8) k = 3; - else if (b == 256) k = 8; // byte array - else if (b == 2) k = 1; - else if (b == 32) k = 5; - else if (b == 4) k = 2; - else { - this.fromRadix(s, b); - return; - } - this.t = 0; - this.s = 0; - var i = s.length, - mi = false, - sh = 0; - while (--i >= 0) { - var x = (k == 8) ? s[i] & 0xff : intAt(s, i); - if (x < 0) { - if (s.charAt(i) == "-") mi = true; - continue; - } - mi = false; - if (sh == 0) - this[this.t++] = x; - else if (sh + k > this.DB) { - this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; - this[this.t++] = (x >> (this.DB - sh)); - } else - this[this.t - 1] |= x << sh; - sh += k; - if (sh >= this.DB) sh -= this.DB; - } - if (k == 8 && (s[0] & 0x80) != 0) { - this.s = -1; - if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; - } - this.clamp(); - if (mi) BigInteger.ZERO.subTo(this, this); -} - -// (protected) clamp off excess high words - -function bnpClamp() { - var c = this.s & this.DM; - while (this.t > 0 && this[this.t - 1] == c)--this.t; -} - -// (public) return string representation in given radix - -function bnToString(b) { - if (this.s < 0) return "-" + this.negate().toString(b); - var k; - if (b == 16) k = 4; - else if (b == 8) k = 3; - else if (b == 2) k = 1; - else if (b == 32) k = 5; - else if (b == 4) k = 2; - else return this.toRadix(b); - var km = (1 << k) - 1, - d, m = false, - r = "", - i = this.t; - var p = this.DB - (i * this.DB) % k; - if (i-- > 0) { - if (p < this.DB && (d = this[i] >> p) > 0) { - m = true; - r = int2char(d); - } - while (i >= 0) { - if (p < k) { - d = (this[i] & ((1 << p) - 1)) << (k - p); - d |= this[--i] >> (p += this.DB - k); - } else { - d = (this[i] >> (p -= k)) & km; - if (p <= 0) { - p += this.DB; - --i; - } - } - if (d > 0) m = true; - if (m) r += int2char(d); - } - } - return m ? r : "0"; -} - -// (public) -this - -function bnNegate() { - var r = nbi(); - BigInteger.ZERO.subTo(this, r); - return r; -} - -// (public) |this| - -function bnAbs() { - return (this.s < 0) ? this.negate() : this; -} - -// (public) return + if this > a, - if this < a, 0 if equal - -function bnCompareTo(a) { - var r = this.s - a.s; - if (r != 0) return r; - var i = this.t; - r = i - a.t; - if (r != 0) return r; - while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r; - return 0; -} - -// returns bit length of the integer x - -function nbits(x) { - var r = 1, - t; - if ((t = x >>> 16) != 0) { - x = t; - r += 16; - } - if ((t = x >> 8) != 0) { - x = t; - r += 8; - } - if ((t = x >> 4) != 0) { - x = t; - r += 4; - } - if ((t = x >> 2) != 0) { - x = t; - r += 2; - } - if ((t = x >> 1) != 0) { - x = t; - r += 1; - } - return r; -} - -// (public) return the number of bits in "this" - -function bnBitLength() { - if (this.t <= 0) return 0; - return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)); -} - -// (protected) r = this << n*DB - -function bnpDLShiftTo(n, r) { - var i; - for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; - for (i = n - 1; i >= 0; --i) r[i] = 0; - r.t = this.t + n; - r.s = this.s; -} - -// (protected) r = this >> n*DB - -function bnpDRShiftTo(n, r) { - for (var i = n; i < this.t; ++i) r[i - n] = this[i]; - r.t = Math.max(this.t - n, 0); - r.s = this.s; -} - -// (protected) r = this << n - -function bnpLShiftTo(n, r) { - var bs = n % this.DB; - var cbs = this.DB - bs; - var bm = (1 << cbs) - 1; - var ds = Math.floor(n / this.DB), - c = (this.s << bs) & this.DM, - i; - for (i = this.t - 1; i >= 0; --i) { - r[i + ds + 1] = (this[i] >> cbs) | c; - c = (this[i] & bm) << bs; - } - for (i = ds - 1; i >= 0; --i) r[i] = 0; - r[ds] = c; - r.t = this.t + ds + 1; - r.s = this.s; - r.clamp(); -} - -// (protected) r = this >> n - -function bnpRShiftTo(n, r) { - r.s = this.s; - var ds = Math.floor(n / this.DB); - if (ds >= this.t) { - r.t = 0; - return; - } - var bs = n % this.DB; - var cbs = this.DB - bs; - var bm = (1 << bs) - 1; - r[0] = this[ds] >> bs; - for (var i = ds + 1; i < this.t; ++i) { - r[i - ds - 1] |= (this[i] & bm) << cbs; - r[i - ds] = this[i] >> bs; - } - if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; - r.t = this.t - ds; - r.clamp(); -} - -// (protected) r = this - a - -function bnpSubTo(a, r) { - var i = 0, - c = 0, - m = Math.min(a.t, this.t); - while (i < m) { - c += this[i] - a[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - if (a.t < this.t) { - c -= a.s; - while (i < this.t) { - c += this[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c += this.s; - } else { - c += this.s; - while (i < a.t) { - c -= a[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = (c < 0) ? -1 : 0; - if (c < -1) r[i++] = this.DV + c; - else if (c > 0) r[i++] = c; - r.t = i; - r.clamp(); -} - -// (protected) r = this * a, r != this,a (HAC 14.12) -// "this" should be the larger one if appropriate. - -function bnpMultiplyTo(a, r) { - var x = this.abs(), - y = a.abs(); - var i = x.t; - r.t = i + y.t; - while (--i >= 0) r[i] = 0; - for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); - r.s = 0; - r.clamp(); - if (this.s != a.s) BigInteger.ZERO.subTo(r, r); -} - -// (protected) r = this^2, r != this (HAC 14.16) - -function bnpSquareTo(r) { - var x = this.abs(); - var i = r.t = 2 * x.t; - while (--i >= 0) r[i] = 0; - for (i = 0; i < x.t - 1; ++i) { - var c = x.am(i, x[i], r, 2 * i, 0, 1); - if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { - r[i + x.t] -= x.DV; - r[i + x.t + 1] = 1; - } - } - if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); - r.s = 0; - r.clamp(); -} - -// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) -// r != q, this != m. q or r may be null. - -function bnpDivRemTo(m, q, r) { - var pm = m.abs(); - if (pm.t <= 0) return; - var pt = this.abs(); - if (pt.t < pm.t) { - if (q != null) q.fromInt(0); - if (r != null) this.copyTo(r); - return; - } - if (r == null) r = nbi(); - var y = nbi(), - ts = this.s, - ms = m.s; - var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus - if (nsh > 0) { - pm.lShiftTo(nsh, y); - pt.lShiftTo(nsh, r); - } else { - pm.copyTo(y); - pt.copyTo(r); - } - var ys = y.t; - var y0 = y[ys - 1]; - if (y0 == 0) return; - var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0); - var d1 = this.FV / yt, - d2 = (1 << this.F1) / yt, - e = 1 << this.F2; - var i = r.t, - j = i - ys, - t = (q == null) ? nbi() : q; - y.dlShiftTo(j, t); - if (r.compareTo(t) >= 0) { - r[r.t++] = 1; - r.subTo(t, r); - } - BigInteger.ONE.dlShiftTo(ys, t); - t.subTo(y, y); // "negative" y so we can replace sub with am later - while (y.t < ys) y[y.t++] = 0; - while (--j >= 0) { - // Estimate quotient digit - var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); - if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out - y.dlShiftTo(j, t); - r.subTo(t, r); - while (r[i] < --qd) r.subTo(t, r); - } - } - if (q != null) { - r.drShiftTo(ys, q); - if (ts != ms) BigInteger.ZERO.subTo(q, q); - } - r.t = ys; - r.clamp(); - if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder - if (ts < 0) BigInteger.ZERO.subTo(r, r); -} - -// (public) this mod a - -function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a, null, r); - if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); - return r; -} - -// Modular reduction using "classic" algorithm - -function Classic(m) { - this.m = m; -} - -function cConvert(x) { - if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; -} - -function cRevert(x) { - return x; -} - -function cReduce(x) { - x.divRemTo(this.m, null, x); -} - -function cMulTo(x, y, r) { - x.multiplyTo(y, r); - this.reduce(r); -} - -function cSqrTo(x, r) { - x.squareTo(r); - this.reduce(r); -} - -Classic.prototype.convert = cConvert; -Classic.prototype.revert = cRevert; -Classic.prototype.reduce = cReduce; -Classic.prototype.mulTo = cMulTo; -Classic.prototype.sqrTo = cSqrTo; - -// (protected) return "-1/this % 2^DB"; useful for Mont. reduction -// justification: -// xy == 1 (mod m) -// xy = 1+km -// xy(2-xy) = (1+km)(1-km) -// x[y(2-xy)] = 1-k^2m^2 -// x[y(2-xy)] == 1 (mod m^2) -// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 -// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. -// JS multiply "overflows" differently from C/C++, so care is needed here. - -function bnpInvDigit() { - if (this.t < 1) return 0; - var x = this[0]; - if ((x & 1) == 0) return 0; - var y = x & 3; // y == 1/x mod 2^2 - y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 - y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 - y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return (y > 0) ? this.DV - y : -y; -} - -// Montgomery reduction - -function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp & 0x7fff; - this.mph = this.mp >> 15; - this.um = (1 << (m.DB - 15)) - 1; - this.mt2 = 2 * m.t; -} - -// xR mod m - -function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t, r); - r.divRemTo(this.m, null, r); - if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); - return r; -} - -// x/R mod m - -function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; -} - -// x = x/R mod m (HAC 14.32) - -function montReduce(x) { - while (x.t <= this.mt2) // pad x so am has enough room later - x[x.t++] = 0; - for (var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i] & 0x7fff; - var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM; - // use am to combine the multiply-shift-add into one call - j = i + this.m.t; - x[j] += this.m.am(0, u0, x, i, 0, this.m.t); - // propagate carry - while (x[j] >= x.DV) { - x[j] -= x.DV; - x[++j]++; - } - } - x.clamp(); - x.drShiftTo(this.m.t, x); - if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); -} - -// r = "x^2/R mod m"; x != r - -function montSqrTo(x, r) { - x.squareTo(r); - this.reduce(r); -} - -// r = "xy/R mod m"; x,y != r - -function montMulTo(x, y, r) { - x.multiplyTo(y, r); - this.reduce(r); -} - -Montgomery.prototype.convert = montConvert; -Montgomery.prototype.revert = montRevert; -Montgomery.prototype.reduce = montReduce; -Montgomery.prototype.mulTo = montMulTo; -Montgomery.prototype.sqrTo = montSqrTo; - -// (protected) true iff this is even - -function bnpIsEven() { - return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; -} - -// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) - -function bnpExp(e, z) { - if (e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), - r2 = nbi(), - g = z.convert(this), - i = nbits(e) - 1; - g.copyTo(r); - while (--i >= 0) { - z.sqrTo(r, r2); - if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); - else { - var t = r; - r = r2; - r2 = t; - } - } - return z.revert(r); -} - -// (public) this^e % m, 0 <= e < 2^32 - -function bnModPowInt(e, m) { - var z; - if (e < 256 || m.isEven()) z = new Classic(m); - else z = new Montgomery(m); - return this.exp(e, z); -} - -// protected -BigInteger.prototype.copyTo = bnpCopyTo; -BigInteger.prototype.fromInt = bnpFromInt; -BigInteger.prototype.fromString = bnpFromString; -BigInteger.prototype.clamp = bnpClamp; -BigInteger.prototype.dlShiftTo = bnpDLShiftTo; -BigInteger.prototype.drShiftTo = bnpDRShiftTo; -BigInteger.prototype.lShiftTo = bnpLShiftTo; -BigInteger.prototype.rShiftTo = bnpRShiftTo; -BigInteger.prototype.subTo = bnpSubTo; -BigInteger.prototype.multiplyTo = bnpMultiplyTo; -BigInteger.prototype.squareTo = bnpSquareTo; -BigInteger.prototype.divRemTo = bnpDivRemTo; -BigInteger.prototype.invDigit = bnpInvDigit; -BigInteger.prototype.isEven = bnpIsEven; -BigInteger.prototype.exp = bnpExp; - -// public -BigInteger.prototype.toString = bnToString; -BigInteger.prototype.negate = bnNegate; -BigInteger.prototype.abs = bnAbs; -BigInteger.prototype.compareTo = bnCompareTo; -BigInteger.prototype.bitLength = bnBitLength; -BigInteger.prototype.mod = bnMod; -BigInteger.prototype.modPowInt = bnModPowInt; - -// "constants" -BigInteger.ZERO = nbv(0); -BigInteger.ONE = nbv(1); - -module.exports = BigInteger; - - - - - - - - - - - - - - - - - - - -/* - * Copyright (c) 2003-2005 Tom Wu (tjw@cs.Stanford.EDU) - * All Rights Reserved. - * - * Modified by Recurity Labs GmbH - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF - * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * In addition, the following condition applies: - * - * All redistributions must retain an intact copy of this copyright notice - * and disclaimer. - */ - - -// Extended JavaScript BN functions, required for RSA private ops. - -// Version 1.1: new BigInteger("0", 10) returns "proper" zero -// Version 1.2: square() API, isProbablePrime fix - -// (public) -function bnClone() { - var r = nbi(); - this.copyTo(r); - return r; -} - -// (public) return value as integer - -function bnIntValue() { - if (this.s < 0) { - if (this.t == 1) return this[0] - this.DV; - else if (this.t == 0) return -1; - } else if (this.t == 1) return this[0]; - else if (this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; -} - -// (public) return value as byte - -function bnByteValue() { - return (this.t == 0) ? this.s : (this[0] << 24) >> 24; -} - -// (public) return value as short (assumes DB>=16) - -function bnShortValue() { - return (this.t == 0) ? this.s : (this[0] << 16) >> 16; -} - -// (protected) return x s.t. r^x < DV - -function bnpChunkSize(r) { - return Math.floor(Math.LN2 * this.DB / Math.log(r)); -} - -// (public) 0 if this == 0, 1 if this > 0 - -function bnSigNum() { - if (this.s < 0) return -1; - else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; -} - -// (protected) convert to radix string - -function bnpToRadix(b) { - if (b == null) b = 10; - if (this.signum() == 0 || b < 2 || b > 36) return "0"; - var cs = this.chunkSize(b); - var a = Math.pow(b, cs); - var d = nbv(a), - y = nbi(), - z = nbi(), - r = ""; - this.divRemTo(d, y, z); - while (y.signum() > 0) { - r = (a + z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d, y, z); - } - return z.intValue().toString(b) + r; -} - -// (protected) convert from radix string - -function bnpFromRadix(s, b) { - this.fromInt(0); - if (b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b, cs), - mi = false, - j = 0, - w = 0; - for (var i = 0; i < s.length; ++i) { - var x = intAt(s, i); - if (x < 0) { - if (s.charAt(i) == "-" && this.signum() == 0) mi = true; - continue; - } - w = b * w + x; - if (++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w, 0); - j = 0; - w = 0; - } - } - if (j > 0) { - this.dMultiply(Math.pow(b, j)); - this.dAddOffset(w, 0); - } - if (mi) BigInteger.ZERO.subTo(this, this); -} - -// (protected) alternate constructor - -function bnpFromNumber(a, b, c) { - if ("number" == typeof b) { - // new BigInteger(int,int,RNG) - if (a < 2) this.fromInt(1); - else { - this.fromNumber(a, c); - if (!this.testBit(a - 1)) // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); - if (this.isEven()) this.dAddOffset(1, 0); // force odd - while (!this.isProbablePrime(b)) { - this.dAddOffset(2, 0); - if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); - } - } - } else { - // new BigInteger(int,RNG) - var x = new Array(), - t = a & 7; - x.length = (a >> 3) + 1; - b.nextBytes(x); - if (t > 0) x[0] &= ((1 << t) - 1); - else x[0] = 0; - this.fromString(x, 256); - } -} - -// (public) convert to bigendian byte array - -function bnToByteArray() { - var i = this.t, - r = new Array(); - r[0] = this.s; - var p = this.DB - (i * this.DB) % 8, - d, k = 0; - if (i-- > 0) { - if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) - r[k++] = d | (this.s << (this.DB - p)); - while (i >= 0) { - if (p < 8) { - d = (this[i] & ((1 << p) - 1)) << (8 - p); - d |= this[--i] >> (p += this.DB - 8); - } else { - d = (this[i] >> (p -= 8)) & 0xff; - if (p <= 0) { - p += this.DB; - --i; - } - } - //if((d&0x80) != 0) d |= -256; - //if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; - if (k > 0 || d != this.s) r[k++] = d; - } - } - return r; -} - -function bnEquals(a) { - return (this.compareTo(a) == 0); -} - -function bnMin(a) { - return (this.compareTo(a) < 0) ? this : a; -} - -function bnMax(a) { - return (this.compareTo(a) > 0) ? this : a; -} - -// (protected) r = this op a (bitwise) - -function bnpBitwiseTo(a, op, r) { - var i, f, m = Math.min(a.t, this.t); - for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); - if (a.t < this.t) { - f = a.s & this.DM; - for (i = m; i < this.t; ++i) r[i] = op(this[i], f); - r.t = this.t; - } else { - f = this.s & this.DM; - for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); - r.t = a.t; - } - r.s = op(this.s, a.s); - r.clamp(); -} - -// (public) this & a - -function op_and(x, y) { - return x & y; -} - -function bnAnd(a) { - var r = nbi(); - this.bitwiseTo(a, op_and, r); - return r; -} - -// (public) this | a - -function op_or(x, y) { - return x | y; -} - -function bnOr(a) { - var r = nbi(); - this.bitwiseTo(a, op_or, r); - return r; -} - -// (public) this ^ a - -function op_xor(x, y) { - return x ^ y; -} - -function bnXor(a) { - var r = nbi(); - this.bitwiseTo(a, op_xor, r); - return r; -} - -// (public) this & ~a - -function op_andnot(x, y) { - return x & ~y; -} - -function bnAndNot(a) { - var r = nbi(); - this.bitwiseTo(a, op_andnot, r); - return r; -} - -// (public) ~this - -function bnNot() { - var r = nbi(); - for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; -} - -// (public) this << n - -function bnShiftLeft(n) { - var r = nbi(); - if (n < 0) this.rShiftTo(-n, r); - else this.lShiftTo(n, r); - return r; -} - -// (public) this >> n - -function bnShiftRight(n) { - var r = nbi(); - if (n < 0) this.lShiftTo(-n, r); - else this.rShiftTo(n, r); - return r; -} - -// return index of lowest 1-bit in x, x < 2^31 - -function lbit(x) { - if (x == 0) return -1; - var r = 0; - if ((x & 0xffff) == 0) { - x >>= 16; - r += 16; - } - if ((x & 0xff) == 0) { - x >>= 8; - r += 8; - } - if ((x & 0xf) == 0) { - x >>= 4; - r += 4; - } - if ((x & 3) == 0) { - x >>= 2; - r += 2; - } - if ((x & 1) == 0)++r; - return r; -} - -// (public) returns index of lowest 1-bit (or -1 if none) - -function bnGetLowestSetBit() { - for (var i = 0; i < this.t; ++i) - if (this[i] != 0) return i * this.DB + lbit(this[i]); - if (this.s < 0) return this.t * this.DB; - return -1; -} - -// return number of 1 bits in x - -function cbit(x) { - var r = 0; - while (x != 0) { - x &= x - 1; - ++r; - } - return r; -} - -// (public) return number of set bits - -function bnBitCount() { - var r = 0, - x = this.s & this.DM; - for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); - return r; -} - -// (public) true iff nth bit is set - -function bnTestBit(n) { - var j = Math.floor(n / this.DB); - if (j >= this.t) return (this.s != 0); - return ((this[j] & (1 << (n % this.DB))) != 0); -} - -// (protected) this op (1<<n) - -function bnpChangeBit(n, op) { - var r = BigInteger.ONE.shiftLeft(n); - this.bitwiseTo(r, op, r); - return r; -} - -// (public) this | (1<<n) - -function bnSetBit(n) { - return this.changeBit(n, op_or); -} - -// (public) this & ~(1<<n) - -function bnClearBit(n) { - return this.changeBit(n, op_andnot); -} - -// (public) this ^ (1<<n) - -function bnFlipBit(n) { - return this.changeBit(n, op_xor); -} - -// (protected) r = this + a - -function bnpAddTo(a, r) { - var i = 0, - c = 0, - m = Math.min(a.t, this.t); - while (i < m) { - c += this[i] + a[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - if (a.t < this.t) { - c += a.s; - while (i < this.t) { - c += this[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c += this.s; - } else { - c += this.s; - while (i < a.t) { - c += a[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = (c < 0) ? -1 : 0; - if (c > 0) r[i++] = c; - else if (c < -1) r[i++] = this.DV + c; - r.t = i; - r.clamp(); -} - -// (public) this + a - -function bnAdd(a) { - var r = nbi(); - this.addTo(a, r); - return r; -} - -// (public) this - a - -function bnSubtract(a) { - var r = nbi(); - this.subTo(a, r); - return r; -} - -// (public) this * a - -function bnMultiply(a) { - var r = nbi(); - this.multiplyTo(a, r); - return r; -} - -// (public) this^2 - -function bnSquare() { - var r = nbi(); - this.squareTo(r); - return r; -} - -// (public) this / a - -function bnDivide(a) { - var r = nbi(); - this.divRemTo(a, r, null); - return r; -} - -// (public) this % a - -function bnRemainder(a) { - var r = nbi(); - this.divRemTo(a, null, r); - return r; -} - -// (public) [this/a,this%a] - -function bnDivideAndRemainder(a) { - var q = nbi(), - r = nbi(); - this.divRemTo(a, q, r); - return new Array(q, r); -} - -// (protected) this *= n, this >= 0, 1 < n < DV - -function bnpDMultiply(n) { - this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); - ++this.t; - this.clamp(); -} - -// (protected) this += n << w words, this >= 0 - -function bnpDAddOffset(n, w) { - if (n == 0) return; - while (this.t <= w) this[this.t++] = 0; - this[w] += n; - while (this[w] >= this.DV) { - this[w] -= this.DV; - if (++w >= this.t) this[this.t++] = 0; - ++this[w]; - } -} - -// A "null" reducer - -function NullExp() {} - -function nNop(x) { - return x; -} - -function nMulTo(x, y, r) { - x.multiplyTo(y, r); -} - -function nSqrTo(x, r) { - x.squareTo(r); -} - -NullExp.prototype.convert = nNop; -NullExp.prototype.revert = nNop; -NullExp.prototype.mulTo = nMulTo; -NullExp.prototype.sqrTo = nSqrTo; - -// (public) this^e - -function bnPow(e) { - return this.exp(e, new NullExp()); -} - -// (protected) r = lower n words of "this * a", a.t <= n -// "this" should be the larger one if appropriate. - -function bnpMultiplyLowerTo(a, n, r) { - var i = Math.min(this.t + a.t, n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while (i > 0) r[--i] = 0; - var j; - for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); - for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); - r.clamp(); -} - -// (protected) r = "this * a" without lower n words, n > 0 -// "this" should be the larger one if appropriate. - -function bnpMultiplyUpperTo(a, n, r) { - --n; - var i = r.t = this.t + a.t - n; - r.s = 0; // assumes a,this >= 0 - while (--i >= 0) r[i] = 0; - for (i = Math.max(n - this.t, 0); i < a.t; ++i) - r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); - r.clamp(); - r.drShiftTo(1, r); -} - -// Barrett modular reduction - -function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); - this.mu = this.r2.divide(m); - this.m = m; -} - -function barrettConvert(x) { - if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); - else if (x.compareTo(this.m) < 0) return x; - else { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; - } -} - -function barrettRevert(x) { - return x; -} - -// x = x mod m (HAC 14.42) - -function barrettReduce(x) { - x.drShiftTo(this.m.t - 1, this.r2); - if (x.t > this.m.t + 1) { - x.t = this.m.t + 1; - x.clamp(); - } - this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); - this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); - while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); - x.subTo(this.r2, x); - while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); -} - -// r = x^2 mod m; x != r - -function barrettSqrTo(x, r) { - x.squareTo(r); - this.reduce(r); -} - -// r = x*y mod m; x,y != r - -function barrettMulTo(x, y, r) { - x.multiplyTo(y, r); - this.reduce(r); -} - -Barrett.prototype.convert = barrettConvert; -Barrett.prototype.revert = barrettRevert; -Barrett.prototype.reduce = barrettReduce; -Barrett.prototype.mulTo = barrettMulTo; -Barrett.prototype.sqrTo = barrettSqrTo; - -// (public) this^e % m (HAC 14.85) - -function bnModPow(e, m) { - var i = e.bitLength(), - k, r = nbv(1), - z; - if (i <= 0) return r; - else if (i < 18) k = 1; - else if (i < 48) k = 3; - else if (i < 144) k = 4; - else if (i < 768) k = 5; - else k = 6; - if (i < 8) - z = new Classic(m); - else if (m.isEven()) - z = new Barrett(m); - else - z = new Montgomery(m); - - // precomputation - var g = new Array(), - n = 3, - k1 = k - 1, - km = (1 << k) - 1; - g[1] = z.convert(this); - if (k > 1) { - var g2 = nbi(); - z.sqrTo(g[1], g2); - while (n <= km) { - g[n] = nbi(); - z.mulTo(g2, g[n - 2], g[n]); - n += 2; - } - } - - var j = e.t - 1, - w, is1 = true, - r2 = nbi(), - t; - i = nbits(e[j]) - 1; - while (j >= 0) { - if (i >= k1) w = (e[j] >> (i - k1)) & km; - else { - w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); - if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); - } - - n = k; - while ((w & 1) == 0) { - w >>= 1; - --n; - } - if ((i -= n) < 0) { - i += this.DB; - --j; - } - if (is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } else { - while (n > 1) { - z.sqrTo(r, r2); - z.sqrTo(r2, r); - n -= 2; - } - if (n > 0) z.sqrTo(r, r2); - else { - t = r; - r = r2; - r2 = t; - } - z.mulTo(r2, g[w], r); - } - - while (j >= 0 && (e[j] & (1 << i)) == 0) { - z.sqrTo(r, r2); - t = r; - r = r2; - r2 = t; - if (--i < 0) { - i = this.DB - 1; - --j; - } - } - } - return z.revert(r); -} - -// (public) gcd(this,a) (HAC 14.54) - -function bnGCD(a) { - var x = (this.s < 0) ? this.negate() : this.clone(); - var y = (a.s < 0) ? a.negate() : a.clone(); - if (x.compareTo(y) < 0) { - var t = x; - x = y; - y = t; - } - var i = x.getLowestSetBit(), - g = y.getLowestSetBit(); - if (g < 0) return x; - if (i < g) g = i; - if (g > 0) { - x.rShiftTo(g, x); - y.rShiftTo(g, y); - } - while (x.signum() > 0) { - if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); - if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); - if (x.compareTo(y) >= 0) { - x.subTo(y, x); - x.rShiftTo(1, x); - } else { - y.subTo(x, y); - y.rShiftTo(1, y); - } - } - if (g > 0) y.lShiftTo(g, y); - return y; -} - -// (protected) this % n, n < 2^26 - -function bnpModInt(n) { - if (n <= 0) return 0; - var d = this.DV % n, - r = (this.s < 0) ? n - 1 : 0; - if (this.t > 0) - if (d == 0) r = this[0] % n; - else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; - return r; -} - -// (public) 1/this % m (HAC 14.61) - -function bnModInverse(m) { - var ac = m.isEven(); - if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), - v = this.clone(); - var a = nbv(1), - b = nbv(0), - c = nbv(0), - d = nbv(1); - while (u.signum() != 0) { - while (u.isEven()) { - u.rShiftTo(1, u); - if (ac) { - if (!a.isEven() || !b.isEven()) { - a.addTo(this, a); - b.subTo(m, b); - } - a.rShiftTo(1, a); - } else if (!b.isEven()) b.subTo(m, b); - b.rShiftTo(1, b); - } - while (v.isEven()) { - v.rShiftTo(1, v); - if (ac) { - if (!c.isEven() || !d.isEven()) { - c.addTo(this, c); - d.subTo(m, d); - } - c.rShiftTo(1, c); - } else if (!d.isEven()) d.subTo(m, d); - d.rShiftTo(1, d); - } - if (u.compareTo(v) >= 0) { - u.subTo(v, u); - if (ac) a.subTo(c, a); - b.subTo(d, b); - } else { - v.subTo(u, v); - if (ac) c.subTo(a, c); - d.subTo(b, d); - } - } - if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if (d.compareTo(m) >= 0) return d.subtract(m); - if (d.signum() < 0) d.addTo(m, d); - else return d; - if (d.signum() < 0) return d.add(m); - else return d; -} - -var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, - 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, - 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, - 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, - 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, - 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, - 977, 983, 991, 997 -]; -var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; - -// (public) test primality with certainty >= 1-.5^t - -function bnIsProbablePrime(t) { - var i, x = this.abs(); - if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { - for (i = 0; i < lowprimes.length; ++i) - if (x[0] == lowprimes[i]) return true; - return false; - } - if (x.isEven()) return false; - i = 1; - while (i < lowprimes.length) { - var m = lowprimes[i], - j = i + 1; - while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while (i < j) if (m % lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); -} - -/* added by Recurity Labs */ - -function nbits(x) { - var n = 1, - t; - if ((t = x >>> 16) != 0) { - x = t; - n += 16; - } - if ((t = x >> 8) != 0) { - x = t; - n += 8; - } - if ((t = x >> 4) != 0) { - x = t; - n += 4; - } - if ((t = x >> 2) != 0) { - x = t; - n += 2; - } - if ((t = x >> 1) != 0) { - x = t; - n += 1; - } - return n; -} - -function bnToMPI() { - var ba = this.toByteArray(); - var size = (ba.length - 1) * 8 + nbits(ba[0]); - var result = ""; - result += String.fromCharCode((size & 0xFF00) >> 8); - result += String.fromCharCode(size & 0xFF); - result += util.bin2str(ba); - return result; -} -/* END of addition */ - -// (protected) true if probably prime (HAC 4.24, Miller-Rabin) -function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if (k <= 0) return false; - var r = n1.shiftRight(k); - t = (t + 1) >> 1; - if (t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - var j, bases = []; - for (var i = 0; i < t; ++i) { - //Pick bases at random, instead of starting at 2 - for (;;) { - j = lowprimes[Math.floor(Math.random() * lowprimes.length)]; - if (bases.indexOf(j) == -1) break; - } - bases.push(j); - a.fromInt(j); - var y = a.modPow(r, this); - if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while (j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2, this); - if (y.compareTo(BigInteger.ONE) == 0) return false; - } - if (y.compareTo(n1) != 0) return false; - } - } - return true; -} - -var BigInteger = require('./jsbn.js'); - -// protected -BigInteger.prototype.chunkSize = bnpChunkSize; -BigInteger.prototype.toRadix = bnpToRadix; -BigInteger.prototype.fromRadix = bnpFromRadix; -BigInteger.prototype.fromNumber = bnpFromNumber; -BigInteger.prototype.bitwiseTo = bnpBitwiseTo; -BigInteger.prototype.changeBit = bnpChangeBit; -BigInteger.prototype.addTo = bnpAddTo; -BigInteger.prototype.dMultiply = bnpDMultiply; -BigInteger.prototype.dAddOffset = bnpDAddOffset; -BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; -BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; -BigInteger.prototype.modInt = bnpModInt; -BigInteger.prototype.millerRabin = bnpMillerRabin; - -// public -BigInteger.prototype.clone = bnClone; -BigInteger.prototype.intValue = bnIntValue; -BigInteger.prototype.byteValue = bnByteValue; -BigInteger.prototype.shortValue = bnShortValue; -BigInteger.prototype.signum = bnSigNum; -BigInteger.prototype.toByteArray = bnToByteArray; -BigInteger.prototype.equals = bnEquals; -BigInteger.prototype.min = bnMin; -BigInteger.prototype.max = bnMax; -BigInteger.prototype.and = bnAnd; -BigInteger.prototype.or = bnOr; -BigInteger.prototype.xor = bnXor; -BigInteger.prototype.andNot = bnAndNot; -BigInteger.prototype.not = bnNot; -BigInteger.prototype.shiftLeft = bnShiftLeft; -BigInteger.prototype.shiftRight = bnShiftRight; -BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; -BigInteger.prototype.bitCount = bnBitCount; -BigInteger.prototype.testBit = bnTestBit; -BigInteger.prototype.setBit = bnSetBit; -BigInteger.prototype.clearBit = bnClearBit; -BigInteger.prototype.flipBit = bnFlipBit; -BigInteger.prototype.add = bnAdd; -BigInteger.prototype.subtract = bnSubtract; -BigInteger.prototype.multiply = bnMultiply; -BigInteger.prototype.divide = bnDivide; -BigInteger.prototype.remainder = bnRemainder; -BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; -BigInteger.prototype.modPow = bnModPow; -BigInteger.prototype.modInverse = bnModInverse; -BigInteger.prototype.pow = bnPow; -BigInteger.prototype.gcd = bnGCD; -BigInteger.prototype.isProbablePrime = bnIsProbablePrime; -BigInteger.prototype.toMPI = bnToMPI; - -// JSBN-specific extension -BigInteger.prototype.square = bnSquare; - -},{"../../util":57,"./jsbn.js":22}],23:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// -// RSA implementation - -var BigInteger = require('./jsbn.js'), - util = require('../../util'), - random = require('../random.js'); - -function SecureRandom() { - function nextBytes(byteArray) { - for (var n = 0; n < byteArray.length; n++) { - byteArray[n] = random.getSecureRandomOctet(); - } - } - this.nextBytes = nextBytes; -} - -function RSA() { - /** - * This function uses jsbn Big Num library to decrypt RSA - * @param m - * message - * @param d - * RSA d as BigInteger - * @param p - * RSA p as BigInteger - * @param q - * RSA q as BigInteger - * @param u - * RSA u as BigInteger - * @return {BigInteger} The decrypted value of the message - */ - function decrypt(m, d, p, q, u) { - var xp = m.mod(p).modPow(d.mod(p.subtract(BigInteger.ONE)), p); - var xq = m.mod(q).modPow(d.mod(q.subtract(BigInteger.ONE)), q); - util.print_debug("rsa.js decrypt\nxpn:" + util.hexstrdump(xp.toMPI()) + "\nxqn:" + util.hexstrdump(xq.toMPI())); - - var t = xq.subtract(xp); - if (t[0] == 0) { - t = xp.subtract(xq); - t = t.multiply(u).mod(q); - t = q.subtract(t); - } else { - t = t.multiply(u).mod(q); - } - return t.multiply(p).add(xp); - } - - /** - * encrypt message - * @param m message as BigInteger - * @param e public MPI part as BigInteger - * @param n public MPI part as BigInteger - * @return BigInteger - */ - function encrypt(m, e, n) { - return m.modPowInt(e, n); - } - - /* Sign and Verify */ - function sign(m, d, n) { - return m.modPow(d, n); - } - - function verify(x, e, n) { - return x.modPowInt(e, n); - } - - // "empty" RSA key constructor - - function keyObject() { - this.n = null; - this.e = 0; - this.ee = null; - this.d = null; - this.p = null; - this.q = null; - this.dmp1 = null; - this.dmq1 = null; - this.u = null; - } - - // Generate a new random private key B bits long, using public expt E - - function generate(B, E) { - var key = new keyObject(); - var rng = new SecureRandom(); - var qs = B >> 1; - key.e = parseInt(E, 16); - key.ee = new BigInteger(E, 16); - for (;;) { - for (;;) { - key.p = new BigInteger(B - qs, 1, rng); - if (key.p.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.p.isProbablePrime(10)) - break; - } - for (;;) { - key.q = new BigInteger(qs, 1, rng); - if (key.q.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.q.isProbablePrime(10)) - break; - } - if (key.p.compareTo(key.q) <= 0) { - var t = key.p; - key.p = key.q; - key.q = t; - } - var p1 = key.p.subtract(BigInteger.ONE); - var q1 = key.q.subtract(BigInteger.ONE); - var phi = p1.multiply(q1); - if (phi.gcd(key.ee).compareTo(BigInteger.ONE) == 0) { - key.n = key.p.multiply(key.q); - key.d = key.ee.modInverse(phi); - key.dmp1 = key.d.mod(p1); - key.dmq1 = key.d.mod(q1); - key.u = key.p.modInverse(key.q); - break; - } - } - return key; - } - - this.encrypt = encrypt; - this.decrypt = decrypt; - this.verify = verify; - this.sign = sign; - this.generate = generate; - this.keyObject = keyObject; -} - -module.exports = RSA; - -},{"../../util":57,"../random.js":24,"./jsbn.js":22}],24:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -// The GPG4Browsers crypto interface - -var type_mpi = require('../type/mpi.js'); - -module.exports = { - /** - * Retrieve secure random byte string of the specified length - * @param {Integer} length Length in bytes to generate - * @return {String} Random byte string - */ - getRandomBytes: function(length) { - var result = ''; - for (var i = 0; i < length; i++) { - result += String.fromCharCode(this.getSecureRandomOctet()); - } - return result; - }, - - /** - * Return a pseudo-random number in the specified range - * @param {Integer} from Min of the random number - * @param {Integer} to Max of the random number (max 32bit) - * @return {Integer} A pseudo random number - */ - getPseudoRandom: function(from, to) { - return Math.round(Math.random() * (to - from)) + from; - }, - - /** - * Return a secure random number in the specified range - * @param {Integer} from Min of the random number - * @param {Integer} to Max of the random number (max 32bit) - * @return {Integer} A secure random number - */ - getSecureRandom: function(from, to) { - var buf = new Uint32Array(1); - window.crypto.getRandomValues(buf); - var bits = ((to - from)).toString(2).length; - while ((buf[0] & (Math.pow(2, bits) - 1)) > (to - from)) - window.crypto.getRandomValues(buf); - return from + (Math.abs(buf[0] & (Math.pow(2, bits) - 1))); - }, - - getSecureRandomOctet: function() { - var buf = new Uint32Array(1); - window.crypto.getRandomValues(buf); - return buf[0] & 0xFF; - }, - - /** - * Create a secure random big integer of bits length - * @param {Integer} bits Bit length of the MPI to create - * @return {BigInteger} Resulting big integer - */ - getRandomBigInteger: function(bits) { - if (bits < 0) { - return null; - } - var numBytes = Math.floor((bits + 7) / 8); - - var randomBits = this.getRandomBytes(numBytes); - if (bits % 8 > 0) { - - randomBits = String.fromCharCode( - (Math.pow(2, bits % 8) - 1) & - randomBits.charCodeAt(0)) + - randomBits.substring(1); - } - var mpi = new type_mpi(); - mpi.fromBytes(randomBits); - return mpi.toBigInteger(); - }, - - getRandomBigIntegerInRange: function(min, max) { - if (max.compareTo(min) <= 0) { - return; - } - - var range = max.subtract(min); - var r = this.getRandomBigInteger(range.bitLength()); - while (r > range) { - r = this.getRandomBigInteger(range.bitLength()); - } - return min.add(r); - } - -}; - -},{"../type/mpi.js":55}],25:[function(require,module,exports){ -var publicKey = require('./public_key'), - pkcs1 = require('./pkcs1.js'), - hashModule = require('./hash'); - -module.exports = { - /** - * - * @param {Integer} algo public Key algorithm - * @param {Integer} hash_algo Hash algorithm - * @param {openpgp_type_mpi[]} msg_MPIs Signature multiprecision integers - * @param {openpgp_type_mpi[]} publickey_MPIs Public key multiprecision integers - * @param {String} data Data on where the signature was computed on. - * @return {Boolean} true if signature (sig_data was equal to data over hash) - */ - verify: function(algo, hash_algo, msg_MPIs, publickey_MPIs, data) { - var calc_hash = hashModule.digest(hash_algo, data); - - switch (algo) { - case 1: - // RSA (Encrypt or Sign) [HAC] - case 2: - // RSA Encrypt-Only [HAC] - case 3: - // RSA Sign-Only [HAC] - var rsa = new publicKey.rsa(); - var n = publickey_MPIs[0].toBigInteger(); - var e = publickey_MPIs[1].toBigInteger(); - var x = msg_MPIs[0].toBigInteger(); - var dopublic = rsa.verify(x, e, n); - var hash = pkcs1.emsa.decode(hash_algo, dopublic.toMPI().substring(2)); - if (hash == -1) { - throw new Error('PKCS1 padding in message or key incorrect. Aborting...'); - } - return hash == calc_hash; - - case 16: - // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - throw new Error("signing with Elgamal is not defined in the OpenPGP standard."); - case 17: - // DSA (Digital Signature Algorithm) [FIPS186] [HAC] - var dsa = new publicKey.dsa(); - var s1 = msg_MPIs[0].toBigInteger(); - var s2 = msg_MPIs[1].toBigInteger(); - var p = publickey_MPIs[0].toBigInteger(); - var q = publickey_MPIs[1].toBigInteger(); - var g = publickey_MPIs[2].toBigInteger(); - var y = publickey_MPIs[3].toBigInteger(); - var m = data; - var dopublic = dsa.verify(hash_algo, s1, s2, m, p, q, g, y); - return dopublic.compareTo(s1) == 0; - default: - throw new Error('Invalid signature algorithm.'); - } - - }, - - /** - * Create a signature on data using the specified algorithm - * @param {Integer} hash_algo hash Algorithm to use (See RFC4880 9.4) - * @param {Integer} algo Asymmetric cipher algorithm to use (See RFC4880 9.1) - * @param {openpgp_type_mpi[]} publicMPIs Public key multiprecision integers - * of the private key - * @param {openpgp_type_mpi[]} secretMPIs Private key multiprecision - * integers which is used to sign the data - * @param {String} data Data to be signed - * @return {openpgp_type_mpi[]} - */ - sign: function(hash_algo, algo, keyIntegers, data) { - - switch (algo) { - case 1: - // RSA (Encrypt or Sign) [HAC] - case 2: - // RSA Encrypt-Only [HAC] - case 3: - // RSA Sign-Only [HAC] - var rsa = new publicKey.rsa(); - var d = keyIntegers[2].toBigInteger(); - var n = keyIntegers[0].toBigInteger(); - var m = pkcs1.emsa.encode(hash_algo, - data, keyIntegers[0].byteLength()); - - return rsa.sign(m, d, n).toMPI(); - - case 17: - // DSA (Digital Signature Algorithm) [FIPS186] [HAC] - var dsa = new publicKey.dsa(); - - var p = keyIntegers[0].toBigInteger(); - var q = keyIntegers[1].toBigInteger(); - var g = keyIntegers[2].toBigInteger(); - var y = keyIntegers[3].toBigInteger(); - var x = keyIntegers[4].toBigInteger(); - var m = data; - var result = dsa.sign(hash_algo, m, g, p, q, x); - - return result[0].toString() + result[1].toString(); - case 16: - // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.'); - default: - throw new Error('Invalid signature algorithm.'); - } - } -} - -},{"./hash":13,"./pkcs1.js":18,"./public_key":21}],26:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var base64 = require('./base64.js'); -var enums = require('../enums.js'); -var config = require('../config'); - -/** - * Finds out which Ascii Armoring type is used. This is an internal function - * @param {String} text [String] ascii armored text - * @returns {Integer} 0 = MESSAGE PART n of m - * 1 = MESSAGE PART n - * 2 = SIGNED MESSAGE - * 3 = PGP MESSAGE - * 4 = PUBLIC KEY BLOCK - * 5 = PRIVATE KEY BLOCK - * null = unknown - */ -function get_type(text) { - var reHeader = /^-----([^-]+)-----$\n/m; - - var header = text.match(reHeader); - - // BEGIN PGP MESSAGE, PART X/Y - // Used for multi-part messages, where the armor is split amongst Y - // parts, and this is the Xth part out of Y. - if (header[1].match(/BEGIN PGP MESSAGE, PART \d+\/\d+/)) { - return enums.armor.multipart_section; - } else - // BEGIN PGP MESSAGE, PART X - // Used for multi-part messages, where this is the Xth part of an - // unspecified number of parts. Requires the MESSAGE-ID Armor - // Header to be used. - if (header[1].match(/BEGIN PGP MESSAGE, PART \d+/)) { - return enums.armor.multipart_last; - - } else - // BEGIN PGP SIGNATURE - // Used for detached signatures, OpenPGP/MIME signatures, and - // cleartext signatures. Note that PGP 2.x uses BEGIN PGP MESSAGE - // for detached signatures. - if (header[1].match(/BEGIN PGP SIGNED MESSAGE/)) { - return enums.armor.signed; - - } else - // BEGIN PGP MESSAGE - // Used for signed, encrypted, or compressed files. - if (header[1].match(/BEGIN PGP MESSAGE/)) { - return enums.armor.message; - - } else - // BEGIN PGP PUBLIC KEY BLOCK - // Used for armoring public keys. - if (header[1].match(/BEGIN PGP PUBLIC KEY BLOCK/)) { - return enums.armor.public_key; - - } else - // BEGIN PGP PRIVATE KEY BLOCK - // Used for armoring private keys. - if (header[1].match(/BEGIN PGP PRIVATE KEY BLOCK/)) { - return enums.armor.private_key; - } -} - -/** - * Add additional information to the armor version of an OpenPGP binary - * packet block. - * @author Alex - * @version 2011-12-16 - * @returns {String} The header information - */ -function armor_addheader() { - var result = ""; - if (config.show_version) { - result += "Version: " + config.versionstring + '\r\n'; - } - if (config.show_comment) { - result += "Comment: " + config.commentstring + '\r\n'; - } - result += '\r\n'; - return result; -} - - - -/** - * Calculates a checksum over the given data and returns it base64 encoded - * @param {String} data Data to create a CRC-24 checksum for - * @return {String} Base64 encoded checksum - */ -function getCheckSum(data) { - var c = createcrc24(data); - var str = "" + String.fromCharCode(c >> 16) + - String.fromCharCode((c >> 8) & 0xFF) + - String.fromCharCode(c & 0xFF); - return base64.encode(str); -} - -/** - * Calculates the checksum over the given data and compares it with the - * given base64 encoded checksum - * @param {String} data Data to create a CRC-24 checksum for - * @param {String} checksum Base64 encoded checksum - * @return {Boolean} True if the given checksum is correct; otherwise false - */ -function verifyCheckSum(data, checksum) { - var c = getCheckSum(data); - var d = checksum; - return c[0] == d[0] && c[1] == d[1] && c[2] == d[2]; -} -/** - * Internal function to calculate a CRC-24 checksum over a given string (data) - * @param {String} data Data to create a CRC-24 checksum for - * @return {Integer} The CRC-24 checksum as number - */ -var crc_table = [ - 0x00000000, 0x00864cfb, 0x018ad50d, 0x010c99f6, 0x0393e6e1, 0x0315aa1a, 0x021933ec, 0x029f7f17, 0x07a18139, - 0x0727cdc2, 0x062b5434, 0x06ad18cf, 0x043267d8, 0x04b42b23, 0x05b8b2d5, 0x053efe2e, 0x0fc54e89, 0x0f430272, - 0x0e4f9b84, 0x0ec9d77f, 0x0c56a868, 0x0cd0e493, 0x0ddc7d65, 0x0d5a319e, 0x0864cfb0, 0x08e2834b, 0x09ee1abd, - 0x09685646, 0x0bf72951, 0x0b7165aa, 0x0a7dfc5c, 0x0afbb0a7, 0x1f0cd1e9, 0x1f8a9d12, 0x1e8604e4, 0x1e00481f, - 0x1c9f3708, 0x1c197bf3, 0x1d15e205, 0x1d93aefe, 0x18ad50d0, 0x182b1c2b, 0x192785dd, 0x19a1c926, 0x1b3eb631, - 0x1bb8faca, 0x1ab4633c, 0x1a322fc7, 0x10c99f60, 0x104fd39b, 0x11434a6d, 0x11c50696, 0x135a7981, 0x13dc357a, - 0x12d0ac8c, 0x1256e077, 0x17681e59, 0x17ee52a2, 0x16e2cb54, 0x166487af, 0x14fbf8b8, 0x147db443, 0x15712db5, - 0x15f7614e, 0x3e19a3d2, 0x3e9fef29, 0x3f9376df, 0x3f153a24, 0x3d8a4533, 0x3d0c09c8, 0x3c00903e, 0x3c86dcc5, - 0x39b822eb, 0x393e6e10, 0x3832f7e6, 0x38b4bb1d, 0x3a2bc40a, 0x3aad88f1, 0x3ba11107, 0x3b275dfc, 0x31dced5b, - 0x315aa1a0, - 0x30563856, 0x30d074ad, 0x324f0bba, 0x32c94741, 0x33c5deb7, 0x3343924c, 0x367d6c62, 0x36fb2099, 0x37f7b96f, - 0x3771f594, 0x35ee8a83, 0x3568c678, 0x34645f8e, 0x34e21375, 0x2115723b, 0x21933ec0, 0x209fa736, 0x2019ebcd, - 0x228694da, 0x2200d821, 0x230c41d7, 0x238a0d2c, 0x26b4f302, 0x2632bff9, 0x273e260f, 0x27b86af4, 0x252715e3, - 0x25a15918, 0x24adc0ee, 0x242b8c15, 0x2ed03cb2, 0x2e567049, 0x2f5ae9bf, 0x2fdca544, 0x2d43da53, 0x2dc596a8, - 0x2cc90f5e, 0x2c4f43a5, 0x2971bd8b, 0x29f7f170, 0x28fb6886, 0x287d247d, 0x2ae25b6a, 0x2a641791, 0x2b688e67, - 0x2beec29c, 0x7c3347a4, 0x7cb50b5f, 0x7db992a9, 0x7d3fde52, 0x7fa0a145, 0x7f26edbe, 0x7e2a7448, 0x7eac38b3, - 0x7b92c69d, 0x7b148a66, 0x7a181390, 0x7a9e5f6b, 0x7801207c, 0x78876c87, 0x798bf571, 0x790db98a, 0x73f6092d, - 0x737045d6, 0x727cdc20, 0x72fa90db, 0x7065efcc, 0x70e3a337, 0x71ef3ac1, 0x7169763a, 0x74578814, 0x74d1c4ef, - 0x75dd5d19, 0x755b11e2, 0x77c46ef5, 0x7742220e, 0x764ebbf8, 0x76c8f703, 0x633f964d, 0x63b9dab6, 0x62b54340, - 0x62330fbb, - 0x60ac70ac, 0x602a3c57, 0x6126a5a1, 0x61a0e95a, 0x649e1774, 0x64185b8f, 0x6514c279, 0x65928e82, 0x670df195, - 0x678bbd6e, 0x66872498, 0x66016863, 0x6cfad8c4, 0x6c7c943f, 0x6d700dc9, 0x6df64132, 0x6f693e25, 0x6fef72de, - 0x6ee3eb28, 0x6e65a7d3, 0x6b5b59fd, 0x6bdd1506, 0x6ad18cf0, 0x6a57c00b, 0x68c8bf1c, 0x684ef3e7, 0x69426a11, - 0x69c426ea, 0x422ae476, 0x42aca88d, 0x43a0317b, 0x43267d80, 0x41b90297, 0x413f4e6c, 0x4033d79a, 0x40b59b61, - 0x458b654f, 0x450d29b4, 0x4401b042, 0x4487fcb9, 0x461883ae, 0x469ecf55, 0x479256a3, 0x47141a58, 0x4defaaff, - 0x4d69e604, 0x4c657ff2, 0x4ce33309, 0x4e7c4c1e, 0x4efa00e5, 0x4ff69913, 0x4f70d5e8, 0x4a4e2bc6, 0x4ac8673d, - 0x4bc4fecb, 0x4b42b230, 0x49ddcd27, 0x495b81dc, 0x4857182a, 0x48d154d1, 0x5d26359f, 0x5da07964, 0x5cace092, - 0x5c2aac69, 0x5eb5d37e, 0x5e339f85, 0x5f3f0673, 0x5fb94a88, 0x5a87b4a6, 0x5a01f85d, 0x5b0d61ab, 0x5b8b2d50, - 0x59145247, 0x59921ebc, 0x589e874a, 0x5818cbb1, 0x52e37b16, 0x526537ed, 0x5369ae1b, 0x53efe2e0, 0x51709df7, - 0x51f6d10c, - 0x50fa48fa, 0x507c0401, 0x5542fa2f, 0x55c4b6d4, 0x54c82f22, 0x544e63d9, 0x56d11cce, 0x56575035, 0x575bc9c3, - 0x57dd8538 -]; - -function createcrc24(input) { - var crc = 0xB704CE; - var index = 0; - - while ((input.length - index) > 16) { - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 1)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 2)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 3)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 4)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 5)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 6)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 7)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 8)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 9)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 10)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 11)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 12)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 13)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 14)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 15)) & 0xff]; - index += 16; - } - - for (var j = index; j < input.length; j++) { - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index++)) & 0xff]; - } - return crc & 0xffffff; -} - -/** - * Splits a message into two parts, the headers and the body. This is an internal function - * @param {String} text OpenPGP armored message part - * @returns {(Boolean|Object)} Either false in case of an error - * or an object with attribute "headers" containing the headers and - * and an attribute "body" containing the body. - */ -function split_headers(text) { - var reEmptyLine = /^[\t ]*\n/m; - var headers = ""; - var body = text; - - var matchResult = reEmptyLine.exec(text); - - if (matchResult != null) { - headers = text.slice(0, matchResult.index); - body = text.slice(matchResult.index + matchResult[0].length); - } - - return { headers: headers, body: body }; -} - -/** - * Splits a message into two parts, the body and the checksum. This is an internal function - * @param {String} text OpenPGP armored message part - * @returns {(Boolean|Object)} Either false in case of an error - * or an object with attribute "body" containing the body - * and an attribute "checksum" containing the checksum. - */ -function split_checksum(text) { - var reChecksumStart = /^=/m; - var body = text; - var checksum = ""; - - var matchResult = reChecksumStart.exec(text); - - if (matchResult != null) { - body = text.slice(0, matchResult.index); - checksum = text.slice(matchResult.index + 1); - } - - return { body: body, checksum: checksum }; -} - -/** - * DeArmor an OpenPGP armored message; verify the checksum and return - * the encoded bytes - * @param {String} text OpenPGP armored message - * @returns {(Boolean|Object)} Either false in case of an error - * or an object with attribute "text" containing the message text - * and an attribute "data" containing the bytes. - */ -function dearmor(text) { - var reSplit = /^-----[^-]+-----$\n/m; - - text = text.replace(/\r/g, ''); - - var type = get_type(text); - - var splittext = text.split(reSplit); - - // IE has a bug in split with a re. If the pattern matches the beginning of the - // string it doesn't create an empty array element 0. So we need to detect this - // so we know the index of the data we are interested in. - var indexBase = 1; - - var result, checksum; - - if (text.search(reSplit) != splittext[0].length) { - indexBase = 0; - } - - if (type != 2) { - var msg = split_headers(splittext[indexBase]); - var msg_sum = split_checksum(msg.body); - - result = { - data: base64.decode(msg_sum.body), - type: type - }; - - checksum = msg_sum.checksum; - } else { - // Reverse dash-escaping for msg and remove trailing whitespace at end of line - var msg = split_headers(splittext[indexBase].replace(/^- /mg, '').replace(/[\t ]+\n/g, "\n")); - var sig = split_headers(splittext[indexBase + 1].replace(/^- /mg, '')); - var sig_sum = split_checksum(sig.body); - - result = { - text: msg.body.replace(/\n$/, '').replace(/\n/g, "\r\n"), - data: base64.decode(sig_sum.body), - type: type - }; - - checksum = sig_sum.checksum; - } - - if (!verifyCheckSum(result.data, checksum)) { - util.print_error("Ascii armor integrity check on message failed: '" - + checksum - + "' should be '" - + getCheckSum(result) + "'"); - return false; - } else { - return result; - } -} - - -/** - * Armor an OpenPGP binary packet block - * @param {Integer} messagetype type of the message - * @param body - * @param {Integer} partindex - * @param {Integer} parttotal - * @returns {String} Armored text - */ -function armor(messagetype, body, partindex, parttotal) { - var result = ""; - switch (messagetype) { - case enums.armor.multipart_section: - result += "-----BEGIN PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n"; - result += armor_addheader(); - result += base64.encode(body); - result += "\r\n=" + getCheckSum(body) + "\r\n"; - result += "-----END PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n"; - break; - case enums.armor.mutlipart_last: - result += "-----BEGIN PGP MESSAGE, PART " + partindex + "-----\r\n"; - result += armor_addheader(); - result += base64.encode(body); - result += "\r\n=" + getCheckSum(body) + "\r\n"; - result += "-----END PGP MESSAGE, PART " + partindex + "-----\r\n"; - break; - case enums.armor.signed: - result += "\r\n-----BEGIN PGP SIGNED MESSAGE-----\r\n"; - result += "Hash: " + body.hash + "\r\n\r\n"; - result += body.text.replace(/\n-/g, "\n- -"); - result += "\r\n-----BEGIN PGP SIGNATURE-----\r\n"; - result += armor_addheader(); - result += base64.encode(body.data); - result += "\r\n=" + getCheckSum(body.data) + "\r\n"; - result += "-----END PGP SIGNATURE-----\r\n"; - break; - case enums.armor.message: - result += "-----BEGIN PGP MESSAGE-----\r\n"; - result += armor_addheader(); - result += base64.encode(body); - result += "\r\n=" + getCheckSum(body) + "\r\n"; - result += "-----END PGP MESSAGE-----\r\n"; - break; - case enums.armor.public_key: - result += "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n"; - result += armor_addheader(); - result += base64.encode(body); - result += "\r\n=" + getCheckSum(body) + "\r\n"; - result += "-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n"; - break; - case enums.armor.private_key: - result += "-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n"; - result += armor_addheader(); - result += base64.encode(body); - result += "\r\n=" + getCheckSum(body) + "\r\n"; - result += "-----END PGP PRIVATE KEY BLOCK-----\r\n"; - break; - } - - return result; -} - -module.exports = { - encode: armor, - decode: dearmor -}; - -},{"../config":4,"../enums.js":28,"./base64.js":27}],27:[function(require,module,exports){ -/* OpenPGP radix-64/base64 string encoding/decoding - * Copyright 2005 Herbert Hanewinkel, www.haneWIN.de - * version 1.0, check www.haneWIN.de for the latest version - * - * This software is provided as-is, without express or implied warranty. - * Permission to use, copy, modify, distribute or sell this software, with or - * without fee, for any purpose and by any individual or organization, is hereby - * granted, provided that the above copyright notice and this paragraph appear - * in all copies. Distribution as a part of an application or binary must - * include the above copyright notice in the documentation and/or other materials - * provided with the application or distribution. - */ - -var b64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - -function s2r(t) { - var a, c, n; - var r = '', - l = 0, - s = 0; - var tl = t.length; - - for (n = 0; n < tl; n++) { - c = t.charCodeAt(n); - if (s == 0) { - r += b64s.charAt((c >> 2) & 63); - a = (c & 3) << 4; - } else if (s == 1) { - r += b64s.charAt((a | (c >> 4) & 15)); - a = (c & 15) << 2; - } else if (s == 2) { - r += b64s.charAt(a | ((c >> 6) & 3)); - l += 1; - if ((l % 60) == 0) - r += "\n"; - r += b64s.charAt(c & 63); - } - l += 1; - if ((l % 60) == 0) - r += "\n"; - - s += 1; - if (s == 3) - s = 0; - } - if (s > 0) { - r += b64s.charAt(a); - l += 1; - if ((l % 60) == 0) - r += "\n"; - r += '='; - l += 1; - } - if (s == 1) { - if ((l % 60) == 0) - r += "\n"; - r += '='; - } - - return r; -} - -function r2s(t) { - var c, n; - var r = '', - s = 0, - a = 0; - var tl = t.length; - - for (n = 0; n < tl; n++) { - c = b64s.indexOf(t.charAt(n)); - if (c >= 0) { - if (s) - r += String.fromCharCode(a | (c >> (6 - s)) & 255); - s = (s + 2) & 7; - a = (c << s) & 255; - } - } - return r; -} - -module.exports = { - encode: s2r, - decode: r2s -} - -},{}],28:[function(require,module,exports){ -var enums = { - - /** A string to key specifier type - * @enum {Integer} - */ - s2k: { - simple: 0, - salted: 1, - iterated: 3, - gnu: 101 - }, - - /** RFC4880, section 9.1 - * @enum {String} - */ - publicKey: { - rsa_encrypt_sign: 1, - rsa_encrypt: 2, - rsa_sign: 3, - elgamal: 16, - dsa: 17 - }, - - /** RFC4880, section 9.2 - * @enum {String} - */ - symmetric: { - plaintext: 0, - /** Not implemented! */ - idea: 1, - tripledes: 2, - cast5: 3, - blowfish: 4, - aes128: 7, - aes192: 8, - aes256: 9, - twofish: 10 - }, - - /** RFC4880, section 9.3 - * @enum {String} - */ - compression: { - uncompressed: 0, - /** RFC1951 */ - zip: 1, - /** RFC1950 */ - zlib: 2, - bzip2: 3 - }, - - /** RFC4880, section 9.4 - * @enum {String} - */ - hash: { - md5: 1, - sha1: 2, - ripemd: 3, - sha256: 8, - sha384: 9, - sha512: 10, - sha224: 11 - }, - - - /** - * @enum {String} - * A list of packet types and numeric tags associated with them. - */ - packet: { - public_key_encrypted_session_key: 1, - signature: 2, - sym_encrypted_session_key: 3, - one_pass_signature: 4, - secret_key: 5, - public_key: 6, - secret_subkey: 7, - compressed: 8, - symmetrically_encrypted: 9, - marker: 10, - literal: 11, - trust: 12, - userid: 13, - public_subkey: 14, - user_attribute: 17, - sym_encrypted_integrity_protected: 18, - modification_detection_code: 19 - }, - - - /** - * Data types in the literal packet - * @readonly - * @enum {String} - */ - literal: { - /** Binary data */ - binary: 'b'.charCodeAt(), - /** Text data */ - text: 't'.charCodeAt(), - /** Utf8 data */ - utf8: 'u'.charCodeAt() - }, - - - /** One pass signature packet type - * @enum {String} */ - signature: { - /** 0x00: Signature of a binary document. */ - binary: 0, - /** 0x01: Signature of a canonical text document. - * Canonicalyzing the document by converting line endings. */ - text: 1, - /** 0x02: Standalone signature. - * This signature is a signature of only its own subpacket contents. - * It is calculated identically to a signature over a zero-lengh - * binary document. Note that it doesn't make sense to have a V3 - * standalone signature. */ - standalone: 2, - /** 0x10: Generic certification of a User ID and Public-Key packet. - * The issuer of this certification does not make any particular - * assertion as to how well the certifier has checked that the owner - * of the key is in fact the person described by the User ID. */ - cert_generic: 16, - /** 0x11: Persona certification of a User ID and Public-Key packet. - * The issuer of this certification has not done any verification of - * the claim that the owner of this key is the User ID specified. */ - cert_persona: 17, - /** 0x12: Casual certification of a User ID and Public-Key packet. - * The issuer of this certification has done some casual - * verification of the claim of identity. */ - cert_casual: 18, - /** 0x13: Positive certification of a User ID and Public-Key packet. - * The issuer of this certification has done substantial - * verification of the claim of identity. - * - * Most OpenPGP implementations make their "key signatures" as 0x10 - * certifications. Some implementations can issue 0x11-0x13 - * certifications, but few differentiate between the types. */ - cert_positive: 19, - /** 0x30: Certification revocation signature - * This signature revokes an earlier User ID certification signature - * (signature class 0x10 through 0x13) or direct-key signature - * (0x1F). It should be issued by the same key that issued the - * revoked signature or an authorized revocation key. The signature - * is computed over the same data as the certificate that it - * revokes, and should have a later creation date than that - * certificate. */ - cert_revocation: 48, - /** 0x18: Subkey Binding Signature - * This signature is a statement by the top-level signing key that - * indicates that it owns the subkey. This signature is calculated - * directly on the primary key and subkey, and not on any User ID or - * other packets. A signature that binds a signing subkey MUST have - * an Embedded Signature subpacket in this binding signature that - * contains a 0x19 signature made by the signing subkey on the - * primary key and subkey. */ - subkey_binding: 24, - /** 0x19: Primary Key Binding Signature - * This signature is a statement by a signing subkey, indicating - * that it is owned by the primary key and subkey. This signature - * is calculated the same way as a 0x18 signature: directly on the - * primary key and subkey, and not on any User ID or other packets. - - * When a signature is made over a key, the hash data starts with the - * octet 0x99, followed by a two-octet length of the key, and then body - * of the key packet. (Note that this is an old-style packet header for - * a key packet with two-octet length.) A subkey binding signature - * (type 0x18) or primary key binding signature (type 0x19) then hashes - * the subkey using the same format as the main key (also using 0x99 as - * the first octet). */ - key_binding: 25, - /** 0x1F: Signature directly on a key - * This signature is calculated directly on a key. It binds the - * information in the Signature subpackets to the key, and is - * appropriate to be used for subpackets that provide information - * about the key, such as the Revocation Key subpacket. It is also - * appropriate for statements that non-self certifiers want to make - * about the key itself, rather than the binding between a key and a - * name. */ - key: 31, - /** 0x20: Key revocation signature - * The signature is calculated directly on the key being revoked. A - * revoked key is not to be used. Only revocation signatures by the - * key being revoked, or by an authorized revocation key, should be - * considered valid revocation signatures.a */ - key_revocation: 32, - /** 0x28: Subkey revocation signature - * The signature is calculated directly on the subkey being revoked. - * A revoked subkey is not to be used. Only revocation signatures - * by the top-level signature key that is bound to this subkey, or - * by an authorized revocation key, should be considered valid - * revocation signatures. - * Key revocation signatures (types 0x20 and 0x28) - * hash only the key being revoked. */ - subkey_revocation: 40, - /** 0x40: Timestamp signature. - * This signature is only meaningful for the timestamp contained in - * it. */ - timestamp: 64, - /** 0x50: Third-Party Confirmation signature. - * This signature is a signature over some other OpenPGP Signature - * packet(s). It is analogous to a notary seal on the signed data. - * A third-party signature SHOULD include Signature Target - * subpacket(s) to give easy identification. Note that we really do - * mean SHOULD. There are plausible uses for this (such as a blind - * party that only sees the signature, not the key or source - * document) that cannot include a target subpacket. */ - third_party: 80 - }, - - signatureSubpacket: { - signature_creation_time: 2, - signature_expiration_time: 3, - exportable_certification: 4, - trust_signature: 5, - regular_expression: 6, - revocable: 7, - key_expiration_time: 9, - placeholder_backwards_compatibility: 10, - preferred_symmetric_algorithms: 11, - revocation_key: 12, - issuer: 16, - notation_data: 20, - preferred_hash_algorithms: 21, - preferred_compression_algorithms: 22, - key_server_preferences: 23, - preferred_key_server: 24, - primary_user_id: 25, - policy_uri: 26, - key_flags: 27, - signers_user_id: 28, - reason_for_revocation: 29, - features: 30, - signature_target: 31, - embedded_signature: 32 - }, - - keyFlags: { - // 0x01 - This key may be used to certify other keys. - certify_keys: 1, - // 0x02 - This key may be used to sign data. - sign_data: 2, - // 0x04 - This key may be used to encrypt communications. - encrypt_communication: 4, - // 0x08 - This key may be used to encrypt storage. - encrypt_storage: 8, - // 0x10 - The private component of this key may have been split - // by a secret-sharing mechanism. - split_private_key: 16, - // 0x20 - This key may be used for authentication. - authentication: 32, - // 0x80 - The private component of this key may be in the - // possession of more than one person. - shared_private_key: 128 - }, - - armor: { - multipart_section: 0, - multipart_last: 1, - signed: 2, - message: 3, - public_key: 4, - private_key: 5 - }, - - // Asserts validity and converts from string/integer to integer. - write: function(type, e) { - if (typeof e == 'number') { - e = this.read(type, e); - } - - if (type[e] !== undefined) { - return type[e]; - } else throw new Error('Invalid enum value.'); - }, - // Converts from an integer to string. - read: function(type, e) { - for (var i in type) - if (type[i] == e) return i; - - throw new Error('Invalid enum value.'); - } -} - -module.exports = enums; - -},{}],29:[function(require,module,exports){ - -module.exports = require('./openpgp.js'); -module.exports.key = require('./key.js'); -module.exports.message = require('./message.js'); -module.exports.cleartext = require('./cleartext.js'); -module.exports.util = require('./util'); -module.exports.packet = require('./packet'); -module.exports.mpi = require('./type/mpi.js'); -module.exports.s2k = require('./type/s2k.js'); -module.exports.keyid = require('./type/keyid.js'); -module.exports.armor = require('./encoding/armor.js'); -module.exports.enums = require('./enums.js'); -module.exports.config = require('./config'); -module.exports.crypto = require('./crypto'); - -},{"./cleartext.js":2,"./config":4,"./crypto":17,"./encoding/armor.js":26,"./enums.js":28,"./key.js":30,"./message.js":32,"./openpgp.js":33,"./packet":36,"./type/keyid.js":54,"./type/mpi.js":55,"./type/s2k.js":56,"./util":57}],30:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); -var config = require('./config'); - -/** - * @class - * @classdesc Class that represents an OpenPGP key. Must contain a primary key. - * Can contain additional subkeys, signatures, user ids, user attributes. - * @param {packetlist} packetlist The packets that form this key - */ - -function Key(packetlist) { - if (!(this instanceof Key)) { - return new Key(packetlist); - } - this.packets = packetlist || new packet.list(); -} - -/** - * Returns the primary key packet (secret or public) - * @returns {packet_secret_key|packet_public_key|null} - */ -Key.prototype.getKeyPacket = function() { - for (var i = 0; i < this.packets.length; i++) { - if (this.packets[i].tag == enums.packet.public_key || - this.packets[i].tag == enums.packet.secret_key) { - return this.packets[i]; - } - } - return null; -}; - -/** - * Returns all the private and public subkey packets - * @returns {[public_subkey|secret_subkey]} - */ -Key.prototype.getSubkeyPackets = function() { - - var subkeys = []; - - for (var i = 0; i < this.packets.length; i++) { - if (this.packets[i].tag == enums.packet.public_subkey || - this.packets[i].tag == enums.packet.secret_subkey) { - subkeys.push(this.packets[i]); - } - } - - return subkeys; -}; - -/** - * Returns all the private and public key and subkey packets - * @returns {[public_subkey|secret_subkey|packet_secret_key|packet_public_key]} - */ -Key.prototype.getAllKeyPackets = function() { - return [this.getKeyPacket()].concat(this.getSubkeyPackets()); -}; - -/** - * Returns key IDs of all key packets - * @returns {[keyid]} - */ -Key.prototype.getKeyIds = function() { - var keyIds = []; - var keys = this.getAllKeyPackets(); - for (var i = 0; i < keys.length; i++) { - keyIds.push(keys[i].getKeyId()); - } - return keyIds; -}; - -function findKey(keys, keyIds) { - for (var i = 0; i < keys.length; i++) { - var keyId = keys[i].getKeyId(); - for (var j = 0; j < keyIds.length; j++) { - if (keyId.equals(keyIds[j])) { - return keys[i]; - } - } - } - return null; -} - -/** - * Returns first public key packet for given array of key IDs - * @param {[keyid]} keyIds - * @return {public_subkey|packet_public_key|null} - */ -Key.prototype.getPublicKeyPacket = function(keyIds) { - var keys = this.packets.filterByTag(enums.packet.public_key, enums.packet.public_subkey); - return findKey(keys, keyIds); -}; - -/** - * Returns first private key packet for given array of key IDs - * @param {[keyid]} keyIds - * @return {secret_subkey|packet_secret_key|null} - */ -Key.prototype.getPrivateKeyPacket = function(keyIds) { - var keys = this.packets.filterByTag(enums.packet.secret_key, enums.packet.secret_subkey); - return findKey(keys, keyIds); -}; - -/** - * Returns true if this is a public key - * @return {Boolean} - */ -Key.prototype.isPublic = function() { - var publicKeyPackets = this.packets.filterByTag(enums.packet.public_key); - return publicKeyPackets.length ? true : false; -}; - -/** - * Returns true if this is a private key - * @return {Boolean} - */ -Key.prototype.isPrivate = function() { - var privateKeyPackets = this.packets.filterByTag(enums.packet.private_key); - return privateKeyPackets.length ? true : false; -}; - -/** - * Returns key as public key - * @return {key} public key - */ -Key.prototype.toPublic = function() { - var packetlist = new packet.list(); - for (var i = 0; i < this.packets.length; i++) { - switch (this.packets[i].tag) { - case enums.packet.secret_key: - var bytes = this.packets[i].writePublicKey(); - var pubKeyPacket = new packet.public_key(); - pubKeyPacket.read(bytes); - packetlist.push(pubKeyPacket); - break; - case enums.packet.secret_subkey: - var bytes = this.packets[i].writePublicKey(); - var pubSubkeyPacket = new packet.public_subkey(); - pubSubkeyPacket.read(bytes); - packetlist.push(pubSubkeyPacket); - break; - default: - packetlist.push(this.packets[i]); - } - } - return new Key(packetlist); -}; - -/** - * Returns ASCII armored text of key - * @return {String} ASCII armor - */ -Key.prototype.armor = function() { - var type = this.isPublic() ? enums.armor.public_key : enums.armor.private_key; - return armor.encode(type, this.packets.write()); -}; - -/** - * Returns first key packet that is available for signing - * @return {public_subkey|secret_subkey|packet_secret_key|packet_public_key|null} - */ -Key.prototype.getSigningKeyPacket = function() { - - var signing = [ enums.publicKey.rsa_encrypt_sign, enums.publicKey.rsa_sign, enums.publicKey.dsa]; - - signing = signing.map(function(s) { - return enums.read(enums.publicKey, s); - }); - - var keys = this.getAllKeyPackets(); - - for (var i = 0; i < keys.length; i++) { - if (signing.indexOf(keys[i].algorithm) !== -1) { - return keys[i]; - } - } - - return null; -}; - -/** - * Returns preferred signature hash algorithm of this key - * @return {String} - */ -Key.prototype.getPreferredSignatureHashAlgorithm = function() { - //TODO implement: https://tools.ietf.org/html/rfc4880#section-5.2.3.8 - //separate private key preference from digest preferences - return config.prefer_hash_algorithm; -}; - -/** - * Returns the first valid encryption key packet for this key - * @returns {public_subkey|secret_subkey|packet_secret_key|packet_public_key|null} key packet or null if no encryption key has been found - */ -Key.prototype.getEncryptionKeyPacket = function() { - // V4: by convention subkeys are prefered for encryption service - // V3: keys MUST NOT have subkeys - var isValidEncryptionKey = function(key) { - //TODO evaluate key flags: http://tools.ietf.org/html/rfc4880#section-5.2.3.21 - return key.algorithm != enums.read(enums.publicKey, enums.publicKey.dsa) && key.algorithm != enums.read(enums.publicKey, - enums.publicKey.rsa_sign); - //TODO verify key - //&& keys.verifyKey() - }; - - var subkeys = this.getSubkeyPackets(); - - for (var j = 0; j < subkeys.length; j++) { - if (isValidEncryptionKey(subkeys[j])) { - return subkeys[j]; - } - } - // if no valid subkey for encryption, use primary key - var primaryKey = this.getKeyPacket(); - if (isValidEncryptionKey(primaryKey)) { - return primaryKey; - } - return null; -}; - -/** - * Decrypts all secret key and subkey packets - * @param {String} passphrase - * @return {Boolean} true if all key and subkey packets decrypted successfully - */ -Key.prototype.decrypt = function(passphrase) { - var keys = this.packets.filterByTag(enums.packet.secret_key, enums.packet.secret_subkey); - for (var i = 0; i < keys.length; i++) { - var success = keys[i].decrypt(passphrase); - if (!success) return false; - } - return true; -}; - -/** - * Decrypts specific key packets by key ID - * @param {[keyid]} keyIds - * @param {String} passphrase - * @return {Boolean} true if all key packets decrypted successfully - */ -Key.prototype.decryptKeyPacket = function(keyIds, passphrase) { - //TODO return value - var keys = this.packets.filterByTag(enums.packet.secret_key, enums.packet.secret_subkey); - for (var i = 0; i < keys.length; i++) { - var keyId = keys[i].getKeyId(); - for (var j = 0; j < keyIds.length; j++) { - if (keyId.equals(keyIds[j])) { - var success = keys[i].decrypt(passphrase); - if (!success) return false; - } - } - } - return true; -}; - -// TODO -Key.prototype.verify = function() { - -}; -// TODO -Key.prototype.revoke = function() { - -}; - -/** - * Reads an OpenPGP armored text and returns a key object - * @param {String} armoredText text to be parsed - * @return {key} new key object - */ -function readArmored(armoredText) { - var input = armor.decode(armoredText); - if (!(input.type == enums.armor.public_key || input.type == enums.armor.private_key)) { - throw new Error('Armored text not of type key'); - } - var packetlist = new packet.list(); - packetlist.read(input.data); - var newKey = new Key(packetlist); - return newKey; -} - -/** - * Generates a new OpenPGP key. Currently only supports RSA keys. - * Primary and subkey will be of same type. - * @param {Integer} keyType to indicate what type of key to make. - * RSA is 1. See http://tools.ietf.org/html/rfc4880#section-9.1 - * @param {Integer} numBits number of bits for the key creation. - * @param {String} userId assumes already in form of "User Name <username@email.com>" - * @param {String} passphrase The passphrase used to encrypt the resulting private key - * @return {Key} - */ -function generate(keyType, numBits, userId, passphrase) { - var packetlist = new packet.list(); - - var secretKeyPacket = new packet.secret_key(); - secretKeyPacket.algorithm = enums.read(enums.publicKey, keyType); - secretKeyPacket.generate(numBits); - secretKeyPacket.encrypt(passphrase); - - var userIdPacket = new packet.userid(); - userIdPacket.read(userId); - - var dataToSign = {}; - dataToSign.userid = userIdPacket; - dataToSign.key = secretKeyPacket; - var signaturePacket = new packet.signature(); - signaturePacket.signatureType = enums.signature.cert_generic; - signaturePacket.publicKeyAlgorithm = keyType; - //TODO we should load preferred hash from config, or as input to this function - signaturePacket.hashAlgorithm = enums.hash.sha256; - signaturePacket.keyFlags = [enums.keyFlags.certify_keys | enums.keyFlags.sign_data]; - signaturePacket.sign(secretKeyPacket, dataToSign); - - var secretSubkeyPacket = new packet.secret_subkey(); - secretSubkeyPacket.algorithm = enums.read(enums.publicKey, keyType); - secretSubkeyPacket.generate(numBits); - secretSubkeyPacket.encrypt(passphrase); - - dataToSign = {}; - dataToSign.key = secretKeyPacket; - dataToSign.bind = secretSubkeyPacket; - var subkeySignaturePacket = new packet.signature(); - subkeySignaturePacket.signatureType = enums.signature.subkey_binding; - subkeySignaturePacket.publicKeyAlgorithm = keyType; - //TODO we should load preferred hash from config, or as input to this function - subkeySignaturePacket.hashAlgorithm = enums.hash.sha256; - subkeySignaturePacket.keyFlags = [enums.keyFlags.encrypt_communication | enums.keyFlags.encrypt_storage]; - subkeySignaturePacket.sign(secretKeyPacket, dataToSign); - - packetlist.push(secretKeyPacket); - packetlist.push(userIdPacket); - packetlist.push(signaturePacket); - packetlist.push(secretSubkeyPacket); - packetlist.push(subkeySignaturePacket); - - return new Key(packetlist); -} - -exports.Key = Key; -exports.readArmored = readArmored; -exports.generate = generate; - -},{"./config":4,"./encoding/armor.js":26,"./enums.js":28,"./packet":36}],31:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); - -/** - * @class - * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. - */ -var keyring = function() { - this.armoredPacketlists = []; - this.parsedPacketlists = []; - - /** - * Initialization routine for the keyring. This method reads the - * keyring from HTML5 local storage and initializes this instance. - * This method is called by openpgp.init(). - */ - function init() { - var armoredPacketlists = JSON.parse(window.localStorage.getItem("armoredPacketlists")); - if (armoredPacketlists === null || armoredPacketlists.length === 0) { - armoredPacketlists = []; - } - this.armoredPacketlists = armoredPacketlists; - - var packetlist; - for (var i = 0; i < armoredPacketlists.length; i++) { - packetlist = new packet.list(); - packetlist.read(armoredPacketlists[i]); - this.parsedPacketlists.push(packetlist); - } - } - this.init = init; - - /** - * Saves the current state of the keyring to HTML5 local storage. - * The privateKeys array and publicKeys array gets Stringified using JSON - */ - function store() { - window.localStorage.setItem("armoredPacketlists", JSON.stringify(this.armoredPacketlists)); - } - this.store = store; - - function emailPacketCheck(packet, email) { - var emailMatch = false; - var packetEmail; - email = email.toLowerCase(); - if (packet.tag == enums.packet.userid) { - packetEmail = packet.userid; - //we need to get just the email from the userid packet - packetEmail = packetEmail.split('<')[1].split('<')[0].trim.toLowerCase(); - if (packetEmail == email) { - emailMatch = true; - } - } - return emailMatch; - } - - function idPacketCheck(packet, id) { - if (packet.getKeyId && packet.getKeyId().write() == id) { - return true; - } - return false; - } - - function helperCheckIdentityAndPacketMatch(identityFunction, identityInput, packetType, packetlist) { - var packet; - for (var l = 0; l < packetlist.length; l++) { - packet = packetlist[l]; - identityMatch = identityFunction(packet, identityInput); - if (!packetType) { - packetMatch = true; - } else if (packet.tag == packetType) { - packetMatch = true; - } - if (packetMatch && identityMatch) { - return true; - } - } - return false; - } - - function checkForIdentityAndPacketMatch(identityFunction, identityInput, packetType) { - var results = []; - var packetlist; - var identityMatch; - var packetMatch; - for (var p = 0; p < this.parsedPacketlists.length; p++) { - identityMatch = false; - packetMatch = false; - packetlist = this.parsedPacketlists[p]; - if (helperCheckIdentityAndPacketMatch(identityFunction, identityInput, packetType, packetlist)) { - results.push(packetlist); - } - } - return results; - } - this.checkForIdentityAndPacketMatch = checkForIdentityAndPacketMatch; - - /** - * searches all public keys in the keyring matching the address or address part of the user ids - * @param {String} email_address - * @return {openpgp_msg_publickey[]} The public keys associated with provided email address. - */ - function getPublicKeyForAddress(email) { - return checkForIdentityAndPacketMatch(emailPacketCheck, email, enums.packet.public_key); - } - this.getPublicKeyForAddress = getPublicKeyForAddress; - - /** - * Searches the keyring for a private key containing the specified email address - * @param {String} email_address email address to search for - * @return {openpgp_msg_privatekey[]} private keys found - */ - function getPrivateKeyForAddress(email_address) { - return checkForIdentityAndPacketMatch(emailPacketCheck, email, enums.packet.secret_key); - } - this.getPrivateKeyForAddress = getPrivateKeyForAddress; - - /** - * Searches the keyring for public keys having the specified key id - * @param {String} keyId provided as string of hex number (lowercase) - * @return {openpgp_msg_privatekey[]} public keys found - */ - function getPacketlistsForKeyId(keyId) { - return this.checkForIdentityAndPacketMatch(idPacketCheck, keyId); - } - this.getPacketlistsForKeyId = getPacketlistsForKeyId; - - /** - * Imports a packet list (public or private key block) from an ascii armored message - * @param {String} armored message to read the packets/key from - */ - function importPacketlist(armored) { - this.armoredPacketlists.push(armored); - - var dearmored = armor.decode(armored.replace(/\r/g, '')).data; - - packetlist = new packet.list(); - packetlist.read(dearmored); - this.parsedPacketlists.push(packetlist); - - return true; - } - this.importPacketlist = importPacketlist; - - /** - * TODO - * returns the openpgp_msg_privatekey representation of the public key at public key ring index - * @param {Integer} index the index of the public key within the publicKeys array - * @return {openpgp_msg_privatekey} the public key object - */ - function exportPublicKey(index) { - return this.publicKey[index]; - } - this.exportPublicKey = exportPublicKey; - - /** - * TODO - * Removes a public key from the public key keyring at the specified index - * @param {Integer} index the index of the public key within the publicKeys array - * @return {openpgp_msg_privatekey} The public key object which has been removed - */ - function removePublicKey(index) { - var removed = this.publicKeys.splice(index, 1); - this.store(); - return removed; - } - this.removePublicKey = removePublicKey; - -}; - -module.exports = new keyring(); - -},{"./encoding/armor.js":26,"./enums.js":28,"./packet":36}],32:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); -var config = require('./config'); -var crypto = require('./crypto'); -var util = require('./util'); - -/** - * @class - * @classdesc Class that represents an OpenPGP message. - * Can be an encrypted message, signed message, compressed message or literal message - * @param {packetlist} packetlist The packets that form this message - * See http://tools.ietf.org/html/rfc4880#section-11.3 - */ - -function Message(packetlist) { - if (!(this instanceof Message)) { - return new Message(packetlist); - } - this.packets = packetlist || new packet.list(); -} - -/** - * Returns the key IDs of the keys to which the session key is encrypted - * @return {[keyId]} array of keyid objects - */ -Message.prototype.getEncryptionKeyIds = function() { - var keyIds = []; - var pkESKeyPacketlist = this.packets.filterByTag(enums.packet.public_key_encrypted_session_key); - pkESKeyPacketlist.forEach(function(packet) { - keyIds.push(packet.publicKeyId); - }); - return keyIds; -}; - -/** - * Returns the key IDs of the keys that signed the message - * @return {[keyId]} array of keyid objects - */ -Message.prototype.getSigningKeyIds = function() { - var keyIds = []; - var msg = this.unwrapCompressed(); - // search for one pass signatures - var onePassSigList = msg.packets.filterByTag(enums.packet.one_pass_signature); - onePassSigList.forEach(function(packet) { - keyIds.push(packet.signingKeyId); - }); - // if nothing found look for signature packets - if (!keyIds.length) { - var signatureList = msg.packets.filterByTag(enums.packet.signature); - signatureList.forEach(function(packet) { - keyIds.push(packet.issuerKeyId); - }); - } - return keyIds; -}; - -/** - * Decrypt the message - * @param {key} privateKey private key with decrypted secret data - * @return {[message]} new message with decrypted content - */ -Message.prototype.decrypt = function(privateKey) { - var encryptionKeyIds = this.getEncryptionKeyIds(); - if (!encryptionKeyIds.length) { - // nothing to decrypt return unmodified message - return this; - } - var privateKeyPacket = privateKey.getPrivateKeyPacket(encryptionKeyIds); - if (!privateKeyPacket.isDecrypted) throw new Error('Private key is not decrypted.'); - var pkESKeyPacketlist = this.packets.filterByTag(enums.packet.public_key_encrypted_session_key); - var pkESKeyPacket; - for (var i = 0; i < pkESKeyPacketlist.length; i++) { - if (pkESKeyPacketlist[i].publicKeyId.equals(privateKeyPacket.getKeyId())) { - pkESKeyPacket = pkESKeyPacketlist[i]; - pkESKeyPacket.decrypt(privateKeyPacket); - break; - } - } - if (pkESKeyPacket) { - var symEncryptedPacketlist = this.packets.filterByTag(enums.packet.symmetrically_encrypted, enums.packet.sym_encrypted_integrity_protected); - if (symEncryptedPacketlist.length !== 0) { - var symEncryptedPacket = symEncryptedPacketlist[0]; - symEncryptedPacket.decrypt(pkESKeyPacket.sessionKeyAlgorithm, pkESKeyPacket.sessionKey); - return new Message(symEncryptedPacket.packets); - } - } -}; - -/** - * Get literal data that is the body of the message - * @return {String|null} literal body of the message as string - */ -Message.prototype.getLiteralData = function() { - var literal = this.packets.findPacket(enums.packet.literal); - return literal && literal.data || null; -}; - -/** - * Get literal data as text - * @return {String|null} literal body of the message interpreted as text - */ -Message.prototype.getText = function() { - var literal = this.packets.findPacket(enums.packet.literal); - if (literal) { - return literal.getText(); - } else { - return null; - } -}; - -/** - * Encrypt the message - * @param {[key]} keys array of keys, used to encrypt the message - * @return {[message]} new message with encrypted content - */ -Message.prototype.encrypt = function(keys) { - var packetlist = new packet.list(); - //TODO get preferred algo from signature - var sessionKey = crypto.generateSessionKey(enums.read(enums.symmetric, config.encryption_cipher)); - keys.forEach(function(key) { - var encryptionKeyPacket = key.getEncryptionKeyPacket(); - if (encryptionKeyPacket) { - var pkESKeyPacket = new packet.public_key_encrypted_session_key(); - pkESKeyPacket.publicKeyId = encryptionKeyPacket.getKeyId(); - pkESKeyPacket.publicKeyAlgorithm = encryptionKeyPacket.algorithm; - pkESKeyPacket.sessionKey = sessionKey; - //TODO get preferred algo from signature - pkESKeyPacket.sessionKeyAlgorithm = enums.read(enums.symmetric, config.encryption_cipher); - pkESKeyPacket.encrypt(encryptionKeyPacket); - packetlist.push(pkESKeyPacket); - } - }); - var symEncryptedPacket; - if (config.integrity_protect) { - symEncryptedPacket = new packet.sym_encrypted_integrity_protected(); - } else { - symEncryptedPacket = new packet.symmetrically_encrypted(); - } - symEncryptedPacket.packets = this.packets; - //TODO get preferred algo from signature - symEncryptedPacket.encrypt(enums.read(enums.symmetric, config.encryption_cipher), sessionKey); - packetlist.push(symEncryptedPacket); - return new Message(packetlist); -}; - -/** - * Sign the message (the literal data packet of the message) - * @param {[key]} privateKey private keys with decrypted secret key data for signing - * @return {message} new message with signed content - */ -Message.prototype.sign = function(privateKeys) { - - var packetlist = new packet.list(); - - var literalDataPacket = this.packets.findPacket(enums.packet.literal); - if (!literalDataPacket) throw new Error('No literal data packet to sign.'); - - var literalFormat = enums.write(enums.literal, literalDataPacket.format); - var signatureType = literalFormat == enums.literal.binary - ? enums.signature.binary : enums.signature.text; - - for (var i = 0; i < privateKeys.length; i++) { - var onePassSig = new packet.one_pass_signature(); - onePassSig.type = signatureType; - //TODO get preferred hashg algo from key signature - onePassSig.hashAlgorithm = config.prefer_hash_algorithm; - var signingKeyPacket = privateKeys[i].getSigningKeyPacket(); - onePassSig.publicKeyAlgorithm = signingKeyPacket.algorithm; - onePassSig.signingKeyId = signingKeyPacket.getKeyId(); - packetlist.push(onePassSig); - } - - packetlist.push(literalDataPacket); - - for (var i = privateKeys.length - 1; i >= 0; i--) { - var signaturePacket = new packet.signature(); - signaturePacket.signatureType = signatureType; - signaturePacket.hashAlgorithm = config.prefer_hash_algorithm; - signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm; - if (!signingKeyPacket.isDecrypted) throw new Error('Private key is not decrypted.'); - signaturePacket.sign(signingKeyPacket, literalDataPacket); - packetlist.push(signaturePacket); - } - - return new Message(packetlist); -}; - -/** - * Verify message signatures - * @param {[key]} publicKeys public keys to verify signatures - * @return {[{'keyid': keyid, 'valid': Boolean}]} list of signer's keyid and validity of signature - */ -Message.prototype.verify = function(publicKeys) { - var result = []; - var msg = this.unwrapCompressed(); - var literalDataList = msg.packets.filterByTag(enums.packet.literal); - if (literalDataList.length !== 1) throw new Error('Can only verify message with one literal data packet.'); - var signatureList = msg.packets.filterByTag(enums.packet.signature); - publicKeys.forEach(function(pubKey) { - for (var i = 0; i < signatureList.length; i++) { - var publicKeyPacket = pubKey.getPublicKeyPacket([signatureList[i].issuerKeyId]); - if (publicKeyPacket) { - var verifiedSig = {}; - verifiedSig.keyid = signatureList[i].issuerKeyId; - verifiedSig.status = signatureList[i].verify(publicKeyPacket, literalDataList[0]); - result.push(verifiedSig); - break; - } - } - }); - return result; -}; - -/** - * Unwrap compressed message - * @return {message} message Content of compressed message - */ -Message.prototype.unwrapCompressed = function() { - var compressed = this.packets.filterByTag(enums.packet.compressed); - if (compressed.length) { - return new Message(compressed[0].packets); - } else { - return this; - } -}; - -/** - * Returns ASCII armored text of message - * @return {String} ASCII armor - */ -Message.prototype.armor = function() { - return armor.encode(enums.armor.message, this.packets.write()); -}; - -/** - * reads an OpenPGP armored message and returns a message object - * @param {String} armoredText text to be parsed - * @return {message} new message object - */ -function readArmored(armoredText) { - //TODO how do we want to handle bad text? Exception throwing - //TODO don't accept non-message armored texts - var input = armor.decode(armoredText).data; - var packetlist = new packet.list(); - packetlist.read(input); - var newMessage = new Message(packetlist); - return newMessage; -} - -/** - * creates new message object from text - * @param {String} text - * @return {message} new message object - */ -function fromText(text) { - var literalDataPacket = new packet.literal(); - // text will be converted to UTF8 - literalDataPacket.setText(text); - var literalDataPacketlist = new packet.list(); - literalDataPacketlist.push(literalDataPacket); - var newMessage = new Message(literalDataPacketlist); - return newMessage; -} - -/** - * creates new message object from binary data - * @param {String} bytes - * @return {message} new message object - */ -function fromBinary(bytes) { - var literalDataPacket = new packet.literal(); - literalDataPacket.setBytes(bytes, enums.read(enums.literal, enums.literal.binary)); - var literalDataPacketlist = new packet.list(); - literalDataPacketlist.push(literalDataPacket); - var newMessage = new Message(literalDataPacketlist); - return newMessage; -} - -exports.Message = Message; -exports.readArmored = readArmored; -exports.fromText = fromText; - -},{"./config":4,"./crypto":17,"./encoding/armor.js":26,"./enums.js":28,"./packet":36,"./util":57}],33:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @fileoverview The openpgp base module should provide all of the functionality - * to consume the openpgp.js library. All additional classes are documented - * for extending and developing on top of the base library. - */ - -var armor = require('./encoding/armor.js'); -var packet = require('./packet'); -var enums = require('./enums.js'); -var config = require('./config'); -var message = require('./message.js'); -var cleartext = require('./cleartext.js'); -var key = require('./key.js'); - - -/** - * Encrypts message text with keys - * @param {[key]} keys array of keys, used to encrypt the message - * @param {String} text message as native JavaScript string - * @return {String} encrypted ASCII armored message - */ -function encryptMessage(keys, text) { - var msg = message.fromText(text); - msg = msg.encrypt(keys); - var armored = armor.encode(enums.armor.message, msg.packets.write()); - return armored; -} - -/** - * Signs message text and encrypts it - * @param {[key]} publicKeys array of keys, used to encrypt the message - * @param {key} privateKey private key with decrypted secret key data for signing - * @param {String} text message as native JavaScript string - * @return {String} encrypted ASCII armored message - */ -function signAndEncryptMessage(publicKeys, privateKey, text) { - var msg = message.fromText(text); - msg = msg.sign([privateKey]); - msg = msg.encrypt(publicKeys); - var armored = armor.encode(enums.armor.message, msg.packets.write()); - return armored; -} - -/** - * Decrypts message - * @param {key} privateKey private key with decrypted secret key data - * @param {message} message the message object with the encrypted data - * @return {String|null} decrypted message as as native JavaScript string - * or null if no literal data found - */ -function decryptMessage(privateKey, message) { - message = message.decrypt(privateKey); - return message.getText(); -} - -/** - * Decrypts message and verifies signatures - * @param {key} privateKey private key with decrypted secret key data - * @param {[key]} publicKeys public keys to verify signatures - * @param {message} message the message object with signed and encrypted data - * @return {{'text': String, signatures: [{'keyid': keyid, 'status': Boolean}]}} - * decrypted message as as native JavaScript string - * with verified signatures or null if no literal data found - */ -function decryptAndVerifyMessage(privateKey, publicKeys, message) { - var result = {}; - message = message.decrypt(privateKey); - result.text = message.getText(); - if (result.text) { - result.signatures = message.verify(publicKeys); - return result; - } - return null; -} - -/** - * Signs a cleartext message - * @param {[Key]} privateKeys private key with decrypted secret key data to sign cleartext - * @param {String} text cleartext - * @return {String} ASCII armored message - */ -function signClearMessage(privateKeys, text) { - var cleartextMessage = new cleartext.CleartextMessage(text); - cleartextMessage.sign(privateKeys); - return cleartextMessage.armor(); -} - -/** - * Verifies signatures of cleartext signed message - * @param {[Key]} publicKeys public keys to verify signatures - * @param {CleartextMessage} message cleartext message object with signatures - * @return {{'text': String, signatures: [{'keyid': keyid, 'status': Boolean}]}} - * cleartext with status of verified signatures - */ -function verifyClearSignedMessage(publicKeys, message) { - var result = {}; - if (!(message instanceof cleartext.CleartextMessage)) { - throw new Error('Parameter [message] needs to be of type CleartextMessage.'); - } - result.text = message.getText(); - result.signatures = message.verify(publicKeys); - return result; -} - -/** - * Generates a new OpenPGP key pair. Currently only supports RSA keys. - * Primary and subkey will be of same type. - * @param {Integer} keyType to indicate what type of key to make. - * RSA is 1. See http://tools.ietf.org/html/rfc4880#section-9.1 - * @param {Integer} numBits number of bits for the key creation. (should be 1024+, generally) - * @param {String} userId assumes already in form of "User Name <username@email.com>" - * @param {String} passphrase The passphrase used to encrypt the resulting private key - * @return {Object} {key: [Key], privateKeyArmored: [String], publicKeyArmored: [String]} - */ -function generateKeyPair(keyType, numBits, userId, passphrase) { - var result = {}; - var newKey = key.generate(keyType, numBits, userId, passphrase); - result.key = newKey; - result.privateKeyArmored = newKey.armor(); - result.publicKeyArmored = newKey.toPublic().armor(); - return result; -} - -exports.encryptMessage = encryptMessage; -exports.signAndEncryptMessage = signAndEncryptMessage; -exports.decryptMessage = decryptMessage; -exports.decryptAndVerifyMessage = decryptAndVerifyMessage -exports.signClearMessage = signClearMessage; -exports.verifyClearSignedMessage = verifyClearSignedMessage; -exports.generateKeyPair = generateKeyPair; - -},{"./cleartext.js":2,"./config":4,"./encoding/armor.js":26,"./enums.js":28,"./key.js":30,"./message.js":32,"./packet":36}],34:[function(require,module,exports){ -var enums = require('../enums.js'); - -// This is pretty ugly, but browserify needs to have the requires explicitly written. -module.exports = { - compressed: require('./compressed.js'), - sym_encrypted_integrity_protected: require('./sym_encrypted_integrity_protected.js'), - public_key_encrypted_session_key: require('./public_key_encrypted_session_key.js'), - sym_encrypted_session_key: require('./sym_encrypted_session_key.js'), - literal: require('./literal.js'), - public_key: require('./public_key.js'), - symmetrically_encrypted: require('./symmetrically_encrypted.js'), - marker: require('./marker.js'), - public_subkey: require('./public_subkey.js'), - user_attribute: require('./user_attribute.js'), - one_pass_signature: require('./one_pass_signature.js'), - secret_key: require('./secret_key.js'), - userid: require('./userid.js'), - secret_subkey: require('./secret_subkey.js'), - signature: require('./signature.js'), - trust: require('./trust.js') -} - -for (var i in enums.packet) { - var packetClass = module.exports[i]; - - if (packetClass != undefined) - packetClass.prototype.tag = enums.packet[i]; -} - -},{"../enums.js":28,"./compressed.js":35,"./literal.js":37,"./marker.js":38,"./one_pass_signature.js":39,"./public_key.js":42,"./public_key_encrypted_session_key.js":43,"./public_subkey.js":44,"./secret_key.js":45,"./secret_subkey.js":46,"./signature.js":47,"./sym_encrypted_integrity_protected.js":48,"./sym_encrypted_session_key.js":49,"./symmetrically_encrypted.js":50,"./trust.js":51,"./user_attribute.js":52,"./userid.js":53}],35:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var enums = require('../enums.js'), - JXG = require('../compression/jxg.js'), - base64 = require('../encoding/base64.js'); - -/** - * @class - * @classdesc Implementation of the Compressed Data Packet (Tag 8) - * - * RFC4880 5.6: - * The Compressed Data packet contains compressed data. Typically, this - * packet is found as the contents of an encrypted packet, or following - * a Signature or One-Pass Signature packet, and contains a literal data - * packet. - */ -module.exports = function packet_compressed() { - /** @type {packetlist} */ - this.packets; - /** @type {compression} */ - this.algorithm = 'uncompressed'; - - this.compressed = null; - - - /** - * Parsing function for the packet. - * @param {String} input Payload of a tag 8 packet - * @param {Integer} position Position to start reading from the input string - * @parAM {iNTEGER} LEN lENGTH OF the packet or the remaining length of - * input at position - * @return {openpgp_packet_compressed} Object representation - */ - this.read = function(bytes) { - // One octet that gives the algorithm used to compress the packet. - this.algorithm = enums.read(enums.compression, bytes.charCodeAt(0)); - - // Compressed data, which makes up the remainder of the packet. - this.compressed = bytes.substr(1); - - this.decompress(); - } - - - - this.write = function() { - if (this.compressed == null) - this.compress(); - - return String.fromCharCode(enums.write(enums.compression, this.algorithm)) + this.compressed; - } - - - /** - * Decompression method for decompressing the compressed data - * read by read_packet - * @return {String} The decompressed data - */ - this.decompress = function() { - var decompressed; - - switch (this.algorithm) { - case 'uncompressed': - decompressed = this.compressed; - break; - - case 'zip': - var compData = this.compressed; - - var radix = base64.encode(compData).replace(/\n/g, ""); - // no header in this case, directly call deflate - var jxg_obj = new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(radix)); - - decompressed = unescape(jxg_obj.deflate()[0][0]); - break; - - case 'zlib': - //RFC 1950. Bits 0-3 Compression Method - var compressionMethod = this.compressed.charCodeAt(0) % 0x10; - - //Bits 4-7 RFC 1950 are LZ77 Window. Generally this value is 7 == 32k window size. - // 2nd Byte in RFC 1950 is for "FLAGs" Allows for a Dictionary - // (how is this defined). Basic checksum, and compression level. - - if (compressionMethod == 8) { //CM 8 is for DEFLATE, RFC 1951 - // remove 4 bytes ADLER32 checksum from the end - var compData = this.compressed.substring(0, this.compressed.length - 4); - var radix = base64.encode(compData).replace(/\n/g, ""); - //TODO check ADLER32 checksum - decompressed = JXG.decompress(radix); - break; - - } else { - util.print_error("Compression algorithm ZLIB only supports " + - "DEFLATE compression method."); - } - break; - - case 'bzip2': - // TODO: need to implement this - throw new Error('Compression algorithm BZip2 [BZ2] is not implemented.'); - break; - - default: - throw new Error("Compression algorithm unknown :" + this.alogrithm); - break; - } - - this.packets.read(decompressed); - } - - /** - * Compress the packet data (member decompressedData) - * @param {Integer} type Algorithm to be used // See RFC 4880 9.3 - * @param {String} data Data to be compressed - * @return {String} The compressed data stored in attribute compressedData - */ - this.compress = function() { - switch (this.algorithm) { - - case 'uncompressed': - // - Uncompressed - this.compressed = this.packets.write(); - break; - - case 'zip': - // - ZIP [RFC1951] - util.print_error("Compression algorithm ZIP [RFC1951] is not implemented."); - break; - - case 'zlib': - // - ZLIB [RFC1950] - // TODO: need to implement this - util.print_error("Compression algorithm ZLIB [RFC1950] is not implemented."); - break; - - case 'bzip2': - // - BZip2 [BZ2] - // TODO: need to implement this - util.print_error("Compression algorithm BZip2 [BZ2] is not implemented."); - break; - - default: - util.print_error("Compression algorithm unknown :" + this.type); - break; - } - } -}; - -},{"../compression/jxg.js":3,"../encoding/base64.js":27,"../enums.js":28}],36:[function(require,module,exports){ -var enums = require('../enums.js'); - -module.exports = { - list: require('./packetlist.js'), -}; - -var packets = require('./all_packets.js'); - -for (var i in packets) - module.exports[i] = packets[i]; - -},{"../enums.js":28,"./all_packets.js":34,"./packetlist.js":41}],37:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var util = require('../util'), - enums = require('../enums.js'); - -/** - * @class - * @classdesc Implementation of the Literal Data Packet (Tag 11) - * - * RFC4880 5.9: A Literal Data packet contains the body of a message; data that - * is not to be further interpreted. - */ -module.exports = function packet_literal() { - this.format = 'utf8'; // default format for literal data packets - this.data = ''; // literal data representation as native JavaScript string or bytes - this.date = new Date(); - - - /** - * Set the packet data to a javascript native string, end of line - * will be normalized to \r\n and by default text is converted to UTF8 - * @param {String} text Any native javascript string - */ - this.setText = function(text) { - // normalize EOL to \r\n - text = text.replace(/\r/g, '').replace(/\n/g, '\r\n'); - // encode UTF8 - this.data = this.format == 'utf8' ? util.encode_utf8(text) : text; - } - - /** - * Returns literal data packets as native JavaScript string - * with normalized end of line to \n - * @return {String} literal data as text - */ - this.getText = function() { - // decode UTF8 - var text = util.decode_utf8(this.data); - // normalize EOL to \n - return text.replace(/\r\n/g, '\n'); - } - - /** - * Set the packet data to value represented by the provided string of bytes. - * @param {String} bytes The string of bytes - * @param {'utf8|'binary'|'text'} format The format of the string of bytes - */ - this.setBytes = function(bytes, format) { - this.format = format; - this.data = bytes; - } - - - /** - * Get the byte sequence representing the literal packet data - * @returns {String} A sequence of bytes - */ - this.getBytes = function() { - return this.data; - } - - - /** - * Parsing function for a literal data packet (tag 11). - * - * @param {String} input Payload of a tag 11 packet - * @param {Integer} position - * Position to start reading from the input string - * @param {Integer} len - * Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encrypteddata} object representation - */ - this.read = function(bytes) { - // - A one-octet field that describes how the data is formatted. - - var format = enums.read(enums.literal, bytes.charCodeAt(0)); - - var filename_len = bytes.charCodeAt(1); - this.filename = util.decode_utf8(bytes.substr(2, filename_len)); - - this.date = util.readDate(bytes.substr(2 + filename_len, 4)); - - var data = bytes.substring(6 + filename_len); - - this.setBytes(data, format); - } - - /** - * Creates a string representation of the packet - * - * @param {String} data The data to be inserted as body - * @return {String} string-representation of the packet - */ - this.write = function() { - var filename = util.encode_utf8("msg.txt"); - - var data = this.getBytes(); - - var result = ''; - result += String.fromCharCode(enums.write(enums.literal, this.format)); - result += String.fromCharCode(filename.length); - result += filename; - result += util.writeDate(this.date); - result += data; - return result; - } -} - -},{"../enums.js":28,"../util":57}],38:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the strange "Marker packet" (Tag 10) - * - * RFC4880 5.8: An experimental version of PGP used this packet as the Literal - * packet, but no released version of PGP generated Literal packets with this - * tag. With PGP 5.x, this packet has been reassigned and is reserved for use as - * the Marker packet. - * - * Such a packet MUST be ignored when received. - */ -function packet_marker() { - /** - * Parsing function for a literal data packet (tag 10). - * - * @param {String} input Payload of a tag 10 packet - * @param {Integer} position - * Position to start reading from the input string - * @param {Integer} len - * Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encrypteddata} Object representation - */ - this.read = function(bytes) { - if (bytes.charCodeAt(0) == 0x50 && // P - bytes.charCodeAt(1) == 0x47 && // G - bytes.charCodeAt(2) == 0x50) // P - return true; - // marker packet does not contain "PGP" - return false; - } -} - -module.exports = packet_marker; - -},{}],39:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the One-Pass Signature Packets (Tag 4) - * - * RFC4880 5.4: - * The One-Pass Signature packet precedes the signed data and contains - * enough information to allow the receiver to begin calculating any - * hashes needed to verify the signature. It allows the Signature - * packet to be placed at the end of the message, so that the signer - * can compute the entire signed message in one pass. - */ - -var enums = require('../enums.js'), - type_keyid = require('../type/keyid.js'); - -module.exports = function packet_one_pass_signature() { - this.version = null; // A one-octet version number. The current version is 3. - this.type = null; // A one-octet signature type. Signature types are described in RFC4880 Section 5.2.1. - this.hashAlgorithm = null; // A one-octet number describing the hash algorithm used. (See RFC4880 9.4) - this.publicKeyAlgorithm = null; // A one-octet number describing the public-key algorithm used. (See RFC4880 9.1) - this.signingKeyId = null; // An eight-octet number holding the Key ID of the signing key. - this.flags = null; // A one-octet number holding a flag showing whether the signature is nested. A zero value indicates that the next packet is another One-Pass Signature packet that describes another signature to be applied to the same message data. - - /** - * parsing function for a one-pass signature packet (tag 4). - * @param {String} bytes payload of a tag 4 packet - * @return {packet_one_pass_signature} object representation - */ - this.read = function(bytes) { - var mypos = 0; - // A one-octet version number. The current version is 3. - this.version = bytes.charCodeAt(mypos++); - - // A one-octet signature type. Signature types are described in - // Section 5.2.1. - this.type = enums.read(enums.signature, bytes.charCodeAt(mypos++)); - - // A one-octet number describing the hash algorithm used. - this.hashAlgorithm = enums.read(enums.hash, bytes.charCodeAt(mypos++)); - - // A one-octet number describing the public-key algorithm used. - this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes.charCodeAt(mypos++)); - - // An eight-octet number holding the Key ID of the signing key. - this.signingKeyId = new type_keyid(); - this.signingKeyId.read(bytes.substr(mypos)); - mypos += 8; - - // A one-octet number holding a flag showing whether the signature - // is nested. A zero value indicates that the next packet is - // another One-Pass Signature packet that describes another - // signature to be applied to the same message data. - this.flags = bytes.charCodeAt(mypos++); - return this; - } - - /** - * creates a string representation of a one-pass signature packet - * @return {String} a string representation of a one-pass signature packet - */ - this.write = function() { - var result = ""; - - result += String.fromCharCode(3); - result += String.fromCharCode(enums.write(enums.signature, this.type)); - result += String.fromCharCode(enums.write(enums.hash, this.hashAlgorithm)); - result += String.fromCharCode(enums.write(enums.publicKey, this.publicKeyAlgorithm)); - result += this.signingKeyId.write(); - result += String.fromCharCode(this.flags); - - return result; - } -}; - -},{"../enums.js":28,"../type/keyid.js":54}],40:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var enums = require('../enums.js'), - util = require('../util'); - - -module.exports = { - readSimpleLength: function(bytes) { - var len = 0, - offset, - type = bytes.charCodeAt(0); - - - if (type < 192) { - len = bytes.charCodeAt(0); - offset = 1; - } else if (type < 255) { - len = ((bytes.charCodeAt(0) - 192) << 8) + (bytes.charCodeAt(1)) + 192; - offset = 2; - } else if (type == 255) { - len = util.readNumber(bytes.substr(1, 4)); - offset = 5; - } - - return { - len: len, - offset: offset - }; - }, - - /** - * Encodes a given integer of length to the openpgp length specifier to a - * string - * - * @param {Integer} length The length to encode - * @return {String} String with openpgp length representation - */ - writeSimpleLength: function(length) { - var result = ""; - if (length < 192) { - result += String.fromCharCode(length); - } else if (length > 191 && length < 8384) { - /* - * let a = (total data packet length) - 192 let bc = two octet - * representation of a let d = b + 192 - */ - result += String.fromCharCode(((length - 192) >> 8) + 192); - result += String.fromCharCode((length - 192) & 0xFF); - } else { - result += String.fromCharCode(255); - result += util.writeNumber(length, 4); - } - return result; - }, - - /** - * Writes a packet header version 4 with the given tag_type and length to a - * string - * - * @param {Integer} tag_type Tag type - * @param {Integer} length Length of the payload - * @return {String} String of the header - */ - writeHeader: function(tag_type, length) { - /* we're only generating v4 packet headers here */ - var result = ""; - result += String.fromCharCode(0xC0 | tag_type); - result += this.writeSimpleLength(length); - return result; - }, - - /** - * Writes a packet header Version 3 with the given tag_type and length to a - * string - * - * @param {Integer} tag_type Tag type - * @param {Integer} length Length of the payload - * @return {String} String of the header - */ - writeOldHeader: function(tag_type, length) { - var result = ""; - if (length < 256) { - result += String.fromCharCode(0x80 | (tag_type << 2)); - result += String.fromCharCode(length); - } else if (length < 65536) { - result += String.fromCharCode(0x80 | (tag_type << 2) | 1); - result += util.writeNumber(length, 2); - } else { - result += String.fromCharCode(0x80 | (tag_type << 2) | 2); - result += util.writeNumber(length, 4); - } - return result; - }, - - /** - * Generic static Packet Parser function - * - * @param {String} input Input stream as string - * @param {integer} position Position to start parsing - * @param {integer} len Length of the input from position on - * @return {Object} Returns a parsed openpgp_packet - */ - read: function(input, position, len) { - // some sanity checks - if (input == null || input.length <= position || input.substring(position).length < 2 || (input.charCodeAt(position) & - 0x80) == 0) { - util - .print_error("Error during parsing. This message / key is probably not containing a valid OpenPGP format."); - return null; - } - var mypos = position; - var tag = -1; - var format = -1; - var packet_length; - - format = 0; // 0 = old format; 1 = new format - if ((input.charCodeAt(mypos) & 0x40) != 0) { - format = 1; - } - - var packet_length_type; - if (format) { - // new format header - tag = input.charCodeAt(mypos) & 0x3F; // bit 5-0 - } else { - // old format header - tag = (input.charCodeAt(mypos) & 0x3F) >> 2; // bit 5-2 - packet_length_type = input.charCodeAt(mypos) & 0x03; // bit 1-0 - } - - // header octet parsing done - mypos++; - - // parsed length from length field - var bodydata = null; - - // used for partial body lengths - var real_packet_length = -1; - if (!format) { - // 4.2.1. Old Format Packet Lengths - switch (packet_length_type) { - case 0: - // The packet has a one-octet length. The header is 2 octets - // long. - packet_length = input.charCodeAt(mypos++); - break; - case 1: - // The packet has a two-octet length. The header is 3 octets - // long. - packet_length = (input.charCodeAt(mypos++) << 8) | input.charCodeAt(mypos++); - break; - case 2: - // The packet has a four-octet length. The header is 5 - // octets long. - packet_length = (input.charCodeAt(mypos++) << 24) | (input.charCodeAt(mypos++) << 16) | (input.charCodeAt(mypos++) << - 8) | input.charCodeAt(mypos++); - break; - default: - // 3 - The packet is of indeterminate length. The header is 1 - // octet long, and the implementation must determine how long - // the packet is. If the packet is in a file, this means that - // the packet extends until the end of the file. In general, - // an implementation SHOULD NOT use indeterminate-length - // packets except where the end of the data will be clear - // from the context, and even then it is better to use a - // definite length, or a new format header. The new format - // headers described below have a mechanism for precisely - // encoding data of indeterminate length. - packet_length = len; - break; - } - - } else // 4.2.2. New Format Packet Lengths - { - - // 4.2.2.1. One-Octet Lengths - if (input.charCodeAt(mypos) < 192) { - packet_length = input.charCodeAt(mypos++); - util.print_debug("1 byte length:" + packet_length); - // 4.2.2.2. Two-Octet Lengths - } else if (input.charCodeAt(mypos) >= 192 && input.charCodeAt(mypos) < 224) { - packet_length = ((input.charCodeAt(mypos++) - 192) << 8) + (input.charCodeAt(mypos++)) + 192; - util.print_debug("2 byte length:" + packet_length); - // 4.2.2.4. Partial Body Lengths - } else if (input.charCodeAt(mypos) > 223 && input.charCodeAt(mypos) < 255) { - packet_length = 1 << (input.charCodeAt(mypos++) & 0x1F); - util.print_debug("4 byte length:" + packet_length); - // EEEK, we're reading the full data here... - var mypos2 = mypos + packet_length; - bodydata = input.substring(mypos, mypos + packet_length); - while (true) { - if (input.charCodeAt(mypos2) < 192) { - var tmplen = input.charCodeAt(mypos2++); - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - break; - } else if (input.charCodeAt(mypos2) >= 192 && input.charCodeAt(mypos2) < 224) { - var tmplen = ((input.charCodeAt(mypos2++) - 192) << 8) + (input.charCodeAt(mypos2++)) + 192; - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - break; - } else if (input.charCodeAt(mypos2) > 223 && input.charCodeAt(mypos2) < 255) { - var tmplen = 1 << (input.charCodeAt(mypos2++) & 0x1F); - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - } else { - mypos2++; - var tmplen = (input.charCodeAt(mypos2++) << 24) | (input.charCodeAt(mypos2++) << 16) | (input[mypos2++] - .charCodeAt() << 8) | input.charCodeAt(mypos2++); - bodydata += input.substring(mypos2, mypos2 + tmplen); - packet_length += tmplen; - mypos2 += tmplen; - break; - } - } - real_packet_length = mypos2; - // 4.2.2.3. Five-Octet Lengths - } else { - mypos++; - packet_length = (input.charCodeAt(mypos++) << 24) | (input.charCodeAt(mypos++) << 16) | (input.charCodeAt(mypos++) << - 8) | input.charCodeAt(mypos++); - } - } - - // if there was'nt a partial body length: use the specified - // packet_length - if (real_packet_length == -1) { - real_packet_length = packet_length; - } - - if (bodydata == null) { - bodydata = input.substring(mypos, mypos + real_packet_length); - } - - return { - tag: tag, - packet: bodydata, - offset: mypos + real_packet_length - }; - } -} - -},{"../enums.js":28,"../util":57}],41:[function(require,module,exports){ -var packetParser = require('./packet.js'), - packets = require('./all_packets.js'), - enums = require('../enums.js'); - -/** - * @class - * @classdesc This class represents a list of openpgp packets. - * Take care when iterating over it - the packets themselves - * are stored as numerical indices. - */ -module.exports = function packetlist() { - /** The number of packets contained within the list. - * @readonly - * @type {Integer} */ - this.length = 0; - - /** - * Reads a stream of binary data and interprents it as a list of packets. - * @param {openpgp_bytearray} An array of bytes. - */ - this.read = function(bytes) { - var i = 0; - - while (i < bytes.length) { - var parsed = packetParser.read(bytes, i, bytes.length - i); - i = parsed.offset; - - var tag = enums.read(enums.packet, parsed.tag); - var packet = new packets[tag](); - - this.push(packet); - - packet.read(parsed.packet); - } - } - - /** - * Creates a binary representation of openpgp objects contained within the - * class instance. - * @returns {openpgp_bytearray} An array of bytes containing valid openpgp packets. - */ - this.write = function() { - var bytes = ''; - - for (var i = 0; i < this.length; i++) { - var packetbytes = this[i].write(); - bytes += packetParser.writeHeader(this[i].tag, packetbytes.length); - bytes += packetbytes; - } - - return bytes; - } - - /** - * Adds a packet to the list. This is the only supported method of doing so; - * writing to packetlist[i] directly will result in an error. - */ - this.push = function(packet) { - packet.packets = packet.packets || new packetlist(); - - this[this.length] = packet; - this.length++; - } - - /** - * Creates a new packetList with all packets that pass the test implemented by the provided function. - */ - this.filter = function(callback) { - - var filtered = new packetlist(); - - for (var i = 0; i < this.length; i++) { - if (callback(this[i], i, this)) { - filtered.push(this[i]); - } - } - - return filtered; - } - - /** - * Creates a new packetList with all packets from the given types - */ - this.filterByTag = function() { - var args = Array.prototype.slice.call(arguments); - var filtered = new packetlist(); - var that = this; - - for (var i = 0; i < this.length; i++) { - if (args.some(function(packetType) {return that[i].tag == packetType})) { - filtered.push(this[i]); - } - } - - return filtered; - } - - /** - * Executes the provided callback once for each element - */ - this.forEach = function(callback) { - for (var i = 0; i < this.length; i++) { - callback(this[i]); - } - } - - /** - * Traverses packet tree and returns first matching packet - * @param {enums.packet} type The packet type - * @return {packet|null} - */ - this.findPacket = function(type) { - var packetlist = this.filterByTag(type); - if (packetlist.length) { - return packetlist[0]; - } else { - var found = null; - for (var i = 0; i < this.length; i++) { - if (this[i].packets.length) { - found = this[i].packets.findPacket(type); - if (found) return found; - } - } - } - return null; - } - -} - -},{"../enums.js":28,"./all_packets.js":34,"./packet.js":40}],42:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var util = require('../util'), - type_mpi = require('../type/mpi.js'), - type_keyid = require('../type/keyid.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - -/** - * @class - * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) - * - * RFC4480 5.5: - * A key material packet contains all the information about a public or - * private key. There are four variants of this packet type, and two - * major versions. Consequently, this section is complex. - */ -module.exports = function packet_public_key() { - /** Key creation date. - * @type {Date} */ - this.created = new Date(); - /** A list of multiprecision integers - * @type {openpgp_type_mpi} */ - this.mpi = []; - /** Public key algorithm - * @type {openpgp.publickey} */ - this.algorithm = 'rsa_sign'; - - - /** - * Internal Parser for public keys as specified in RFC 4880 section - * 5.5.2 Public-Key Packet Formats - * called by read_tag<num> - * @param {String} input Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet or remaining length of input - * @return {Object} This object with attributes set by the parser - */ - this.readPublicKey = this.read = function(bytes) { - // A one-octet version number (3 or 4). - var version = bytes.charCodeAt(0); - - if (version == 4) { - // - A four-octet number denoting the time that the key was created. - this.created = util.readDate(bytes.substr(1, 4)); - - // - A one-octet number denoting the public-key algorithm of this key. - this.algorithm = enums.read(enums.publicKey, bytes.charCodeAt(5)); - - var mpicount = crypto.getPublicMpiCount(this.algorithm); - this.mpi = []; - - var bmpi = bytes.substr(6); - var p = 0; - - for (var i = 0; i < mpicount && p < bmpi.length; i++) { - - this.mpi[i] = new type_mpi(); - - p += this.mpi[i].read(bmpi.substr(p)) - - if (p > bmpi.length) - util.print_error("openpgp.packet.keymaterial.js\n" + 'error reading MPI @:' + p); - } - - return p + 6; - } else { - throw new Error('Version ' + version + ' of the key packet is unsupported.'); - } - } - - /* - * Same as write_private_key, but has less information because of - * public key. - * @param {Integer} keyType Follows the OpenPGP algorithm standard, - * IE 1 corresponds to RSA. - * @param {RSA.keyObject} key - * @param timePacket - * @return {Object} {body: [string]OpenPGP packet body contents, - * header: [string] OpenPGP packet header, string: [string] header+body} - */ - this.writePublicKey = this.write = function() { - // Version - var result = String.fromCharCode(4); - result += util.writeDate(this.created); - result += String.fromCharCode(enums.write(enums.publicKey, this.algorithm)); - - var mpicount = crypto.getPublicMpiCount(this.algorithm); - - for (var i = 0; i < mpicount; i++) { - result += this.mpi[i].write(); - } - - return result; - } - - // Write an old version packet - it's used by some of the internal routines. - this.writeOld = function() { - var bytes = this.writePublicKey(); - - return String.fromCharCode(0x99) + - util.writeNumber(bytes.length, 2) + - bytes; - } - - /** - * Calculates the key id of the key - * @return {String} A 8 byte key id - */ - this.getKeyId = function() { - var keyid = new type_keyid(); - keyid.read(this.getFingerprint().substr(12, 8)); - return keyid; - } - - /** - * Calculates the fingerprint of the key - * @return {String} A string containing the fingerprint - */ - this.getFingerprint = function() { - var toHash = this.writeOld(); - return crypto.hash.sha1(toHash, toHash.length); - } - -} - -},{"../crypto":17,"../enums.js":28,"../type/keyid.js":54,"../type/mpi.js":55,"../util":57}],43:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var type_keyid = require('../type/keyid.js'), - util = require('../util'), - type_mpi = require('../type/mpi.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - - -/** - * @class - * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) - * - * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key - * used to encrypt a message. Zero or more Public-Key Encrypted Session Key - * packets and/or Symmetric-Key Encrypted Session Key packets may precede a - * Symmetrically Encrypted Data Packet, which holds an encrypted message. The - * message is encrypted with the session key, and the session key is itself - * encrypted and stored in the Encrypted Session Key packet(s). The - * Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted - * Session Key packet for each OpenPGP key to which the message is encrypted. - * The recipient of the message finds a session key that is encrypted to their - * public key, decrypts the session key, and then uses the session key to - * decrypt the message. - */ -module.exports = function packet_public_key_encrypted_session_key() { - this.version = 3; - - this.publicKeyId = new type_keyid(); - this.publicKeyAlgorithm = 'rsa_encrypt'; - - this.sessionKey = null; - this.sessionKeyAlgorithm = 'aes256'; - - /** @type {openpgp_type_mpi[]} */ - this.encrypted = []; - - /** - * Parsing function for a publickey encrypted session key packet (tag 1). - * - * @param {String} input Payload of a tag 1 packet - * @param {Integer} position Position to start reading from the input string - * @param {Integer} len Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encrypteddata} Object representation - */ - this.read = function(bytes) { - - this.version = bytes.charCodeAt(0); - this.publicKeyId.read(bytes.substr(1)); - this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes.charCodeAt(9)); - - var i = 10; - - var integerCount = (function(algo) { - switch (algo) { - case 'rsa_encrypt': - case 'rsa_encrypt_sign': - return 1; - - case 'elgamal': - return 2; - - default: - throw new Error("Invalid algorithm."); - } - })(this.publicKeyAlgorithm); - - this.encrypted = []; - - for (var j = 0; j < integerCount; j++) { - var mpi = new type_mpi(); - i += mpi.read(bytes.substr(i)); - this.encrypted.push(mpi); - } - } - - /** - * Create a string representation of a tag 1 packet - * - * @param {String} publicKeyId - * The public key id corresponding to publicMPIs key as string - * @param {openpgp_type_mpi[]} publicMPIs - * Multiprecision integer objects describing the public key - * @param {Integer} pubalgo - * The corresponding public key algorithm // See RFC4880 9.1 - * @param {Integer} symmalgo - * The symmetric cipher algorithm used to encrypt the data - * within an encrypteddatapacket or encryptedintegrity- - * protecteddatapacket - * following this packet //See RFC4880 9.2 - * @param {String} sessionkey - * A string of randombytes representing the session key - * @return {String} The string representation - */ - this.write = function() { - - var result = String.fromCharCode(this.version); - result += this.publicKeyId.write(); - result += String.fromCharCode( - enums.write(enums.publicKey, this.publicKeyAlgorithm)); - - for (var i = 0; i < this.encrypted.length; i++) { - result += this.encrypted[i].write() - } - - return result; - } - - this.encrypt = function(key) { - var data = String.fromCharCode( - enums.write(enums.symmetric, this.sessionKeyAlgorithm)); - - data += this.sessionKey; - var checksum = util.calc_checksum(this.sessionKey); - data += util.writeNumber(checksum, 2); - - var mpi = new type_mpi(); - mpi.fromBytes(crypto.pkcs1.eme.encode( - data, - key.mpi[0].byteLength())); - - this.encrypted = crypto.publicKeyEncrypt( - this.publicKeyAlgorithm, - key.mpi, - mpi); - } - - /** - * Decrypts the session key (only for public key encrypted session key - * packets (tag 1) - * - * @param {openpgp_msg_message} msg - * The message object (with member encryptedData - * @param {openpgp_msg_privatekey} key - * Private key with secMPIs unlocked - * @return {String} The unencrypted session key - */ - this.decrypt = function(key) { - var result = crypto.publicKeyDecrypt( - this.publicKeyAlgorithm, - key.mpi, - this.encrypted).toBytes(); - - var checksum = util.readNumber(result.substr(result.length - 2)); - - var decoded = crypto.pkcs1.eme.decode( - result, - key.mpi[0].byteLength()); - - var key = decoded.substring(1, decoded.length - 2); - - if (checksum != util.calc_checksum(key)) { - throw new Error('Checksum mismatch'); - } else { - this.sessionKey = key; - this.sessionKeyAlgorithm = - enums.read(enums.symmetric, decoded.charCodeAt(0)); - } - } -}; - -},{"../crypto":17,"../enums.js":28,"../type/keyid.js":54,"../type/mpi.js":55,"../util":57}],44:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var public_key = require('./public_key.js'); - -module.exports = function public_subkey() { - public_key.call(this); -} - -},{"./public_key.js":42}],45:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var publicKey = require('./public_key.js'), - enums = require('../enums.js'), - util = require('../util'), - crypto = require('../crypto'), - type_mpi = require('../type/mpi.js'), - type_s2k = require('../type/s2k.js'); - -/** - * @class - * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) - * - * RFC4480 5.5: - * A key material packet contains all the information about a public or - * private key. There are four variants of this packet type, and two - * major versions. Consequently, this section is complex. - */ -function packet_secret_key() { - publicKey.call(this); - // encrypted secret-key data - this.encrypted = null; - // indicator if secret-key data is available in decrypted form - this.isDecrypted = false; - - - function get_hash_len(hash) { - if (hash == 'sha1') - return 20; - else - return 2; - } - - function get_hash_fn(hash) { - if (hash == 'sha1') - return crypto.hash.sha1; - else - return function(c) { - return util.writeNumber(util.calc_checksum(c), 2); - }; - } - - // Helper function - - function parse_cleartext_mpi(hash_algorithm, cleartext, algorithm) { - var hashlen = get_hash_len(hash_algorithm), - hashfn = get_hash_fn(hash_algorithm); - - var hashtext = cleartext.substr(cleartext.length - hashlen); - cleartext = cleartext.substr(0, cleartext.length - hashlen); - - var hash = hashfn(cleartext); - - if (hash != hashtext) - return new Error("Hash mismatch."); - - var mpis = crypto.getPrivateMpiCount(algorithm); - - var j = 0; - var mpi = []; - - for (var i = 0; i < mpis && j < cleartext.length; i++) { - mpi[i] = new type_mpi(); - j += mpi[i].read(cleartext.substr(j)); - } - - return mpi; - } - - function write_cleartext_mpi(hash_algorithm, algorithm, mpi) { - var bytes = ''; - var discard = crypto.getPublicMpiCount(algorithm); - - for (var i = discard; i < mpi.length; i++) { - bytes += mpi[i].write(); - } - - - bytes += get_hash_fn(hash_algorithm)(bytes); - - return bytes; - } - - - // 5.5.3. Secret-Key Packet Formats - - /** - * Internal parser for private keys as specified in RFC 4880 section 5.5.3 - * @param {String} bytes Input string to read the packet from - */ - this.read = function(bytes) { - // - A Public-Key or Public-Subkey packet, as described above. - var len = this.readPublicKey(bytes); - - bytes = bytes.substr(len); - - - // - One octet indicating string-to-key usage conventions. Zero - // indicates that the secret-key data is not encrypted. 255 or 254 - // indicates that a string-to-key specifier is being given. Any - // other value is a symmetric-key encryption algorithm identifier. - var isEncrypted = bytes.charCodeAt(0); - - if (isEncrypted) { - this.encrypted = bytes; - } else { - - // - Plain or encrypted multiprecision integers comprising the secret - // key data. These algorithm-specific fields are as described - // below. - var parsedMPI = parse_cleartext_mpi('mod', bytes.substr(1), this.algorithm); - if (parsedMPI instanceof Error) - throw parsedMPI; - this.mpi = this.mpi.concat(parsedMPI); - this.isDecrypted = true; - } - - }; - - /** Creates an OpenPGP key packet for the given key. - * @return {String} A string of bytes containing the secret key OpenPGP packet - */ - this.write = function() { - var bytes = this.writePublicKey(); - - if (!this.encrypted) { - bytes += String.fromCharCode(0); - - bytes += write_cleartext_mpi('mod', this.algorithm, this.mpi); - } else { - bytes += this.encrypted; - } - - return bytes; - }; - - - - - /** Encrypt the payload. By default, we use aes256 and iterated, salted string - * to key specifier - * @param {String} passphrase - */ - this.encrypt = function(passphrase) { - - var s2k = new type_s2k(), - symmetric = 'aes256', - cleartext = write_cleartext_mpi('sha1', this.algorithm, this.mpi), - key = produceEncryptionKey(s2k, passphrase, symmetric), - blockLen = crypto.cipher[symmetric].blockSize, - iv = crypto.random.getRandomBytes(blockLen); - - - this.encrypted = ''; - this.encrypted += String.fromCharCode(254); - this.encrypted += String.fromCharCode(enums.write(enums.symmetric, symmetric)); - this.encrypted += s2k.write(); - this.encrypted += iv; - - this.encrypted += crypto.cfb.normalEncrypt(symmetric, key, cleartext, iv); - }; - - function produceEncryptionKey(s2k, passphrase, algorithm) { - return s2k.produce_key(passphrase, - crypto.cipher[algorithm].keySize); - } - - /** - * Decrypts the private key MPIs which are needed to use the key. - * openpgp_packet_keymaterial.hasUnencryptedSecretKeyData should be - * false otherwise - * a call to this function is not needed - * - * @param {String} str_passphrase The passphrase for this private key - * as string - * @return {Boolean} True if the passphrase was correct or MPI already - * decrypted; false if not - */ - this.decrypt = function(passphrase) { - if (this.isDecrypted) - return true; - - var i = 0, - symmetric, - key; - - var s2k_usage = this.encrypted.charCodeAt(i++); - - // - [Optional] If string-to-key usage octet was 255 or 254, a one- - // octet symmetric encryption algorithm. - if (s2k_usage == 255 || s2k_usage == 254) { - symmetric = this.encrypted.charCodeAt(i++); - symmetric = enums.read(enums.symmetric, symmetric); - - // - [Optional] If string-to-key usage octet was 255 or 254, a - // string-to-key specifier. The length of the string-to-key - // specifier is implied by its type, as described above. - var s2k = new type_s2k(); - i += s2k.read(this.encrypted.substr(i)); - - key = produceEncryptionKey(s2k, passphrase, symmetric); - } else { - symmetric = s2k_usage; - symmetric = enums.read(enums.symmetric, symmetric); - key = crypto.hash.md5(passphrase); - } - - - // - [Optional] If secret data is encrypted (string-to-key usage octet - // not zero), an Initial Vector (IV) of the same length as the - // cipher's block size. - var iv = this.encrypted.substr(i, - crypto.cipher[symmetric].blockSize); - - i += iv.length; - - var cleartext, - ciphertext = this.encrypted.substr(i); - - cleartext = crypto.cfb.normalDecrypt(symmetric, key, ciphertext, iv); - - var hash = s2k_usage == 254 ? - 'sha1' : - 'mod'; - - var parsedMPI = parse_cleartext_mpi(hash, cleartext, this.algorithm); - if (parsedMPI instanceof Error) - return false; - this.mpi = this.mpi.concat(parsedMPI); - this.isDecrypted = true; - return true; - }; - - this.generate = function(bits) { - this.mpi = crypto.generateMpi(this.algorithm, bits); - this.isDecrypted = true; - }; - -} - -packet_secret_key.prototype = new publicKey; - -module.exports = packet_secret_key; - -},{"../crypto":17,"../enums.js":28,"../type/mpi.js":55,"../type/s2k.js":56,"../util":57,"./public_key.js":42}],46:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var secret_key = require('./secret_key.js'); - -module.exports = function secret_subkey() { - secret_key.call(this); -} - -},{"./secret_key.js":45}],47:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var util = require('../util'), - packet = require('./packet.js'), - enums = require('../enums.js'), - crypto = require('../crypto'), - type_mpi = require('../type/mpi.js'), - type_keyid = require('../type/keyid.js'); - -/** - * @class - * @classdesc Implementation of the Signature Packet (Tag 2) - * - * RFC4480 5.2: - * A Signature packet describes a binding between some public key and - * some data. The most common signatures are a signature of a file or a - * block of text, and a signature that is a certification of a User ID. - */ -module.exports = function packet_signature() { - - this.version = null; - this.signatureType = null; - this.hashAlgorithm = null; - this.publicKeyAlgorithm = null; - - this.signatureData = null; - this.signedHashValue = null; - this.mpi = null; - - this.created = new Date(); - this.signatureExpirationTime = null; - this.signatureNeverExpires = null; - this.exportable = null; - this.trustLevel = null; - this.trustAmount = null; - this.regularExpression = null; - this.revocable = null; - this.keyExpirationTime = null; - this.keyNeverExpires = null; - this.preferredSymmetricAlgorithms = null; - this.revocationKeyClass = null; - this.revocationKeyAlgorithm = null; - this.revocationKeyFingerprint = null; - this.issuerKeyId = new type_keyid(); - this.notation = null; - this.preferredHashAlgorithms = null; - this.preferredCompressionAlgorithms = null; - this.keyServerPreferences = null; - this.preferredKeyServer = null; - this.isPrimaryUserID = null; - this.policyURI = null; - this.keyFlags = null; - this.signersUserId = null; - this.reasonForRevocationFlag = null; - this.reasonForRevocationString = null; - this.features = null; - this.signatureTargetPublicKeyAlgorithm = null; - this.signatureTargetHashAlgorithm = null; - this.signatureTargetHash = null; - this.embeddedSignature = null; - - this.verified = false; - - /** - * parsing function for a signature packet (tag 2). - * @param {String} bytes payload of a tag 2 packet - * @param {Integer} position position to start reading from the bytes string - * @param {Integer} len length of the packet or the remaining length of bytes at position - * @return {openpgp_packet_encrypteddata} object representation - */ - this.read = function(bytes) { - var i = 0; - - this.version = bytes.charCodeAt(i++); - // switch on version (3 and 4) - switch (this.version) { - case 3: - // One-octet length of following hashed material. MUST be 5. - if (bytes.charCodeAt(i++) != 5) - util.print_debug("openpgp.packet.signature.js\n" + - 'invalid One-octet length of following hashed material.' + - 'MUST be 5. @:' + (i - 1)); - - var sigpos = i; - // One-octet signature type. - this.signatureType = bytes.charCodeAt(i++); - - // Four-octet creation time. - this.created = util.readDate(bytes.substr(i, 4)); - i += 4; - - // storing data appended to data which gets verified - this.signatureData = bytes.substring(sigpos, i); - - // Eight-octet Key ID of signer. - this.issuerKeyId.read(bytes.substring(i, i + 8)); - i += 8; - - // One-octet public-key algorithm. - this.publicKeyAlgorithm = bytes.charCodeAt(i++); - - // One-octet hash algorithm. - this.hashAlgorithm = bytes.charCodeAt(i++); - break; - case 4: - this.signatureType = bytes.charCodeAt(i++); - this.publicKeyAlgorithm = bytes.charCodeAt(i++); - this.hashAlgorithm = bytes.charCodeAt(i++); - - function subpackets(bytes) { - // Two-octet scalar octet count for following subpacket data. - var subpacket_length = util.readNumber( - bytes.substr(0, 2)); - - var i = 2; - - // subpacket data set (zero or more subpackets) - var subpacked_read = 0; - while (i < 2 + subpacket_length) { - - var len = packet.readSimpleLength(bytes.substr(i)); - i += len.offset; - - this.read_sub_packet(bytes.substr(i, len.len)); - - i += len.len; - } - - return i; - } - - // hashed subpackets - i += subpackets.call(this, bytes.substr(i), true); - - // A V4 signature hashes the packet body - // starting from its first field, the version number, through the end - // of the hashed subpacket data. Thus, the fields hashed are the - // signature version, the signature type, the public-key algorithm, the - // hash algorithm, the hashed subpacket length, and the hashed - // subpacket body. - this.signatureData = bytes.substr(0, i); - - // unhashed subpackets - i += subpackets.call(this, bytes.substr(i), false); - - break; - default: - throw new Error('Version ' + version + ' of the signature is unsupported.'); - break; - } - - // Two-octet field holding left 16 bits of signed hash value. - this.signedHashValue = bytes.substr(i, 2); - i += 2; - - this.signature = bytes.substr(i); - }; - - this.write = function() { - return this.signatureData + - util.writeNumber(0, 2) + // Number of unsigned subpackets. - this.signedHashValue + - this.signature; - }; - - /** - * Signs provided data. This needs to be done prior to serialization. - * @param {Object} data Contains packets to be signed. - * @param {openpgp_msg_privatekey} privatekey private key used to sign the message. - */ - this.sign = function(key, data) { - var signatureType = enums.write(enums.signature, this.signatureType), - publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm), - hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm); - - var result = String.fromCharCode(4); - result += String.fromCharCode(signatureType); - result += String.fromCharCode(publicKeyAlgorithm); - result += String.fromCharCode(hashAlgorithm); - - this.issuerKeyId = key.getKeyId(); - - // Add hashed subpackets - result += this.write_all_sub_packets(); - - this.signatureData = result; - - var trailer = this.calculateTrailer(); - - var toHash = this.toSign(signatureType, data) + - this.signatureData + trailer; - - var hash = crypto.hash.digest(hashAlgorithm, toHash); - - this.signedHashValue = hash.substr(0, 2); - - this.signature = crypto.signature.sign(hashAlgorithm, - publicKeyAlgorithm, key.mpi, toHash); - }; - - /** - * Creates string of bytes with all subpacket data - * @return {String} a string-representation of a all subpacket data - */ - this.write_all_sub_packets = function() { - var sub = enums.signatureSubpacket; - var result = ''; - var bytes = ''; - if (this.created !== null) { - result += write_sub_packet(sub.signature_creation_time, util.writeDate(this.created)); - } - if (this.signatureExpirationTime !== null) { - result += write_sub_packet(sub.signature_expiration_time, util.writeDate(this.signatureExpirationTime)); - } - if (this.exportable !== null) { - result += write_sub_packet(sub.exportable_certification, String.fromCharCode(this.exportable ? 1 : 0)); - } - if (this.trustLevel !== null) { - bytes = String.fromCharCode(this.trustLevel) + String.fromCharCode(this.trustAmount); - result += write_sub_packet(sub.trust_signature, bytes); - } - if (this.regularExpression !== null) { - result += write_sub_packet(sub.regular_expression, this.regularExpression); - } - if (this.revocable !== null) { - result += write_sub_packet(sub.revocable, String.fromCharCode(this.revocable ? 1 : 0)); - } - if (this.keyExpirationTime !== null) { - result += write_sub_packet(sub.key_expiration_time, util.writeDate(this.keyExpirationTime)); - } - if (this.preferredSymmetricAlgorithms !== null) { - bytes = util.bin2str(this.preferredSymmetricAlgorithms); - result += write_sub_packet(sub.preferred_symmetric_algorithms, bytes); - } - if (this.revocationKeyClass !== null) { - bytes = String.fromCharCode(this.revocationKeyClass); - bytes += String.fromCharCode(this.revocationKeyAlgorithm); - bytes += this.revocationKeyFingerprint; - result += write_sub_packet(sub.revocation_key, bytes); - } - if (!this.issuerKeyId.isNull()) { - result += write_sub_packet(sub.issuer, this.issuerKeyId.write()); - } - if (this.notation !== null) { - for (var name in this.notation) { - if (this.notation.hasOwnProperty(name)) { - var value = this.notation[name]; - bytes = String.fromCharCode(0x80); - bytes += String.fromCharCode(0); - bytes += String.fromCharCode(0); - bytes += String.fromCharCode(0); - // 2 octets of name length - bytes += util.writeNumber(name.length, 2); - // 2 octets of value length - bytes += util.writeNumber(value.length, 2); - bytes += name + value; - result += write_sub_packet(sub.notation_data, bytes); - } - } - } - if (this.preferredHashAlgorithms !== null) { - bytes = util.bin2str(this.preferredHashAlgorithms); - result += write_sub_packet(sub.preferred_hash_algorithms, bytes); - } - if (this.preferredCompressionAlgorithms !== null) { - bytes = util.bin2str(this.preferredCompressionAlgorithms); - result += write_sub_packet(sub.preferred_hash_algorithms, bytes); - } - if (this.keyServerPreferences !== null) { - bytes = util.bin2str(this.keyServerPreferences); - result += write_sub_packet(sub.key_server_preferences, bytes); - } - if (this.preferredKeyServer !== null) { - result += write_sub_packet(sub.preferred_key_server, this.preferredKeyServer); - } - if (this.isPrimaryUserID !== null) { - result += write_sub_packet(sub.primary_user_id, String.fromCharCode(this.isPrimaryUserID ? 1 : 0)); - } - if (this.policyURI !== null) { - result += write_sub_packet(sub.policy_uri, this.policyURI); - } - if (this.keyFlags !== null) { - bytes = util.bin2str(this.keyFlags); - result += write_sub_packet(sub.key_flags, bytes); - } - if (this.signersUserId !== null) { - result += write_sub_packet(sub.signers_user_id, this.signersUserId); - } - if (this.reasonForRevocationFlag !== null) { - bytes = String.fromCharCode(this.reasonForRevocationFlag); - bytes += this.reasonForRevocationString; - result += write_sub_packet(sub.reason_for_revocation, bytes); - } - if (this.features !== null) { - bytes = util.bin2str(this.features); - result += write_sub_packet(sub.features, bytes); - } - if (this.signatureTargetPublicKeyAlgorithm !== null) { - bytes = String.fromCharCode(this.signatureTargetPublicKeyAlgorithm); - bytes += String.fromCharCode(this.signatureTargetHashAlgorithm); - bytes += this.signatureTargetHash; - result += write_sub_packet(sub.signature_target, bytes); - } - if (this.embeddedSignature !== null) { - result += write_sub_packet(sub.embedded_signature, this.embeddedSignature.write()); - } - result = util.writeNumber(result.length, 2) + result; - return result; - }; - - /** - * creates a string representation of a sub signature packet (See RFC 4880 5.2.3.1) - * @param {Integer} type subpacket signature type. Signature types as described - * in RFC4880 Section 5.2.3.2 - * @param {String} data data to be included - * @return {String} a string-representation of a sub signature packet (See RFC 4880 5.2.3.1) - */ - function write_sub_packet(type, data) { - var result = ""; - result += packet.writeSimpleLength(data.length + 1); - result += String.fromCharCode(type); - result += data; - return result; - } - - // V4 signature sub packets - - this.read_sub_packet = function(bytes) { - var mypos = 0; - - function read_array(prop, bytes) { - this[prop] = []; - - for (var i = 0; i < bytes.length; i++) { - this[prop].push(bytes.charCodeAt(i)); - } - } - - // The leftwost bit denotes a "critical" packet, but we ignore it. - var type = bytes.charCodeAt(mypos++) & 0x7F; - - // subpacket type - switch (type) { - case 2: - // Signature Creation Time - this.created = util.readDate(bytes.substr(mypos)); - break; - case 3: - // Signature Expiration Time - var time = util.readDate(bytes.substr(mypos)); - - this.signatureNeverExpires = time.getTime() == 0; - this.signatureExpirationTime = time; - - break; - case 4: - // Exportable Certification - this.exportable = bytes.charCodeAt(mypos++) == 1; - break; - case 5: - // Trust Signature - this.trustLevel = bytes.charCodeAt(mypos++); - this.trustAmount = bytes.charCodeAt(mypos++); - break; - case 6: - // Regular Expression - this.regularExpression = bytes.substr(mypos); - break; - case 7: - // Revocable - this.revocable = bytes.charCodeAt(mypos++) == 1; - break; - case 9: - // Key Expiration Time - var time = util.readDate(bytes.substr(mypos)); - - this.keyExpirationTime = time; - this.keyNeverExpires = time.getTime() == 0; - - break; - case 11: - // Preferred Symmetric Algorithms - this.preferredSymmetricAlgorithms = []; - - while (mypos != bytes.length) { - this.preferredSymmetricAlgorithms.push(bytes.charCodeAt(mypos++)); - } - - break; - case 12: - // Revocation Key - // (1 octet of class, 1 octet of public-key algorithm ID, 20 - // octets of - // fingerprint) - this.revocationKeyClass = bytes.charCodeAt(mypos++); - this.revocationKeyAlgorithm = bytes.charCodeAt(mypos++); - this.revocationKeyFingerprint = bytes.substr(mypos, 20); - break; - - case 16: - // Issuer - this.issuerKeyId.read(bytes.substr(mypos)); - break; - - case 20: - // Notation Data - // We don't know how to handle anything but a text flagged data. - if (bytes.charCodeAt(mypos) == 0x80) { - - // We extract key/value tuple from the byte stream. - mypos += 4; - var m = util.readNumber(bytes.substr(mypos, 2)); - mypos += 2 - var n = util.readNumber(bytes.substr(mypos, 2)); - mypos += 2 - - var name = bytes.substr(mypos, m), - value = bytes.substr(mypos + m, n); - - this.notation = this.notation || {}; - this.notation[name] = value; - } else throw new Error("Unsupported notation flag."); - break; - case 21: - // Preferred Hash Algorithms - read_array.call(this, 'preferredHashAlgorithms', bytes.substr(mypos)); - break; - case 22: - // Preferred Compression Algorithms - read_array.call(this, 'preferredCompressionAlgorithms ', bytes.substr(mypos)); - break; - case 23: - // Key Server Preferences - read_array.call(this, 'keyServerPreferencess', bytes.substr(mypos)); - break; - case 24: - // Preferred Key Server - this.preferredKeyServer = bytes.substr(mypos); - break; - case 25: - // Primary User ID - this.isPrimaryUserID = bytes[mypos++] != 0; - break; - case 26: - // Policy URI - this.policyURI = bytes.substr(mypos); - break; - case 27: - // Key Flags - read_array.call(this, 'keyFlags', bytes.substr(mypos)); - break; - case 28: - // Signer's User ID - this.signersUserId += bytes.substr(mypos); - break; - case 29: - // Reason for Revocation - this.reasonForRevocationFlag = bytes.charCodeAt(mypos++); - this.reasonForRevocationString = bytes.substr(mypos); - break; - case 30: - // Features - read_array.call(this, 'features', bytes.substr(mypos)); - break; - case 31: - // Signature Target - // (1 octet public-key algorithm, 1 octet hash algorithm, N octets hash) - this.signatureTargetPublicKeyAlgorithm = bytes.charCodeAt(mypos++); - this.signatureTargetHashAlgorithm = bytes.charCodeAt(mypos++); - - var len = crypto.getHashByteLength(this.signatureTargetHashAlgorithm); - - this.signatureTargetHash = bytes.substr(mypos, len); - break; - case 32: - // Embedded Signature - this.embeddedSignature = new packet_signature(); - this.embeddedSignature.read(bytes.substr(mypos)); - break; - default: - util.print_error("openpgp.packet.signature.js\n" + - 'unknown signature subpacket type ' + type + " @:" + mypos + - " subplen:" + subplen + " len:" + len); - break; - } - }; - - // Produces data to produce signature on - this.toSign = function(type, data) { - var t = enums.signature; - - switch (type) { - case t.binary: - case t.text: - return data.getBytes(); - - case t.standalone: - return ''; - - case t.cert_generic: - case t.cert_persona: - case t.cert_casual: - case t.cert_positive: - case t.cert_revocation: - { - var packet, tag; - - if (data.userid !== undefined) { - tag = 0xB4; - packet = data.userid; - } else if (data.userattribute !== undefined) { - tag = 0xD1; - packet = data.userattribute; - } else throw new Error('Either a userid or userattribute packet needs to be ' + - 'supplied for certification.'); - - var bytes = packet.write(); - - return this.toSign(t.key, data) + - String.fromCharCode(tag) + - util.writeNumber(bytes.length, 4) + - bytes; - } - case t.subkey_binding: - case t.key_binding: - { - return this.toSign(t.key, data) + this.toSign(t.key, { - key: data.bind - }); - } - case t.key: - { - if (data.key == undefined) - throw new Error('Key packet is required for this sigtature.'); - - return data.key.writeOld(); - } - case t.key_revocation: - case t.subkey_revocation: - return this.toSign(t.key, data); - case t.timestamp: - return ''; - case t.third_party: - throw new Error('Not implemented'); - break; - default: - throw new Error('Unknown signature type.') - } - } - - - this.calculateTrailer = function() { - // calculating the trailer - var trailer = ''; - // V3 signatures don't have a trailer - if (this.version == 3) return trailer; - trailer += String.fromCharCode(4); // Version - trailer += String.fromCharCode(0xFF); - trailer += util.writeNumber(this.signatureData.length, 4); - return trailer - } - - - /** - * verifys the signature packet. Note: not signature types are implemented - * @param {String|Object} data data which on the signature applies - * @param {public_subkey|packet_public_key} key the public key to verify the signature - * @return {boolean} True if message is verified, else false. - */ - this.verify = function(key, data) { - var signatureType = enums.write(enums.signature, this.signatureType), - publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm), - hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm); - - var bytes = this.toSign(signatureType, data), - trailer = this.calculateTrailer(); - - - var mpicount = 0; - // Algorithm-Specific Fields for RSA signatures: - // - multiprecision number (MPI) of RSA signature value m**d mod n. - if (publicKeyAlgorithm > 0 && publicKeyAlgorithm < 4) - mpicount = 1; - // Algorithm-Specific Fields for DSA signatures: - // - MPI of DSA value r. - // - MPI of DSA value s. - else if (publicKeyAlgorithm == 17) - mpicount = 2; - - var mpi = [], - i = 0; - for (var j = 0; j < mpicount; j++) { - mpi[j] = new type_mpi(); - i += mpi[j].read(this.signature.substr(i)); - } - - this.verified = crypto.signature.verify(publicKeyAlgorithm, - hashAlgorithm, mpi, key.mpi, - bytes + this.signatureData + trailer); - - return this.verified; - } -} - -},{"../crypto":17,"../enums.js":28,"../type/keyid.js":54,"../type/mpi.js":55,"../util":57,"./packet.js":40}],48:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var util = require('../util'), - crypto = require('../crypto'); - -/** - * @class - * @classdesc Implementation of the Sym. Encrypted Integrity Protected Data - * Packet (Tag 18) - * - * RFC4880 5.13: The Symmetrically Encrypted Integrity Protected Data packet is - * a variant of the Symmetrically Encrypted Data packet. It is a new feature - * created for OpenPGP that addresses the problem of detecting a modification to - * encrypted data. It is used in combination with a Modification Detection Code - * packet. - */ - -module.exports = function packet_sym_encrypted_integrity_protected() { - /** The encrypted payload. */ - this.encrypted = null; // string - /** @type {Boolean} - * If after decrypting the packet this is set to true, - * a modification has been detected and thus the contents - * should be discarded. - */ - this.modification = false; - this.packets; - - - this.read = function(bytes) { - // - A one-octet version number. The only currently defined value is - // 1. - var version = bytes.charCodeAt(0); - - if (version != 1) { - throw new Error('Invalid packet version.'); - } - - // - Encrypted data, the output of the selected symmetric-key cipher - // operating in Cipher Feedback mode with shift amount equal to the - // block size of the cipher (CFB-n where n is the block size). - this.encrypted = bytes.substr(1); - } - - this.write = function() { - - return String.fromCharCode(1) // Version - + this.encrypted; - } - - this.encrypt = function(sessionKeyAlgorithm, key) { - var bytes = this.packets.write() - - var prefixrandom = crypto.getPrefixRandom(sessionKeyAlgorithm); - var prefix = prefixrandom + prefixrandom.charAt(prefixrandom.length - 2) + prefixrandom.charAt(prefixrandom.length - - 1) - - var tohash = bytes; - - - // Modification detection code packet. - tohash += String.fromCharCode(0xD3); - tohash += String.fromCharCode(0x14); - - - tohash += crypto.hash.sha1(prefix + tohash); - - - this.encrypted = crypto.cfb.encrypt(prefixrandom, - sessionKeyAlgorithm, tohash, key, false).substring(0, - prefix.length + tohash.length); - } - - /** - * Decrypts the encrypted data contained in this object read_packet must - * have been called before - * - * @param {Integer} sessionKeyAlgorithm - * The selected symmetric encryption algorithm to be used - * @param {String} key The key of cipher blocksize length to be used - * @return {String} The decrypted data of this packet - */ - this.decrypt = function(sessionKeyAlgorithm, key) { - var decrypted = crypto.cfb.decrypt( - sessionKeyAlgorithm, key, this.encrypted, false); - - - // there must be a modification detection code packet as the - // last packet and everything gets hashed except the hash itself - this.hash = crypto.hash.sha1( - crypto.cfb.mdc(sessionKeyAlgorithm, key, this.encrypted) + decrypted.substring(0, decrypted.length - 20)); - - - var mdc = decrypted.substr(decrypted.length - 20, 20); - - if (this.hash != mdc) { - throw new Error('Modification detected.'); - } else - this.packets.read(decrypted.substr(0, decrypted.length - 22)); - } -}; - -},{"../crypto":17,"../util":57}],49:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var type_s2k = require('../type/s2k.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - -/** - * @class - * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) - * - * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key - * used to encrypt a message. Zero or more Public-Key Encrypted Session Key - * packets and/or Symmetric-Key Encrypted Session Key packets may precede a - * Symmetrically Encrypted Data Packet, which holds an encrypted message. The - * message is encrypted with the session key, and the session key is itself - * encrypted and stored in the Encrypted Session Key packet(s). The - * Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted - * Session Key packet for each OpenPGP key to which the message is encrypted. - * The recipient of the message finds a session key that is encrypted to their - * public key, decrypts the session key, and then uses the session key to - * decrypt the message. - */ -module.exports = function packet_sym_encrypted_session_key() { - this.tag = 3; - this.sessionKeyEncryptionAlgorithm = null; - this.sessionKeyAlgorithm = 'aes256'; - this.encrypted = null; - this.s2k = new type_s2k(); - - /** - * Parsing function for a symmetric encrypted session key packet (tag 3). - * - * @param {String} input Payload of a tag 1 packet - * @param {Integer} position Position to start reading from the input string - * @param {Integer} len - * Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encrypteddata} Object representation - */ - this.read = function(bytes) { - // A one-octet version number. The only currently defined version is 4. - this.version = bytes.charCodeAt(0); - - // A one-octet number describing the symmetric algorithm used. - var algo = enums.read(enums.symmetric, bytes.charCodeAt(1)); - - // A string-to-key (S2K) specifier, length as defined above. - var s2klength = this.s2k.read(bytes.substr(2)); - - // Optionally, the encrypted session key itself, which is decrypted - // with the string-to-key object. - var done = s2klength + 2; - - if (done < bytes.length) { - this.encrypted = bytes.substr(done); - this.sessionKeyEncryptionAlgorithm = algo - } else - this.sessionKeyAlgorithm = algo; - } - - this.write = function() { - var algo = this.encrypted == null ? - this.sessionKeyAlgorithm : - this.sessionKeyEncryptionAlgorithm; - - var bytes = String.fromCharCode(this.version) + - String.fromCharCode(enums.write(enums.symmetric, algo)) + - this.s2k.write(); - - if (this.encrypted != null) - bytes += this.encrypted; - return bytes; - } - - /** - * Decrypts the session key (only for public key encrypted session key - * packets (tag 1) - * - * @param {openpgp_msg_message} msg - * The message object (with member encryptedData - * @param {openpgp_msg_privatekey} key - * Private key with secMPIs unlocked - * @return {String} The unencrypted session key - */ - this.decrypt = function(passphrase) { - var algo = this.sessionKeyEncryptionAlgorithm != null ? - this.sessionKeyEncryptionAlgorithm : - this.sessionKeyAlgorithm; - - - var length = crypto.cipher[algo].keySize; - var key = this.s2k.produce_key(passphrase, length); - - if (this.encrypted == null) { - this.sessionKey = key; - - } else { - var decrypted = crypto.cfb.decrypt( - this.sessionKeyEncryptionAlgorithm, key, this.encrypted, true); - - this.sessionKeyAlgorithm = enums.read(enums.symmetric, - decrypted[0].keyCodeAt()); - - this.sessionKey = decrypted.substr(1); - } - } - - this.encrypt = function(passphrase) { - var length = crypto.getKeyLength(this.sessionKeyEncryptionAlgorithm); - var key = this.s2k.produce_key(passphrase, length); - - var private_key = String.fromCharCode( - enums.write(enums.symmetric, this.sessionKeyAlgorithm)) + - - crypto.getRandomBytes( - crypto.getKeyLength(this.sessionKeyAlgorithm)); - - this.encrypted = crypto.cfb.encrypt( - crypto.getPrefixRandom(this.sessionKeyEncryptionAlgorithm), - this.sessionKeyEncryptionAlgorithm, key, private_key, true); - } -}; - -},{"../crypto":17,"../enums.js":28,"../type/s2k.js":56}],50:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var crypto = require('../crypto'); - -/** - * @class - * @classdesc Implementation of the Symmetrically Encrypted Data Packet (Tag 9) - * - * RFC4880 5.7: The Symmetrically Encrypted Data packet contains data encrypted - * with a symmetric-key algorithm. When it has been decrypted, it contains other - * packets (usually a literal data packet or compressed data packet, but in - * theory other Symmetrically Encrypted Data packets or sequences of packets - * that form whole OpenPGP messages). - */ - -module.exports = function packet_symmetrically_encrypted() { - this.encrypted = null; - /** Decrypted packets contained within. - * @type {openpgp_packetlist} */ - this.packets; - - this.read = function(bytes) { - this.encrypted = bytes; - } - - this.write = function() { - return this.encrypted; - } - - /** - * Symmetrically decrypt the packet data - * - * @param {Integer} sessionKeyAlgorithm - * Symmetric key algorithm to use // See RFC4880 9.2 - * @param {String} key - * Key as string with the corresponding length to the - * algorithm - * @return The decrypted data; - */ - this.decrypt = function(sessionKeyAlgorithm, key) { - var decrypted = crypto.cfb.decrypt( - sessionKeyAlgorithm, key, this.encrypted, true); - - this.packets.read(decrypted); - } - - this.encrypt = function(algo, key) { - var data = this.packets.write(); - - this.encrypted = crypto.cfb.encrypt( - crypto.getPrefixRandom(algo), algo, data, key, true); - } -}; - -},{"../crypto":17}],51:[function(require,module,exports){ -module.exports = function packet_trust() { - -}; - -},{}],52:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the User Attribute Packet (Tag 17) - * The User Attribute packet is a variation of the User ID packet. It - * is capable of storing more types of data than the User ID packet, - * which is limited to text. Like the User ID packet, a User Attribute - * packet may be certified by the key owner ("self-signed") or any other - * key owner who cares to certify it. Except as noted, a User Attribute - * packet may be used anywhere that a User ID packet may be used. - * - * While User Attribute packets are not a required part of the OpenPGP - * standard, implementations SHOULD provide at least enough - * compatibility to properly handle a certification signature on the - * User Attribute packet. A simple way to do this is by treating the - * User Attribute packet as a User ID packet with opaque contents, but - * an implementation may use any method desired. - */ -module.exports = function packet_user_attribute() { - this.tag = 17; - this.attributes = []; - - /** - * parsing function for a user attribute packet (tag 17). - * @param {String} input payload of a tag 17 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input at position - * @return {openpgp_packet_encrypteddata} object representation - */ - this.read = function(bytes) { - var i = 0; - while (i < bytes.length) { - var len = openpgp_packet.read_simple_length(bytes); - - i += len.offset; - this.attributes.push(bytes.substr(i, len.len)); - i += len.len; - } - } -}; - -},{}],53:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var util = require('../util'); - -/** - * @class - * @classdesc Implementation of the User ID Packet (Tag 13) - * A User ID packet consists of UTF-8 text that is intended to represent - * the name and email address of the key holder. By convention, it - * includes an RFC 2822 [RFC2822] mail name-addr, but there are no - * restrictions on its content. The packet length in the header - * specifies the length of the User ID. - */ -module.exports = function packet_userid() { - /** @type {String} A string containing the user id. Usually in the form - * John Doe <john@example.com> - */ - this.userid = ''; - - - /** - * Parsing function for a user id packet (tag 13). - * @param {String} input payload of a tag 13 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input - * at position - * @return {openpgp_packet_encrypteddata} object representation - */ - this.read = function(bytes) { - this.userid = util.decode_utf8(bytes); - } - - /** - * Creates a string representation of the user id packet - * @param {String} user_id the user id as string ("John Doe <john.doe@mail.us") - * @return {String} string representation - */ - this.write = function() { - return util.encode_utf8(this.userid); - } -} - -},{"../util":57}],54:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var util = require('../util'); - -/** - * @class - * @classdesc Implementation of type key id (RFC4880 3.3) - * A Key ID is an eight-octet scalar that identifies a key. - Implementations SHOULD NOT assume that Key IDs are unique. The - section "Enhanced Key Formats" below describes how Key IDs are - formed. - */ -function keyid() { - - this.bytes = ''; - - - /** - * Parsing method for a key id - * @param {String} input Input to read the key id from - * @param {integer} position Position where to start reading the key - * id from input - * @return {openpgp_type_keyid} This object - */ - this.read = function(bytes) { - this.bytes = bytes.substr(0, 8); - } - - this.write = function() { - return this.bytes; - } - - this.toHex = function() { - return util.hexstrdump(this.bytes); - } - - this.equals = function(keyid) { - return this.bytes == keyid.bytes; - } - - this.isNull = function() { - return this.bytes === ''; - } -} - -keyid.mapToHex = function(keyid) { - return keyid.toHex(); -} - -module.exports = keyid; - -},{"../util":57}],55:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -// Hint: We hold our MPIs as an array of octets in big endian format preceeding a two -// octet scalar: MPI: [a,b,c,d,e,f] -// - MPI size: (a << 8) | b -// - MPI = c | d << 8 | e << ((MPI.length -2)*8) | f ((MPI.length -2)*8) - -var BigInteger = require('../crypto/public_key/jsbn.js'), - util = require('../util'); - -/** - * @class - * @classdescImplementation of type MPI (RFC4880 3.2) - * Multiprecision integers (also called MPIs) are unsigned integers used - * to hold large integers such as the ones used in cryptographic - * calculations. - * An MPI consists of two pieces: a two-octet scalar that is the length - * of the MPI in bits followed by a string of octets that contain the - * actual integer. - */ -module.exports = function mpi() { - /** An implementation dependent integer */ - this.data = null; - - /** - * Parsing function for a mpi (RFC 4880 3.2). - * @param {String} input Payload of mpi data - * @param {Integer} position Position to start reading from the input - * string - * @param {Integer} len Length of the packet or the remaining length of - * input at position - * @return {openpgp_type_mpi} Object representation - */ - this.read = function(bytes) { - var bits = (bytes.charCodeAt(0) << 8) | bytes.charCodeAt(1); - - // Additional rules: - // - // The size of an MPI is ((MPI.length + 7) / 8) + 2 octets. - // - // The length field of an MPI describes the length starting from its - // most significant non-zero bit. Thus, the MPI [00 02 01] is not - // formed correctly. It should be [00 01 01]. - - // TODO: Verification of this size method! This size calculation as - // specified above is not applicable in JavaScript - var bytelen = Math.ceil(bits / 8); - - var raw = bytes.substr(2, bytelen); - this.fromBytes(raw); - - return 2 + bytelen; - } - - this.fromBytes = function(bytes) { - this.data = new BigInteger(util.hexstrdump(bytes), 16); - } - - this.toBytes = function() { - return this.write().substr(2); - } - - this.byteLength = function() { - return this.toBytes().length; - } - - /** - * Converts the mpi object to a string as specified in RFC4880 3.2 - * @return {String} mpi Byte representation - */ - this.write = function() { - return this.data.toMPI(); - } - - this.toBigInteger = function() { - return this.data.clone(); - } - - this.fromBigInteger = function(bn) { - this.data = bn.clone(); - } -} - -},{"../crypto/public_key/jsbn.js":22,"../util":57}],56:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var enums = require('../enums.js'), - util = require('../util'), - crypto = require('../crypto'); - -/** - * @class - * @classdesc Implementation of the String-to-key specifier (RFC4880 3.7) - * String-to-key (S2K) specifiers are used to convert passphrase strings - into symmetric-key encryption/decryption keys. They are used in two - places, currently: to encrypt the secret part of private keys in the - private keyring, and to convert passphrases to encryption keys for - symmetrically encrypted messages. - */ -module.exports = function s2k() { - /** @type {openpgp.hash} */ - this.algorithm = 'sha256'; - /** @type {openpgp_type_s2k.type} */ - this.type = 'iterated'; - this.c = 96; - /** @type {openpgp_bytearray} - * Eight bytes of salt. */ - this.salt = crypto.random.getRandomBytes(8); - - - // Exponen bias, defined in RFC4880 - var expbias = 6; - - this.get_count = function() { - return (16 + (this.c & 15)) << ((this.c >> 4) + expbias); - } - - /** - * Parsing function for a string-to-key specifier (RFC 4880 3.7). - * @param {String} input Payload of string-to-key specifier - * @return {Integer} Actual length of the object - */ - this.read = function(bytes) { - var i = 0; - this.type = enums.read(enums.s2k, bytes.charCodeAt(i++)); - this.algorithm = enums.read(enums.hash, bytes.charCodeAt(i++)); - - switch (this.type) { - case 'simple': - break; - - case 'salted': - this.salt = bytes.substr(i, 8); - i += 8; - break; - - case 'iterated': - this.salt = bytes.substr(i, 8); - i += 8; - - // Octet 10: count, a one-octet, coded value - this.c = bytes.charCodeAt(i++); - break; - - case 'gnu': - if (bytes.substr(i, 3) == "GNU") { - i += 3; // GNU - var gnuExtType = 1000 + bytes.charCodeAt(i++); - if (gnuExtType == 1001) { - this.type = gnuExtType; - // GnuPG extension mode 1001 -- don't write secret key at all - } else { - throw new Error("Unknown s2k gnu protection mode."); - } - } else { - throw new Error("Unknown s2k type."); - } - break; - - default: - throw new Error("Unknown s2k type."); - break; - } - - return i; - } - - - /** - * writes an s2k hash based on the inputs. - * @return {String} Produced key of hashAlgorithm hash length - */ - this.write = function() { - var bytes = String.fromCharCode(enums.write(enums.s2k, this.type)); - bytes += String.fromCharCode(enums.write(enums.hash, this.algorithm)); - - switch (this.type) { - case 'simple': - break; - case 'salted': - bytes += this.salt; - break; - case 'iterated': - bytes += this.salt; - bytes += String.fromCharCode(this.c); - break; - }; - - return bytes; - } - - /** - * Produces a key using the specified passphrase and the defined - * hashAlgorithm - * @param {String} passphrase Passphrase containing user input - * @return {String} Produced key with a length corresponding to - * hashAlgorithm hash length - */ - this.produce_key = function(passphrase, numBytes) { - passphrase = util.encode_utf8(passphrase); - - function round(prefix, s2k) { - var algorithm = enums.write(enums.hash, s2k.algorithm); - - switch (s2k.type) { - case 'simple': - return crypto.hash.digest(algorithm, prefix + passphrase); - - case 'salted': - return crypto.hash.digest(algorithm, - prefix + s2k.salt + passphrase); - - case 'iterated': - var isp = [], - count = s2k.get_count(); - data = s2k.salt + passphrase; - - while (isp.length * data.length < count) - isp.push(data); - - isp = isp.join(''); - - if (isp.length > count) - isp = isp.substr(0, count); - - return crypto.hash.digest(algorithm, prefix + isp); - }; - } - - var result = '', - prefix = ''; - - while (result.length <= numBytes) { - result += round(prefix, this); - prefix += String.fromCharCode(0); - } - - return result.substr(0, numBytes); - } -} - -},{"../crypto":17,"../enums.js":28,"../util":57}],57:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var config = require('../config'); - -var Util = function() { - - this.readNumber = function(bytes) { - var n = 0; - - for (var i = 0; i < bytes.length; i++) { - n <<= 8; - n += bytes.charCodeAt(i); - } - - return n; - }; - - this.writeNumber = function(n, bytes) { - var b = ''; - for (var i = 0; i < bytes; i++) { - b += String.fromCharCode((n >> (8 * (bytes - i - 1))) & 0xFF); - } - - return b; - }; - - - - this.readDate = function(bytes) { - var n = this.readNumber(bytes); - var d = new Date(); - d.setTime(n * 1000); - return d; - }; - - this.writeDate = function(time) { - var numeric = Math.round(time.getTime() / 1000); - - return this.writeNumber(numeric, 4); - }; - - this.emailRegEx = /^[+a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,6}$/; - - this.debug = false; - - this.hexdump = function(str) { - var r = []; - var e = str.length; - var c = 0; - var h; - var i = 0; - while (c < e) { - h = str.charCodeAt(c++).toString(16); - while (h.length < 2) h = "0" + h; - r.push(" " + h); - i++; - if (i % 32 == 0) - r.push("\n "); - } - return r.join(''); - }; - - /** - * Create hexstring from a binary - * @param {String} str String to convert - * @return {String} String containing the hexadecimal values - */ - this.hexstrdump = function(str) { - if (str == null) - return ""; - var r = []; - var e = str.length; - var c = 0; - var h; - while (c < e) { - h = str.charCodeAt(c++).toString(16); - while (h.length < 2) h = "0" + h; - r.push("" + h); - } - return r.join(''); - }; - - /** - * Create binary string from a hex encoded string - * @param {String} str Hex string to convert - * @return {String} String containing the binary values - */ - this.hex2bin = function(hex) { - var str = ''; - for (var i = 0; i < hex.length; i += 2) - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - return str; - }; - - /** - * Creating a hex string from an binary array of integers (0..255) - * @param {String} str Array of bytes to convert - * @return {String} Hexadecimal representation of the array - */ - this.hexidump = function(str) { - var r = []; - var e = str.length; - var c = 0; - var h; - while (c < e) { - h = str[c++].toString(16); - while (h.length < 2) h = "0" + h; - r.push("" + h); - } - return r.join(''); - }; - - - /** - * Convert a native javascript string to a string of utf8 bytes - * @param {String} str The string to convert - * @return {String} A valid squence of utf8 bytes - */ - this.encode_utf8 = function(str) { - return unescape(encodeURIComponent(str)); - }; - - /** - * Convert a string of utf8 bytes to a native javascript string - * @param {String} utf8 A valid squence of utf8 bytes - * @return {String} A native javascript string - */ - this.decode_utf8 = function(utf8) { - try { - return decodeURIComponent(escape(utf8)); - } catch (e) { - return utf8; - } - }; - - var str2bin = function(str, result) { - for (var i = 0; i < str.length; i++) { - result[i] = str.charCodeAt(i); - } - - return result; - }; - - var bin2str = function(bin) { - var result = []; - - for (var i = 0; i < bin.length; i++) { - result.push(String.fromCharCode(bin[i])); - } - - return result.join(''); - }; - - /** - * Convert a string to an array of integers(0.255) - * @param {String} str String to convert - * @return {Integer[]} An array of (binary) integers - */ - this.str2bin = function(str) { - return str2bin(str, new Array(str.length)); - }; - - - /** - * Convert an array of integers(0.255) to a string - * @param {Integer[]} bin An array of (binary) integers to convert - * @return {String} The string representation of the array - */ - this.bin2str = bin2str; - - /** - * Convert a string to a Uint8Array - * @param {String} str String to convert - * @return {Uint8Array} The array of (binary) integers - */ - this.str2Uint8Array = function(str) { - return str2bin(str, new Uint8Array(new ArrayBuffer(str.length))); - }; - - /** - * Convert a Uint8Array to a string. This currently functions - * the same as bin2str. - * @param {Uint8Array} bin An array of (binary) integers to convert - * @return {String} String representation of the array - */ - this.Uint8Array2str = bin2str; - - /** - * Calculates a 16bit sum of a string by adding each character - * codes modulus 65535 - * @param {String} text String to create a sum of - * @return {Integer} An integer containing the sum of all character - * codes % 65535 - */ - this.calc_checksum = function(text) { - var checksum = { - s: 0, - add: function(sadd) { - this.s = (this.s + sadd) % 65536; - } - }; - for (var i = 0; i < text.length; i++) { - checksum.add(text.charCodeAt(i)); - } - return checksum.s; - }; - - /** - * Helper function to print a debug message. Debug - * messages are only printed if - * openpgp.config.debug is set to true. - * @param {String} str String of the debug message - */ - this.print_debug = function(str) { - if (config.debug) { - console.log(str); - } - }; - - /** - * Helper function to print a debug message. Debug - * messages are only printed if - * openpgp.config.debug is set to true. - * Different than print_debug because will call hexstrdump iff necessary. - * @param {String} str String of the debug message - */ - this.print_debug_hexstr_dump = function(str, strToHex) { - if (config.debug) { - str = str + this.hexstrdump(strToHex); - console.log(str); - } - }; - - /** - * Helper function to print an error message. - * @param {String} str String of the error message - */ - this.print_error = function(str) { - if (config.debug) - throw str; - console.log(str); - }; - - /** - * Helper function to print an info message. - * @param {String} str String of the info message - */ - this.print_info = function(str) { - if (config.debug) - console.log(str); - }; - - this.print_warning = function(str) { - console.log(str); - }; - - this.getLeftNBits = function(string, bitcount) { - var rest = bitcount % 8; - if (rest == 0) - return string.substring(0, bitcount / 8); - var bytes = (bitcount - rest) / 8 + 1; - var result = string.substring(0, bytes); - return this.shiftRight(result, 8 - rest); // +String.fromCharCode(string.charCodeAt(bytes -1) << (8-rest) & 0xFF); - }; - - /** - * Shifting a string to n bits right - * @param {String} value The string to shift - * @param {Integer} bitcount Amount of bits to shift (MUST be smaller - * than 9) - * @return {String} Resulting string. - */ - this.shiftRight = function(value, bitcount) { - var temp = util.str2bin(value); - if (bitcount % 8 != 0) { - for (var i = temp.length - 1; i >= 0; i--) { - temp[i] >>= bitcount % 8; - if (i > 0) - temp[i] |= (temp[i - 1] << (8 - (bitcount % 8))) & 0xFF; - } - } else { - return value; - } - return util.bin2str(temp); - }; - - /** - * Return the algorithm type as string - * @return {String} String representing the message type - */ - this.get_hashAlgorithmString = function(algo) { - switch (algo) { - case 1: - return "MD5"; - case 2: - return "SHA1"; - case 3: - return "RIPEMD160"; - case 8: - return "SHA256"; - case 9: - return "SHA384"; - case 10: - return "SHA512"; - case 11: - return "SHA224"; - } - return "unknown"; - }; - -}; - -/** - * an instance that should be used. - */ -module.exports = new Util(); - -},{"../config":4}],58:[function(require,module,exports){ -var unit = require('../../unit.js'); - -unit.register("AES Rijndael cipher test with test vectors from ecb_tbl.txt", function() { - var openpgp = require('../../../'); - var util = openpgp.util; - - var result = new Array(); - - function test_aes(input, key, output) { - var aes = new openpgp.crypto.cipher.aes128(util.bin2str(key)); - - var result = util.bin2str(aes.encrypt(input)); - - return util.hexstrdump(result) == util.hexstrdump(util.bin2str(output)); - }; - - var testvectors128 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12],[0x50,0x68,0x12,0xA4,0x5F,0x08,0xC8,0x89,0xB9,0x7F,0x59,0x80,0x03,0x8B,0x83,0x59],[0xD8,0xF5,0x32,0x53,0x82,0x89,0xEF,0x7D,0x06,0xB5,0x06,0xA4,0xFD,0x5B,0xE9,0xC9]], - [[0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26],[0x5C,0x6D,0x71,0xCA,0x30,0xDE,0x8B,0x8B,0x00,0x54,0x99,0x84,0xD2,0xEC,0x7D,0x4B],[0x59,0xAB,0x30,0xF4,0xD4,0xEE,0x6E,0x4F,0xF9,0x90,0x7E,0xF6,0x5B,0x1F,0xB6,0x8C]], - [[0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A],[0x53,0xF3,0xF4,0xC6,0x4F,0x86,0x16,0xE4,0xE7,0xC5,0x61,0x99,0xF4,0x8F,0x21,0xF6],[0xBF,0x1E,0xD2,0xFC,0xB2,0xAF,0x3F,0xD4,0x14,0x43,0xB5,0x6D,0x85,0x02,0x5C,0xB1]], - [[0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E],[0xA1,0xEB,0x65,0xA3,0x48,0x71,0x65,0xFB,0x0F,0x1C,0x27,0xFF,0x99,0x59,0xF7,0x03],[0x73,0x16,0x63,0x2D,0x5C,0x32,0x23,0x3E,0xDC,0xB0,0x78,0x05,0x60,0xEA,0xE8,0xB2]], - [[0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58,0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62],[0x35,0x53,0xEC,0xF0,0xB1,0x73,0x95,0x58,0xB0,0x8E,0x35,0x0A,0x98,0xA3,0x9B,0xFA],[0x40,0x8C,0x07,0x3E,0x3E,0x25,0x38,0x07,0x2B,0x72,0x62,0x5E,0x68,0xB8,0x36,0x4B]], - [[0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0x67,0x42,0x99,0x69,0x49,0x0B,0x97,0x11,0xAE,0x2B,0x01,0xDC,0x49,0x7A,0xFD,0xE8],[0xE1,0xF9,0x4D,0xFA,0x77,0x65,0x97,0xBE,0xAC,0xA2,0x62,0xF2,0xF6,0x36,0x6F,0xEA]], - [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A],[0x93,0x38,0x5C,0x1F,0x2A,0xEC,0x8B,0xED,0x19,0x2F,0x5A,0x8E,0x16,0x1D,0xD5,0x08],[0xF2,0x9E,0x98,0x6C,0x6A,0x1C,0x27,0xD7,0xB2,0x9F,0xFD,0x7E,0xE9,0x2B,0x75,0xF1]], - [[0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E],[0xB5,0xBF,0x94,0x6B,0xE1,0x9B,0xEB,0x8D,0xB3,0x98,0x3B,0x5F,0x4C,0x6E,0x8D,0xDB],[0x13,0x1C,0x88,0x6A,0x57,0xF8,0xC2,0xE7,0x13,0xAB,0xA6,0x95,0x5E,0x2B,0x55,0xB5]], - [[0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2],[0x41,0x32,0x1E,0xE1,0x0E,0x21,0xBD,0x90,0x72,0x27,0xC4,0x45,0x0F,0xF4,0x23,0x24],[0xD2,0xAB,0x76,0x62,0xDF,0x9B,0x8C,0x74,0x02,0x10,0xE5,0xEE,0xB6,0x1C,0x19,0x9D]], - [[0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6],[0x00,0xA8,0x2F,0x59,0xC9,0x1C,0x84,0x86,0xD1,0x2C,0x0A,0x80,0x12,0x4F,0x60,0x89],[0x14,0xC1,0x05,0x54,0xB2,0x85,0x9C,0x48,0x4C,0xAB,0x58,0x69,0xBB,0xE7,0xC4,0x70]], - [[0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0,0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA],[0x7C,0xE0,0xFD,0x07,0x67,0x54,0x69,0x1B,0x4B,0xBD,0x9F,0xAF,0x8A,0x13,0x72,0xFE],[0xDB,0x4D,0x49,0x8F,0x0A,0x49,0xCF,0x55,0x44,0x5D,0x50,0x2C,0x1F,0x9A,0xB3,0xB5]], - [[0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0x23,0x60,0x5A,0x82,0x43,0xD0,0x77,0x64,0x54,0x1B,0xC5,0xAD,0x35,0x5B,0x31,0x29],[0x6D,0x96,0xFE,0xF7,0xD6,0x65,0x90,0xA7,0x7A,0x77,0xBB,0x20,0x56,0x66,0x7F,0x7F]], - [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02],[0x12,0xA8,0xCF,0xA2,0x3E,0xA7,0x64,0xFD,0x87,0x62,0x32,0xB4,0xE8,0x42,0xBC,0x44],[0x31,0x6F,0xB6,0x8E,0xDB,0xA7,0x36,0xC5,0x3E,0x78,0x47,0x7B,0xF9,0x13,0x72,0x5C]], - [[0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16],[0xBC,0xAF,0x32,0x41,0x5E,0x83,0x08,0xB3,0x72,0x3E,0x5F,0xDD,0x85,0x3C,0xCC,0x80],[0x69,0x36,0xF2,0xB9,0x3A,0xF8,0x39,0x7F,0xD3,0xA7,0x71,0xFC,0x01,0x1C,0x8C,0x37]], - [[0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E],[0x89,0xAF,0xAE,0x68,0x5D,0x80,0x1A,0xD7,0x47,0xAC,0xE9,0x1F,0xC4,0x9A,0xDD,0xE0],[0xF3,0xF9,0x2F,0x7A,0x9C,0x59,0x17,0x9C,0x1F,0xCC,0x2C,0x2B,0xA0,0xB0,0x82,0xCD]]]; - - var testvectors192 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C],[0x2D,0x33,0xEE,0xF2,0xC0,0x43,0x0A,0x8A,0x9E,0xBF,0x45,0xE8,0x09,0xC4,0x0B,0xB6],[0xDF,0xF4,0x94,0x5E,0x03,0x36,0xDF,0x4C,0x1C,0x56,0xBC,0x70,0x0E,0xFF,0x83,0x7F]], - [[0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26,0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A],[0x6A,0xA3,0x75,0xD1,0xFA,0x15,0x5A,0x61,0xFB,0x72,0x35,0x3E,0x0A,0x5A,0x87,0x56],[0xB6,0xFD,0xDE,0xF4,0x75,0x27,0x65,0xE3,0x47,0xD5,0xD2,0xDC,0x19,0x6D,0x12,0x52]], - [[0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E,0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58],[0xBC,0x37,0x36,0x51,0x8B,0x94,0x90,0xDC,0xB8,0xED,0x60,0xEB,0x26,0x75,0x8E,0xD4],[0xD2,0x36,0x84,0xE3,0xD9,0x63,0xB3,0xAF,0xCF,0x1A,0x11,0x4A,0xCA,0x90,0xCB,0xD6]], - [[0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0xAA,0x21,0x44,0x02,0xB4,0x6C,0xFF,0xB9,0xF7,0x61,0xEC,0x11,0x26,0x3A,0x31,0x1E],[0x3A,0x7A,0xC0,0x27,0x75,0x3E,0x2A,0x18,0xC2,0xCE,0xAB,0x9E,0x17,0xC1,0x1F,0xD0]], - [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94],[0x02,0xAE,0xA8,0x6E,0x57,0x2E,0xEA,0xB6,0x6B,0x2C,0x3A,0xF5,0xE9,0xA4,0x6F,0xD6],[0x8F,0x67,0x86,0xBD,0x00,0x75,0x28,0xBA,0x26,0x60,0x3C,0x16,0x01,0xCD,0xD0,0xD8]], - [[0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2],[0xE2,0xAE,0xF6,0xAC,0xC3,0x3B,0x96,0x5C,0x4F,0xA1,0xF9,0x1C,0x75,0xFF,0x6F,0x36],[0xD1,0x7D,0x07,0x3B,0x01,0xE7,0x15,0x02,0xE2,0x8B,0x47,0xAB,0x55,0x11,0x68,0xB3]], - [[0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0],[0x06,0x59,0xDF,0x46,0x42,0x71,0x62,0xB9,0x43,0x48,0x65,0xDD,0x94,0x99,0xF9,0x1D],[0xA4,0x69,0xDA,0x51,0x71,0x19,0xFA,0xB9,0x58,0x76,0xF4,0x1D,0x06,0xD4,0x0F,0xFA]], - [[0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0x49,0xA4,0x42,0x39,0xC7,0x48,0xFE,0xB4,0x56,0xF5,0x9C,0x27,0x6A,0x56,0x58,0xDF],[0x60,0x91,0xAA,0x3B,0x69,0x5C,0x11,0xF5,0xC0,0xB6,0xAD,0x26,0xD3,0xD8,0x62,0xFF]], - [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02,0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C],[0x66,0x20,0x8F,0x6E,0x9D,0x04,0x52,0x5B,0xDE,0xDB,0x27,0x33,0xB6,0xA6,0xBE,0x37],[0x70,0xF9,0xE6,0x7F,0x9F,0x8D,0xF1,0x29,0x41,0x31,0x66,0x2D,0xC6,0xE6,0x93,0x64]], - [[0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16,0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20,0x22,0x23,0x24,0x25,0x27,0x28,0x29,0x2A],[0x33,0x93,0xF8,0xDF,0xC7,0x29,0xC9,0x7F,0x54,0x80,0xB9,0x50,0xBC,0x96,0x66,0xB0],[0xD1,0x54,0xDC,0xAF,0xAD,0x8B,0x20,0x7F,0xA5,0xCB,0xC9,0x5E,0x99,0x96,0xB5,0x59]], - [[0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E,0x40,0x41,0x42,0x43,0x45,0x46,0x47,0x48],[0x60,0x68,0x34,0xC8,0xCE,0x06,0x3F,0x32,0x34,0xCF,0x11,0x45,0x32,0x5D,0xBD,0x71],[0x49,0x34,0xD5,0x41,0xE8,0xB4,0x6F,0xA3,0x39,0xC8,0x05,0xA7,0xAE,0xB9,0xE5,0xDA]], - [[0x4A,0x4B,0x4C,0x4D,0x4F,0x50,0x51,0x52,0x54,0x55,0x56,0x57,0x59,0x5A,0x5B,0x5C,0x5E,0x5F,0x60,0x61,0x63,0x64,0x65,0x66],[0xFE,0xC1,0xC0,0x4F,0x52,0x9B,0xBD,0x17,0xD8,0xCE,0xCF,0xCC,0x47,0x18,0xB1,0x7F],[0x62,0x56,0x4C,0x73,0x8F,0x3E,0xFE,0x18,0x6E,0x1A,0x12,0x7A,0x0C,0x4D,0x3C,0x61]], - [[0x68,0x69,0x6A,0x6B,0x6D,0x6E,0x6F,0x70,0x72,0x73,0x74,0x75,0x77,0x78,0x79,0x7A,0x7C,0x7D,0x7E,0x7F,0x81,0x82,0x83,0x84],[0x32,0xDF,0x99,0xB4,0x31,0xED,0x5D,0xC5,0xAC,0xF8,0xCA,0xF6,0xDC,0x6C,0xE4,0x75],[0x07,0x80,0x5A,0xA0,0x43,0x98,0x6E,0xB2,0x36,0x93,0xE2,0x3B,0xEF,0x8F,0x34,0x38]], - [[0x86,0x87,0x88,0x89,0x8B,0x8C,0x8D,0x8E,0x90,0x91,0x92,0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,0x9D,0x9F,0xA0,0xA1,0xA2],[0x7F,0xDC,0x2B,0x74,0x6F,0x3F,0x66,0x52,0x96,0x94,0x3B,0x83,0x71,0x0D,0x1F,0x82],[0xDF,0x0B,0x49,0x31,0x03,0x8B,0xAD,0xE8,0x48,0xDE,0xE3,0xB4,0xB8,0x5A,0xA4,0x4B]], - [[0xA4,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0],[0x8F,0xBA,0x15,0x10,0xA3,0xC5,0xB8,0x7E,0x2E,0xAA,0x3F,0x7A,0x91,0x45,0x5C,0xA2],[0x59,0x2D,0x5F,0xDE,0xD7,0x65,0x82,0xE4,0x14,0x3C,0x65,0x09,0x93,0x09,0x47,0x7C]]]; - - var testvectors256 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26],[0x83,0x4E,0xAD,0xFC,0xCA,0xC7,0xE1,0xB3,0x06,0x64,0xB1,0xAB,0xA4,0x48,0x15,0xAB],[0x19,0x46,0xDA,0xBF,0x6A,0x03,0xA2,0xA2,0xC3,0xD0,0xB0,0x50,0x80,0xAE,0xD6,0xFC]], - [[0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A,0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E],[0xD9,0xDC,0x4D,0xBA,0x30,0x21,0xB0,0x5D,0x67,0xC0,0x51,0x8F,0x72,0xB6,0x2B,0xF1],[0x5E,0xD3,0x01,0xD7,0x47,0xD3,0xCC,0x71,0x54,0x45,0xEB,0xDE,0xC6,0x2F,0x2F,0xB4]], - [[0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58,0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0xA2,0x91,0xD8,0x63,0x01,0xA4,0xA7,0x39,0xF7,0x39,0x21,0x73,0xAA,0x3C,0x60,0x4C],[0x65,0x85,0xC8,0xF4,0x3D,0x13,0xA6,0xBE,0xAB,0x64,0x19,0xFC,0x59,0x35,0xB9,0xD0]], - [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E],[0x42,0x64,0xB2,0x69,0x64,0x98,0xDE,0x4D,0xF7,0x97,0x88,0xA9,0xF8,0x3E,0x93,0x90],[0x2A,0x5B,0x56,0xA5,0x96,0x68,0x0F,0xCC,0x0E,0x05,0xF5,0xE0,0xF1,0x51,0xEC,0xAE]], - [[0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2,0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6],[0xEE,0x99,0x32,0xB3,0x72,0x18,0x04,0xD5,0xA8,0x3E,0xF5,0x94,0x92,0x45,0xB6,0xF6],[0xF5,0xD6,0xFF,0x41,0x4F,0xD2,0xC6,0x18,0x14,0x94,0xD2,0x0C,0x37,0xF2,0xB8,0xC4]], - [[0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0,0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0xE6,0x24,0x8F,0x55,0xC5,0xFD,0xCB,0xCA,0x9C,0xBB,0xB0,0x1C,0x88,0xA2,0xEA,0x77],[0x85,0x39,0x9C,0x01,0xF5,0x9F,0xFF,0xB5,0x20,0x4F,0x19,0xF8,0x48,0x2F,0x00,0xB8]], - [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02,0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16],[0xB8,0x35,0x8E,0x41,0xB9,0xDF,0xF6,0x5F,0xD4,0x61,0xD5,0x5A,0x99,0x26,0x62,0x47],[0x92,0x09,0x7B,0x4C,0x88,0xA0,0x41,0xDD,0xF9,0x81,0x44,0xBC,0x8D,0x22,0xE8,0xE7]], - [[0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20,0x22,0x23,0x24,0x25,0x27,0x28,0x29,0x2A,0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E],[0xF0,0xE2,0xD7,0x22,0x60,0xAF,0x58,0xE2,0x1E,0x01,0x5A,0xB3,0xA4,0xC0,0xD9,0x06],[0x89,0xBD,0x5B,0x73,0xB3,0x56,0xAB,0x41,0x2A,0xEF,0x9F,0x76,0xCE,0xA2,0xD6,0x5C]], - [[0x40,0x41,0x42,0x43,0x45,0x46,0x47,0x48,0x4A,0x4B,0x4C,0x4D,0x4F,0x50,0x51,0x52,0x54,0x55,0x56,0x57,0x59,0x5A,0x5B,0x5C,0x5E,0x5F,0x60,0x61,0x63,0x64,0x65,0x66],[0x47,0x5B,0x8B,0x82,0x3C,0xE8,0x89,0x3D,0xB3,0xC4,0x4A,0x9F,0x2A,0x37,0x9F,0xF7],[0x25,0x36,0x96,0x90,0x93,0xC5,0x5F,0xF9,0x45,0x46,0x92,0xF2,0xFA,0xC2,0xF5,0x30]], - [[0x68,0x69,0x6A,0x6B,0x6D,0x6E,0x6F,0x70,0x72,0x73,0x74,0x75,0x77,0x78,0x79,0x7A,0x7C,0x7D,0x7E,0x7F,0x81,0x82,0x83,0x84,0x86,0x87,0x88,0x89,0x8B,0x8C,0x8D,0x8E],[0x68,0x8F,0x52,0x81,0x94,0x58,0x12,0x86,0x2F,0x5F,0x30,0x76,0xCF,0x80,0x41,0x2F],[0x07,0xFC,0x76,0xA8,0x72,0x84,0x3F,0x3F,0x6E,0x00,0x81,0xEE,0x93,0x96,0xD6,0x37]], - [[0x90,0x91,0x92,0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,0x9D,0x9F,0xA0,0xA1,0xA2,0xA4,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,0xB1,0xB3,0xB4,0xB5,0xB6],[0x08,0xD1,0xD2,0xBC,0x75,0x0A,0xF5,0x53,0x36,0x5D,0x35,0xE7,0x5A,0xFA,0xCE,0xAA],[0xE3,0x8B,0xA8,0xEC,0x2A,0xA7,0x41,0x35,0x8D,0xCC,0x93,0xE8,0xF1,0x41,0xC4,0x91]], - [[0xB8,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC5,0xC7,0xC8,0xC9,0xCA,0xCC,0xCD,0xCE,0xCF,0xD1,0xD2,0xD3,0xD4,0xD6,0xD7,0xD8,0xD9,0xDB,0xDC,0xDD,0xDE],[0x87,0x07,0x12,0x1F,0x47,0xCC,0x3E,0xFC,0xEC,0xA5,0xF9,0xA8,0x47,0x49,0x50,0xA1],[0xD0,0x28,0xEE,0x23,0xE4,0xA8,0x90,0x75,0xD0,0xB0,0x3E,0x86,0x8D,0x7D,0x3A,0x42]], - [[0xE0,0xE1,0xE2,0xE3,0xE5,0xE6,0xE7,0xE8,0xEA,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,0xFC,0xFE,0xFE,0x01,0x01,0x03,0x04,0x05,0x06],[0xE5,0x1A,0xA0,0xB1,0x35,0xDB,0xA5,0x66,0x93,0x9C,0x3B,0x63,0x59,0xA9,0x80,0xC5],[0x8C,0xD9,0x42,0x3D,0xFC,0x45,0x9E,0x54,0x71,0x55,0xC5,0xD1,0xD5,0x22,0xE5,0x40]], - [[0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A,0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E],[0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21],[0x08,0x0E,0x95,0x17,0xEB,0x16,0x77,0x71,0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3]], - [[0x30,0x31,0x32,0x33,0x35,0x36,0x37,0x38,0x3A,0x3B,0x3C,0x3D,0x3F,0x40,0x41,0x42,0x44,0x45,0x46,0x47,0x49,0x4A,0x4B,0x4C,0x4E,0x4F,0x50,0x51,0x53,0x54,0x55,0x56],[0x72,0x61,0x65,0xC1,0x72,0x3F,0xBC,0xF6,0xC0,0x26,0xD7,0xD0,0x0B,0x09,0x10,0x27],[0x7C,0x17,0x00,0x21,0x1A,0x39,0x91,0xFC,0x0E,0xCD,0xED,0x0A,0xB3,0xE5,0x76,0xB0]]]; - - var res = true; - var j = 0; - for (var i = 0; i < testvectors128.length; i++) { - var res2 = test_aes(testvectors128[i][1],testvectors128[i][0],testvectors128[i][2]); - res &= res2; - if (!res2) { - result[j] = new unit.result("Testing 128 bit key vector with block "+ - util.hexidump(testvectors128[i][1])+ - " and key "+util.hexidump(testvectors128[i][0])+ - " should be "+util.hexidump(testvectors128[i][2]), - false); - j++; - } - } - if (res) { - result[j] = new unit.result("128 bit key test vectors completed.",true) - j++; - } - - res = true; - for (var i = 0; i < testvectors192.length; i++) { - var res2 = test_aes(testvectors192[i][1],testvectors192[i][0],testvectors192[i][2]); - res &= res2; - if (!res2) { - result[j] = new unit.result("Testing 192 bit key vector with block "+ - util.hexidump(testvectors192[i][1])+ - " and key "+util.hexidump(testvectors192[i][0])+ - " should be "+util.hexidump(testvectors192[i][2]), - false); - j++; - } - } - if (res) { - result[j] = new unit.result("192 bit key test vectors completed.",true) - j++; - } - - res = true; - for (var i = 0; i < testvectors256.length; i++) { - var res2 = test_aes(testvectors256[i][1],testvectors256[i][0],testvectors256[i][2]); - res &= res2; - if (!res2) { - result[j] = new unit.result("Testing 256 bit key vector with block "+ - util.hexidump(testvectors256[i][1])+ - " and key "+util.hexidump(testvectors256[i][0])+ - " should be "+util.hexidump(testvectors256[i][2]), - false); - j++; - } - } - if (res) { - result[j] = new unit.result("256 bit key test vectors completed.", true) - j++; - } - - return result; -}); - -},{"../../../":29,"../../unit.js":73}],59:[function(require,module,exports){ -var unit = require('../../unit.js'); - -unit.register("Blowfish cipher test with test vectors from http://www.schneier.com/code/vectors.txt", function() { - var openpgp = require('../../../'), - util = openpgp.util, - BFencrypt = openpgp.crypto.cipher.blowfish; - - var result = []; - function test_bf(input, key, output) { - var blowfish = new openpgp.crypto.cipher.blowfish(util.bin2str(key)); - var result = util.bin2str(blowfish.encrypt(input)); - - return (util.hexstrdump(result) == util.hexstrdump(util.bin2str(output))); - } - var testvectors = [[[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78]], - [[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x51,0x86,0x6F,0xD5,0xB8,0x5E,0xCB,0x8A]], - [[0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01],[0x7D,0x85,0x6F,0x9A,0x61,0x30,0x63,0xF2]], - [[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x24,0x66,0xDD,0x87,0x8B,0x96,0x3C,0x9D]], - [[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x61,0xF9,0xC3,0x80,0x22,0x81,0xB0,0x96]], - [[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x7D,0x0C,0xC6,0x30,0xAF,0xDA,0x1E,0xC7]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78]], - [[0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x0A,0xCE,0xAB,0x0F,0xC6,0xA0,0xA2,0x8D]], - [[0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57],[0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42],[0x59,0xC6,0x82,0x45,0xEB,0x05,0x28,0x2B]], - [[0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E],[0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA],[0xB1,0xB8,0xCC,0x0B,0x25,0x0F,0x09,0xA0]], - [[0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86],[0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72],[0x17,0x30,0xE5,0x77,0x8B,0xEA,0x1D,0xA4]], - [[0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E],[0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A],[0xA2,0x5E,0x78,0x56,0xCF,0x26,0x51,0xEB]], - [[0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6],[0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2],[0x35,0x38,0x82,0xB1,0x09,0xCE,0x8F,0x1A]], - [[0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE],[0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A],[0x48,0xF4,0xD0,0x88,0x4C,0x37,0x99,0x18]], - [[0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6],[0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2],[0x43,0x21,0x93,0xB7,0x89,0x51,0xFC,0x98]], - [[0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE],[0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A],[0x13,0xF0,0x41,0x54,0xD6,0x9D,0x1A,0xE5]], - [[0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16],[0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02],[0x2E,0xED,0xDA,0x93,0xFF,0xD3,0x9C,0x79]], - [[0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F],[0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A],[0xD8,0x87,0xE0,0x39,0x3C,0x2D,0xA6,0xE3]], - [[0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46],[0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32],[0x5F,0x99,0xD0,0x4F,0x5B,0x16,0x39,0x69]], - [[0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E],[0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA],[0x4A,0x05,0x7A,0x3B,0x24,0xD3,0x97,0x7B]], - [[0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76],[0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62],[0x45,0x20,0x31,0xC1,0xE4,0xFA,0xDA,0x8E]], - [[0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07],[0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2],[0x75,0x55,0xAE,0x39,0xF5,0x9B,0x87,0xBD]], - [[0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F],[0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA],[0x53,0xC5,0x5F,0x9C,0xB4,0x9F,0xC0,0x19]], - [[0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7],[0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92],[0x7A,0x8E,0x7B,0xFA,0x93,0x7E,0x89,0xA3]], - [[0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF],[0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A],[0xCF,0x9C,0x5D,0x7A,0x49,0x86,0xAD,0xB5]], - [[0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6],[0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2],[0xD1,0xAB,0xB2,0x90,0x65,0x8B,0xC7,0x78]], - [[0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF],[0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A],[0x55,0xCB,0x37,0x74,0xD1,0x3E,0xF2,0x01]], - [[0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0xFA,0x34,0xEC,0x48,0x47,0xB2,0x68,0xB2]], - [[0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0xA7,0x90,0x79,0x51,0x08,0xEA,0x3C,0xAE]], - [[0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0xC3,0x9E,0x07,0x2D,0x9F,0xAC,0x63,0x1D]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x01,0x49,0x33,0xE0,0xCD,0xAF,0xF6,0xE4]], - [[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0xF2,0x1E,0x9A,0x77,0xB7,0x1C,0x49,0xBC]], - [[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x24,0x59,0x46,0x88,0x57,0x54,0x36,0x9A]], - [[0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10],[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x6B,0x5C,0x5A,0x9C,0x5D,0x9E,0x0A,0x5A]]]; - - var res = true; - var j = 0; - for (var i = 0; i < testvectors.length; i++) { - var res2 = test_bf(testvectors[i][1],testvectors[i][0],testvectors[i][2]); - res &= res2; - if (!res2) { - result[j] = new unit.result("Testing vector "+i+" with block "+ - util.hexidump(testvectors[i][0])+ - " and key "+util.hexidump(testvectors[i][1])+ - " should be "+util.hexidump(testvectors[i][2]), false); - j++; - } - } - if (res) { - result[j] = new unit.result("34 test vectors completed ", true); - } - return result; -}); - -},{"../../../":29,"../../unit.js":73}],60:[function(require,module,exports){ -var unit = require('../../unit.js'); - -unit.register("CAST-128 cipher test with test vectors from RFC2144", function() { - var openpgp = require('../../../'), - util = openpgp.util; - - var result = []; - function test_cast(input, key, output) { - var cast5 = new openpgp.crypto.cipher.cast5(util.bin2str(key)); - var result = util.bin2str(cast5.encrypt(input)); - - return util.hexstrdump(result) == util.hexstrdump(util.bin2str(output)); - } - - var testvectors = [[[0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x23,0x8B,0x4F,0xE5,0x84,0x7E,0x44,0xB2]]]; - - for (var i = 0; i < testvectors.length; i++) { - result[i] = new unit.result("Testing vector with block "+ - util.hexidump(testvectors[i][0])+ - " and key "+util.hexidump(testvectors[i][1])+ - " should be "+util.hexidump(testvectors[i][2]), - test_cast(testvectors[i][1],testvectors[i][0],testvectors[i][2])); - } - return result; -}); - -},{"../../../":29,"../../unit.js":73}],61:[function(require,module,exports){ -var unit = require('../../unit.js'); - -unit.register("TripleDES (EDE) cipher test with test vectors from http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf", function() { - var openpgp = require('../../../'), - util = openpgp.util; - - var result = []; - var key = util.bin2str([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]); - var testvectors = [[[0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00]], - [[0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0xDD,0x7F,0x12,0x1C,0xA5,0x01,0x56,0x19]], - [[0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x2E,0x86,0x53,0x10,0x4F,0x38,0x34,0xEA]], - [[0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4B,0xD3,0x88,0xFF,0x6C,0xD8,0x1D,0x4F]], - [[0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x20,0xB9,0xE7,0x67,0xB2,0xFB,0x14,0x56]], - [[0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x55,0x57,0x93,0x80,0xD7,0x71,0x38,0xEF]], - [[0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x6C,0xC5,0xDE,0xFA,0xAF,0x04,0x51,0x2F]], - [[0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x0D,0x9F,0x27,0x9B,0xA5,0xD8,0x72,0x60]], - [[0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00],[0xD9,0x03,0x1B,0x02,0x71,0xBD,0x5A,0x0A]], - [[0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00],[0x42,0x42,0x50,0xB3,0x7C,0x3D,0xD9,0x51]], - [[0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00],[0xB8,0x06,0x1B,0x7E,0xCD,0x9A,0x21,0xE5]], - [[0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00],[0xF1,0x5D,0x0F,0x28,0x6B,0x65,0xBD,0x28]], - [[0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00],[0xAD,0xD0,0xCC,0x8D,0x6E,0x5D,0xEB,0xA1]], - [[0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00],[0xE6,0xD5,0xF8,0x27,0x52,0xAD,0x63,0xD1]], - [[0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00],[0xEC,0xBF,0xE3,0xBD,0x3F,0x59,0x1A,0x5E]], - [[0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00],[0xF3,0x56,0x83,0x43,0x79,0xD1,0x65,0xCD]], - [[0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00],[0x2B,0x9F,0x98,0x2F,0x20,0x03,0x7F,0xA9]], - [[0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00],[0x88,0x9D,0xE0,0x68,0xA1,0x6F,0x0B,0xE6]], - [[0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00],[0xE1,0x9E,0x27,0x5D,0x84,0x6A,0x12,0x98]], - [[0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00],[0x32,0x9A,0x8E,0xD5,0x23,0xD7,0x1A,0xEC]], - [[0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00],[0xE7,0xFC,0xE2,0x25,0x57,0xD2,0x3C,0x97]], - [[0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00],[0x12,0xA9,0xF5,0x81,0x7F,0xF2,0xD6,0x5D]], - [[0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00],[0xA4,0x84,0xC3,0xAD,0x38,0xDC,0x9C,0x19]], - [[0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00],[0xFB,0xE0,0x0A,0x8A,0x1E,0xF8,0xAD,0x72]], - [[0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00],[0x75,0x0D,0x07,0x94,0x07,0x52,0x13,0x63]], - [[0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00],[0x64,0xFE,0xED,0x9C,0x72,0x4C,0x2F,0xAF]], - [[0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00],[0xF0,0x2B,0x26,0x3B,0x32,0x8E,0x2B,0x60]], - [[0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00],[0x9D,0x64,0x55,0x5A,0x9A,0x10,0xB8,0x52]], - [[0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00],[0xD1,0x06,0xFF,0x0B,0xED,0x52,0x55,0xD7]], - [[0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00],[0xE1,0x65,0x2C,0x6B,0x13,0x8C,0x64,0xA5]], - [[0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00],[0xE4,0x28,0x58,0x11,0x86,0xEC,0x8F,0x46]], - [[0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00],[0xAE,0xB5,0xF5,0xED,0xE2,0x2D,0x1A,0x36]], - [[0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00],[0xE9,0x43,0xD7,0x56,0x8A,0xEC,0x0C,0x5C]], - [[0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00],[0xDF,0x98,0xC8,0x27,0x6F,0x54,0xB0,0x4B]], - [[0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00],[0xB1,0x60,0xE4,0x68,0x0F,0x6C,0x69,0x6F]], - [[0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00],[0xFA,0x07,0x52,0xB0,0x7D,0x9C,0x4A,0xB8]], - [[0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00],[0xCA,0x3A,0x2B,0x03,0x6D,0xBC,0x85,0x02]], - [[0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00],[0x5E,0x09,0x05,0x51,0x7B,0xB5,0x9B,0xCF]], - [[0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00],[0x81,0x4E,0xEB,0x3B,0x91,0xD9,0x07,0x26]], - [[0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00],[0x4D,0x49,0xDB,0x15,0x32,0x91,0x9C,0x9F]], - [[0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00],[0x25,0xEB,0x5F,0xC3,0xF8,0xCF,0x06,0x21]], - [[0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00],[0xAB,0x6A,0x20,0xC0,0x62,0x0D,0x1C,0x6F]], - [[0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00],[0x79,0xE9,0x0D,0xBC,0x98,0xF9,0x2C,0xCA]], - [[0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00],[0x86,0x6E,0xCE,0xDD,0x80,0x72,0xBB,0x0E]], - [[0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00],[0x8B,0x54,0x53,0x6F,0x2F,0x3E,0x64,0xA8]], - [[0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00],[0xEA,0x51,0xD3,0x97,0x55,0x95,0xB8,0x6B]], - [[0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00],[0xCA,0xFF,0xC6,0xAC,0x45,0x42,0xDE,0x31]], - [[0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00],[0x8D,0xD4,0x5A,0x2D,0xDF,0x90,0x79,0x6C]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00],[0x10,0x29,0xD5,0x5E,0x88,0x0E,0xC2,0xD0]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00],[0x5D,0x86,0xCB,0x23,0x63,0x9D,0xBE,0xA9]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00],[0x1D,0x1C,0xA8,0x53,0xAE,0x7C,0x0C,0x5F]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00],[0xCE,0x33,0x23,0x29,0x24,0x8F,0x32,0x28]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00],[0x84,0x05,0xD1,0xAB,0xE2,0x4F,0xB9,0x42]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00],[0xE6,0x43,0xD7,0x80,0x90,0xCA,0x42,0x07]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00],[0x48,0x22,0x1B,0x99,0x37,0x74,0x8A,0x23]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00],[0xDD,0x7C,0x0B,0xBD,0x61,0xFA,0xFD,0x54]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80],[0x2F,0xBC,0x29,0x1A,0x57,0x0D,0xB5,0xC4]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40],[0xE0,0x7C,0x30,0xD7,0xE4,0xE2,0x6E,0x12]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20],[0x09,0x53,0xE2,0x25,0x8E,0x8E,0x90,0xA1]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10],[0x5B,0x71,0x1B,0xC4,0xCE,0xEB,0xF2,0xEE]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08],[0xCC,0x08,0x3F,0x1E,0x6D,0x9E,0x85,0xF6]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04],[0xD2,0xFD,0x88,0x67,0xD5,0x0D,0x2D,0xFE]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02],[0x06,0xE7,0xEA,0x22,0xCE,0x92,0x70,0x8F]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01],[0x16,0x6B,0x40,0xB4,0x4A,0xBA,0x4B,0xD6]]]; - - var res = true; - var j = 0; - for (var i = 0; i < testvectors.length; i++) { - var des = new openpgp.crypto.cipher.des(key); - - var encr = util.bin2str(des.encrypt(testvectors[i][0], key)); - var res2 = encr == util.bin2str(testvectors[i][1]); - - res &= res2; - - if (!res2) { - result[j] = new unit.result("Testing vector with block " + - util.hexidump(testvectors[i][0]) + - " and key " + util.hexstrdump(key) + - " should be " + util.hexidump(testvectors[i][1]) + " != " + - util.hexidump(encr), - false); - j++; - } - } - if (res) { - result[j] = new unit.result("All 3DES EDE test vectors completed", true); - } - return result; -}); - - -unit.register("DES encrypt/decrypt padding tests", function () { - var openpgp = require('../../../'), - util = openpgp.util; - - var result = []; - var key = util.bin2str([0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF]); - var testvectors = new Array(); - testvectors[0] = [[[0x01], [0x24, 0xC7, 0x4A, 0x9A, 0x79, 0x75, 0x4B, 0xC7]], - [[0x02, 0x03], [0xA7, 0x7A, 0x9A, 0x59, 0x8A, 0x86, 0x85, 0xC5]], - [[0x03, 0x04, 0x05], [0x01, 0xCF, 0xEB, 0x6A, 0x74, 0x60, 0xF5, 0x02]], - [[0x04, 0x05, 0x06, 0x07], [0xA8, 0xF0, 0x3D, 0x59, 0xBA, 0x6B, 0x0E, 0x76]], - [[0x05, 0x06, 0x07, 0x08, 0x09], [0x86, 0x40, 0x33, 0x61, 0x3F, 0x55, 0x73, 0x49]], - [[0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B], [0x13, 0x21, 0x3E, 0x0E, 0xCE, 0x2C, 0x94, 0x01]], - [[0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D], [0x30, 0x49, 0x97, 0xC1, 0xDA, 0xD5, 0x59, 0xA5]], - [[0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F], [0x83, 0x25, 0x79, 0x06, 0x54, 0xA4, 0x44, 0xD9]]]; - testvectors[1] = [[[0x01], [0xF2, 0xAB, 0x1C, 0x9E, 0x70, 0x7D, 0xCC, 0x92]], - [[0x02, 0x03], [0x6B, 0x4C, 0x67, 0x24, 0x9F, 0xB7, 0x4D, 0xAC]], - [[0x03, 0x04, 0x05], [0x68, 0x95, 0xAB, 0xA8, 0xEA, 0x53, 0x13, 0x23]], - [[0x04, 0x05, 0x06, 0x07], [0xC8, 0xDE, 0x60, 0x8F, 0xF6, 0x09, 0x90, 0xB5]], - [[0x05, 0x06, 0x07, 0x08, 0x09], [0x19, 0x13, 0x50, 0x20, 0x70, 0x40, 0x2E, 0x09]], - [[0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B], [0xA8, 0x23, 0x40, 0xC6, 0x17, 0xA6, 0x31, 0x4A]], - [[0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D], [0x36, 0x62, 0xF2, 0x99, 0x68, 0xD4, 0xBF, 0x7C]], - [[0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F], [0x83, 0x25, 0x79, 0x06, 0x54, 0xA4, 0x44, 0xD9, 0x08, 0x6F, 0x9A, 0x1D, 0x74, 0xC9, 0x4D, 0x4E]]]; - testvectors[2] = [[[0x01], [0x83, 0x68, 0xE4, 0x9C, 0x84, 0xCC, 0xCB, 0xF0]], - [[0x02, 0x03], [0xBB, 0xA8, 0x0B, 0x66, 0x1B, 0x62, 0xC4, 0xC8]], - [[0x03, 0x04, 0x05], [0x9A, 0xD7, 0x5A, 0x24, 0xFD, 0x3F, 0xBF, 0x22]], - [[0x04, 0x05, 0x06, 0x07], [0x14, 0x4E, 0x68, 0x6D, 0x2E, 0xC1, 0xB7, 0x52]], - [[0x05, 0x06, 0x07, 0x08, 0x09], [0x12, 0x0A, 0x51, 0x08, 0xF9, 0xA3, 0x03, 0x74]], - [[0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B], [0xB2, 0x07, 0xD1, 0x05, 0xF6, 0x67, 0xAF, 0xBA]], - [[0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D], [0xCA, 0x59, 0x61, 0x3A, 0x83, 0x23, 0x26, 0xDD]], - [[0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F], [0x83, 0x25, 0x79, 0x06, 0x54, 0xA4, 0x44, 0xD9]]]; - - var des = new openpgp.crypto.cipher.originalDes(key); - - var res = true; - var j = 0; - - for (var padding = 0; padding < 3; padding++) { - var thisVectorSet = testvectors[padding]; - - for (var i = 0; i < thisVectorSet.length; i++) { - var encrypted = des.encrypt(thisVectorSet[i][0], padding); - var decrypted = des.decrypt(encrypted, padding); - - var res2 = (util.bin2str(encrypted) == util.bin2str(thisVectorSet[i][1])); - var res3 = (util.bin2str(decrypted) == util.bin2str(thisVectorSet[i][0])); - res &= res2; - res &= res3; - if (!res2 || !res3) { - result[j] = new unit.result( - "Testing vector with block [" + - util.hexidump(thisVectorSet[i][0]) + - "] and key [" + util.hexstrdump(key) + - "] and padding [" + padding + - "] should be " + util.hexidump(thisVectorSet[i][1]) + " - Actually [ENC:" + util.hexidump(encrypted) + ", DEC:" + util.hexidump(decrypted) + "]", - false); - j++; - } - } - } - if (res) { - result[j] = new unit.result("All DES test vectors completed", true); - } - return result; -}); - -},{"../../../":29,"../../unit.js":73}],62:[function(require,module,exports){ -var unit = require('../../unit.js'); - -unit.register("Twofish test with test vectors from http://www.schneier.com/code/ecb_ival.txt", function() { - var openpgp = require('../../../'), - util = openpgp.util; - - function TFencrypt(block, key) { - var tf = new openpgp.crypto.cipher.twofish(key); - - return tf.encrypt(block); - } - - - var result = []; - var start = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; - var start_short = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; - var testvectors = [[0x57,0xFF,0x73,0x9D,0x4D,0xC9,0x2C,0x1B,0xD7,0xFC,0x01,0x70,0x0C,0xC8,0x21,0x6F], - [0xD4,0x3B,0xB7,0x55,0x6E,0xA3,0x2E,0x46,0xF2,0xA2,0x82,0xB7,0xD4,0x5B,0x4E,0x0D], - [0x90,0xAF,0xE9,0x1B,0xB2,0x88,0x54,0x4F,0x2C,0x32,0xDC,0x23,0x9B,0x26,0x35,0xE6], - [0x6C,0xB4,0x56,0x1C,0x40,0xBF,0x0A,0x97,0x05,0x93,0x1C,0xB6,0xD4,0x08,0xE7,0xFA], - [0x30,0x59,0xD6,0xD6,0x17,0x53,0xB9,0x58,0xD9,0x2F,0x47,0x81,0xC8,0x64,0x0E,0x58], - [0xE6,0x94,0x65,0x77,0x05,0x05,0xD7,0xF8,0x0E,0xF6,0x8C,0xA3,0x8A,0xB3,0xA3,0xD6], - [0x5A,0xB6,0x7A,0x5F,0x85,0x39,0xA4,0xA5,0xFD,0x9F,0x03,0x73,0xBA,0x46,0x34,0x66], - [0xDC,0x09,0x6B,0xCD,0x99,0xFC,0x72,0xF7,0x99,0x36,0xD4,0xC7,0x48,0xE7,0x5A,0xF7], - [0xC5,0xA3,0xE7,0xCE,0xE0,0xF1,0xB7,0x26,0x05,0x28,0xA6,0x8F,0xB4,0xEA,0x05,0xF2], - [0x43,0xD5,0xCE,0xC3,0x27,0xB2,0x4A,0xB9,0x0A,0xD3,0x4A,0x79,0xD0,0x46,0x91,0x51]]; - testvectors[47] = [0x43,0x10,0x58,0xF4,0xDB,0xC7,0xF7,0x34,0xDA,0x4F,0x02,0xF0,0x4C,0xC4,0xF4,0x59]; - testvectors[48] = [0x37,0xFE,0x26,0xFF,0x1C,0xF6,0x61,0x75,0xF5,0xDD,0xF4,0xC3,0x3B,0x97,0xA2,0x05]; - var res = true; - var j = 0; - for (var i = 0; i < 49; i++) { - var res2 = false; - var blk, key, ct; - if (i === 0) { - blk = start_short; - key = util.bin2str(start); - ct = testvectors[0]; - res2 = (util.bin2str(TFencrypt(blk,key)) == util.bin2str(ct)); - } else if (i === 1) { - blk = testvectors[0]; - key = util.bin2str(start); - ct = testvectors[1]; - res2 = (util.bin2str(TFencrypt(blk,key)) == util.bin2str(ct)); - } else if (i === 2) { - blk = testvectors[i-1]; - key = util.bin2str(testvectors[i-2].concat(start_short)); - ct = testvectors[i]; - res2 = (util.bin2str(TFencrypt(blk,key)) == util.bin2str(ct)); - } else if (i < 10 || i > 46) { - blk = testvectors[i-1]; - key = util.bin2str(testvectors[i-2].concat(testvectors[i-3])); - ct = testvectors[i]; - res2 = (util.bin2str(TFencrypt(blk,key)) == util.bin2str(ct)); - } else { - testvectors[i] = TFencrypt(testvectors[i-1],util.bin2str(testvectors[i-2].concat(testvectors[i-3]))); - res2 = true; - } - res &= res2; - if (!res2) { - result[j] = new unit.result("Testing vector with block "+util.hexidump(blk)+" with key "+ util.hexstrdump(key) +" should be "+util.hexidump(ct)+" but is "+util.hexidump(TFencrypt(blk,key)), false); - j++; - } - } - if (res) { - result[j] = new unit.result("49 test vectors completed", true); - } - return result; -}); - -},{"../../../":29,"../../unit.js":73}],63:[function(require,module,exports){ -var unit = require('../unit.js'); - -unit.register("Functional testing of openpgp.crypto.* methods", function() { - var openpgp = require('../../'); - var util = openpgp.util; - var result = []; - var RSApubMPIstrs = [ - util.bin2str([0x08,0x00,0xac,0x15,0xb3,0xd6,0xd2,0x0f,0xf0,0x7a,0xdd,0x21,0xb7, - 0xbf,0x61,0xfa,0xca,0x93,0x86,0xc8,0x55,0x5a,0x4b,0xa6,0xa4,0x1a, - 0x60,0xa2,0x3a,0x37,0x06,0x08,0xd8,0x15,0x8e,0x85,0x45,0xaa,0xb7, - 0x1d,0x7b,0x0b,0x73,0x94,0x55,0x0c,0x5c,0xec,0xc0,0x22,0x4b,0xa1, - 0x64,0x20,0x7d,0x4d,0xa8,0x96,0x1a,0x64,0x38,0x93,0xcd,0xec,0x73, - 0x5d,0xf9,0x89,0x88,0x24,0x3d,0x48,0xff,0x3b,0x87,0x62,0xd0,0x84, - 0xea,0xff,0x39,0xb5,0x27,0x70,0xea,0x4a,0xb2,0x2e,0x9d,0xf1,0x7c, - 0x23,0xec,0xf4,0x5e,0xea,0x61,0x3d,0xe5,0xd8,0x0d,0xf9,0x59,0x6d, - 0x28,0x00,0xeb,0xcb,0xc9,0x55,0x00,0x72,0x30,0x1f,0x65,0x9d,0xd6, - 0x17,0x58,0x5f,0xa6,0x4a,0xa0,0xdd,0xe1,0x76,0xf2,0xef,0x21,0x9f, - 0x84,0xfc,0xaa,0x5b,0x52,0x6e,0xc1,0xa2,0xb9,0xbd,0xb9,0xf4,0x9e, - 0x49,0x92,0xf2,0xaf,0x57,0x86,0xf2,0xef,0x70,0xbf,0x51,0x40,0xfd, - 0xbf,0x56,0x51,0xe8,0x2c,0xa2,0x4f,0xf8,0xa4,0xd7,0x36,0x18,0x85, - 0xce,0x09,0x0d,0xbc,0x8d,0x65,0x5e,0x8a,0x1d,0x98,0xb0,0x4d,0x9d, - 0xc1,0xcf,0x82,0xe1,0xb7,0x43,0x5d,0x5a,0x72,0xcd,0x55,0xd2,0xff, - 0xb1,0xb4,0x78,0xbf,0xa1,0x7d,0xac,0xd9,0x1b,0xc4,0xfa,0x39,0x34, - 0x92,0x09,0xf9,0x08,0x2a,0x6b,0x9d,0x14,0x56,0x12,0x4c,0xe9,0xa6, - 0x29,0xc1,0xf3,0xa9,0x0b,0xfc,0x31,0x75,0x58,0x74,0x2a,0x88,0xaf, - 0xee,0xc9,0xa4,0xcd,0x15,0xdc,0x1b,0x8d,0x64,0xc1,0x36,0x17,0xc4, - 0x8d,0x5e,0x99,0x7a,0x5b,0x9f,0x39,0xd0,0x00,0x6e,0xf9]), - util.bin2str([0x00,0x11,0x01,0x00,0x01])]; - var RSAsecMPIstrs = [ - util.bin2str([0x07,0xfe,0x23,0xff,0xce,0x45,0x6c,0x60,0x65,0x40,0x6e,0xae,0x35, - 0x10,0x56,0x60,0xee,0xab,0xfa,0x10,0x42,0xba,0xc7,0x04,0xaf,0x63, - 0xcd,0x3f,0x62,0xca,0x4b,0xfa,0xe1,0xa9,0x70,0xcd,0x34,0x8b,0xc8, - 0x0e,0xe4,0xc4,0xba,0x83,0x17,0x5f,0xa4,0xb8,0xea,0x60,0xc2,0x4d, - 0x9a,0xf2,0xa9,0x03,0xeb,0xf6,0xaa,0xc2,0xb8,0x8b,0x43,0x12,0xe9, - 0xf7,0x88,0xd2,0x5a,0xa6,0xaa,0x23,0x71,0x31,0x74,0xdb,0x19,0x20, - 0x15,0x41,0x1b,0x43,0x68,0x62,0xd8,0xc0,0x93,0x91,0xe8,0xfc,0xb1, - 0xa9,0x9a,0x52,0x6c,0xe0,0xbf,0x43,0x01,0xa8,0x37,0x14,0x28,0xbf, - 0x0b,0x15,0x56,0x3e,0xa5,0x79,0xa0,0xc4,0x42,0x88,0xee,0xeb,0x1b, - 0xf4,0x7a,0x4a,0x58,0x31,0x58,0x81,0xd2,0x3e,0xde,0x07,0x64,0x92, - 0xf0,0x60,0xd3,0x9a,0x29,0xca,0xc6,0x67,0x75,0x07,0xca,0x92,0x39, - 0x56,0xf6,0x11,0x84,0xba,0x6d,0x4b,0xe6,0x6f,0x66,0xc2,0x17,0xeb, - 0x46,0x69,0x1c,0xbb,0xdf,0xc0,0x38,0x00,0xd6,0x01,0xe6,0x70,0x9d, - 0x4b,0x9b,0x70,0xed,0x5c,0xb8,0xcf,0xe8,0x68,0x71,0xbe,0x24,0x6d, - 0xb1,0xa3,0x13,0xcc,0xf1,0xbc,0x67,0xdc,0xe0,0x69,0x09,0x82,0x3c, - 0x3b,0x0f,0x14,0x98,0x48,0x30,0xb2,0x70,0xc6,0x9e,0xfa,0x46,0x8f, - 0xf1,0xc0,0x65,0x8e,0xc6,0xae,0xdc,0x47,0x91,0x13,0x1e,0xd6,0x4a, - 0xf2,0xad,0xda,0xc2,0xc7,0x39,0x78,0x99,0xde,0x57,0x14,0x45,0x7f, - 0x32,0x38,0xa3,0x44,0x0f,0xe7,0x39,0x4c,0x6f,0x0f,0x32,0x7e,0xf1, - 0x5c,0x84,0x97,0xdd,0xa0,0x0c,0x87,0x66,0x7d,0x75,0x79]), - util.bin2str([0x04,0x00,0xc2,0xbc,0x71,0xf7,0x41,0x4a,0x09,0x66,0x70,0x02,0x68, - 0x8b,0xeb,0xe2,0x34,0xd1,0x12,0x83,0x93,0x75,0xe9,0x71,0x32,0xe2, - 0xed,0x18,0x6f,0x8e,0x3a,0xff,0x22,0x70,0x28,0x01,0xbf,0x4a,0x39, - 0x41,0xbb,0x3c,0x4a,0xbc,0xb8,0x13,0xfc,0x14,0xf6,0x71,0xa1,0x44, - 0x1c,0x02,0xa1,0x73,0x81,0xcc,0xa0,0x35,0x02,0x3e,0x97,0xb5,0xc4, - 0x94,0x33,0xf1,0xd1,0xdf,0x14,0x3f,0xfb,0x8f,0xb9,0x75,0x70,0xdc, - 0x74,0x3f,0x07,0x35,0x8f,0x53,0xaa,0xb2,0xd6,0x88,0x51,0x71,0x4e, - 0x01,0x24,0xec,0x7d,0xca,0xf6,0xa2,0xb3,0xbb,0xad,0x2e,0x60,0xfb, - 0x1c,0xee,0x49,0xd0,0x4e,0x5c,0xe3,0x1f,0x88,0x48,0xe4,0x68,0x14, - 0x3d,0x71,0xba,0xd7,0x4d,0x35,0x10,0x86,0x37,0x62,0xe0,0xa5,0x0b]), - util.bin2str([0x04,0x00,0xe2,0x38,0xf9,0xc8,0x3c,0xd1,0xcf,0x62,0x93,0xc3,0x77, - 0x76,0x97,0x44,0xe8,0xc8,0xca,0x93,0x9a,0xef,0xf0,0x63,0x76,0x25, - 0x3b,0x1c,0x46,0xff,0x90,0x13,0x91,0x15,0x97,0x7e,0x88,0x95,0xd4, - 0x7f,0x2f,0x52,0x6e,0x0d,0x55,0x55,0x2e,0xf1,0x58,0x5c,0x7e,0x56, - 0xd4,0x48,0xaa,0xdb,0x8c,0x44,0x4d,0x84,0x69,0x33,0x87,0x07,0xb2, - 0x7e,0xf5,0xa0,0x60,0xfb,0x73,0x59,0x46,0x29,0xcb,0x1e,0x3f,0x7c, - 0x2f,0xa6,0x53,0xe3,0x8c,0xef,0xd5,0xeb,0xbb,0xc8,0x9a,0x8e,0x66, - 0x4a,0x47,0x2f,0xe1,0xba,0x5e,0x32,0xd4,0x52,0x04,0x88,0x9d,0x63, - 0x3e,0xba,0x71,0x2d,0xf7,0x61,0xd5,0xfc,0x26,0xbf,0xd8,0x60,0x92, - 0x7b,0x94,0xf8,0x6f,0x3d,0x97,0x0b,0x0c,0x52,0x8c,0xb3,0xb6,0x8b]), - util.bin2str([0x04,0x00,0xb7,0xc5,0x4d,0x6e,0x2f,0xdd,0xef,0xec,0x07,0x70,0xa2, - 0x7c,0x1c,0x9d,0x8e,0x66,0x60,0x7c,0x61,0x1e,0x45,0xe9,0xdc,0x82, - 0x2f,0xc5,0x7e,0x1a,0xc6,0xd0,0x92,0xc5,0x22,0x9b,0x9a,0xfb,0x73, - 0x95,0x99,0xf2,0x7c,0xdb,0x2a,0x93,0x7b,0x5a,0x29,0x73,0x24,0x16, - 0x41,0x49,0xb5,0xf2,0x5f,0xbe,0xe7,0x64,0x4d,0xda,0x52,0x9e,0xc1, - 0x41,0x40,0x5e,0x03,0x92,0x8d,0x39,0x95,0x1f,0x68,0x9f,0x00,0x2e, - 0x0c,0x6f,0xcf,0xd9,0x6d,0x68,0xf7,0x00,0x4f,0x0e,0xc8,0x0b,0xfa, - 0x51,0xe0,0x22,0xf0,0xff,0xa7,0x42,0xd4,0xde,0x0b,0x47,0x8f,0x2b, - 0xf5,0x4d,0x04,0x32,0x91,0x89,0x4b,0x0e,0x05,0x8d,0x70,0xf9,0xbb, - 0xe7,0xd6,0x76,0xea,0x0e,0x1a,0x90,0x30,0xf5,0x98,0x01,0xc5,0x73])]; - - var DSApubMPIstrs = [ - util.bin2str([0x08,0x00,0xa8,0x85,0x5c,0x28,0x05,0x94,0x03,0xbe,0x07,0x6c,0x13,0x3e,0x65, - 0xfb,0xb5,0xe1,0x99,0x7c,0xfa,0x84,0xe3,0xac,0x47,0xa5,0xc4,0x46,0xd8,0x5f, - 0x44,0xe9,0xc1,0x6b,0x69,0xf7,0x10,0x76,0x49,0xa7,0x25,0x85,0xf4,0x1b,0xed, - 0xc6,0x60,0xc4,0x5b,0xaa,0xd4,0x87,0xd6,0x8f,0x92,0x56,0x7d,0x55,0x3f,0x45, - 0xae,0x12,0x73,0xda,0x29,0x8c,0xba,0x32,0xcc,0xd7,0xa4,0xd0,0x24,0xb0,0x7c, - 0xd8,0x0c,0x3a,0x91,0x6f,0x98,0x40,0x9c,0x9a,0xa8,0xcc,0x28,0x27,0x95,0x0b, - 0xe1,0x5b,0xb9,0x3b,0x1c,0x1c,0xd2,0xec,0xab,0x07,0x25,0x8d,0x7a,0x2a,0x2b, - 0x16,0x14,0xe8,0xda,0x71,0xd2,0xab,0xba,0x85,0x14,0x0d,0xc5,0xe0,0x88,0xeb, - 0xa5,0xe2,0xd5,0x48,0x3d,0x74,0x0c,0x41,0xeb,0xfd,0xb6,0x4e,0xf9,0x2c,0x82, - 0x17,0xdd,0x64,0x1e,0x19,0x39,0xa3,0x7f,0xf9,0x00,0xcd,0x9b,0xda,0x2e,0xbd, - 0x71,0x12,0xdf,0x0d,0x7c,0x0a,0x6b,0x2d,0x21,0x3b,0x9c,0x66,0x93,0x4a,0x1e, - 0x90,0x79,0xd3,0x5a,0x5b,0xe5,0xb9,0x94,0x1b,0xe6,0x47,0x99,0x06,0x98,0xd8, - 0x2a,0xe5,0xe2,0xa6,0x95,0x6a,0x07,0xc8,0xac,0x7c,0xe9,0xfc,0xa2,0x6a,0x16, - 0x2c,0x94,0x98,0xbd,0x91,0x0a,0x7c,0x7c,0x2c,0xb9,0x7e,0xa2,0x51,0x8b,0x45, - 0x1d,0x46,0x34,0xa8,0x52,0x2b,0xdd,0xd9,0xa8,0xbc,0x46,0x78,0x66,0xe1,0x72, - 0x11,0xf1,0xcb,0x1a,0xb6,0x4e,0x05,0x54,0xf7,0xe9,0xbe,0x4c,0x25,0x59,0x08, - 0x9f,0xf8,0xea,0x25,0x97,0x33,0xd6,0xc9,0x0f,0x59,0x0e,0xfd,0x9f,0xdc,0xe2, - 0xc0,0xcf,0x2f]), - util.bin2str([0x01,0x00,0xe1,0x72,0x2c,0xd0,0xbb,0x1a,0x4f,0xb6,0xb6,0x95,0x77,0x71,0x2e, - 0x01,0x48,0x3e,0x35,0x54,0x64,0x2b,0xed,0x40,0x5f,0x65,0x0c,0x57,0x28,0x5f, - 0xfd,0xfd,0xff,0xd7]), - util.bin2str([0x07,0xff,0x5d,0x9f,0xc4,0xb5,0x63,0x25,0x9d,0x72,0x88,0xe5,0x53,0x46,0x98, - 0xe3,0xe9,0x62,0xcb,0x0c,0xa1,0xb7,0x75,0x9f,0x18,0x41,0x94,0x32,0x28,0x29, - 0x6d,0x69,0xe0,0x3f,0x7d,0x7b,0x2b,0x06,0x5a,0x33,0x5c,0xd4,0x36,0x31,0x09, - 0x54,0x85,0x9d,0xb8,0x20,0xfe,0xda,0xfc,0xcd,0x1f,0xb1,0x2c,0x15,0x08,0x9d, - 0x32,0x53,0x2f,0xc1,0x42,0x22,0x69,0xff,0x67,0x2e,0x39,0x97,0x50,0x66,0x39, - 0xda,0xcf,0xfd,0x64,0x6f,0x91,0x05,0x64,0x37,0xc5,0x07,0x24,0xaa,0x40,0xa0, - 0x75,0x82,0x1d,0x97,0x96,0x12,0xf1,0xbd,0x9e,0x09,0x26,0x3c,0x97,0x5d,0x57, - 0xb8,0x5c,0x7d,0x89,0x03,0x82,0xcd,0x40,0xe5,0x03,0xe6,0x4a,0xfb,0xbc,0xd2, - 0xef,0x7a,0x89,0x02,0x08,0xc8,0x52,0xfa,0x97,0x74,0x66,0x32,0xae,0xa6,0x52, - 0x4b,0xef,0x5f,0xce,0x91,0x23,0x3f,0xab,0x9d,0x62,0x21,0xef,0x48,0x6d,0x07, - 0x5a,0xba,0xdf,0x00,0x91,0x54,0xea,0x5c,0xfa,0x4b,0x16,0x28,0x1a,0xce,0x48, - 0xb7,0x5c,0x50,0xa5,0x59,0xa4,0xb4,0xaf,0x1f,0xeb,0x8d,0x58,0x3f,0x0a,0xa5, - 0x97,0x2b,0x51,0x56,0xe8,0x88,0xf6,0x07,0xbc,0xdf,0xfa,0x2b,0x7b,0x88,0xe0, - 0x46,0xc8,0x7a,0x3e,0xd8,0x80,0xdb,0x4d,0x87,0x61,0x4f,0x64,0xcd,0xeb,0xe8, - 0x0d,0x86,0x16,0xcc,0xdd,0x6c,0x76,0x66,0xc1,0x73,0xb7,0x08,0x98,0x89,0x2f, - 0x67,0x69,0xd1,0xfc,0x97,0x4d,0xa2,0xce,0xad,0xbb,0x6f,0xab,0xa5,0xd6,0x18, - 0xb3,0x1a,0x96,0x02,0xbc,0x31,0x42,0xa2,0xad,0x77,0xe8,0xe2,0x4c,0x99,0xf9, - 0xdd,0xbe,0xcd]), - util.bin2str([0x07,0xff,0x5d,0xfe,0x9c,0x98,0xef,0x3a,0xa6,0x49,0xf0,0x10,0x67,0x79,0x2a, - 0x9d,0x79,0x43,0x06,0xa4,0xa8,0x6b,0x1a,0x6d,0x1f,0x77,0x6e,0x00,0x31,0xb9, - 0xed,0xc9,0x66,0xff,0xf1,0x21,0x32,0xfa,0x62,0x43,0xcd,0x97,0xd3,0x3d,0xaf, - 0xb4,0x29,0x29,0x26,0x4e,0x1c,0xa0,0xad,0x1c,0x07,0x28,0x3f,0xe5,0x43,0x10, - 0xba,0xb4,0x08,0xe0,0xdc,0xa2,0xc3,0x5b,0x1f,0xbd,0x94,0xc7,0x43,0xe5,0xf2, - 0x17,0x30,0x54,0x7f,0x14,0xbe,0xf4,0xbd,0x91,0x3b,0xe4,0x36,0xa4,0x50,0x5b, - 0x37,0x89,0x5e,0xcc,0xc7,0x74,0x54,0x32,0x20,0x09,0x63,0x98,0xb7,0xd9,0xaf, - 0x7f,0xb0,0x6c,0x27,0x43,0xfe,0x52,0xe6,0x1a,0x88,0x59,0x25,0xfc,0xeb,0x43, - 0x50,0xc7,0x65,0x43,0xc1,0x86,0x73,0x58,0x53,0x3a,0xcf,0x7a,0xa3,0x1d,0x56, - 0xc8,0x4a,0x80,0x70,0xb7,0xbf,0xf2,0xa3,0xec,0xe8,0x77,0x05,0x33,0x09,0x9d, - 0xaa,0xca,0xa0,0xe1,0x64,0x64,0x6f,0x76,0x99,0x41,0x75,0x78,0x90,0xf6,0xe7, - 0x23,0xe6,0xec,0x50,0xe5,0x99,0xa8,0x3e,0x1a,0x4b,0xc9,0x88,0x58,0x66,0xae, - 0x1a,0x53,0x5e,0xe4,0xb7,0x86,0xcf,0xa6,0xe5,0xad,0xb4,0x80,0xa0,0xf1,0x0d, - 0x96,0xb8,0x41,0xd0,0x07,0x9a,0x21,0x8d,0x50,0x7f,0x4f,0x73,0x13,0xa2,0xe2, - 0x02,0x07,0xc3,0xa3,0x0f,0x09,0x18,0x7f,0xf7,0x6b,0x90,0x70,0xc0,0xf9,0x0c, - 0x67,0x8d,0x9d,0x14,0xb6,0x9d,0x32,0x82,0xd0,0xb5,0xc6,0x57,0xf0,0x91,0xd9, - 0xc3,0x26,0xae,0x9f,0xa9,0x67,0x49,0x96,0x5c,0x07,0x3e,0x47,0x5c,0xed,0x60, - 0x07,0xac,0x6a])]; - var DSAsecMPIstrs = [util.bin2str([0x01,0x00,0x9b,0x58,0xa8,0xf4,0x04,0xb1,0xd5,0x14,0x09,0xe1, - 0xe1,0xa1,0x8a,0x0b,0xa3,0xc3,0xa3,0x66,0xaa,0x27,0x99,0x50, - 0x1c,0x4d,0xba,0x24,0xee,0xdf,0xdf,0xb8,0x8e,0x8e])]; - - var ElgamalpubMPIstrs = - [util.bin2str([0x08,0x00,0xea,0xcc,0xbe,0xe2,0xe4,0x5a,0x51,0x18,0x93,0xa1,0x12,0x2f, - 0x00,0x99,0x42,0xd8,0x5c,0x1c,0x2f,0xb6,0x3c,0xd9,0x94,0x61,0xb4,0x55, - 0x8d,0x4e,0x73,0xe6,0x69,0xbc,0x1d,0x33,0xe3,0x2d,0x91,0x23,0x69,0x95, - 0x98,0xd7,0x18,0x5a,0xaf,0xa7,0x93,0xc6,0x05,0x93,0x3a,0xc7,0xea,0xd0, - 0xb1,0xa9,0xc7,0xab,0x41,0x89,0xc8,0x38,0x99,0xdc,0x1a,0x57,0x35,0x1a, - 0x27,0x62,0x40,0x71,0x9f,0x36,0x1c,0x6d,0x18,0x1c,0x93,0xf7,0xba,0x35, - 0x06,0xed,0x30,0xb8,0xd9,0x8a,0x7c,0x03,0xaf,0xba,0x40,0x1f,0x62,0xf1, - 0x6d,0x87,0x2c,0xa6,0x2e,0x46,0xb0,0xaa,0xbc,0xbc,0x93,0xfa,0x9b,0x47, - 0x3f,0x70,0x1f,0x2a,0xc2,0x66,0x9c,0x7c,0x69,0xe0,0x2b,0x05,0xee,0xb7, - 0xa7,0x7f,0xf3,0x21,0x48,0x85,0xc2,0x95,0x5f,0x6f,0x1e,0xb3,0x9b,0x97, - 0xf8,0x14,0xc3,0xff,0x4d,0x97,0x25,0x29,0x94,0x41,0x4b,0x90,0xd8,0xba, - 0x71,0x45,0x4b,0x1e,0x2f,0xca,0x82,0x5f,0x56,0x77,0xe9,0xd3,0x88,0x5d, - 0x8b,0xec,0x92,0x8b,0x8a,0x23,0x88,0x05,0xf8,0x2c,0xa8,0xf1,0x70,0x76, - 0xe7,0xbf,0x75,0xa8,0x31,0x14,0x8e,0x76,0xc8,0x01,0xa6,0x25,0x27,0x49, - 0xaf,0xdc,0xf4,0xf6,0xf4,0xce,0x90,0x84,0x15,0x2b,0x4d,0xb3,0xcc,0x77, - 0xdb,0x65,0x71,0x75,0xd3,0x00,0x1d,0x22,0xc5,0x42,0x2f,0x51,0xfa,0x7b, - 0xeb,0x6e,0x03,0xd9,0x41,0xdd,0x2d,0x1a,0xdd,0x07,0x74,0x8b,0xb7,0xa2, - 0xfa,0xb2,0x59,0x0e,0x0e,0x94,0x7c,0x00,0xad,0x95,0x23,0x42,0x91,0x18, - 0x4c,0x97,0xf1,0x27,0x62,0x77]), - util.bin2str([0x00,0x03,0x05]), - util.bin2str([0x07,0xff,0x57,0x19,0x76,0xfc,0x09,0x6a,0x7a,0xf7,0xba,0xb2,0x42,0xbf, - 0xcd,0x2b,0xc1,0x1a,0x79,0x25,0x8c,0xad,0xf4,0x3a,0x0a,0x7a,0x9b,0x4c, - 0x46,0x3c,0xe0,0x4f,0xcc,0x6e,0xe5,0x7a,0x33,0x3a,0x4e,0x80,0xcb,0xd3, - 0x62,0xd7,0x8f,0xe2,0xc8,0xb0,0xd0,0xcb,0x49,0xc9,0x9e,0x2d,0x97,0x16, - 0x3a,0x7d,0xb1,0xe1,0xd3,0xd9,0xd7,0x3f,0x20,0x60,0xe3,0x3e,0x77,0xea, - 0x0c,0xe4,0x7b,0xf0,0x39,0x1a,0x0d,0xd9,0x8f,0x73,0xd2,0x51,0xb8,0x0c, - 0x0e,0x15,0x1e,0xad,0x7c,0xd8,0x9d,0x74,0x6e,0xa2,0x17,0x6b,0x58,0x14, - 0x2b,0xb7,0xad,0x8a,0xd7,0x66,0xc0,0xdf,0xea,0x2d,0xfc,0xc4,0x6e,0x68, - 0xb6,0x4c,0x9a,0x16,0xa4,0x3d,0xc2,0x26,0x0c,0xb7,0xd4,0x13,0x7b,0x22, - 0xfd,0x84,0xd7,0x0f,0xdc,0x42,0x75,0x05,0x85,0x29,0x00,0x31,0x1d,0xec, - 0x4e,0x22,0x8b,0xf6,0x37,0x83,0x45,0xe5,0xb3,0x31,0x61,0x2c,0x02,0xa1, - 0xc6,0x9d,0xea,0xba,0x3d,0x8a,0xab,0x0f,0x61,0x5e,0x14,0x64,0x69,0x1e, - 0xa0,0x15,0x48,0x86,0xe5,0x11,0x06,0xe8,0xde,0x34,0xc7,0xa7,0x3d,0x35, - 0xd1,0x76,0xc2,0xbe,0x01,0x82,0x61,0x8d,0xe7,0x7e,0x28,0x1d,0x4e,0x8c, - 0xb9,0xe8,0x7e,0xa4,0x5f,0xa6,0x3a,0x9e,0x5d,0xac,0xf3,0x60,0x22,0x14, - 0xd5,0xd5,0xbe,0x1f,0xf0,0x19,0xe6,0x81,0xfd,0x5d,0xe1,0xf8,0x76,0x5f, - 0xe3,0xda,0xba,0x19,0xf3,0xcb,0x10,0xa0,0x6b,0xd0,0x2d,0xbe,0x40,0x42, - 0x7b,0x9b,0x15,0xa4,0x2d,0xec,0xcf,0x09,0xd6,0xe3,0x92,0xc3,0x8d,0x65, - 0x6b,0x60,0x97,0xda,0x6b,0xca])]; - - var ElgamalsecMPIstrs = [ - util.bin2str([0x01,0x52,0x02,0x80,0x87,0xf6,0xe4,0x49,0xd7,0x2e,0x3e,0xfe,0x60,0xb9, - 0xa3,0x2a,0xf0,0x67,0x58,0xe9,0xf6,0x47,0x83,0xde,0x7e,0xfb,0xbb,0xbd, - 0xdf,0x48,0x12,0x1b,0x06,0x7d,0x13,0xbc,0x3b,0x49,0xf9,0x86,0xd4,0x53, - 0xed,0x2d,0x68])]; - - var RSApubMPIs = []; - var i; - for (i = 0; i < 2; i++) { - RSApubMPIs[i] = new openpgp.mpi(); - RSApubMPIs[i].read(RSApubMPIstrs[i]); - } - - var RSAsecMPIs = []; - for (i = 0; i < 4; i++) { - RSAsecMPIs[i] = new openpgp.mpi(); - RSAsecMPIs[i].read(RSAsecMPIstrs[i]); - } - - var DSAsecMPIs = []; - for (i = 0; i < 1; i++) { - DSAsecMPIs[i] = new openpgp.mpi(); - DSAsecMPIs[i].read(DSAsecMPIstrs[i]); - } - - var DSApubMPIs = []; - for (i = 0; i < 4; i++) { - DSApubMPIs[i] = new openpgp.mpi(); - DSApubMPIs[i].read(DSApubMPIstrs[i]); - } - var ElgamalsecMPIs = []; - for (i = 0; i < 1; i++) { - ElgamalsecMPIs[i] = new openpgp.mpi(); - ElgamalsecMPIs[i].read(ElgamalsecMPIstrs[i]); - } - - var ElgamalpubMPIs = []; - for (i = 0; i < 3; i++) { - ElgamalpubMPIs[i] = new openpgp.mpi(); - ElgamalpubMPIs[i].read(ElgamalpubMPIstrs[i]); - } - - //Originally we passed public and secret MPI separately, now they are joined. Is this what we want to do long term? - // RSA - var RSAsignedData = openpgp.crypto.signature.sign(2, 1, RSApubMPIs.concat(RSAsecMPIs), "foobar"); - var RSAsignedDataMPI = new openpgp.mpi(); - RSAsignedDataMPI.read(RSAsignedData); - result[0] = new unit.result("Testing RSA Sign and Verify", - openpgp.crypto.signature.verify(1, 2, [RSAsignedDataMPI], RSApubMPIs, "foobar")); - - // DSA - var DSAsignedData = openpgp.crypto.signature.sign(2, 17, DSApubMPIs.concat(DSAsecMPIs), "foobar"); - - var DSAmsgMPIs = []; - DSAmsgMPIs[0] = new openpgp.mpi(); - DSAmsgMPIs[1] = new openpgp.mpi(); - DSAmsgMPIs[0].read(DSAsignedData.substring(0,34)); - DSAmsgMPIs[1].read(DSAsignedData.substring(34,68)); - result[1] = new unit.result("Testing DSA Sign and Verify", - openpgp.crypto.signature.verify(17, 2, DSAmsgMPIs, DSApubMPIs, "foobar")); - - var symmAlgo = "aes256"; // AES256 - var symmKey = openpgp.crypto.generateSessionKey(symmAlgo); - var symmencDataOCFB = openpgp.crypto.cfb.encrypt(openpgp.crypto.getPrefixRandom(symmAlgo), symmAlgo, "foobarfoobar1234567890", symmKey, true); - var symmencDataCFB = openpgp.crypto.cfb.encrypt(openpgp.crypto.getPrefixRandom(symmAlgo), symmAlgo, "foobarfoobar1234567890", symmKey, false); - - result[2] = new unit.result("Testing symmetric encrypt and decrypt with OpenPGP CFB resync", - openpgp.crypto.cfb.decrypt(symmAlgo,symmKey,symmencDataOCFB,true) == "foobarfoobar1234567890"); - result[3] = new unit.result("Testing symmetric encrypt and decrypt without OpenPGP CFB resync (used in modification detection code \"MDC\" packets)", - openpgp.crypto.cfb.decrypt(symmAlgo,symmKey,symmencDataCFB,false) == "foobarfoobar1234567890"); - - var RSAUnencryptedData = new openpgp.mpi(); - RSAUnencryptedData.fromBytes(openpgp.crypto.pkcs1.eme.encode(symmKey, RSApubMPIs[0].byteLength())); - var RSAEncryptedData = openpgp.crypto.publicKeyEncrypt("rsa_encrypt_sign", RSApubMPIs, RSAUnencryptedData); - - result[4] = new unit.result("Testing asymmetric encrypt and decrypt using RSA with eme_pkcs1 padding", - openpgp.crypto.pkcs1.eme.decode(openpgp.crypto.publicKeyDecrypt("rsa_encrypt_sign", RSApubMPIs.concat(RSAsecMPIs), RSAEncryptedData).write().substring(2), RSApubMPIs[0].byteLength()) == symmKey); - - var ElgamalUnencryptedData = new openpgp.mpi(); - ElgamalUnencryptedData.fromBytes(openpgp.crypto.pkcs1.eme.encode(symmKey, ElgamalpubMPIs[0].byteLength())); - var ElgamalEncryptedData = openpgp.crypto.publicKeyEncrypt("elgamal", ElgamalpubMPIs, ElgamalUnencryptedData); - - result[5] = new unit.result("Testing asymmetric encrypt and decrypt using Elgamal with eme_pkcs1 padding", - openpgp.crypto.pkcs1.eme.decode(openpgp.crypto.publicKeyDecrypt("elgamal", ElgamalpubMPIs.concat(ElgamalsecMPIs), ElgamalEncryptedData).write().substring(2), ElgamalpubMPIs[0].byteLength()) == symmKey); - - return result; -}); - -},{"../../":29,"../unit.js":73}],64:[function(require,module,exports){ -var unit = require('../../unit.js'); - -unit.register("MD5 test with test vectors from RFC 1321", function() { - var openpgp = require('../../../'), - util = openpgp.util, - MD5 = openpgp.crypto.hash.md5; - - var result = new Array(); - result[0] = new unit.result("MD5 (\"\") = d41d8cd98f00b204e9800998ecf8427e", - util.hexstrdump(MD5("")) == "d41d8cd98f00b204e9800998ecf8427e"); - result[1] = new unit.result("MD5 (\"a\") = 0cc175b9c0f1b6a831c399e269772661", - util.hexstrdump(MD5 ("abc")) == "900150983cd24fb0d6963f7d28e17f72"); - result[2] = new unit.result("MD5 (\"message digest\") = f96b697d7cb7938d525a2f31aaf161d0", - util.hexstrdump(MD5 ("message digest")) == "f96b697d7cb7938d525a2f31aaf161d0"); - result[3] = new unit.result("MD5 (\"abcdefghijklmnopqrstuvwxyz\") = c3fcd3d76192e4007dfb496cca67e13b", - util.hexstrdump(MD5 ("abcdefghijklmnopqrstuvwxyz")) == "c3fcd3d76192e4007dfb496cca67e13b"); - result[4] = new unit.result("MD5 (\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\") = d174ab98d277d9f5a5611c2c9f419d9f", - util.hexstrdump(MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")) == "d174ab98d277d9f5a5611c2c9f419d9f"); - result[5] = new unit.result("MD5 (\"12345678901234567890123456789012345678901234567890123456789012345678901234567890\") = 57edf4a22be3c955ac49da2e2107b67a", - util.hexstrdump(MD5 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890")) == "57edf4a22be3c955ac49da2e2107b67a"); - return result; -}); - -},{"../../../":29,"../../unit.js":73}],65:[function(require,module,exports){ -var unit = require('../../unit.js'); - -unit.register("RIPE-MD 160 bits test with test vectors from http://homes.esat.kuleuven.be/~bosselae/ripemd160.html", function() { - - var openpgp = require('../../../'), - util = openpgp.util, - RMDstring = openpgp.crypto.hash.ripemd; - - var result = new Array(); - result[0] = new unit.result("RMDstring (\"\") = 9c1185a5c5e9fc54612808977ee8f548b2258d31", - util.hexstrdump(RMDstring("")) == "9c1185a5c5e9fc54612808977ee8f548b2258d31"); - result[1] = new unit.result("RMDstring (\"a\") = 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", - util.hexstrdump(RMDstring("a")) == "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe"); - result[2] = new unit.result("RMDstring (\"abc\") = 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", - util.hexstrdump(RMDstring("abc")) == "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"); - result[3] = new unit.result("RMDstring (\"message digest\") = 5d0689ef49d2fae572b881b123a85ffa21595f36", - util.hexstrdump(RMDstring("message digest")) == "5d0689ef49d2fae572b881b123a85ffa21595f36"); - return result; -}); - -},{"../../../":29,"../../unit.js":73}],66:[function(require,module,exports){ -var unit = require('../../unit.js'); - - -unit.register("SHA* test with test vectors from NIST FIPS 180-2", function() { - var openpgp = require('../../../'), - util = openpgp.util, - hash = openpgp.crypto.hash; - - var result = new Array(); - - result[0] = new unit.result("SHA1 - a9993e364706816aba3e25717850c26c9cd0d89d = hash.sha1(\"abc\") ", - "a9993e364706816aba3e25717850c26c9cd0d89d" == util.hexstrdump(hash.sha1("abc"))); - result[1] = new unit.result("SHA1 - 84983e441c3bd26ebaae4aa1f95129e5e54670f1 = hash.sha1(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\") ", - "84983e441c3bd26ebaae4aa1f95129e5e54670f1" == util.hexstrdump(hash.sha1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"))); - result[2] = new unit.result("SHA224 - 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7 = hash.sha224(\"abc\") ", - "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7" == util.hexstrdump(hash.sha224("abc"))); - result[3] = new unit.result("SHA224 - 75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525 = hash.sha224(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\") ", - "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525" == util.hexstrdump(hash.sha224("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"))); - result[4] = new unit.result("SHA256 - ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad = hash.sha256(\"abc\") ", - "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" == util.hexstrdump(hash.sha256("abc"))); - result[5] = new unit.result("SHA256 - 248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1 = hash.sha256(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\") ", - "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" == util.hexstrdump(hash.sha256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"))); - result[6] = new unit.result("SHA384 - cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7 = hash.sha384(\"abc\") ", - "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" == util.hexstrdump(hash.sha384("abc"))); - result[7] = new unit.result("SHA384 - 3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b = str384(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\") ", - "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b" == util.hexstrdump(hash.sha384("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"))); - result[8] = new unit.result("SHA512 - ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f = hash.sha512(\"abc\") ", - "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" == util.hexstrdump(hash.sha512("abc"))); - result[9] = new unit.result("SHA512 - 204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445 = hash.sha512(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\") ", - "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445" == util.hexstrdump(hash.sha512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"))); - return result; -}); - -},{"../../../":29,"../../unit.js":73}],67:[function(require,module,exports){ -var unit = require('../unit.js'); - -unit.register("Key generation/encryption/decryption", function() { - var openpgp = require('../../'); - var result = []; - var testHelper = function(passphrase, userid, message) { - var key = openpgp.generateKeyPair(openpgp.enums.publicKey.rsa_encrypt_sign, 512, - userid, passphrase); - - var info = '\npassphrase: ' + passphrase + '\n' - + 'userid: ' + userid + '\n' - + 'message: ' + message; - - var privKey = openpgp.key.readArmored(key.privateKeyArmored); - - var encrypted = openpgp.encryptMessage([privKey], message); - - var msg = openpgp.message.readArmored(encrypted); - - var keyids = msg.getEncryptionKeyIds(); - - privKey.decryptKeyPacket(keyids, passphrase); - - try { - var decrypted = openpgp.decryptMessage(privKey, msg); - return new unit.result(message + ' == ' + decrypted + info, message == decrypted); - } catch (e) { - return new unit.result("Exception on decrypt of private key packet!" + info, false); - } - - }; - - result.push(testHelper('password', 'Test McTestington <test@example.com>', 'hello world')); - result.push(testHelper('●●●●', '♔♔♔♔ <test@example.com>', 'łäóć')); - - return result; -}); - -unit.register("Message encryption/decryption", function() { - var openpgp = require('../../'); - - var result = []; - - var pub_key = - ['-----BEGIN PGP PUBLIC KEY BLOCK-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - 'Type: RSA/RSA', - '', - 'mI0EUmEvTgEEANyWtQQMOybQ9JltDqmaX0WnNPJeLILIM36sw6zL0nfTQ5zXSS3+', - 'fIF6P29lJFxpblWk02PSID5zX/DYU9/zjM2xPO8Oa4xo0cVTOTLj++Ri5mtr//f5', - 'GLsIXxFrBJhD/ghFsL3Op0GXOeLJ9A5bsOn8th7x6JucNKuaRB6bQbSPABEBAAG0', - 'JFRlc3QgTWNUZXN0aW5ndG9uIDx0ZXN0QGV4YW1wbGUuY29tPoi5BBMBAgAjBQJS', - 'YS9OAhsvBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQSmNhOk1uQJQwDAP6', - 'AgrTyqkRlJVqz2pb46TfbDM2TDF7o9CBnBzIGoxBhlRwpqALz7z2kxBDmwpQa+ki', - 'Bq3jZN/UosY9y8bhwMAlnrDY9jP1gdCo+H0sD48CdXybblNwaYpwqC8VSpDdTndf', - '9j2wE/weihGp/DAdy/2kyBCaiOY1sjhUfJ1GogF49rC4jQRSYS9OAQQA6R/PtBFa', - 'JaT4jq10yqASk4sqwVMsc6HcifM5lSdxzExFP74naUMMyEsKHP53QxTF0Grqusag', - 'Qg/ZtgT0CN1HUM152y7ACOdp1giKjpMzOTQClqCoclyvWOFB+L/SwGEIJf7LSCEr', - 'woBuJifJc8xAVr0XX0JthoW+uP91eTQ3XpsAEQEAAYkBPQQYAQIACQUCUmEvTgIb', - 'LgCoCRBKY2E6TW5AlJ0gBBkBAgAGBQJSYS9OAAoJEOCE90RsICyXuqIEANmmiRCA', - 'SF7YK7PvFkieJNwzeK0V3F2lGX+uu6Y3Q/Zxdtwc4xR+me/CSBmsURyXTO29OWhP', - 'GLszPH9zSJU9BdDi6v0yNprmFPX/1Ng0Abn/sCkwetvjxC1YIvTLFwtUL/7v6NS2', - 'bZpsUxRTg9+cSrMWWSNjiY9qUKajm1tuzPDZXAUEAMNmAN3xXN/Kjyvj2OK2ck0X', - 'W748sl/tc3qiKPMJ+0AkMF7Pjhmh9nxqE9+QCEl7qinFqqBLjuzgUhBU4QlwX1GD', - 'AtNTq6ihLMD5v1d82ZC7tNatdlDMGWnIdvEMCv2GZcuIqDQ9rXWs49e7tq1NncLY', - 'hz3tYjKhoFTKEIq3y3Pp', - '=h/aX', - '-----END PGP PUBLIC KEY BLOCK-----'].join('\n'); - - var priv_key = - ['-----BEGIN PGP PRIVATE KEY BLOCK-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - 'Type: RSA/RSA', - 'Pwd: hello world', - '', - 'lQH+BFJhL04BBADclrUEDDsm0PSZbQ6pml9FpzTyXiyCyDN+rMOsy9J300Oc10kt', - '/nyBej9vZSRcaW5VpNNj0iA+c1/w2FPf84zNsTzvDmuMaNHFUzky4/vkYuZra//3', - '+Ri7CF8RawSYQ/4IRbC9zqdBlzniyfQOW7Dp/LYe8eibnDSrmkQem0G0jwARAQAB', - '/gMDAu7L//czBpE40p1ZqO8K3k7UejemjsQqc7kOqnlDYd1Z6/3NEA/UM30Siipr', - 'KjdIFY5+hp0hcs6EiiNq0PDfm/W2j+7HfrZ5kpeQVxDek4irezYZrl7JS2xezaLv', - 'k0Fv/6fxasnFtjOM6Qbstu67s5Gpl9y06ZxbP3VpT62+Xeibn/swWrfiJjuGEEhM', - 'bgnsMpHtzAz/L8y6KSzViG/05hBaqrvk3/GeEA6nE+o0+0a6r0LYLTemmq6FbaA1', - 'PHo+x7k7oFcBFUUeSzgx78GckuPwqr2mNfeF+IuSRnrlpZl3kcbHASPAOfEkyMXS', - 'sWGE7grCAjbyQyM3OEXTSyqnehvGS/1RdB6kDDxGwgE/QFbwNyEh6K4eaaAThW2j', - 'IEEI0WEnRkPi9fXyxhFsCLSI1XhqTaq7iDNqJTxE+AX2b9ZuZXAxI3Tc/7++vEyL', - '3p18N/MB2kt1Wb1azmXWL2EKlT1BZ5yDaJuBQ8BhphM3tCRUZXN0IE1jVGVzdGlu', - 'Z3RvbiA8dGVzdEBleGFtcGxlLmNvbT6IuQQTAQIAIwUCUmEvTgIbLwcLCQgHAwIB', - 'BhUIAgkKCwQWAgMBAh4BAheAAAoJEEpjYTpNbkCUMAwD+gIK08qpEZSVas9qW+Ok', - '32wzNkwxe6PQgZwcyBqMQYZUcKagC8+89pMQQ5sKUGvpIgat42Tf1KLGPcvG4cDA', - 'JZ6w2PYz9YHQqPh9LA+PAnV8m25TcGmKcKgvFUqQ3U53X/Y9sBP8HooRqfwwHcv9', - 'pMgQmojmNbI4VHydRqIBePawnQH+BFJhL04BBADpH8+0EVolpPiOrXTKoBKTiyrB', - 'UyxzodyJ8zmVJ3HMTEU/vidpQwzISwoc/ndDFMXQauq6xqBCD9m2BPQI3UdQzXnb', - 'LsAI52nWCIqOkzM5NAKWoKhyXK9Y4UH4v9LAYQgl/stIISvCgG4mJ8lzzEBWvRdf', - 'Qm2Ghb64/3V5NDdemwARAQAB/gMDAu7L//czBpE40iPcpLzL7GwBbWFhSWgSLy53', - 'Md99Kxw3cApWCok2E8R9/4VS0490xKZIa5y2I/K8thVhqk96Z8Kbt7MRMC1WLHgC', - 'qJvkeQCI6PrFM0PUIPLHAQtDJYKtaLXxYuexcAdKzZj3FHdtLNWCooK6n3vJlL1c', - 'WjZcHJ1PH7USlj1jup4XfxsbziuysRUSyXkjn92GZLm+64vCIiwhqAYoizF2NHHG', - 'hRTN4gQzxrxgkeVchl+ag7DkQUDANIIVI+A63JeLJgWJiH1fbYlwESByHW+zBFNt', - 'qStjfIOhjrfNIc3RvsggbDdWQLcbxmLZj4sB0ydPSgRKoaUdRHJY0S4vp9ouKOtl', - '2au/P1BP3bhD0fDXl91oeheYth+MSmsJFDg/vZJzCJhFaQ9dp+2EnjN5auNCNbaI', - 'beFJRHFf9cha8p3hh+AK54NRCT++B2MXYf+TPwqX88jYMBv8kk8vYUgo8128r1zQ', - 'EzjviQE9BBgBAgAJBQJSYS9OAhsuAKgJEEpjYTpNbkCUnSAEGQECAAYFAlJhL04A', - 'CgkQ4IT3RGwgLJe6ogQA2aaJEIBIXtgrs+8WSJ4k3DN4rRXcXaUZf667pjdD9nF2', - '3BzjFH6Z78JIGaxRHJdM7b05aE8YuzM8f3NIlT0F0OLq/TI2muYU9f/U2DQBuf+w', - 'KTB62+PELVgi9MsXC1Qv/u/o1LZtmmxTFFOD35xKsxZZI2OJj2pQpqObW27M8Nlc', - 'BQQAw2YA3fFc38qPK+PY4rZyTRdbvjyyX+1zeqIo8wn7QCQwXs+OGaH2fGoT35AI', - 'SXuqKcWqoEuO7OBSEFThCXBfUYMC01OrqKEswPm/V3zZkLu01q12UMwZach28QwK', - '/YZly4ioND2tdazj17u2rU2dwtiHPe1iMqGgVMoQirfLc+k=', - '=lw5e', - '-----END PGP PRIVATE KEY BLOCK-----'].join('\n'); - - var plaintext = 'short message\nnext line\n한국어/조선말'; - - var key = openpgp.key.readArmored(pub_key); - - var encrypted = openpgp.encryptMessage([key], plaintext); - - var message = openpgp.message.readArmored(encrypted); - - var privKey = openpgp.key.readArmored(priv_key); - - // get key IDs the message is encrypted for - var keyids = message.getEncryptionKeyIds(); - - // decrypt only required key packets - var success = privKey.decryptKeyPacket(keyids, 'hello what?') - - result.push(new unit.result('Decrypting key packet with wrong password returns false', !success)); - - var decrypted, error; - try { - decrypted = openpgp.decryptMessage(privKey, message); - } catch (e) { - error = e; - } - result.push(new unit.result('Calling decryptMessage with not decrypted key packet leads to exception: \'' + (error || '') + '\'', error)); - - success = privKey.decryptKeyPacket(keyids, 'hello world'); - - result.push(new unit.result('Decrypting key packet with correct password returns true', success)); - - decrypted = openpgp.decryptMessage(privKey, message); - - result.push(new unit.result('Encrypt plain text and afterwards decrypt leads to same result', plaintext == decrypted)); - - return result; - -}); - -},{"../../":29,"../unit.js":73}],68:[function(require,module,exports){ -var unit = require('../unit.js'); - -unit.register("Keyring testing", function() { - var openpgp = require('../../'); - var keyring = require('../../src/keyring.js'); - var result = []; - - // Exercises the ability of openpgp_keyring.getPublicKeysForKeyId to return subkeys - keyring.init(); - keyring.importPacketlist([ - '-----BEGIN PGP PUBLIC KEY BLOCK-----', - 'Version: GnuPG v1.4.11 (GNU/Linux)', - '', - 'mQGiBFERvI4RBAD0M/HGglCtVNXPF72ehT8riAXrl0rSec4RJC61Bh+UAOhxn5+U', - 'fDgos5p1SpIzYmn+M87JoSSVLAjfakFk0gHgR9I3bu7SIwq3Bikk1Vw3gO+yDSO6', - 'TKpLUFGYDiBSSE1MGdxBadWLE1hlRf5B2x62gnGmjSpSVbly33PFkoDmrwCg9rAp', - 'RmncnF9GhWjOLFkEoQw9Yx8EAOsxvq8Ig5Z1gk+ZKfDZeftpHRe3FdrRtbnhxvYY', - '7z+w9uz1EpoZUwDR5G4X3hTwJQ7lXmIOskg/+eRMLEAqEY7b/7tW6RaUJ2d6Ehsi', - 'dOS89fIxElwjAOnVOM5S24f0FDQTTto7QBOoxcNTfkEJCHXSlpoOUmGAP85fXh3l', - 'yPTGBACJfKc76Un3UWC1sWIRDxYiyh3ZpZyNEskoV6ESW8jEI1RnMnv5TrfGJH5K', - 'E8jWX7TTnoFyPJtBTjlucAtkQaS4Bb7dg1LLja17zAqKNGOJK2b9fb2Z+lnTjPiY', - 'i7DPH1XHnfaEexjlh/U7mYa5RrwIphRxNi8gCuxv874ZMmhEn7QWVGVzdDMgPHRl', - 'c3QzQHRlc3QuY29tPohiBBMRAgAiBQJREbyOAhsDBgsJCAcDAgYVCAIJCgsEFgID', - 'AQIeAQIXgAAKCRC0u8O0Moa2JYxyAJ9Oi2UlcUT0VJNgwjyl/VF9Xcjf9gCeJPvy', - 'g/fp4EAU8MJIaN2yMI8pLFS5AaIEURG8nhEEAKVgeNDuYDPufLuJ0GrJV/CbXEjj', - 'aEPA0iTUqV0nTCPdAfQ/nmE3gh5UlNMr/zSHJ+c4FQhYdLrzRGDOSzV+mfPHH3t+', - 'YVx+wat0BYwABpHAtsIuLIVo2RQqYZYH85tatwBkm71HHT3jmlEAvr6NFH38+v3s', - '3w4Wl0/sdHyaeiSXAKCxJ4X1eOdN7L1rrbJozQ/gDCFuVQP/dcV6Ksss8Aw443jG', - 'AYBLHWh6o4GhAY6/h1kijF0xD+uc+tNmTQnQi1tEOoTeIZMXnSRwtk8XEuJkkbAP', - '+uyvMgyV3wrk9zkaTAin7nrjAERxezFOdBEOtnB1CovJxtMn+RRxaMEGpC4GnETy', - 'N5+6FkLuLcNXiCQP75ajzOAN1aID/juNjUNpBbNpfqBV7j1K+Kn0n9HYTyQl9ghy', - '026+/4c8ag2HV+bg3BD7c2VTVu9xBODHsfu0q8Ql/QB9W8tmYugU6DeXMHaeWPUH', - 'ph98guM9kF2yHIiRBvAd5i7wOjwn+I/Ir6nBR2yxJ3p31CDUnUlbjTPYg7mtQvHW', - 'EY2Cp4SWiJEEGBECAAkFAlERvJ4CGwIAUgkQtLvDtDKGtiVHIAQZEQIABgUCURG8', - 'ngAKCRAMiMeR296Y2SjyAJ9V3wRJJ2Szazqal4khWGfLu5R6/wCfQQIRD24yVdz8', - '2a+2eCrwyALT2GAihACfS0nWM3a0gtITqngpJsRws+Ep+eIAn15qD2itutxNb8NI', - 'bR2gBB5QmVJ3', - '=pGA6', - '-----END PGP PUBLIC KEY BLOCK-----' - ].join("\n")); - - var msg2 = openpgp.message.readArmored([ - '-----BEGIN PGP MESSAGE-----', - 'Version: GnuPG v1.4.11 (GNU/Linux)', - '', - 'kA0DAAIRDIjHkdvemNkBrB1iB2Zvby50eHRREbz3VEVTVCBEQVRBIDEyMzQ1NohG', - 'BAARAgAGBQJREbz3AAoJEAyIx5Hb3pjZ2TcAn32LpDEuHe9QrSRlyvSuREKNOFwz', - 'AJ9zh4zsK4GIPuEu81YPNmHsju7DYg==', - '=WaSx', - '-----END PGP MESSAGE-----' - ].join("\n")).packets; - var packetlists = keyring.getPacketlistsForKeyId(msg2[0].signingKeyId.write()); - var pubKey = packetlists[0]; - msg2[2].verify(pubKey[3], msg2[1]); - result[2] = new unit.result("Testing keyring public subkey support", - packetlists !== null && - packetlists.length == 1 && - msg2[2].verified); - return result; -}); - - - -},{"../../":29,"../../src/keyring.js":31,"../unit.js":73}],69:[function(require,module,exports){ -var unit = require('../unit.js'); - -unit.register("Packet testing", function() { - - var openpgp = require('../../'); - - var armored_key = - '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' + - 'Version: GnuPG v2.0.19 (GNU/Linux)\n' + - '\n' + - 'lQH+BFF79J8BBADDhRUOMUSGdYM1Kq9J/vVS3qLfaZHweycAKm9SnpLGLJE+Qbki\n' + - 'JRXLAhxZ+HgVThR9VXs8wbPR2UXnDhMJGe+VcMA0jiwIOEAF0y9M3ZQsPFWguej2\n' + - '1ZycgOwxYHehbKdPqRK+nFgFbhvg6f6x2Gt+a0ZbvivGL1BqSSGsL+dchQARAQAB\n' + - '/gMDAijatUNeUFZSyfg16x343/1Jo6u07LVTdH6Bcbx4yBQjEHvlgb6m1eqEIbZ1\n' + - 'holVzt0fSKTzmlxltDaOwFLf7i42lqNoWyfaqFrOblJ5Ays7Q+6xiJTBROG9po+j\n' + - 'Z2AE+hkBIwKghB645OikchR4sn9Ej3ipea5v9+a7YimHlVmIiqgLDygQvXkzXVaf\n' + - 'Zi1P2wB7eU6If2xeeX5GSR8rWo+I7ujns0W8S9PxBHlH3n1oXUmFWsWLZCY/qpkD\n' + - 'I/FroBhXxBVRpQhQmdsWPUdcgmQTEj8jnP++lwSQexfgk2QboAW7ODUA8Cl9oy87\n' + - 'Uor5schwwdD3oRoLGcJZfR6Dyu9dCYdQSDWj+IQs95hJQfHNcfj7XFtTyOi7Kxx0\n' + - 'Jxio9De84QnxNAoNYuLtwkaRgkUVKVph2nYWJfAJunuMMosM2WdcidHJ5d6RIdxB\n' + - 'U6o3T+d8BPXuRQEZH9+FkDkb4ihakKO3+Zcon85e1ZUUtB1QYXRyaWNrIDxwYXRy\n' + - 'aWNrQGV4YW1wbGUuY29tPoi5BBMBAgAjBQJRe/SfAhsDBwsJCAcDAgEGFQgCCQoL\n' + - 'BBYCAwECHgECF4AACgkQObliSdM/GEJbjgP/ffei4lU6fXp8Qu0ubNHh4A6swkTO\n' + - 'b3suuBELE4A2/pK5YnW5yByFFSi4kq8bJp5O6p9ydXpOA38t3aQ8wrbo0yDvGekr\n' + - '1S1HWOLgCaY7rEDQubuCOHd2R81/VQOJyG3zgX4KFIgkVyV9BZXUpz4PXuhMORmv\n' + - '81uzej9r7BYkJ6GdAf4EUXv0nwEEAKbO02jtGEHet2fQfkAYyO+789sTxyfrUy5y\n' + - 'SAf5n3GgkuiHz8dFevhgqYyMK0OYEOCZqdd1lRBjL6Us7PxTljHc2jtGhoAgE4aZ\n' + - 'LKarI3j+5Oofcaq0+S0bhqiQ5hl6C4SkdYOEeJ0Hlq2008n0pJIlU4E5yIu0oNvb\n' + - '4+4owTpRABEBAAH+AwMCKNq1Q15QVlLJyeuGBEA+7nXS3aSy6mE4lR5f3Ml5NRqt\n' + - 'jm6Q+UUI69DzhLGX4jHRxna6NMP74S3CghOz9eChMndkfWLC/c11h1npzLci+AwJ\n' + - '45xMbw/OW5PLlaxdtkg/SnsHpFGCAuTUWY87kuWoG0HSVMn9Clm+67rdicOW6L5a\n' + - 'ChfyWcVZ+Hvwjx8YM0/j11If7oUkCZEstSUeJYOI10JQLhNLpDdkB89vXhAMaCuU\n' + - 'Ijhdq0vvJi6JruKQGPK+jajJ4MMannpQtKAvt8aifqpdovYy8w4yh2pGkadFvrsZ\n' + - 'mxpjqmmawab6zlOW5WrLxQVL1cQRdrIQ7jYtuLApGWkPfytSCBZ20pSyWnmkxd4X\n' + - 'OIms6BjqrP9LxBEXsPBwdUA5Iranr+UBIPDxQrTp5k0DJhXBCpJ1k3ZT+2dxiRS2\n' + - 'sk83w2VUBnXdYWZx0YlMqr3bDT6J5fO+8V8pbgY5BkHRCFMacFx45km/fvmInwQY\n' + - 'AQIACQUCUXv0nwIbDAAKCRA5uWJJ0z8YQqb3A/97njLl33OQYXVp9OTk/VgE6O+w\n' + - 'oSYa+6xMOzsk7tluLIRQtnIprga/e8vEZXGTomV2a77HBksg+YjlTh/l8oMuaoxG\n' + - 'QNkMpoRJKPip29RTW4gLdnoJVekZ/awkBN2S3NMArOZGca8U+M1IuV7OyVchSVSl\n' + - 'YRlci72GHhlyos8YHA==\n' + - '=KXkj\n' + - '-----END PGP PRIVATE KEY BLOCK-----'; - - - var tests = [function() { - var message = new openpgp.packet.list(); - - var literal = new openpgp.packet.literal(); - literal.setText('Hello world'); - - var enc = new openpgp.packet.symmetrically_encrypted(); - message.push(enc); - enc.packets.push(literal); - - var key = '12345678901234567890123456789012', - algo = 'aes256'; - - enc.encrypt(algo, key); - - - - var msg2 = new openpgp.packet.list(); - msg2.read(message.write()); - - msg2[0].decrypt(algo, key); - - return new unit.result('Symmetrically encrypted packet', - msg2[0].packets[0].data == literal.data); - - }, function() { - var key = '12345678901234567890123456789012', - algo = 'aes256'; - - var literal = new openpgp.packet.literal(), - enc = new openpgp.packet.sym_encrypted_integrity_protected(), - msg = new openpgp.packet.list(); - - msg.push(enc); - literal.setText('Hello world!'); - enc.packets.push(literal); - enc.encrypt(algo, key); - - - - var msg2 = new openpgp.packet.list(); - msg2.read(msg.write()); - - msg2[0].decrypt(algo, key); - - return new unit.result('Sym. encrypted integrity protected packet', - msg2[0].packets[0].data == literal.data); - - }, function() { - - var msg = - '-----BEGIN PGP MESSAGE-----\n' + - 'Version: GnuPG v2.0.19 (GNU/Linux)\n' + - '\n' + - 'jA0ECQMCpo7I8WqsebTJ0koBmm6/oqdHXJU9aPe+Po+nk/k4/PZrLmlXwz2lhqBg\n' + - 'GAlY9rxVStLBrg0Hn+5gkhyHI9B85rM1BEYXQ8pP5CSFuTwbJ3O2s67dzQ==\n' + - '=VZ0/\n' + - '-----END PGP MESSAGE-----'; - - - - var msgbytes = openpgp.armor.decode(msg).data; - - var parsed = new openpgp.packet.list(); - parsed.read(msgbytes); - - parsed[0].decrypt('test'); - - var key = parsed[0].sessionKey; - parsed[1].decrypt(parsed[0].sessionKeyAlgorithm, key); - var compressed = parsed[1].packets[0]; - - var result = compressed.packets[0].data; - - return new unit.result('Sym encrypted session key with a compressed packet', - result == 'Hello world!\n'); - - }, function() { - - var rsa = new openpgp.crypto.publicKey.rsa(), - mpi = rsa.generate(512, "10001") - - var mpi = [mpi.n, mpi.ee, mpi.d, mpi.p, mpi.q, mpi.u]; - - mpi = mpi.map(function(k) { - var mpi = new openpgp.mpi(); - mpi.fromBigInteger(k); - return mpi; - }); - - var enc = new openpgp.packet.public_key_encrypted_session_key(), - msg = new openpgp.packet.list(), - msg2 = new openpgp.packet.list(); - - enc.sessionKey = '12345678901234567890123456789012'; - enc.publicKeyAlgorithm = 'rsa_encrypt'; - enc.sessionKeyAlgorithm = 'aes256'; - enc.publicKeyId.bytes = '12345678'; - enc.encrypt({ mpi: mpi }); - - msg.push(enc); - - msg2.read(msg.write()); - - msg2[0].decrypt({ mpi: mpi }); - - return new unit.result('Public key encrypted symmetric key packet', - msg2[0].sessionKey == enc.sessionKey && - msg2[0].sessionKeyAlgorithm == enc.sessionKeyAlgorithm); - }, function() { - var armored_key = - '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' + - 'Version: GnuPG v2.0.19 (GNU/Linux)\n' + - '\n' + - 'lQHYBFF33iMBBAC9YfOYahJlWrVj2J1TjQiZLunWljI4G9e6ARTyD99nfOkV3swh\n' + - '0WaOse4Utj7BfTqdYcoezhCaQpuExUupKWZqmduBcwSmEBfNu1XyKcxlDQuuk0Vk\n' + - 'viGC3kFRce/cJaKVFSRU8V5zPgt6KQNv/wNz7ydEisaSoNbk51vQt5oGfwARAQAB\n' + - 'AAP5AVL8xWMuKgLj9g7/wftMH+jO7vhAxje2W3Y+8r8TnOSn0536lQvzl/eQyeLC\n' + - 'VK2k3+7+trgO7I4KuXCXZqgAbEi3niDYXDaCJ+8gdR9qvPM2gi9NM71TGXZvGE0w\n' + - 'X8gIZfqLTQWKm9TIS/3tdrth4nwhiye0ASychOboIiN6VIECAMbCQ4/noxGV6yTK\n' + - 'VezsGSz+iCMxz2lV270/Ac2C5WPk+OlxXloxUXeEkGIr6Xkmhhpceed2KL41UC8Y\n' + - 'w5ttGIECAPPsahniKGyqp9CHy6W0B83yhhcIbmLlaVG2ftKyUEDxIggzOlXuVrue\n' + - 'z9XRd6wFqwDd1QMFW0uUyHPDCIFPnv8CAJaDFSZutuWdWMt15NZXjfgRgfJuDrtv\n' + - 'E7yFY/p0el8lCihOT8WoHbTn1PbCYMzNBc0IhHaZKAtA2pjkE+wzz9ClP7QbR2Vv\n' + - 'cmdlIDxnZW9yZ2VAZXhhbXBsZS5jb20+iLkEEwECACMFAlF33iMCGwMHCwkIBwMC\n' + - 'AQYVCAIJCgsEFgIDAQIeAQIXgAAKCRBcqs36fwJCXRbvA/9LPiK6WFKcFoNBnLEJ\n' + - 'mS/CNkL8yTpkslpCP6+TwJMc8uXqwYl9/PW2+CwmzZjs6JsvTzMcR/ZbfZJuSW6Y\n' + - 'EsLNejsSpgcY9aiewGtE+53e5oKYnlmVMTWOPywciIgMvXlzdGhxcwqJ8u0hT+ug\n' + - '9CjcAfuX9yw85LwXtdGwNh7J8Q==\n' + - '=lKiS\n' + - '-----END PGP PRIVATE KEY BLOCK-----'; - - key = new openpgp.packet.list(); - key.read(openpgp.armor.decode(armored_key).data); - key = key[0]; - - var enc = new openpgp.packet.public_key_encrypted_session_key(), - secret = '12345678901234567890123456789012'; - - enc.sessionKey = secret; - enc.publicKeyAlgorithm = 'rsa_encrypt'; - enc.sessionKeyAlgorithm = 'aes256'; - enc.publicKeyId.bytes = '12345678'; - - enc.encrypt(key); - - enc.decrypt(key); - - return new unit.result('Secret key packet (reading, unencrpted)', - enc.sessionKey == secret); - }, function() { - - var armored_key = - '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' + - 'Version: GnuPG v2.0.19 (GNU/Linux)\n' + - '\n' + - 'lQHYBFF6gtkBBADKUOWZK6/V75MNwBS+hLYicoS0Sojbo3qWXXpS7eM+uhiDm4bP\n' + - 'DNjdNVA0R+TCjvhWbc3W6cvdHYTmHRMhTIOefncZRt3OwF7AvVk53fKKPiNNv5C9\n' + - 'IK8bcDhAknSOg1TXRSpXLHtYy36A6iDgffNSjoCOVaeKpuRDMA37PvJWFQARAQAB\n' + - 'AAP+KxHbOwcrnPPuXppCYEew3Xb7LMWESpvMFFgsmxx1COzFnLjek1P1E+yOWT7n\n' + - '4opcsEuaazLk+TrYSMOuR6O6DgGg5c+ctVPU+NGNNCiiTkOzuD+8ow8NgsoINOxi\n' + - '481qLK0NYpc5sEg394J3fRuzpfEi6DTS/RzCN7YDiGFccNECAM71NuaAzH5LrZ+B\n' + - '4Okwy9CQQbgoYrdaia24CjEaUODaROnyNsvOb0ydEebVAbGzrsBr6LrisTidyZsG\n' + - 't2T+L7ECAPpCFzZIwwk6giZ10HmXEhXZLXYmdhQD/1fwegpTrEciMA6MCcdkcCyO\n' + - '2/J+S+NXM62ykMGDhg2cjhU1rj/uaaUCAJfCjkwpxMsDKHYDFDXyjJFy2vEmA3s8\n' + - 'cnmAUDF1caPyEcPEZmYJRE+KdroOD6IGhzp7oA34Ef3D6HOCovH9YaCgbbQbSm9o\n' + - 'bm55IDxqb2hubnlAZXhhbXBsZS5jb20+iLkEEwECACMFAlF6gtkCGwMHCwkIBwMC\n' + - 'AQYVCAIJCgsEFgIDAQIeAQIXgAAKCRA6HTM8yP08keZgA/4vL273zrqnmOrqmo/K\n' + - 'UxQgD0vMhM58d25UjGYI6LAZkAls/k4FvFt5GUHVWJR3HBRuuNlB7UndH/uYlU7j\n' + - 'm/bQLiP4uvFQuRGuG76f0O5t/KyeUdzrpNiJpe8tYDAnoPxUzENYsIv0fm2ZISo1\n' + - 'QnnXX2WuVZGMZH1YhQoakZxbnp0B2ARReoLZAQQAvQvPp2MLu9vnRvZ3Py559kQf\n' + - '0Z5AnEXVokALTn5A2m51dLekQ9T3Rhz8p9I6C/XjVQwBkp1USOaDUz+L7lsbNdY4\n' + - 'YbUi3eIA5RImVXeTIrD1hE4CllDNKmqT5wFN07eEu7QhDEuYioO+4gtjjhUDYeIA\n' + - 'dCVtVO//q8rP8ukZEc8AEQEAAQAD/RHlttyNe3RnDr/AoKx6HXDLpUmGlm5VDDMm\n' + - 'pgth14j2cSdCJYqIdHqOTvsiY31zY3jPQKzdOTgHnsI4X2qK9InbwXepSBkaOJzY\n' + - 'iNhifPSUs9qoNawDqbFJ8PMXd4QQGgM93w+tudKC650Zuq7M7eWSdQg0u9aoLY97\n' + - 'MpKx3DUFAgDA/RgoO8xYMgkKN1tuKWa61qesLdJRAZI/3cnvtsmmEBt9tdbcDoBz\n' + - 'gOIAAvUFgipuP6dBWLyf2NRNRVVQdNTlAgD6xS7S87g3kTa3GLcEI2cveaP1WWNK\n' + - 'rKFnVWsjBKArKFzMQ5N6FMnFD4T96i3sYlACE5UjH90SpOgBKOpdKzSjAf9nghrw\n' + - 'kbFbF708ZIpVEwxvp/JoSutYUQ4v01MImnCGqzDVuSef3eutLLu4ZG7kLekxNauV\n' + - '8tGFwxsdtv30RL/3nW+InwQYAQIACQUCUXqC2QIbDAAKCRA6HTM8yP08kRXjBACu\n' + - 'RtEwjU+p6qqm3pmh7xz1CzhQN1F7VOj9dFUeECJJ1iv8J71w5UINH0otIceeBeWy\n' + - 'NLA/QvK8+4/b9QW+S8aDZyeZpYg37gBwdTNGNT7TsEAxz9SUbx9uRja0wNmtb5xW\n' + - 'mG+VE8CBXNkp8JTWx05AHwtK3baWlHWwpwnRlbU94Q==\n' + - '=FSwA\n' + - '-----END PGP PRIVATE KEY BLOCK-----'; - - var armored_msg = - '-----BEGIN PGP MESSAGE-----\n' + - 'Version: GnuPG v2.0.19 (GNU/Linux)\n' + - '\n' + - 'hIwDFYET+7bfx/ABA/95Uc9942Tg8oqpO0vEu2eSKwPALM3a0DrVdAiFOIK/dJmZ\n' + - 'YrtPRw3EEwHZjl6CO9RD+95iE27tPbsICw1K43gofSV/wWsPO6vvs3eftQYHSxxa\n' + - 'IQbTPImiRaJ73Mf7iM3CNtQM4iUBsx1HnUGl+rtD0nz3fLm6i3CjwiNQWW42I9JH\n' + - 'AWv8EvvpxZ8X2ClFfSW3UVBoROHe9CAWHM/40nGutAZK8MIgmUI4xqkLFBbqqTyx\n' + - '/cDSC4Q+sv65UX4urbfc7uJuk1Cpj54=\n' + - '=iSaK\n' + - '-----END PGP MESSAGE-----'; - - - var key = new openpgp.packet.list(); - key.read(openpgp.armor.decode(armored_key).data); - key = key[3]; - - var msg = new openpgp.packet.list(); - msg.read(openpgp.armor.decode(armored_msg).data); - - msg[0].decrypt(key); - msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); - - var text = msg[1].packets[0].packets[0].data; - - - return new unit.result('Public key encrypted packet (reading, GPG)', - text == 'Hello world!'); - }, function() { - - var passphrase = 'hello', - algo = 'aes256'; - - var literal = new openpgp.packet.literal(), - key_enc = new openpgp.packet.sym_encrypted_session_key(), - enc = new openpgp.packet.sym_encrypted_integrity_protected(), - msg = new openpgp.packet.list(); - - msg.push(key_enc); - msg.push(enc); - - key_enc.sessionKeyAlgorithm = algo; - key_enc.decrypt(passphrase); - - var key = key_enc.sessionKey; - - literal.setText('Hello world!'); - enc.packets.push(literal); - enc.encrypt(algo, key); - - - var msg2 = new openpgp.packet.list(); - msg2.read(msg.write()); - - msg2[0].decrypt(passphrase); - var key2 = msg2[0].sessionKey; - msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2); - - - return new unit.result('Sym encrypted session key reading/writing', - msg2[1].packets[0].data == literal.data); - - }, function() { - var armored_msg = - '-----BEGIN PGP MESSAGE-----\n' + - 'Version: GnuPG v2.0.19 (GNU/Linux)\n' + - '\n' + - 'hIwD95D9aHS5fxEBA/98CwH54XZmwobOmHUcvWcDDQysBEC4uf7wASiGcRbejDaO\n' + - 'aJqcrK/3k8sBQMO7yOhvrCRqqpGDqnmx7IaaKLnZS7nYAZoHEsK9UyG0hDa8Cfbo\n' + - 'CP4xZVcgIvIfAW/in1LeT2td0QcQNbeewBmPea+vQEEvRgIP10tlE7MK8Ay48dJH\n' + - 'AagMgNYg7MBUjpuOCVrjM1pWja8uzbULfYhTq3IJ8H3QhbdT+k9khY9f0aJPEeYi\n' + - 'dVv6DK9uviMGc/DsVCw5K8lQRLlkcHc=\n' + - '=pR+C\n' + - '-----END PGP MESSAGE-----'; - - var key = new openpgp.packet.list(); - key.read(openpgp.armor.decode(armored_key).data); - key = key[3]; - key.decrypt('test'); - - var msg = new openpgp.packet.list(); - msg.read(openpgp.armor.decode(armored_msg).data); - - msg[0].decrypt(key); - msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); - - var text = msg[1].packets[0].packets[0].data; - - - - return new unit.result('Secret key encryption/decryption test', - text == 'Hello world!'); - }, function() { - - - var key = new openpgp.packet.list(); - key.read(openpgp.armor.decode(armored_key).data); - - - var verified = key[2].verify(key[0], - { - userid: key[1], - key: key[0] - }); - - verified = verified && key[4].verify(key[0], - { - key: key[0], - bind: key[3], - }) - - - return new unit.result('Secret key reading with signature verification.', - verified == true); - }, function() { - - var armored_msg = - '-----BEGIN PGP MESSAGE-----\n' + - 'Version: GnuPG v2.0.19 (GNU/Linux)\n' + - '\n' + - 'hIwD95D9aHS5fxEBA/4/X4myvH+jB1HYNeZvdK+WsBNDMfLsBGOf205Rxr3vSob/\n' + - 'A09boj8/9lFaipqu+AEdQKEjCB8sZ+OY0WiQPEPpuhG+mVqDqEiPFkdpcqNtS0VV\n' + - 'pwqplHo6QnH2MHfxprZHYuwcEC9ynJCxJ6kSCD8Xs99h+PjxNNw7NhMjkF+N69LA\n' + - 'NwGPtbLx2/r2nR4gO8gV92A2RQCOwPP7ZV+6fXgWIs+mhyCHFP3xUP5DaFCNM8mo\n' + - 'PN97i659ucxF6IbOoK56FEaUbOPTD6xdyhWamxKfMsIb0UJgVUNhGaq+VlvOJxaB\n' + - 'iRcnY5UxsypKgtqfcKIseb21MIo4vcNdogyxBIDlAO472Zfxn0udzr6W2aQ77+NK\n' + - 'FE1O0kCXS+DTFOYYVD7X8rXGSglQsdXJmHd89sdYFQkO7D7bOLdRJuXgdgH2czCs\n' + - 'UBGuHZzsGbTdyKvpVBuS3rnyHHBk6oCnsm1Nl7eLs64VkZUxjEUbq5pb4dlr1pw2\n' + - 'ztpmpAnRcmM=\n' + - '=htrB\n' + - '-----END PGP MESSAGE-----' - - var key = new openpgp.packet.list(); - key.read(openpgp.armor.decode(armored_key).data); - key[3].decrypt('test') - - var msg = new openpgp.packet.list(); - msg.read(openpgp.armor.decode(armored_msg).data); - - - msg[0].decrypt(key[3]); - msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); - - var payload = msg[1].packets[0].packets - - - - var verified = payload[2].verify(key[0], payload[1]); - - - - return new unit.result('Reading a signed, encrypted message.', - verified == true); - }, function() { - var key = new openpgp.packet.list(); - key.push(new openpgp.packet.secret_key); - - var rsa = new openpgp.crypto.publicKey.rsa(), - mpi = rsa.generate(512, "10001") - - - var mpi = [mpi.n, mpi.ee, mpi.d, mpi.p, mpi.q, mpi.u]; - - mpi = mpi.map(function(k) { - var mpi = new openpgp.mpi(); - mpi.fromBigInteger(k); - return mpi; - }); - - key[0].mpi = mpi; - - key[0].encrypt('hello'); - - var raw = key.write(); - - var key2 = new openpgp.packet.list(); - key2.read(raw); - key2[0].decrypt('hello'); - - - return new unit.result('Writing and encryptio of a secret key packet.', - key[0].mpi.toString() == key2[0].mpi.toString()); - }, function() { - - var key = new openpgp.packet.secret_key(); - - var rsa = new openpgp.crypto.publicKey.rsa, - mpi = rsa.generate(512, "10001") - - var mpi = [mpi.n, mpi.ee, mpi.d, mpi.p, mpi.q, mpi.u]; - - mpi = mpi.map(function(k) { - var mpi = new openpgp.mpi(); - mpi.fromBigInteger(k); - return mpi; - }); - - key.mpi = mpi; - - var signed = new openpgp.packet.list(), - literal = new openpgp.packet.literal(), - signature = new openpgp.packet.signature(); - - literal.setText('Hello world'); - - signature.hashAlgorithm = 'sha256'; - signature.publicKeyAlgorithm = 'rsa_sign'; - signature.signatureType = 'binary'; - - signature.sign(key, literal); - - signed.push(literal); - signed.push(signature); - - var raw = signed.write(); - - var signed2 = new openpgp.packet.list(); - signed2.read(raw); - - var verified = signed2[1].verify(key, signed2[0]); - - - return new unit.result('Writing and verification of a signature packet.', - verified == true); - }]; - - - - tests.reverse(); - - var results = []; - - for(var i in tests) { - results.push(tests[i]()); - } - - - return results; -}); - -},{"../../":29,"../unit.js":73}],70:[function(require,module,exports){ -var unit = require('../unit.js'); - -unit.register("Signature testing", function() { - var openpgp = require('../../'); - - var priv_key_arm1 = - [ '-----BEGIN PGP PRIVATE KEY BLOCK-----', - 'Version: GnuPG v1.4.11 (GNU/Linux)', - '', - 'lQHhBFERnrMRBADmM0hIfkI3yosjgbWo9v0Lnr3CCE+8KsMszgVS+hBu0XfGraKm', - 'ivcA2aaJimHqVYOP7gEnwFAxHBBpeTJcu5wzCFyJwEYqVeS3nnaIhBPplSF14Duf', - 'i6bB9RV7KxVAg6aunmM2tAutqC+a0y2rDaf7jkJoZ9gWJe2zI+vraD6fiwCgxvHo', - '3IgULB9RqIqpLoMgXfcjC+cD/1jeJlKRm+n71ryYwT/ECKsspFz7S36z6q3XyS8Q', - 'QfrsUz2p1fbFicvJwIOJ8B20J/N2/nit4P0gBUTUxv3QEa7XCM/56/xrGkyBzscW', - 'AzBoy/AK9K7GN6z13RozuAS60F1xO7MQc6Yi2VU3eASDQEKiyL/Ubf/s/rkZ+sGj', - 'yJizBACtwCbQzA+z9XBZNUat5NPgcZz5Qeh1nwF9Nxnr6pyBv7tkrLh/3gxRGHqG', - '063dMbUk8pmUcJzBUyRsNiIPDoEUsLjY5zmZZmp/waAhpREsnK29WLCbqLdpUors', - 'c1JJBsObkA1IM8TZY8YUmvsMEvBLCCanuKpclZZXqeRAeOHJ0v4DAwK8WfuTe5B+', - 'M2BOOeZbN8BpfiA1l//fMMHLRS3UvbLBv4P1+4SyvhyYTR7M76Q0xPc03MFOWHL+', - 'S9VumbQWVGVzdDIgPHRlc3QyQHRlc3QuY29tPohiBBMRAgAiBQJREZ6zAhsDBgsJ', - 'CAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRARJ5QDyxae+MXNAKCzWSDR3tMrTrDb', - 'TAri73N1Xb3j1ACfSl9y+SAah2q7GvmiR1+6+/ekqJGdAVgEURGesxAEANlpMZjW', - '33jMxlKHDdyRFXtKOq8RreXhq00plorHbgz9zFEWm4VF53+E/KGnmHGyY5Cy8TKy', - 'ZjaueZZ9XuG0huZg5If68irFfNZtxdA26jv8//PdZ0Uj+X6J3RVa2peMLDDswTYL', - 'OL1ZO1fxdtDD40fdAiIZ1QyjwEG0APtz41EfAAMFBAC5/dtgBBPtHe8UjDBaUe4n', - 'NzHuUBBp6XE+H7eqHNFCuZAJ7yqJLGVHNIaQR419cNy08/OO/+YUQ7rg78LxjFiv', - 'CH7IzhfU+6yvELSbgRMicY6EnAP2GT+b1+MtFNa3lBGtBHcJla52c2rTAHthYZWk', - 'fT5R5DnJuQ2cJHBMS9HWyP4DAwK8WfuTe5B+M2C7a/YJSUv6SexdGCaiaTcAm6g/', - 'PvA6hw/FLzIEP67QcQSSTmhftQIwnddt4S4MyJJH3U4fJaFfYQ1zCniYJohJBBgR', - 'AgAJBQJREZ6zAhsMAAoJEBEnlAPLFp74QbMAn3V4857xwnO9/+vzIVnL93W3k0/8', - 'AKC8omYPPomN1E/UJFfXdLDIMi5LoA==', - '=LSrW', - '-----END PGP PRIVATE KEY BLOCK-----' - ].join("\n"); - var pub_key_arm1 = - [ '-----BEGIN PGP PUBLIC KEY BLOCK-----', - 'Version: GnuPG v1.4.11 (GNU/Linux)', - '', - 'mQGiBFERlw4RBAD6Bmcf2w1dtUmtCLkdxeqZLArk3vYoQAjdibxA3gXVyur7fsWb', - 'ro0jVbBHqOCtC6jDxE2l52NP9+tTlWeVMaqqNvUE47LSaPq2DGI8Wx1Rj6bF3mTs', - 'obYEwhGbGh/MhJnME9AHODarvk8AZbzo0+k1EwrBWF6dTUBPfqO7rGU2ewCg80WV', - 'x5pt3evj8rRK3jQ8SMKTNRsD/1PhTdxdZTdXARAFzcW1VaaruWW0Rr1+XHKKwDCz', - 'i7HE76SO9qjnQfZCZG75CdQxI0h8GFeN3zsDqmhob2iSz2aJ1krtjM+iZ1FBFd57', - 'OqCV6wmk5IT0RBN12ZzMS19YvzN/ONXHrmTZlKExd9Mh9RKLeVNw+bf6JsKQEzcY', - 'JzFkBACX9X+hDYchO/2hiTwx4iOO9Fhsuh7eIWumB3gt+aUpm1jrSbas/QLTymmk', - 'uZuQVXI4NtnlvzlNgWv4L5s5RU5WqNGG7WSaKNdcrvJZRC2dgbUJt04J5CKrWp6R', - 'aIYal/81Ut1778lU01PEt563TcQnUBlnjU5OR25KhfSeN5CZY7QUVGVzdCA8dGVz', - 'dEB0ZXN0LmNvbT6IYgQTEQIAIgUCURGXDgIbAwYLCQgHAwIGFQgCCQoLBBYCAwEC', - 'HgECF4AACgkQikDlZK/UvLSspgCfcNaOpTg1W2ucR1JwBbBGvaERfuMAnRgt3/rs', - 'EplqEakMckCtikEnpxYe', - '=b2Ln', - '-----END PGP PUBLIC KEY BLOCK-----' - ].join("\n"); - var msg_arm1 = - [ '-----BEGIN PGP MESSAGE-----', - 'Version: GnuPG v1.4.11 (GNU/Linux)', - '', - 'hQEOA1N4OCSSjECBEAP/diDJCQn4e88193PgqhbfAkohk9RQ0v0MPnXpJbCRTHKO', - '8r9nxiAr/TQv4ZOingXdAp2JZEoE9pXxZ3r1UWew04czxmgJ8FP1ztZYWVFAWFVi', - 'Tj930TBD7L1fY/MD4fK6xjEG7z5GT8k4tn4mLm/PpWMbarIglfMopTy1M/py2cID', - '/2Sj7Ikh3UFiG+zm4sViYc5roNbMy8ixeoKixxi99Mx8INa2cxNfqbabjblFyc0Z', - 'BwmbIc+ZiY2meRNI5y/tk0gRD7hT84IXGGl6/mH00bsX/kkWdKGeTvz8s5G8RDHa', - 'Za4HgLbXItkX/QarvRS9kvkD01ujHfj+1ZvgmOBttNfP0p8BQLIICqvg1eYD9aPB', - '+GtOZ2F3+k5VyBL5yIn/s65SBjNO8Fqs3aL0x+p7s1cfUzx8J8a8nWpqq/qIQIqg', - 'ZJH6MZRKuQwscwH6NWgsSVwcnVCAXnYOpbHxFQ+j7RbF/+uiuqU+DFH/Rd5pik8b', - '0Dqnp0yfefrkjQ0nuvubgB6Rv89mHpnvuJfFJRInpg4lrHwLvRwdpN2HDozFHcKK', - 'aOU=', - '=4iGt', - '-----END PGP MESSAGE-----' - ].join("\n"); - - var priv_key_arm2 = - ['-----BEGIN PGP PRIVATE KEY BLOCK-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - 'Type: RSA/RSA', - 'Pwd: hello world', - '', - 'lQH+BFJhL04BBADclrUEDDsm0PSZbQ6pml9FpzTyXiyCyDN+rMOsy9J300Oc10kt', - '/nyBej9vZSRcaW5VpNNj0iA+c1/w2FPf84zNsTzvDmuMaNHFUzky4/vkYuZra//3', - '+Ri7CF8RawSYQ/4IRbC9zqdBlzniyfQOW7Dp/LYe8eibnDSrmkQem0G0jwARAQAB', - '/gMDAu7L//czBpE40p1ZqO8K3k7UejemjsQqc7kOqnlDYd1Z6/3NEA/UM30Siipr', - 'KjdIFY5+hp0hcs6EiiNq0PDfm/W2j+7HfrZ5kpeQVxDek4irezYZrl7JS2xezaLv', - 'k0Fv/6fxasnFtjOM6Qbstu67s5Gpl9y06ZxbP3VpT62+Xeibn/swWrfiJjuGEEhM', - 'bgnsMpHtzAz/L8y6KSzViG/05hBaqrvk3/GeEA6nE+o0+0a6r0LYLTemmq6FbaA1', - 'PHo+x7k7oFcBFUUeSzgx78GckuPwqr2mNfeF+IuSRnrlpZl3kcbHASPAOfEkyMXS', - 'sWGE7grCAjbyQyM3OEXTSyqnehvGS/1RdB6kDDxGwgE/QFbwNyEh6K4eaaAThW2j', - 'IEEI0WEnRkPi9fXyxhFsCLSI1XhqTaq7iDNqJTxE+AX2b9ZuZXAxI3Tc/7++vEyL', - '3p18N/MB2kt1Wb1azmXWL2EKlT1BZ5yDaJuBQ8BhphM3tCRUZXN0IE1jVGVzdGlu', - 'Z3RvbiA8dGVzdEBleGFtcGxlLmNvbT6IuQQTAQIAIwUCUmEvTgIbLwcLCQgHAwIB', - 'BhUIAgkKCwQWAgMBAh4BAheAAAoJEEpjYTpNbkCUMAwD+gIK08qpEZSVas9qW+Ok', - '32wzNkwxe6PQgZwcyBqMQYZUcKagC8+89pMQQ5sKUGvpIgat42Tf1KLGPcvG4cDA', - 'JZ6w2PYz9YHQqPh9LA+PAnV8m25TcGmKcKgvFUqQ3U53X/Y9sBP8HooRqfwwHcv9', - 'pMgQmojmNbI4VHydRqIBePawnQH+BFJhL04BBADpH8+0EVolpPiOrXTKoBKTiyrB', - 'UyxzodyJ8zmVJ3HMTEU/vidpQwzISwoc/ndDFMXQauq6xqBCD9m2BPQI3UdQzXnb', - 'LsAI52nWCIqOkzM5NAKWoKhyXK9Y4UH4v9LAYQgl/stIISvCgG4mJ8lzzEBWvRdf', - 'Qm2Ghb64/3V5NDdemwARAQAB/gMDAu7L//czBpE40iPcpLzL7GwBbWFhSWgSLy53', - 'Md99Kxw3cApWCok2E8R9/4VS0490xKZIa5y2I/K8thVhqk96Z8Kbt7MRMC1WLHgC', - 'qJvkeQCI6PrFM0PUIPLHAQtDJYKtaLXxYuexcAdKzZj3FHdtLNWCooK6n3vJlL1c', - 'WjZcHJ1PH7USlj1jup4XfxsbziuysRUSyXkjn92GZLm+64vCIiwhqAYoizF2NHHG', - 'hRTN4gQzxrxgkeVchl+ag7DkQUDANIIVI+A63JeLJgWJiH1fbYlwESByHW+zBFNt', - 'qStjfIOhjrfNIc3RvsggbDdWQLcbxmLZj4sB0ydPSgRKoaUdRHJY0S4vp9ouKOtl', - '2au/P1BP3bhD0fDXl91oeheYth+MSmsJFDg/vZJzCJhFaQ9dp+2EnjN5auNCNbaI', - 'beFJRHFf9cha8p3hh+AK54NRCT++B2MXYf+TPwqX88jYMBv8kk8vYUgo8128r1zQ', - 'EzjviQE9BBgBAgAJBQJSYS9OAhsuAKgJEEpjYTpNbkCUnSAEGQECAAYFAlJhL04A', - 'CgkQ4IT3RGwgLJe6ogQA2aaJEIBIXtgrs+8WSJ4k3DN4rRXcXaUZf667pjdD9nF2', - '3BzjFH6Z78JIGaxRHJdM7b05aE8YuzM8f3NIlT0F0OLq/TI2muYU9f/U2DQBuf+w', - 'KTB62+PELVgi9MsXC1Qv/u/o1LZtmmxTFFOD35xKsxZZI2OJj2pQpqObW27M8Nlc', - 'BQQAw2YA3fFc38qPK+PY4rZyTRdbvjyyX+1zeqIo8wn7QCQwXs+OGaH2fGoT35AI', - 'SXuqKcWqoEuO7OBSEFThCXBfUYMC01OrqKEswPm/V3zZkLu01q12UMwZach28QwK', - '/YZly4ioND2tdazj17u2rU2dwtiHPe1iMqGgVMoQirfLc+k=', - '=lw5e', - '-----END PGP PRIVATE KEY BLOCK-----'].join('\n'); - - var pub_key_arm2 = - ['-----BEGIN PGP PUBLIC KEY BLOCK-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - 'Type: RSA/RSA', - '', - 'mI0EUmEvTgEEANyWtQQMOybQ9JltDqmaX0WnNPJeLILIM36sw6zL0nfTQ5zXSS3+', - 'fIF6P29lJFxpblWk02PSID5zX/DYU9/zjM2xPO8Oa4xo0cVTOTLj++Ri5mtr//f5', - 'GLsIXxFrBJhD/ghFsL3Op0GXOeLJ9A5bsOn8th7x6JucNKuaRB6bQbSPABEBAAG0', - 'JFRlc3QgTWNUZXN0aW5ndG9uIDx0ZXN0QGV4YW1wbGUuY29tPoi5BBMBAgAjBQJS', - 'YS9OAhsvBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQSmNhOk1uQJQwDAP6', - 'AgrTyqkRlJVqz2pb46TfbDM2TDF7o9CBnBzIGoxBhlRwpqALz7z2kxBDmwpQa+ki', - 'Bq3jZN/UosY9y8bhwMAlnrDY9jP1gdCo+H0sD48CdXybblNwaYpwqC8VSpDdTndf', - '9j2wE/weihGp/DAdy/2kyBCaiOY1sjhUfJ1GogF49rC4jQRSYS9OAQQA6R/PtBFa', - 'JaT4jq10yqASk4sqwVMsc6HcifM5lSdxzExFP74naUMMyEsKHP53QxTF0Grqusag', - 'Qg/ZtgT0CN1HUM152y7ACOdp1giKjpMzOTQClqCoclyvWOFB+L/SwGEIJf7LSCEr', - 'woBuJifJc8xAVr0XX0JthoW+uP91eTQ3XpsAEQEAAYkBPQQYAQIACQUCUmEvTgIb', - 'LgCoCRBKY2E6TW5AlJ0gBBkBAgAGBQJSYS9OAAoJEOCE90RsICyXuqIEANmmiRCA', - 'SF7YK7PvFkieJNwzeK0V3F2lGX+uu6Y3Q/Zxdtwc4xR+me/CSBmsURyXTO29OWhP', - 'GLszPH9zSJU9BdDi6v0yNprmFPX/1Ng0Abn/sCkwetvjxC1YIvTLFwtUL/7v6NS2', - 'bZpsUxRTg9+cSrMWWSNjiY9qUKajm1tuzPDZXAUEAMNmAN3xXN/Kjyvj2OK2ck0X', - 'W748sl/tc3qiKPMJ+0AkMF7Pjhmh9nxqE9+QCEl7qinFqqBLjuzgUhBU4QlwX1GD', - 'AtNTq6ihLMD5v1d82ZC7tNatdlDMGWnIdvEMCv2GZcuIqDQ9rXWs49e7tq1NncLY', - 'hz3tYjKhoFTKEIq3y3Pp', - '=h/aX', - '-----END PGP PUBLIC KEY BLOCK-----'].join('\n'); - -var pub_key_arm3 = - ['-----BEGIN PGP PUBLIC KEY BLOCK-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - '', - 'mQENBFKV0FUBCACtZliApy01KBGbGNB36YGH4lpr+5KoqF1I8A5IT0YeNjyGisOk', - 'WsDsUzOqaNvgzQ82I3MY/jQV5rLBhH/6LiRmCA16WkKcqBrHfNGIxJ+Q+ofVBHUb', - 'aS9ClXYI88j747QgWzirnLuEA0GfilRZcewII1pDA/G7+m1HwV4qHsPataYLeboq', - 'hPA3h1EVVQFMAcwlqjOuS8+weHQRfNVRGQdRMm6H7166PseDVRUHdkJpVaKFhptg', - 'rDoNI0lO+UujdqeF1o5tVZ0j/s7RbyBvdLTXNuBbcpq93ceSWuJPZmi1XztQXKYe', - 'y0f+ltgVtZDEc7TGV5WDX9erRECCcA3+s7J3ABEBAAG0G0pTIENyeXB0byA8ZGlm', - 'ZmllQGhvbWUub3JnPokBPwQTAQIAKQUCUpXQVQIbAwUJCWYBgAcLCQgHAwIBBhUI', - 'AgkKCwQWAgMBAh4BAheAAAoJENvyI+hwU030yRAIAKX/mGEgi/miqasbbQoyK/CS', - 'a7sRxgZwOWQLdi2xxpE5V4W4HJIDNLJs5vGpRN4mmcNK2fmJAh74w0PskmVgJEhP', - 'dFJ14UC3fFPq5nbqkBl7hU0tDP5jZxo9ruQZfDOWpHKxOCz5guYJ0CW97bz4fChZ', - 'NFDyfU7VsJQwRIoViVcMCipP0fVZQkIhhwpzQpmVmN8E0a6jWezTZv1YpMdlzbEf', - 'H79l3StaOh9/Un9CkIyqEWdYiKvIYms9nENyehN7r/OKYN3SW+qlt5GaL+ws+N1w', - '6kEZjPFwnsr+Y4A3oHcAwXq7nfOz71USojSmmo8pgdN8je16CP98vw3/k6TncLS5', - 'AQ0EUpXQVQEIAMEjHMeqg7B04FliUFWr/8C6sJDb492MlGAWgghIbnuJfXAnUGdN', - 'oAzn0S+n93Y/qHbW6YcjHD4/G+kK3MuxthAFqcVjdHZQXK0rkhXO/u1co7v1cdtk', - 'OTEcyOpyLXolM/1S2UYImhrml7YulTHMnWVja7xu6QIRso+7HBFT/u9D47L/xXrX', - 'MzXFVZfBtVY+yoeTrOY3OX9cBMOAu0kuN9eT18Yv2yi6XMzP3iONVHtl6HfFrAA7', - 'kAtx4ne0jgAPWZ+a8hMy59on2ZFs/AvSpJtSc1kw/vMTWkyVP1Ky20vAPHQ6Ej5q', - '1NGJ/JbcFgolvEeI/3uDueLjj4SdSIbLOXMAEQEAAYkBJQQYAQIADwUCUpXQVQIb', - 'DAUJCWYBgAAKCRDb8iPocFNN9NLkB/wO4iRxia0zf4Kw2RLVZG8qcuo3Bw9UTXYY', - 'lI0AutoLNnSURMLLCq6rcJ0BCXGj/2iZ0NBxZq3t5vbRh6uUv+hpiSxK1nF7AheN', - '4aAAzhbWx0UDTF04ebG/neE4uDklRIJLhif6+Bwu+EUeTlGbDj7fqGSsNe8g92w7', - '1e41rF/9CMoOswrKgIjXAou3aexogWcHvKY2D+1q9exORe1rIa1+sUGl5PG2wsEs', - 'znN6qtN5gMlGY1ofWDY+I02gO4qzaZ/FxRZfittCw7v5dmQYKot9qRi2Kx3Fvw+h', - 'ivFBpC4TWgppFBnJJnAsFXZJQcejMW4nEmOViRQXY8N8PepQmgsu', - '=ummy', - '-----END PGP PUBLIC KEY BLOCK-----'].join('\n'); - - - var tests = [function() { - var priv_key = openpgp.key.readArmored(priv_key_arm1).packets; - var pub_key = openpgp.key.readArmored(pub_key_arm1).packets; - var msg = openpgp.message.readArmored(msg_arm1).packets; - //TODO need both? - priv_key[0].decrypt("abcd"); - priv_key[3].decrypt("abcd"); - msg[0].decrypt(priv_key[3]); - msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); - msg[1].packets[2].verify(pub_key[0], msg[1].packets[1]); - return new unit.result("Testing signature checking on CAST5-enciphered message", - msg[1].packets[2].verified === true); - - }, function() { - - // exercises the GnuPG s2k type 1001 extension: - // the secrets on the primary key have been stripped. - var priv_key_gnupg_ext = openpgp.key.readArmored([ - '-----BEGIN PGP PRIVATE KEY BLOCK-----', - 'Version: GnuPG v1.4.11 (GNU/Linux)', - '', - 'lQGqBFERnrMRBADmM0hIfkI3yosjgbWo9v0Lnr3CCE+8KsMszgVS+hBu0XfGraKm', - 'ivcA2aaJimHqVYOP7gEnwFAxHBBpeTJcu5wzCFyJwEYqVeS3nnaIhBPplSF14Duf', - 'i6bB9RV7KxVAg6aunmM2tAutqC+a0y2rDaf7jkJoZ9gWJe2zI+vraD6fiwCgxvHo', - '3IgULB9RqIqpLoMgXfcjC+cD/1jeJlKRm+n71ryYwT/ECKsspFz7S36z6q3XyS8Q', - 'QfrsUz2p1fbFicvJwIOJ8B20J/N2/nit4P0gBUTUxv3QEa7XCM/56/xrGkyBzscW', - 'AzBoy/AK9K7GN6z13RozuAS60F1xO7MQc6Yi2VU3eASDQEKiyL/Ubf/s/rkZ+sGj', - 'yJizBACtwCbQzA+z9XBZNUat5NPgcZz5Qeh1nwF9Nxnr6pyBv7tkrLh/3gxRGHqG', - '063dMbUk8pmUcJzBUyRsNiIPDoEUsLjY5zmZZmp/waAhpREsnK29WLCbqLdpUors', - 'c1JJBsObkA1IM8TZY8YUmvsMEvBLCCanuKpclZZXqeRAeOHJ0v4DZQJHTlUBtBZU', - 'ZXN0MiA8dGVzdDJAdGVzdC5jb20+iGIEExECACIFAlERnrMCGwMGCwkIBwMCBhUI', - 'AgkKCwQWAgMBAh4BAheAAAoJEBEnlAPLFp74xc0AoLNZINHe0ytOsNtMCuLvc3Vd', - 'vePUAJ9KX3L5IBqHarsa+aJHX7r796SokZ0BWARREZ6zEAQA2WkxmNbfeMzGUocN', - '3JEVe0o6rxGt5eGrTSmWisduDP3MURabhUXnf4T8oaeYcbJjkLLxMrJmNq55ln1e', - '4bSG5mDkh/ryKsV81m3F0DbqO/z/891nRSP5fondFVral4wsMOzBNgs4vVk7V/F2', - '0MPjR90CIhnVDKPAQbQA+3PjUR8AAwUEALn922AEE+0d7xSMMFpR7ic3Me5QEGnp', - 'cT4ft6oc0UK5kAnvKoksZUc0hpBHjX1w3LTz847/5hRDuuDvwvGMWK8IfsjOF9T7', - 'rK8QtJuBEyJxjoScA/YZP5vX4y0U1reUEa0EdwmVrnZzatMAe2FhlaR9PlHkOcm5', - 'DZwkcExL0dbI/gMDArxZ+5N7kH4zYLtr9glJS/pJ7F0YJqJpNwCbqD8+8DqHD8Uv', - 'MgQ/rtBxBJJOaF+1AjCd123hLgzIkkfdTh8loV9hDXMKeJgmiEkEGBECAAkFAlER', - 'nrMCGwwACgkQESeUA8sWnvhBswCfdXjznvHCc73/6/MhWcv3dbeTT/wAoLyiZg8+', - 'iY3UT9QkV9d0sMgyLkug', - '=GQsY', - '-----END PGP PRIVATE KEY BLOCK-----', - ].join("\n")).packets; - var pub_key = openpgp.key.readArmored(pub_key_arm1).packets; - var msg = openpgp.message.readArmored(msg_arm1).packets; - - priv_key_gnupg_ext[3].decrypt("abcd"); - msg[0].decrypt(priv_key_gnupg_ext[3]); - msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); - msg[1].packets[2].verify(pub_key[0], msg[1].packets[1]); - return new unit.result("Testing GnuPG stripped-key extensions", - msg[1].packets[2].verified === true); - - }, function() { - - var signedArmor = - ['-----BEGIN PGP MESSAGE-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - '', - 'owGbwMvMwMT4oOW7S46CznTGNeZJLCWpFSVBU3ZGF2fkF5Uo5KYWFyemp3LlAUUV', - 'cjLzUrneTp3zauvaN9O26L9ZuOFNy4LXyydwcXXMYWFgZGJgY2UCaWXg4hSAmblK', - 'nPmfsXYxd58Ka9eVrEnSpzilr520fXBrJsf2P/oTqzTj3hzyLG0o3TTzxFfrtOXf', - 'cw6U57n3/Z4X0pEZ68C5/o/6NpPICD7fuEOz3936raZ6wXGzueY8pfPnVjY0ajAc', - 'PtJzvvqj+ubYaT1sK9wWhd9lL3/V+9Zuua9QjOWC22buchsCroh8fLoZAA==', - '=VH8F', - '-----END PGP MESSAGE-----'].join('\n'); - - var sMsg = openpgp.message.readArmored(signedArmor).packets; - var pub_key = openpgp.key.readArmored(pub_key_arm2).packets; - sMsg[0].packets[2].verify(pub_key[3], sMsg[0].packets[1]); - return new unit.result("Verify V4 signature. Hash: SHA1. PK: RSA. Signature Type: 0x00 (binary document)", sMsg[0].packets[2].verified); - }, function() { - - var signedArmor = - ['-----BEGIN PGP MESSAGE-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - '', - 'owGbwMvMyMj4oOW7S46CznTG09YlLCWpFSVBU47xFGfkF5Uo5KYWFyemp/Jy5QGF', - 'FXIy84DMt1PnvNq69s20LfpvFm5407Lg9fIJvFy8XJ0MU5lZGUFa4eYxxiQz/6+/', - 'aFt4/6+e76O6s1afLi65emmK9xsdh7Mr60UnT2UN0LwocWnT7t/nOMJubnypvzTu', - 'aPJyvm9TTpobW/O+P1n2THLS4UCvWt12Oa2lJ04GLwk/bDF1u+8ZpfPCpsxLVzcs', - 'ZGtbq/f23XxV/jkL47hr3s3Ic4yoZTW4oZO27GYf37TPp9L3VboCAA==', - '=pa6B', - '-----END PGP MESSAGE-----'].join('\n'); - - var sMsg = openpgp.message.readArmored(signedArmor).packets; - var pub_key = openpgp.key.readArmored(pub_key_arm2).packets; - sMsg[0].packets[2].verify(pub_key[3], sMsg[0].packets[1]); - return new unit.result("Verify V3 signature. Hash: MD5. PK: RSA. Signature Type: 0x01 (text document)", sMsg[0].packets[2].verified); - }, function() { - - var msg_armor = - ['-----BEGIN PGP MESSAGE-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - '', - 'hIwD4IT3RGwgLJcBBADEBdm+GEW7IV1K/Bykg0nB0WYO08ai7/8/+Y/O9xu6RiU0', - 'q7/jWuKms7kSjw9gxMCjf2dGnAuT4Cg505Kj5WfeBuHh618ovO8qo4h0qHyp1/y3', - 'o1P0IXPAb+LGJOeO7DyM9Xp2AOBiIKOVWzFTg+MBZOc+XZEVx3FioHfm9SSDudLA', - 'WAEkDakCG6MRFj/7SmOiV8mQKH+YPMKT69eDZW7hjINabrpM2pdRU7c9lC7CMUBx', - 'Vj7wZsQBMASSC8f2rhpGA2iKvYMsmW3g9R1xkvj1MXWftSPUS4jeNTAgEwvvF6Af', - 'cP+OYSXKlTbwfEr73ES2O3/IFE9sHRjPqWaxWuv4DDQ5YfIxE54C1aE8Aq5/QaIH', - 'v38TUSia0yEMCc/tJd58DikkT07AF162tcx9Ro0ZjhudyuvUyXIfPfxA+XWR2pdz', - 'ifxyV4zia9RvaCUY8vXGM+gQJ3NNXx2LkZA3kWUEyxFVL1Vl/XUQY0M6U+uccSk4', - 'eMXm6eyEWDcj0lBRckqKoKo1w/uan11jPuHsnRz6jO9DsuKEz79UDgI=', - '=cFi7', - '-----END PGP MESSAGE-----'].join('\n'); - - var plaintext = 'short message\nnext line\n한국어/조선말'; - var esMsg = openpgp.message.readArmored(msg_armor); - var pubKey = openpgp.key.readArmored(pub_key_arm2); - var privKey = openpgp.key.readArmored(priv_key_arm2); - - var keyids = esMsg.getEncryptionKeyIds(); - privKey.decryptKeyPacket(keyids, 'hello world'); - - var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], esMsg); - var verified = decrypted.text == plaintext && decrypted.signatures[0].status; - - return new unit.result("Verify signature of signed and encrypted message from GPG2 with openpgp.decryptAndVerifyMessage", verified); - }, function() { - - var msg_armor = - ['-----BEGIN PGP MESSAGE-----', - 'Version: Encryption Desktop 10.3.0 (Build 9307)', - 'Charset: utf-8', - '', - 'qANQR1DBjAPghPdEbCAslwED/2S4oNvCjO5TdLUMMUuVOQc8fi6c5XIBu7Y09fEX', - 'Jm/UrkDHVgmPojLGBDF0CYENNZOVrNfpahY7A3r4HPzGucBzCO1uxuUIKjhtNAAM', - 'mjD939ernjooOZrM6xDuRaX8adG0LSxpNaVJGxXd/EdlmKDJbYDI6aJ5INrUxzAR', - 'DAqw0sBSAXgRWgiH6IIiAo5y5WFEDEN9sGStaEQT2wd32kX73M4iZuMt/GM2agiB', - 'sWb7yLcNHiJ/3OnTfDg9+T543kFq9FlwFbwqygO/wm9e/kgMBq0ZsFOfV+GRtXep', - '3qNbJsmzGvdqiUHb/+hkdE191jaSVcO/zaMW4N0Vc1IwIEhZ8I9+9bKwusdVhHT5', - 'MySnhIogv+0Ilag/aY+UiCt+Zcie69T7Eix48fC/VVW5w3INf1T2CMmDm5ZLZFRN', - 'oyqzb9Vsgu1gS7SCb6qTbnbV9PlSyU4wJB6siX8hz/U0urokT5se3uYRjiV0KbkA', - 'zl1/r/wCrmwX4Gl9VN9+33cQgYZAlJLsRw8N82GhbVweZS8qwv24GQ==', - '=nx90', - '-----END PGP MESSAGE-----'].join('\n'); - - var plaintext = 'short message\nnext line\n한국어/조선말\n\n'; - var esMsg = openpgp.message.readArmored(msg_armor); - var pubKey = openpgp.key.readArmored(pub_key_arm2); - var privKey = openpgp.key.readArmored(priv_key_arm2); - - var keyids = esMsg.getEncryptionKeyIds(); - privKey.decryptKeyPacket(keyids, 'hello world'); - - var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], esMsg); - var verified = decrypted.text == plaintext && decrypted.signatures[0].status; - - return new unit.result("Verify signature of signed and encrypted message from PGP 10.3.0 with openpgp.decryptAndVerifyMessage", verified); - }, function() { - - var msg_armor = - ['-----BEGIN PGP MESSAGE-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - '', - 'owGbwMvMwMF4+5Pyi4Jg3y8ME8DcBy3fXXIUdKYzrjFNYilJrSgJmsXDXJyRX1Si', - 'kJtaXJyYnsqVBxRVyMnMS+V6O3XOq61r30zbov9m4YY3LQteL5/QMYeFgZGDgY2V', - 'CaSRgYtTAGZiYxYLwySbQk07ptZel6gmjrKyBWsyWdkOG3oscLBdIpXXfDdb6fNv', - '8ULN5L1ed+xNo79P2dBotWud6vn7e9dtLJ7o12PunnvEz8gyyvP4/As/los0xsnZ', - 'H+8ublrhvGtLxJUZuUKZO6QdHq2Nepuw8OrfiMXPBDQXXpV2q11Ze+rD3lndgv/C', - 'bJQNOhll0J0H839jFvt/16m20h/ZmDoWqJywapnypjdIjcXr+7rJFess40yenV7Q', - '2LSu/EX6Aq29x+dv+GPUMfuhTNE3viWWUR4PD6T7XfmdViUwmSf8fkRNUn/t3a2n', - 'cq46Xr36seCor/OLp0atSZwHrjx2SU5zPLheZn+zw/0d1/YZnD7AEeP9s/Cuycyv', - 'CZ5HZNKufvB8fsh+dfdSXW0GfqkPfxk36Vw8ufpjaoZDyt2nxxg/6D4KS3UvZzv3', - 'axdLZ9yd0OJNZv4P501If24W4vTGz6nI7Ser8Yd2PiOvE5MWMT0wLZQ+zPX1sv0/', - 's8PvkyWmVM0O0fB/ZSHovHNNPffDg/rWhzOmXQ9/7vTn477F+aWm5sYzJ75/BQA=', - '=+L0S', - '-----END PGP MESSAGE-----'].join('\n'); - - var plaintext = 'short message\nnext line\n한국어/조선말'; - var sMsg = openpgp.message.readArmored(msg_armor); - var pubKey2 = openpgp.key.readArmored(pub_key_arm2); - var pubKey3 = openpgp.key.readArmored(pub_key_arm3); - - var keyids = sMsg.getSigningKeyIds(); - - var verified = pubKey2.getPublicKeyPacket(keyids) !== null && pubKey3.getPublicKeyPacket(keyids) !== null; - - verified = verified && sMsg.getText() == plaintext; - - var verifiedSig = sMsg.verify([pubKey2, pubKey3]); - - verified = verified && verifiedSig[0].status && verifiedSig[1].status; - - return new unit.result("Verify signed message with two one pass signatures", verified); - }, function() { - - var msg_armor = - ['-----BEGIN PGP SIGNED MESSAGE-----', - 'Hash: SHA256', - '', - 'short message', - 'next line', - '한국어/조선말', - '-----BEGIN PGP SIGNATURE-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - '', - 'iJwEAQEIAAYFAlKcju8ACgkQ4IT3RGwgLJci6gP/dCmIraUa6AGpJxzGfK+jYpjl', - 'G0KunFyGmyPxeJVnPi2bBp3EPIbiayQ71CcDe9DKpF046tora07AA9eo+/YbvJ9P', - 'PWeScw3oj/ejsmKQoDBGzyDMFUphevnhgc5lENjovJqmiu6FKjNmADTxcZ/qFTOq', - '44EWTgdW3IqXFkNpKjeJARwEAQEIAAYFAlKcju8ACgkQ2/Ij6HBTTfQi6gf9HxhE', - 'ycLDhQ8iyC090TaYwsDytScU2vOMiI5rJCy2tfDV0pfn+UekYGMnKxZTpwtmno1j', - 'mVOlieENszz5IcehS5TYwk4lmRFjoba+Z8qwPEYhYxP29GMbmRIsH811sQHFTigo', - 'LI2t4pSSSUpAiXd9y6KtvkWcGGn8IfkNHCEHPh1ov28QvH0+ByIiKYK5N6ZB8hEo', - '0uMYhKQPVJdPCvMkAxQCRPw84EvmxuJ0HMCeSB9tHQXpz5un2m8D9yiGpBQPnqlW', - 'vCCq7fgaUz8ksxvQ9bSwv0iIIbbBdTP7Z8y2c1Oof6NDl7irH+QCeNT7IIGs8Smn', - 'BEzv/FqkQAhjy3Krxg==', - '=3Pkl', - '-----END PGP SIGNATURE-----'].join('\n'); - - var plaintext = 'short message\nnext line\n한국어/조선말'; - var csMsg = openpgp.cleartext.readArmored(msg_armor); - var pubKey2 = openpgp.key.readArmored(pub_key_arm2); - var pubKey3 = openpgp.key.readArmored(pub_key_arm3); - - var keyids = csMsg.getSigningKeyIds(); - - var verified = pubKey2.getPublicKeyPacket(keyids) !== null && pubKey3.getPublicKeyPacket(keyids) !== null; - - var cleartextSig = openpgp.verifyClearSignedMessage([pubKey2, pubKey3], csMsg); - - verified = verified && cleartextSig.text == plaintext; - - verified = verified && cleartextSig.signatures[0].status && cleartextSig.signatures[1].status; - - return new unit.result("Verify cleartext signed message with two signatures with openpgp.verifyClearSignedMessage", verified); - }, function() { - - var plaintext = 'short message\nnext line\n한국어/조선말'; - var pubKey = openpgp.key.readArmored(pub_key_arm2); - var privKey = openpgp.key.readArmored(priv_key_arm2); - privKey.getSigningKeyPacket().decrypt('hello world'); - - var clearSignedArmor = openpgp.signClearMessage([privKey], plaintext); - - var csMsg = openpgp.cleartext.readArmored(clearSignedArmor); - - var cleartextSig = openpgp.verifyClearSignedMessage([pubKey], csMsg); - - var verified = cleartextSig.text == plaintext.replace(/\r/g,''); - - verified = verified && cleartextSig.signatures[0].status; - - return new unit.result("Sign text with openpgp.signClearMessage and verify with openpgp.verifyClearSignedMessage leads to same cleartext and valid signatures", verified); - }, function() { - - var msg_armor = - ['-----BEGIN PGP SIGNED MESSAGE-----', - 'Hash: SHA256', - '', - 'äöü', - 'some', - 'more', - '-----BEGIN PGP SIGNATURE-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - '', - 'iJwEAQEIAAYFAlKkbS8ACgkQ4IT3RGwgLJf/4wQAiG8s4CwL+YcvVaY/UVEuVCN+', - '7Z/y9kNIU3MuPQy/7kiAV/f3mE488363LelrLuppZRpAmbYFmFCklK/xgXF1MfRQ', - 'J7ZGW0PrxQPi8KR8kSPzaUjkzUk86sARB0LeIxcG+5T/qh7fDXCRRyXPom5Ebqsf', - 'XCEfvvdJ60zitnlFiIY=', - '=dm/N', - '-----END PGP SIGNATURE-----'].join('\n'); - - var plaintext = 'äöü\nsome\nmore'; - var csMsg = openpgp.cleartext.readArmored(msg_armor); - var pubKey2 = openpgp.key.readArmored(pub_key_arm2); - - var keyids = csMsg.getSigningKeyIds(); - - var cleartextSig = openpgp.verifyClearSignedMessage([pubKey2], csMsg); - - var verified = cleartextSig.text == plaintext; - - verified = verified && cleartextSig.signatures[0].status; - - return new unit.result("Verify cleartext signed message with CP-1252 character encoding", verified); - }]; - - var results = []; - - for(var i in tests) { - results.push(tests[i]()); - } - - return results; - -}); -},{"../../":29,"../unit.js":73}],"test-bundle.js":[function(require,module,exports){ -module.exports=require('QjPZ1q'); -},{}],"QjPZ1q":[function(require,module,exports){ - -module.exports = require('./unit.js'); - -require('./crypto/hash/sha.js'); -require('./crypto/hash/md5.js'); -require('./crypto/hash/ripemd.js'); - -require('./crypto/cipher/aes.js'); -require('./crypto/cipher/blowfish.js'); -require('./crypto/cipher/cast5.js'); -require('./crypto/cipher/des.js'); -require('./crypto/cipher/twofish.js'); - -require('./crypto/crypto.js'); - -require('./general/basic.js'); -require('./general/keyring.js'); -require('./general/packet.js'); -require('./general/signature.js'); - -},{"./crypto/cipher/aes.js":58,"./crypto/cipher/blowfish.js":59,"./crypto/cipher/cast5.js":60,"./crypto/cipher/des.js":61,"./crypto/cipher/twofish.js":62,"./crypto/crypto.js":63,"./crypto/hash/md5.js":64,"./crypto/hash/ripemd.js":65,"./crypto/hash/sha.js":66,"./general/basic.js":67,"./general/keyring.js":68,"./general/packet.js":69,"./general/signature.js":70,"./unit.js":73}],73:[function(require,module,exports){ -var process=require("__browserify_process"); -module.exports = { - tests: [], - register: function(str_title, func_runtest) { - this.tests.push({ title: str_title, run: func_runtest }); - }, - - run: function() { - var test = this.tests.shift(); - - var result = { - title: test.title - }; - - - result.tests = test.run(); - - return result; - }, - - run_all: function() { - var passed = true; - - while(this.tests.length > 0) { - var result = this.run(); - - console.log('Test: ' + result.title); - - for(var i in result.tests) { - - var res = result.tests[i].result ? - 'SUCCESS' : 'FAILED'; - - console.log(result.tests[i].description + ' ' + res); - - passed = passed && result.tests[i].result; - } - } - - if(!passed) process.exit(1); - }, - - result: function(str_description, boolean_result) { - this.description = str_description; - this.result = boolean_result; - } -} - - -},{"__browserify_process":1}]},{},[]) -//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyIvaG9tZS90b2Jlcm5kby9kZXYvbm9kZS9saWIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2luc2VydC1tb2R1bGUtZ2xvYmFscy9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY2xlYXJ0ZXh0LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY29tcHJlc3Npb24vanhnLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY29uZmlnL2NvbmZpZy5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9jZmIuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vY2lwaGVyL2Flcy5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9jaXBoZXIvYmxvd2Zpc2guanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vY2lwaGVyL2Nhc3Q1LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NpcGhlci9kZXMuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vY2lwaGVyL2luZGV4LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NpcGhlci90d29maXNoLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NyeXB0by5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9oYXNoL2luZGV4LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2hhc2gvbWQ1LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2hhc2gvcmlwZS1tZC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9oYXNoL3NoYS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9pbmRleC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9wa2NzMS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9wdWJsaWNfa2V5L2RzYS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9wdWJsaWNfa2V5L2VsZ2FtYWwuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vcHVibGljX2tleS9pbmRleC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9wdWJsaWNfa2V5L2pzYm4uanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vcHVibGljX2tleS9yc2EuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vcmFuZG9tLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL3NpZ25hdHVyZS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2VuY29kaW5nL2FybW9yLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvZW5jb2RpbmcvYmFzZTY0LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvZW51bXMuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9pbmRleC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2tleS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL2tleXJpbmcuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9tZXNzYWdlLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvb3BlbnBncC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9hbGxfcGFja2V0cy5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9jb21wcmVzc2VkLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L2luZGV4LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L2xpdGVyYWwuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvbWFya2VyLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L29uZV9wYXNzX3NpZ25hdHVyZS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9wYWNrZXQuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvcGFja2V0bGlzdC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9wdWJsaWNfa2V5LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3B1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3B1YmxpY19zdWJrZXkuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvc2VjcmV0X2tleS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9zZWNyZXRfc3Via2V5LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3NpZ25hdHVyZS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9zeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9zeW1tZXRyaWNhbGx5X2VuY3J5cHRlZC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC90cnVzdC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC91c2VyX2F0dHJpYnV0ZS5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC91c2VyaWQuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy90eXBlL2tleWlkLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC9zcmMvdHlwZS9tcGkuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3NyYy90eXBlL3Myay5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvc3JjL3V0aWwvdXRpbC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvdGVzdC9jcnlwdG8vY2lwaGVyL2Flcy5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvdGVzdC9jcnlwdG8vY2lwaGVyL2Jsb3dmaXNoLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC90ZXN0L2NyeXB0by9jaXBoZXIvY2FzdDUuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3Rlc3QvY3J5cHRvL2NpcGhlci9kZXMuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3Rlc3QvY3J5cHRvL2NpcGhlci90d29maXNoLmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC90ZXN0L2NyeXB0by9jcnlwdG8uanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3Rlc3QvY3J5cHRvL2hhc2gvbWQ1LmpzIiwiL2hvbWUvdG9iZXJuZG8vZGV2L29wZW5wZ3Bqcy1kZXZlbC90ZXN0L2NyeXB0by9oYXNoL3JpcGVtZC5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvdGVzdC9jcnlwdG8vaGFzaC9zaGEuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3Rlc3QvZ2VuZXJhbC9iYXNpYy5qcyIsIi9ob21lL3RvYmVybmRvL2Rldi9vcGVucGdwanMtZGV2ZWwvdGVzdC9nZW5lcmFsL2tleXJpbmcuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3Rlc3QvZ2VuZXJhbC9wYWNrZXQuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3Rlc3QvZ2VuZXJhbC9zaWduYXR1cmUuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3Rlc3QvdGVzdC1hbGwuanMiLCIvaG9tZS90b2Jlcm5kby9kZXYvb3BlbnBncGpzLWRldmVsL3Rlc3QvdW5pdC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNudkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNVpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNWxCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMVhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25TQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1bENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6cURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25KQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25LQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDblFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxbUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0ZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdjQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbnByb2Nlc3MubmV4dFRpY2sgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBjYW5TZXRJbW1lZGlhdGUgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5zZXRJbW1lZGlhdGU7XG4gICAgdmFyIGNhblBvc3QgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5wb3N0TWVzc2FnZSAmJiB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lclxuICAgIDtcblxuICAgIGlmIChjYW5TZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChmKSB7IHJldHVybiB3aW5kb3cuc2V0SW1tZWRpYXRlKGYpIH07XG4gICAgfVxuXG4gICAgaWYgKGNhblBvc3QpIHtcbiAgICAgICAgdmFyIHF1ZXVlID0gW107XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICBpZiAoZXYuc291cmNlID09PSB3aW5kb3cgJiYgZXYuZGF0YSA9PT0gJ3Byb2Nlc3MtdGljaycpIHtcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICBpZiAocXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm4gPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdHJ1ZSk7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgICAgICBxdWV1ZS5wdXNoKGZuKTtcbiAgICAgICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgncHJvY2Vzcy10aWNrJywgJyonKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dFRpY2soZm4pIHtcbiAgICAgICAgc2V0VGltZW91dChmbiwgMCk7XG4gICAgfTtcbn0pKCk7XG5cbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7XG52YXIgcGFja2V0ID0gcmVxdWlyZSgnLi9wYWNrZXQnKTtcbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4vZW51bXMuanMnKTtcbnZhciBhcm1vciA9IHJlcXVpcmUoJy4vZW5jb2RpbmcvYXJtb3IuanMnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgQ2xhc3MgdGhhdCByZXByZXNlbnRzIGFuIE9wZW5QR1AgY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlLlxuICogU2VlIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQ4ODAjc2VjdGlvbi03XG4gKiBAcGFyYW0gIHtTdHJpbmd9ICAgICB0ZXh0ICAgICAgIFRoZSBjbGVhcnRleHQgb2YgdGhlIHNpZ25lZCBtZXNzYWdlXG4gKiBAcGFyYW0gIHtwYWNrZXRsaXN0fSBwYWNrZXRsaXN0IFRoZSBwYWNrZXRsaXN0IHdpdGggc2lnbmF0dXJlIHBhY2tldHMgb3IgdW5kZWZpbmVkXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIG1lc3NhZ2Ugbm90IHlldCBzaWduZWRcbiAqL1xuXG5mdW5jdGlvbiBDbGVhcnRleHRNZXNzYWdlKHRleHQsIHBhY2tldGxpc3QpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIENsZWFydGV4dE1lc3NhZ2UpKSB7XG4gICAgcmV0dXJuIG5ldyBDbGVhcnRleHRNZXNzYWdlKHBhY2tldGxpc3QpO1xuICB9XG4gIC8vIG5vcm1hbGl6ZSBFT0wgdG8gY2Fub25pY2FsIGZvcm0gPENSPjxMRj5cbiAgdGhpcy50ZXh0ID0gdGV4dC5yZXBsYWNlKC9cXHIvZywgJycpLnJlcGxhY2UoL1tcXHQgXStcXG4vZywgXCJcXG5cIikucmVwbGFjZSgvXFxuL2csXCJcXHJcXG5cIik7XG4gIHRoaXMucGFja2V0cyA9IHBhY2tldGxpc3QgfHwgbmV3IHBhY2tldC5saXN0KCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUga2V5IElEcyBvZiB0aGUga2V5cyB0aGF0IHNpZ25lZCB0aGUgY2xlYXJ0ZXh0IG1lc3NhZ2VcbiAqIEByZXR1cm4ge1trZXlJZF19IGFycmF5IG9mIGtleWlkIG9iamVjdHNcbiAqL1xuQ2xlYXJ0ZXh0TWVzc2FnZS5wcm90b3R5cGUuZ2V0U2lnbmluZ0tleUlkcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIga2V5SWRzID0gW107XG4gIHZhciBzaWduYXR1cmVMaXN0ID0gdGhpcy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5zaWduYXR1cmUpO1xuICBzaWduYXR1cmVMaXN0LmZvckVhY2goZnVuY3Rpb24ocGFja2V0KSB7XG4gICAga2V5SWRzLnB1c2gocGFja2V0Lmlzc3VlcktleUlkKTtcbiAgfSk7XG4gIHJldHVybiBrZXlJZHM7XG59O1xuXG4vKipcbiAqIFNpZ24gdGhlIGNsZWFydGV4dCBtZXNzYWdlXG4gKiBAcGFyYW0gIHtba2V5XX0gcHJpdmF0ZUtleXMgcHJpdmF0ZSBrZXlzIHdpdGggZGVjcnlwdGVkIHNlY3JldCBrZXkgZGF0YSBmb3Igc2lnbmluZ1xuICovXG5DbGVhcnRleHRNZXNzYWdlLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24ocHJpdmF0ZUtleXMpIHtcbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTsgIFxuICB2YXIgbGl0ZXJhbERhdGFQYWNrZXQgPSBuZXcgcGFja2V0LmxpdGVyYWwoKTtcbiAgbGl0ZXJhbERhdGFQYWNrZXQuc2V0VGV4dCh0aGlzLnRleHQpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHByaXZhdGVLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHNpZ25hdHVyZVBhY2tldCA9IG5ldyBwYWNrZXQuc2lnbmF0dXJlKCk7XG4gICAgc2lnbmF0dXJlUGFja2V0LnNpZ25hdHVyZVR5cGUgPSBlbnVtcy5zaWduYXR1cmUudGV4dDtcbiAgICBzaWduYXR1cmVQYWNrZXQuaGFzaEFsZ29yaXRobSA9IGNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG07XG4gICAgdmFyIHNpZ25pbmdLZXlQYWNrZXQgPSBwcml2YXRlS2V5c1tpXS5nZXRTaWduaW5nS2V5UGFja2V0KCk7XG4gICAgc2lnbmF0dXJlUGFja2V0LnB1YmxpY0tleUFsZ29yaXRobSA9IHNpZ25pbmdLZXlQYWNrZXQuYWxnb3JpdGhtO1xuICAgIGlmICghc2lnbmluZ0tleVBhY2tldC5pc0RlY3J5cHRlZCkgdGhyb3cgbmV3IEVycm9yKCdQcml2YXRlIGtleSBpcyBub3QgZGVjcnlwdGVkLicpO1xuICAgIHNpZ25hdHVyZVBhY2tldC5zaWduKHNpZ25pbmdLZXlQYWNrZXQsIGxpdGVyYWxEYXRhUGFja2V0KTtcbiAgICBwYWNrZXRsaXN0LnB1c2goc2lnbmF0dXJlUGFja2V0KTtcbiAgfVxuICB0aGlzLnBhY2tldHMgPSBwYWNrZXRsaXN0O1xufTtcblxuLyoqXG4gKiBWZXJpZnkgc2lnbmF0dXJlcyBvZiBjbGVhcnRleHQgc2lnbmVkIG1lc3NhZ2VcbiAqIEBwYXJhbSB7W2tleV19IHB1YmxpY0tleXMgcHVibGljIGtleXMgdG8gdmVyaWZ5IHNpZ25hdHVyZXNcbiAqIEByZXR1cm4ge1t7J2tleWlkJzoga2V5aWQsICd2YWxpZCc6IEJvb2xlYW59XX0gbGlzdCBvZiBzaWduZXIncyBrZXlpZCBhbmQgdmFsaWRpdHkgb2Ygc2lnbmF0dXJlXG4gKi9cbkNsZWFydGV4dE1lc3NhZ2UucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uKHB1YmxpY0tleXMpIHtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIgc2lnbmF0dXJlTGlzdCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuc2lnbmF0dXJlKTtcbiAgdmFyIGxpdGVyYWxEYXRhUGFja2V0ID0gbmV3IHBhY2tldC5saXRlcmFsKCk7XG4gIC8vIHdlIGFzc3VtZSB0aGF0IGNsZWFydGV4dCBzaWduYXR1cmUgaXMgZ2VuZXJhdGVkIGJhc2VkIG9uIFVURjggY2xlYXJ0ZXh0LFxuICAvLyBmYWlscyBmb3Igb3RoZXIgZW5jb2RpbmdzLCBzZWUgQ1AtMTI1MiB0ZXN0IGNhc2UgaW4gdGVzdC9zaWduYXR1cmUuanNcbiAgbGl0ZXJhbERhdGFQYWNrZXQuc2V0VGV4dCh0aGlzLnRleHQpO1xuICBwdWJsaWNLZXlzLmZvckVhY2goZnVuY3Rpb24ocHViS2V5KSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaWduYXR1cmVMaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcHVibGljS2V5UGFja2V0ID0gcHViS2V5LmdldFB1YmxpY0tleVBhY2tldChbc2lnbmF0dXJlTGlzdFtpXS5pc3N1ZXJLZXlJZF0pO1xuICAgICAgaWYgKHB1YmxpY0tleVBhY2tldCkge1xuICAgICAgICB2YXIgdmVyaWZpZWRTaWcgPSB7fTtcbiAgICAgICAgdmVyaWZpZWRTaWcua2V5aWQgPSBzaWduYXR1cmVMaXN0W2ldLmlzc3VlcktleUlkO1xuICAgICAgICB2ZXJpZmllZFNpZy5zdGF0dXMgPSBzaWduYXR1cmVMaXN0W2ldLnZlcmlmeShwdWJsaWNLZXlQYWNrZXQsIGxpdGVyYWxEYXRhUGFja2V0KTtcbiAgICAgICAgcmVzdWx0LnB1c2godmVyaWZpZWRTaWcpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLyoqXG4gKiBHZXQgY2xlYXJ0ZXh0XG4gKiBAcmV0dXJuIHtTdHJpbmd9IGNsZWFydGV4dCBvZiBtZXNzYWdlXG4gKi9cbkNsZWFydGV4dE1lc3NhZ2UucHJvdG90eXBlLmdldFRleHQgPSBmdW5jdGlvbigpIHtcbiAgLy8gbm9ybWFsaXplIGVuZCBvZiBsaW5lIHRvIFxcblxuICByZXR1cm4gdGhpcy50ZXh0LnJlcGxhY2UoL1xcclxcbi9nLFwiXFxuXCIpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIEFTQ0lJIGFybW9yZWQgdGV4dCBvZiBjbGVhcnRleHQgc2lnbmVkIG1lc3NhZ2VcbiAqIEByZXR1cm4ge1N0cmluZ30gQVNDSUkgYXJtb3JcbiAqL1xuQ2xlYXJ0ZXh0TWVzc2FnZS5wcm90b3R5cGUuYXJtb3IgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGJvZHkgPSB7XG4gICAgaGFzaDogZW51bXMucmVhZChlbnVtcy5oYXNoLCBjb25maWcucHJlZmVyX2hhc2hfYWxnb3JpdGhtKS50b1VwcGVyQ2FzZSgpLFxuICAgIHRleHQ6IHRoaXMudGV4dCxcbiAgICBkYXRhOiB0aGlzLnBhY2tldHMud3JpdGUoKVxuICB9XG4gIHJldHVybiBhcm1vci5lbmNvZGUoZW51bXMuYXJtb3Iuc2lnbmVkLCBib2R5KTtcbn07XG5cblxuLyoqXG4gKiByZWFkcyBhbiBPcGVuUEdQIGNsZWFydGV4dCBzaWduZWQgbWVzc2FnZSBhbmQgcmV0dXJucyBhIENsZWFydGV4dE1lc3NhZ2Ugb2JqZWN0XG4gKiBAcGFyYW0ge1N0cmluZ30gYXJtb3JlZFRleHQgdGV4dCB0byBiZSBwYXJzZWRcbiAqIEByZXR1cm4ge0NsZWFydGV4dE1lc3NhZ2V9IG5ldyBjbGVhcnRleHQgbWVzc2FnZSBvYmplY3RcbiAqL1xuZnVuY3Rpb24gcmVhZEFybW9yZWQoYXJtb3JlZFRleHQpIHtcbiAgdmFyIGlucHV0ID0gYXJtb3IuZGVjb2RlKGFybW9yZWRUZXh0KTtcbiAgaWYgKGlucHV0LnR5cGUgIT09IGVudW1zLmFybW9yLnNpZ25lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignTm8gY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlLicpO1xuICB9XG4gIHZhciBwYWNrZXRsaXN0ID0gbmV3IHBhY2tldC5saXN0KCk7XG4gIHBhY2tldGxpc3QucmVhZChpbnB1dC5kYXRhKTtcbiAgdmFyIG5ld01lc3NhZ2UgPSBuZXcgQ2xlYXJ0ZXh0TWVzc2FnZShpbnB1dC50ZXh0LCBwYWNrZXRsaXN0KTtcbiAgcmV0dXJuIG5ld01lc3NhZ2U7XG59XG5cbmV4cG9ydHMuQ2xlYXJ0ZXh0TWVzc2FnZSA9IENsZWFydGV4dE1lc3NhZ2U7XG5leHBvcnRzLnJlYWRBcm1vcmVkID0gcmVhZEFybW9yZWQ7XG4iLCJKWEcgPSB7XG4gIGV4aXN0czogKGZ1bmN0aW9uKHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBmdW5jdGlvbih2KSB7XG4gICAgICByZXR1cm4gISh2ID09PSB1bmRlZmluZWQgfHwgdiA9PT0gbnVsbCk7XG4gICAgfVxuICB9KSgpXG59O1xuSlhHLmRlY29tcHJlc3MgPSBmdW5jdGlvbihzdHIpIHtcbiAgcmV0dXJuIHVuZXNjYXBlKChuZXcgSlhHLlV0aWwuVW56aXAoSlhHLlV0aWwuQmFzZTY0LmRlY29kZUFzQXJyYXkoc3RyKSkpLnVuemlwKClbMF1bMF0pO1xufTtcbi8qXG4gICAgQ29weXJpZ2h0IDIwMDgtMjAxMlxuICAgICAgICBNYXR0aGlhcyBFaG1hbm4sXG4gICAgICAgIE1pY2hhZWwgR2VyaGFldXNlcixcbiAgICAgICAgQ2Fyc3RlbiBNaWxsZXIsXG4gICAgICAgIEJpYW5jYSBWYWxlbnRpbixcbiAgICAgICAgQWxmcmVkIFdhc3Nlcm1hbm4sXG4gICAgICAgIFBldGVyIFdpbGZhaHJ0XG5cbiAgICBUaGlzIGZpbGUgaXMgcGFydCBvZiBKU1hHcmFwaC5cbiAgICBcbiAgICBEdWFsIGxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCwgb3IgTEdQTCBWZXJzaW9uIDMgbGljZW5zZXMuXG5cbiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAgICBhbG9uZyB3aXRoIEpTWENvbXByZXNzb3IuICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gICAgXG4gICAgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgQXBhY2hlIExpY2Vuc2UgYWxvbmcgd2l0aCBKU1hDb21wcmVzc29yLiAgXG4gICAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy8+LlxuXG4qL1xuXG4vKipcbiAqIEBjbGFzcyBVdGlsIGNsYXNzXG4gKiBAY2xhc3NkZXNjIFV0aWxpdGllcyBmb3IgdW5jb21wcmVzc2luZyBhbmQgYmFzZTY0IGRlY29kaW5nXG4gKiBDbGFzcyBmb3IgZ3VuemlwcGluZywgdW56aXBwaW5nIGFuZCBiYXNlNjQgZGVjb2Rpbmcgb2YgZmlsZXMuXG4gKiBJdCBpcyB1c2VkIGZvciByZWFkaW5nIEdFT05FeFQsIEdlb2dlYnJhIGFuZCBJbnRlcmdlbyBmaWxlcy5cbiAqXG4gKiBPbmx5IEh1ZmZtYW4gY29kZXMgYXJlIGRlY29kZWQgaW4gZ3VuemlwLlxuICogVGhlIGNvZGUgaXMgYmFzZWQgb24gdGhlIHNvdXJjZSBjb2RlIGZvciBndW56aXAuYyBieSBQYXNpIE9qYWxhIFxuICoge0BsaW5rIGh0dHA6Ly93d3cuY3MudHV0LmZpL35hbGJlcnQvRGV2L2d1bnppcC9ndW56aXAuY31cbiAqIHtAbGluayBodHRwOi8vd3d3LmNzLnR1dC5maS9+YWxiZXJ0fVxuICovXG5KWEcuVXRpbCA9IHt9O1xuXG4vKipcbiAqIFVuemlwIHppcCBmaWxlc1xuICovXG5KWEcuVXRpbC5VbnppcCA9IGZ1bmN0aW9uKGJhcnJheSkge1xuICB2YXIgb3V0cHV0QXJyID0gW10sXG4gICAgb3V0cHV0ID0gXCJcIixcbiAgICBkZWJ1ZyA9IGZhbHNlLFxuICAgIGdwZmxhZ3MsXG4gICAgZmlsZXMgPSAwLFxuICAgIHVuemlwcGVkID0gW10sXG4gICAgY3JjLFxuICAgIGJ1ZjMyayA9IG5ldyBBcnJheSgzMjc2OCksXG4gICAgYklkeCA9IDAsXG4gICAgbW9kZVpJUCA9IGZhbHNlLFxuXG4gICAgQ1JDLCBTSVpFLFxuXG4gICAgYml0UmV2ZXJzZSA9IFtcbiAgICAgICAgMHgwMCwgMHg4MCwgMHg0MCwgMHhjMCwgMHgyMCwgMHhhMCwgMHg2MCwgMHhlMCxcbiAgICAgICAgMHgxMCwgMHg5MCwgMHg1MCwgMHhkMCwgMHgzMCwgMHhiMCwgMHg3MCwgMHhmMCxcbiAgICAgICAgMHgwOCwgMHg4OCwgMHg0OCwgMHhjOCwgMHgyOCwgMHhhOCwgMHg2OCwgMHhlOCxcbiAgICAgICAgMHgxOCwgMHg5OCwgMHg1OCwgMHhkOCwgMHgzOCwgMHhiOCwgMHg3OCwgMHhmOCxcbiAgICAgICAgMHgwNCwgMHg4NCwgMHg0NCwgMHhjNCwgMHgyNCwgMHhhNCwgMHg2NCwgMHhlNCxcbiAgICAgICAgMHgxNCwgMHg5NCwgMHg1NCwgMHhkNCwgMHgzNCwgMHhiNCwgMHg3NCwgMHhmNCxcbiAgICAgICAgMHgwYywgMHg4YywgMHg0YywgMHhjYywgMHgyYywgMHhhYywgMHg2YywgMHhlYyxcbiAgICAgICAgMHgxYywgMHg5YywgMHg1YywgMHhkYywgMHgzYywgMHhiYywgMHg3YywgMHhmYyxcbiAgICAgICAgMHgwMiwgMHg4MiwgMHg0MiwgMHhjMiwgMHgyMiwgMHhhMiwgMHg2MiwgMHhlMixcbiAgICAgICAgMHgxMiwgMHg5MiwgMHg1MiwgMHhkMiwgMHgzMiwgMHhiMiwgMHg3MiwgMHhmMixcbiAgICAgICAgMHgwYSwgMHg4YSwgMHg0YSwgMHhjYSwgMHgyYSwgMHhhYSwgMHg2YSwgMHhlYSxcbiAgICAgICAgMHgxYSwgMHg5YSwgMHg1YSwgMHhkYSwgMHgzYSwgMHhiYSwgMHg3YSwgMHhmYSxcbiAgICAgICAgMHgwNiwgMHg4NiwgMHg0NiwgMHhjNiwgMHgyNiwgMHhhNiwgMHg2NiwgMHhlNixcbiAgICAgICAgMHgxNiwgMHg5NiwgMHg1NiwgMHhkNiwgMHgzNiwgMHhiNiwgMHg3NiwgMHhmNixcbiAgICAgICAgMHgwZSwgMHg4ZSwgMHg0ZSwgMHhjZSwgMHgyZSwgMHhhZSwgMHg2ZSwgMHhlZSxcbiAgICAgICAgMHgxZSwgMHg5ZSwgMHg1ZSwgMHhkZSwgMHgzZSwgMHhiZSwgMHg3ZSwgMHhmZSxcbiAgICAgICAgMHgwMSwgMHg4MSwgMHg0MSwgMHhjMSwgMHgyMSwgMHhhMSwgMHg2MSwgMHhlMSxcbiAgICAgICAgMHgxMSwgMHg5MSwgMHg1MSwgMHhkMSwgMHgzMSwgMHhiMSwgMHg3MSwgMHhmMSxcbiAgICAgICAgMHgwOSwgMHg4OSwgMHg0OSwgMHhjOSwgMHgyOSwgMHhhOSwgMHg2OSwgMHhlOSxcbiAgICAgICAgMHgxOSwgMHg5OSwgMHg1OSwgMHhkOSwgMHgzOSwgMHhiOSwgMHg3OSwgMHhmOSxcbiAgICAgICAgMHgwNSwgMHg4NSwgMHg0NSwgMHhjNSwgMHgyNSwgMHhhNSwgMHg2NSwgMHhlNSxcbiAgICAgICAgMHgxNSwgMHg5NSwgMHg1NSwgMHhkNSwgMHgzNSwgMHhiNSwgMHg3NSwgMHhmNSxcbiAgICAgICAgMHgwZCwgMHg4ZCwgMHg0ZCwgMHhjZCwgMHgyZCwgMHhhZCwgMHg2ZCwgMHhlZCxcbiAgICAgICAgMHgxZCwgMHg5ZCwgMHg1ZCwgMHhkZCwgMHgzZCwgMHhiZCwgMHg3ZCwgMHhmZCxcbiAgICAgICAgMHgwMywgMHg4MywgMHg0MywgMHhjMywgMHgyMywgMHhhMywgMHg2MywgMHhlMyxcbiAgICAgICAgMHgxMywgMHg5MywgMHg1MywgMHhkMywgMHgzMywgMHhiMywgMHg3MywgMHhmMyxcbiAgICAgICAgMHgwYiwgMHg4YiwgMHg0YiwgMHhjYiwgMHgyYiwgMHhhYiwgMHg2YiwgMHhlYixcbiAgICAgICAgMHgxYiwgMHg5YiwgMHg1YiwgMHhkYiwgMHgzYiwgMHhiYiwgMHg3YiwgMHhmYixcbiAgICAgICAgMHgwNywgMHg4NywgMHg0NywgMHhjNywgMHgyNywgMHhhNywgMHg2NywgMHhlNyxcbiAgICAgICAgMHgxNywgMHg5NywgMHg1NywgMHhkNywgMHgzNywgMHhiNywgMHg3NywgMHhmNyxcbiAgICAgICAgMHgwZiwgMHg4ZiwgMHg0ZiwgMHhjZiwgMHgyZiwgMHhhZiwgMHg2ZiwgMHhlZixcbiAgICAgICAgMHgxZiwgMHg5ZiwgMHg1ZiwgMHhkZiwgMHgzZiwgMHhiZiwgMHg3ZiwgMHhmZlxuICAgIF0sXG5cbiAgICBjcGxlbnMgPSBbXG4gICAgICAgIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTMsIDE1LCAxNywgMTksIDIzLCAyNywgMzEsXG4gICAgICAgIDM1LCA0MywgNTEsIDU5LCA2NywgODMsIDk5LCAxMTUsIDEzMSwgMTYzLCAxOTUsIDIyNywgMjU4LCAwLCAwXG4gICAgXSxcblxuICAgIGNwbGV4dCA9IFtcbiAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMiwgMiwgMiwgMixcbiAgICAgICAgMywgMywgMywgMywgNCwgNCwgNCwgNCwgNSwgNSwgNSwgNSwgMCwgOTksIDk5XG4gICAgXSxcbiAgICAvKiA5OT09aW52YWxpZCAqL1xuXG4gICAgY3BkaXN0ID0gW1xuICAgICAgICAweDAwMDEsIDB4MDAwMiwgMHgwMDAzLCAweDAwMDQsIDB4MDAwNSwgMHgwMDA3LCAweDAwMDksIDB4MDAwZCxcbiAgICAgICAgMHgwMDExLCAweDAwMTksIDB4MDAyMSwgMHgwMDMxLCAweDAwNDEsIDB4MDA2MSwgMHgwMDgxLCAweDAwYzEsXG4gICAgICAgIDB4MDEwMSwgMHgwMTgxLCAweDAyMDEsIDB4MDMwMSwgMHgwNDAxLCAweDA2MDEsIDB4MDgwMSwgMHgwYzAxLFxuICAgICAgICAweDEwMDEsIDB4MTgwMSwgMHgyMDAxLCAweDMwMDEsIDB4NDAwMSwgMHg2MDAxXG4gICAgXSxcblxuICAgIGNwZGV4dCA9IFtcbiAgICAgICAgMCwgMCwgMCwgMCwgMSwgMSwgMiwgMixcbiAgICAgICAgMywgMywgNCwgNCwgNSwgNSwgNiwgNixcbiAgICAgICAgNywgNywgOCwgOCwgOSwgOSwgMTAsIDEwLFxuICAgICAgICAxMSwgMTEsIDEyLCAxMiwgMTMsIDEzXG4gICAgXSxcblxuICAgIGJvcmRlciA9IFsxNiwgMTcsIDE4LCAwLCA4LCA3LCA5LCA2LCAxMCwgNSwgMTEsIDQsIDEyLCAzLCAxMywgMiwgMTQsIDEsIDE1XSxcblxuICAgIGJBID0gYmFycmF5LFxuXG4gICAgYnl0ZXBvcyA9IDAsXG4gICAgYml0cG9zID0gMCxcbiAgICBiYiA9IDEsXG4gICAgYml0cyA9IDAsXG5cbiAgICBOQU1FTUFYID0gMjU2LFxuXG4gICAgbmFtZUJ1ZiA9IFtdLFxuXG4gICAgZmlsZW91dDtcblxuICBmdW5jdGlvbiByZWFkQnl0ZSgpIHtcbiAgICBiaXRzICs9IDg7XG4gICAgaWYgKGJ5dGVwb3MgPCBiQS5sZW5ndGgpIHtcbiAgICAgIC8vaWYgKGRlYnVnKVxuICAgICAgLy8gICAgZG9jdW1lbnQud3JpdGUoYnl0ZXBvcytcIjogXCIrYkFbYnl0ZXBvc10rXCI8YnI+XCIpO1xuICAgICAgcmV0dXJuIGJBW2J5dGVwb3MrK107XG4gICAgfSBlbHNlXG4gICAgICByZXR1cm4gLTE7XG4gIH07XG5cbiAgZnVuY3Rpb24gYnl0ZUFsaWduKCkge1xuICAgIGJiID0gMTtcbiAgfTtcblxuICBmdW5jdGlvbiByZWFkQml0KCkge1xuICAgIHZhciBjYXJyeTtcbiAgICBiaXRzKys7XG4gICAgY2FycnkgPSAoYmIgJiAxKTtcbiAgICBiYiA+Pj0gMTtcbiAgICBpZiAoYmIgPT0gMCkge1xuICAgICAgYmIgPSByZWFkQnl0ZSgpO1xuICAgICAgY2FycnkgPSAoYmIgJiAxKTtcbiAgICAgIGJiID0gKGJiID4+IDEpIHwgMHg4MDtcbiAgICB9XG4gICAgcmV0dXJuIGNhcnJ5O1xuICB9O1xuXG4gIGZ1bmN0aW9uIHJlYWRCaXRzKGEpIHtcbiAgICB2YXIgcmVzID0gMCxcbiAgICAgIGkgPSBhO1xuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgcmVzID0gKHJlcyA8PCAxKSB8IHJlYWRCaXQoKTtcbiAgICB9XG4gICAgaWYgKGEpIHtcbiAgICAgIHJlcyA9IGJpdFJldmVyc2VbcmVzXSA+PiAoOCAtIGEpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIGZ1bmN0aW9uIGZsdXNoQnVmZmVyKCkge1xuICAgIC8vZG9jdW1lbnQud3JpdGUoJ0ZMVVNIQlVGRkVSOicrYnVmMzJrKTtcbiAgICBiSWR4ID0gMDtcbiAgfTtcblxuICBmdW5jdGlvbiBhZGRCdWZmZXIoYSkge1xuICAgIFNJWkUrKztcbiAgICAvL0NSQz11cGRjcmMoYSxjcmMpO1xuICAgIGJ1ZjMya1tiSWR4KytdID0gYTtcbiAgICBvdXRwdXRBcnIucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGEpKTtcbiAgICAvL291dHB1dCs9U3RyaW5nLmZyb21DaGFyQ29kZShhKTtcbiAgICBpZiAoYklkeCA9PSAweDgwMDApIHtcbiAgICAgIC8vZG9jdW1lbnQud3JpdGUoJ0FEREJVRkZFUjonK2J1ZjMyayk7XG4gICAgICBiSWR4ID0gMDtcbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gSHVmTm9kZSgpIHtcbiAgICB0aGlzLmIwID0gMDtcbiAgICB0aGlzLmIxID0gMDtcbiAgICB0aGlzLmp1bXAgPSBudWxsO1xuICAgIHRoaXMuanVtcHBvcyA9IC0xO1xuICB9O1xuXG4gIHZhciBMSVRFUkFMUyA9IDI4ODtcblxuICB2YXIgbGl0ZXJhbFRyZWUgPSBuZXcgQXJyYXkoTElURVJBTFMpO1xuICB2YXIgZGlzdGFuY2VUcmVlID0gbmV3IEFycmF5KDMyKTtcbiAgdmFyIHRyZWVwb3MgPSAwO1xuICB2YXIgUGxhY2VzID0gbnVsbDtcbiAgdmFyIFBsYWNlczIgPSBudWxsO1xuXG4gIHZhciBpbXBEaXN0YW5jZVRyZWUgPSBuZXcgQXJyYXkoNjQpO1xuICB2YXIgaW1wTGVuZ3RoVHJlZSA9IG5ldyBBcnJheSg2NCk7XG5cbiAgdmFyIGxlbiA9IDA7XG4gIHZhciBmcG9zID0gbmV3IEFycmF5KDE3KTtcbiAgZnBvc1swXSA9IDA7XG4gIHZhciBmbGVucztcbiAgdmFyIGZtYXg7XG5cbiAgZnVuY3Rpb24gSXNQYXQoKSB7XG4gICAgd2hpbGUgKDEpIHtcbiAgICAgIGlmIChmcG9zW2xlbl0gPj0gZm1heClcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgaWYgKGZsZW5zW2Zwb3NbbGVuXV0gPT0gbGVuKVxuICAgICAgICByZXR1cm4gZnBvc1tsZW5dKys7XG4gICAgICBmcG9zW2xlbl0rKztcbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gUmVjKCkge1xuICAgIHZhciBjdXJwbGFjZSA9IFBsYWNlc1t0cmVlcG9zXTtcbiAgICB2YXIgdG1wO1xuICAgIGlmIChkZWJ1ZylcbiAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPmxlbjpcIiArIGxlbiArIFwiIHRyZWVwb3M6XCIgKyB0cmVlcG9zKTtcbiAgICBpZiAobGVuID09IDE3KSB7IC8vd2FyIDE3XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIHRyZWVwb3MrKztcbiAgICBsZW4rKztcblxuICAgIHRtcCA9IElzUGF0KCk7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+SXNQYXQgXCIgKyB0bXApO1xuICAgIGlmICh0bXAgPj0gMCkge1xuICAgICAgY3VycGxhY2UuYjAgPSB0bXA7IC8qIGxlYWYgY2VsbCBmb3IgMC1iaXQgKi9cbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+YjAgXCIgKyBjdXJwbGFjZS5iMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIE5vdCBhIExlYWYgY2VsbCAqL1xuICAgICAgY3VycGxhY2UuYjAgPSAweDgwMDA7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPmIwIFwiICsgY3VycGxhY2UuYjApO1xuICAgICAgaWYgKFJlYygpKVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIHRtcCA9IElzUGF0KCk7XG4gICAgaWYgKHRtcCA+PSAwKSB7XG4gICAgICBjdXJwbGFjZS5iMSA9IHRtcDsgLyogbGVhZiBjZWxsIGZvciAxLWJpdCAqL1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5iMSBcIiArIGN1cnBsYWNlLmIxKTtcbiAgICAgIGN1cnBsYWNlLmp1bXAgPSBudWxsOyAvKiBKdXN0IGZvciB0aGUgZGlzcGxheSByb3V0aW5lICovXG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIE5vdCBhIExlYWYgY2VsbCAqL1xuICAgICAgY3VycGxhY2UuYjEgPSAweDgwMDA7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPmIxIFwiICsgY3VycGxhY2UuYjEpO1xuICAgICAgY3VycGxhY2UuanVtcCA9IFBsYWNlc1t0cmVlcG9zXTtcbiAgICAgIGN1cnBsYWNlLmp1bXBwb3MgPSB0cmVlcG9zO1xuICAgICAgaWYgKFJlYygpKVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIGxlbi0tO1xuICAgIHJldHVybiAwO1xuICB9O1xuXG4gIGZ1bmN0aW9uIENyZWF0ZVRyZWUoY3VycmVudFRyZWUsIG51bXZhbCwgbGVuZ3Rocywgc2hvdykge1xuICAgIHZhciBpO1xuICAgIC8qIENyZWF0ZSB0aGUgSHVmZm1hbiBkZWNvZGUgdHJlZS90YWJsZSAqL1xuICAgIC8vZG9jdW1lbnQud3JpdGUoXCI8YnI+Y3JlYXRldHJlZTxicj5cIik7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgZG9jdW1lbnQud3JpdGUoXCJjdXJyZW50VHJlZSBcIiArIGN1cnJlbnRUcmVlICsgXCIgbnVtdmFsIFwiICsgbnVtdmFsICsgXCIgbGVuZ3RocyBcIiArIGxlbmd0aHMgKyBcIiBzaG93IFwiICsgc2hvdyk7XG4gICAgUGxhY2VzID0gY3VycmVudFRyZWU7XG4gICAgdHJlZXBvcyA9IDA7XG4gICAgZmxlbnMgPSBsZW5ndGhzO1xuICAgIGZtYXggPSBudW12YWw7XG4gICAgZm9yIChpID0gMDsgaSA8IDE3OyBpKyspXG4gICAgICBmcG9zW2ldID0gMDtcbiAgICBsZW4gPSAwO1xuICAgIGlmIChSZWMoKSkge1xuICAgICAgLy9mcHJpbnRmKHN0ZGVyciwgXCJpbnZhbGlkIGh1ZmZtYW4gdHJlZVxcblwiKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJpbnZhbGlkIGh1ZmZtYW4gdHJlZVxcblwiKTtcbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgaWYgKGRlYnVnKSB7XG4gICAgICBkb2N1bWVudC53cml0ZSgnPGJyPlRyZWU6ICcgKyBQbGFjZXMubGVuZ3RoKTtcbiAgICAgIGZvciAodmFyIGEgPSAwOyBhIDwgMzI7IGErKykge1xuICAgICAgICBkb2N1bWVudC53cml0ZShcIlBsYWNlc1tcIiArIGEgKyBcIl0uYjA9XCIgKyBQbGFjZXNbYV0uYjAgKyBcIjxicj5cIik7XG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiUGxhY2VzW1wiICsgYSArIFwiXS5iMT1cIiArIFBsYWNlc1thXS5iMSArIFwiPGJyPlwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKmlmKHNob3cpIHtcbiAgICAgICAgICAgIHZhciB0bXA7XG4gICAgICAgICAgICBmb3IodG1wPWN1cnJlbnRUcmVlO3RtcDxQbGFjZXM7dG1wKyspIHtcbiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgXCIweCUwM3ggIDB4JTAzeCAoMHglMDR4KVwiLHRtcC1jdXJyZW50VHJlZSwgdG1wLT5qdW1wP3RtcC0+anVtcC1jdXJyZW50VHJlZTowLCh0bXAtPmp1bXA/dG1wLT5qdW1wLWN1cnJlbnRUcmVlOjApKjYrMHhjZjApO1xuICAgICAgICAgICAgICAgIGlmKCEodG1wLmIwICYgMHg4MDAwKSkge1xuICAgICAgICAgICAgICAgICAgICAvL2ZwcmludGYoc3Rkb3V0LCBcIiAgMHglMDN4ICglYylcIiwgdG1wLT5iMCwodG1wLT5iMDwyNTYgJiYgaXNwcmludCh0bXAtPmIwKSk/dG1wLT5iMDon77+9Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmKCEodG1wLmIxICYgMHg4MDAwKSkge1xuICAgICAgICAgICAgICAgICAgICBpZigodG1wLmIwICYgMHg4MDAwKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCBcIiAgICAgICAgICAgXCIpO1xuICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgXCIgIDB4JTAzeCAoJWMpXCIsIHRtcC0+YjEsKHRtcC0+YjE8MjU2ICYmIGlzcHJpbnQodG1wLT5iMSkpP3RtcC0+YjE6J++/vScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgXCJcXG5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0qL1xuICAgIHJldHVybiAwO1xuICB9O1xuXG4gIGZ1bmN0aW9uIERlY29kZVZhbHVlKGN1cnJlbnRUcmVlKSB7XG4gICAgdmFyIGxlbiwgaSxcbiAgICAgIHh0cmVlcG9zID0gMCxcbiAgICAgIFggPSBjdXJyZW50VHJlZVt4dHJlZXBvc10sXG4gICAgICBiO1xuXG4gICAgLyogZGVjb2RlIG9uZSBzeW1ib2wgb2YgdGhlIGRhdGEgKi9cbiAgICB3aGlsZSAoMSkge1xuICAgICAgYiA9IHJlYWRCaXQoKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCJiPVwiICsgYik7XG4gICAgICBpZiAoYikge1xuICAgICAgICBpZiAoIShYLmIxICYgMHg4MDAwKSkge1xuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwicmV0MVwiKTtcbiAgICAgICAgICByZXR1cm4gWC5iMTsgLyogSWYgbGVhZiBub2RlLCByZXR1cm4gZGF0YSAqL1xuICAgICAgICB9XG4gICAgICAgIFggPSBYLmp1bXA7XG4gICAgICAgIGxlbiA9IGN1cnJlbnRUcmVlLmxlbmd0aDtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnRUcmVlW2ldID09PSBYKSB7XG4gICAgICAgICAgICB4dHJlZXBvcyA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy94dHJlZXBvcysrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCEoWC5iMCAmIDB4ODAwMCkpIHtcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBkb2N1bWVudC53cml0ZShcInJldDJcIik7XG4gICAgICAgICAgcmV0dXJuIFguYjA7IC8qIElmIGxlYWYgbm9kZSwgcmV0dXJuIGRhdGEgKi9cbiAgICAgICAgfVxuICAgICAgICAvL1grKzsgLy8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz9cbiAgICAgICAgeHRyZWVwb3MrKztcbiAgICAgICAgWCA9IGN1cnJlbnRUcmVlW3h0cmVlcG9zXTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gRGVmbGF0ZUxvb3AoKSB7XG4gICAgdmFyIGxhc3QsIGMsIHR5cGUsIGksIGxlbjtcblxuICAgIGRvIHtcbiAgICAgIC8qaWYoKGxhc3QgPSByZWFkQml0KCkpKXtcbiAgICAgICAgICAgIGZwcmludGYoZXJyZnAsIFwiTGFzdCBCbG9jazogXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZnByaW50ZihlcnJmcCwgXCJOb3QgTGFzdCBCbG9jazogXCIpO1xuICAgICAgICB9Ki9cbiAgICAgIGxhc3QgPSByZWFkQml0KCk7XG4gICAgICB0eXBlID0gcmVhZEJpdHMoMik7XG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGFsZXJ0KFwiU3RvcmVkXFxuXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQoXCJGaXhlZCBIdWZmbWFuIGNvZGVzXFxuXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQoXCJEeW5hbWljIEh1ZmZtYW4gY29kZXNcXG5cIik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBhbGVydChcIlJlc2VydmVkIGJsb2NrIHR5cGUhIVxcblwiKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBhbGVydChcIlVuZXhwZWN0ZWQgdmFsdWUgJWQhXFxuXCIsIHR5cGUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZSA9PSAwKSB7XG4gICAgICAgIHZhciBibG9ja0xlbiwgY1N1bTtcblxuICAgICAgICAvLyBTdG9yZWQgXG4gICAgICAgIGJ5dGVBbGlnbigpO1xuICAgICAgICBibG9ja0xlbiA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGJsb2NrTGVuIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuXG4gICAgICAgIGNTdW0gPSByZWFkQnl0ZSgpO1xuICAgICAgICBjU3VtIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuXG4gICAgICAgIGlmICgoKGJsb2NrTGVuIF4gfmNTdW0pICYgMHhmZmZmKSkge1xuICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwiQmxvY2tMZW4gY2hlY2tzdW0gbWlzbWF0Y2hcXG5cIik7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGJsb2NrTGVuLS0pIHtcbiAgICAgICAgICBjID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgICBhZGRCdWZmZXIoYyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSAxKSB7XG4gICAgICAgIHZhciBqO1xuXG4gICAgICAgIC8qIEZpeGVkIEh1ZmZtYW4gdGFibGVzIC0tIGZpeGVkIGRlY29kZSByb3V0aW5lICovXG4gICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAyNTYgICAgMDAwMDAwMCAgICAgICAgMFxuICAgICAgICAgICAgICAgIDogICA6ICAgICA6XG4gICAgICAgICAgICAgICAgMjc5ICAgIDAwMTAxMTEgICAgICAgIDIzXG4gICAgICAgICAgICAgICAgMCAgIDAwMTEwMDAwICAgIDQ4XG4gICAgICAgICAgICAgICAgOiAgICA6ICAgICAgOlxuICAgICAgICAgICAgICAgIDE0MyAgICAxMDExMTExMSAgICAxOTFcbiAgICAgICAgICAgICAgICAyODAgMTEwMDAwMDAgICAgMTkyXG4gICAgICAgICAgICAgICAgOiAgICA6ICAgICAgOlxuICAgICAgICAgICAgICAgIDI4NyAxMTAwMDExMSAgICAxOTlcbiAgICAgICAgICAgICAgICAxNDQgICAgMTEwMDEwMDAwICAgIDQwMFxuICAgICAgICAgICAgICAgIDogICAgOiAgICAgICA6XG4gICAgICAgICAgICAgICAgMjU1ICAgIDExMTExMTExMSAgICA1MTFcbiAgICBcbiAgICAgICAgICAgICAgICBOb3RlIHRoZSBiaXQgb3JkZXIhXG4gICAgICAgICAgICAgICAgKi9cblxuICAgICAgICAgIGogPSAoYml0UmV2ZXJzZVtyZWFkQml0cyg3KV0gPj4gMSk7XG4gICAgICAgICAgaWYgKGogPiAyMykge1xuICAgICAgICAgICAgaiA9IChqIDw8IDEpIHwgcmVhZEJpdCgpOyAvKiA0OC4uMjU1ICovXG5cbiAgICAgICAgICAgIGlmIChqID4gMTk5KSB7IC8qIDIwMC4uMjU1ICovXG4gICAgICAgICAgICAgIGogLT0gMTI4OyAvKiAgNzIuLjEyNyAqL1xuICAgICAgICAgICAgICBqID0gKGogPDwgMSkgfCByZWFkQml0KCk7IC8qIDE0NC4uMjU1IDw8ICovXG4gICAgICAgICAgICB9IGVsc2UgeyAvKiAgNDguLjE5OSAqL1xuICAgICAgICAgICAgICBqIC09IDQ4OyAvKiAgIDAuLjE1MSAqL1xuICAgICAgICAgICAgICBpZiAoaiA+IDE0Mykge1xuICAgICAgICAgICAgICAgIGogPSBqICsgMTM2OyAvKiAyODAuLjI4NyA8PCAqL1xuICAgICAgICAgICAgICAgIC8qICAgMC4uMTQzIDw8ICovXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgeyAvKiAgIDAuLjIzICovXG4gICAgICAgICAgICBqICs9IDI1NjsgLyogMjU2Li4yNzkgPDwgKi9cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGogPCAyNTYpIHtcbiAgICAgICAgICAgIGFkZEJ1ZmZlcihqKTtcbiAgICAgICAgICAgIC8vZG9jdW1lbnQud3JpdGUoXCJvdXQ6XCIrU3RyaW5nLmZyb21DaGFyQ29kZShqKSk7XG4gICAgICAgICAgICAvKmZwcmludGYoZXJyZnAsIFwiQCVkICUwMnhcXG5cIiwgU0laRSwgaik7Ki9cbiAgICAgICAgICB9IGVsc2UgaWYgKGogPT0gMjU2KSB7XG4gICAgICAgICAgICAvKiBFT0YgKi9cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgbGVuLCBkaXN0O1xuXG4gICAgICAgICAgICBqIC09IDI1NiArIDE7IC8qIGJ5dGVzICsgRU9GICovXG4gICAgICAgICAgICBsZW4gPSByZWFkQml0cyhjcGxleHRbal0pICsgY3BsZW5zW2pdO1xuXG4gICAgICAgICAgICBqID0gYml0UmV2ZXJzZVtyZWFkQml0cyg1KV0gPj4gMztcbiAgICAgICAgICAgIGlmIChjcGRleHRbal0gPiA4KSB7XG4gICAgICAgICAgICAgIGRpc3QgPSByZWFkQml0cyg4KTtcbiAgICAgICAgICAgICAgZGlzdCB8PSAocmVhZEJpdHMoY3BkZXh0W2pdIC0gOCkgPDwgOCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBkaXN0ID0gcmVhZEJpdHMoY3BkZXh0W2pdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRpc3QgKz0gY3BkaXN0W2pdO1xuXG4gICAgICAgICAgICAvKmZwcmludGYoZXJyZnAsIFwiQCVkIChsJTAyeCxkJTA0eClcXG5cIiwgU0laRSwgbGVuLCBkaXN0KTsqL1xuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgICAgIHZhciBjID0gYnVmMzJrWyhiSWR4IC0gZGlzdCkgJiAweDdmZmZdO1xuICAgICAgICAgICAgICBhZGRCdWZmZXIoYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIHdoaWxlXG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gMikge1xuICAgICAgICB2YXIgaiwgbiwgbGl0ZXJhbENvZGVzLCBkaXN0Q29kZXMsIGxlbkNvZGVzO1xuICAgICAgICB2YXIgbGwgPSBuZXcgQXJyYXkoMjg4ICsgMzIpOyAvLyBcInN0YXRpY1wiIGp1c3QgdG8gcHJlc2VydmUgc3RhY2tcblxuICAgICAgICAvLyBEeW5hbWljIEh1ZmZtYW4gdGFibGVzIFxuXG4gICAgICAgIGxpdGVyYWxDb2RlcyA9IDI1NyArIHJlYWRCaXRzKDUpO1xuICAgICAgICBkaXN0Q29kZXMgPSAxICsgcmVhZEJpdHMoNSk7XG4gICAgICAgIGxlbkNvZGVzID0gNCArIHJlYWRCaXRzKDQpO1xuICAgICAgICAvL2RvY3VtZW50LndyaXRlKFwiPGJyPnBhcmFtOiBcIitsaXRlcmFsQ29kZXMrXCIgXCIrZGlzdENvZGVzK1wiIFwiK2xlbkNvZGVzK1wiPGJyPlwiKTtcbiAgICAgICAgZm9yIChqID0gMDsgaiA8IDE5OyBqKyspIHtcbiAgICAgICAgICBsbFtqXSA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIGRlY29kZSB0cmVlIGNvZGUgbGVuZ3Roc1xuXG4gICAgICAgIC8vZG9jdW1lbnQud3JpdGUoXCI8YnI+XCIpO1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgbGVuQ29kZXM7IGorKykge1xuICAgICAgICAgIGxsW2JvcmRlcltqXV0gPSByZWFkQml0cygzKTtcbiAgICAgICAgICAvL2RvY3VtZW50LndyaXRlKGxsW2JvcmRlcltqXV0rXCIgXCIpO1xuICAgICAgICB9XG4gICAgICAgIC8vZnByaW50ZihlcnJmcCwgXCJcXG5cIik7XG4gICAgICAgIC8vZG9jdW1lbnQud3JpdGUoJzxicj5sbDonK2xsKTtcbiAgICAgICAgbGVuID0gZGlzdGFuY2VUcmVlLmxlbmd0aDtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgIGRpc3RhbmNlVHJlZVtpXSA9IG5ldyBIdWZOb2RlKCk7XG4gICAgICAgIGlmIChDcmVhdGVUcmVlKGRpc3RhbmNlVHJlZSwgMTksIGxsLCAwKSkge1xuICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlYnVnKSB7XG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+ZGlzdGFuY2VUcmVlXCIpO1xuICAgICAgICAgIGZvciAodmFyIGEgPSAwOyBhIDwgZGlzdGFuY2VUcmVlLmxlbmd0aDsgYSsrKSB7XG4gICAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5cIiArIGRpc3RhbmNlVHJlZVthXS5iMCArIFwiIFwiICsgZGlzdGFuY2VUcmVlW2FdLmIxICsgXCIgXCIgKyBkaXN0YW5jZVRyZWVbYV0uanVtcCArIFwiIFwiICtcbiAgICAgICAgICAgICAgZGlzdGFuY2VUcmVlW2FdLmp1bXBwb3MpO1xuICAgICAgICAgICAgLyppZiAoZGlzdGFuY2VUcmVlW2FdLmp1bXBwb3MhPS0xKVxuICAgICAgICAgICAgICAgICAgICBcdGRvY3VtZW50LndyaXRlKFwiIFwiK2Rpc3RhbmNlVHJlZVthXS5qdW1wLmIwK1wiIFwiK2Rpc3RhbmNlVHJlZVthXS5qdW1wLmIxKTtcbiAgICAgICAgICAgICAgICBcdCovXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vZG9jdW1lbnQud3JpdGUoJzxCUj50cmVlIGNyZWF0ZWQnKTtcblxuICAgICAgICAvL3JlYWQgaW4gbGl0ZXJhbCBhbmQgZGlzdGFuY2UgY29kZSBsZW5ndGhzXG4gICAgICAgIG4gPSBsaXRlcmFsQ29kZXMgKyBkaXN0Q29kZXM7XG4gICAgICAgIGkgPSAwO1xuICAgICAgICB2YXIgeiA9IC0xO1xuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+bj1cIiArIG4gKyBcIiBiaXRzOiBcIiArIGJpdHMgKyBcIjxicj5cIik7XG4gICAgICAgIHdoaWxlIChpIDwgbikge1xuICAgICAgICAgIHorKztcbiAgICAgICAgICBqID0gRGVjb2RlVmFsdWUoZGlzdGFuY2VUcmVlKTtcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5cIiArIHogKyBcIiBpOlwiICsgaSArIFwiIGRlY29kZTogXCIgKyBqICsgXCIgICAgYml0cyBcIiArIGJpdHMgKyBcIjxicj5cIik7XG4gICAgICAgICAgaWYgKGogPCAxNikgeyAvLyBsZW5ndGggb2YgY29kZSBpbiBiaXRzICgwLi4xNSlcbiAgICAgICAgICAgIGxsW2krK10gPSBqO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaiA9PSAxNikgeyAvLyByZXBlYXQgbGFzdCBsZW5ndGggMyB0byA2IHRpbWVzIFxuICAgICAgICAgICAgdmFyIGw7XG4gICAgICAgICAgICBqID0gMyArIHJlYWRCaXRzKDIpO1xuICAgICAgICAgICAgaWYgKGkgKyBqID4gbikge1xuICAgICAgICAgICAgICBmbHVzaEJ1ZmZlcigpO1xuICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGwgPSBpID8gbGxbaSAtIDFdIDogMDtcbiAgICAgICAgICAgIHdoaWxlIChqLS0pIHtcbiAgICAgICAgICAgICAgbGxbaSsrXSA9IGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChqID09IDE3KSB7IC8vIDMgdG8gMTAgemVybyBsZW5ndGggY29kZXNcbiAgICAgICAgICAgICAgaiA9IDMgKyByZWFkQml0cygzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGogPT0gMTg6IDExIHRvIDEzOCB6ZXJvIGxlbmd0aCBjb2RlcyBcbiAgICAgICAgICAgICAgaiA9IDExICsgcmVhZEJpdHMoNyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaSArIGogPiBuKSB7XG4gICAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgd2hpbGUgKGotLSkge1xuICAgICAgICAgICAgICBsbFtpKytdID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLypmb3Ioaj0wOyBqPGxpdGVyYWxDb2RlcytkaXN0Q29kZXM7IGorKykge1xuICAgICAgICAgICAgICAgIC8vZnByaW50ZihlcnJmcCwgXCIlZCBcIiwgbGxbal0pO1xuICAgICAgICAgICAgICAgIGlmICgoaiY3KT09NylcbiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihlcnJmcCwgXCJcXG5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmcHJpbnRmKGVycmZwLCBcIlxcblwiKTsqL1xuICAgICAgICAvLyBDYW4gb3ZlcndyaXRlIHRyZWUgZGVjb2RlIHRyZWUgYXMgaXQgaXMgbm90IHVzZWQgYW55bW9yZVxuICAgICAgICBsZW4gPSBsaXRlcmFsVHJlZS5sZW5ndGg7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgICAgICBsaXRlcmFsVHJlZVtpXSA9IG5ldyBIdWZOb2RlKCk7XG4gICAgICAgIGlmIChDcmVhdGVUcmVlKGxpdGVyYWxUcmVlLCBsaXRlcmFsQ29kZXMsIGxsLCAwKSkge1xuICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgbGVuID0gbGl0ZXJhbFRyZWUubGVuZ3RoO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICAgICAgZGlzdGFuY2VUcmVlW2ldID0gbmV3IEh1Zk5vZGUoKTtcbiAgICAgICAgdmFyIGxsMiA9IG5ldyBBcnJheSgpO1xuICAgICAgICBmb3IgKGkgPSBsaXRlcmFsQ29kZXM7IGkgPCBsbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGxsMltpIC0gbGl0ZXJhbENvZGVzXSA9IGxsW2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChDcmVhdGVUcmVlKGRpc3RhbmNlVHJlZSwgZGlzdENvZGVzLCBsbDIsIDApKSB7XG4gICAgICAgICAgZmx1c2hCdWZmZXIoKTtcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+bGl0ZXJhbFRyZWVcIik7XG4gICAgICAgIG91dGVyOiB3aGlsZSAoMSkge1xuICAgICAgICAgIGogPSBEZWNvZGVWYWx1ZShsaXRlcmFsVHJlZSk7XG4gICAgICAgICAgaWYgKGogPj0gMjU2KSB7IC8vIEluIEM2NDogaWYgY2Fycnkgc2V0XG4gICAgICAgICAgICB2YXIgbGVuLCBkaXN0O1xuICAgICAgICAgICAgaiAtPSAyNTY7XG4gICAgICAgICAgICBpZiAoaiA9PSAwKSB7XG4gICAgICAgICAgICAgIC8vIEVPRlxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGotLTtcbiAgICAgICAgICAgIGxlbiA9IHJlYWRCaXRzKGNwbGV4dFtqXSkgKyBjcGxlbnNbal07XG5cbiAgICAgICAgICAgIGogPSBEZWNvZGVWYWx1ZShkaXN0YW5jZVRyZWUpO1xuICAgICAgICAgICAgaWYgKGNwZGV4dFtqXSA+IDgpIHtcbiAgICAgICAgICAgICAgZGlzdCA9IHJlYWRCaXRzKDgpO1xuICAgICAgICAgICAgICBkaXN0IHw9IChyZWFkQml0cyhjcGRleHRbal0gLSA4KSA8PCA4KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGRpc3QgPSByZWFkQml0cyhjcGRleHRbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGlzdCArPSBjcGRpc3Rbal07XG4gICAgICAgICAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgICAgICAgICAgaWYgKGJJZHggLSBkaXN0IDwgMCkge1xuICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHZhciBjID0gYnVmMzJrWyhiSWR4IC0gZGlzdCkgJiAweDdmZmZdO1xuICAgICAgICAgICAgICBhZGRCdWZmZXIoYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFkZEJ1ZmZlcihqKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IHdoaWxlICghbGFzdCk7XG4gICAgZmx1c2hCdWZmZXIoKTtcblxuICAgIGJ5dGVBbGlnbigpO1xuICAgIHJldHVybiAwO1xuICB9O1xuXG4gIEpYRy5VdGlsLlVuemlwLnByb3RvdHlwZS51bnppcEZpbGUgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgdmFyIGk7XG4gICAgdGhpcy51bnppcCgpO1xuICAgIC8vYWxlcnQodW56aXBwZWRbMF1bMV0pO1xuICAgIGZvciAoaSA9IDA7IGkgPCB1bnppcHBlZC5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHVuemlwcGVkW2ldWzFdID09IG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHVuemlwcGVkW2ldWzBdO1xuICAgICAgfVxuICAgIH1cblxuICB9O1xuXG4gIEpYRy5VdGlsLlVuemlwLnByb3RvdHlwZS5kZWZsYXRlID0gZnVuY3Rpb24oKSB7XG4gICAgb3V0cHV0QXJyID0gW107XG4gICAgdmFyIHRtcCA9IFtdO1xuICAgIG1vZGVaSVAgPSBmYWxzZTtcbiAgICBEZWZsYXRlTG9vcCgpO1xuICAgIGlmIChkZWJ1ZylcbiAgICAgIGFsZXJ0KG91dHB1dEFyci5qb2luKCcnKSk7XG4gICAgdW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpO1xuICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICB1bnppcHBlZFtmaWxlc11bMV0gPSBcIkRFRkxBVEVcIjtcbiAgICBmaWxlcysrO1xuICAgIHJldHVybiB1bnppcHBlZDtcbiAgfVxuXG4gIEpYRy5VdGlsLlVuemlwLnByb3RvdHlwZS51bnppcCA9IGZ1bmN0aW9uKCkge1xuICAgIC8vY29udmVydFRvQnl0ZUFycmF5KGlucHV0KTtcbiAgICBpZiAoZGVidWcpXG4gICAgICBhbGVydChiQSk7XG4gICAgLypmb3IgKGk9MDtpPGJBLmxlbmd0aCo4O2krKyl7XG5cdFx0ZG9jdW1lbnQud3JpdGUocmVhZEJpdCgpKTtcblx0XHRpZiAoKGkrMSklOD09MClcblx0XHRcdGRvY3VtZW50LndyaXRlKFwiIFwiKTtcblx0fSovXG4gICAgLypmb3IgKGk9MDtpPGJBLmxlbmd0aDtpKyspe1xuXHRcdGRvY3VtZW50LndyaXRlKHJlYWRCeXRlKCkrXCIgXCIpO1xuXHRcdGlmICgoaSsxKSU4PT0wKVxuXHRcdFx0ZG9jdW1lbnQud3JpdGUoXCIgXCIpO1xuXHR9XG5cdGZvciAoaT0wO2k8YkEubGVuZ3RoO2krKyl7XG5cdFx0ZG9jdW1lbnQud3JpdGUoYkFbaV0rXCIgXCIpO1xuXHRcdGlmICgoaSsxKSUxNj09MClcblx0XHRcdGRvY3VtZW50LndyaXRlKFwiPGJyPlwiKTtcblx0fVx0XG5cdCovXG4gICAgLy9hbGVydChiQSk7XG4gICAgbmV4dEZpbGUoKTtcbiAgICByZXR1cm4gdW56aXBwZWQ7XG4gIH07XG5cbiAgZnVuY3Rpb24gbmV4dEZpbGUoKSB7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgYWxlcnQoXCJORVhURklMRVwiKTtcbiAgICBvdXRwdXRBcnIgPSBbXTtcbiAgICB2YXIgdG1wID0gW107XG4gICAgbW9kZVpJUCA9IGZhbHNlO1xuICAgIHRtcFswXSA9IHJlYWRCeXRlKCk7XG4gICAgdG1wWzFdID0gcmVhZEJ5dGUoKTtcbiAgICBpZiAoZGVidWcpXG4gICAgICBhbGVydChcInR5cGU6IFwiICsgdG1wWzBdICsgXCIgXCIgKyB0bXBbMV0pO1xuICAgIGlmICh0bXBbMF0gPT0gcGFyc2VJbnQoXCI3OFwiLCAxNikgJiYgdG1wWzFdID09IHBhcnNlSW50KFwiZGFcIiwgMTYpKSB7IC8vR1pJUFxuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcIkdFT05FeFQtR1pJUFwiKTtcbiAgICAgIERlZmxhdGVMb29wKCk7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KG91dHB1dEFyci5qb2luKCcnKSk7XG4gICAgICB1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7XG4gICAgICB1bnppcHBlZFtmaWxlc11bMF0gPSBvdXRwdXRBcnIuam9pbignJyk7XG4gICAgICB1bnppcHBlZFtmaWxlc11bMV0gPSBcImdlb25leHQuZ3h0XCI7XG4gICAgICBmaWxlcysrO1xuICAgIH1cbiAgICBpZiAodG1wWzBdID09IHBhcnNlSW50KFwiNzhcIiwgMTYpICYmIHRtcFsxXSA9PSBwYXJzZUludChcIjljXCIsIDE2KSkgeyAvL1pMSUJcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJaTElCXCIpO1xuICAgICAgRGVmbGF0ZUxvb3AoKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXSA9IG5ldyBBcnJheSgyKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IFwiWkxJQlwiO1xuICAgICAgZmlsZXMrKztcbiAgICB9XG4gICAgaWYgKHRtcFswXSA9PSBwYXJzZUludChcIjFmXCIsIDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCI4YlwiLCAxNikpIHsgLy9HWklQXG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KFwiR1pJUFwiKTtcbiAgICAgIC8vRGVmbGF0ZUxvb3AoKTtcbiAgICAgIHNraXBkaXIoKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXSA9IG5ldyBBcnJheSgyKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IFwiZmlsZVwiO1xuICAgICAgZmlsZXMrKztcbiAgICB9XG4gICAgaWYgKHRtcFswXSA9PSBwYXJzZUludChcIjUwXCIsIDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCI0YlwiLCAxNikpIHsgLy9aSVBcbiAgICAgIG1vZGVaSVAgPSB0cnVlO1xuICAgICAgdG1wWzJdID0gcmVhZEJ5dGUoKTtcbiAgICAgIHRtcFszXSA9IHJlYWRCeXRlKCk7XG4gICAgICBpZiAodG1wWzJdID09IHBhcnNlSW50KFwiM1wiLCAxNikgJiYgdG1wWzNdID09IHBhcnNlSW50KFwiNFwiLCAxNikpIHtcbiAgICAgICAgLy9NT0RFX1pJUFxuICAgICAgICB0bXBbMF0gPSByZWFkQnl0ZSgpO1xuICAgICAgICB0bXBbMV0gPSByZWFkQnl0ZSgpO1xuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgYWxlcnQoXCJaSVAtVmVyc2lvbjogXCIgKyB0bXBbMV0gKyBcIiBcIiArIHRtcFswXSAvIDEwICsgXCIuXCIgKyB0bXBbMF0gJSAxMCk7XG5cbiAgICAgICAgZ3BmbGFncyA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGdwZmxhZ3MgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBhbGVydChcImdwZmxhZ3M6IFwiICsgZ3BmbGFncyk7XG5cbiAgICAgICAgdmFyIG1ldGhvZCA9IHJlYWRCeXRlKCk7XG4gICAgICAgIG1ldGhvZCB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgIGFsZXJ0KFwibWV0aG9kOiBcIiArIG1ldGhvZCk7XG5cbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgICAgcmVhZEJ5dGUoKTtcblxuICAgICAgICB2YXIgY3JjID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgICAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgICAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgMjQpO1xuXG4gICAgICAgIHZhciBjb21wU2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgICAgICBjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgICB2YXIgc2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgICAgICBzaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgYWxlcnQoXCJsb2NhbCBDUkM6IFwiICsgY3JjICsgXCJcXG5sb2NhbCBTaXplOiBcIiArIHNpemUgKyBcIlxcbmxvY2FsIENvbXBTaXplOiBcIiArIGNvbXBTaXplKTtcblxuICAgICAgICB2YXIgZmlsZWxlbiA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGZpbGVsZW4gfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG5cbiAgICAgICAgdmFyIGV4dHJhbGVuID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgZXh0cmFsZW4gfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG5cbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgIGFsZXJ0KFwiZmlsZWxlbiBcIiArIGZpbGVsZW4pO1xuICAgICAgICBpID0gMDtcbiAgICAgICAgbmFtZUJ1ZiA9IFtdO1xuICAgICAgICB3aGlsZSAoZmlsZWxlbi0tKSB7XG4gICAgICAgICAgdmFyIGMgPSByZWFkQnl0ZSgpO1xuICAgICAgICAgIGlmIChjID09IFwiL1wiIHwgYyA9PSBcIjpcIikge1xuICAgICAgICAgICAgaSA9IDA7XG4gICAgICAgICAgfSBlbHNlIGlmIChpIDwgTkFNRU1BWCAtIDEpXG4gICAgICAgICAgICBuYW1lQnVmW2krK10gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBhbGVydChcIm5hbWVCdWY6IFwiICsgbmFtZUJ1Zik7XG5cbiAgICAgICAgLy9uYW1lQnVmW2ldID0gXCJcXDBcIjtcbiAgICAgICAgaWYgKCFmaWxlb3V0KVxuICAgICAgICAgIGZpbGVvdXQgPSBuYW1lQnVmO1xuXG4gICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPCBleHRyYWxlbikge1xuICAgICAgICAgIGMgPSByZWFkQnl0ZSgpO1xuICAgICAgICAgIGkrKztcbiAgICAgICAgfVxuXG4gICAgICAgIENSQyA9IDB4ZmZmZmZmZmY7XG4gICAgICAgIFNJWkUgPSAwO1xuXG4gICAgICAgIGlmIChzaXplID09IDAgJiYgZmlsZU91dC5jaGFyQXQoZmlsZW91dC5sZW5ndGggLSAxKSA9PSBcIi9cIikge1xuICAgICAgICAgIC8vc2tpcGRpclxuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGFsZXJ0KFwic2tpcGRpclwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0aG9kID09IDgpIHtcbiAgICAgICAgICBEZWZsYXRlTG9vcCgpO1xuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGFsZXJ0KG91dHB1dEFyci5qb2luKCcnKSk7XG4gICAgICAgICAgdW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpO1xuICAgICAgICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICAgICAgICB1bnppcHBlZFtmaWxlc11bMV0gPSBuYW1lQnVmLmpvaW4oJycpO1xuICAgICAgICAgIGZpbGVzKys7XG4gICAgICAgICAgLy9yZXR1cm4gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgICAgICB9XG4gICAgICAgIHNraXBkaXIoKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gc2tpcGRpcigpIHtcbiAgICB2YXIgY3JjLFxuICAgICAgdG1wID0gW10sXG4gICAgICBjb21wU2l6ZSwgc2l6ZSwgb3MsIGksIGM7XG5cbiAgICBpZiAoKGdwZmxhZ3MgJiA4KSkge1xuICAgICAgdG1wWzBdID0gcmVhZEJ5dGUoKTtcbiAgICAgIHRtcFsxXSA9IHJlYWRCeXRlKCk7XG4gICAgICB0bXBbMl0gPSByZWFkQnl0ZSgpO1xuICAgICAgdG1wWzNdID0gcmVhZEJ5dGUoKTtcblxuICAgICAgaWYgKHRtcFswXSA9PSBwYXJzZUludChcIjUwXCIsIDE2KSAmJlxuICAgICAgICB0bXBbMV0gPT0gcGFyc2VJbnQoXCI0YlwiLCAxNikgJiZcbiAgICAgICAgdG1wWzJdID09IHBhcnNlSW50KFwiMDdcIiwgMTYpICYmXG4gICAgICAgIHRtcFszXSA9PSBwYXJzZUludChcIjA4XCIsIDE2KSkge1xuICAgICAgICBjcmMgPSByZWFkQnl0ZSgpO1xuICAgICAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjcmMgPSB0bXBbMF0gfCAodG1wWzFdIDw8IDgpIHwgKHRtcFsyXSA8PCAxNikgfCAodG1wWzNdIDw8IDI0KTtcbiAgICAgIH1cblxuICAgICAgY29tcFNpemUgPSByZWFkQnl0ZSgpO1xuICAgICAgY29tcFNpemUgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICBjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICBjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG5cbiAgICAgIHNpemUgPSByZWFkQnl0ZSgpO1xuICAgICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG5cbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJDUkM6XCIpO1xuICAgIH1cblxuICAgIGlmIChtb2RlWklQKVxuICAgICAgbmV4dEZpbGUoKTtcblxuICAgIHRtcFswXSA9IHJlYWRCeXRlKCk7XG4gICAgaWYgKHRtcFswXSAhPSA4KSB7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KFwiVW5rbm93biBjb21wcmVzc2lvbiBtZXRob2QhXCIpO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgZ3BmbGFncyA9IHJlYWRCeXRlKCk7XG4gICAgaWYgKGRlYnVnKSB7XG4gICAgICBpZiAoKGdwZmxhZ3MgJiB+KHBhcnNlSW50KFwiMWZcIiwgMTYpKSkpXG4gICAgICAgIGFsZXJ0KFwiVW5rbm93biBmbGFncyBzZXQhXCIpO1xuICAgIH1cblxuICAgIHJlYWRCeXRlKCk7XG4gICAgcmVhZEJ5dGUoKTtcbiAgICByZWFkQnl0ZSgpO1xuICAgIHJlYWRCeXRlKCk7XG5cbiAgICByZWFkQnl0ZSgpO1xuICAgIG9zID0gcmVhZEJ5dGUoKTtcblxuICAgIGlmICgoZ3BmbGFncyAmIDQpKSB7XG4gICAgICB0bXBbMF0gPSByZWFkQnl0ZSgpO1xuICAgICAgdG1wWzJdID0gcmVhZEJ5dGUoKTtcbiAgICAgIGxlbiA9IHRtcFswXSArIDI1NiAqIHRtcFsxXTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJFeHRyYSBmaWVsZCBzaXplOiBcIiArIGxlbik7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICAgIHJlYWRCeXRlKCk7XG4gICAgfVxuXG4gICAgaWYgKChncGZsYWdzICYgOCkpIHtcbiAgICAgIGkgPSAwO1xuICAgICAgbmFtZUJ1ZiA9IFtdO1xuICAgICAgd2hpbGUgKGMgPSByZWFkQnl0ZSgpKSB7XG4gICAgICAgIGlmIChjID09IFwiN1wiIHx8IGMgPT0gXCI6XCIpXG4gICAgICAgICAgaSA9IDA7XG4gICAgICAgIGlmIChpIDwgTkFNRU1BWCAtIDEpXG4gICAgICAgICAgbmFtZUJ1ZltpKytdID0gYztcbiAgICAgIH1cbiAgICAgIC8vbmFtZUJ1ZltpXSA9IFwiXFwwXCI7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KFwib3JpZ2luYWwgZmlsZSBuYW1lOiBcIiArIG5hbWVCdWYpO1xuICAgIH1cblxuICAgIGlmICgoZ3BmbGFncyAmIDE2KSkge1xuICAgICAgd2hpbGUgKGMgPSByZWFkQnl0ZSgpKSB7XG4gICAgICAgIC8vRklMRSBDT01NRU5UXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKChncGZsYWdzICYgMikpIHtcbiAgICAgIHJlYWRCeXRlKCk7XG4gICAgICByZWFkQnl0ZSgpO1xuICAgIH1cblxuICAgIERlZmxhdGVMb29wKCk7XG5cbiAgICBjcmMgPSByZWFkQnl0ZSgpO1xuICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG5cbiAgICBzaXplID0gcmVhZEJ5dGUoKTtcbiAgICBzaXplIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMjQpO1xuXG4gICAgaWYgKG1vZGVaSVApXG4gICAgICBuZXh0RmlsZSgpO1xuXG4gIH07XG5cbn07XG5cbi8qKlxuICogIEJhc2U2NCBlbmNvZGluZyAvIGRlY29kaW5nXG4gKiAge0BsaW5rIGh0dHA6Ly93d3cud2VidG9vbGtpdC5pbmZvL31cbiAqL1xuSlhHLlV0aWwuQmFzZTY0ID0ge1xuXG4gIC8vIHByaXZhdGUgcHJvcGVydHlcbiAgX2tleVN0cjogXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVwiLFxuXG4gIC8vIHB1YmxpYyBtZXRob2QgZm9yIGVuY29kaW5nXG4gIGVuY29kZTogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICB2YXIgb3V0cHV0ID0gW10sXG4gICAgICBjaHIxLCBjaHIyLCBjaHIzLCBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0LFxuICAgICAgaSA9IDA7XG5cbiAgICBpbnB1dCA9IEpYRy5VdGlsLkJhc2U2NC5fdXRmOF9lbmNvZGUoaW5wdXQpO1xuXG4gICAgd2hpbGUgKGkgPCBpbnB1dC5sZW5ndGgpIHtcblxuICAgICAgY2hyMSA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgIGNocjIgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICBjaHIzID0gaW5wdXQuY2hhckNvZGVBdChpKyspO1xuXG4gICAgICBlbmMxID0gY2hyMSA+PiAyO1xuICAgICAgZW5jMiA9ICgoY2hyMSAmIDMpIDw8IDQpIHwgKGNocjIgPj4gNCk7XG4gICAgICBlbmMzID0gKChjaHIyICYgMTUpIDw8IDIpIHwgKGNocjMgPj4gNik7XG4gICAgICBlbmM0ID0gY2hyMyAmIDYzO1xuXG4gICAgICBpZiAoaXNOYU4oY2hyMikpIHtcbiAgICAgICAgZW5jMyA9IGVuYzQgPSA2NDtcbiAgICAgIH0gZWxzZSBpZiAoaXNOYU4oY2hyMykpIHtcbiAgICAgICAgZW5jNCA9IDY0O1xuICAgICAgfVxuXG4gICAgICBvdXRwdXQucHVzaChbdGhpcy5fa2V5U3RyLmNoYXJBdChlbmMxKSxcbiAgICAgICAgICB0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzIpLFxuICAgICAgICAgIHRoaXMuX2tleVN0ci5jaGFyQXQoZW5jMyksXG4gICAgICAgICAgdGhpcy5fa2V5U3RyLmNoYXJBdChlbmM0KVxuICAgICAgXS5qb2luKCcnKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dC5qb2luKCcnKTtcbiAgfSxcblxuICAvLyBwdWJsaWMgbWV0aG9kIGZvciBkZWNvZGluZ1xuICBkZWNvZGU6IGZ1bmN0aW9uKGlucHV0LCB1dGY4KSB7XG4gICAgdmFyIG91dHB1dCA9IFtdLFxuICAgICAgY2hyMSwgY2hyMiwgY2hyMyxcbiAgICAgIGVuYzEsIGVuYzIsIGVuYzMsIGVuYzQsXG4gICAgICBpID0gMDtcblxuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvW15BLVphLXowLTlcXCtcXC9cXD1dL2csIFwiXCIpO1xuXG4gICAgd2hpbGUgKGkgPCBpbnB1dC5sZW5ndGgpIHtcblxuICAgICAgZW5jMSA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcbiAgICAgIGVuYzIgPSB0aGlzLl9rZXlTdHIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICBlbmMzID0gdGhpcy5fa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuICAgICAgZW5jNCA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcblxuICAgICAgY2hyMSA9IChlbmMxIDw8IDIpIHwgKGVuYzIgPj4gNCk7XG4gICAgICBjaHIyID0gKChlbmMyICYgMTUpIDw8IDQpIHwgKGVuYzMgPj4gMik7XG4gICAgICBjaHIzID0gKChlbmMzICYgMykgPDwgNikgfCBlbmM0O1xuXG4gICAgICBvdXRwdXQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGNocjEpKTtcblxuICAgICAgaWYgKGVuYzMgIT0gNjQpIHtcbiAgICAgICAgb3V0cHV0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjaHIyKSk7XG4gICAgICB9XG4gICAgICBpZiAoZW5jNCAhPSA2NCkge1xuICAgICAgICBvdXRwdXQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGNocjMpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBvdXRwdXQgPSBvdXRwdXQuam9pbignJyk7XG5cbiAgICBpZiAodXRmOCkge1xuICAgICAgb3V0cHV0ID0gSlhHLlV0aWwuQmFzZTY0Ll91dGY4X2RlY29kZShvdXRwdXQpO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0O1xuXG4gIH0sXG5cbiAgLy8gcHJpdmF0ZSBtZXRob2QgZm9yIFVURi04IGVuY29kaW5nXG4gIF91dGY4X2VuY29kZTogZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UoL1xcclxcbi9nLCBcIlxcblwiKTtcbiAgICB2YXIgdXRmdGV4dCA9IFwiXCI7XG5cbiAgICBmb3IgKHZhciBuID0gMDsgbiA8IHN0cmluZy5sZW5ndGg7IG4rKykge1xuXG4gICAgICB2YXIgYyA9IHN0cmluZy5jaGFyQ29kZUF0KG4pO1xuXG4gICAgICBpZiAoYyA8IDEyOCkge1xuICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyk7XG4gICAgICB9IGVsc2UgaWYgKChjID4gMTI3KSAmJiAoYyA8IDIwNDgpKSB7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoYyA+PiA2KSB8IDE5Mik7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoYyAmIDYzKSB8IDEyOCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGMgPj4gMTIpIHwgMjI0KTtcbiAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyA+PiA2KSAmIDYzKSB8IDEyOCk7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoYyAmIDYzKSB8IDEyOCk7XG4gICAgICB9XG5cbiAgICB9XG5cbiAgICByZXR1cm4gdXRmdGV4dDtcbiAgfSxcblxuICAvLyBwcml2YXRlIG1ldGhvZCBmb3IgVVRGLTggZGVjb2RpbmdcbiAgX3V0ZjhfZGVjb2RlOiBmdW5jdGlvbih1dGZ0ZXh0KSB7XG4gICAgdmFyIHN0cmluZyA9IFtdLFxuICAgICAgaSA9IDAsXG4gICAgICBjID0gMCxcbiAgICAgIGMyID0gMCxcbiAgICAgIGMzID0gMDtcblxuICAgIHdoaWxlIChpIDwgdXRmdGV4dC5sZW5ndGgpIHtcbiAgICAgIGMgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSk7XG4gICAgICBpZiAoYyA8IDEyOCkge1xuICAgICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGMpKTtcbiAgICAgICAgaSsrO1xuICAgICAgfSBlbHNlIGlmICgoYyA+IDE5MSkgJiYgKGMgPCAyMjQpKSB7XG4gICAgICAgIGMyID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAxKTtcbiAgICAgICAgc3RyaW5nLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgJiAzMSkgPDwgNikgfCAoYzIgJiA2MykpKTtcbiAgICAgICAgaSArPSAyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYzIgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSArIDEpO1xuICAgICAgICBjMyA9IHV0ZnRleHQuY2hhckNvZGVBdChpICsgMik7XG4gICAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoKChjICYgMTUpIDw8IDEyKSB8ICgoYzIgJiA2MykgPDwgNikgfCAoYzMgJiA2MykpKTtcbiAgICAgICAgaSArPSAzO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc3RyaW5nLmpvaW4oJycpO1xuICB9LFxuXG4gIF9kZXN0cmlwOiBmdW5jdGlvbihzdHJpcHBlZCwgd3JhcCkge1xuICAgIHZhciBsaW5lcyA9IFtdLFxuICAgICAgbGluZW5vLCBpLFxuICAgICAgZGVzdHJpcHBlZCA9IFtdO1xuXG4gICAgaWYgKHdyYXAgPT0gbnVsbClcbiAgICAgIHdyYXAgPSA3NjtcblxuICAgIHN0cmlwcGVkLnJlcGxhY2UoLyAvZywgXCJcIik7XG4gICAgbGluZW5vID0gc3RyaXBwZWQubGVuZ3RoIC8gd3JhcDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGluZW5vOyBpKyspXG4gICAgICBsaW5lc1tpXSA9IHN0cmlwcGVkLnN1YnN0cihpICogd3JhcCwgd3JhcCk7XG4gICAgaWYgKGxpbmVubyAhPSBzdHJpcHBlZC5sZW5ndGggLyB3cmFwKVxuICAgICAgbGluZXNbbGluZXMubGVuZ3RoXSA9IHN0cmlwcGVkLnN1YnN0cihsaW5lbm8gKiB3cmFwLCBzdHJpcHBlZC5sZW5ndGggLSAobGluZW5vICogd3JhcCkpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKVxuICAgICAgZGVzdHJpcHBlZC5wdXNoKGxpbmVzW2ldKTtcbiAgICByZXR1cm4gZGVzdHJpcHBlZC5qb2luKCdcXG4nKTtcbiAgfSxcblxuICBkZWNvZGVBc0FycmF5OiBmdW5jdGlvbihpbnB1dCkge1xuICAgIHZhciBkZWMgPSB0aGlzLmRlY29kZShpbnB1dCksXG4gICAgICBhciA9IFtdLFxuICAgICAgaTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgZGVjLmxlbmd0aDsgaSsrKSB7XG4gICAgICBhcltpXSA9IGRlYy5jaGFyQ29kZUF0KGkpO1xuICAgIH1cbiAgICByZXR1cm4gYXI7XG4gIH0sXG5cbiAgZGVjb2RlR0VPTkV4VDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICByZXR1cm4gZGVjb2RlQXNBcnJheShkZXN0cmlwKGlucHV0KSwgZmFsc2UpO1xuICB9XG59O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbkpYRy5VdGlsLmFzY2lpQ2hhckNvZGVBdCA9IGZ1bmN0aW9uKHN0ciwgaSkge1xuICB2YXIgYyA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuICBpZiAoYyA+IDI1NSkge1xuICAgIHN3aXRjaCAoYykge1xuICAgICAgY2FzZSA4MzY0OlxuICAgICAgICBjID0gMTI4O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIxODpcbiAgICAgICAgYyA9IDEzMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDQwMjpcbiAgICAgICAgYyA9IDEzMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMjI6XG4gICAgICAgIGMgPSAxMzI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjMwOlxuICAgICAgICBjID0gMTMzO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyNDpcbiAgICAgICAgYyA9IDEzNDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMjU6XG4gICAgICAgIGMgPSAxMzU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA3MTA6XG4gICAgICAgIGMgPSAxMzY7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjQwOlxuICAgICAgICBjID0gMTM3O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzUyOlxuICAgICAgICBjID0gMTM4O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODI0OTpcbiAgICAgICAgYyA9IDEzOTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDMzODpcbiAgICAgICAgYyA9IDE0MDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM4MTpcbiAgICAgICAgYyA9IDE0MjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMTY6XG4gICAgICAgIGMgPSAxNDU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjE3OlxuICAgICAgICBjID0gMTQ2O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyMDpcbiAgICAgICAgYyA9IDE0NztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMjE6XG4gICAgICAgIGMgPSAxNDg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjI2OlxuICAgICAgICBjID0gMTQ5O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIxMTpcbiAgICAgICAgYyA9IDE1MDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMTI6XG4gICAgICAgIGMgPSAxNTE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA3MzI6XG4gICAgICAgIGMgPSAxNTI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4NDgyOlxuICAgICAgICBjID0gMTUzO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzUzOlxuICAgICAgICBjID0gMTU0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODI1MDpcbiAgICAgICAgYyA9IDE1NTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDMzOTpcbiAgICAgICAgYyA9IDE1NjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM4MjpcbiAgICAgICAgYyA9IDE1ODtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM3NjpcbiAgICAgICAgYyA9IDE1OTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGM7XG59O1xuXG4vKipcbiAqIERlY29kaW5nIHN0cmluZyBpbnRvIHV0Zi04XG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyaW5nIHRvIGRlY29kZVxuICogQHJldHVybiB7U3RyaW5nfSB1dGY4IGRlY29kZWQgc3RyaW5nXG4gKi9cbkpYRy5VdGlsLnV0ZjhEZWNvZGUgPSBmdW5jdGlvbih1dGZ0ZXh0KSB7XG4gIHZhciBzdHJpbmcgPSBbXTtcbiAgdmFyIGkgPSAwO1xuICB2YXIgYyA9IDAsXG4gICAgYzEgPSAwLFxuICAgIGMyID0gMCxcbiAgICBjMztcbiAgaWYgKCFKWEcuZXhpc3RzKHV0ZnRleHQpKSByZXR1cm4gJyc7XG5cbiAgd2hpbGUgKGkgPCB1dGZ0ZXh0Lmxlbmd0aCkge1xuICAgIGMgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSk7XG5cbiAgICBpZiAoYyA8IDEyOCkge1xuICAgICAgc3RyaW5nLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjKSk7XG4gICAgICBpKys7XG4gICAgfSBlbHNlIGlmICgoYyA+IDE5MSkgJiYgKGMgPCAyMjQpKSB7XG4gICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpICsgMSk7XG4gICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAmIDMxKSA8PCA2KSB8IChjMiAmIDYzKSkpO1xuICAgICAgaSArPSAyO1xuICAgIH0gZWxzZSB7XG4gICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpICsgMSk7XG4gICAgICBjMyA9IHV0ZnRleHQuY2hhckNvZGVBdChpICsgMik7XG4gICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAmIDE1KSA8PCAxMikgfCAoKGMyICYgNjMpIDw8IDYpIHwgKGMzICYgNjMpKSk7XG4gICAgICBpICs9IDM7XG4gICAgfVxuICB9O1xuICByZXR1cm4gc3RyaW5nLmpvaW4oJycpO1xufTtcblxuLyoqXG4gKiBHZW5lcmF0ZSBhIHJhbmRvbSB1dWlkLlxuICogaHR0cDovL3d3dy5icm9vZmEuY29tXG4gKiBtYWlsdG86cm9iZXJ0QGJyb29mYS5jb21cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTAgUm9iZXJ0IEtpZWZmZXJcbiAqIER1YWwgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBhbmQgR1BMIGxpY2Vuc2VzLlxuICpcbiAqIEVYQU1QTEVTOlxuICogICA+Pj4gTWF0aC51dWlkKClcbiAqICAgXCI5MjMyOUQzOS02RjVDLTQ1MjAtQUJGQy1BQUI2NDU0NEUxNzJcIlxuICovXG5KWEcuVXRpbC5nZW5VVUlEID0gZnVuY3Rpb24oKSB7XG4gIC8vIFByaXZhdGUgYXJyYXkgb2YgY2hhcnMgdG8gdXNlXG4gIHZhciBjaGFycyA9ICcwMTIzNDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eicuc3BsaXQoJycpLFxuICAgIHV1aWQgPSBuZXcgQXJyYXkoMzYpLFxuICAgIHJuZCA9IDAsXG4gICAgcjtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDM2OyBpKyspIHtcbiAgICBpZiAoaSA9PSA4IHx8IGkgPT0gMTMgfHwgaSA9PSAxOCB8fCBpID09IDIzKSB7XG4gICAgICB1dWlkW2ldID0gJy0nO1xuICAgIH0gZWxzZSBpZiAoaSA9PSAxNCkge1xuICAgICAgdXVpZFtpXSA9ICc0JztcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHJuZCA8PSAweDAyKSBybmQgPSAweDIwMDAwMDAgKyAoTWF0aC5yYW5kb20oKSAqIDB4MTAwMDAwMCkgfCAwO1xuICAgICAgciA9IHJuZCAmIDB4ZjtcbiAgICAgIHJuZCA9IHJuZCA+PiA0O1xuICAgICAgdXVpZFtpXSA9IGNoYXJzWyhpID09IDE5KSA/IChyICYgMHgzKSB8IDB4OCA6IHJdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1dWlkLmpvaW4oJycpO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpYRztcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy9cbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyk7XG5cbi8qKlxuICpcbiAqIFRoaXMgb2JqZWN0IGNvbnRhaW5zIGNvbmZpZ3VyYXRpb24gdmFsdWVzIGFuZCBpbXBsZW1lbnRzXG4gKiBzdG9yaW5nIGFuZCByZXRyaWV2aW5nIGNvbmZpZ3VyYXRpb24gdGhlbSBmcm9tIEhUTUw1IGxvY2FsIHN0b3JhZ2UuXG4gKlxuICogVGhpcyBvYmplY3QgY2FuIGJlIGFjY2Vzc2VkIGFmdGVyIGNhbGxpbmcgb3BlbnBncC5pbml0KClcbiAqIHVzaW5nIG9wZW5wZ3AuY29uZmlnXG4gKiBTdG9yZWQgY29uZmlnIHBhcmFtZXRlcnMgY2FuIGJlIGFjY2Vzc2VkIHVzaW5nXG4gKiBvcGVucGdwLmNvbmZpZy5jb25maWdcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgR1BHNEJyb3dzZXJzIGNvbmZpZyBvYmplY3RcbiAqL1xudmFyIGNvbmZpZyA9IGZ1bmN0aW9uKCkge1xuICAvKipcbiAgICogQHByb3BlcnR5IHtJbnRlZ2VyfSBwcmVmZXJfaGFzaF9hbGdvcml0aG1cbiAgICogQHByb3BlcnR5IHtJbnRlZ2VyfSBlbmNyeXB0aW9uX2NpcGhlclxuICAgKiBAcHJvcGVydHkge0ludGVnZXJ9IGNvbXByZXNzaW9uXG4gICAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gc2hvd192ZXJzaW9uXG4gICAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gc2hvd19jb21tZW50XG4gICAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gaW50ZWdyaXR5X3Byb3RlY3RcbiAgICogQHByb3BlcnR5IHtTdHJpbmd9IGtleXNlcnZlclxuICAgKi9cbiAgdGhpcy5wcmVmZXJfaGFzaF9hbGdvcml0aG0gPSBlbnVtcy5oYXNoLnNoYTI1NjtcbiAgdGhpcy5lbmNyeXB0aW9uX2NpcGhlciA9IGVudW1zLnN5bW1ldHJpYy5hZXMyNTY7XG4gIHRoaXMuY29tcHJlc3Npb24gPSBlbnVtcy5jb21wcmVzc2lvbi56aXA7XG4gIHRoaXMuc2hvd192ZXJzaW9uID0gdHJ1ZTtcbiAgdGhpcy5zaG93X2NvbW1lbnQgPSB0cnVlO1xuICB0aGlzLmludGVncml0eV9wcm90ZWN0ID0gdHJ1ZTtcbiAgdGhpcy5rZXlzZXJ2ZXIgPSBcImtleXNlcnZlci5saW51eC5pdFwiOyAvLyBcInBncC5taXQuZWR1OjExMzcxXCJcblxuICB0aGlzLnZlcnNpb25zdHJpbmcgPSBcIk9wZW5QR1AuanMgVkVSU0lPTlwiO1xuICB0aGlzLmNvbW1lbnRzdHJpbmcgPSBcImh0dHA6Ly9vcGVucGdwanMub3JnXCI7XG5cbiAgLyoqXG4gICAqIElmIGVuYWJsZWQsIGRlYnVnIG1lc3NhZ2VzIHdpbGwgYmUgcHJpbnRlZFxuICAgKi9cbiAgdGhpcy5kZWJ1ZyA9IGZhbHNlO1xuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBjb25maWcoKTtcbiIsIi8vIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSCBcblxuLy8gbW9kaWZpZWQgdmVyc2lvbiBvZiBodHRwOi8vd3d3LmhhbmV3aW4ubmV0L2VuY3J5cHQvUEdkZWNvZGUuanM6XG5cbi8qIE9wZW5QR1AgZW5jcnlwdGlvbiB1c2luZyBSU0EvQUVTXG4gKiBDb3B5cmlnaHQgMjAwNS0yMDA2IEhlcmJlcnQgSGFuZXdpbmtlbCwgd3d3LmhhbmVXSU4uZGVcbiAqIHZlcnNpb24gMi4wLCBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uXG5cbiAqIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYXMtaXMsIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LiAgXG4gKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlIG9yIHNlbGwgdGhpcyBzb2Z0d2FyZSwgd2l0aCBvclxuICogd2l0aG91dCBmZWUsIGZvciBhbnkgcHVycG9zZSBhbmQgYnkgYW55IGluZGl2aWR1YWwgb3Igb3JnYW5pemF0aW9uLCBpcyBoZXJlYnlcbiAqIGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGFyYWdyYXBoIGFwcGVhciBcbiAqIGluIGFsbCBjb3BpZXMuIERpc3RyaWJ1dGlvbiBhcyBhIHBhcnQgb2YgYW4gYXBwbGljYXRpb24gb3IgYmluYXJ5IG11c3RcbiAqIGluY2x1ZGUgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyXG4gKiBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgYXBwbGljYXRpb24gb3IgZGlzdHJpYnV0aW9uLlxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICBjaXBoZXIgPSByZXF1aXJlKCcuL2NpcGhlcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICAvKipcbiAgICogQW4gYXJyYXkgb2YgYnl0ZXMsIHRoYXQgaXMgaW50ZWdlcnMgd2l0aCB2YWx1ZXMgZnJvbSAwIHRvIDI1NVxuICAgKiBAdHlwZWRlZiB7KEFycmF5fFVpbnQ4QXJyYXkpfSBvcGVucGdwX2J5dGVfYXJyYXlcbiAgICovXG5cbiAgLyoqXG4gICAqIEJsb2NrIGNpcGhlciBmdW5jdGlvblxuICAgKiBAY2FsbGJhY2sgb3BlbnBncF9jaXBoZXJfYmxvY2tfZm5cbiAgICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGJsb2NrIEEgYmxvY2sgdG8gcGVyZm9ybSBvcGVyYXRpb25zIG9uXG4gICAqIEBwYXJhbSB7b3BlbnBncF9ieXRlX2FycmF5fSBrZXkgdG8gdXNlIGluIGVuY3J5cHRpb24vZGVjcnlwdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX2J5dGVfYXJyYXl9IEVuY3J5cHRlZC9kZWNyeXB0ZWQgYmxvY2tcbiAgICovXG5cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBlbmNyeXB0cyBhIGdpdmVuIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXhyYW5kb20gXG4gICAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgYmxvY2tjaXBoZXIgdG8gZW5jcnlwdCBhIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByZWZpeHJhbmRvbSByYW5kb20gYnl0ZXMgb2YgYmxvY2tfc2l6ZSBsZW5ndGggcHJvdmlkZWQgXG4gICAqICBhcyBhIHN0cmluZyB0byBiZSB1c2VkIGluIHByZWZpeGluZyB0aGUgZGF0YVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfY2lwaGVyX2Jsb2NrX2ZufSBibG9ja2NpcGhlcmZuIHRoZSBhbGdvcml0aG0gZW5jcnlwdCBmdW5jdGlvbiB0byBlbmNyeXB0XG4gICAqICBkYXRhIGluIG9uZSBibG9ja19zaXplIGVuY3J5cHRpb24uIFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGJsb2NrX3NpemUgdGhlIGJsb2NrIHNpemUgaW4gYnl0ZXMgb2YgdGhlIGFsZ29yaXRobSB1c2VkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwbGFpbnRleHQgZGF0YSB0byBiZSBlbmNyeXB0ZWQgcHJvdmlkZWQgYXMgYSBzdHJpbmdcbiAgICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGtleSBrZXkgdG8gYmUgdXNlZCB0byBlbmNyeXB0IHRoZSBkYXRhLiBUaGlzIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBcbiAgICogIGJsb2NrY2lwaGVyZm5cbiAgICogQHBhcmFtIHtCb29sZWFufSByZXN5bmMgYSBib29sZWFuIHZhbHVlIHNwZWNpZnlpbmcgaWYgYSByZXN5bmMgb2YgdGhlIFxuICAgKiAgSVYgc2hvdWxkIGJlIHVzZWQgb3Igbm90LiBUaGUgZW5jcnlwdGVkZGF0YXBhY2tldCB1c2VzIHRoZSBcbiAgICogIFwib2xkXCIgc3R5bGUgd2l0aCBhIHJlc3luYy4gRW5jcnlwdGlvbiB3aXRoaW4gYW4gXG4gICAqICBlbmNyeXB0ZWRpbnRlZ3JpdHlwcm90ZWN0ZWRkYXRhIHBhY2tldCBpcyBub3QgcmVzeW5jaW5nIHRoZSBJVi5cbiAgICogQHJldHVybiB7U3RyaW5nfSBhIHN0cmluZyB3aXRoIHRoZSBlbmNyeXB0ZWQgZGF0YVxuICAgKi9cbiAgZW5jcnlwdDogZnVuY3Rpb24ocHJlZml4cmFuZG9tLCBjaXBoZXJmbiwgcGxhaW50ZXh0LCBrZXksIHJlc3luYykge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBGUiA9IG5ldyBBcnJheShibG9ja19zaXplKTtcbiAgICB2YXIgRlJFID0gbmV3IEFycmF5KGJsb2NrX3NpemUpO1xuXG4gICAgcHJlZml4cmFuZG9tID0gcHJlZml4cmFuZG9tICsgcHJlZml4cmFuZG9tLmNoYXJBdChibG9ja19zaXplIC0gMikgKyBwcmVmaXhyYW5kb20uY2hhckF0KGJsb2NrX3NpemUgLSAxKTtcbiAgICB1dGlsLnByaW50X2RlYnVnKFwicHJlZml4cmFuZG9tOlwiICsgdXRpbC5oZXhzdHJkdW1wKHByZWZpeHJhbmRvbSkpO1xuICAgIHZhciBjaXBoZXJ0ZXh0ID0gXCJcIjtcbiAgICAvLyAxLiAgVGhlIGZlZWRiYWNrIHJlZ2lzdGVyIChGUikgaXMgc2V0IHRvIHRoZSBJViwgd2hpY2ggaXMgYWxsIHplcm9zLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IDA7XG5cbiAgICAvLyAyLiAgRlIgaXMgZW5jcnlwdGVkIHRvIHByb2R1Y2UgRlJFIChGUiBFbmNyeXB0ZWQpLiAgVGhpcyBpcyB0aGVcbiAgICAvLyAgICAgZW5jcnlwdGlvbiBvZiBhbiBhbGwtemVybyB2YWx1ZS5cbiAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSKTtcbiAgICAvLyAzLiAgRlJFIGlzIHhvcmVkIHdpdGggdGhlIGZpcnN0IEJTIG9jdGV0cyBvZiByYW5kb20gZGF0YSBwcmVmaXhlZCB0b1xuICAgIC8vICAgICB0aGUgcGxhaW50ZXh0IHRvIHByb2R1Y2UgQ1sxXSB0aHJvdWdoIENbQlNdLCB0aGUgZmlyc3QgQlMgb2N0ZXRzXG4gICAgLy8gICAgIG9mIGNpcGhlcnRleHQuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGNpcGhlcnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwcmVmaXhyYW5kb20uY2hhckNvZGVBdChpKSk7XG5cbiAgICAvLyA0LiAgRlIgaXMgbG9hZGVkIHdpdGggQ1sxXSB0aHJvdWdoIENbQlNdLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcblxuICAgIC8vIDUuICBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUsIHRoZSBlbmNyeXB0aW9uIG9mIHRoZSBmaXJzdCBCU1xuICAgIC8vIFx0ICAgb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgRlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUik7XG5cbiAgICAvLyA2LiAgVGhlIGxlZnQgdHdvIG9jdGV0cyBvZiBGUkUgZ2V0IHhvcmVkIHdpdGggdGhlIG5leHQgdHdvIG9jdGV0cyBvZlxuICAgIC8vICAgICBkYXRhIHRoYXQgd2VyZSBwcmVmaXhlZCB0byB0aGUgcGxhaW50ZXh0LiAgVGhpcyBwcm9kdWNlcyBDW0JTKzFdXG4gICAgLy8gICAgIGFuZCBDW0JTKzJdLCB0aGUgbmV4dCB0d28gb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVswXSBeIHByZWZpeHJhbmRvbS5jaGFyQ29kZUF0KGJsb2NrX3NpemUpKTtcbiAgICBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFWzFdIF4gcHJlZml4cmFuZG9tLmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSArIDEpKTtcblxuICAgIGlmIChyZXN5bmMpIHtcbiAgICAgIC8vIDcuICAoVGhlIHJlc3luYyBzdGVwKSBGUiBpcyBsb2FkZWQgd2l0aCBDMy1DMTAuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgRlJbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSArIDIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgRlJbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICAgIC8vIDguICBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUuXG4gICAgRlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUiwga2V5KTtcblxuICAgIGlmIChyZXN5bmMpIHtcbiAgICAgIC8vIDkuICBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgZmlyc3QgOCBvY3RldHMgb2YgdGhlIGdpdmVuIHBsYWludGV4dCwgbm93XG4gICAgICAvL1x0ICAgdGhhdCB3ZSBoYXZlIGZpbmlzaGVkIGVuY3J5cHRpbmcgdGhlIDEwIG9jdGV0cyBvZiBwcmVmaXhlZCBkYXRhLlxuICAgICAgLy8gXHQgICBUaGlzIHByb2R1Y2VzIEMxMS1DMTgsIHRoZSBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKylcbiAgICAgICAgY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KGkpKTtcbiAgICAgIGZvciAobiA9IGJsb2NrX3NpemUgKyAyOyBuIDwgcGxhaW50ZXh0Lmxlbmd0aDsgbiArPSBibG9ja19zaXplKSB7XG4gICAgICAgIC8vIDEwLiBGUiBpcyBsb2FkZWQgd2l0aCBDMTEtQzE4XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChuICsgaSk7XG5cbiAgICAgICAgLy8gMTEuIEZSIGlzIGVuY3J5cHRlZCB0byBwcm9kdWNlIEZSRS5cbiAgICAgICAgRlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUik7XG5cbiAgICAgICAgLy8gMTIuIEZSRSBpcyB4b3JlZCB3aXRoIHRoZSBuZXh0IDggb2N0ZXRzIG9mIHBsYWludGV4dCwgdG8gcHJvZHVjZSB0aGVcbiAgICAgICAgLy8gbmV4dCA4IG9jdGV0cyBvZiBjaXBoZXJ0ZXh0LiAgVGhlc2UgYXJlIGxvYWRlZCBpbnRvIEZSIGFuZCB0aGVcbiAgICAgICAgLy8gcHJvY2VzcyBpcyByZXBlYXRlZCB1bnRpbCB0aGUgcGxhaW50ZXh0IGlzIHVzZWQgdXAuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQoKG4gLSAyKSArXG4gICAgICAgICAgICBpKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHBsYWludGV4dCA9IFwiICBcIiArIHBsYWludGV4dDtcbiAgICAgIC8vIDkuICBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgZmlyc3QgOCBvY3RldHMgb2YgdGhlIGdpdmVuIHBsYWludGV4dCwgbm93XG4gICAgICAvL1x0ICAgdGhhdCB3ZSBoYXZlIGZpbmlzaGVkIGVuY3J5cHRpbmcgdGhlIDEwIG9jdGV0cyBvZiBwcmVmaXhlZCBkYXRhLlxuICAgICAgLy8gXHQgICBUaGlzIHByb2R1Y2VzIEMxMS1DMTgsIHRoZSBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGJsb2NrX3NpemU7IGkrKykgY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KGkpKTtcbiAgICAgIHZhciB0ZW1wQ2lwaGVydGV4dCA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKDAsIDIgKiBibG9ja19zaXplKS5zcGxpdCgnJyk7XG4gICAgICB2YXIgdGVtcENpcGhlcnRleHRTdHJpbmcgPSBjaXBoZXJ0ZXh0LnN1YnN0cmluZyhibG9ja19zaXplKTtcbiAgICAgIGZvciAobiA9IGJsb2NrX3NpemU7IG4gPCBwbGFpbnRleHQubGVuZ3RoOyBuICs9IGJsb2NrX3NpemUpIHtcbiAgICAgICAgLy8gMTAuIEZSIGlzIGxvYWRlZCB3aXRoIEMxMS1DMThcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gdGVtcENpcGhlcnRleHRTdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICAgICAgdGVtcENpcGhlcnRleHRTdHJpbmcgPSAnJztcblxuICAgICAgICAvLyAxMS4gRlIgaXMgZW5jcnlwdGVkIHRvIHByb2R1Y2UgRlJFLlxuICAgICAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSKTtcblxuICAgICAgICAvLyAxMi4gRlJFIGlzIHhvcmVkIHdpdGggdGhlIG5leHQgOCBvY3RldHMgb2YgcGxhaW50ZXh0LCB0byBwcm9kdWNlIHRoZVxuICAgICAgICAvLyAgICAgbmV4dCA4IG9jdGV0cyBvZiBjaXBoZXJ0ZXh0LiAgVGhlc2UgYXJlIGxvYWRlZCBpbnRvIEZSIGFuZCB0aGVcbiAgICAgICAgLy8gICAgIHByb2Nlc3MgaXMgcmVwZWF0ZWQgdW50aWwgdGhlIHBsYWludGV4dCBpcyB1c2VkIHVwLlxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykge1xuICAgICAgICAgIHRlbXBDaXBoZXJ0ZXh0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwbGFpbnRleHQuY2hhckNvZGVBdChuICsgaSkpKTtcbiAgICAgICAgICB0ZW1wQ2lwaGVydGV4dFN0cmluZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KG4gKyBpKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNpcGhlcnRleHQgPSB0ZW1wQ2lwaGVydGV4dC5qb2luKCcnKTtcblxuICAgIH1cblxuICAgIGNpcGhlcnRleHQgPSBjaXBoZXJ0ZXh0LnN1YnN0cmluZygwLCBwbGFpbnRleHQubGVuZ3RoICsgMiArIGJsb2NrX3NpemUpO1xuXG4gICAgcmV0dXJuIGNpcGhlcnRleHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBwcmVmaXhlZCBkYXRhIGZvciB0aGUgTW9kaWZpY2F0aW9uIERldGVjdGlvbiBDb2RlIChNREMpIGNvbXB1dGF0aW9uXG4gICAqIEBwYXJhbSB7b3BlbnBncF9ibG9ja19jaXBoZXJfZm59IGNpcGhlcmZuLmVuY3J5cHQgQ2lwaGVyIGZ1bmN0aW9uIHRvIHVzZVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGJsb2NrX3NpemUgQmxvY2tzaXplIG9mIHRoZSBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGtleSBUaGUga2V5IGZvciBlbmNyeXB0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjaXBoZXJ0ZXh0IFRoZSBlbmNyeXB0ZWQgZGF0YVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IHBsYWludGV4dCBEYXRhIG9mIEQoY2lwaGVydGV4dCkgd2l0aCBibG9ja3NpemUgbGVuZ3RoICsyXG4gICAqL1xuICBtZGM6IGZ1bmN0aW9uKGNpcGhlcmZuLCBrZXksIGNpcGhlcnRleHQpIHtcbiAgICBjaXBoZXJmbiA9IG5ldyBjaXBoZXJbY2lwaGVyZm5dKGtleSk7XG4gICAgdmFyIGJsb2NrX3NpemUgPSBjaXBoZXJmbi5ibG9ja1NpemU7XG5cbiAgICB2YXIgaWJsb2NrID0gbmV3IEFycmF5KGJsb2NrX3NpemUpO1xuICAgIHZhciBhYmxvY2sgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG4gICAgdmFyIGk7XG5cblxuICAgIC8vIGluaXRpYWxpc2F0aW9uIHZlY3RvclxuICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGlibG9ja1tpXSA9IDA7XG5cbiAgICBpYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KGlibG9jayk7XG4gICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykge1xuICAgICAgYWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWJsb2NrW2ldIF49IGFibG9ja1tpXTtcbiAgICB9XG5cbiAgICBhYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KGFibG9jayk7XG5cbiAgICByZXR1cm4gdXRpbC5iaW4yc3RyKGlibG9jaykgK1xuICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZShhYmxvY2tbMF0gXiBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSkpICtcbiAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoYWJsb2NrWzFdIF4gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGJsb2NrX3NpemUgKyAxKSk7XG4gIH0sXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGRlY3J5cHRzIGEgZ2l2ZW4gcGxhaW50ZXh0IHVzaW5nIHRoZSBzcGVjaWZpZWRcbiAgICogYmxvY2tjaXBoZXIgdG8gZGVjcnlwdCBhIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtvcGVucGdwX2NpcGhlcl9ibG9ja19mbn0gYmxvY2tjaXBoZXJmbiBUaGUgYWxnb3JpdGhtIF9lbmNyeXB0XyBmdW5jdGlvbiB0byBlbmNyeXB0XG4gICAqICBkYXRhIGluIG9uZSBibG9ja19zaXplIGVuY3J5cHRpb24uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYmxvY2tfc2l6ZSB0aGUgYmxvY2sgc2l6ZSBpbiBieXRlcyBvZiB0aGUgYWxnb3JpdGhtIHVzZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBsYWludGV4dCBjaXBoZXJ0ZXh0IHRvIGJlIGRlY3J5cHRlZCBwcm92aWRlZCBhcyBhIHN0cmluZ1xuICAgKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZV9hcnJheX0ga2V5IGtleSB0byBiZSB1c2VkIHRvIGRlY3J5cHQgdGhlIGNpcGhlcnRleHQuIFRoaXMgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIFxuICAgKiAgYmxvY2tjaXBoZXJmblxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlc3luYyBhIGJvb2xlYW4gdmFsdWUgc3BlY2lmeWluZyBpZiBhIHJlc3luYyBvZiB0aGUgXG4gICAqICBJViBzaG91bGQgYmUgdXNlZCBvciBub3QuIFRoZSBlbmNyeXB0ZWRkYXRhcGFja2V0IHVzZXMgdGhlIFxuICAgKiAgXCJvbGRcIiBzdHlsZSB3aXRoIGEgcmVzeW5jLiBEZWNyeXB0aW9uIHdpdGhpbiBhbiBcbiAgICogIGVuY3J5cHRlZGludGVncml0eXByb3RlY3RlZGRhdGEgcGFja2V0IGlzIG5vdCByZXN5bmNpbmcgdGhlIElWLlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGEgc3RyaW5nIHdpdGggdGhlIHBsYWludGV4dCBkYXRhXG4gICAqL1xuXG4gIGRlY3J5cHQ6IGZ1bmN0aW9uKGNpcGhlcmZuLCBrZXksIGNpcGhlcnRleHQsIHJlc3luYykge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBpYmxvY2sgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG4gICAgdmFyIGFibG9jayA9IG5ldyBBcnJheShibG9ja19zaXplKTtcbiAgICB2YXIgaSwgbiA9ICcnO1xuICAgIHZhciB0ZXh0ID0gW107XG5cbiAgICAvLyBpbml0aWFsaXNhdGlvbiB2ZWN0b3JcbiAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSAwO1xuXG4gICAgaWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChpYmxvY2ssIGtleSk7XG4gICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykge1xuICAgICAgYWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWJsb2NrW2ldIF49IGFibG9ja1tpXTtcbiAgICB9XG5cbiAgICBhYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KGFibG9jaywga2V5KTtcblxuICAgIC8vIHRlc3QgY2hlY2sgb2N0ZXRzXG4gICAgaWYgKGlibG9ja1tibG9ja19zaXplIC0gMl0gIT0gKGFibG9ja1swXSBeIGNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplKSkgfHwgaWJsb2NrW2Jsb2NrX3NpemUgLSAxXSAhPSAoYWJsb2NrW1xuICAgICAgMV0gXiBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSArIDEpKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGEuJyk7XG4gICAgfVxuXG4gICAgLyogIFJGQzQ4ODA6IFRhZyAxOCBhbmQgUmVzeW5jOlxuXHRcdCAqICBbLi4uXSBVbmxpa2UgdGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgUGFja2V0LCBub1xuXHRcdCAqICBzcGVjaWFsIENGQiByZXN5bmNocm9uaXphdGlvbiBpcyBkb25lIGFmdGVyIGVuY3J5cHRpbmcgdGhpcyBwcmVmaXhcblx0XHQgKiAgZGF0YS4gIFNlZSBcIk9wZW5QR1AgQ0ZCIE1vZGVcIiBiZWxvdyBmb3IgbW9yZSBkZXRhaWxzLlxuXG5cdFx0ICovXG5cbiAgICBpZiAocmVzeW5jKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSArIDIpO1xuICAgICAgZm9yIChuID0gYmxvY2tfc2l6ZSArIDI7IG4gPCBjaXBoZXJ0ZXh0Lmxlbmd0aDsgbiArPSBibG9ja19zaXplKSB7XG4gICAgICAgIGFibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoaWJsb2NrKTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZSAmJiBpICsgbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQobiArIGkpO1xuICAgICAgICAgIHRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGFibG9ja1tpXSBeIGlibG9ja1tpXSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGlibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcbiAgICAgIGZvciAobiA9IGJsb2NrX3NpemU7IG4gPCBjaXBoZXJ0ZXh0Lmxlbmd0aDsgbiArPSBibG9ja19zaXplKSB7XG4gICAgICAgIGFibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoaWJsb2NrKTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemUgJiYgaSArIG4gPCBjaXBoZXJ0ZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KG4gKyBpKTtcbiAgICAgICAgICB0ZXh0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShhYmxvY2tbaV0gXiBpYmxvY2tbaV0pKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBuID0gcmVzeW5jID8gMCA6IDI7XG5cbiAgICB0ZXh0ID0gdGV4dC5qb2luKCcnKTtcblxuICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZyhuLCBjaXBoZXJ0ZXh0Lmxlbmd0aCAtIGJsb2NrX3NpemUgLSAyICsgbik7XG5cblxuICAgIHJldHVybiB0ZXh0O1xuICB9LFxuXG5cbiAgbm9ybWFsRW5jcnlwdDogZnVuY3Rpb24oY2lwaGVyZm4sIGtleSwgcGxhaW50ZXh0LCBpdikge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBibG9ja2kgPSBcIlwiO1xuICAgIHZhciBibG9ja2MgPSBcIlwiO1xuICAgIHZhciBwb3MgPSAwO1xuICAgIHZhciBjeXBoZXJ0ZXh0ID0gW107XG4gICAgdmFyIHRlbXBCbG9jayA9IFtdO1xuICAgIGJsb2NrYyA9IGl2LnN1YnN0cmluZygwLCBibG9ja19zaXplKTtcbiAgICB3aGlsZSAocGxhaW50ZXh0Lmxlbmd0aCA+IGJsb2NrX3NpemUgKiBwb3MpIHtcbiAgICAgIHZhciBlbmNibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQodXRpbC5zdHIyYmluKGJsb2NrYykpO1xuICAgICAgYmxvY2tpID0gcGxhaW50ZXh0LnN1YnN0cmluZygocG9zICogYmxvY2tfc2l6ZSksIChwb3MgKiBibG9ja19zaXplKSArIGJsb2NrX3NpemUpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja2kubGVuZ3RoOyBpKyspXG4gICAgICAgIHRlbXBCbG9jay5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYmxvY2tpLmNoYXJDb2RlQXQoaSkgXiBlbmNibG9ja1tpXSkpO1xuICAgICAgYmxvY2tjID0gdGVtcEJsb2NrLmpvaW4oJycpO1xuICAgICAgdGVtcEJsb2NrID0gW107XG4gICAgICBjeXBoZXJ0ZXh0LnB1c2goYmxvY2tjKTtcbiAgICAgIHBvcysrO1xuICAgIH1cbiAgICByZXR1cm4gY3lwaGVydGV4dC5qb2luKCcnKTtcbiAgfSxcblxuICBub3JtYWxEZWNyeXB0OiBmdW5jdGlvbihjaXBoZXJmbiwga2V5LCBjaXBoZXJ0ZXh0LCBpdikge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBibG9ja3AgPSBcIlwiO1xuICAgIHZhciBwb3MgPSAwO1xuICAgIHZhciBwbGFpbnRleHQgPSBbXTtcbiAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICBpZiAoaXYgPT0gbnVsbClcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBibG9ja3AgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICBlbHNlXG4gICAgICBibG9ja3AgPSBpdi5zdWJzdHJpbmcoMCwgYmxvY2tfc2l6ZSk7XG4gICAgd2hpbGUgKGNpcGhlcnRleHQubGVuZ3RoID4gKGJsb2NrX3NpemUgKiBwb3MpKSB7XG4gICAgICB2YXIgZGVjYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KHV0aWwuc3RyMmJpbihibG9ja3ApKTtcbiAgICAgIGJsb2NrcCA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKChwb3MgKiAoYmxvY2tfc2l6ZSkpICsgb2Zmc2V0LCAocG9zICogKGJsb2NrX3NpemUpKSArIChibG9ja19zaXplKSArIG9mZnNldCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrcC5sZW5ndGg7IGkrKykge1xuICAgICAgICBwbGFpbnRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJsb2NrcC5jaGFyQ29kZUF0KGkpIF4gZGVjYmxvY2tbaV0pKTtcbiAgICAgIH1cbiAgICAgIHBvcysrO1xuICAgIH1cblxuICAgIHJldHVybiBwbGFpbnRleHQuam9pbignJyk7XG4gIH1cbn1cbiIsIi8qIFJpam5kYWVsIChBRVMpIEVuY3J5cHRpb25cbiAqIENvcHlyaWdodCAyMDA1IEhlcmJlcnQgSGFuZXdpbmtlbCwgd3d3LmhhbmVXSU4uZGVcbiAqIHZlcnNpb24gMS4xLCBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uXG5cbiAqIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYXMtaXMsIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LiAgXG4gKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlIG9yIHNlbGwgdGhpcyBzb2Z0d2FyZSwgd2l0aCBvclxuICogd2l0aG91dCBmZWUsIGZvciBhbnkgcHVycG9zZSBhbmQgYnkgYW55IGluZGl2aWR1YWwgb3Igb3JnYW5pemF0aW9uLCBpcyBoZXJlYnlcbiAqIGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGFyYWdyYXBoIGFwcGVhciBcbiAqIGluIGFsbCBjb3BpZXMuIERpc3RyaWJ1dGlvbiBhcyBhIHBhcnQgb2YgYW4gYXBwbGljYXRpb24gb3IgYmluYXJ5IG11c3RcbiAqIGluY2x1ZGUgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyXG4gKiBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgYXBwbGljYXRpb24gb3IgZGlzdHJpYnV0aW9uLlxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBUaGUgcm91bmQgY29uc3RhbnRzIHVzZWQgaW4gc3Via2V5IGV4cGFuc2lvblxudmFyIFJjb24gPSBbXG4gICAgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxYiwgMHgzNiwgMHg2YywgMHhkOCxcbiAgICAweGFiLCAweDRkLCAweDlhLCAweDJmLCAweDVlLCAweGJjLCAweDYzLCAweGM2LCAweDk3LCAweDM1LCAweDZhLCAweGQ0LFxuICAgIDB4YjMsIDB4N2QsIDB4ZmEsIDB4ZWYsIDB4YzUsIDB4OTFcbl07XG5cbi8vIFByZWNvbXB1dGVkIGxvb2t1cCB0YWJsZSBmb3IgdGhlIFNCb3hcbnZhciBTID0gW1xuICAgIDk5LCAxMjQsIDExOSwgMTIzLCAyNDIsIDEwNywgMTExLCAxOTcsIDQ4LCAxLCAxMDMsIDQzLCAyNTQsIDIxNSwgMTcxLFxuICAgIDExOCwgMjAyLCAxMzAsIDIwMSwgMTI1LCAyNTAsIDg5LCA3MSwgMjQwLCAxNzMsIDIxMiwgMTYyLCAxNzUsIDE1NiwgMTY0LFxuICAgIDExNCwgMTkyLCAxODMsIDI1MywgMTQ3LCAzOCwgNTQsIDYzLCAyNDcsIDIwNCwgNTIsIDE2NSwgMjI5LCAyNDEsIDExMyxcbiAgICAyMTYsIDQ5LCAyMSwgNCwgMTk5LCAzNSwgMTk1LCAyNCwgMTUwLCA1LCAxNTQsIDcsIDE4LCAxMjgsIDIyNixcbiAgICAyMzUsIDM5LCAxNzgsIDExNywgOSwgMTMxLCA0NCwgMjYsIDI3LCAxMTAsIDkwLCAxNjAsIDgyLCA1OSwgMjE0LFxuICAgIDE3OSwgNDEsIDIyNywgNDcsIDEzMiwgODMsIDIwOSwgMCwgMjM3LCAzMiwgMjUyLCAxNzcsIDkxLCAxMDYsIDIwMyxcbiAgICAxOTAsIDU3LCA3NCwgNzYsIDg4LCAyMDcsIDIwOCwgMjM5LCAxNzAsIDI1MSwgNjcsIDc3LCA1MSwgMTMzLCA2OSxcbiAgICAyNDksIDIsIDEyNywgODAsIDYwLCAxNTksIDE2OCwgODEsIDE2MywgNjQsIDE0MywgMTQ2LCAxNTcsIDU2LCAyNDUsXG4gICAgMTg4LCAxODIsIDIxOCwgMzMsIDE2LCAyNTUsIDI0MywgMjEwLCAyMDUsIDEyLCAxOSwgMjM2LCA5NSwgMTUxLCA2OCxcbiAgICAyMywgMTk2LCAxNjcsIDEyNiwgNjEsIDEwMCwgOTMsIDI1LCAxMTUsIDk2LCAxMjksIDc5LCAyMjAsIDM0LCA0MixcbiAgICAxNDQsIDEzNiwgNzAsIDIzOCwgMTg0LCAyMCwgMjIyLCA5NCwgMTEsIDIxOSwgMjI0LCA1MCwgNTgsIDEwLCA3MyxcbiAgICA2LCAzNiwgOTIsIDE5NCwgMjExLCAxNzIsIDk4LCAxNDUsIDE0OSwgMjI4LCAxMjEsIDIzMSwgMjAwLCA1NSwgMTA5LFxuICAgIDE0MSwgMjEzLCA3OCwgMTY5LCAxMDgsIDg2LCAyNDQsIDIzNCwgMTAxLCAxMjIsIDE3NCwgOCwgMTg2LCAxMjAsIDM3LFxuICAgIDQ2LCAyOCwgMTY2LCAxODAsIDE5OCwgMjMyLCAyMjEsIDExNiwgMzEsIDc1LCAxODksIDEzOSwgMTM4LCAxMTIsIDYyLFxuICAgIDE4MSwgMTAyLCA3MiwgMywgMjQ2LCAxNCwgOTcsIDUzLCA4NywgMTg1LCAxMzQsIDE5MywgMjksIDE1OCwgMjI1LFxuICAgIDI0OCwgMTUyLCAxNywgMTA1LCAyMTcsIDE0MiwgMTQ4LCAxNTUsIDMwLCAxMzUsIDIzMywgMjA2LCA4NSwgNDAsIDIyMyxcbiAgICAxNDAsIDE2MSwgMTM3LCAxMywgMTkxLCAyMzAsIDY2LCAxMDQsIDY1LCAxNTMsIDQ1LCAxNSwgMTc2LCA4NCwgMTg3LFxuICAgIDIyXG5dO1xuXG52YXIgVDEgPSBbXG4gICAgMHhhNTYzNjNjNiwgMHg4NDdjN2NmOCwgMHg5OTc3NzdlZSwgMHg4ZDdiN2JmNixcbiAgICAweDBkZjJmMmZmLCAweGJkNmI2YmQ2LCAweGIxNmY2ZmRlLCAweDU0YzVjNTkxLFxuICAgIDB4NTAzMDMwNjAsIDB4MDMwMTAxMDIsIDB4YTk2NzY3Y2UsIDB4N2QyYjJiNTYsXG4gICAgMHgxOWZlZmVlNywgMHg2MmQ3ZDdiNSwgMHhlNmFiYWI0ZCwgMHg5YTc2NzZlYyxcbiAgICAweDQ1Y2FjYThmLCAweDlkODI4MjFmLCAweDQwYzljOTg5LCAweDg3N2Q3ZGZhLFxuICAgIDB4MTVmYWZhZWYsIDB4ZWI1OTU5YjIsIDB4Yzk0NzQ3OGUsIDB4MGJmMGYwZmIsXG4gICAgMHhlY2FkYWQ0MSwgMHg2N2Q0ZDRiMywgMHhmZGEyYTI1ZiwgMHhlYWFmYWY0NSxcbiAgICAweGJmOWM5YzIzLCAweGY3YTRhNDUzLCAweDk2NzI3MmU0LCAweDViYzBjMDliLFxuICAgIDB4YzJiN2I3NzUsIDB4MWNmZGZkZTEsIDB4YWU5MzkzM2QsIDB4NmEyNjI2NGMsXG4gICAgMHg1YTM2MzY2YywgMHg0MTNmM2Y3ZSwgMHgwMmY3ZjdmNSwgMHg0ZmNjY2M4MyxcbiAgICAweDVjMzQzNDY4LCAweGY0YTVhNTUxLCAweDM0ZTVlNWQxLCAweDA4ZjFmMWY5LFxuICAgIDB4OTM3MTcxZTIsIDB4NzNkOGQ4YWIsIDB4NTMzMTMxNjIsIDB4M2YxNTE1MmEsXG4gICAgMHgwYzA0MDQwOCwgMHg1MmM3Yzc5NSwgMHg2NTIzMjM0NiwgMHg1ZWMzYzM5ZCxcbiAgICAweDI4MTgxODMwLCAweGExOTY5NjM3LCAweDBmMDUwNTBhLCAweGI1OWE5YTJmLFxuICAgIDB4MDkwNzA3MGUsIDB4MzYxMjEyMjQsIDB4OWI4MDgwMWIsIDB4M2RlMmUyZGYsXG4gICAgMHgyNmViZWJjZCwgMHg2OTI3Mjc0ZSwgMHhjZGIyYjI3ZiwgMHg5Zjc1NzVlYSxcbiAgICAweDFiMDkwOTEyLCAweDllODM4MzFkLCAweDc0MmMyYzU4LCAweDJlMWExYTM0LFxuICAgIDB4MmQxYjFiMzYsIDB4YjI2ZTZlZGMsIDB4ZWU1YTVhYjQsIDB4ZmJhMGEwNWIsXG4gICAgMHhmNjUyNTJhNCwgMHg0ZDNiM2I3NiwgMHg2MWQ2ZDZiNywgMHhjZWIzYjM3ZCxcbiAgICAweDdiMjkyOTUyLCAweDNlZTNlM2RkLCAweDcxMmYyZjVlLCAweDk3ODQ4NDEzLFxuICAgIDB4ZjU1MzUzYTYsIDB4NjhkMWQxYjksIDB4MDAwMDAwMDAsIDB4MmNlZGVkYzEsXG4gICAgMHg2MDIwMjA0MCwgMHgxZmZjZmNlMywgMHhjOGIxYjE3OSwgMHhlZDViNWJiNixcbiAgICAweGJlNmE2YWQ0LCAweDQ2Y2JjYjhkLCAweGQ5YmViZTY3LCAweDRiMzkzOTcyLFxuICAgIDB4ZGU0YTRhOTQsIDB4ZDQ0YzRjOTgsIDB4ZTg1ODU4YjAsIDB4NGFjZmNmODUsXG4gICAgMHg2YmQwZDBiYiwgMHgyYWVmZWZjNSwgMHhlNWFhYWE0ZiwgMHgxNmZiZmJlZCxcbiAgICAweGM1NDM0Mzg2LCAweGQ3NGQ0ZDlhLCAweDU1MzMzMzY2LCAweDk0ODU4NTExLFxuICAgIDB4Y2Y0NTQ1OGEsIDB4MTBmOWY5ZTksIDB4MDYwMjAyMDQsIDB4ODE3ZjdmZmUsXG4gICAgMHhmMDUwNTBhMCwgMHg0NDNjM2M3OCwgMHhiYTlmOWYyNSwgMHhlM2E4YTg0YixcbiAgICAweGYzNTE1MWEyLCAweGZlYTNhMzVkLCAweGMwNDA0MDgwLCAweDhhOGY4ZjA1LFxuICAgIDB4YWQ5MjkyM2YsIDB4YmM5ZDlkMjEsIDB4NDgzODM4NzAsIDB4MDRmNWY1ZjEsXG4gICAgMHhkZmJjYmM2MywgMHhjMWI2YjY3NywgMHg3NWRhZGFhZiwgMHg2MzIxMjE0MixcbiAgICAweDMwMTAxMDIwLCAweDFhZmZmZmU1LCAweDBlZjNmM2ZkLCAweDZkZDJkMmJmLFxuICAgIDB4NGNjZGNkODEsIDB4MTQwYzBjMTgsIDB4MzUxMzEzMjYsIDB4MmZlY2VjYzMsXG4gICAgMHhlMTVmNWZiZSwgMHhhMjk3OTczNSwgMHhjYzQ0NDQ4OCwgMHgzOTE3MTcyZSxcbiAgICAweDU3YzRjNDkzLCAweGYyYTdhNzU1LCAweDgyN2U3ZWZjLCAweDQ3M2QzZDdhLFxuICAgIDB4YWM2NDY0YzgsIDB4ZTc1ZDVkYmEsIDB4MmIxOTE5MzIsIDB4OTU3MzczZTYsXG4gICAgMHhhMDYwNjBjMCwgMHg5ODgxODExOSwgMHhkMTRmNGY5ZSwgMHg3ZmRjZGNhMyxcbiAgICAweDY2MjIyMjQ0LCAweDdlMmEyYTU0LCAweGFiOTA5MDNiLCAweDgzODg4ODBiLFxuICAgIDB4Y2E0NjQ2OGMsIDB4MjllZWVlYzcsIDB4ZDNiOGI4NmIsIDB4M2MxNDE0MjgsXG4gICAgMHg3OWRlZGVhNywgMHhlMjVlNWViYywgMHgxZDBiMGIxNiwgMHg3NmRiZGJhZCxcbiAgICAweDNiZTBlMGRiLCAweDU2MzIzMjY0LCAweDRlM2EzYTc0LCAweDFlMGEwYTE0LFxuICAgIDB4ZGI0OTQ5OTIsIDB4MGEwNjA2MGMsIDB4NmMyNDI0NDgsIDB4ZTQ1YzVjYjgsXG4gICAgMHg1ZGMyYzI5ZiwgMHg2ZWQzZDNiZCwgMHhlZmFjYWM0MywgMHhhNjYyNjJjNCxcbiAgICAweGE4OTE5MTM5LCAweGE0OTU5NTMxLCAweDM3ZTRlNGQzLCAweDhiNzk3OWYyLFxuICAgIDB4MzJlN2U3ZDUsIDB4NDNjOGM4OGIsIDB4NTkzNzM3NmUsIDB4Yjc2ZDZkZGEsXG4gICAgMHg4YzhkOGQwMSwgMHg2NGQ1ZDViMSwgMHhkMjRlNGU5YywgMHhlMGE5YTk0OSxcbiAgICAweGI0NmM2Y2Q4LCAweGZhNTY1NmFjLCAweDA3ZjRmNGYzLCAweDI1ZWFlYWNmLFxuICAgIDB4YWY2NTY1Y2EsIDB4OGU3YTdhZjQsIDB4ZTlhZWFlNDcsIDB4MTgwODA4MTAsXG4gICAgMHhkNWJhYmE2ZiwgMHg4ODc4NzhmMCwgMHg2ZjI1MjU0YSwgMHg3MjJlMmU1YyxcbiAgICAweDI0MWMxYzM4LCAweGYxYTZhNjU3LCAweGM3YjRiNDczLCAweDUxYzZjNjk3LFxuICAgIDB4MjNlOGU4Y2IsIDB4N2NkZGRkYTEsIDB4OWM3NDc0ZTgsIDB4MjExZjFmM2UsXG4gICAgMHhkZDRiNGI5NiwgMHhkY2JkYmQ2MSwgMHg4NjhiOGIwZCwgMHg4NThhOGEwZixcbiAgICAweDkwNzA3MGUwLCAweDQyM2UzZTdjLCAweGM0YjViNTcxLCAweGFhNjY2NmNjLFxuICAgIDB4ZDg0ODQ4OTAsIDB4MDUwMzAzMDYsIDB4MDFmNmY2ZjcsIDB4MTIwZTBlMWMsXG4gICAgMHhhMzYxNjFjMiwgMHg1ZjM1MzU2YSwgMHhmOTU3NTdhZSwgMHhkMGI5Yjk2OSxcbiAgICAweDkxODY4NjE3LCAweDU4YzFjMTk5LCAweDI3MWQxZDNhLCAweGI5OWU5ZTI3LFxuICAgIDB4MzhlMWUxZDksIDB4MTNmOGY4ZWIsIDB4YjM5ODk4MmIsIDB4MzMxMTExMjIsXG4gICAgMHhiYjY5NjlkMiwgMHg3MGQ5ZDlhOSwgMHg4OThlOGUwNywgMHhhNzk0OTQzMyxcbiAgICAweGI2OWI5YjJkLCAweDIyMWUxZTNjLCAweDkyODc4NzE1LCAweDIwZTllOWM5LFxuICAgIDB4NDljZWNlODcsIDB4ZmY1NTU1YWEsIDB4NzgyODI4NTAsIDB4N2FkZmRmYTUsXG4gICAgMHg4ZjhjOGMwMywgMHhmOGExYTE1OSwgMHg4MDg5ODkwOSwgMHgxNzBkMGQxYSxcbiAgICAweGRhYmZiZjY1LCAweDMxZTZlNmQ3LCAweGM2NDI0Mjg0LCAweGI4Njg2OGQwLFxuICAgIDB4YzM0MTQxODIsIDB4YjA5OTk5MjksIDB4NzcyZDJkNWEsIDB4MTEwZjBmMWUsXG4gICAgMHhjYmIwYjA3YiwgMHhmYzU0NTRhOCwgMHhkNmJiYmI2ZCwgMHgzYTE2MTYyY1xuXTtcblxudmFyIFQyID0gW1xuICAgIDB4NjM2M2M2YTUsIDB4N2M3Y2Y4ODQsIDB4Nzc3N2VlOTksIDB4N2I3YmY2OGQsXG4gICAgMHhmMmYyZmYwZCwgMHg2YjZiZDZiZCwgMHg2ZjZmZGViMSwgMHhjNWM1OTE1NCxcbiAgICAweDMwMzA2MDUwLCAweDAxMDEwMjAzLCAweDY3NjdjZWE5LCAweDJiMmI1NjdkLFxuICAgIDB4ZmVmZWU3MTksIDB4ZDdkN2I1NjIsIDB4YWJhYjRkZTYsIDB4NzY3NmVjOWEsXG4gICAgMHhjYWNhOGY0NSwgMHg4MjgyMWY5ZCwgMHhjOWM5ODk0MCwgMHg3ZDdkZmE4NyxcbiAgICAweGZhZmFlZjE1LCAweDU5NTliMmViLCAweDQ3NDc4ZWM5LCAweGYwZjBmYjBiLFxuICAgIDB4YWRhZDQxZWMsIDB4ZDRkNGIzNjcsIDB4YTJhMjVmZmQsIDB4YWZhZjQ1ZWEsXG4gICAgMHg5YzljMjNiZiwgMHhhNGE0NTNmNywgMHg3MjcyZTQ5NiwgMHhjMGMwOWI1YixcbiAgICAweGI3Yjc3NWMyLCAweGZkZmRlMTFjLCAweDkzOTMzZGFlLCAweDI2MjY0YzZhLFxuICAgIDB4MzYzNjZjNWEsIDB4M2YzZjdlNDEsIDB4ZjdmN2Y1MDIsIDB4Y2NjYzgzNGYsXG4gICAgMHgzNDM0Njg1YywgMHhhNWE1NTFmNCwgMHhlNWU1ZDEzNCwgMHhmMWYxZjkwOCxcbiAgICAweDcxNzFlMjkzLCAweGQ4ZDhhYjczLCAweDMxMzE2MjUzLCAweDE1MTUyYTNmLFxuICAgIDB4MDQwNDA4MGMsIDB4YzdjNzk1NTIsIDB4MjMyMzQ2NjUsIDB4YzNjMzlkNWUsXG4gICAgMHgxODE4MzAyOCwgMHg5Njk2MzdhMSwgMHgwNTA1MGEwZiwgMHg5YTlhMmZiNSxcbiAgICAweDA3MDcwZTA5LCAweDEyMTIyNDM2LCAweDgwODAxYjliLCAweGUyZTJkZjNkLFxuICAgIDB4ZWJlYmNkMjYsIDB4MjcyNzRlNjksIDB4YjJiMjdmY2QsIDB4NzU3NWVhOWYsXG4gICAgMHgwOTA5MTIxYiwgMHg4MzgzMWQ5ZSwgMHgyYzJjNTg3NCwgMHgxYTFhMzQyZSxcbiAgICAweDFiMWIzNjJkLCAweDZlNmVkY2IyLCAweDVhNWFiNGVlLCAweGEwYTA1YmZiLFxuICAgIDB4NTI1MmE0ZjYsIDB4M2IzYjc2NGQsIDB4ZDZkNmI3NjEsIDB4YjNiMzdkY2UsXG4gICAgMHgyOTI5NTI3YiwgMHhlM2UzZGQzZSwgMHgyZjJmNWU3MSwgMHg4NDg0MTM5NyxcbiAgICAweDUzNTNhNmY1LCAweGQxZDFiOTY4LCAweDAwMDAwMDAwLCAweGVkZWRjMTJjLFxuICAgIDB4MjAyMDQwNjAsIDB4ZmNmY2UzMWYsIDB4YjFiMTc5YzgsIDB4NWI1YmI2ZWQsXG4gICAgMHg2YTZhZDRiZSwgMHhjYmNiOGQ0NiwgMHhiZWJlNjdkOSwgMHgzOTM5NzI0YixcbiAgICAweDRhNGE5NGRlLCAweDRjNGM5OGQ0LCAweDU4NThiMGU4LCAweGNmY2Y4NTRhLFxuICAgIDB4ZDBkMGJiNmIsIDB4ZWZlZmM1MmEsIDB4YWFhYTRmZTUsIDB4ZmJmYmVkMTYsXG4gICAgMHg0MzQzODZjNSwgMHg0ZDRkOWFkNywgMHgzMzMzNjY1NSwgMHg4NTg1MTE5NCxcbiAgICAweDQ1NDU4YWNmLCAweGY5ZjllOTEwLCAweDAyMDIwNDA2LCAweDdmN2ZmZTgxLFxuICAgIDB4NTA1MGEwZjAsIDB4M2MzYzc4NDQsIDB4OWY5ZjI1YmEsIDB4YThhODRiZTMsXG4gICAgMHg1MTUxYTJmMywgMHhhM2EzNWRmZSwgMHg0MDQwODBjMCwgMHg4ZjhmMDU4YSxcbiAgICAweDkyOTIzZmFkLCAweDlkOWQyMWJjLCAweDM4Mzg3MDQ4LCAweGY1ZjVmMTA0LFxuICAgIDB4YmNiYzYzZGYsIDB4YjZiNjc3YzEsIDB4ZGFkYWFmNzUsIDB4MjEyMTQyNjMsXG4gICAgMHgxMDEwMjAzMCwgMHhmZmZmZTUxYSwgMHhmM2YzZmQwZSwgMHhkMmQyYmY2ZCxcbiAgICAweGNkY2Q4MTRjLCAweDBjMGMxODE0LCAweDEzMTMyNjM1LCAweGVjZWNjMzJmLFxuICAgIDB4NWY1ZmJlZTEsIDB4OTc5NzM1YTIsIDB4NDQ0NDg4Y2MsIDB4MTcxNzJlMzksXG4gICAgMHhjNGM0OTM1NywgMHhhN2E3NTVmMiwgMHg3ZTdlZmM4MiwgMHgzZDNkN2E0NyxcbiAgICAweDY0NjRjOGFjLCAweDVkNWRiYWU3LCAweDE5MTkzMjJiLCAweDczNzNlNjk1LFxuICAgIDB4NjA2MGMwYTAsIDB4ODE4MTE5OTgsIDB4NGY0ZjllZDEsIDB4ZGNkY2EzN2YsXG4gICAgMHgyMjIyNDQ2NiwgMHgyYTJhNTQ3ZSwgMHg5MDkwM2JhYiwgMHg4ODg4MGI4MyxcbiAgICAweDQ2NDY4Y2NhLCAweGVlZWVjNzI5LCAweGI4Yjg2YmQzLCAweDE0MTQyODNjLFxuICAgIDB4ZGVkZWE3NzksIDB4NWU1ZWJjZTIsIDB4MGIwYjE2MWQsIDB4ZGJkYmFkNzYsXG4gICAgMHhlMGUwZGIzYiwgMHgzMjMyNjQ1NiwgMHgzYTNhNzQ0ZSwgMHgwYTBhMTQxZSxcbiAgICAweDQ5NDk5MmRiLCAweDA2MDYwYzBhLCAweDI0MjQ0ODZjLCAweDVjNWNiOGU0LFxuICAgIDB4YzJjMjlmNWQsIDB4ZDNkM2JkNmUsIDB4YWNhYzQzZWYsIDB4NjI2MmM0YTYsXG4gICAgMHg5MTkxMzlhOCwgMHg5NTk1MzFhNCwgMHhlNGU0ZDMzNywgMHg3OTc5ZjI4YixcbiAgICAweGU3ZTdkNTMyLCAweGM4Yzg4YjQzLCAweDM3Mzc2ZTU5LCAweDZkNmRkYWI3LFxuICAgIDB4OGQ4ZDAxOGMsIDB4ZDVkNWIxNjQsIDB4NGU0ZTljZDIsIDB4YTlhOTQ5ZTAsXG4gICAgMHg2YzZjZDhiNCwgMHg1NjU2YWNmYSwgMHhmNGY0ZjMwNywgMHhlYWVhY2YyNSxcbiAgICAweDY1NjVjYWFmLCAweDdhN2FmNDhlLCAweGFlYWU0N2U5LCAweDA4MDgxMDE4LFxuICAgIDB4YmFiYTZmZDUsIDB4Nzg3OGYwODgsIDB4MjUyNTRhNmYsIDB4MmUyZTVjNzIsXG4gICAgMHgxYzFjMzgyNCwgMHhhNmE2NTdmMSwgMHhiNGI0NzNjNywgMHhjNmM2OTc1MSxcbiAgICAweGU4ZThjYjIzLCAweGRkZGRhMTdjLCAweDc0NzRlODljLCAweDFmMWYzZTIxLFxuICAgIDB4NGI0Yjk2ZGQsIDB4YmRiZDYxZGMsIDB4OGI4YjBkODYsIDB4OGE4YTBmODUsXG4gICAgMHg3MDcwZTA5MCwgMHgzZTNlN2M0MiwgMHhiNWI1NzFjNCwgMHg2NjY2Y2NhYSxcbiAgICAweDQ4NDg5MGQ4LCAweDAzMDMwNjA1LCAweGY2ZjZmNzAxLCAweDBlMGUxYzEyLFxuICAgIDB4NjE2MWMyYTMsIDB4MzUzNTZhNWYsIDB4NTc1N2FlZjksIDB4YjliOTY5ZDAsXG4gICAgMHg4Njg2MTc5MSwgMHhjMWMxOTk1OCwgMHgxZDFkM2EyNywgMHg5ZTllMjdiOSxcbiAgICAweGUxZTFkOTM4LCAweGY4ZjhlYjEzLCAweDk4OTgyYmIzLCAweDExMTEyMjMzLFxuICAgIDB4Njk2OWQyYmIsIDB4ZDlkOWE5NzAsIDB4OGU4ZTA3ODksIDB4OTQ5NDMzYTcsXG4gICAgMHg5YjliMmRiNiwgMHgxZTFlM2MyMiwgMHg4Nzg3MTU5MiwgMHhlOWU5YzkyMCxcbiAgICAweGNlY2U4NzQ5LCAweDU1NTVhYWZmLCAweDI4Mjg1MDc4LCAweGRmZGZhNTdhLFxuICAgIDB4OGM4YzAzOGYsIDB4YTFhMTU5ZjgsIDB4ODk4OTA5ODAsIDB4MGQwZDFhMTcsXG4gICAgMHhiZmJmNjVkYSwgMHhlNmU2ZDczMSwgMHg0MjQyODRjNiwgMHg2ODY4ZDBiOCxcbiAgICAweDQxNDE4MmMzLCAweDk5OTkyOWIwLCAweDJkMmQ1YTc3LCAweDBmMGYxZTExLFxuICAgIDB4YjBiMDdiY2IsIDB4NTQ1NGE4ZmMsIDB4YmJiYjZkZDYsIDB4MTYxNjJjM2Fcbl07XG5cbnZhciBUMyA9IFtcbiAgICAweDYzYzZhNTYzLCAweDdjZjg4NDdjLCAweDc3ZWU5OTc3LCAweDdiZjY4ZDdiLFxuICAgIDB4ZjJmZjBkZjIsIDB4NmJkNmJkNmIsIDB4NmZkZWIxNmYsIDB4YzU5MTU0YzUsXG4gICAgMHgzMDYwNTAzMCwgMHgwMTAyMDMwMSwgMHg2N2NlYTk2NywgMHgyYjU2N2QyYixcbiAgICAweGZlZTcxOWZlLCAweGQ3YjU2MmQ3LCAweGFiNGRlNmFiLCAweDc2ZWM5YTc2LFxuICAgIDB4Y2E4ZjQ1Y2EsIDB4ODIxZjlkODIsIDB4Yzk4OTQwYzksIDB4N2RmYTg3N2QsXG4gICAgMHhmYWVmMTVmYSwgMHg1OWIyZWI1OSwgMHg0NzhlYzk0NywgMHhmMGZiMGJmMCxcbiAgICAweGFkNDFlY2FkLCAweGQ0YjM2N2Q0LCAweGEyNWZmZGEyLCAweGFmNDVlYWFmLFxuICAgIDB4OWMyM2JmOWMsIDB4YTQ1M2Y3YTQsIDB4NzJlNDk2NzIsIDB4YzA5YjViYzAsXG4gICAgMHhiNzc1YzJiNywgMHhmZGUxMWNmZCwgMHg5MzNkYWU5MywgMHgyNjRjNmEyNixcbiAgICAweDM2NmM1YTM2LCAweDNmN2U0MTNmLCAweGY3ZjUwMmY3LCAweGNjODM0ZmNjLFxuICAgIDB4MzQ2ODVjMzQsIDB4YTU1MWY0YTUsIDB4ZTVkMTM0ZTUsIDB4ZjFmOTA4ZjEsXG4gICAgMHg3MWUyOTM3MSwgMHhkOGFiNzNkOCwgMHgzMTYyNTMzMSwgMHgxNTJhM2YxNSxcbiAgICAweDA0MDgwYzA0LCAweGM3OTU1MmM3LCAweDIzNDY2NTIzLCAweGMzOWQ1ZWMzLFxuICAgIDB4MTgzMDI4MTgsIDB4OTYzN2ExOTYsIDB4MDUwYTBmMDUsIDB4OWEyZmI1OWEsXG4gICAgMHgwNzBlMDkwNywgMHgxMjI0MzYxMiwgMHg4MDFiOWI4MCwgMHhlMmRmM2RlMixcbiAgICAweGViY2QyNmViLCAweDI3NGU2OTI3LCAweGIyN2ZjZGIyLCAweDc1ZWE5Zjc1LFxuICAgIDB4MDkxMjFiMDksIDB4ODMxZDllODMsIDB4MmM1ODc0MmMsIDB4MWEzNDJlMWEsXG4gICAgMHgxYjM2MmQxYiwgMHg2ZWRjYjI2ZSwgMHg1YWI0ZWU1YSwgMHhhMDViZmJhMCxcbiAgICAweDUyYTRmNjUyLCAweDNiNzY0ZDNiLCAweGQ2Yjc2MWQ2LCAweGIzN2RjZWIzLFxuICAgIDB4Mjk1MjdiMjksIDB4ZTNkZDNlZTMsIDB4MmY1ZTcxMmYsIDB4ODQxMzk3ODQsXG4gICAgMHg1M2E2ZjU1MywgMHhkMWI5NjhkMSwgMHgwMDAwMDAwMCwgMHhlZGMxMmNlZCxcbiAgICAweDIwNDA2MDIwLCAweGZjZTMxZmZjLCAweGIxNzljOGIxLCAweDViYjZlZDViLFxuICAgIDB4NmFkNGJlNmEsIDB4Y2I4ZDQ2Y2IsIDB4YmU2N2Q5YmUsIDB4Mzk3MjRiMzksXG4gICAgMHg0YTk0ZGU0YSwgMHg0Yzk4ZDQ0YywgMHg1OGIwZTg1OCwgMHhjZjg1NGFjZixcbiAgICAweGQwYmI2YmQwLCAweGVmYzUyYWVmLCAweGFhNGZlNWFhLCAweGZiZWQxNmZiLFxuICAgIDB4NDM4NmM1NDMsIDB4NGQ5YWQ3NGQsIDB4MzM2NjU1MzMsIDB4ODUxMTk0ODUsXG4gICAgMHg0NThhY2Y0NSwgMHhmOWU5MTBmOSwgMHgwMjA0MDYwMiwgMHg3ZmZlODE3ZixcbiAgICAweDUwYTBmMDUwLCAweDNjNzg0NDNjLCAweDlmMjViYTlmLCAweGE4NGJlM2E4LFxuICAgIDB4NTFhMmYzNTEsIDB4YTM1ZGZlYTMsIDB4NDA4MGMwNDAsIDB4OGYwNThhOGYsXG4gICAgMHg5MjNmYWQ5MiwgMHg5ZDIxYmM5ZCwgMHgzODcwNDgzOCwgMHhmNWYxMDRmNSxcbiAgICAweGJjNjNkZmJjLCAweGI2NzdjMWI2LCAweGRhYWY3NWRhLCAweDIxNDI2MzIxLFxuICAgIDB4MTAyMDMwMTAsIDB4ZmZlNTFhZmYsIDB4ZjNmZDBlZjMsIDB4ZDJiZjZkZDIsXG4gICAgMHhjZDgxNGNjZCwgMHgwYzE4MTQwYywgMHgxMzI2MzUxMywgMHhlY2MzMmZlYyxcbiAgICAweDVmYmVlMTVmLCAweDk3MzVhMjk3LCAweDQ0ODhjYzQ0LCAweDE3MmUzOTE3LFxuICAgIDB4YzQ5MzU3YzQsIDB4YTc1NWYyYTcsIDB4N2VmYzgyN2UsIDB4M2Q3YTQ3M2QsXG4gICAgMHg2NGM4YWM2NCwgMHg1ZGJhZTc1ZCwgMHgxOTMyMmIxOSwgMHg3M2U2OTU3MyxcbiAgICAweDYwYzBhMDYwLCAweDgxMTk5ODgxLCAweDRmOWVkMTRmLCAweGRjYTM3ZmRjLFxuICAgIDB4MjI0NDY2MjIsIDB4MmE1NDdlMmEsIDB4OTAzYmFiOTAsIDB4ODgwYjgzODgsXG4gICAgMHg0NjhjY2E0NiwgMHhlZWM3MjllZSwgMHhiODZiZDNiOCwgMHgxNDI4M2MxNCxcbiAgICAweGRlYTc3OWRlLCAweDVlYmNlMjVlLCAweDBiMTYxZDBiLCAweGRiYWQ3NmRiLFxuICAgIDB4ZTBkYjNiZTAsIDB4MzI2NDU2MzIsIDB4M2E3NDRlM2EsIDB4MGExNDFlMGEsXG4gICAgMHg0OTkyZGI0OSwgMHgwNjBjMGEwNiwgMHgyNDQ4NmMyNCwgMHg1Y2I4ZTQ1YyxcbiAgICAweGMyOWY1ZGMyLCAweGQzYmQ2ZWQzLCAweGFjNDNlZmFjLCAweDYyYzRhNjYyLFxuICAgIDB4OTEzOWE4OTEsIDB4OTUzMWE0OTUsIDB4ZTRkMzM3ZTQsIDB4NzlmMjhiNzksXG4gICAgMHhlN2Q1MzJlNywgMHhjODhiNDNjOCwgMHgzNzZlNTkzNywgMHg2ZGRhYjc2ZCxcbiAgICAweDhkMDE4YzhkLCAweGQ1YjE2NGQ1LCAweDRlOWNkMjRlLCAweGE5NDllMGE5LFxuICAgIDB4NmNkOGI0NmMsIDB4NTZhY2ZhNTYsIDB4ZjRmMzA3ZjQsIDB4ZWFjZjI1ZWEsXG4gICAgMHg2NWNhYWY2NSwgMHg3YWY0OGU3YSwgMHhhZTQ3ZTlhZSwgMHgwODEwMTgwOCxcbiAgICAweGJhNmZkNWJhLCAweDc4ZjA4ODc4LCAweDI1NGE2ZjI1LCAweDJlNWM3MjJlLFxuICAgIDB4MWMzODI0MWMsIDB4YTY1N2YxYTYsIDB4YjQ3M2M3YjQsIDB4YzY5NzUxYzYsXG4gICAgMHhlOGNiMjNlOCwgMHhkZGExN2NkZCwgMHg3NGU4OWM3NCwgMHgxZjNlMjExZixcbiAgICAweDRiOTZkZDRiLCAweGJkNjFkY2JkLCAweDhiMGQ4NjhiLCAweDhhMGY4NThhLFxuICAgIDB4NzBlMDkwNzAsIDB4M2U3YzQyM2UsIDB4YjU3MWM0YjUsIDB4NjZjY2FhNjYsXG4gICAgMHg0ODkwZDg0OCwgMHgwMzA2MDUwMywgMHhmNmY3MDFmNiwgMHgwZTFjMTIwZSxcbiAgICAweDYxYzJhMzYxLCAweDM1NmE1ZjM1LCAweDU3YWVmOTU3LCAweGI5NjlkMGI5LFxuICAgIDB4ODYxNzkxODYsIDB4YzE5OTU4YzEsIDB4MWQzYTI3MWQsIDB4OWUyN2I5OWUsXG4gICAgMHhlMWQ5MzhlMSwgMHhmOGViMTNmOCwgMHg5ODJiYjM5OCwgMHgxMTIyMzMxMSxcbiAgICAweDY5ZDJiYjY5LCAweGQ5YTk3MGQ5LCAweDhlMDc4OThlLCAweDk0MzNhNzk0LFxuICAgIDB4OWIyZGI2OWIsIDB4MWUzYzIyMWUsIDB4ODcxNTkyODcsIDB4ZTljOTIwZTksXG4gICAgMHhjZTg3NDljZSwgMHg1NWFhZmY1NSwgMHgyODUwNzgyOCwgMHhkZmE1N2FkZixcbiAgICAweDhjMDM4ZjhjLCAweGExNTlmOGExLCAweDg5MDk4MDg5LCAweDBkMWExNzBkLFxuICAgIDB4YmY2NWRhYmYsIDB4ZTZkNzMxZTYsIDB4NDI4NGM2NDIsIDB4NjhkMGI4NjgsXG4gICAgMHg0MTgyYzM0MSwgMHg5OTI5YjA5OSwgMHgyZDVhNzcyZCwgMHgwZjFlMTEwZixcbiAgICAweGIwN2JjYmIwLCAweDU0YThmYzU0LCAweGJiNmRkNmJiLCAweDE2MmMzYTE2XG5dO1xuXG52YXIgVDQgPSBbXG4gICAgMHhjNmE1NjM2MywgMHhmODg0N2M3YywgMHhlZTk5Nzc3NywgMHhmNjhkN2I3YixcbiAgICAweGZmMGRmMmYyLCAweGQ2YmQ2YjZiLCAweGRlYjE2ZjZmLCAweDkxNTRjNWM1LFxuICAgIDB4NjA1MDMwMzAsIDB4MDIwMzAxMDEsIDB4Y2VhOTY3NjcsIDB4NTY3ZDJiMmIsXG4gICAgMHhlNzE5ZmVmZSwgMHhiNTYyZDdkNywgMHg0ZGU2YWJhYiwgMHhlYzlhNzY3NixcbiAgICAweDhmNDVjYWNhLCAweDFmOWQ4MjgyLCAweDg5NDBjOWM5LCAweGZhODc3ZDdkLFxuICAgIDB4ZWYxNWZhZmEsIDB4YjJlYjU5NTksIDB4OGVjOTQ3NDcsIDB4ZmIwYmYwZjAsXG4gICAgMHg0MWVjYWRhZCwgMHhiMzY3ZDRkNCwgMHg1ZmZkYTJhMiwgMHg0NWVhYWZhZixcbiAgICAweDIzYmY5YzljLCAweDUzZjdhNGE0LCAweGU0OTY3MjcyLCAweDliNWJjMGMwLFxuICAgIDB4NzVjMmI3YjcsIDB4ZTExY2ZkZmQsIDB4M2RhZTkzOTMsIDB4NGM2YTI2MjYsXG4gICAgMHg2YzVhMzYzNiwgMHg3ZTQxM2YzZiwgMHhmNTAyZjdmNywgMHg4MzRmY2NjYyxcbiAgICAweDY4NWMzNDM0LCAweDUxZjRhNWE1LCAweGQxMzRlNWU1LCAweGY5MDhmMWYxLFxuICAgIDB4ZTI5MzcxNzEsIDB4YWI3M2Q4ZDgsIDB4NjI1MzMxMzEsIDB4MmEzZjE1MTUsXG4gICAgMHgwODBjMDQwNCwgMHg5NTUyYzdjNywgMHg0NjY1MjMyMywgMHg5ZDVlYzNjMyxcbiAgICAweDMwMjgxODE4LCAweDM3YTE5Njk2LCAweDBhMGYwNTA1LCAweDJmYjU5YTlhLFxuICAgIDB4MGUwOTA3MDcsIDB4MjQzNjEyMTIsIDB4MWI5YjgwODAsIDB4ZGYzZGUyZTIsXG4gICAgMHhjZDI2ZWJlYiwgMHg0ZTY5MjcyNywgMHg3ZmNkYjJiMiwgMHhlYTlmNzU3NSxcbiAgICAweDEyMWIwOTA5LCAweDFkOWU4MzgzLCAweDU4NzQyYzJjLCAweDM0MmUxYTFhLFxuICAgIDB4MzYyZDFiMWIsIDB4ZGNiMjZlNmUsIDB4YjRlZTVhNWEsIDB4NWJmYmEwYTAsXG4gICAgMHhhNGY2NTI1MiwgMHg3NjRkM2IzYiwgMHhiNzYxZDZkNiwgMHg3ZGNlYjNiMyxcbiAgICAweDUyN2IyOTI5LCAweGRkM2VlM2UzLCAweDVlNzEyZjJmLCAweDEzOTc4NDg0LFxuICAgIDB4YTZmNTUzNTMsIDB4Yjk2OGQxZDEsIDB4MDAwMDAwMDAsIDB4YzEyY2VkZWQsXG4gICAgMHg0MDYwMjAyMCwgMHhlMzFmZmNmYywgMHg3OWM4YjFiMSwgMHhiNmVkNWI1YixcbiAgICAweGQ0YmU2YTZhLCAweDhkNDZjYmNiLCAweDY3ZDliZWJlLCAweDcyNGIzOTM5LFxuICAgIDB4OTRkZTRhNGEsIDB4OThkNDRjNGMsIDB4YjBlODU4NTgsIDB4ODU0YWNmY2YsXG4gICAgMHhiYjZiZDBkMCwgMHhjNTJhZWZlZiwgMHg0ZmU1YWFhYSwgMHhlZDE2ZmJmYixcbiAgICAweDg2YzU0MzQzLCAweDlhZDc0ZDRkLCAweDY2NTUzMzMzLCAweDExOTQ4NTg1LFxuICAgIDB4OGFjZjQ1NDUsIDB4ZTkxMGY5ZjksIDB4MDQwNjAyMDIsIDB4ZmU4MTdmN2YsXG4gICAgMHhhMGYwNTA1MCwgMHg3ODQ0M2MzYywgMHgyNWJhOWY5ZiwgMHg0YmUzYThhOCxcbiAgICAweGEyZjM1MTUxLCAweDVkZmVhM2EzLCAweDgwYzA0MDQwLCAweDA1OGE4ZjhmLFxuICAgIDB4M2ZhZDkyOTIsIDB4MjFiYzlkOWQsIDB4NzA0ODM4MzgsIDB4ZjEwNGY1ZjUsXG4gICAgMHg2M2RmYmNiYywgMHg3N2MxYjZiNiwgMHhhZjc1ZGFkYSwgMHg0MjYzMjEyMSxcbiAgICAweDIwMzAxMDEwLCAweGU1MWFmZmZmLCAweGZkMGVmM2YzLCAweGJmNmRkMmQyLFxuICAgIDB4ODE0Y2NkY2QsIDB4MTgxNDBjMGMsIDB4MjYzNTEzMTMsIDB4YzMyZmVjZWMsXG4gICAgMHhiZWUxNWY1ZiwgMHgzNWEyOTc5NywgMHg4OGNjNDQ0NCwgMHgyZTM5MTcxNyxcbiAgICAweDkzNTdjNGM0LCAweDU1ZjJhN2E3LCAweGZjODI3ZTdlLCAweDdhNDczZDNkLFxuICAgIDB4YzhhYzY0NjQsIDB4YmFlNzVkNWQsIDB4MzIyYjE5MTksIDB4ZTY5NTczNzMsXG4gICAgMHhjMGEwNjA2MCwgMHgxOTk4ODE4MSwgMHg5ZWQxNGY0ZiwgMHhhMzdmZGNkYyxcbiAgICAweDQ0NjYyMjIyLCAweDU0N2UyYTJhLCAweDNiYWI5MDkwLCAweDBiODM4ODg4LFxuICAgIDB4OGNjYTQ2NDYsIDB4YzcyOWVlZWUsIDB4NmJkM2I4YjgsIDB4MjgzYzE0MTQsXG4gICAgMHhhNzc5ZGVkZSwgMHhiY2UyNWU1ZSwgMHgxNjFkMGIwYiwgMHhhZDc2ZGJkYixcbiAgICAweGRiM2JlMGUwLCAweDY0NTYzMjMyLCAweDc0NGUzYTNhLCAweDE0MWUwYTBhLFxuICAgIDB4OTJkYjQ5NDksIDB4MGMwYTA2MDYsIDB4NDg2YzI0MjQsIDB4YjhlNDVjNWMsXG4gICAgMHg5ZjVkYzJjMiwgMHhiZDZlZDNkMywgMHg0M2VmYWNhYywgMHhjNGE2NjI2MixcbiAgICAweDM5YTg5MTkxLCAweDMxYTQ5NTk1LCAweGQzMzdlNGU0LCAweGYyOGI3OTc5LFxuICAgIDB4ZDUzMmU3ZTcsIDB4OGI0M2M4YzgsIDB4NmU1OTM3MzcsIDB4ZGFiNzZkNmQsXG4gICAgMHgwMThjOGQ4ZCwgMHhiMTY0ZDVkNSwgMHg5Y2QyNGU0ZSwgMHg0OWUwYTlhOSxcbiAgICAweGQ4YjQ2YzZjLCAweGFjZmE1NjU2LCAweGYzMDdmNGY0LCAweGNmMjVlYWVhLFxuICAgIDB4Y2FhZjY1NjUsIDB4ZjQ4ZTdhN2EsIDB4NDdlOWFlYWUsIDB4MTAxODA4MDgsXG4gICAgMHg2ZmQ1YmFiYSwgMHhmMDg4Nzg3OCwgMHg0YTZmMjUyNSwgMHg1YzcyMmUyZSxcbiAgICAweDM4MjQxYzFjLCAweDU3ZjFhNmE2LCAweDczYzdiNGI0LCAweDk3NTFjNmM2LFxuICAgIDB4Y2IyM2U4ZTgsIDB4YTE3Y2RkZGQsIDB4ZTg5Yzc0NzQsIDB4M2UyMTFmMWYsXG4gICAgMHg5NmRkNGI0YiwgMHg2MWRjYmRiZCwgMHgwZDg2OGI4YiwgMHgwZjg1OGE4YSxcbiAgICAweGUwOTA3MDcwLCAweDdjNDIzZTNlLCAweDcxYzRiNWI1LCAweGNjYWE2NjY2LFxuICAgIDB4OTBkODQ4NDgsIDB4MDYwNTAzMDMsIDB4ZjcwMWY2ZjYsIDB4MWMxMjBlMGUsXG4gICAgMHhjMmEzNjE2MSwgMHg2YTVmMzUzNSwgMHhhZWY5NTc1NywgMHg2OWQwYjliOSxcbiAgICAweDE3OTE4Njg2LCAweDk5NThjMWMxLCAweDNhMjcxZDFkLCAweDI3Yjk5ZTllLFxuICAgIDB4ZDkzOGUxZTEsIDB4ZWIxM2Y4ZjgsIDB4MmJiMzk4OTgsIDB4MjIzMzExMTEsXG4gICAgMHhkMmJiNjk2OSwgMHhhOTcwZDlkOSwgMHgwNzg5OGU4ZSwgMHgzM2E3OTQ5NCxcbiAgICAweDJkYjY5YjliLCAweDNjMjIxZTFlLCAweDE1OTI4Nzg3LCAweGM5MjBlOWU5LFxuICAgIDB4ODc0OWNlY2UsIDB4YWFmZjU1NTUsIDB4NTA3ODI4MjgsIDB4YTU3YWRmZGYsXG4gICAgMHgwMzhmOGM4YywgMHg1OWY4YTFhMSwgMHgwOTgwODk4OSwgMHgxYTE3MGQwZCxcbiAgICAweDY1ZGFiZmJmLCAweGQ3MzFlNmU2LCAweDg0YzY0MjQyLCAweGQwYjg2ODY4LFxuICAgIDB4ODJjMzQxNDEsIDB4MjliMDk5OTksIDB4NWE3NzJkMmQsIDB4MWUxMTBmMGYsXG4gICAgMHg3YmNiYjBiMCwgMHhhOGZjNTQ1NCwgMHg2ZGQ2YmJiYiwgMHgyYzNhMTYxNlxuXTtcblxuZnVuY3Rpb24gQjAoeCkge1xuICByZXR1cm4gKHggJiAyNTUpO1xufVxuXG5mdW5jdGlvbiBCMSh4KSB7XG4gIHJldHVybiAoKHggPj4gOCkgJiAyNTUpO1xufVxuXG5mdW5jdGlvbiBCMih4KSB7XG4gIHJldHVybiAoKHggPj4gMTYpICYgMjU1KTtcbn1cblxuZnVuY3Rpb24gQjMoeCkge1xuICByZXR1cm4gKCh4ID4+IDI0KSAmIDI1NSk7XG59XG5cbmZ1bmN0aW9uIEYxKHgwLCB4MSwgeDIsIHgzKSB7XG4gIHJldHVybiBCMShUMVt4MCAmIDI1NV0pIHwgKEIxKFQxWyh4MSA+PiA4KSAmIDI1NV0pIDw8IDgpIHwgKEIxKFQxWyh4MiA+PiAxNikgJiAyNTVdKSA8PCAxNikgfCAoQjEoVDFbeDMgPj4+IDI0XSkgPDxcbiAgICAyNCk7XG59XG5cbmZ1bmN0aW9uIHBhY2tCeXRlcyhvY3RldHMpIHtcbiAgdmFyIGksIGo7XG4gIHZhciBsZW4gPSBvY3RldHMubGVuZ3RoO1xuICB2YXIgYiA9IG5ldyBBcnJheShsZW4gLyA0KTtcblxuICBpZiAoIW9jdGV0cyB8fCBsZW4gJSA0KSByZXR1cm47XG5cbiAgZm9yIChpID0gMCwgaiA9IDA7IGogPCBsZW47IGogKz0gNClcbiAgICBiW2krK10gPSBvY3RldHNbal0gfCAob2N0ZXRzW2ogKyAxXSA8PCA4KSB8IChvY3RldHNbaiArIDJdIDw8IDE2KSB8IChvY3RldHNbaiArIDNdIDw8IDI0KTtcblxuICByZXR1cm4gYjtcbn1cblxuZnVuY3Rpb24gdW5wYWNrQnl0ZXMocGFja2VkKSB7XG4gIHZhciBqO1xuICB2YXIgaSA9IDAsXG4gICAgbCA9IHBhY2tlZC5sZW5ndGg7XG4gIHZhciByID0gbmV3IEFycmF5KGwgKiA0KTtcblxuICBmb3IgKGogPSAwOyBqIDwgbDsgaisrKSB7XG4gICAgcltpKytdID0gQjAocGFja2VkW2pdKTtcbiAgICByW2krK10gPSBCMShwYWNrZWRbal0pO1xuICAgIHJbaSsrXSA9IEIyKHBhY2tlZFtqXSk7XG4gICAgcltpKytdID0gQjMocGFja2VkW2pdKTtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbnZhciBtYXhrYyA9IDg7XG52YXIgbWF4cmsgPSAxNDtcblxuZnVuY3Rpb24ga2V5RXhwYW5zaW9uKGtleSkge1xuICB2YXIga2MsIGksIGosIHIsIHQ7XG4gIHZhciByb3VuZHM7XG4gIHZhciBrZXlTY2hlZCA9IG5ldyBBcnJheShtYXhyayArIDEpO1xuICB2YXIga2V5bGVuID0ga2V5Lmxlbmd0aDtcbiAgdmFyIGsgPSBuZXcgQXJyYXkobWF4a2MpO1xuICB2YXIgdGsgPSBuZXcgQXJyYXkobWF4a2MpO1xuICB2YXIgcmNvbnBvaW50ZXIgPSAwO1xuXG4gIGlmIChrZXlsZW4gPT0gMTYpIHtcbiAgICByb3VuZHMgPSAxMDtcbiAgICBrYyA9IDQ7XG4gIH0gZWxzZSBpZiAoa2V5bGVuID09IDI0KSB7XG4gICAgcm91bmRzID0gMTI7XG4gICAga2MgPSA2O1xuICB9IGVsc2UgaWYgKGtleWxlbiA9PSAzMikge1xuICAgIHJvdW5kcyA9IDE0O1xuICAgIGtjID0gODtcbiAgfSBlbHNlIHtcbiAgICB1dGlsLnByaW50X2Vycm9yKCdhZXMuanM6IEludmFsaWQga2V5LWxlbmd0aCBmb3IgQUVTIGtleTonICsga2V5bGVuKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgbWF4cmsgKyAxOyBpKyspIGtleVNjaGVkW2ldID0gbmV3IEFycmF5KDQpO1xuXG4gIGZvciAoaSA9IDAsIGogPSAwOyBqIDwga2V5bGVuOyBqKyssIGkgKz0gNClcbiAgICBrW2pdID0ga2V5LmNoYXJDb2RlQXQoaSkgfCAoa2V5LmNoYXJDb2RlQXQoaSArIDEpIDw8IDgpIHwgKGtleS5jaGFyQ29kZUF0KGkgKyAyKSA8PCAxNikgfCAoa2V5LmNoYXJDb2RlQXQoaSArIDMpIDw8XG4gICAgICAyNCk7XG5cbiAgZm9yIChqID0ga2MgLSAxOyBqID49IDA7IGotLSkgdGtbal0gPSBrW2pdO1xuXG4gIHIgPSAwO1xuICB0ID0gMDtcbiAgZm9yIChqID0gMDtcbiAgKGogPCBrYykgJiYgKHIgPCByb3VuZHMgKyAxKTspIHtcbiAgICBmb3IgKDtcbiAgICAoaiA8IGtjKSAmJiAodCA8IDQpOyBqKyssIHQrKykge1xuICAgICAga2V5U2NoZWRbcl1bdF0gPSB0a1tqXTtcbiAgICB9XG4gICAgaWYgKHQgPT0gNCkge1xuICAgICAgcisrO1xuICAgICAgdCA9IDA7XG4gICAgfVxuICB9XG5cbiAgd2hpbGUgKHIgPCByb3VuZHMgKyAxKSB7XG4gICAgdmFyIHRlbXAgPSB0a1trYyAtIDFdO1xuXG4gICAgdGtbMF0gXj0gU1tCMSh0ZW1wKV0gfCAoU1tCMih0ZW1wKV0gPDwgOCkgfCAoU1tCMyh0ZW1wKV0gPDwgMTYpIHwgKFNbQjAodGVtcCldIDw8IDI0KTtcbiAgICB0a1swXSBePSBSY29uW3Jjb25wb2ludGVyKytdO1xuXG4gICAgaWYgKGtjICE9IDgpIHtcbiAgICAgIGZvciAoaiA9IDE7IGogPCBrYzsgaisrKSB0a1tqXSBePSB0a1tqIC0gMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoaiA9IDE7IGogPCBrYyAvIDI7IGorKykgdGtbal0gXj0gdGtbaiAtIDFdO1xuXG4gICAgICB0ZW1wID0gdGtba2MgLyAyIC0gMV07XG4gICAgICB0a1trYyAvIDJdIF49IFNbQjAodGVtcCldIHwgKFNbQjEodGVtcCldIDw8IDgpIHwgKFNbQjIodGVtcCldIDw8IDE2KSB8IChTW0IzKHRlbXApXSA8PCAyNCk7XG5cbiAgICAgIGZvciAoaiA9IGtjIC8gMiArIDE7IGogPCBrYzsgaisrKSB0a1tqXSBePSB0a1tqIC0gMV07XG4gICAgfVxuXG4gICAgZm9yIChqID0gMDtcbiAgICAoaiA8IGtjKSAmJiAociA8IHJvdW5kcyArIDEpOykge1xuICAgICAgZm9yICg7XG4gICAgICAoaiA8IGtjKSAmJiAodCA8IDQpOyBqKyssIHQrKykge1xuICAgICAgICBrZXlTY2hlZFtyXVt0XSA9IHRrW2pdO1xuICAgICAgfVxuICAgICAgaWYgKHQgPT0gNCkge1xuICAgICAgICByKys7XG4gICAgICAgIHQgPSAwO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICB0aGlzLnJvdW5kcyA9IHJvdW5kcztcbiAgdGhpcy5yayA9IGtleVNjaGVkO1xuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gQUVTZW5jcnlwdChibG9jaywgY3R4KSB7XG4gIHZhciByO1xuICB2YXIgdDAsIHQxLCB0MiwgdDM7XG5cbiAgdmFyIGIgPSBwYWNrQnl0ZXMoYmxvY2spO1xuICB2YXIgcm91bmRzID0gY3R4LnJvdW5kcztcbiAgdmFyIGIwID0gYlswXTtcbiAgdmFyIGIxID0gYlsxXTtcbiAgdmFyIGIyID0gYlsyXTtcbiAgdmFyIGIzID0gYlszXTtcblxuICBmb3IgKHIgPSAwOyByIDwgcm91bmRzIC0gMTsgcisrKSB7XG4gICAgdDAgPSBiMCBeIGN0eC5ya1tyXVswXTtcbiAgICB0MSA9IGIxIF4gY3R4LnJrW3JdWzFdO1xuICAgIHQyID0gYjIgXiBjdHgucmtbcl1bMl07XG4gICAgdDMgPSBiMyBeIGN0eC5ya1tyXVszXTtcblxuICAgIGIwID0gVDFbdDAgJiAyNTVdIF4gVDJbKHQxID4+IDgpICYgMjU1XSBeIFQzWyh0MiA+PiAxNikgJiAyNTVdIF4gVDRbdDMgPj4+IDI0XTtcbiAgICBiMSA9IFQxW3QxICYgMjU1XSBeIFQyWyh0MiA+PiA4KSAmIDI1NV0gXiBUM1sodDMgPj4gMTYpICYgMjU1XSBeIFQ0W3QwID4+PiAyNF07XG4gICAgYjIgPSBUMVt0MiAmIDI1NV0gXiBUMlsodDMgPj4gOCkgJiAyNTVdIF4gVDNbKHQwID4+IDE2KSAmIDI1NV0gXiBUNFt0MSA+Pj4gMjRdO1xuICAgIGIzID0gVDFbdDMgJiAyNTVdIF4gVDJbKHQwID4+IDgpICYgMjU1XSBeIFQzWyh0MSA+PiAxNikgJiAyNTVdIF4gVDRbdDIgPj4+IDI0XTtcbiAgfVxuXG4gIC8vIGxhc3Qgcm91bmQgaXMgc3BlY2lhbFxuICByID0gcm91bmRzIC0gMTtcblxuICB0MCA9IGIwIF4gY3R4LnJrW3JdWzBdO1xuICB0MSA9IGIxIF4gY3R4LnJrW3JdWzFdO1xuICB0MiA9IGIyIF4gY3R4LnJrW3JdWzJdO1xuICB0MyA9IGIzIF4gY3R4LnJrW3JdWzNdO1xuXG4gIGJbMF0gPSBGMSh0MCwgdDEsIHQyLCB0MykgXiBjdHgucmtbcm91bmRzXVswXTtcbiAgYlsxXSA9IEYxKHQxLCB0MiwgdDMsIHQwKSBeIGN0eC5ya1tyb3VuZHNdWzFdO1xuICBiWzJdID0gRjEodDIsIHQzLCB0MCwgdDEpIF4gY3R4LnJrW3JvdW5kc11bMl07XG4gIGJbM10gPSBGMSh0MywgdDAsIHQxLCB0MikgXiBjdHgucmtbcm91bmRzXVszXTtcblxuICByZXR1cm4gdW5wYWNrQnl0ZXMoYik7XG59XG5cbmZ1bmN0aW9uIG1ha2VDbGFzcyhsZW5ndGgpIHtcblxuICB2YXIgYyA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHRoaXMua2V5ID0ga2V5RXhwYW5zaW9uKGtleSk7XG5cbiAgICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaykge1xuICAgICAgcmV0dXJuIEFFU2VuY3J5cHQoYmxvY2ssIHRoaXMua2V5KTtcbiAgICB9XG4gIH1cblxuICBjLmJsb2NrU2l6ZSA9IGMucHJvdG90eXBlLmJsb2NrU2l6ZSA9IDE2O1xuICBjLmtleVNpemUgPSBjLnByb3RvdHlwZS5rZXlTaXplID0gbGVuZ3RoIC8gODtcblxuICByZXR1cm4gYztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7fVxuXG52YXIgdHlwZXMgPSBbMTI4LCAxOTIsIDI1Nl07XG5cbmZvciAodmFyIGkgaW4gdHlwZXMpIHtcbiAgbW9kdWxlLmV4cG9ydHNbdHlwZXNbaV1dID0gbWFrZUNsYXNzKHR5cGVzW2ldKTtcbn1cbiIsIi8qIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSCBcbiAqIFxuICogT3JpZ2luYWxseSB3cml0dGVuIGJ5IG5rbGVpbiBzb2Z0d2FyZSAobmtsZWluLmNvbSlcbiAqL1xuXG4vKiBcbiAqIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gYmFzZWQgb24gQnJ1Y2UgU2NobmVpZXIncyByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24uXG4gKlxuICpcbiAqIFRoZSBjb25zdHJ1Y3RvciBkb2Vzbid0IGRvIG11Y2ggb2YgYW55dGhpbmcuICBJdCdzIGp1c3QgaGVyZVxuICogc28gd2UgY2FuIHN0YXJ0IGRlZmluaW5nIHByb3BlcnRpZXMgYW5kIG1ldGhvZHMgYW5kIHN1Y2guXG4gKi9cbmZ1bmN0aW9uIEJsb3dmaXNoKCkge307XG5cbi8qXG4gKiBEZWNsYXJlIHRoZSBibG9jayBzaXplIHNvIHRoYXQgcHJvdG9jb2xzIGtub3cgd2hhdCBzaXplXG4gKiBJbml0aWFsaXphdGlvbiBWZWN0b3IgKElWKSB0aGV5IHdpbGwgbmVlZC5cbiAqL1xuQmxvd2Zpc2gucHJvdG90eXBlLkJMT0NLU0laRSA9IDg7XG5cbi8qXG4gKiBUaGVzZSBhcmUgdGhlIGRlZmF1bHQgU0JPWEVTLlxuICovXG5CbG93ZmlzaC5wcm90b3R5cGUuU0JPWEVTID0gW1xuICBbXG4gICAgICAweGQxMzEwYmE2LCAweDk4ZGZiNWFjLCAweDJmZmQ3MmRiLCAweGQwMWFkZmI3LCAweGI4ZTFhZmVkLCAweDZhMjY3ZTk2LFxuICAgICAgMHhiYTdjOTA0NSwgMHhmMTJjN2Y5OSwgMHgyNGExOTk0NywgMHhiMzkxNmNmNywgMHgwODAxZjJlMiwgMHg4NThlZmMxNixcbiAgICAgIDB4NjM2OTIwZDgsIDB4NzE1NzRlNjksIDB4YTQ1OGZlYTMsIDB4ZjQ5MzNkN2UsIDB4MGQ5NTc0OGYsIDB4NzI4ZWI2NTgsXG4gICAgICAweDcxOGJjZDU4LCAweDgyMTU0YWVlLCAweDdiNTRhNDFkLCAweGMyNWE1OWI1LCAweDljMzBkNTM5LCAweDJhZjI2MDEzLFxuICAgICAgMHhjNWQxYjAyMywgMHgyODYwODVmMCwgMHhjYTQxNzkxOCwgMHhiOGRiMzhlZiwgMHg4ZTc5ZGNiMCwgMHg2MDNhMTgwZSxcbiAgICAgIDB4NmM5ZTBlOGIsIDB4YjAxZThhM2UsIDB4ZDcxNTc3YzEsIDB4YmQzMTRiMjcsIDB4NzhhZjJmZGEsIDB4NTU2MDVjNjAsXG4gICAgICAweGU2NTUyNWYzLCAweGFhNTVhYjk0LCAweDU3NDg5ODYyLCAweDYzZTgxNDQwLCAweDU1Y2EzOTZhLCAweDJhYWIxMGI2LFxuICAgICAgMHhiNGNjNWMzNCwgMHgxMTQxZThjZSwgMHhhMTU0ODZhZiwgMHg3YzcyZTk5MywgMHhiM2VlMTQxMSwgMHg2MzZmYmMyYSxcbiAgICAgIDB4MmJhOWM1NWQsIDB4NzQxODMxZjYsIDB4Y2U1YzNlMTYsIDB4OWI4NzkzMWUsIDB4YWZkNmJhMzMsIDB4NmMyNGNmNWMsXG4gICAgICAweDdhMzI1MzgxLCAweDI4OTU4Njc3LCAweDNiOGY0ODk4LCAweDZiNGJiOWFmLCAweGM0YmZlODFiLCAweDY2MjgyMTkzLFxuICAgICAgMHg2MWQ4MDljYywgMHhmYjIxYTk5MSwgMHg0ODdjYWM2MCwgMHg1ZGVjODAzMiwgMHhlZjg0NWQ1ZCwgMHhlOTg1NzViMSxcbiAgICAgIDB4ZGMyNjIzMDIsIDB4ZWI2NTFiODgsIDB4MjM4OTNlODEsIDB4ZDM5NmFjYzUsIDB4MGY2ZDZmZjMsIDB4ODNmNDQyMzksXG4gICAgICAweDJlMGI0NDgyLCAweGE0ODQyMDA0LCAweDY5YzhmMDRhLCAweDllMWY5YjVlLCAweDIxYzY2ODQyLCAweGY2ZTk2YzlhLFxuICAgICAgMHg2NzBjOWM2MSwgMHhhYmQzODhmMCwgMHg2YTUxYTBkMiwgMHhkODU0MmY2OCwgMHg5NjBmYTcyOCwgMHhhYjUxMzNhMyxcbiAgICAgIDB4NmVlZjBiNmMsIDB4MTM3YTNiZTQsIDB4YmEzYmYwNTAsIDB4N2VmYjJhOTgsIDB4YTFmMTY1MWQsIDB4MzlhZjAxNzYsXG4gICAgICAweDY2Y2E1OTNlLCAweDgyNDMwZTg4LCAweDhjZWU4NjE5LCAweDQ1NmY5ZmI0LCAweDdkODRhNWMzLCAweDNiOGI1ZWJlLFxuICAgICAgMHhlMDZmNzVkOCwgMHg4NWMxMjA3MywgMHg0MDFhNDQ5ZiwgMHg1NmMxNmFhNiwgMHg0ZWQzYWE2MiwgMHgzNjNmNzcwNixcbiAgICAgIDB4MWJmZWRmNzIsIDB4NDI5YjAyM2QsIDB4MzdkMGQ3MjQsIDB4ZDAwYTEyNDgsIDB4ZGIwZmVhZDMsIDB4NDlmMWMwOWIsXG4gICAgICAweDA3NTM3MmM5LCAweDgwOTkxYjdiLCAweDI1ZDQ3OWQ4LCAweGY2ZThkZWY3LCAweGUzZmU1MDFhLCAweGI2Nzk0YzNiLFxuICAgICAgMHg5NzZjZTBiZCwgMHgwNGMwMDZiYSwgMHhjMWE5NGZiNiwgMHg0MDlmNjBjNCwgMHg1ZTVjOWVjMiwgMHgxOTZhMjQ2MyxcbiAgICAgIDB4NjhmYjZmYWYsIDB4M2U2YzUzYjUsIDB4MTMzOWIyZWIsIDB4M2I1MmVjNmYsIDB4NmRmYzUxMWYsIDB4OWIzMDk1MmMsXG4gICAgICAweGNjODE0NTQ0LCAweGFmNWViZDA5LCAweGJlZTNkMDA0LCAweGRlMzM0YWZkLCAweDY2MGYyODA3LCAweDE5MmU0YmIzLFxuICAgICAgMHhjMGNiYTg1NywgMHg0NWM4NzQwZiwgMHhkMjBiNWYzOSwgMHhiOWQzZmJkYiwgMHg1NTc5YzBiZCwgMHgxYTYwMzIwYSxcbiAgICAgIDB4ZDZhMTAwYzYsIDB4NDAyYzcyNzksIDB4Njc5ZjI1ZmUsIDB4ZmIxZmEzY2MsIDB4OGVhNWU5ZjgsIDB4ZGIzMjIyZjgsXG4gICAgICAweDNjNzUxNmRmLCAweGZkNjE2YjE1LCAweDJmNTAxZWM4LCAweGFkMDU1MmFiLCAweDMyM2RiNWZhLCAweGZkMjM4NzYwLFxuICAgICAgMHg1MzMxN2I0OCwgMHgzZTAwZGY4MiwgMHg5ZTVjNTdiYiwgMHhjYTZmOGNhMCwgMHgxYTg3NTYyZSwgMHhkZjE3NjlkYixcbiAgICAgIDB4ZDU0MmE4ZjYsIDB4Mjg3ZWZmYzMsIDB4YWM2NzMyYzYsIDB4OGM0ZjU1NzMsIDB4Njk1YjI3YjAsIDB4YmJjYTU4YzgsXG4gICAgICAweGUxZmZhMzVkLCAweGI4ZjAxMWEwLCAweDEwZmEzZDk4LCAweGZkMjE4M2I4LCAweDRhZmNiNTZjLCAweDJkZDFkMzViLFxuICAgICAgMHg5YTUzZTQ3OSwgMHhiNmY4NDU2NSwgMHhkMjhlNDliYywgMHg0YmZiOTc5MCwgMHhlMWRkZjJkYSwgMHhhNGNiN2UzMyxcbiAgICAgIDB4NjJmYjEzNDEsIDB4Y2VlNGM2ZTgsIDB4ZWYyMGNhZGEsIDB4MzY3NzRjMDEsIDB4ZDA3ZTllZmUsIDB4MmJmMTFmYjQsXG4gICAgICAweDk1ZGJkYTRkLCAweGFlOTA5MTk4LCAweGVhYWQ4ZTcxLCAweDZiOTNkNWEwLCAweGQwOGVkMWQwLCAweGFmYzcyNWUwLFxuICAgICAgMHg4ZTNjNWIyZiwgMHg4ZTc1OTRiNywgMHg4ZmY2ZTJmYiwgMHhmMjEyMmI2NCwgMHg4ODg4YjgxMiwgMHg5MDBkZjAxYyxcbiAgICAgIDB4NGZhZDVlYTAsIDB4Njg4ZmMzMWMsIDB4ZDFjZmYxOTEsIDB4YjNhOGMxYWQsIDB4MmYyZjIyMTgsIDB4YmUwZTE3NzcsXG4gICAgICAweGVhNzUyZGZlLCAweDhiMDIxZmExLCAweGU1YTBjYzBmLCAweGI1NmY3NGU4LCAweDE4YWNmM2Q2LCAweGNlODllMjk5LFxuICAgICAgMHhiNGE4NGZlMCwgMHhmZDEzZTBiNywgMHg3Y2M0M2I4MSwgMHhkMmFkYThkOSwgMHgxNjVmYTI2NiwgMHg4MDk1NzcwNSxcbiAgICAgIDB4OTNjYzczMTQsIDB4MjExYTE0NzcsIDB4ZTZhZDIwNjUsIDB4NzdiNWZhODYsIDB4Yzc1NDQyZjUsIDB4ZmI5ZDM1Y2YsXG4gICAgICAweGViY2RhZjBjLCAweDdiM2U4OWEwLCAweGQ2NDExYmQzLCAweGFlMWU3ZTQ5LCAweDAwMjUwZTJkLCAweDIwNzFiMzVlLFxuICAgICAgMHgyMjY4MDBiYiwgMHg1N2I4ZTBhZiwgMHgyNDY0MzY5YiwgMHhmMDA5YjkxZSwgMHg1NTYzOTExZCwgMHg1OWRmYTZhYSxcbiAgICAgIDB4NzhjMTQzODksIDB4ZDk1YTUzN2YsIDB4MjA3ZDViYTIsIDB4MDJlNWI5YzUsIDB4ODMyNjAzNzYsIDB4NjI5NWNmYTksXG4gICAgICAweDExYzgxOTY4LCAweDRlNzM0YTQxLCAweGIzNDcyZGNhLCAweDdiMTRhOTRhLCAweDFiNTEwMDUyLCAweDlhNTMyOTE1LFxuICAgICAgMHhkNjBmNTczZiwgMHhiYzliYzZlNCwgMHgyYjYwYTQ3NiwgMHg4MWU2NzQwMCwgMHgwOGJhNmZiNSwgMHg1NzFiZTkxZixcbiAgICAgIDB4ZjI5NmVjNmIsIDB4MmEwZGQ5MTUsIDB4YjY2MzY1MjEsIDB4ZTdiOWY5YjYsIDB4ZmYzNDA1MmUsIDB4YzU4NTU2NjQsXG4gICAgICAweDUzYjAyZDVkLCAweGE5OWY4ZmExLCAweDA4YmE0Nzk5LCAweDZlODUwNzZhXG4gIF0sXG4gIFtcbiAgICAgIDB4NGI3YTcwZTksIDB4YjViMzI5NDQsIDB4ZGI3NTA5MmUsIDB4YzQxOTI2MjMsIDB4YWQ2ZWE2YjAsIDB4NDlhN2RmN2QsXG4gICAgICAweDljZWU2MGI4LCAweDhmZWRiMjY2LCAweGVjYWE4YzcxLCAweDY5OWExN2ZmLCAweDU2NjQ1MjZjLCAweGMyYjE5ZWUxLFxuICAgICAgMHgxOTM2MDJhNSwgMHg3NTA5NGMyOSwgMHhhMDU5MTM0MCwgMHhlNDE4M2EzZSwgMHgzZjU0OTg5YSwgMHg1YjQyOWQ2NSxcbiAgICAgIDB4NmI4ZmU0ZDYsIDB4OTlmNzNmZDYsIDB4YTFkMjljMDcsIDB4ZWZlODMwZjUsIDB4NGQyZDM4ZTYsIDB4ZjAyNTVkYzEsXG4gICAgICAweDRjZGQyMDg2LCAweDg0NzBlYjI2LCAweDYzODJlOWM2LCAweDAyMWVjYzVlLCAweDA5Njg2YjNmLCAweDNlYmFlZmM5LFxuICAgICAgMHgzYzk3MTgxNCwgMHg2YjZhNzBhMSwgMHg2ODdmMzU4NCwgMHg1MmEwZTI4NiwgMHhiNzljNTMwNSwgMHhhYTUwMDczNyxcbiAgICAgIDB4M2UwNzg0MWMsIDB4N2ZkZWFlNWMsIDB4OGU3ZDQ0ZWMsIDB4NTcxNmYyYjgsIDB4YjAzYWRhMzcsIDB4ZjA1MDBjMGQsXG4gICAgICAweGYwMWMxZjA0LCAweDAyMDBiM2ZmLCAweGFlMGNmNTFhLCAweDNjYjU3NGIyLCAweDI1ODM3YTU4LCAweGRjMDkyMWJkLFxuICAgICAgMHhkMTkxMTNmOSwgMHg3Y2E5MmZmNiwgMHg5NDMyNDc3MywgMHgyMmY1NDcwMSwgMHgzYWU1ZTU4MSwgMHgzN2MyZGFkYyxcbiAgICAgIDB4YzhiNTc2MzQsIDB4OWFmM2RkYTcsIDB4YTk0NDYxNDYsIDB4MGZkMDAzMGUsIDB4ZWNjOGM3M2UsIDB4YTQ3NTFlNDEsXG4gICAgICAweGUyMzhjZDk5LCAweDNiZWEwZTJmLCAweDMyODBiYmExLCAweDE4M2ViMzMxLCAweDRlNTQ4YjM4LCAweDRmNmRiOTA4LFxuICAgICAgMHg2ZjQyMGQwMywgMHhmNjBhMDRiZiwgMHgyY2I4MTI5MCwgMHgyNDk3N2M3OSwgMHg1Njc5YjA3MiwgMHhiY2FmODlhZixcbiAgICAgIDB4ZGU5YTc3MWYsIDB4ZDk5MzA4MTAsIDB4YjM4YmFlMTIsIDB4ZGNjZjNmMmUsIDB4NTUxMjcyMWYsIDB4MmU2YjcxMjQsXG4gICAgICAweDUwMWFkZGU2LCAweDlmODRjZDg3LCAweDdhNTg0NzE4LCAweDc0MDhkYTE3LCAweGJjOWY5YWJjLCAweGU5NGI3ZDhjLFxuICAgICAgMHhlYzdhZWMzYSwgMHhkYjg1MWRmYSwgMHg2MzA5NDM2NiwgMHhjNDY0YzNkMiwgMHhlZjFjMTg0NywgMHgzMjE1ZDkwOCxcbiAgICAgIDB4ZGQ0MzNiMzcsIDB4MjRjMmJhMTYsIDB4MTJhMTRkNDMsIDB4MmE2NWM0NTEsIDB4NTA5NDAwMDIsIDB4MTMzYWU0ZGQsXG4gICAgICAweDcxZGZmODllLCAweDEwMzE0ZTU1LCAweDgxYWM3N2Q2LCAweDVmMTExOTliLCAweDA0MzU1NmYxLCAweGQ3YTNjNzZiLFxuICAgICAgMHgzYzExMTgzYiwgMHg1OTI0YTUwOSwgMHhmMjhmZTZlZCwgMHg5N2YxZmJmYSwgMHg5ZWJhYmYyYywgMHgxZTE1M2M2ZSxcbiAgICAgIDB4ODZlMzQ1NzAsIDB4ZWFlOTZmYjEsIDB4ODYwZTVlMGEsIDB4NWEzZTJhYjMsIDB4NzcxZmU3MWMsIDB4NGUzZDA2ZmEsXG4gICAgICAweDI5NjVkY2I5LCAweDk5ZTcxZDBmLCAweDgwM2U4OWQ2LCAweDUyNjZjODI1LCAweDJlNGNjOTc4LCAweDljMTBiMzZhLFxuICAgICAgMHhjNjE1MGViYSwgMHg5NGUyZWE3OCwgMHhhNWZjM2M1MywgMHgxZTBhMmRmNCwgMHhmMmY3NGVhNywgMHgzNjFkMmIzZCxcbiAgICAgIDB4MTkzOTI2MGYsIDB4MTljMjc5NjAsIDB4NTIyM2E3MDgsIDB4ZjcxMzEyYjYsIDB4ZWJhZGZlNmUsIDB4ZWFjMzFmNjYsXG4gICAgICAweGUzYmM0NTk1LCAweGE2N2JjODgzLCAweGIxN2YzN2QxLCAweDAxOGNmZjI4LCAweGMzMzJkZGVmLCAweGJlNmM1YWE1LFxuICAgICAgMHg2NTU4MjE4NSwgMHg2OGFiOTgwMiwgMHhlZWNlYTUwZiwgMHhkYjJmOTUzYiwgMHgyYWVmN2RhZCwgMHg1YjZlMmY4NCxcbiAgICAgIDB4MTUyMWI2MjgsIDB4MjkwNzYxNzAsIDB4ZWNkZDQ3NzUsIDB4NjE5ZjE1MTAsIDB4MTNjY2E4MzAsIDB4ZWI2MWJkOTYsXG4gICAgICAweDAzMzRmZTFlLCAweGFhMDM2M2NmLCAweGI1NzM1YzkwLCAweDRjNzBhMjM5LCAweGQ1OWU5ZTBiLCAweGNiYWFkZTE0LFxuICAgICAgMHhlZWNjODZiYywgMHg2MDYyMmNhNywgMHg5Y2FiNWNhYiwgMHhiMmYzODQ2ZSwgMHg2NDhiMWVhZiwgMHgxOWJkZjBjYSxcbiAgICAgIDB4YTAyMzY5YjksIDB4NjU1YWJiNTAsIDB4NDA2ODVhMzIsIDB4M2MyYWI0YjMsIDB4MzE5ZWU5ZDUsIDB4YzAyMWI4ZjcsXG4gICAgICAweDliNTQwYjE5LCAweDg3NWZhMDk5LCAweDk1Zjc5OTdlLCAweDYyM2Q3ZGE4LCAweGY4Mzc4ODlhLCAweDk3ZTMyZDc3LFxuICAgICAgMHgxMWVkOTM1ZiwgMHgxNjY4MTI4MSwgMHgwZTM1ODgyOSwgMHhjN2U2MWZkNiwgMHg5NmRlZGZhMSwgMHg3ODU4YmE5OSxcbiAgICAgIDB4NTdmNTg0YTUsIDB4MWIyMjcyNjMsIDB4OWI4M2MzZmYsIDB4MWFjMjQ2OTYsIDB4Y2RiMzBhZWIsIDB4NTMyZTMwNTQsXG4gICAgICAweDhmZDk0OGU0LCAweDZkYmMzMTI4LCAweDU4ZWJmMmVmLCAweDM0YzZmZmVhLCAweGZlMjhlZDYxLCAweGVlN2MzYzczLFxuICAgICAgMHg1ZDRhMTRkOSwgMHhlODY0YjdlMywgMHg0MjEwNWQxNCwgMHgyMDNlMTNlMCwgMHg0NWVlZTJiNiwgMHhhM2FhYWJlYSxcbiAgICAgIDB4ZGI2YzRmMTUsIDB4ZmFjYjRmZDAsIDB4Yzc0MmY0NDIsIDB4ZWY2YWJiYjUsIDB4NjU0ZjNiMWQsIDB4NDFjZDIxMDUsXG4gICAgICAweGQ4MWU3OTllLCAweDg2ODU0ZGM3LCAweGU0NGI0NzZhLCAweDNkODE2MjUwLCAweGNmNjJhMWYyLCAweDViOGQyNjQ2LFxuICAgICAgMHhmYzg4ODNhMCwgMHhjMWM3YjZhMywgMHg3ZjE1MjRjMywgMHg2OWNiNzQ5MiwgMHg0Nzg0OGEwYiwgMHg1NjkyYjI4NSxcbiAgICAgIDB4MDk1YmJmMDAsIDB4YWQxOTQ4OWQsIDB4MTQ2MmIxNzQsIDB4MjM4MjBlMDAsIDB4NTg0MjhkMmEsIDB4MGM1NWY1ZWEsXG4gICAgICAweDFkYWRmNDNlLCAweDIzM2Y3MDYxLCAweDMzNzJmMDkyLCAweDhkOTM3ZTQxLCAweGQ2NWZlY2YxLCAweDZjMjIzYmRiLFxuICAgICAgMHg3Y2RlMzc1OSwgMHhjYmVlNzQ2MCwgMHg0MDg1ZjJhNywgMHhjZTc3MzI2ZSwgMHhhNjA3ODA4NCwgMHgxOWY4NTA5ZSxcbiAgICAgIDB4ZThlZmQ4NTUsIDB4NjFkOTk3MzUsIDB4YTk2OWE3YWEsIDB4YzUwYzA2YzIsIDB4NWEwNGFiZmMsIDB4ODAwYmNhZGMsXG4gICAgICAweDllNDQ3YTJlLCAweGMzNDUzNDg0LCAweGZkZDU2NzA1LCAweDBlMWU5ZWM5LCAweGRiNzNkYmQzLCAweDEwNTU4OGNkLFxuICAgICAgMHg2NzVmZGE3OSwgMHhlMzY3NDM0MCwgMHhjNWM0MzQ2NSwgMHg3MTNlMzhkOCwgMHgzZDI4Zjg5ZSwgMHhmMTZkZmYyMCxcbiAgICAgIDB4MTUzZTIxZTcsIDB4OGZiMDNkNGEsIDB4ZTZlMzlmMmIsIDB4ZGI4M2FkZjdcbiAgXSxcbiAgW1xuICAgICAgMHhlOTNkNWE2OCwgMHg5NDgxNDBmNywgMHhmNjRjMjYxYywgMHg5NDY5MjkzNCwgMHg0MTE1MjBmNywgMHg3NjAyZDRmNyxcbiAgICAgIDB4YmNmNDZiMmUsIDB4ZDRhMjAwNjgsIDB4ZDQwODI0NzEsIDB4MzMyMGY0NmEsIDB4NDNiN2Q0YjcsIDB4NTAwMDYxYWYsXG4gICAgICAweDFlMzlmNjJlLCAweDk3MjQ0NTQ2LCAweDE0MjE0Zjc0LCAweGJmOGI4ODQwLCAweDRkOTVmYzFkLCAweDk2YjU5MWFmLFxuICAgICAgMHg3MGY0ZGRkMywgMHg2NmEwMmY0NSwgMHhiZmJjMDllYywgMHgwM2JkOTc4NSwgMHg3ZmFjNmRkMCwgMHgzMWNiODUwNCxcbiAgICAgIDB4OTZlYjI3YjMsIDB4NTVmZDM5NDEsIDB4ZGEyNTQ3ZTYsIDB4YWJjYTBhOWEsIDB4Mjg1MDc4MjUsIDB4NTMwNDI5ZjQsXG4gICAgICAweDBhMmM4NmRhLCAweGU5YjY2ZGZiLCAweDY4ZGMxNDYyLCAweGQ3NDg2OTAwLCAweDY4MGVjMGE0LCAweDI3YTE4ZGVlLFxuICAgICAgMHg0ZjNmZmVhMiwgMHhlODg3YWQ4YywgMHhiNThjZTAwNiwgMHg3YWY0ZDZiNiwgMHhhYWNlMWU3YywgMHhkMzM3NWZlYyxcbiAgICAgIDB4Y2U3OGEzOTksIDB4NDA2YjJhNDIsIDB4MjBmZTllMzUsIDB4ZDlmMzg1YjksIDB4ZWUzOWQ3YWIsIDB4M2IxMjRlOGIsXG4gICAgICAweDFkYzlmYWY3LCAweDRiNmQxODU2LCAweDI2YTM2NjMxLCAweGVhZTM5N2IyLCAweDNhNmVmYTc0LCAweGRkNWI0MzMyLFxuICAgICAgMHg2ODQxZTdmNywgMHhjYTc4MjBmYiwgMHhmYjBhZjU0ZSwgMHhkOGZlYjM5NywgMHg0NTQwNTZhYywgMHhiYTQ4OTUyNyxcbiAgICAgIDB4NTU1MzNhM2EsIDB4MjA4MzhkODcsIDB4ZmU2YmE5YjcsIDB4ZDA5Njk1NGIsIDB4NTVhODY3YmMsIDB4YTExNTlhNTgsXG4gICAgICAweGNjYTkyOTYzLCAweDk5ZTFkYjMzLCAweGE2MmE0YTU2LCAweDNmMzEyNWY5LCAweDVlZjQ3ZTFjLCAweDkwMjkzMTdjLFxuICAgICAgMHhmZGY4ZTgwMiwgMHgwNDI3MmY3MCwgMHg4MGJiMTU1YywgMHgwNTI4MmNlMywgMHg5NWMxMTU0OCwgMHhlNGM2NmQyMixcbiAgICAgIDB4NDhjMTEzM2YsIDB4YzcwZjg2ZGMsIDB4MDdmOWM5ZWUsIDB4NDEwNDFmMGYsIDB4NDA0Nzc5YTQsIDB4NWQ4ODZlMTcsXG4gICAgICAweDMyNWY1MWViLCAweGQ1OWJjMGQxLCAweGYyYmNjMThmLCAweDQxMTEzNTY0LCAweDI1N2I3ODM0LCAweDYwMmE5YzYwLFxuICAgICAgMHhkZmY4ZThhMywgMHgxZjYzNmMxYiwgMHgwZTEyYjRjMiwgMHgwMmUxMzI5ZSwgMHhhZjY2NGZkMSwgMHhjYWQxODExNSxcbiAgICAgIDB4NmIyMzk1ZTAsIDB4MzMzZTkyZTEsIDB4M2IyNDBiNjIsIDB4ZWViZWI5MjIsIDB4ODViMmEyMGUsIDB4ZTZiYTBkOTksXG4gICAgICAweGRlNzIwYzhjLCAweDJkYTJmNzI4LCAweGQwMTI3ODQ1LCAweDk1Yjc5NGZkLCAweDY0N2QwODYyLCAweGU3Y2NmNWYwLFxuICAgICAgMHg1NDQ5YTM2ZiwgMHg4NzdkNDhmYSwgMHhjMzlkZmQyNywgMHhmMzNlOGQxZSwgMHgwYTQ3NjM0MSwgMHg5OTJlZmY3NCxcbiAgICAgIDB4M2E2ZjZlYWIsIDB4ZjRmOGZkMzcsIDB4YTgxMmRjNjAsIDB4YTFlYmRkZjgsIDB4OTkxYmUxNGMsIDB4ZGI2ZTZiMGQsXG4gICAgICAweGM2N2I1NTEwLCAweDZkNjcyYzM3LCAweDI3NjVkNDNiLCAweGRjZDBlODA0LCAweGYxMjkwZGM3LCAweGNjMDBmZmEzLFxuICAgICAgMHhiNTM5MGY5MiwgMHg2OTBmZWQwYiwgMHg2NjdiOWZmYiwgMHhjZWRiN2Q5YywgMHhhMDkxY2YwYiwgMHhkOTE1NWVhMyxcbiAgICAgIDB4YmIxMzJmODgsIDB4NTE1YmFkMjQsIDB4N2I5NDc5YmYsIDB4NzYzYmQ2ZWIsIDB4MzczOTJlYjMsIDB4Y2MxMTU5NzksXG4gICAgICAweDgwMjZlMjk3LCAweGY0MmUzMTJkLCAweDY4NDJhZGE3LCAweGM2NmEyYjNiLCAweDEyNzU0Y2NjLCAweDc4MmVmMTFjLFxuICAgICAgMHg2YTEyNDIzNywgMHhiNzkyNTFlNywgMHgwNmExYmJlNiwgMHg0YmZiNjM1MCwgMHgxYTZiMTAxOCwgMHgxMWNhZWRmYSxcbiAgICAgIDB4M2QyNWJkZDgsIDB4ZTJlMWMzYzksIDB4NDQ0MjE2NTksIDB4MGExMjEzODYsIDB4ZDkwY2VjNmUsIDB4ZDVhYmVhMmEsXG4gICAgICAweDY0YWY2NzRlLCAweGRhODZhODVmLCAweGJlYmZlOTg4LCAweDY0ZTRjM2ZlLCAweDlkYmM4MDU3LCAweGYwZjdjMDg2LFxuICAgICAgMHg2MDc4N2JmOCwgMHg2MDAzNjA0ZCwgMHhkMWZkODM0NiwgMHhmNjM4MWZiMCwgMHg3NzQ1YWUwNCwgMHhkNzM2ZmNjYyxcbiAgICAgIDB4ODM0MjZiMzMsIDB4ZjAxZWFiNzEsIDB4YjA4MDQxODcsIDB4M2MwMDVlNWYsIDB4NzdhMDU3YmUsIDB4YmRlOGFlMjQsXG4gICAgICAweDU1NDY0Mjk5LCAweGJmNTgyZTYxLCAweDRlNThmNDhmLCAweGYyZGRmZGEyLCAweGY0NzRlZjM4LCAweDg3ODliZGMyLFxuICAgICAgMHg1MzY2ZjljMywgMHhjOGIzOGU3NCwgMHhiNDc1ZjI1NSwgMHg0NmZjZDliOSwgMHg3YWViMjY2MSwgMHg4YjFkZGY4NCxcbiAgICAgIDB4ODQ2YTBlNzksIDB4OTE1Zjk1ZTIsIDB4NDY2ZTU5OGUsIDB4MjBiNDU3NzAsIDB4OGNkNTU1OTEsIDB4YzkwMmRlNGMsXG4gICAgICAweGI5MGJhY2UxLCAweGJiODIwNWQwLCAweDExYTg2MjQ4LCAweDc1NzRhOTllLCAweGI3N2YxOWI2LCAweGUwYTlkYzA5LFxuICAgICAgMHg2NjJkMDlhMSwgMHhjNDMyNDYzMywgMHhlODVhMWYwMiwgMHgwOWYwYmU4YywgMHg0YTk5YTAyNSwgMHgxZDZlZmUxMCxcbiAgICAgIDB4MWFiOTNkMWQsIDB4MGJhNWE0ZGYsIDB4YTE4NmYyMGYsIDB4Mjg2OGYxNjksIDB4ZGNiN2RhODMsIDB4NTczOTA2ZmUsXG4gICAgICAweGExZTJjZTliLCAweDRmY2Q3ZjUyLCAweDUwMTE1ZTAxLCAweGE3MDY4M2ZhLCAweGEwMDJiNWM0LCAweDBkZTZkMDI3LFxuICAgICAgMHg5YWY4OGMyNywgMHg3NzNmODY0MSwgMHhjMzYwNGMwNiwgMHg2MWE4MDZiNSwgMHhmMDE3N2EyOCwgMHhjMGY1ODZlMCxcbiAgICAgIDB4MDA2MDU4YWEsIDB4MzBkYzdkNjIsIDB4MTFlNjllZDcsIDB4MjMzOGVhNjMsIDB4NTNjMmRkOTQsIDB4YzJjMjE2MzQsXG4gICAgICAweGJiY2JlZTU2LCAweDkwYmNiNmRlLCAweGViZmM3ZGExLCAweGNlNTkxZDc2LCAweDZmMDVlNDA5LCAweDRiN2MwMTg4LFxuICAgICAgMHgzOTcyMGEzZCwgMHg3YzkyN2MyNCwgMHg4NmUzNzI1ZiwgMHg3MjRkOWRiOSwgMHgxYWMxNWJiNCwgMHhkMzllYjhmYyxcbiAgICAgIDB4ZWQ1NDU1NzgsIDB4MDhmY2E1YjUsIDB4ZDgzZDdjZDMsIDB4NGRhZDBmYzQsIDB4MWU1MGVmNWUsIDB4YjE2MWU2ZjgsXG4gICAgICAweGEyODUxNGQ5LCAweDZjNTExMzNjLCAweDZmZDVjN2U3LCAweDU2ZTE0ZWM0LCAweDM2MmFiZmNlLCAweGRkYzZjODM3LFxuICAgICAgMHhkNzlhMzIzNCwgMHg5MjYzODIxMiwgMHg2NzBlZmE4ZSwgMHg0MDYwMDBlMFxuICBdLFxuICBbXG4gICAgICAweDNhMzljZTM3LCAweGQzZmFmNWNmLCAweGFiYzI3NzM3LCAweDVhYzUyZDFiLCAweDVjYjA2NzllLCAweDRmYTMzNzQyLFxuICAgICAgMHhkMzgyMjc0MCwgMHg5OWJjOWJiZSwgMHhkNTExOGU5ZCwgMHhiZjBmNzMxNSwgMHhkNjJkMWM3ZSwgMHhjNzAwYzQ3YixcbiAgICAgIDB4Yjc4YzFiNmIsIDB4MjFhMTkwNDUsIDB4YjI2ZWIxYmUsIDB4NmEzNjZlYjQsIDB4NTc0OGFiMmYsIDB4YmM5NDZlNzksXG4gICAgICAweGM2YTM3NmQyLCAweDY1NDljMmM4LCAweDUzMGZmOGVlLCAweDQ2OGRkZTdkLCAweGQ1NzMwYTFkLCAweDRjZDA0ZGM2LFxuICAgICAgMHgyOTM5YmJkYiwgMHhhOWJhNDY1MCwgMHhhYzk1MjZlOCwgMHhiZTVlZTMwNCwgMHhhMWZhZDVmMCwgMHg2YTJkNTE5YSxcbiAgICAgIDB4NjNlZjhjZTIsIDB4OWE4NmVlMjIsIDB4YzA4OWMyYjgsIDB4NDMyNDJlZjYsIDB4YTUxZTAzYWEsIDB4OWNmMmQwYTQsXG4gICAgICAweDgzYzA2MWJhLCAweDliZTk2YTRkLCAweDhmZTUxNTUwLCAweGJhNjQ1YmQ2LCAweDI4MjZhMmY5LCAweGE3M2EzYWUxLFxuICAgICAgMHg0YmE5OTU4NiwgMHhlZjU1NjJlOSwgMHhjNzJmZWZkMywgMHhmNzUyZjdkYSwgMHgzZjA0NmY2OSwgMHg3N2ZhMGE1OSxcbiAgICAgIDB4ODBlNGE5MTUsIDB4ODdiMDg2MDEsIDB4OWIwOWU2YWQsIDB4M2IzZWU1OTMsIDB4ZTk5MGZkNWEsIDB4OWUzNGQ3OTcsXG4gICAgICAweDJjZjBiN2Q5LCAweDAyMmI4YjUxLCAweDk2ZDVhYzNhLCAweDAxN2RhNjdkLCAweGQxY2YzZWQ2LCAweDdjN2QyZDI4LFxuICAgICAgMHgxZjlmMjVjZiwgMHhhZGYyYjg5YiwgMHg1YWQ2YjQ3MiwgMHg1YTg4ZjU0YywgMHhlMDI5YWM3MSwgMHhlMDE5YTVlNixcbiAgICAgIDB4NDdiMGFjZmQsIDB4ZWQ5M2ZhOWIsIDB4ZThkM2M0OGQsIDB4MjgzYjU3Y2MsIDB4ZjhkNTY2MjksIDB4NzkxMzJlMjgsXG4gICAgICAweDc4NWYwMTkxLCAweGVkNzU2MDU1LCAweGY3OTYwZTQ0LCAweGUzZDM1ZThjLCAweDE1MDU2ZGQ0LCAweDg4ZjQ2ZGJhLFxuICAgICAgMHgwM2ExNjEyNSwgMHgwNTY0ZjBiZCwgMHhjM2ViOWUxNSwgMHgzYzkwNTdhMiwgMHg5NzI3MWFlYywgMHhhOTNhMDcyYSxcbiAgICAgIDB4MWIzZjZkOWIsIDB4MWU2MzIxZjUsIDB4ZjU5YzY2ZmIsIDB4MjZkY2YzMTksIDB4NzUzM2Q5MjgsIDB4YjE1NWZkZjUsXG4gICAgICAweDAzNTYzNDgyLCAweDhhYmEzY2JiLCAweDI4NTE3NzExLCAweGMyMGFkOWY4LCAweGFiY2M1MTY3LCAweGNjYWQ5MjVmLFxuICAgICAgMHg0ZGU4MTc1MSwgMHgzODMwZGM4ZSwgMHgzNzlkNTg2MiwgMHg5MzIwZjk5MSwgMHhlYTdhOTBjMiwgMHhmYjNlN2JjZSxcbiAgICAgIDB4NTEyMWNlNjQsIDB4Nzc0ZmJlMzIsIDB4YThiNmUzN2UsIDB4YzMyOTNkNDYsIDB4NDhkZTUzNjksIDB4NjQxM2U2ODAsXG4gICAgICAweGEyYWUwODEwLCAweGRkNmRiMjI0LCAweDY5ODUyZGZkLCAweDA5MDcyMTY2LCAweGIzOWE0NjBhLCAweDY0NDVjMGRkLFxuICAgICAgMHg1ODZjZGVjZiwgMHgxYzIwYzhhZSwgMHg1YmJlZjdkZCwgMHgxYjU4OGQ0MCwgMHhjY2QyMDE3ZiwgMHg2YmI0ZTNiYixcbiAgICAgIDB4ZGRhMjZhN2UsIDB4M2E1OWZmNDUsIDB4M2UzNTBhNDQsIDB4YmNiNGNkZDUsIDB4NzJlYWNlYTgsIDB4ZmE2NDg0YmIsXG4gICAgICAweDhkNjYxMmFlLCAweGJmM2M2ZjQ3LCAweGQyOWJlNDYzLCAweDU0MmY1ZDllLCAweGFlYzI3NzFiLCAweGY2NGU2MzcwLFxuICAgICAgMHg3NDBlMGQ4ZCwgMHhlNzViMTM1NywgMHhmODcyMTY3MSwgMHhhZjUzN2Q1ZCwgMHg0MDQwY2IwOCwgMHg0ZWI0ZTJjYyxcbiAgICAgIDB4MzRkMjQ2NmEsIDB4MDExNWFmODQsIDB4ZTFiMDA0MjgsIDB4OTU5ODNhMWQsIDB4MDZiODlmYjQsIDB4Y2U2ZWEwNDgsXG4gICAgICAweDZmM2YzYjgyLCAweDM1MjBhYjgyLCAweDAxMWExZDRiLCAweDI3NzIyN2Y4LCAweDYxMTU2MGIxLCAweGU3OTMzZmRjLFxuICAgICAgMHhiYjNhNzkyYiwgMHgzNDQ1MjViZCwgMHhhMDg4MzllMSwgMHg1MWNlNzk0YiwgMHgyZjMyYzliNywgMHhhMDFmYmFjOSxcbiAgICAgIDB4ZTAxY2M4N2UsIDB4YmNjN2QxZjYsIDB4Y2YwMTExYzMsIDB4YTFlOGFhYzcsIDB4MWE5MDg3NDksIDB4ZDQ0ZmJkOWEsXG4gICAgICAweGQwZGFkZWNiLCAweGQ1MGFkYTM4LCAweDAzMzljMzJhLCAweGM2OTEzNjY3LCAweDhkZjkzMTdjLCAweGUwYjEyYjRmLFxuICAgICAgMHhmNzllNTliNywgMHg0M2Y1YmIzYSwgMHhmMmQ1MTlmZiwgMHgyN2Q5NDU5YywgMHhiZjk3MjIyYywgMHgxNWU2ZmMyYSxcbiAgICAgIDB4MGY5MWZjNzEsIDB4OWI5NDE1MjUsIDB4ZmFlNTkzNjEsIDB4Y2ViNjljZWIsIDB4YzJhODY0NTksIDB4MTJiYWE4ZDEsXG4gICAgICAweGI2YzEwNzVlLCAweGUzMDU2YTBjLCAweDEwZDI1MDY1LCAweGNiMDNhNDQyLCAweGUwZWM2ZTBlLCAweDE2OThkYjNiLFxuICAgICAgMHg0Yzk4YTBiZSwgMHgzMjc4ZTk2NCwgMHg5ZjFmOTUzMiwgMHhlMGQzOTJkZiwgMHhkM2EwMzQyYiwgMHg4OTcxZjIxZSxcbiAgICAgIDB4MWIwYTc0NDEsIDB4NGJhMzM0OGMsIDB4YzViZTcxMjAsIDB4YzM3NjMyZDgsIDB4ZGYzNTlmOGQsIDB4OWI5OTJmMmUsXG4gICAgICAweGU2MGI2ZjQ3LCAweDBmZTNmMTFkLCAweGU1NGNkYTU0LCAweDFlZGFkODkxLCAweGNlNjI3OWNmLCAweGNkM2U3ZTZmLFxuICAgICAgMHgxNjE4YjE2NiwgMHhmZDJjMWQwNSwgMHg4NDhmZDJjNSwgMHhmNmZiMjI5OSwgMHhmNTIzZjM1NywgMHhhNjMyNzYyMyxcbiAgICAgIDB4OTNhODM1MzEsIDB4NTZjY2NkMDIsIDB4YWNmMDgxNjIsIDB4NWE3NWViYjUsIDB4NmUxNjM2OTcsIDB4ODhkMjczY2MsXG4gICAgICAweGRlOTY2MjkyLCAweDgxYjk0OWQwLCAweDRjNTA5MDFiLCAweDcxYzY1NjE0LCAweGU2YzZjN2JkLCAweDMyN2ExNDBhLFxuICAgICAgMHg0NWUxZDAwNiwgMHhjM2YyN2I5YSwgMHhjOWFhNTNmZCwgMHg2MmE4MGYwMCwgMHhiYjI1YmZlMiwgMHgzNWJkZDJmNixcbiAgICAgIDB4NzExMjY5MDUsIDB4YjIwNDAyMjIsIDB4YjZjYmNmN2MsIDB4Y2Q3NjljMmIsIDB4NTMxMTNlYzAsIDB4MTY0MGUzZDMsXG4gICAgICAweDM4YWJiZDYwLCAweDI1NDdhZGYwLCAweGJhMzgyMDljLCAweGY3NDZjZTc2LCAweDc3YWZhMWM1LCAweDIwNzU2MDYwLFxuICAgICAgMHg4NWNiZmU0ZSwgMHg4YWU4OGRkOCwgMHg3YWFhZjliMCwgMHg0Y2Y5YWE3ZSwgMHgxOTQ4YzI1YywgMHgwMmZiOGE4YyxcbiAgICAgIDB4MDFjMzZhZTQsIDB4ZDZlYmUxZjksIDB4OTBkNGY4NjksIDB4YTY1Y2RlYTAsIDB4M2YwOTI1MmQsIDB4YzIwOGU2OWYsXG4gICAgICAweGI3NGU2MTMyLCAweGNlNzdlMjViLCAweDU3OGZkZmUzLCAweDNhYzM3MmU2XG4gIF1cbl07XG5cbi8vKlxuLy8qIFRoaXMgaXMgdGhlIGRlZmF1bHQgUEFSUkFZXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5QQVJSQVkgPSBbXG4gICAgMHgyNDNmNmE4OCwgMHg4NWEzMDhkMywgMHgxMzE5OGEyZSwgMHgwMzcwNzM0NCwgMHhhNDA5MzgyMiwgMHgyOTlmMzFkMCxcbiAgICAweDA4MmVmYTk4LCAweGVjNGU2Yzg5LCAweDQ1MjgyMWU2LCAweDM4ZDAxMzc3LCAweGJlNTQ2NmNmLCAweDM0ZTkwYzZjLFxuICAgIDB4YzBhYzI5YjcsIDB4Yzk3YzUwZGQsIDB4M2Y4NGQ1YjUsIDB4YjU0NzA5MTcsIDB4OTIxNmQ1ZDksIDB4ODk3OWZiMWJcbl07XG5cbi8vKlxuLy8qIFRoaXMgaXMgdGhlIG51bWJlciBvZiByb3VuZHMgdGhlIGNpcGhlciB3aWxsIGdvXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5OTiA9IDE2O1xuXG4vLypcbi8vKiBUaGlzIGZ1bmN0aW9uIGlzIG5lZWRlZCB0byBnZXQgcmlkIG9mIHByb2JsZW1zXG4vLyogd2l0aCB0aGUgaGlnaC1iaXQgZ2V0dGluZyBzZXQuICBJZiB3ZSBkb24ndCBkb1xuLy8qIHRoaXMsIHRoZW4gc29tZXRpbWVzICggYWEgJiAweDAwRkZGRkZGRkYgKSBpcyBub3Rcbi8vKiBlcXVhbCB0byAoIGJiICYgMHgwMEZGRkZGRkZGICkgZXZlbiB3aGVuIHRoZXlcbi8vKiBhZ3JlZSBiaXQtZm9yLWJpdCBmb3IgdGhlIGZpcnN0IDMyIGJpdHMuXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5fY2xlYW4gPSBmdW5jdGlvbih4eCkge1xuICBpZiAoeHggPCAwKSB7XG4gICAgdmFyIHl5ID0geHggJiAweDdGRkZGRkZGO1xuICAgIHh4ID0geXkgKyAweDgwMDAwMDAwO1xuICB9XG4gIHJldHVybiB4eDtcbn07XG5cbi8vKlxuLy8qIFRoaXMgaXMgdGhlIG1peGluZyBmdW5jdGlvbiB0aGF0IHVzZXMgdGhlIHNib3hlc1xuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuX0YgPSBmdW5jdGlvbih4eCkge1xuICB2YXIgYWE7XG4gIHZhciBiYjtcbiAgdmFyIGNjO1xuICB2YXIgZGQ7XG4gIHZhciB5eTtcblxuICBkZCA9IHh4ICYgMHgwMEZGO1xuICB4eCA+Pj49IDg7XG4gIGNjID0geHggJiAweDAwRkY7XG4gIHh4ID4+Pj0gODtcbiAgYmIgPSB4eCAmIDB4MDBGRjtcbiAgeHggPj4+PSA4O1xuICBhYSA9IHh4ICYgMHgwMEZGO1xuXG4gIHl5ID0gdGhpcy5zYm94ZXNbMF1bYWFdICsgdGhpcy5zYm94ZXNbMV1bYmJdO1xuICB5eSA9IHl5IF4gdGhpcy5zYm94ZXNbMl1bY2NdO1xuICB5eSA9IHl5ICsgdGhpcy5zYm94ZXNbM11bZGRdO1xuXG4gIHJldHVybiB5eTtcbn07XG5cbi8vKlxuLy8qIFRoaXMgbWV0aG9kIHRha2VzIGFuIGFycmF5IHdpdGggdHdvIHZhbHVlcywgbGVmdCBhbmQgcmlnaHRcbi8vKiBhbmQgZG9lcyBOTiByb3VuZHMgb2YgQmxvd2Zpc2ggb24gdGhlbS5cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLl9lbmNyeXB0X2Jsb2NrID0gZnVuY3Rpb24odmFscykge1xuICB2YXIgZGF0YUwgPSB2YWxzWzBdO1xuICB2YXIgZGF0YVIgPSB2YWxzWzFdO1xuXG4gIHZhciBpaTtcblxuICBmb3IgKGlpID0gMDsgaWkgPCB0aGlzLk5OOyArK2lpKSB7XG4gICAgZGF0YUwgPSBkYXRhTCBeIHRoaXMucGFycmF5W2lpXTtcbiAgICBkYXRhUiA9IHRoaXMuX0YoZGF0YUwpIF4gZGF0YVI7XG5cbiAgICB2YXIgdG1wID0gZGF0YUw7XG4gICAgZGF0YUwgPSBkYXRhUjtcbiAgICBkYXRhUiA9IHRtcDtcbiAgfVxuXG4gIGRhdGFMID0gZGF0YUwgXiB0aGlzLnBhcnJheVt0aGlzLk5OICsgMF07XG4gIGRhdGFSID0gZGF0YVIgXiB0aGlzLnBhcnJheVt0aGlzLk5OICsgMV07XG5cbiAgdmFsc1swXSA9IHRoaXMuX2NsZWFuKGRhdGFSKTtcbiAgdmFsc1sxXSA9IHRoaXMuX2NsZWFuKGRhdGFMKTtcbn07XG5cbi8vKlxuLy8qIFRoaXMgbWV0aG9kIHRha2VzIGEgdmVjdG9yIG9mIG51bWJlcnMgYW5kIHR1cm5zIHRoZW1cbi8vKiBpbnRvIGxvbmcgd29yZHMgc28gdGhhdCB0aGV5IGNhbiBiZSBwcm9jZXNzZWQgYnkgdGhlXG4vLyogcmVhbCBhbGdvcml0aG0uXG4vLypcbi8vKiBNYXliZSBJIHNob3VsZCBtYWtlIHRoZSByZWFsIGFsZ29yaXRobSBhYm92ZSB0YWtlIGEgdmVjdG9yXG4vLyogaW5zdGVhZC4gIFRoYXQgd2lsbCBpbnZvbHZlIG1vcmUgbG9vcGluZywgYnV0IGl0IHdvbid0IHJlcXVpcmVcbi8vKiB0aGUgRigpIG1ldGhvZCB0byBkZWNvbnN0cnVjdCB0aGUgdmVjdG9yLlxuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuZW5jcnlwdF9ibG9jayA9IGZ1bmN0aW9uKHZlY3Rvcikge1xuICB2YXIgaWk7XG4gIHZhciB2YWxzID0gWzAsIDBdO1xuICB2YXIgb2ZmID0gdGhpcy5CTE9DS1NJWkUgLyAyO1xuICBmb3IgKGlpID0gMDsgaWkgPCB0aGlzLkJMT0NLU0laRSAvIDI7ICsraWkpIHtcbiAgICB2YWxzWzBdID0gKHZhbHNbMF0gPDwgOCkgfCAodmVjdG9yW2lpICsgMF0gJiAweDAwRkYpO1xuICAgIHZhbHNbMV0gPSAodmFsc1sxXSA8PCA4KSB8ICh2ZWN0b3JbaWkgKyBvZmZdICYgMHgwMEZGKTtcbiAgfVxuXG4gIHRoaXMuX2VuY3J5cHRfYmxvY2sodmFscyk7XG5cbiAgdmFyIHJldCA9IFtdO1xuICBmb3IgKGlpID0gMDsgaWkgPCB0aGlzLkJMT0NLU0laRSAvIDI7ICsraWkpIHtcbiAgICByZXRbaWkgKyAwXSA9ICh2YWxzWzBdID4+PiAoMjQgLSA4ICogKGlpKSkgJiAweDAwRkYpO1xuICAgIHJldFtpaSArIG9mZl0gPSAodmFsc1sxXSA+Pj4gKDI0IC0gOCAqIChpaSkpICYgMHgwMEZGKTtcbiAgICAvLyB2YWxzWyAwIF0gPSAoIHZhbHNbIDAgXSA+Pj4gOCApO1xuICAgIC8vIHZhbHNbIDEgXSA9ICggdmFsc1sgMSBdID4+PiA4ICk7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufTtcblxuLy8qXG4vLyogVGhpcyBtZXRob2QgdGFrZXMgYW4gYXJyYXkgd2l0aCB0d28gdmFsdWVzLCBsZWZ0IGFuZCByaWdodFxuLy8qIGFuZCB1bmRvZXMgTk4gcm91bmRzIG9mIEJsb3dmaXNoIG9uIHRoZW0uXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5fZGVjcnlwdF9ibG9jayA9IGZ1bmN0aW9uKHZhbHMpIHtcbiAgdmFyIGRhdGFMID0gdmFsc1swXTtcbiAgdmFyIGRhdGFSID0gdmFsc1sxXTtcblxuICB2YXIgaWk7XG5cbiAgZm9yIChpaSA9IHRoaXMuTk4gKyAxOyBpaSA+IDE7IC0taWkpIHtcbiAgICBkYXRhTCA9IGRhdGFMIF4gdGhpcy5wYXJyYXlbaWldO1xuICAgIGRhdGFSID0gdGhpcy5fRihkYXRhTCkgXiBkYXRhUjtcblxuICAgIHZhciB0bXAgPSBkYXRhTDtcbiAgICBkYXRhTCA9IGRhdGFSO1xuICAgIGRhdGFSID0gdG1wO1xuICB9XG5cbiAgZGF0YUwgPSBkYXRhTCBeIHRoaXMucGFycmF5WzFdO1xuICBkYXRhUiA9IGRhdGFSIF4gdGhpcy5wYXJyYXlbMF07XG5cbiAgdmFsc1swXSA9IHRoaXMuX2NsZWFuKGRhdGFSKTtcbiAgdmFsc1sxXSA9IHRoaXMuX2NsZWFuKGRhdGFMKTtcbn07XG5cbi8vKlxuLy8qIFRoaXMgbWV0aG9kIHRha2VzIGEga2V5IGFycmF5IGFuZCBpbml0aWFsaXplcyB0aGVcbi8vKiBzYm94ZXMgYW5kIHBhcnJheSBmb3IgdGhpcyBlbmNyeXB0aW9uLlxuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKGtleSkge1xuICB2YXIgaWk7XG4gIHZhciBqaiA9IDA7XG5cbiAgdGhpcy5wYXJyYXkgPSBbXTtcbiAgZm9yIChpaSA9IDA7IGlpIDwgdGhpcy5OTiArIDI7ICsraWkpIHtcbiAgICB2YXIgZGF0YSA9IDB4MDAwMDAwMDA7XG4gICAgdmFyIGtrO1xuICAgIGZvciAoa2sgPSAwOyBrayA8IDQ7ICsra2spIHtcbiAgICAgIGRhdGEgPSAoZGF0YSA8PCA4KSB8IChrZXlbampdICYgMHgwMEZGKTtcbiAgICAgIGlmICgrK2pqID49IGtleS5sZW5ndGgpIHtcbiAgICAgICAgamogPSAwO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnBhcnJheVtpaV0gPSB0aGlzLlBBUlJBWVtpaV0gXiBkYXRhO1xuICB9XG5cbiAgdGhpcy5zYm94ZXMgPSBbXTtcbiAgZm9yIChpaSA9IDA7IGlpIDwgNDsgKytpaSkge1xuICAgIHRoaXMuc2JveGVzW2lpXSA9IFtdO1xuICAgIGZvciAoamogPSAwOyBqaiA8IDI1NjsgKytqaikge1xuICAgICAgdGhpcy5zYm94ZXNbaWldW2pqXSA9IHRoaXMuU0JPWEVTW2lpXVtqal07XG4gICAgfVxuICB9XG5cbiAgdmFyIHZhbHMgPSBbMHgwMDAwMDAwMCwgMHgwMDAwMDAwMF07XG5cbiAgZm9yIChpaSA9IDA7IGlpIDwgdGhpcy5OTiArIDI7IGlpICs9IDIpIHtcbiAgICB0aGlzLl9lbmNyeXB0X2Jsb2NrKHZhbHMpO1xuICAgIHRoaXMucGFycmF5W2lpICsgMF0gPSB2YWxzWzBdO1xuICAgIHRoaXMucGFycmF5W2lpICsgMV0gPSB2YWxzWzFdO1xuICB9XG5cbiAgZm9yIChpaSA9IDA7IGlpIDwgNDsgKytpaSkge1xuICAgIGZvciAoamogPSAwOyBqaiA8IDI1NjsgamogKz0gMikge1xuICAgICAgdGhpcy5fZW5jcnlwdF9ibG9jayh2YWxzKTtcbiAgICAgIHRoaXMuc2JveGVzW2lpXVtqaiArIDBdID0gdmFsc1swXTtcbiAgICAgIHRoaXMuc2JveGVzW2lpXVtqaiArIDFdID0gdmFsc1sxXTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbmZ1bmN0aW9uIEJGZW5jcnlwdChibG9jaywga2V5KSB7XG4gIHZhciBiZiA9IG5ldyBCbG93ZmlzaCgpO1xuICBiZi5pbml0KHV0aWwuc3RyMmJpbihrZXkpKTtcbiAgcmV0dXJuIGJmLmVuY3J5cHRfYmxvY2soYmxvY2spO1xufVxuXG5mdW5jdGlvbiBCRihrZXkpIHtcbiAgdGhpcy5iZiA9IG5ldyBCbG93ZmlzaCgpO1xuICB0aGlzLmJmLmluaXQodXRpbC5zdHIyYmluKGtleSkpO1xuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG4gICAgcmV0dXJuIHRoaXMuYmYuZW5jcnlwdF9ibG9jayhibG9jayk7XG4gIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IEJGO1xubW9kdWxlLmV4cG9ydHMua2V5U2l6ZSA9IEJGLnByb3RvdHlwZS5rZXlTaXplID0gMTY7XG5tb2R1bGUuZXhwb3J0cy5ibG9ja1NpemUgPSBCRi5wcm90b3R5cGUuYmxvY2tTaXplID0gMTY7XG4iLCIvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZVxuLy8gbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLlxuXG4vLyBDb3B5cmlnaHQgMjAxMCBwamFjb2JzQHhlZWtyLmNvbSAuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cbi8vIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSFxuXG4vLyBmaXhlZC9tb2RpZmllZCBieSBIZXJiZXJ0IEhhbmV3aW5rZWwsIHd3dy5oYW5lV0lOLmRlXG4vLyBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uXG5cbi8vIGNhc3Q1LmpzIGlzIGEgSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBDQVNULTEyOCwgYXMgZGVmaW5lZCBpbiBSRkMgMjE0NC5cbi8vIENBU1QtMTI4IGlzIGEgY29tbW9uIE9wZW5QR1AgY2lwaGVyLlxuXG5cbi8vIENBU1Q1IGNvbnN0cnVjdG9yXG5cblxuXG5mdW5jdGlvbiBvcGVucGdwX3N5bWVuY19jYXN0NSgpIHtcbiAgdGhpcy5CbG9ja1NpemUgPSA4O1xuICB0aGlzLktleVNpemUgPSAxNjtcblxuICB0aGlzLnNldEtleSA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHRoaXMubWFza2luZyA9IG5ldyBBcnJheSgxNik7XG4gICAgdGhpcy5yb3RhdGUgPSBuZXcgQXJyYXkoMTYpO1xuXG4gICAgdGhpcy5yZXNldCgpO1xuXG4gICAgaWYgKGtleS5sZW5ndGggPT0gdGhpcy5LZXlTaXplKSB7XG4gICAgICB0aGlzLmtleVNjaGVkdWxlKGtleSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHV0aWwucHJpbnRfZXJyb3IoJ2Nhc3Q1LmpzOiBDQVNULTEyODoga2V5cyBtdXN0IGJlIDE2IGJ5dGVzJyk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIHRoaXMucmVzZXQgPSBmdW5jdGlvbigpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICAgIHRoaXMubWFza2luZ1tpXSA9IDA7XG4gICAgICB0aGlzLnJvdGF0ZVtpXSA9IDA7XG4gICAgfVxuICB9O1xuXG4gIHRoaXMuZ2V0QmxvY2tTaXplID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIEJsb2NrU2l6ZTtcbiAgfTtcblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihzcmMpIHtcbiAgICB2YXIgZHN0ID0gbmV3IEFycmF5KHNyYy5sZW5ndGgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzcmMubGVuZ3RoOyBpICs9IDgpIHtcbiAgICAgIHZhciBsID0gc3JjW2ldIDw8IDI0IHwgc3JjW2kgKyAxXSA8PCAxNiB8IHNyY1tpICsgMl0gPDwgOCB8IHNyY1tpICsgM107XG4gICAgICB2YXIgciA9IHNyY1tpICsgNF0gPDwgMjQgfCBzcmNbaSArIDVdIDw8IDE2IHwgc3JjW2kgKyA2XSA8PCA4IHwgc3JjW2kgKyA3XTtcbiAgICAgIHZhciB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzBdLCB0aGlzLnJvdGF0ZVswXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbMV0sIHRoaXMucm90YXRlWzFdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1syXSwgdGhpcy5yb3RhdGVbMl0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzNdLCB0aGlzLnJvdGF0ZVszXSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1s0XSwgdGhpcy5yb3RhdGVbNF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzVdLCB0aGlzLnJvdGF0ZVs1XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbNl0sIHRoaXMucm90YXRlWzZdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1s3XSwgdGhpcy5yb3RhdGVbN10pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbOF0sIHRoaXMucm90YXRlWzhdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1s5XSwgdGhpcy5yb3RhdGVbOV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzEwXSwgdGhpcy5yb3RhdGVbMTBdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1sxMV0sIHRoaXMucm90YXRlWzExXSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1sxMl0sIHRoaXMucm90YXRlWzEyXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbMTNdLCB0aGlzLnJvdGF0ZVsxM10pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzE0XSwgdGhpcy5yb3RhdGVbMTRdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1sxNV0sIHRoaXMucm90YXRlWzE1XSk7XG4gICAgICBsID0gdDtcblxuICAgICAgZHN0W2ldID0gKHIgPj4+IDI0KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgMV0gPSAociA+Pj4gMTYpICYgMjU1O1xuICAgICAgZHN0W2kgKyAyXSA9IChyID4+PiA4KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgM10gPSByICYgMjU1O1xuICAgICAgZHN0W2kgKyA0XSA9IChsID4+PiAyNCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDVdID0gKGwgPj4+IDE2KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgNl0gPSAobCA+Pj4gOCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDddID0gbCAmIDI1NTtcbiAgICB9XG5cbiAgICByZXR1cm4gZHN0O1xuICB9O1xuXG4gIHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKHNyYykge1xuICAgIHZhciBkc3QgPSBuZXcgQXJyYXkoc3JjLmxlbmd0aCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNyYy5sZW5ndGg7IGkgKz0gOCkge1xuICAgICAgdmFyIGwgPSBzcmNbaV0gPDwgMjQgfCBzcmNbaSArIDFdIDw8IDE2IHwgc3JjW2kgKyAyXSA8PCA4IHwgc3JjW2kgKyAzXTtcbiAgICAgIHZhciByID0gc3JjW2kgKyA0XSA8PCAyNCB8IHNyY1tpICsgNV0gPDwgMTYgfCBzcmNbaSArIDZdIDw8IDggfCBzcmNbaSArIDddO1xuICAgICAgdmFyIHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbMTVdLCB0aGlzLnJvdGF0ZVsxNV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzE0XSwgdGhpcy5yb3RhdGVbMTRdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1sxM10sIHRoaXMucm90YXRlWzEzXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbMTJdLCB0aGlzLnJvdGF0ZVsxMl0pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbMTFdLCB0aGlzLnJvdGF0ZVsxMV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzEwXSwgdGhpcy5yb3RhdGVbMTBdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1s5XSwgdGhpcy5yb3RhdGVbOV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzhdLCB0aGlzLnJvdGF0ZVs4XSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1s3XSwgdGhpcy5yb3RhdGVbN10pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzZdLCB0aGlzLnJvdGF0ZVs2XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbNV0sIHRoaXMucm90YXRlWzVdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1s0XSwgdGhpcy5yb3RhdGVbNF0pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbM10sIHRoaXMucm90YXRlWzNdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1syXSwgdGhpcy5yb3RhdGVbMl0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzFdLCB0aGlzLnJvdGF0ZVsxXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbMF0sIHRoaXMucm90YXRlWzBdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICBkc3RbaV0gPSAociA+Pj4gMjQpICYgMjU1O1xuICAgICAgZHN0W2kgKyAxXSA9IChyID4+PiAxNikgJiAyNTU7XG4gICAgICBkc3RbaSArIDJdID0gKHIgPj4+IDgpICYgMjU1O1xuICAgICAgZHN0W2kgKyAzXSA9IHIgJiAyNTU7XG4gICAgICBkc3RbaSArIDRdID0gKGwgPj4+IDI0KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgNV0gPSAobCA+PiAxNikgJiAyNTU7XG4gICAgICBkc3RbaSArIDZdID0gKGwgPj4gOCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDddID0gbCAmIDI1NTtcbiAgICB9XG5cbiAgICByZXR1cm4gZHN0O1xuICB9O1xuICB2YXIgc2NoZWR1bGVBID0gbmV3IEFycmF5KDQpO1xuXG4gIHNjaGVkdWxlQVswXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVBWzBdWzBdID0gbmV3IEFycmF5KDQsIDAsIDB4ZCwgMHhmLCAweGMsIDB4ZSwgMHg4KTtcbiAgc2NoZWR1bGVBWzBdWzFdID0gbmV3IEFycmF5KDUsIDIsIDE2ICsgMCwgMTYgKyAyLCAxNiArIDEsIDE2ICsgMywgMHhhKTtcbiAgc2NoZWR1bGVBWzBdWzJdID0gbmV3IEFycmF5KDYsIDMsIDE2ICsgNywgMTYgKyA2LCAxNiArIDUsIDE2ICsgNCwgOSk7XG4gIHNjaGVkdWxlQVswXVszXSA9IG5ldyBBcnJheSg3LCAxLCAxNiArIDB4YSwgMTYgKyA5LCAxNiArIDB4YiwgMTYgKyA4LCAweGIpO1xuXG4gIHNjaGVkdWxlQVsxXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVBWzFdWzBdID0gbmV3IEFycmF5KDAsIDYsIDE2ICsgNSwgMTYgKyA3LCAxNiArIDQsIDE2ICsgNiwgMTYgKyAwKTtcbiAgc2NoZWR1bGVBWzFdWzFdID0gbmV3IEFycmF5KDEsIDQsIDAsIDIsIDEsIDMsIDE2ICsgMik7XG4gIHNjaGVkdWxlQVsxXVsyXSA9IG5ldyBBcnJheSgyLCA1LCA3LCA2LCA1LCA0LCAxNiArIDEpO1xuICBzY2hlZHVsZUFbMV1bM10gPSBuZXcgQXJyYXkoMywgNywgMHhhLCA5LCAweGIsIDgsIDE2ICsgMyk7XG5cbiAgc2NoZWR1bGVBWzJdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUFbMl1bMF0gPSBuZXcgQXJyYXkoNCwgMCwgMHhkLCAweGYsIDB4YywgMHhlLCA4KTtcbiAgc2NoZWR1bGVBWzJdWzFdID0gbmV3IEFycmF5KDUsIDIsIDE2ICsgMCwgMTYgKyAyLCAxNiArIDEsIDE2ICsgMywgMHhhKTtcbiAgc2NoZWR1bGVBWzJdWzJdID0gbmV3IEFycmF5KDYsIDMsIDE2ICsgNywgMTYgKyA2LCAxNiArIDUsIDE2ICsgNCwgOSk7XG4gIHNjaGVkdWxlQVsyXVszXSA9IG5ldyBBcnJheSg3LCAxLCAxNiArIDB4YSwgMTYgKyA5LCAxNiArIDB4YiwgMTYgKyA4LCAweGIpO1xuXG5cbiAgc2NoZWR1bGVBWzNdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUFbM11bMF0gPSBuZXcgQXJyYXkoMCwgNiwgMTYgKyA1LCAxNiArIDcsIDE2ICsgNCwgMTYgKyA2LCAxNiArIDApO1xuICBzY2hlZHVsZUFbM11bMV0gPSBuZXcgQXJyYXkoMSwgNCwgMCwgMiwgMSwgMywgMTYgKyAyKTtcbiAgc2NoZWR1bGVBWzNdWzJdID0gbmV3IEFycmF5KDIsIDUsIDcsIDYsIDUsIDQsIDE2ICsgMSk7XG4gIHNjaGVkdWxlQVszXVszXSA9IG5ldyBBcnJheSgzLCA3LCAweGEsIDksIDB4YiwgOCwgMTYgKyAzKTtcblxuICB2YXIgc2NoZWR1bGVCID0gbmV3IEFycmF5KDQpO1xuXG4gIHNjaGVkdWxlQlswXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVCWzBdWzBdID0gbmV3IEFycmF5KDE2ICsgOCwgMTYgKyA5LCAxNiArIDcsIDE2ICsgNiwgMTYgKyAyKTtcbiAgc2NoZWR1bGVCWzBdWzFdID0gbmV3IEFycmF5KDE2ICsgMHhhLCAxNiArIDB4YiwgMTYgKyA1LCAxNiArIDQsIDE2ICsgNik7XG4gIHNjaGVkdWxlQlswXVsyXSA9IG5ldyBBcnJheSgxNiArIDB4YywgMTYgKyAweGQsIDE2ICsgMywgMTYgKyAyLCAxNiArIDkpO1xuICBzY2hlZHVsZUJbMF1bM10gPSBuZXcgQXJyYXkoMTYgKyAweGUsIDE2ICsgMHhmLCAxNiArIDEsIDE2ICsgMCwgMTYgKyAweGMpO1xuXG4gIHNjaGVkdWxlQlsxXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVCWzFdWzBdID0gbmV3IEFycmF5KDMsIDIsIDB4YywgMHhkLCA4KTtcbiAgc2NoZWR1bGVCWzFdWzFdID0gbmV3IEFycmF5KDEsIDAsIDB4ZSwgMHhmLCAweGQpO1xuICBzY2hlZHVsZUJbMV1bMl0gPSBuZXcgQXJyYXkoNywgNiwgOCwgOSwgMyk7XG4gIHNjaGVkdWxlQlsxXVszXSA9IG5ldyBBcnJheSg1LCA0LCAweGEsIDB4YiwgNyk7XG5cblxuICBzY2hlZHVsZUJbMl0gPSBuZXcgQXJyYXkoNCk7XG4gIHNjaGVkdWxlQlsyXVswXSA9IG5ldyBBcnJheSgxNiArIDMsIDE2ICsgMiwgMTYgKyAweGMsIDE2ICsgMHhkLCAxNiArIDkpO1xuICBzY2hlZHVsZUJbMl1bMV0gPSBuZXcgQXJyYXkoMTYgKyAxLCAxNiArIDAsIDE2ICsgMHhlLCAxNiArIDB4ZiwgMTYgKyAweGMpO1xuICBzY2hlZHVsZUJbMl1bMl0gPSBuZXcgQXJyYXkoMTYgKyA3LCAxNiArIDYsIDE2ICsgOCwgMTYgKyA5LCAxNiArIDIpO1xuICBzY2hlZHVsZUJbMl1bM10gPSBuZXcgQXJyYXkoMTYgKyA1LCAxNiArIDQsIDE2ICsgMHhhLCAxNiArIDB4YiwgMTYgKyA2KTtcblxuXG4gIHNjaGVkdWxlQlszXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVCWzNdWzBdID0gbmV3IEFycmF5KDgsIDksIDcsIDYsIDMpO1xuICBzY2hlZHVsZUJbM11bMV0gPSBuZXcgQXJyYXkoMHhhLCAweGIsIDUsIDQsIDcpO1xuICBzY2hlZHVsZUJbM11bMl0gPSBuZXcgQXJyYXkoMHhjLCAweGQsIDMsIDIsIDgpO1xuICBzY2hlZHVsZUJbM11bM10gPSBuZXcgQXJyYXkoMHhlLCAweGYsIDEsIDAsIDB4ZCk7XG5cbiAgLy8gY2hhbmdlZCAnaW4nIHRvICdpbm4nIChpbiBqYXZhc2NyaXB0ICdpbicgaXMgYSByZXNlcnZlZCB3b3JkKVxuICB0aGlzLmtleVNjaGVkdWxlID0gZnVuY3Rpb24oaW5uKSB7XG4gICAgdmFyIHQgPSBuZXcgQXJyYXkoOCk7XG4gICAgdmFyIGsgPSBuZXcgQXJyYXkoMzIpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICAgIHZhciBqID0gaSAqIDQ7XG4gICAgICB0W2ldID0gaW5uW2pdIDw8IDI0IHwgaW5uW2ogKyAxXSA8PCAxNiB8IGlubltqICsgMl0gPDwgOCB8IGlubltqICsgM107XG4gICAgfVxuXG4gICAgdmFyIHggPSBbNiwgNywgNCwgNV07XG4gICAgdmFyIGtpID0gMDtcblxuICAgIGZvciAodmFyIGhhbGYgPSAwOyBoYWxmIDwgMjsgaGFsZisrKSB7XG4gICAgICBmb3IgKHZhciByb3VuZCA9IDA7IHJvdW5kIDwgNDsgcm91bmQrKykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IDQ7IGorKykge1xuICAgICAgICAgIHZhciBhID0gc2NoZWR1bGVBW3JvdW5kXVtqXTtcbiAgICAgICAgICB2YXIgdyA9IHRbYVsxXV07XG5cbiAgICAgICAgICB3IF49IHNCb3hbNF1bKHRbYVsyXSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYVsyXSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbNV1bKHRbYVszXSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYVszXSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbNl1bKHRbYVs0XSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYVs0XSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbN11bKHRbYVs1XSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYVs1XSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbeFtqXV1bKHRbYVs2XSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYVs2XSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB0W2FbMF1dID0gdztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgNDsgaisrKSB7XG4gICAgICAgICAgdmFyIGIgPSBzY2hlZHVsZUJbcm91bmRdW2pdO1xuICAgICAgICAgIHZhciB3ID0gc0JveFs0XVsodFtiWzBdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChiWzBdICYgMykpKSAmIDB4ZmZdO1xuXG4gICAgICAgICAgdyBePSBzQm94WzVdWyh0W2JbMV0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGJbMV0gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAgdyBePSBzQm94WzZdWyh0W2JbMl0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGJbMl0gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAgdyBePSBzQm94WzddWyh0W2JbM10gPj4+IDJdID4+PiAoMjQgLSA4ICogKGJbM10gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAgdyBePSBzQm94WzQgKyBqXVsodFtiWzRdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChiWzRdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIGtba2ldID0gdztcbiAgICAgICAgICBraSsrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgICB0aGlzLm1hc2tpbmdbaV0gPSBrW2ldO1xuICAgICAgdGhpcy5yb3RhdGVbaV0gPSBrWzE2ICsgaV0gJiAweDFmO1xuICAgIH1cbiAgfTtcblxuICAvLyBUaGVzZSBhcmUgdGhlIHRocmVlICdmJyBmdW5jdGlvbnMuIFNlZSBSRkMgMjE0NCwgc2VjdGlvbiAyLjIuXG5cbiAgZnVuY3Rpb24gZjEoZCwgbSwgcikge1xuICAgIHZhciB0ID0gbSArIGQ7XG4gICAgdmFyIEkgPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7XG4gICAgcmV0dXJuICgoc0JveFswXVtJID4+PiAyNF0gXiBzQm94WzFdWyhJID4+PiAxNikgJiAyNTVdKSAtIHNCb3hbMl1bKEkgPj4+IDgpICYgMjU1XSkgKyBzQm94WzNdW0kgJiAyNTVdO1xuICB9XG5cbiAgZnVuY3Rpb24gZjIoZCwgbSwgcikge1xuICAgIHZhciB0ID0gbSBeIGQ7XG4gICAgdmFyIEkgPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7XG4gICAgcmV0dXJuICgoc0JveFswXVtJID4+PiAyNF0gLSBzQm94WzFdWyhJID4+PiAxNikgJiAyNTVdKSArIHNCb3hbMl1bKEkgPj4+IDgpICYgMjU1XSkgXiBzQm94WzNdW0kgJiAyNTVdO1xuICB9XG5cbiAgZnVuY3Rpb24gZjMoZCwgbSwgcikge1xuICAgIHZhciB0ID0gbSAtIGQ7XG4gICAgdmFyIEkgPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7XG4gICAgcmV0dXJuICgoc0JveFswXVtJID4+PiAyNF0gKyBzQm94WzFdWyhJID4+PiAxNikgJiAyNTVdKSBeIHNCb3hbMl1bKEkgPj4+IDgpICYgMjU1XSkgLSBzQm94WzNdW0kgJiAyNTVdO1xuICB9XG5cbiAgdmFyIHNCb3ggPSBuZXcgQXJyYXkoOCk7XG4gIHNCb3hbMF0gPSBuZXcgQXJyYXkoXG4gICAgMHgzMGZiNDBkNCwgMHg5ZmEwZmYwYiwgMHg2YmVjY2QyZiwgMHgzZjI1OGM3YSwgMHgxZTIxM2YyZiwgMHg5YzAwNGRkMywgMHg2MDAzZTU0MCwgMHhjZjlmYzk0OSxcbiAgICAweGJmZDRhZjI3LCAweDg4YmJiZGI1LCAweGUyMDM0MDkwLCAweDk4ZDA5Njc1LCAweDZlNjNhMGUwLCAweDE1YzM2MWQyLCAweGMyZTc2NjFkLCAweDIyZDRmZjhlLFxuICAgIDB4Mjg2ODNiNmYsIDB4YzA3ZmQwNTksIDB4ZmYyMzc5YzgsIDB4Nzc1ZjUwZTIsIDB4NDNjMzQwZDMsIDB4ZGYyZjg2NTYsIDB4ODg3Y2E0MWEsIDB4YTJkMmJkMmQsXG4gICAgMHhhMWM5ZTBkNiwgMHgzNDZjNDgxOSwgMHg2MWI3NmQ4NywgMHgyMjU0MGYyZiwgMHgyYWJlMzJlMSwgMHhhYTU0MTY2YiwgMHgyMjU2OGUzYSwgMHhhMmQzNDFkMCxcbiAgICAweDY2ZGI0MGM4LCAweGE3ODQzOTJmLCAweDAwNGRmZjJmLCAweDJkYjlkMmRlLCAweDk3OTQzZmFjLCAweDRhOTdjMWQ4LCAweDUyNzY0NGI3LCAweGI1ZjQzN2E3LFxuICAgIDB4YjgyY2JhZWYsIDB4ZDc1MWQxNTksIDB4NmZmN2YwZWQsIDB4NWEwOTdhMWYsIDB4ODI3YjY4ZDAsIDB4OTBlY2Y1MmUsIDB4MjJiMGMwNTQsIDB4YmM4ZTU5MzUsXG4gICAgMHg0YjZkMmY3ZiwgMHg1MGJiNjRhMiwgMHhkMjY2NDkxMCwgMHhiZWU1ODEyZCwgMHhiNzMzMjI5MCwgMHhlOTNiMTU5ZiwgMHhiNDhlZTQxMSwgMHg0YmZmMzQ1ZCxcbiAgICAweGZkNDVjMjQwLCAweGFkMzE5NzNmLCAweGM0ZjZkMDJlLCAweDU1ZmM4MTY1LCAweGQ1YjFjYWFkLCAweGExYWMyZGFlLCAweGEyZDRiNzZkLCAweGMxOWIwYzUwLFxuICAgIDB4ODgyMjQwZjIsIDB4MGM2ZTRmMzgsIDB4YTRlNGJmZDcsIDB4NGY1YmEyNzIsIDB4NTY0YzFkMmYsIDB4YzU5YzUzMTksIDB4Yjk0OWUzNTQsIDB4YjA0NjY5ZmUsXG4gICAgMHhiMWI2YWI4YSwgMHhjNzEzNThkZCwgMHg2Mzg1YzU0NSwgMHgxMTBmOTM1ZCwgMHg1NzUzOGFkNSwgMHg2YTM5MDQ5MywgMHhlNjNkMzdlMCwgMHgyYTU0ZjZiMyxcbiAgICAweDNhNzg3ZDVmLCAweDYyNzZhMGI1LCAweDE5YTZmY2RmLCAweDdhNDIyMDZhLCAweDI5ZjlkNGQ1LCAweGY2MWIxODkxLCAweGJiNzIyNzVlLCAweGFhNTA4MTY3LFxuICAgIDB4Mzg5MDEwOTEsIDB4YzZiNTA1ZWIsIDB4ODRjN2NiOGMsIDB4MmFkNzVhMGYsIDB4ODc0YTE0MjcsIDB4YTJkMTkzNmIsIDB4MmFkMjg2YWYsIDB4YWE1NmQyOTEsXG4gICAgMHhkNzg5NDM2MCwgMHg0MjVjNzUwZCwgMHg5M2IzOWUyNiwgMHgxODcxODRjOSwgMHg2YzAwYjMyZCwgMHg3M2UyYmIxNCwgMHhhMGJlYmMzYywgMHg1NDYyMzc3OSxcbiAgICAweDY0NDU5ZWFiLCAweDNmMzI4YjgyLCAweDc3MThjZjgyLCAweDU5YTJjZWE2LCAweDA0ZWUwMDJlLCAweDg5ZmU3OGU2LCAweDNmYWIwOTUwLCAweDMyNWZmNmMyLFxuICAgIDB4ODEzODNmMDUsIDB4Njk2M2M1YzgsIDB4NzZjYjVhZDYsIDB4ZDQ5OTc0YzksIDB4Y2ExODBkY2YsIDB4MzgwNzgyZDUsIDB4YzdmYTVjZjYsIDB4OGFjMzE1MTEsXG4gICAgMHgzNWU3OWUxMywgMHg0N2RhOTFkMCwgMHhmNDBmOTA4NiwgMHhhN2UyNDE5ZSwgMHgzMTM2NjI0MSwgMHgwNTFlZjQ5NSwgMHhhYTU3M2IwNCwgMHg0YTgwNWQ4ZCxcbiAgICAweDU0ODMwMGQwLCAweDAwMzIyYTNjLCAweGJmNjRjZGRmLCAweGJhNTdhNjhlLCAweDc1YzYzNzJiLCAweDUwYWZkMzQxLCAweGE3YzEzMjc1LCAweDkxNWEwYmY1LFxuICAgIDB4NmI1NGJmYWIsIDB4MmIwYjE0MjYsIDB4YWI0Y2M5ZDcsIDB4NDQ5Y2NkODIsIDB4ZjdmYmYyNjUsIDB4YWI4NWM1ZjMsIDB4MWI1NWRiOTQsIDB4YWFkNGUzMjQsXG4gICAgMHhjZmE0YmQzZiwgMHgyZGVhYTNlMiwgMHg5ZTIwNGQwMiwgMHhjOGJkMjVhYywgMHhlYWRmNTViMywgMHhkNWJkOWU5OCwgMHhlMzEyMzFiMiwgMHgyYWQ1YWQ2YyxcbiAgICAweDk1NDMyOWRlLCAweGFkYmU0NTI4LCAweGQ4NzEwZjY5LCAweGFhNTFjOTBmLCAweGFhNzg2YmY2LCAweDIyNTEzZjFlLCAweGFhNTFhNzliLCAweDJhZDM0NGNjLFxuICAgIDB4N2I1YTQxZjAsIDB4ZDM3Y2ZiYWQsIDB4MWIwNjk1MDUsIDB4NDFlY2U0OTEsIDB4YjRjMzMyZTYsIDB4MDMyMjY4ZDQsIDB4Yzk2MDBhY2MsIDB4Y2UzODdlNmQsXG4gICAgMHhiZjZiYjE2YywgMHg2YTcwZmI3OCwgMHgwZDAzZDljOSwgMHhkNGRmMzlkZSwgMHhlMDEwNjNkYSwgMHg0NzM2ZjQ2NCwgMHg1YWQzMjhkOCwgMHhiMzQ3Y2M5NixcbiAgICAweDc1YmIwZmMzLCAweDk4NTExYmZiLCAweDRmZmJjYzM1LCAweGI1OGJjZjZhLCAweGUxMWYwYWJjLCAweGJmYzVmZTRhLCAweGE3MGFlYzEwLCAweGFjMzk1NzBhLFxuICAgIDB4M2YwNDQ0MmYsIDB4NjE4OGIxNTMsIDB4ZTAzOTdhMmUsIDB4NTcyN2NiNzksIDB4OWNlYjQxOGYsIDB4MWNhY2Q2OGQsIDB4MmFkMzdjOTYsIDB4MDE3NWNiOWQsXG4gICAgMHhjNjlkZmYwOSwgMHhjNzViNjVmMCwgMHhkOWRiNDBkOCwgMHhlYzBlNzc3OSwgMHg0NzQ0ZWFkNCwgMHhiMTFjMzI3NCwgMHhkZDI0Y2I5ZSwgMHg3ZTFjNTRiZCxcbiAgICAweGYwMTE0NGY5LCAweGQyMjQwZWIxLCAweDk2NzViM2ZkLCAweGEzYWMzNzU1LCAweGQ0N2MyN2FmLCAweDUxYzg1ZjRkLCAweDU2OTA3NTk2LCAweGE1YmIxNWU2LFxuICAgIDB4NTgwMzA0ZjAsIDB4Y2EwNDJjZjEsIDB4MDExYTM3ZWEsIDB4OGRiZmFhZGIsIDB4MzViYTNlNGEsIDB4MzUyNmZmYTAsIDB4YzM3YjRkMDksIDB4YmMzMDZlZDksXG4gICAgMHg5OGE1MjY2NiwgMHg1NjQ4ZjcyNSwgMHhmZjVlNTY5ZCwgMHgwY2VkNjNkMCwgMHg3YzYzYjJjZiwgMHg3MDBiNDVlMSwgMHhkNWVhNTBmMSwgMHg4NWE5Mjg3MixcbiAgICAweGFmMWZiZGE3LCAweGQ0MjM0ODcwLCAweGE3ODcwYmYzLCAweDJkM2I0ZDc5LCAweDQyZTA0MTk4LCAweDBjZDBlZGU3LCAweDI2NDcwZGI4LCAweGY4ODE4MTRjLFxuICAgIDB4NDc0ZDZhZDcsIDB4N2MwYzVlNWMsIDB4ZDEyMzE5NTksIDB4MzgxYjcyOTgsIDB4ZjVkMmY0ZGIsIDB4YWI4Mzg2NTMsIDB4NmUyZjFlMjMsIDB4ODM3MTljOWUsXG4gICAgMHhiZDkxZTA0NiwgMHg5YTU2NDU2ZSwgMHhkYzM5MjAwYywgMHgyMGM4YzU3MSwgMHg5NjJiZGExYywgMHhlMWU2OTZmZiwgMHhiMTQxYWIwOCwgMHg3Y2NhODliOSxcbiAgICAweDFhNjllNzgzLCAweDAyY2M0ODQzLCAweGEyZjdjNTc5LCAweDQyOWVmNDdkLCAweDQyN2IxNjljLCAweDVhYzlmMDQ5LCAweGRkOGYwZjAwLCAweDVjODE2NWJmKTtcblxuICBzQm94WzFdID0gbmV3IEFycmF5KFxuICAgIDB4MWYyMDEwOTQsIDB4ZWYwYmE3NWIsIDB4NjllM2NmN2UsIDB4MzkzZjQzODAsIDB4ZmU2MWNmN2EsIDB4ZWVjNTIwN2EsIDB4NTU4ODljOTQsIDB4NzJmYzA2NTEsXG4gICAgMHhhZGE3ZWY3OSwgMHg0ZTFkNzIzNSwgMHhkNTVhNjNjZSwgMHhkZTA0MzZiYSwgMHg5OWM0MzBlZiwgMHg1ZjBjMDc5NCwgMHgxOGRjZGI3ZCwgMHhhMWQ2ZWZmMyxcbiAgICAweGEwYjUyZjdiLCAweDU5ZTgzNjA1LCAweGVlMTViMDk0LCAweGU5ZmZkOTA5LCAweGRjNDQwMDg2LCAweGVmOTQ0NDU5LCAweGJhODNjY2IzLCAweGUwYzNjZGZiLFxuICAgIDB4ZDFkYTQxODEsIDB4M2IwOTJhYjEsIDB4Zjk5N2YxYzEsIDB4YTVlNmNmN2IsIDB4MDE0MjBkZGIsIDB4ZTRlN2VmNWIsIDB4MjVhMWZmNDEsIDB4ZTE4MGY4MDYsXG4gICAgMHgxZmM0MTA4MCwgMHgxNzliZWU3YSwgMHhkMzdhYzZhOSwgMHhmZTU4MzBhNCwgMHg5OGRlOGI3ZiwgMHg3N2U4M2Y0ZSwgMHg3OTkyOTI2OSwgMHgyNGZhOWY3YixcbiAgICAweGUxMTNjODViLCAweGFjYzQwMDgzLCAweGQ3NTAzNTI1LCAweGY3ZWE2MTVmLCAweDYyMTQzMTU0LCAweDBkNTU0YjYzLCAweDVkNjgxMTIxLCAweGM4NjZjMzU5LFxuICAgIDB4M2Q2M2NmNzMsIDB4Y2VlMjM0YzAsIDB4ZDRkODdlODcsIDB4NWM2NzJiMjEsIDB4MDcxZjYxODEsIDB4MzlmNzYyN2YsIDB4MzYxZTMwODQsIDB4ZTRlYjU3M2IsXG4gICAgMHg2MDJmNjRhNCwgMHhkNjNhY2Q5YywgMHgxYmJjNDYzNSwgMHg5ZTgxMDMyZCwgMHgyNzAxZjUwYywgMHg5OTg0N2FiNCwgMHhhMGUzZGY3OSwgMHhiYTZjZjM4YyxcbiAgICAweDEwODQzMDk0LCAweDI1MzdhOTVlLCAweGY0NmY2ZmZlLCAweGExZmYzYjFmLCAweDIwOGNmYjZhLCAweDhmNDU4Yzc0LCAweGQ5ZTBhMjI3LCAweDRlYzczYTM0LFxuICAgIDB4ZmM4ODRmNjksIDB4M2U0ZGU4ZGYsIDB4ZWYwZTAwODgsIDB4MzU1OTY0OGQsIDB4OGE0NTM4OGMsIDB4MWQ4MDQzNjYsIDB4NzIxZDliZmQsIDB4YTU4Njg0YmIsXG4gICAgMHhlODI1NjMzMywgMHg4NDRlODIxMiwgMHgxMjhkODA5OCwgMHhmZWQzM2ZiNCwgMHhjZTI4MGFlMSwgMHgyN2UxOWJhNSwgMHhkNWE2YzI1MiwgMHhlNDk3NTRiZCxcbiAgICAweGM1ZDY1NWRkLCAweGViNjY3MDY0LCAweDc3ODQwYjRkLCAweGExYjZhODAxLCAweDg0ZGIyNmE5LCAweGUwYjU2NzE0LCAweDIxZjA0M2I3LCAweGU1ZDA1ODYwLFxuICAgIDB4NTRmMDMwODQsIDB4MDY2ZmY0NzIsIDB4YTMxYWExNTMsIDB4ZGFkYzQ3NTUsIDB4YjU2MjVkYmYsIDB4Njg1NjFiZTYsIDB4ODNjYTZiOTQsIDB4MmQ2ZWQyM2IsXG4gICAgMHhlY2NmMDFkYiwgMHhhNmQzZDBiYSwgMHhiNjgwM2Q1YywgMHhhZjc3YTcwOSwgMHgzM2I0YTM0YywgMHgzOTdiYzhkNiwgMHg1ZWUyMmI5NSwgMHg1ZjBlNTMwNCxcbiAgICAweDgxZWQ2ZjYxLCAweDIwZTc0MzY0LCAweGI0NWUxMzc4LCAweGRlMTg2MzliLCAweDg4MWNhMTIyLCAweGI5NjcyNmQxLCAweDgwNDlhN2U4LCAweDIyYjdkYTdiLFxuICAgIDB4NWU1NTJkMjUsIDB4NTI3MmQyMzcsIDB4NzlkMjk1MWMsIDB4YzYwZDg5NGMsIDB4NDg4Y2I0MDIsIDB4MWJhNGZlNWIsIDB4YTRiMDlmNmIsIDB4MWNhODE1Y2YsXG4gICAgMHhhMjBjMzAwNSwgMHg4ODcxZGY2MywgMHhiOWRlMmZjYiwgMHgwY2M2YzllOSwgMHgwYmVlZmY1MywgMHhlMzIxNDUxNywgMHhiNDU0MjgzNSwgMHg5ZjYzMjkzYyxcbiAgICAweGVlNDFlNzI5LCAweDZlMWQyZDdjLCAweDUwMDQ1Mjg2LCAweDFlNjY4NWYzLCAweGYzMzQwMWM2LCAweDMwYTIyYzk1LCAweDMxYTcwODUwLCAweDYwOTMwZjEzLFxuICAgIDB4NzNmOTg0MTcsIDB4YTEyNjk4NTksIDB4ZWM2NDVjNDQsIDB4NTJjODc3YTksIDB4Y2RmZjMzYTYsIDB4YTAyYjE3NDEsIDB4N2NiYWQ5YTIsIDB4MjE4MDAzNmYsXG4gICAgMHg1MGQ5OWMwOCwgMHhjYjNmNDg2MSwgMHhjMjZiZDc2NSwgMHg2NGEzZjZhYiwgMHg4MDM0MjY3NiwgMHgyNWE3NWU3YiwgMHhlNGU2ZDFmYywgMHgyMGM3MTBlNixcbiAgICAweGNkZjBiNjgwLCAweDE3ODQ0ZDNiLCAweDMxZWVmODRkLCAweDdlMDgyNGU0LCAweDJjY2I0OWViLCAweDg0NmEzYmFlLCAweDhmZjc3ODg4LCAweGVlNWQ2MGY2LFxuICAgIDB4N2FmNzU2NzMsIDB4MmZkZDVjZGIsIDB4YTExNjMxYzEsIDB4MzBmNjZmNDMsIDB4YjNmYWVjNTQsIDB4MTU3ZmQ3ZmEsIDB4ZWY4NTc5Y2MsIDB4ZDE1MmRlNTgsXG4gICAgMHhkYjJmZmQ1ZSwgMHg4ZjMyY2UxOSwgMHgzMDZhZjk3YSwgMHgwMmYwM2VmOCwgMHg5OTMxOWFkNSwgMHhjMjQyZmEwZiwgMHhhN2UzZWJiMCwgMHhjNjhlNDkwNixcbiAgICAweGI4ZGEyMzBjLCAweDgwODIzMDI4LCAweGRjZGVmM2M4LCAweGQzNWZiMTcxLCAweDA4OGExYmM4LCAweGJlYzBjNTYwLCAweDYxYTNjOWU4LCAweGJjYThmNTRkLFxuICAgIDB4YzcyZmVmZmEsIDB4MjI4MjJlOTksIDB4ODJjNTcwYjQsIDB4ZDhkOTRlODksIDB4OGIxYzM0YmMsIDB4MzAxZTE2ZTYsIDB4MjczYmU5NzksIDB4YjBmZmVhYTYsXG4gICAgMHg2MWQ5YjhjNiwgMHgwMGIyNDg2OSwgMHhiN2ZmY2UzZiwgMHgwOGRjMjgzYiwgMHg0M2RhZjY1YSwgMHhmN2UxOTc5OCwgMHg3NjE5YjcyZiwgMHg4ZjFjOWJhNCxcbiAgICAweGRjODYzN2EwLCAweDE2YTdkM2IxLCAweDlmYzM5M2I3LCAweGE3MTM2ZWViLCAweGM2YmNjNjNlLCAweDFhNTEzNzQyLCAweGVmNjgyOGJjLCAweDUyMDM2NWQ2LFxuICAgIDB4MmQ2YTc3YWIsIDB4MzUyN2VkNGIsIDB4ODIxZmQyMTYsIDB4MDk1YzZlMmUsIDB4ZGI5MmYyZmIsIDB4NWVlYTI5Y2IsIDB4MTQ1ODkyZjUsIDB4OTE1ODRmN2YsXG4gICAgMHg1NDgzNjk3YiwgMHgyNjY3YThjYywgMHg4NTE5NjA0OCwgMHg4YzRiYWNlYSwgMHg4MzM4NjBkNCwgMHgwZDIzZTBmOSwgMHg2YzM4N2U4YSwgMHgwYWU2ZDI0OSxcbiAgICAweGIyODQ2MDBjLCAweGQ4MzU3MzFkLCAweGRjYjFjNjQ3LCAweGFjNGM1NmVhLCAweDNlYmQ4MWIzLCAweDIzMGVhYmIwLCAweDY0MzhiYzg3LCAweGYwYjViMWZhLFxuICAgIDB4OGY1ZWEyYjMsIDB4ZmMxODQ2NDIsIDB4MGEwMzZiN2EsIDB4NGZiMDg5YmQsIDB4NjQ5ZGE1ODksIDB4YTM0NTQxNWUsIDB4NWMwMzgzMjMsIDB4M2U1ZDNiYjksXG4gICAgMHg0M2Q3OTU3MiwgMHg3ZTZkZDA3YywgMHgwNmRmZGYxZSwgMHg2YzZjYzRlZiwgMHg3MTYwYTUzOSwgMHg3M2JmYmU3MCwgMHg4Mzg3NzYwNSwgMHg0NTIzZWNmMSk7XG5cbiAgc0JveFsyXSA9IG5ldyBBcnJheShcbiAgICAweDhkZWZjMjQwLCAweDI1ZmE1ZDlmLCAweGViOTAzZGJmLCAweGU4MTBjOTA3LCAweDQ3NjA3ZmZmLCAweDM2OWZlNDRiLCAweDhjMWZjNjQ0LCAweGFlY2VjYTkwLFxuICAgIDB4YmViMWY5YmYsIDB4ZWVmYmNhZWEsIDB4ZThjZjE5NTAsIDB4NTFkZjA3YWUsIDB4OTIwZTg4MDYsIDB4ZjBhZDA1NDgsIDB4ZTEzYzhkODMsIDB4OTI3MDEwZDUsXG4gICAgMHgxMTEwN2Q5ZiwgMHgwNzY0N2RiOSwgMHhiMmUzZTRkNCwgMHgzZDRmMjg1ZSwgMHhiOWFmYTgyMCwgMHhmYWRlODJlMCwgMHhhMDY3MjY4YiwgMHg4MjcyNzkyZSxcbiAgICAweDU1M2ZiMmMwLCAweDQ4OWFlMjJiLCAweGQ0ZWY5Nzk0LCAweDEyNWUzZmJjLCAweDIxZmZmY2VlLCAweDgyNWIxYmZkLCAweDkyNTVjNWVkLCAweDEyNTdhMjQwLFxuICAgIDB4NGUxYTgzMDIsIDB4YmFlMDdmZmYsIDB4NTI4MjQ2ZTcsIDB4OGU1NzE0MGUsIDB4MzM3M2Y3YmYsIDB4OGM5ZjgxODgsIDB4YTZmYzRlZTgsIDB4Yzk4MmI1YTUsXG4gICAgMHhhOGMwMWRiNywgMHg1NzlmYzI2NCwgMHg2NzA5NGYzMSwgMHhmMmJkM2Y1ZiwgMHg0MGZmZjdjMSwgMHgxZmI3OGRmYywgMHg4ZTZiZDJjMSwgMHg0MzdiZTU5YixcbiAgICAweDk5YjAzZGJmLCAweGI1ZGJjNjRiLCAweDYzOGRjMGU2LCAweDU1ODE5ZDk5LCAweGExOTdjODFjLCAweDRhMDEyZDZlLCAweGM1ODg0YTI4LCAweGNjYzM2ZjcxLFxuICAgIDB4Yjg0M2MyMTMsIDB4NmMwNzQzZjEsIDB4ODMwOTg5M2MsIDB4MGZlZGRkNWYsIDB4MmY3ZmU4NTAsIDB4ZDdjMDdmN2UsIDB4MDI1MDdmYmYsIDB4NWFmYjlhMDQsXG4gICAgMHhhNzQ3ZDJkMCwgMHgxNjUxMTkyZSwgMHhhZjcwYmYzZSwgMHg1OGMzMTM4MCwgMHg1Zjk4MzAyZSwgMHg3MjdjYzNjNCwgMHgwYTBmYjQwMiwgMHgwZjdmZWY4MixcbiAgICAweDhjOTZmZGFkLCAweDVkMmMyYWFlLCAweDhlZTk5YTQ5LCAweDUwZGE4OGI4LCAweDg0MjdmNGEwLCAweDFlYWM1NzkwLCAweDc5NmZiNDQ5LCAweDgyNTJkYzE1LFxuICAgIDB4ZWZiZDdkOWIsIDB4YTY3MjU5N2QsIDB4YWRhODQwZDgsIDB4NDVmNTQ1MDQsIDB4ZmE1ZDc0MDMsIDB4ZTgzZWMzMDUsIDB4NGY5MTc1MWEsIDB4OTI1NjY5YzIsXG4gICAgMHgyM2VmZTk0MSwgMHhhOTAzZjEyZSwgMHg2MDI3MGRmMiwgMHgwMjc2ZTRiNiwgMHg5NGZkNjU3NCwgMHg5Mjc5ODViMiwgMHg4Mjc2ZGJjYiwgMHgwMjc3ODE3NixcbiAgICAweGY4YWY5MThkLCAweDRlNDhmNzllLCAweDhmNjE2ZGRmLCAweGUyOWQ4NDBlLCAweDg0MmY3ZDgzLCAweDM0MGNlNWM4LCAweDk2YmJiNjgyLCAweDkzYjRiMTQ4LFxuICAgIDB4ZWYzMDNjYWIsIDB4OTg0ZmFmMjgsIDB4Nzc5ZmFmOWIsIDB4OTJkYzU2MGQsIDB4MjI0ZDFlMjAsIDB4ODQzN2FhODgsIDB4N2QyOWRjOTYsIDB4Mjc1NmQzZGMsXG4gICAgMHg4YjkwN2NlZSwgMHhiNTFmZDI0MCwgMHhlN2MwN2NlMywgMHhlNTY2YjRhMSwgMHhjM2U5NjE1ZSwgMHgzY2Y4MjA5ZCwgMHg2MDk0ZDFlMywgMHhjZDljYTM0MSxcbiAgICAweDVjNzY0NjBlLCAweDAwZWE5ODNiLCAweGQ0ZDY3ODgxLCAweGZkNDc1NzJjLCAweGY3NmNlZGQ5LCAweGJkYTgyMjljLCAweDEyN2RhZGFhLCAweDQzOGEwNzRlLFxuICAgIDB4MWY5N2MwOTAsIDB4MDgxYmRiOGEsIDB4OTNhMDdlYmUsIDB4YjkzOGNhMTUsIDB4OTdiMDNjZmYsIDB4M2RjMmMwZjgsIDB4OGQxYWIyZWMsIDB4NjQzODBlNTEsXG4gICAgMHg2OGNjN2JmYiwgMHhkOTBmMjc4OCwgMHgxMjQ5MDE4MSwgMHg1ZGU1ZmZkNCwgMHhkZDdlZjg2YSwgMHg3NmEyZTIxNCwgMHhiOWE0MDM2OCwgMHg5MjVkOTU4ZixcbiAgICAweDRiMzlmZmZhLCAweGJhMzlhZWU5LCAweGE0ZmZkMzBiLCAweGZhZjc5MzNiLCAweDZkNDk4NjIzLCAweDE5M2NiY2ZhLCAweDI3NjI3NTQ1LCAweDgyNWNmNDdhLFxuICAgIDB4NjFiZDhiYTAsIDB4ZDExZTQyZDEsIDB4Y2VhZDA0ZjQsIDB4MTI3ZWEzOTIsIDB4MTA0MjhkYjcsIDB4ODI3MmE5NzIsIDB4OTI3MGM0YTgsIDB4MTI3ZGU1MGIsXG4gICAgMHgyODViYTFjOCwgMHgzYzYyZjQ0ZiwgMHgzNWMwZWFhNSwgMHhlODA1ZDIzMSwgMHg0Mjg5MjlmYiwgMHhiNGZjZGY4MiwgMHg0ZmI2NmE1MywgMHgwZTdkYzE1YixcbiAgICAweDFmMDgxZmFiLCAweDEwODYxOGFlLCAweGZjZmQwODZkLCAweGY5ZmYyODg5LCAweDY5NGJjYzExLCAweDIzNmE1Y2FlLCAweDEyZGVjYTRkLCAweDJjM2Y4Y2M1LFxuICAgIDB4ZDJkMDJkZmUsIDB4ZjhlZjU4OTYsIDB4ZTRjZjUyZGEsIDB4OTUxNTViNjcsIDB4NDk0YTQ4OGMsIDB4YjliNmE4MGMsIDB4NWM4ZjgyYmMsIDB4ODlkMzZiNDUsXG4gICAgMHgzYTYwOTQzNywgMHhlYzAwYzlhOSwgMHg0NDcxNTI1MywgMHgwYTg3NGI0OSwgMHhkNzczYmM0MCwgMHg3YzM0NjcxYywgMHgwMjcxN2VmNiwgMHg0ZmViNTUzNixcbiAgICAweGEyZDAyZmZmLCAweGQyYmY2MGM0LCAweGQ0M2YwM2MwLCAweDUwYjRlZjZkLCAweDA3NDc4Y2QxLCAweDAwNmUxODg4LCAweGEyZTUzZjU1LCAweGI5ZTZkNGJjLFxuICAgIDB4YTIwNDgwMTYsIDB4OTc1NzM4MzMsIDB4ZDcyMDdkNjcsIDB4ZGUwZjhmM2QsIDB4NzJmODdiMzMsIDB4YWJjYzRmMzMsIDB4NzY4OGM1NWQsIDB4N2IwMGE2YjAsXG4gICAgMHg5NDdiMDAwMSwgMHg1NzAwNzVkMiwgMHhmOWJiODhmOCwgMHg4OTQyMDE5ZSwgMHg0MjY0YTVmZiwgMHg4NTYzMDJlMCwgMHg3MmRiZDkyYiwgMHhlZTk3MWI2OSxcbiAgICAweDZlYTIyZmRlLCAweDVmMDhhZTJiLCAweGFmN2E2MTZkLCAweGU1Yzk4NzY3LCAweGNmMWZlYmQyLCAweDYxZWZjOGMyLCAweGYxYWMyNTcxLCAweGNjODIzOWMyLFxuICAgIDB4NjcyMTRjYjgsIDB4YjFlNTgzZDEsIDB4YjdkYzNlNjIsIDB4N2YxMGJkY2UsIDB4ZjkwYTVjMzgsIDB4MGZmMDQ0M2QsIDB4NjA2ZTZkYzYsIDB4NjA1NDNhNDksXG4gICAgMHg1NzI3YzE0OCwgMHgyYmU5OGExZCwgMHg4YWI0MTczOCwgMHgyMGUxYmUyNCwgMHhhZjk2ZGEwZiwgMHg2ODQ1ODQyNSwgMHg5OTgzM2JlNSwgMHg2MDBkNDU3ZCxcbiAgICAweDI4MmY5MzUwLCAweDgzMzRiMzYyLCAweGQ5MWQxMTIwLCAweDJiNmQ4ZGEwLCAweDY0MmIxZTMxLCAweDljMzA1YTAwLCAweDUyYmNlNjg4LCAweDFiMDM1ODhhLFxuICAgIDB4ZjdiYWVmZDUsIDB4NDE0MmVkOWMsIDB4YTQzMTVjMTEsIDB4ODMzMjNlYzUsIDB4ZGZlZjQ2MzYsIDB4YTEzM2M1MDEsIDB4ZTlkMzUzMWMsIDB4ZWUzNTM3ODMpO1xuXG4gIHNCb3hbM10gPSBuZXcgQXJyYXkoXG4gICAgMHg5ZGIzMDQyMCwgMHgxZmI2ZTlkZSwgMHhhN2JlN2JlZiwgMHhkMjczYTI5OCwgMHg0YTRmN2JkYiwgMHg2NGFkOGM1NywgMHg4NTUxMDQ0MywgMHhmYTAyMGVkMSxcbiAgICAweDdlMjg3YWZmLCAweGU2MGZiNjYzLCAweDA5NWYzNWExLCAweDc5ZWJmMTIwLCAweGZkMDU5ZDQzLCAweDY0OTdiN2IxLCAweGYzNjQxZjYzLCAweDI0MWU0YWRmLFxuICAgIDB4MjgxNDdmNWYsIDB4NGZhMmI4Y2QsIDB4Yzk0MzAwNDAsIDB4MGNjMzIyMjAsIDB4ZmRkMzBiMzAsIDB4YzBhNTM3NGYsIDB4MWQyZDAwZDksIDB4MjQxNDdiMTUsXG4gICAgMHhlZTRkMTExYSwgMHgwZmNhNTE2NywgMHg3MWZmOTA0YywgMHgyZDE5NWZmZSwgMHgxYTA1NjQ1ZiwgMHgwYzEzZmVmZSwgMHgwODFiMDhjYSwgMHgwNTE3MDEyMSxcbiAgICAweDgwNTMwMTAwLCAweGU4M2U1ZWZlLCAweGFjOWFmNGY4LCAweDdmZTcyNzAxLCAweGQyYjhlZTVmLCAweDA2ZGY0MjYxLCAweGJiOWU5YjhhLCAweDcyOTNlYTI1LFxuICAgIDB4Y2U4NGZmZGYsIDB4ZjU3MTg4MDEsIDB4M2RkNjRiMDQsIDB4YTI2ZjI2M2IsIDB4N2VkNDg0MDAsIDB4NTQ3ZWViZTYsIDB4NDQ2ZDRjYTAsIDB4NmNmM2Q2ZjUsXG4gICAgMHgyNjQ5YWJkZiwgMHhhZWEwYzdmNSwgMHgzNjMzOGNjMSwgMHg1MDNmN2U5MywgMHhkMzc3MjA2MSwgMHgxMWI2MzhlMSwgMHg3MjUwMGUwMywgMHhmODBlYjJiYixcbiAgICAweGFiZTA1MDJlLCAweGVjOGQ3N2RlLCAweDU3OTcxZTgxLCAweGUxNGY2NzQ2LCAweGM5MzM1NDAwLCAweDY5MjAzMThmLCAweDA4MWRiYjk5LCAweGZmYzMwNGE1LFxuICAgIDB4NGQzNTE4MDUsIDB4N2YzZDVjZTMsIDB4YTZjODY2YzYsIDB4NWQ1YmNjYTksIDB4ZGFlYzZmZWEsIDB4OWY5MjZmOTEsIDB4OWY0NjIyMmYsIDB4Mzk5MTQ2N2QsXG4gICAgMHhhNWJmNmQ4ZSwgMHgxMTQzYzQ0ZiwgMHg0Mzk1ODMwMiwgMHhkMDIxNGVlYiwgMHgwMjIwODNiOCwgMHgzZmI2MTgwYywgMHgxOGY4OTMxZSwgMHgyODE2NThlNixcbiAgICAweDI2NDg2ZTNlLCAweDhiZDc4YTcwLCAweDc0NzdlNGMxLCAweGI1MDZlMDdjLCAweGYzMmQwYTI1LCAweDc5MDk4YjAyLCAweGU0ZWFiYjgxLCAweDI4MTIzYjIzLFxuICAgIDB4NjlkZWFkMzgsIDB4MTU3NGNhMTYsIDB4ZGY4NzFiNjIsIDB4MjExYzQwYjcsIDB4YTUxYTllZjksIDB4MDAxNDM3N2IsIDB4MDQxZThhYzgsIDB4MDkxMTQwMDMsXG4gICAgMHhiZDU5ZTRkMiwgMHhlM2QxNTZkNSwgMHg0ZmU4NzZkNSwgMHgyZjkxYTM0MCwgMHg1NTdiZThkZSwgMHgwMGVhZTRhNywgMHgwY2U1YzJlYywgMHg0ZGI0YmJhNixcbiAgICAweGU3NTZiZGZmLCAweGRkMzM2OWFjLCAweGVjMTdiMDM1LCAweDA2NTcyMzI3LCAweDk5YWZjOGIwLCAweDU2YzhjMzkxLCAweDZiNjU4MTFjLCAweDVlMTQ2MTE5LFxuICAgIDB4NmU4NWNiNzUsIDB4YmUwN2MwMDIsIDB4YzIzMjU1NzcsIDB4ODkzZmY0ZWMsIDB4NWJiZmM5MmQsIDB4ZDBlYzNiMjUsIDB4Yjc4MDFhYjcsIDB4OGQ2ZDNiMjQsXG4gICAgMHgyMGM3NjNlZiwgMHhjMzY2YTVmYywgMHg5YzM4Mjg4MCwgMHgwYWNlMzIwNSwgMHhhYWM5NTQ4YSwgMHhlY2ExZDdjNywgMHgwNDFhZmEzMiwgMHgxZDE2NjI1YSxcbiAgICAweDY3MDE5MDJjLCAweDliNzU3YTU0LCAweDMxZDQ3N2Y3LCAweDkxMjZiMDMxLCAweDM2Y2M2ZmRiLCAweGM3MGI4YjQ2LCAweGQ5ZTY2YTQ4LCAweDU2ZTU1YTc5LFxuICAgIDB4MDI2YTRjZWIsIDB4NTI0MzdlZmYsIDB4MmY4Zjc2YjQsIDB4MGRmOTgwYTUsIDB4ODY3NGNkZTMsIDB4ZWRkYTA0ZWIsIDB4MTdhOWJlMDQsIDB4MmMxOGY0ZGYsXG4gICAgMHhiNzc0N2Y5ZCwgMHhhYjJhZjdiNCwgMHhlZmMzNGQyMCwgMHgyZTA5NmI3YywgMHgxNzQxYTI1NCwgMHhlNWI2YTAzNSwgMHgyMTNkNDJmNiwgMHgyYzFjN2MyNixcbiAgICAweDYxYzJmNTBmLCAweDY1NTJkYWY5LCAweGQyYzIzMWY4LCAweDI1MTMwZjY5LCAweGQ4MTY3ZmEyLCAweDA0MThmMmM4LCAweDAwMWE5NmE2LCAweDBkMTUyNmFiLFxuICAgIDB4NjMzMTVjMjEsIDB4NWUwYTcyZWMsIDB4NDliYWZlZmQsIDB4MTg3OTA4ZDksIDB4OGQwZGJkODYsIDB4MzExMTcwYTcsIDB4M2U5YjY0MGMsIDB4Y2MzZTEwZDcsXG4gICAgMHhkNWNhZDNiNiwgMHgwY2FlYzM4OCwgMHhmNzMwMDFlMSwgMHg2YzcyOGFmZiwgMHg3MWVhZTJhMSwgMHgxZjlhZjM2ZSwgMHhjZmNiZDEyZiwgMHhjMWRlODQxNyxcbiAgICAweGFjMDdiZTZiLCAweGNiNDRhMWQ4LCAweDhiOWIwZjU2LCAweDAxMzk4OGMzLCAweGIxYzUyZmNhLCAweGI0YmUzMWNkLCAweGQ4NzgyODA2LCAweDEyYTNhNGUyLFxuICAgIDB4NmY3ZGU1MzIsIDB4NThmZDdlYjYsIDB4ZDAxZWU5MDAsIDB4MjRhZGZmYzIsIDB4ZjQ5OTBmYzUsIDB4OTcxMWFhYzUsIDB4MDAxZDdiOTUsIDB4ODJlNWU3ZDIsXG4gICAgMHgxMDk4NzNmNiwgMHgwMDYxMzA5NiwgMHhjMzJkOTUyMSwgMHhhZGExMjFmZiwgMHgyOTkwODQxNSwgMHg3ZmJiOTc3ZiwgMHhhZjllYjNkYiwgMHgyOWM5ZWQyYSxcbiAgICAweDVjZTJhNDY1LCAweGE3MzBmMzJjLCAweGQwYWEzZmU4LCAweDhhNWNjMDkxLCAweGQ0OWUyY2U3LCAweDBjZTQ1NGE5LCAweGQ2MGFjZDg2LCAweDAxNWYxOTE5LFxuICAgIDB4NzcwNzkxMDMsIDB4ZGVhMDNhZjYsIDB4NzhhODU2NWUsIDB4ZGVlMzU2ZGYsIDB4MjFmMDVjYmUsIDB4OGI3NWUzODcsIDB4YjNjNTA2NTEsIDB4YjhhNWMzZWYsXG4gICAgMHhkOGVlYjZkMiwgMHhlNTIzYmU3NywgMHhjMjE1NDUyOSwgMHgyZjY5ZWZkZiwgMHhhZmU2N2FmYiwgMHhmNDcwYzRiMiwgMHhmM2UwZWI1YiwgMHhkNmNjOTg3NixcbiAgICAweDM5ZTQ0NjBjLCAweDFmZGE4NTM4LCAweDE5ODc4MzJmLCAweGNhMDA3MzY3LCAweGE5OTE0NGY4LCAweDI5NmIyOTllLCAweDQ5MmZjMjk1LCAweDkyNjZiZWFiLFxuICAgIDB4YjU2NzZlNjksIDB4OWJkM2RkZGEsIDB4ZGY3ZTA1MmYsIDB4ZGIyNTcwMWMsIDB4MWI1ZTUxZWUsIDB4ZjY1MzI0ZTYsIDB4NmFmY2UzNmMsIDB4MDMxNmNjMDQsXG4gICAgMHg4NjQ0MjEzZSwgMHhiN2RjNTlkMCwgMHg3OTY1MjkxZiwgMHhjY2Q2ZmQ0MywgMHg0MTgyMzk3OSwgMHg5MzJiY2RmNiwgMHhiNjU3YzM0ZCwgMHg0ZWRmZDI4MixcbiAgICAweDdhZTUyOTBjLCAweDNjYjk1MzZiLCAweDg1MWUyMGZlLCAweDk4MzM1NTdlLCAweDEzZWNmMGIwLCAweGQzZmZiMzcyLCAweDNmODVjNWMxLCAweDBhZWY3ZWQyKTtcblxuICBzQm94WzRdID0gbmV3IEFycmF5KFxuICAgIDB4N2VjOTBjMDQsIDB4MmM2ZTc0YjksIDB4OWIwZTY2ZGYsIDB4YTYzMzc5MTEsIDB4Yjg2YTdmZmYsIDB4MWRkMzU4ZjUsIDB4NDRkZDlkNDQsIDB4MTczMTE2N2YsXG4gICAgMHgwOGZiZjFmYSwgMHhlN2Y1MTFjYywgMHhkMjA1MWIwMCwgMHg3MzVhYmEwMCwgMHgyYWI3MjJkOCwgMHgzODYzODFjYiwgMHhhY2Y2MjQzYSwgMHg2OWJlZmQ3YSxcbiAgICAweGU2YTJlNzdmLCAweGYwYzcyMGNkLCAweGM0NDk0ODE2LCAweGNjZjVjMTgwLCAweDM4ODUxNjQwLCAweDE1YjBhODQ4LCAweGU2OGIxOGNiLCAweDRjYWFkZWZmLFxuICAgIDB4NWY0ODBhMDEsIDB4MDQxMmIyYWEsIDB4MjU5ODE0ZmMsIDB4NDFkMGVmZTIsIDB4NGU0MGI0OGQsIDB4MjQ4ZWI2ZmIsIDB4OGRiYTFjZmUsIDB4NDFhOTliMDIsXG4gICAgMHgxYTU1MGEwNCwgMHhiYThmNjVjYiwgMHg3MjUxZjRlNywgMHg5NWE1MTcyNSwgMHhjMTA2ZWNkNywgMHg5N2E1OTgwYSwgMHhjNTM5YjlhYSwgMHg0ZDc5ZmU2YSxcbiAgICAweGYyZjNmNzYzLCAweDY4YWY4MDQwLCAweGVkMGM5ZTU2LCAweDExYjQ5NThiLCAweGUxZWI1YTg4LCAweDg3MDllNmIwLCAweGQ3ZTA3MTU2LCAweDRlMjlmZWE3LFxuICAgIDB4NjM2NmU1MmQsIDB4MDJkMWMwMDAsIDB4YzRhYzhlMDUsIDB4OTM3N2Y1NzEsIDB4MGMwNTM3MmEsIDB4NTc4NTM1ZjIsIDB4MjI2MWJlMDIsIDB4ZDY0MmEwYzksXG4gICAgMHhkZjEzYTI4MCwgMHg3NGI1NWJkMiwgMHg2ODIxOTljMCwgMHhkNDIxZTVlYywgMHg1M2ZiM2NlOCwgMHhjOGFkZWRiMywgMHgyOGE4N2ZjOSwgMHgzZDk1OTk4MSxcbiAgICAweDVjMWZmOTAwLCAweGZlMzhkMzk5LCAweDBjNGVmZjBiLCAweDA2MjQwN2VhLCAweGFhMmY0ZmIxLCAweDRmYjk2OTc2LCAweDkwYzc5NTA1LCAweGIwYThhNzc0LFxuICAgIDB4ZWY1NWExZmYsIDB4ZTU5Y2EyYzIsIDB4YTZiNjJkMjcsIDB4ZTY2YTQyNjMsIDB4ZGY2NTAwMWYsIDB4MGVjNTA5NjYsIDB4ZGZkZDU1YmMsIDB4MjlkZTA2NTUsXG4gICAgMHg5MTFlNzM5YSwgMHgxN2FmODk3NSwgMHgzMmM3OTExYywgMHg4OWY4OTQ2OCwgMHgwZDAxZTk4MCwgMHg1MjQ3NTVmNCwgMHgwM2I2M2NjOSwgMHgwY2M4NDRiMixcbiAgICAweGJjZjNmMGFhLCAweDg3YWMzNmU5LCAweGU1M2E3NDI2LCAweDAxYjNkODJiLCAweDFhOWU3NDQ5LCAweDY0ZWUyZDdlLCAweGNkZGJiMWRhLCAweDAxYzk0OTEwLFxuICAgIDB4Yjg2OGJmODAsIDB4MGQyNmYzZmQsIDB4OTM0MmVkZTcsIDB4MDRhNWMyODQsIDB4NjM2NzM3YjYsIDB4NTBmNWI2MTYsIDB4ZjI0NzY2ZTMsIDB4OGVjYTM2YzEsXG4gICAgMHgxMzZlMDVkYiwgMHhmZWYxODM5MSwgMHhmYjg4N2EzNywgMHhkNmU3ZjdkNCwgMHhjN2ZiN2RjOSwgMHgzMDYzZmNkZiwgMHhiNmY1ODlkZSwgMHhlYzI5NDFkYSxcbiAgICAweDI2ZTQ2Njk1LCAweGI3NTY2NDE5LCAweGY2NTRlZmM1LCAweGQwOGQ1OGI3LCAweDQ4OTI1NDAxLCAweGMxYmFjYjdmLCAweGU1ZmY1NTBmLCAweGI2MDgzMDQ5LFxuICAgIDB4NWJiNWQwZTgsIDB4ODdkNzJlNWEsIDB4YWI2YTZlZTEsIDB4MjIzYTY2Y2UsIDB4YzYyYmYzY2QsIDB4OWUwODg1ZjksIDB4NjhjYjNlNDcsIDB4MDg2YzAxMGYsXG4gICAgMHhhMjFkZTgyMCwgMHhkMThiNjlkZSwgMHhmM2Y2NTc3NywgMHhmYTAyYzNmNiwgMHg0MDdlZGFjMywgMHhjYmIzZDU1MCwgMHgxNzkzMDg0ZCwgMHhiMGQ3MGViYSxcbiAgICAweDBhYjM3OGQ1LCAweGQ5NTFmYjBjLCAweGRlZDdkYTU2LCAweDQxMjRiYmU0LCAweDk0Y2EwYjU2LCAweDBmNTc1NWQxLCAweGUwZTFlNTZlLCAweDYxODRiNWJlLFxuICAgIDB4NTgwYTI0OWYsIDB4OTRmNzRiYzAsIDB4ZTMyNzg4OGUsIDB4OWY3YjU1NjEsIDB4YzNkYzAyODAsIDB4MDU2ODc3MTUsIDB4NjQ2YzZiZDcsIDB4NDQ5MDRkYjMsXG4gICAgMHg2NmI0ZjBhMywgMHhjMGYxNjQ4YSwgMHg2OTdlZDVhZiwgMHg0OWU5MmZmNiwgMHgzMDllMzc0ZiwgMHgyY2I2MzU2YSwgMHg4NTgwODU3MywgMHg0OTkxZjg0MCxcbiAgICAweDc2ZjBhZTAyLCAweDA4M2JlODRkLCAweDI4NDIxYzlhLCAweDQ0NDg5NDA2LCAweDczNmU0Y2I4LCAweGMxMDkyOTEwLCAweDhiYzk1ZmM2LCAweDdkODY5Y2Y0LFxuICAgIDB4MTM0ZjYxNmYsIDB4MmU3NzExOGQsIDB4YjMxYjJiZTEsIDB4YWE5MGI0NzIsIDB4M2NhNWQ3MTcsIDB4N2QxNjFiYmEsIDB4OWNhZDkwMTAsIDB4YWY0NjJiYTIsXG4gICAgMHg5ZmU0NTlkMiwgMHg0NWQzNDU1OSwgMHhkOWYyZGExMywgMHhkYmM2NTQ4NywgMHhmM2U0Zjk0ZSwgMHgxNzZkNDg2ZiwgMHgwOTdjMTNlYSwgMHg2MzFkYTVjNyxcbiAgICAweDQ0NWY3MzgyLCAweDE3NTY4M2Y0LCAweGNkYzY2YTk3LCAweDcwYmUwMjg4LCAweGIzY2RjZjcyLCAweDZlNWRkMmYzLCAweDIwOTM2MDc5LCAweDQ1OWI4MGE1LFxuICAgIDB4YmU2MGUyZGIsIDB4YTljMjMxMDEsIDB4ZWJhNTMxNWMsIDB4MjI0ZTQyZjIsIDB4MWM1YzE1NzIsIDB4ZjY3MjFiMmMsIDB4MWFkMmZmZjMsIDB4OGMyNTQwNGUsXG4gICAgMHgzMjRlZDcyZiwgMHg0MDY3YjdmZCwgMHgwNTIzMTM4ZSwgMHg1Y2EzYmM3OCwgMHhkYzBmZDY2ZSwgMHg3NTkyMjI4MywgMHg3ODRkNmIxNywgMHg1OGViYjE2ZSxcbiAgICAweDQ0MDk0Zjg1LCAweDNmNDgxZDg3LCAweGZjZmVhZTdiLCAweDc3YjVmZjc2LCAweDhjMjMwMmJmLCAweGFhZjQ3NTU2LCAweDVmNDZiMDJhLCAweDJiMDkyODAxLFxuICAgIDB4M2QzOGY1ZjcsIDB4MGNhODFmMzYsIDB4NTJhZjRhOGEsIDB4NjZkNWU3YzAsIDB4ZGYzYjA4NzQsIDB4OTUwNTUxMTAsIDB4MWI1YWQ3YTgsIDB4ZjYxZWQ1YWQsXG4gICAgMHg2Y2Y2ZTQ3OSwgMHgyMDc1ODE4NCwgMHhkMGNlZmE2NSwgMHg4OGY3YmU1OCwgMHg0YTA0NjgyNiwgMHgwZmY2ZjhmMywgMHhhMDljN2Y3MCwgMHg1MzQ2YWJhMCxcbiAgICAweDVjZTk2YzI4LCAweGUxNzZlZGEzLCAweDZiYWMzMDdmLCAweDM3NjgyOWQyLCAweDg1MzYwZmE5LCAweDE3ZTNmZTJhLCAweDI0Yjc5NzY3LCAweGY1YTk2YjIwLFxuICAgIDB4ZDZjZDI1OTUsIDB4NjhmZjFlYmYsIDB4NzU1NTQ0MmMsIDB4ZjE5ZjA2YmUsIDB4ZjllMDY1OWEsIDB4ZWViOTQ5MWQsIDB4MzQwMTA3MTgsIDB4YmIzMGNhYjgsXG4gICAgMHhlODIyZmUxNSwgMHg4ODU3MDk4MywgMHg3NTBlNjI0OSwgMHhkYTYyN2U1NSwgMHg1ZTc2ZmZhOCwgMHhiMTUzNDU0NiwgMHg2ZDQ3ZGUwOCwgMHhlZmU5ZTdkNCk7XG5cbiAgc0JveFs1XSA9IG5ldyBBcnJheShcbiAgICAweGY2ZmE4ZjlkLCAweDJjYWM2Y2UxLCAweDRjYTM0ODY3LCAweGUyMzM3ZjdjLCAweDk1ZGIwOGU3LCAweDAxNjg0M2I0LCAweGVjZWQ1Y2JjLCAweDMyNTU1M2FjLFxuICAgIDB4YmY5ZjA5NjAsIDB4ZGZhMWUyZWQsIDB4ODNmMDU3OWQsIDB4NjNlZDg2YjksIDB4MWFiNmE2YjgsIDB4ZGU1ZWJlMzksIDB4ZjM4ZmY3MzIsIDB4ODk4OWIxMzgsXG4gICAgMHgzM2YxNDk2MSwgMHhjMDE5MzdiZCwgMHhmNTA2YzZkYSwgMHhlNDYyNWU3ZSwgMHhhMzA4ZWE5OSwgMHg0ZTIzZTMzYywgMHg3OWNiZDdjYywgMHg0OGExNDM2NyxcbiAgICAweGEzMTQ5NjE5LCAweGZlYzk0YmQ1LCAweGExMTQxNzRhLCAweGVhYTAxODY2LCAweGEwODRkYjJkLCAweDA5YTg0ODZmLCAweGE4ODg2MTRhLCAweDI5MDBhZjk4LFxuICAgIDB4MDE2NjU5OTEsIDB4ZTE5OTI4NjMsIDB4YzhmMzBjNjAsIDB4MmU3OGVmM2MsIDB4ZDBkNTE5MzIsIDB4Y2YwZmVjMTQsIDB4ZjdjYTA3ZDIsIDB4ZDBhODIwNzIsXG4gICAgMHhmZDQxMTk3ZSwgMHg5MzA1YTZiMCwgMHhlODZiZTNkYSwgMHg3NGJlZDNjZCwgMHgzNzJkYTUzYywgMHg0YzdmNDQ0OCwgMHhkYWI1ZDQ0MCwgMHg2ZGJhMGVjMyxcbiAgICAweDA4MzkxOWE3LCAweDlmYmFlZWQ5LCAweDQ5ZGJjZmIwLCAweDRlNjcwYzUzLCAweDVjM2Q5YzAxLCAweDY0YmRiOTQxLCAweDJjMGU2MzZhLCAweGJhN2RkOWNkLFxuICAgIDB4ZWE2ZjczODgsIDB4ZTcwYmM3NjIsIDB4MzVmMjlhZGIsIDB4NWM0Y2RkOGQsIDB4ZjBkNDhkOGMsIDB4Yjg4MTUzZTIsIDB4MDhhMTk4NjYsIDB4MWFlMmVhYzgsXG4gICAgMHgyODRjYWY4OSwgMHhhYTkyODIyMywgMHg5MzM0YmU1MywgMHgzYjNhMjFiZiwgMHgxNjQzNGJlMywgMHg5YWVhMzkwNiwgMHhlZmU4YzM2ZSwgMHhmODkwY2RkOSxcbiAgICAweDgwMjI2ZGFlLCAweGMzNDBhNGEzLCAweGRmN2U5YzA5LCAweGE2OTRhODA3LCAweDViN2M1ZWNjLCAweDIyMWRiM2E2LCAweDlhNjlhMDJmLCAweDY4ODE4YTU0LFxuICAgIDB4Y2ViMjI5NmYsIDB4NTNjMDg0M2EsIDB4ZmU4OTM2NTUsIDB4MjViZmU2OGEsIDB4YjQ2MjhhYmMsIDB4Y2YyMjJlYmYsIDB4MjVhYzZmNDgsIDB4YTlhOTkzODcsXG4gICAgMHg1M2JkZGI2NSwgMHhlNzZmZmJlNywgMHhlOTY3ZmQ3OCwgMHgwYmE5MzU2MywgMHg4ZTM0MmJjMSwgMHhlOGExMWJlOSwgMHg0OTgwNzQwZCwgMHhjODA4N2RmYyxcbiAgICAweDhkZTRiZjk5LCAweGExMTEwMWEwLCAweDdmZDM3OTc1LCAweGRhNWEyNmMwLCAweGU4MWY5OTRmLCAweDk1MjhjZDg5LCAweGZkMzM5ZmVkLCAweGI4NzgzNGJmLFxuICAgIDB4NWYwNDQ1NmQsIDB4MjIyNTg2OTgsIDB4YzljNGM4M2IsIDB4MmRjMTU2YmUsIDB4NGY2MjhkYWEsIDB4NTdmNTVlYzUsIDB4ZTIyMjBhYmUsIDB4ZDI5MTZlYmYsXG4gICAgMHg0ZWM3NWI5NSwgMHgyNGYyYzNjMCwgMHg0MmQxNWQ5OSwgMHhjZDBkN2ZhMCwgMHg3YjZlMjdmZiwgMHhhOGRjOGFmMCwgMHg3MzQ1YzEwNiwgMHhmNDFlMjMyZixcbiAgICAweDM1MTYyMzg2LCAweGU2ZWE4OTI2LCAweDMzMzNiMDk0LCAweDE1N2VjNmYyLCAweDM3MmI3NGFmLCAweDY5MjU3M2U0LCAweGU5YTlkODQ4LCAweGYzMTYwMjg5LFxuICAgIDB4M2E2MmVmMWQsIDB4YTc4N2UyMzgsIDB4ZjNhNWY2NzYsIDB4NzQzNjQ4NTMsIDB4MjA5NTEwNjMsIDB4NDU3NjY5OGQsIDB4YjZmYWQ0MDcsIDB4NTkyYWY5NTAsXG4gICAgMHgzNmY3MzUyMywgMHg0Y2ZiNmU4NywgMHg3ZGE0Y2VjMCwgMHg2YzE1MmRhYSwgMHhjYjAzOTZhOCwgMHhjNTBkZmU1ZCwgMHhmY2Q3MDdhYiwgMHgwOTIxYzQyZixcbiAgICAweDg5ZGZmMGJiLCAweDVmZTJiZTc4LCAweDQ0OGY0ZjMzLCAweDc1NDYxM2M5LCAweDJiMDVkMDhkLCAweDQ4YjlkNTg1LCAweGRjMDQ5NDQxLCAweGM4MDk4ZjliLFxuICAgIDB4N2RlZGU3ODYsIDB4YzM5YTMzNzMsIDB4NDI0MTAwMDUsIDB4NmEwOTE3NTEsIDB4MGVmM2M4YTYsIDB4ODkwMDcyZDYsIDB4MjgyMDc2ODIsIDB4YTlhOWY3YmUsXG4gICAgMHhiZjMyNjc5ZCwgMHhkNDViNWI3NSwgMHhiMzUzZmQwMCwgMHhjYmIwZTM1OCwgMHg4MzBmMjIwYSwgMHgxZjhmYjIxNCwgMHhkMzcyY2YwOCwgMHhjYzNjNGExMyxcbiAgICAweDhjZjYzMTY2LCAweDA2MWM4N2JlLCAweDg4Yzk4Zjg4LCAweDYwNjJlMzk3LCAweDQ3Y2Y4ZTdhLCAweGI2Yzg1MjgzLCAweDNjYzJhY2ZiLCAweDNmYzA2OTc2LFxuICAgIDB4NGU4ZjAyNTIsIDB4NjRkODMxNGQsIDB4ZGEzODcwZTMsIDB4MWU2NjU0NTksIDB4YzEwOTA4ZjAsIDB4NTEzMDIxYTUsIDB4NmM1YjY4YjcsIDB4ODIyZjhhYTAsXG4gICAgMHgzMDA3Y2QzZSwgMHg3NDcxOWVlZiwgMHhkYzg3MjY4MSwgMHgwNzMzNDBkNCwgMHg3ZTQzMmZkOSwgMHgwYzVlYzI0MSwgMHg4ODA5Mjg2YywgMHhmNTkyZDg5MSxcbiAgICAweDA4YTkzMGY2LCAweDk1N2VmMzA1LCAweGI3ZmJmZmJkLCAweGMyNjZlOTZmLCAweDZmZTRhYzk4LCAweGIxNzNlY2MwLCAweGJjNjBiNDJhLCAweDk1MzQ5OGRhLFxuICAgIDB4ZmJhMWFlMTIsIDB4MmQ0YmQ3MzYsIDB4MGYyNWZhYWIsIDB4YTRmM2ZjZWIsIDB4ZTI5NjkxMjMsIDB4MjU3ZjBjM2QsIDB4OTM0OGFmNDksIDB4MzYxNDAwYmMsXG4gICAgMHhlODgxNmY0YSwgMHgzODE0ZjIwMCwgMHhhM2Y5NDA0MywgMHg5YzdhNTRjMiwgMHhiYzcwNGY1NywgMHhkYTQxZTdmOSwgMHhjMjVhZDMzYSwgMHg1NGY0YTA4NCxcbiAgICAweGIxN2Y1NTA1LCAweDU5MzU3Y2JlLCAweGVkYmQxNWM4LCAweDdmOTdjNWFiLCAweGJhNWFjN2I1LCAweGI2ZjZkZWFmLCAweDNhNDc5YzNhLCAweDUzMDJkYTI1LFxuICAgIDB4NjUzZDdlNmEsIDB4NTQyNjhkNDksIDB4NTFhNDc3ZWEsIDB4NTAxN2Q1NWIsIDB4ZDdkMjVkODgsIDB4NDQxMzZjNzYsIDB4MDQwNGE4YzgsIDB4YjhlNWExMjEsXG4gICAgMHhiODFhOTI4YSwgMHg2MGVkNTg2OSwgMHg5N2M1NWI5NiwgMHhlYWVjOTkxYiwgMHgyOTkzNTkxMywgMHgwMWZkYjdmMSwgMHgwODhlOGRmYSwgMHg5YWI2ZjZmNSxcbiAgICAweDNiNGNiZjlmLCAweDRhNWRlM2FiLCAweGU2MDUxZDM1LCAweGEwZTFkODU1LCAweGQzNmI0Y2YxLCAweGY1NDRlZGViLCAweGIwZTkzNTI0LCAweGJlYmI4ZmJkLFxuICAgIDB4YTJkNzYyY2YsIDB4NDljOTJmNTQsIDB4MzhiNWYzMzEsIDB4NzEyOGE0NTQsIDB4NDgzOTI5MDUsIDB4YTY1YjFkYjgsIDB4ODUxYzk3YmQsIDB4ZDY3NWNmMmYpO1xuXG4gIHNCb3hbNl0gPSBuZXcgQXJyYXkoXG4gICAgMHg4NWUwNDAxOSwgMHgzMzJiZjU2NywgMHg2NjJkYmZmZiwgMHhjZmM2NTY5MywgMHgyYThkN2Y2ZiwgMHhhYjliYzkxMiwgMHhkZTYwMDhhMSwgMHgyMDI4ZGExZixcbiAgICAweDAyMjdiY2U3LCAweDRkNjQyOTE2LCAweDE4ZmFjMzAwLCAweDUwZjE4YjgyLCAweDJjYjJjYjExLCAweGIyMzJlNzVjLCAweDRiMzY5NWYyLCAweGIyODcwN2RlLFxuICAgIDB4YTA1ZmJjZjYsIDB4Y2Q0MTgxZTksIDB4ZTE1MDIxMGMsIDB4ZTI0ZWYxYmQsIDB4YjE2OGMzODEsIDB4ZmRlNGU3ODksIDB4NWM3OWIwZDgsIDB4MWU4YmZkNDMsXG4gICAgMHg0ZDQ5NTAwMSwgMHgzOGJlNDM0MSwgMHg5MTNjZWUxZCwgMHg5MmE3OWMzZiwgMHgwODk3NjZiZSwgMHhiYWVlYWRmNCwgMHgxMjg2YmVjZiwgMHhiNmVhY2IxOSxcbiAgICAweDI2NjBjMjAwLCAweDc1NjViZGU0LCAweDY0MjQxZjdhLCAweDgyNDhkY2E5LCAweGMzYjNhZDY2LCAweDI4MTM2MDg2LCAweDBiZDhkZmE4LCAweDM1NmQxY2YyLFxuICAgIDB4MTA3Nzg5YmUsIDB4YjNiMmU5Y2UsIDB4MDUwMmFhOGYsIDB4MGJjMDM1MWUsIDB4MTY2YmY1MmEsIDB4ZWIxMmZmODIsIDB4ZTM0ODY5MTEsIDB4ZDM0ZDc1MTYsXG4gICAgMHg0ZTdiM2FmZiwgMHg1ZjQzNjcxYiwgMHg5Y2Y2ZTAzNywgMHg0OTgxYWM4MywgMHgzMzQyNjZjZSwgMHg4YzkzNDFiNywgMHhkMGQ4NTRjMCwgMHhjYjNhNmM4OCxcbiAgICAweDQ3YmMyODI5LCAweDQ3MjViYTM3LCAweGE2NmFkMjJiLCAweDdhZDYxZjFlLCAweDBjNWNiYWZhLCAweDQ0MzdmMTA3LCAweGI2ZTc5OTYyLCAweDQyZDJkODE2LFxuICAgIDB4MGE5NjEyODgsIDB4ZTFhNWMwNmUsIDB4MTM3NDllNjcsIDB4NzJmYzA4MWEsIDB4YjFkMTM5ZjcsIDB4Zjk1ODM3NDUsIDB4Y2YxOWRmNTgsIDB4YmVjM2Y3NTYsXG4gICAgMHhjMDZlYmEzMCwgMHgwNzIxMWIyNCwgMHg0NWMyODgyOSwgMHhjOTVlMzE3ZiwgMHhiYzhlYzUxMSwgMHgzOGJjNDZlOSwgMHhjNmU2ZmExNCwgMHhiYWU4NTg0YSxcbiAgICAweGFkNGViYzQ2LCAweDQ2OGY1MDhiLCAweDc4Mjk0MzVmLCAweGYxMjQxODNiLCAweDgyMWRiYTlmLCAweGFmZjYwZmY0LCAweGVhMmM0ZTZkLCAweDE2ZTM5MjY0LFxuICAgIDB4OTI1NDRhOGIsIDB4MDA5YjRmYzMsIDB4YWJhNjhjZWQsIDB4OWFjOTZmNzgsIDB4MDZhNWI3OWEsIDB4YjI4NTZlNmUsIDB4MWFlYzNjYTksIDB4YmU4Mzg2ODgsXG4gICAgMHgwZTA4MDRlOSwgMHg1NWYxYmU1NiwgMHhlN2U1MzYzYiwgMHhiM2ExZjI1ZCwgMHhmN2RlYmI4NSwgMHg2MWZlMDMzYywgMHgxNjc0NjIzMywgMHgzYzAzNGMyOCxcbiAgICAweGRhNmQwYzc0LCAweDc5YWFjNTZjLCAweDNjZTRlMWFkLCAweDUxZjBjODAyLCAweDk4ZjhmMzVhLCAweDE2MjZhNDlmLCAweGVlZDgyYjI5LCAweDFkMzgyZmUzLFxuICAgIDB4MGM0ZmI5OWEsIDB4YmIzMjU3NzgsIDB4M2VjNmQ5N2IsIDB4NmU3N2E2YTksIDB4Y2I2NThiNWMsIDB4ZDQ1MjMwYzcsIDB4MmJkMTQwOGIsIDB4NjBjMDNlYjcsXG4gICAgMHhiOTA2OGQ3OCwgMHhhMzM3NTRmNCwgMHhmNDMwYzg3ZCwgMHhjOGE3MTMwMiwgMHhiOTZkOGMzMiwgMHhlYmQ0ZTdiZSwgMHhiZThiOWQyZCwgMHg3OTc5ZmIwNixcbiAgICAweGU3MjI1MzA4LCAweDhiNzVjZjc3LCAweDExZWY4ZGE0LCAweGUwODNjODU4LCAweDhkNmI3ODZmLCAweDVhNjMxN2E2LCAweGZhNWNmN2EwLCAweDVkZGEwMDMzLFxuICAgIDB4ZjI4ZWJmYjAsIDB4ZjViOWMzMTAsIDB4YTBlYWMyODAsIDB4MDhiOTc2N2EsIDB4YTNkOWQyYjAsIDB4NzlkMzQyMTcsIDB4MDIxYTcxOGQsIDB4OWFjNjMzNmEsXG4gICAgMHgyNzExZmQ2MCwgMHg0MzgwNTBlMywgMHgwNjk5MDhhOCwgMHgzZDdmZWRjNCwgMHg4MjZkMmJlZiwgMHg0ZWViODQ3NiwgMHg0ODhkY2YyNSwgMHgzNmM5ZDU2NixcbiAgICAweDI4ZTc0ZTQxLCAweGMyNjEwYWNhLCAweDNkNDlhOWNmLCAweGJhZTNiOWRmLCAweGI2NWY4ZGU2LCAweDkyYWVhZjY0LCAweDNhYzdkNWU2LCAweDllYTgwNTA5LFxuICAgIDB4ZjIyYjAxN2QsIDB4YTQxNzNmNzAsIDB4ZGQxZTE2YzMsIDB4MTVlMGQ3ZjksIDB4NTBiMWI4ODcsIDB4MmI5ZjRmZDUsIDB4NjI1YWJhODIsIDB4NmEwMTc5NjIsXG4gICAgMHgyZWMwMWI5YywgMHgxNTQ4OGFhOSwgMHhkNzE2ZTc0MCwgMHg0MDA1NWEyYywgMHg5M2QyOWEyMiwgMHhlMzJkYmY5YSwgMHgwNTg3NDViOSwgMHgzNDUzZGMxZSxcbiAgICAweGQ2OTkyOTZlLCAweDQ5NmNmZjZmLCAweDFjOWY0OTg2LCAweGRmZTJlZDA3LCAweGI4NzI0MmQxLCAweDE5ZGU3ZWFlLCAweDA1M2U1NjFhLCAweDE1YWQ2ZjhjLFxuICAgIDB4NjY2MjZjMWMsIDB4NzE1NGMyNGMsIDB4ZWEwODJiMmEsIDB4OTNlYjI5MzksIDB4MTdkY2IwZjAsIDB4NThkNGYyYWUsIDB4OWVhMjk0ZmIsIDB4NTJjZjU2NGMsXG4gICAgMHg5ODgzZmU2NiwgMHgyZWM0MDU4MSwgMHg3NjM5NTNjMywgMHgwMWQ2NjkyZSwgMHhkM2EwYzEwOCwgMHhhMWU3MTYwZSwgMHhlNGYyZGZhNiwgMHg2OTNlZDI4NSxcbiAgICAweDc0OTA0Njk4LCAweDRjMmIwZWRkLCAweDRmNzU3NjU2LCAweDVkMzkzMzc4LCAweGExMzIyMzRmLCAweDNkMzIxYzVkLCAweGMzZjVlMTk0LCAweDRiMjY5MzAxLFxuICAgIDB4Yzc5ZjAyMmYsIDB4M2M5OTdlN2UsIDB4NWU0Zjk1MDQsIDB4M2ZmYWZiYmQsIDB4NzZmN2FkMGUsIDB4Mjk2NjkzZjQsIDB4M2QxZmNlNmYsIDB4YzYxZTQ1YmUsXG4gICAgMHhkM2I1YWIzNCwgMHhmNzJiZjliNywgMHgxYjA0MzRjMCwgMHg0ZTcyYjU2NywgMHg1NTkyYTMzZCwgMHhiNTIyOTMwMSwgMHhjZmQyYTg3ZiwgMHg2MGFlYjc2NyxcbiAgICAweDE4MTQzODZiLCAweDMwYmNjMzNkLCAweDM4YTBjMDdkLCAweGZkMTYwNmYyLCAweGMzNjM1MTliLCAweDU4OWRkMzkwLCAweDU0NzlmOGU2LCAweDFjYjhkNjQ3LFxuICAgIDB4OTdmZDYxYTksIDB4ZWE3NzU5ZjQsIDB4MmQ1NzUzOWQsIDB4NTY5YTU4Y2YsIDB4ZTg0ZTYzYWQsIDB4NDYyZTFiNzgsIDB4NjU4MGY4N2UsIDB4ZjM4MTc5MTQsXG4gICAgMHg5MWRhNTVmNCwgMHg0MGEyMzBmMywgMHhkMTk4OGYzNSwgMHhiNmUzMThkMiwgMHgzZmZhNTBiYywgMHgzZDQwZjAyMSwgMHhjM2MwYmRhZSwgMHg0OTU4YzI0YyxcbiAgICAweDUxOGYzNmIyLCAweDg0YjFkMzcwLCAweDBmZWRjZTgzLCAweDg3OGRkYWRhLCAweGYyYTI3OWM3LCAweDk0ZTAxYmU4LCAweDkwNzE2ZjRiLCAweDk1NGI4YWEzKTtcblxuICBzQm94WzddID0gbmV3IEFycmF5KFxuICAgIDB4ZTIxNjMwMGQsIDB4YmJkZGZmZmMsIDB4YTdlYmRhYmQsIDB4MzU2NDgwOTUsIDB4Nzc4OWY4YjcsIDB4ZTZjMTEyMWIsIDB4MGUyNDE2MDAsIDB4MDUyY2U4YjUsXG4gICAgMHgxMWE5Y2ZiMCwgMHhlNTk1MmYxMSwgMHhlY2U3OTkwYSwgMHg5Mzg2ZDE3NCwgMHgyYTQyOTMxYywgMHg3NmUzODExMSwgMHhiMTJkZWYzYSwgMHgzN2RkZGRmYyxcbiAgICAweGRlOWFkZWIxLCAweDBhMGNjMzJjLCAweGJlMTk3MDI5LCAweDg0YTAwOTQwLCAweGJiMjQzYTBmLCAweGI0ZDEzN2NmLCAweGI0NGU3OWYwLCAweDA0OWVlZGZkLFxuICAgIDB4MGIxNWExNWQsIDB4NDgwZDMxNjgsIDB4OGJiYmRlNWEsIDB4NjY5ZGVkNDIsIDB4YzdlY2U4MzEsIDB4M2Y4Zjk1ZTcsIDB4NzJkZjE5MWIsIDB4NzU4MDMzMGQsXG4gICAgMHg5NDA3NDI1MSwgMHg1YzdkY2RmYSwgMHhhYmJlNmQ2MywgMHhhYTQwMjE2NCwgMHhiMzAxZDQwYSwgMHgwMmU3ZDFjYSwgMHg1MzU3MWRhZSwgMHg3YTMxODJhMixcbiAgICAweDEyYThkZGVjLCAweGZkYWEzMzVkLCAweDE3NmY0M2U4LCAweDcxZmI0NmQ0LCAweDM4MTI5MDIyLCAweGNlOTQ5YWQ0LCAweGI4NDc2OWFkLCAweDk2NWJkODYyLFxuICAgIDB4ODJmM2QwNTUsIDB4NjZmYjk3NjcsIDB4MTViODBiNGUsIDB4MWQ1YjQ3YTAsIDB4NGNmZGUwNmYsIDB4YzI4ZWM0YjgsIDB4NTdlODcyNmUsIDB4NjQ3YTc4ZmMsXG4gICAgMHg5OTg2NWQ0NCwgMHg2MDhiZDU5MywgMHg2YzIwMGUwMywgMHgzOWRjNWZmNiwgMHg1ZDBiMDBhMywgMHhhZTYzYWZmMiwgMHg3ZThiZDYzMiwgMHg3MDEwOGMwYyxcbiAgICAweGJiZDM1MDQ5LCAweDI5OThkZjA0LCAweDk4MGNmNDJhLCAweDliNmRmNDkxLCAweDllN2VkZDUzLCAweDA2OTE4NTQ4LCAweDU4Y2I3ZTA3LCAweDNiNzRlZjJlLFxuICAgIDB4NTIyZmZmYjEsIDB4ZDI0NzA4Y2MsIDB4MWM3ZTI3Y2QsIDB4YTRlYjIxNWIsIDB4M2NmMWQyZTIsIDB4MTliNDdhMzgsIDB4NDI0Zjc2MTgsIDB4MzU4NTYwMzksXG4gICAgMHg5ZDE3ZGVlNywgMHgyN2ViMzVlNiwgMHhjOWFmZjY3YiwgMHgzNmJhZjViOCwgMHgwOWM0NjdjZCwgMHhjMTg5MTBiMSwgMHhlMTFkYmY3YiwgMHgwNmNkMWFmOCxcbiAgICAweDcxNzBjNjA4LCAweDJkNWUzMzU0LCAweGQ0ZGU0OTVhLCAweDY0YzZkMDA2LCAweGJjYzBjNjJjLCAweDNkZDAwZGIzLCAweDcwOGY4ZjM0LCAweDc3ZDUxYjQyLFxuICAgIDB4MjY0ZjYyMGYsIDB4MjRiOGQyYmYsIDB4MTVjMWI3OWUsIDB4NDZhNTI1NjQsIDB4ZjhkN2U1NGUsIDB4M2UzNzgxNjAsIDB4Nzg5NWNkYTUsIDB4ODU5YzE1YTUsXG4gICAgMHhlNjQ1OTc4OCwgMHhjMzdiYzc1ZiwgMHhkYjA3YmEwYywgMHgwNjc2YTNhYiwgMHg3ZjIyOWIxZSwgMHgzMTg0MmU3YiwgMHgyNDI1OWZkNywgMHhmOGJlZjQ3MixcbiAgICAweDgzNWZmY2I4LCAweDZkZjRjMWYyLCAweDk2ZjViMTk1LCAweGZkMGFmMGZjLCAweGIwZmUxMzRjLCAweGUyNTA2ZDNkLCAweDRmOWIxMmVhLCAweGYyMTVmMjI1LFxuICAgIDB4YTIyMzczNmYsIDB4OWZiNGM0MjgsIDB4MjVkMDQ5NzksIDB4MzRjNzEzZjgsIDB4YzQ2MTgxODcsIDB4ZWE3YTZlOTgsIDB4N2NkMTZlZmMsIDB4MTQzNjg3NmMsXG4gICAgMHhmMTU0NDEwNywgMHhiZWRlZWUxNCwgMHg1NmU5YWYyNywgMHhhMDRhYTQ0MSwgMHgzY2Y3Yzg5OSwgMHg5MmVjYmFlNiwgMHhkZDY3MDE2ZCwgMHgxNTE2ODJlYixcbiAgICAweGE4NDJlZWRmLCAweGZkYmE2MGI0LCAweGYxOTA3Yjc1LCAweDIwZTMwMzBmLCAweDI0ZDhjMjllLCAweGUxMzk2NzNiLCAweGVmYTYzZmI4LCAweDcxODczMDU0LFxuICAgIDB4YjZmMmNmM2IsIDB4OWYzMjY0NDIsIDB4Y2IxNWE0Y2MsIDB4YjAxYTQ1MDQsIDB4ZjFlNDdkOGQsIDB4ODQ0YTFiZTUsIDB4YmFlN2RmZGMsIDB4NDJjYmRhNzAsXG4gICAgMHhjZDdkYWUwYSwgMHg1N2U4NWI3YSwgMHhkNTNmNWFmNiwgMHgyMGNmNGQ4YywgMHhjZWE0ZDQyOCwgMHg3OWQxMzBhNCwgMHgzNDg2ZWJmYiwgMHgzM2QzY2RkYyxcbiAgICAweDc3ODUzYjUzLCAweDM3ZWZmY2I1LCAweGM1MDY4Nzc4LCAweGU1ODBiM2U2LCAweDRlNjhiOGY0LCAweGM1YzhiMzdlLCAweDBkODA5ZWEyLCAweDM5OGZlYjdjLFxuICAgIDB4MTMyYTRmOTQsIDB4NDNiNzk1MGUsIDB4MmZlZTdkMWMsIDB4MjIzNjEzYmQsIDB4ZGQwNmNhYTIsIDB4MzdkZjkzMmIsIDB4YzQyNDgyODksIDB4YWNmM2ViYzMsXG4gICAgMHg1NzE1ZjZiNywgMHhlZjM0NzhkZCwgMHhmMjY3NjE2ZiwgMHhjMTQ4Y2JlNCwgMHg5MDUyODE1ZSwgMHg1ZTQxMGZhYiwgMHhiNDhhMjQ2NSwgMHgyZWRhN2ZhNCxcbiAgICAweGU4N2I0MGU0LCAweGU5OGVhMDg0LCAweDU4ODllOWUxLCAweGVmZDM5MGZjLCAweGRkMDdkMzViLCAweGRiNDg1Njk0LCAweDM4ZDdlNWIyLCAweDU3NzIwMTAxLFxuICAgIDB4NzMwZWRlYmMsIDB4NWI2NDMxMTMsIDB4OTQ5MTdlNGYsIDB4NTAzYzJmYmEsIDB4NjQ2ZjEyODIsIDB4NzUyM2QyNGEsIDB4ZTA3Nzk2OTUsIDB4ZjljMTdhOGYsXG4gICAgMHg3YTViMjEyMSwgMHhkMTg3Yjg5NiwgMHgyOTI2M2E0ZCwgMHhiYTUxMGNkZiwgMHg4MWY0N2M5ZiwgMHhhZDExNjNlZCwgMHhlYTdiNTk2NSwgMHgxYTAwNzI2ZSxcbiAgICAweDExNDAzMDkyLCAweDAwZGE2ZDc3LCAweDRhMGNkZDYxLCAweGFkMWY0NjAzLCAweDYwNWJkZmIwLCAweDllZWRjMzY0LCAweDIyZWJlNmE4LCAweGNlZTdkMjhhLFxuICAgIDB4YTBlNzM2YTAsIDB4NTU2NGE2YjksIDB4MTA4NTMyMDksIDB4YzdlYjhmMzcsIDB4MmRlNzA1Y2EsIDB4ODk1MTU3MGYsIDB4ZGYwOTgyMmIsIDB4YmQ2OTFhNmMsXG4gICAgMHhhYTEyZTRmMiwgMHg4NzQ1MWMwZiwgMHhlMGY2YTI3YSwgMHgzYWRhNDgxOSwgMHg0Y2YxNzY0ZiwgMHgwZDc3MWMyYiwgMHg2N2NkYjE1NiwgMHgzNTBkODM4NCxcbiAgICAweDU5MzhmYTBmLCAweDQyMzk5ZWYzLCAweDM2OTk3YjA3LCAweDBlODQwOTNkLCAweDRhYTkzZTYxLCAweDgzNjBkODdiLCAweDFmYTk4YjBjLCAweDExNDkzODJjLFxuICAgIDB4ZTk3NjI1YTUsIDB4MDYxNGQxYjcsIDB4MGUyNTI0NGIsIDB4MGM3NjgzNDcsIDB4NTg5ZThkODIsIDB4MGQyMDU5ZDEsIDB4YTQ2NmJiMWUsIDB4ZjhkYTBhODIsXG4gICAgMHgwNGYxOTEzMCwgMHhiYTZlNGVjMCwgMHg5OTI2NTE2NCwgMHgxZWU3MjMwZCwgMHg1MGIyYWQ4MCwgMHhlYWVlNjgwMSwgMHg4ZGIyYTI4MywgMHhlYThiZjU5ZSk7XG5cbn07XG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG5mdW5jdGlvbiBjYXN0NShrZXkpIHtcbiAgdGhpcy5jYXN0NSA9IG5ldyBvcGVucGdwX3N5bWVuY19jYXN0NSgpO1xuICB0aGlzLmNhc3Q1LnNldEtleSh1dGlsLnN0cjJiaW4oa2V5KSk7XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYmxvY2spIHtcbiAgICByZXR1cm4gdGhpcy5jYXN0NS5lbmNyeXB0KGJsb2NrKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNhc3Q1O1xubW9kdWxlLmV4cG9ydHMuYmxvY2tTaXplID0gY2FzdDUucHJvdG90eXBlLmJsb2NrU2l6ZSA9IDg7XG5tb2R1bGUuZXhwb3J0cy5rZXlTaXplID0gY2FzdDUucHJvdG90eXBlLmtleVNpemUgPSAxNjtcbiIsIi8vUGF1bCBUZXJvLCBKdWx5IDIwMDFcbi8vaHR0cDovL3d3dy50ZXJvLmNvLnVrL2Rlcy9cbi8vXG4vL09wdGltaXNlZCBmb3IgcGVyZm9ybWFuY2Ugd2l0aCBsYXJnZSBibG9ja3MgYnkgTWljaGFlbCBIYXl3b3J0aCwgTm92ZW1iZXIgMjAwMVxuLy9odHRwOi8vd3d3Lm5ldGRlYWxpbmcuY29tXG4vL1xuLy8gTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIXG5cbi8vVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EXG4vL0FOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuLy9JTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuLy9BUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRVxuLy9GT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuLy9EQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EU1xuLy9PUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTilcbi8vSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1Rcbi8vTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWVxuLy9PVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GXG4vL1NVQ0ggREFNQUdFLlxuXG4vL2Rlc1xuLy90aGlzIHRha2VzIHRoZSBrZXksIHRoZSBtZXNzYWdlLCBhbmQgd2hldGhlciB0byBlbmNyeXB0IG9yIGRlY3J5cHRcblxuXG5cblxuZnVuY3Rpb24gZGVzKGtleXMsIG1lc3NhZ2UsIGVuY3J5cHQsIG1vZGUsIGl2LCBwYWRkaW5nKSB7XG4gIC8vZGVjbGFyaW5nIHRoaXMgbG9jYWxseSBzcGVlZHMgdGhpbmdzIHVwIGEgYml0XG4gIHZhciBzcGZ1bmN0aW9uMSA9IG5ldyBBcnJheSgweDEwMTA0MDAsIDAsIDB4MTAwMDAsIDB4MTAxMDQwNCwgMHgxMDEwMDA0LCAweDEwNDA0LCAweDQsIDB4MTAwMDAsIDB4NDAwLCAweDEwMTA0MDAsXG4gICAgMHgxMDEwNDA0LCAweDQwMCwgMHgxMDAwNDA0LCAweDEwMTAwMDQsIDB4MTAwMDAwMCwgMHg0LCAweDQwNCwgMHgxMDAwNDAwLCAweDEwMDA0MDAsIDB4MTA0MDAsIDB4MTA0MDAsIDB4MTAxMDAwMCxcbiAgICAweDEwMTAwMDAsIDB4MTAwMDQwNCwgMHgxMDAwNCwgMHgxMDAwMDA0LCAweDEwMDAwMDQsIDB4MTAwMDQsIDAsIDB4NDA0LCAweDEwNDA0LCAweDEwMDAwMDAsIDB4MTAwMDAsIDB4MTAxMDQwNCwgMHg0LFxuICAgIDB4MTAxMDAwMCwgMHgxMDEwNDAwLCAweDEwMDAwMDAsIDB4MTAwMDAwMCwgMHg0MDAsIDB4MTAxMDAwNCwgMHgxMDAwMCwgMHgxMDQwMCwgMHgxMDAwMDA0LCAweDQwMCwgMHg0LCAweDEwMDA0MDQsXG4gICAgMHgxMDQwNCwgMHgxMDEwNDA0LCAweDEwMDA0LCAweDEwMTAwMDAsIDB4MTAwMDQwNCwgMHgxMDAwMDA0LCAweDQwNCwgMHgxMDQwNCwgMHgxMDEwNDAwLCAweDQwNCwgMHgxMDAwNDAwLFxuICAgIDB4MTAwMDQwMCwgMCwgMHgxMDAwNCwgMHgxMDQwMCwgMCwgMHgxMDEwMDA0KTtcbiAgdmFyIHNwZnVuY3Rpb24yID0gbmV3IEFycmF5KC0weDdmZWY3ZmUwLCAtMHg3ZmZmODAwMCwgMHg4MDAwLCAweDEwODAyMCwgMHgxMDAwMDAsIDB4MjAsIC0weDdmZWZmZmUwLCAtMHg3ZmZmN2ZlMCwgLVxuICAgIDB4N2ZmZmZmZTAsIC0weDdmZWY3ZmUwLCAtMHg3ZmVmODAwMCwgLTB4ODAwMDAwMDAsIC0weDdmZmY4MDAwLCAweDEwMDAwMCwgMHgyMCwgLTB4N2ZlZmZmZTAsIDB4MTA4MDAwLCAweDEwMDAyMCwgLVxuICAgIDB4N2ZmZjdmZTAsIDAsIC0weDgwMDAwMDAwLCAweDgwMDAsIDB4MTA4MDIwLCAtMHg3ZmYwMDAwMCwgMHgxMDAwMjAsIC0weDdmZmZmZmUwLCAwLCAweDEwODAwMCwgMHg4MDIwLCAtMHg3ZmVmODAwMCwgLVxuICAgIDB4N2ZmMDAwMDAsIDB4ODAyMCwgMCwgMHgxMDgwMjAsIC0weDdmZWZmZmUwLCAweDEwMDAwMCwgLTB4N2ZmZjdmZTAsIC0weDdmZjAwMDAwLCAtMHg3ZmVmODAwMCwgMHg4MDAwLCAtMHg3ZmYwMDAwMCwgLVxuICAgIDB4N2ZmZjgwMDAsIDB4MjAsIC0weDdmZWY3ZmUwLCAweDEwODAyMCwgMHgyMCwgMHg4MDAwLCAtMHg4MDAwMDAwMCwgMHg4MDIwLCAtMHg3ZmVmODAwMCwgMHgxMDAwMDAsIC0weDdmZmZmZmUwLFxuICAgIDB4MTAwMDIwLCAtMHg3ZmZmN2ZlMCwgLTB4N2ZmZmZmZTAsIDB4MTAwMDIwLCAweDEwODAwMCwgMCwgLTB4N2ZmZjgwMDAsIDB4ODAyMCwgLTB4ODAwMDAwMDAsIC0weDdmZWZmZmUwLCAtXG4gICAgMHg3ZmVmN2ZlMCwgMHgxMDgwMDApO1xuICB2YXIgc3BmdW5jdGlvbjMgPSBuZXcgQXJyYXkoMHgyMDgsIDB4ODAyMDIwMCwgMCwgMHg4MDIwMDA4LCAweDgwMDAyMDAsIDAsIDB4MjAyMDgsIDB4ODAwMDIwMCwgMHgyMDAwOCwgMHg4MDAwMDA4LFxuICAgIDB4ODAwMDAwOCwgMHgyMDAwMCwgMHg4MDIwMjA4LCAweDIwMDA4LCAweDgwMjAwMDAsIDB4MjA4LCAweDgwMDAwMDAsIDB4OCwgMHg4MDIwMjAwLCAweDIwMCwgMHgyMDIwMCwgMHg4MDIwMDAwLFxuICAgIDB4ODAyMDAwOCwgMHgyMDIwOCwgMHg4MDAwMjA4LCAweDIwMjAwLCAweDIwMDAwLCAweDgwMDAyMDgsIDB4OCwgMHg4MDIwMjA4LCAweDIwMCwgMHg4MDAwMDAwLCAweDgwMjAyMDAsIDB4ODAwMDAwMCxcbiAgICAweDIwMDA4LCAweDIwOCwgMHgyMDAwMCwgMHg4MDIwMjAwLCAweDgwMDAyMDAsIDAsIDB4MjAwLCAweDIwMDA4LCAweDgwMjAyMDgsIDB4ODAwMDIwMCwgMHg4MDAwMDA4LCAweDIwMCwgMCxcbiAgICAweDgwMjAwMDgsIDB4ODAwMDIwOCwgMHgyMDAwMCwgMHg4MDAwMDAwLCAweDgwMjAyMDgsIDB4OCwgMHgyMDIwOCwgMHgyMDIwMCwgMHg4MDAwMDA4LCAweDgwMjAwMDAsIDB4ODAwMDIwOCwgMHgyMDgsXG4gICAgMHg4MDIwMDAwLCAweDIwMjA4LCAweDgsIDB4ODAyMDAwOCwgMHgyMDIwMCk7XG4gIHZhciBzcGZ1bmN0aW9uNCA9IG5ldyBBcnJheSgweDgwMjAwMSwgMHgyMDgxLCAweDIwODEsIDB4ODAsIDB4ODAyMDgwLCAweDgwMDA4MSwgMHg4MDAwMDEsIDB4MjAwMSwgMCwgMHg4MDIwMDAsXG4gICAgMHg4MDIwMDAsIDB4ODAyMDgxLCAweDgxLCAwLCAweDgwMDA4MCwgMHg4MDAwMDEsIDB4MSwgMHgyMDAwLCAweDgwMDAwMCwgMHg4MDIwMDEsIDB4ODAsIDB4ODAwMDAwLCAweDIwMDEsIDB4MjA4MCxcbiAgICAweDgwMDA4MSwgMHgxLCAweDIwODAsIDB4ODAwMDgwLCAweDIwMDAsIDB4ODAyMDgwLCAweDgwMjA4MSwgMHg4MSwgMHg4MDAwODAsIDB4ODAwMDAxLCAweDgwMjAwMCwgMHg4MDIwODEsIDB4ODEsIDAsXG4gICAgMCwgMHg4MDIwMDAsIDB4MjA4MCwgMHg4MDAwODAsIDB4ODAwMDgxLCAweDEsIDB4ODAyMDAxLCAweDIwODEsIDB4MjA4MSwgMHg4MCwgMHg4MDIwODEsIDB4ODEsIDB4MSwgMHgyMDAwLCAweDgwMDAwMSxcbiAgICAweDIwMDEsIDB4ODAyMDgwLCAweDgwMDA4MSwgMHgyMDAxLCAweDIwODAsIDB4ODAwMDAwLCAweDgwMjAwMSwgMHg4MCwgMHg4MDAwMDAsIDB4MjAwMCwgMHg4MDIwODApO1xuICB2YXIgc3BmdW5jdGlvbjUgPSBuZXcgQXJyYXkoMHgxMDAsIDB4MjA4MDEwMCwgMHgyMDgwMDAwLCAweDQyMDAwMTAwLCAweDgwMDAwLCAweDEwMCwgMHg0MDAwMDAwMCwgMHgyMDgwMDAwLFxuICAgIDB4NDAwODAxMDAsIDB4ODAwMDAsIDB4MjAwMDEwMCwgMHg0MDA4MDEwMCwgMHg0MjAwMDEwMCwgMHg0MjA4MDAwMCwgMHg4MDEwMCwgMHg0MDAwMDAwMCwgMHgyMDAwMDAwLCAweDQwMDgwMDAwLFxuICAgIDB4NDAwODAwMDAsIDAsIDB4NDAwMDAxMDAsIDB4NDIwODAxMDAsIDB4NDIwODAxMDAsIDB4MjAwMDEwMCwgMHg0MjA4MDAwMCwgMHg0MDAwMDEwMCwgMCwgMHg0MjAwMDAwMCwgMHgyMDgwMTAwLFxuICAgIDB4MjAwMDAwMCwgMHg0MjAwMDAwMCwgMHg4MDEwMCwgMHg4MDAwMCwgMHg0MjAwMDEwMCwgMHgxMDAsIDB4MjAwMDAwMCwgMHg0MDAwMDAwMCwgMHgyMDgwMDAwLCAweDQyMDAwMTAwLFxuICAgIDB4NDAwODAxMDAsIDB4MjAwMDEwMCwgMHg0MDAwMDAwMCwgMHg0MjA4MDAwMCwgMHgyMDgwMTAwLCAweDQwMDgwMTAwLCAweDEwMCwgMHgyMDAwMDAwLCAweDQyMDgwMDAwLCAweDQyMDgwMTAwLFxuICAgIDB4ODAxMDAsIDB4NDIwMDAwMDAsIDB4NDIwODAxMDAsIDB4MjA4MDAwMCwgMCwgMHg0MDA4MDAwMCwgMHg0MjAwMDAwMCwgMHg4MDEwMCwgMHgyMDAwMTAwLCAweDQwMDAwMTAwLCAweDgwMDAwLCAwLFxuICAgIDB4NDAwODAwMDAsIDB4MjA4MDEwMCwgMHg0MDAwMDEwMCk7XG4gIHZhciBzcGZ1bmN0aW9uNiA9IG5ldyBBcnJheSgweDIwMDAwMDEwLCAweDIwNDAwMDAwLCAweDQwMDAsIDB4MjA0MDQwMTAsIDB4MjA0MDAwMDAsIDB4MTAsIDB4MjA0MDQwMTAsIDB4NDAwMDAwLFxuICAgIDB4MjAwMDQwMDAsIDB4NDA0MDEwLCAweDQwMDAwMCwgMHgyMDAwMDAxMCwgMHg0MDAwMTAsIDB4MjAwMDQwMDAsIDB4MjAwMDAwMDAsIDB4NDAxMCwgMCwgMHg0MDAwMTAsIDB4MjAwMDQwMTAsXG4gICAgMHg0MDAwLCAweDQwNDAwMCwgMHgyMDAwNDAxMCwgMHgxMCwgMHgyMDQwMDAxMCwgMHgyMDQwMDAxMCwgMCwgMHg0MDQwMTAsIDB4MjA0MDQwMDAsIDB4NDAxMCwgMHg0MDQwMDAsIDB4MjA0MDQwMDAsXG4gICAgMHgyMDAwMDAwMCwgMHgyMDAwNDAwMCwgMHgxMCwgMHgyMDQwMDAxMCwgMHg0MDQwMDAsIDB4MjA0MDQwMTAsIDB4NDAwMDAwLCAweDQwMTAsIDB4MjAwMDAwMTAsIDB4NDAwMDAwLCAweDIwMDA0MDAwLFxuICAgIDB4MjAwMDAwMDAsIDB4NDAxMCwgMHgyMDAwMDAxMCwgMHgyMDQwNDAxMCwgMHg0MDQwMDAsIDB4MjA0MDAwMDAsIDB4NDA0MDEwLCAweDIwNDA0MDAwLCAwLCAweDIwNDAwMDEwLCAweDEwLCAweDQwMDAsXG4gICAgMHgyMDQwMDAwMCwgMHg0MDQwMTAsIDB4NDAwMCwgMHg0MDAwMTAsIDB4MjAwMDQwMTAsIDAsIDB4MjA0MDQwMDAsIDB4MjAwMDAwMDAsIDB4NDAwMDEwLCAweDIwMDA0MDEwKTtcbiAgdmFyIHNwZnVuY3Rpb243ID0gbmV3IEFycmF5KDB4MjAwMDAwLCAweDQyMDAwMDIsIDB4NDAwMDgwMiwgMCwgMHg4MDAsIDB4NDAwMDgwMiwgMHgyMDA4MDIsIDB4NDIwMDgwMCwgMHg0MjAwODAyLFxuICAgIDB4MjAwMDAwLCAwLCAweDQwMDAwMDIsIDB4MiwgMHg0MDAwMDAwLCAweDQyMDAwMDIsIDB4ODAyLCAweDQwMDA4MDAsIDB4MjAwODAyLCAweDIwMDAwMiwgMHg0MDAwODAwLCAweDQwMDAwMDIsXG4gICAgMHg0MjAwMDAwLCAweDQyMDA4MDAsIDB4MjAwMDAyLCAweDQyMDAwMDAsIDB4ODAwLCAweDgwMiwgMHg0MjAwODAyLCAweDIwMDgwMCwgMHgyLCAweDQwMDAwMDAsIDB4MjAwODAwLCAweDQwMDAwMDAsXG4gICAgMHgyMDA4MDAsIDB4MjAwMDAwLCAweDQwMDA4MDIsIDB4NDAwMDgwMiwgMHg0MjAwMDAyLCAweDQyMDAwMDIsIDB4MiwgMHgyMDAwMDIsIDB4NDAwMDAwMCwgMHg0MDAwODAwLCAweDIwMDAwMCxcbiAgICAweDQyMDA4MDAsIDB4ODAyLCAweDIwMDgwMiwgMHg0MjAwODAwLCAweDgwMiwgMHg0MDAwMDAyLCAweDQyMDA4MDIsIDB4NDIwMDAwMCwgMHgyMDA4MDAsIDAsIDB4MiwgMHg0MjAwODAyLCAwLFxuICAgIDB4MjAwODAyLCAweDQyMDAwMDAsIDB4ODAwLCAweDQwMDAwMDIsIDB4NDAwMDgwMCwgMHg4MDAsIDB4MjAwMDAyKTtcbiAgdmFyIHNwZnVuY3Rpb244ID0gbmV3IEFycmF5KDB4MTAwMDEwNDAsIDB4MTAwMCwgMHg0MDAwMCwgMHgxMDA0MTA0MCwgMHgxMDAwMDAwMCwgMHgxMDAwMTA0MCwgMHg0MCwgMHgxMDAwMDAwMCxcbiAgICAweDQwMDQwLCAweDEwMDQwMDAwLCAweDEwMDQxMDQwLCAweDQxMDAwLCAweDEwMDQxMDAwLCAweDQxMDQwLCAweDEwMDAsIDB4NDAsIDB4MTAwNDAwMDAsIDB4MTAwMDAwNDAsIDB4MTAwMDEwMDAsXG4gICAgMHgxMDQwLCAweDQxMDAwLCAweDQwMDQwLCAweDEwMDQwMDQwLCAweDEwMDQxMDAwLCAweDEwNDAsIDAsIDAsIDB4MTAwNDAwNDAsIDB4MTAwMDAwNDAsIDB4MTAwMDEwMDAsIDB4NDEwNDAsXG4gICAgMHg0MDAwMCwgMHg0MTA0MCwgMHg0MDAwMCwgMHgxMDA0MTAwMCwgMHgxMDAwLCAweDQwLCAweDEwMDQwMDQwLCAweDEwMDAsIDB4NDEwNDAsIDB4MTAwMDEwMDAsIDB4NDAsIDB4MTAwMDAwNDAsXG4gICAgMHgxMDA0MDAwMCwgMHgxMDA0MDA0MCwgMHgxMDAwMDAwMCwgMHg0MDAwMCwgMHgxMDAwMTA0MCwgMCwgMHgxMDA0MTA0MCwgMHg0MDA0MCwgMHgxMDAwMDA0MCwgMHgxMDA0MDAwMCwgMHgxMDAwMTAwMCxcbiAgICAweDEwMDAxMDQwLCAwLCAweDEwMDQxMDQwLCAweDQxMDAwLCAweDQxMDAwLCAweDEwNDAsIDB4MTA0MCwgMHg0MDA0MCwgMHgxMDAwMDAwMCwgMHgxMDA0MTAwMCk7XG5cbiAgLy9jcmVhdGUgdGhlIDE2IG9yIDQ4IHN1YmtleXMgd2Ugd2lsbCBuZWVkXG4gIHZhciBtID0gMCxcbiAgICBpLCBqLCB0ZW1wLCB0ZW1wMiwgcmlnaHQxLCByaWdodDIsIGxlZnQsIHJpZ2h0LCBsb29waW5nO1xuICB2YXIgY2JjbGVmdCwgY2JjbGVmdDIsIGNiY3JpZ2h0LCBjYmNyaWdodDJcbiAgdmFyIGVuZGxvb3AsIGxvb3BpbmM7XG4gIHZhciBsZW4gPSBtZXNzYWdlLmxlbmd0aDtcbiAgdmFyIGNodW5rID0gMDtcbiAgLy9zZXQgdXAgdGhlIGxvb3BzIGZvciBzaW5nbGUgYW5kIHRyaXBsZSBkZXNcbiAgdmFyIGl0ZXJhdGlvbnMgPSBrZXlzLmxlbmd0aCA9PSAzMiA/IDMgOiA5OyAvL3NpbmdsZSBvciB0cmlwbGUgZGVzXG4gIGlmIChpdGVyYXRpb25zID09IDMpIHtcbiAgICBsb29waW5nID0gZW5jcnlwdCA/IG5ldyBBcnJheSgwLCAzMiwgMikgOiBuZXcgQXJyYXkoMzAsIC0yLCAtMik7XG4gIH0gZWxzZSB7XG4gICAgbG9vcGluZyA9IGVuY3J5cHQgPyBuZXcgQXJyYXkoMCwgMzIsIDIsIDYyLCAzMCwgLTIsIDY0LCA5NiwgMikgOiBuZXcgQXJyYXkoOTQsIDYyLCAtMiwgMzIsIDY0LCAyLCAzMCwgLTIsIC0yKTtcbiAgfVxuXG4gIC8vcGFkIHRoZSBtZXNzYWdlIGRlcGVuZGluZyBvbiB0aGUgcGFkZGluZyBwYXJhbWV0ZXJcbiAgLy9vbmx5IGFkZCBwYWRkaW5nIGlmIGVuY3J5cHRpbmcgLSBub3RlIHRoYXQgeW91IG5lZWQgdG8gdXNlIHRoZSBzYW1lIHBhZGRpbmcgb3B0aW9uIGZvciBib3RoIGVuY3J5cHQgYW5kIGRlY3J5cHRcbiAgaWYgKGVuY3J5cHQpIHtcbiAgICBtZXNzYWdlID0gZGVzX2FkZFBhZGRpbmcobWVzc2FnZSwgcGFkZGluZyk7XG4gICAgbGVuID0gbWVzc2FnZS5sZW5ndGg7XG4gIH1cblxuICAvL3N0b3JlIHRoZSByZXN1bHQgaGVyZVxuICByZXN1bHQgPSBcIlwiO1xuICB0ZW1wcmVzdWx0ID0gXCJcIjtcblxuICBpZiAobW9kZSA9PSAxKSB7IC8vQ0JDIG1vZGVcbiAgICBjYmNsZWZ0ID0gKGl2LmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAoaXYuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfCBpdi5jaGFyQ29kZUF0KG0rKyk7XG4gICAgY2JjcmlnaHQgPSAoaXYuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgMTYpIHwgKGl2LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGl2LmNoYXJDb2RlQXQobSsrKTtcbiAgICBtID0gMDtcbiAgfVxuXG4gIC8vbG9vcCB0aHJvdWdoIGVhY2ggNjQgYml0IGNodW5rIG9mIHRoZSBtZXNzYWdlXG4gIHdoaWxlIChtIDwgbGVuKSB7XG4gICAgbGVmdCA9IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgMTYpIHwgKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDgpIHwgbWVzc2FnZVxuICAgICAgLmNoYXJDb2RlQXQobSsrKTtcbiAgICByaWdodCA9IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgMTYpIHwgKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDgpIHxcbiAgICAgIG1lc3NhZ2UuY2hhckNvZGVBdChtKyspO1xuXG4gICAgLy9mb3IgQ2lwaGVyIEJsb2NrIENoYWluaW5nIG1vZGUsIHhvciB0aGUgbWVzc2FnZSB3aXRoIHRoZSBwcmV2aW91cyByZXN1bHRcbiAgICBpZiAobW9kZSA9PSAxKSB7XG4gICAgICBpZiAoZW5jcnlwdCkge1xuICAgICAgICBsZWZ0IF49IGNiY2xlZnQ7XG4gICAgICAgIHJpZ2h0IF49IGNiY3JpZ2h0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2JjbGVmdDIgPSBjYmNsZWZ0O1xuICAgICAgICBjYmNyaWdodDIgPSBjYmNyaWdodDtcbiAgICAgICAgY2JjbGVmdCA9IGxlZnQ7XG4gICAgICAgIGNiY3JpZ2h0ID0gcmlnaHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy9maXJzdCBlYWNoIDY0IGJ1dCBjaHVuayBvZiB0aGUgbWVzc2FnZSBtdXN0IGJlIHBlcm11dGVkIGFjY29yZGluZyB0byBJUFxuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDQpIF4gcmlnaHQpICYgMHgwZjBmMGYwZjtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgNCk7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMTYpIF4gcmlnaHQpICYgMHgwMDAwZmZmZjtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgMTYpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiAyKSBeIGxlZnQpICYgMHgzMzMzMzMzMztcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgMik7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmO1xuICAgIGxlZnQgXj0gdGVtcDtcbiAgICByaWdodCBePSAodGVtcCA8PCA4KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDEpO1xuXG4gICAgbGVmdCA9ICgobGVmdCA8PCAxKSB8IChsZWZ0ID4+PiAzMSkpO1xuICAgIHJpZ2h0ID0gKChyaWdodCA8PCAxKSB8IChyaWdodCA+Pj4gMzEpKTtcblxuICAgIC8vZG8gdGhpcyBlaXRoZXIgMSBvciAzIHRpbWVzIGZvciBlYWNoIGNodW5rIG9mIHRoZSBtZXNzYWdlXG4gICAgZm9yIChqID0gMDsgaiA8IGl0ZXJhdGlvbnM7IGogKz0gMykge1xuICAgICAgZW5kbG9vcCA9IGxvb3BpbmdbaiArIDFdO1xuICAgICAgbG9vcGluYyA9IGxvb3BpbmdbaiArIDJdO1xuICAgICAgLy9ub3cgZ28gdGhyb3VnaCBhbmQgcGVyZm9ybSB0aGUgZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uICBcbiAgICAgIGZvciAoaSA9IGxvb3Bpbmdbal07IGkgIT0gZW5kbG9vcDsgaSArPSBsb29waW5jKSB7IC8vZm9yIGVmZmljaWVuY3lcbiAgICAgICAgcmlnaHQxID0gcmlnaHQgXiBrZXlzW2ldO1xuICAgICAgICByaWdodDIgPSAoKHJpZ2h0ID4+PiA0KSB8IChyaWdodCA8PCAyOCkpIF4ga2V5c1tpICsgMV07XG4gICAgICAgIC8vdGhlIHJlc3VsdCBpcyBhdHRhaW5lZCBieSBwYXNzaW5nIHRoZXNlIGJ5dGVzIHRocm91Z2ggdGhlIFMgc2VsZWN0aW9uIGZ1bmN0aW9uc1xuICAgICAgICB0ZW1wID0gbGVmdDtcbiAgICAgICAgbGVmdCA9IHJpZ2h0O1xuICAgICAgICByaWdodCA9IHRlbXAgXiAoc3BmdW5jdGlvbjJbKHJpZ2h0MSA+Pj4gMjQpICYgMHgzZl0gfCBzcGZ1bmN0aW9uNFsocmlnaHQxID4+PiAxNikgJiAweDNmXSB8IHNwZnVuY3Rpb242WyhyaWdodDEgPj4+XG4gICAgICAgICAgOCkgJiAweDNmXSB8IHNwZnVuY3Rpb244W3JpZ2h0MSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjFbKHJpZ2h0MiA+Pj4gMjQpICYgMHgzZl0gfCBzcGZ1bmN0aW9uM1socmlnaHQyID4+PiAxNikgJlxuICAgICAgICAgIDB4M2ZdIHwgc3BmdW5jdGlvbjVbKHJpZ2h0MiA+Pj4gOCkgJiAweDNmXSB8IHNwZnVuY3Rpb243W3JpZ2h0MiAmIDB4M2ZdKTtcbiAgICAgIH1cbiAgICAgIHRlbXAgPSBsZWZ0O1xuICAgICAgbGVmdCA9IHJpZ2h0O1xuICAgICAgcmlnaHQgPSB0ZW1wOyAvL3VucmV2ZXJzZSBsZWZ0IGFuZCByaWdodFxuICAgIH0gLy9mb3IgZWl0aGVyIDEgb3IgMyBpdGVyYXRpb25zXG5cbiAgICAvL21vdmUgdGhlbiBlYWNoIG9uZSBiaXQgdG8gdGhlIHJpZ2h0XG4gICAgbGVmdCA9ICgobGVmdCA+Pj4gMSkgfCAobGVmdCA8PCAzMSkpO1xuICAgIHJpZ2h0ID0gKChyaWdodCA+Pj4gMSkgfCAocmlnaHQgPDwgMzEpKTtcblxuICAgIC8vbm93IHBlcmZvcm0gSVAtMSwgd2hpY2ggaXMgSVAgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvblxuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDEpIF4gcmlnaHQpICYgMHg1NTU1NTU1NTtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgMSk7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmO1xuICAgIGxlZnQgXj0gdGVtcDtcbiAgICByaWdodCBePSAodGVtcCA8PCA4KTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gMikgXiBsZWZ0KSAmIDB4MzMzMzMzMzM7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IDIpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDE2KSBeIHJpZ2h0KSAmIDB4MDAwMGZmZmY7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDE2KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiA0KSBeIHJpZ2h0KSAmIDB4MGYwZjBmMGY7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDQpO1xuXG4gICAgLy9mb3IgQ2lwaGVyIEJsb2NrIENoYWluaW5nIG1vZGUsIHhvciB0aGUgbWVzc2FnZSB3aXRoIHRoZSBwcmV2aW91cyByZXN1bHRcbiAgICBpZiAobW9kZSA9PSAxKSB7XG4gICAgICBpZiAoZW5jcnlwdCkge1xuICAgICAgICBjYmNsZWZ0ID0gbGVmdDtcbiAgICAgICAgY2JjcmlnaHQgPSByaWdodDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxlZnQgXj0gY2JjbGVmdDI7XG4gICAgICAgIHJpZ2h0IF49IGNiY3JpZ2h0MjtcbiAgICAgIH1cbiAgICB9XG4gICAgdGVtcHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChsZWZ0ID4+PiAyNCksICgobGVmdCA+Pj4gMTYpICYgMHhmZiksICgobGVmdCA+Pj4gOCkgJiAweGZmKSwgKGxlZnQgJiAweGZmKSwgKFxuICAgICAgcmlnaHQgPj4+IDI0KSwgKChyaWdodCA+Pj4gMTYpICYgMHhmZiksICgocmlnaHQgPj4+IDgpICYgMHhmZiksIChyaWdodCAmIDB4ZmYpKTtcblxuICAgIGNodW5rICs9IDg7XG4gICAgaWYgKGNodW5rID09IDUxMikge1xuICAgICAgcmVzdWx0ICs9IHRlbXByZXN1bHQ7XG4gICAgICB0ZW1wcmVzdWx0ID0gXCJcIjtcbiAgICAgIGNodW5rID0gMDtcbiAgICB9XG4gIH0gLy9mb3IgZXZlcnkgOCBjaGFyYWN0ZXJzLCBvciA2NCBiaXRzIGluIHRoZSBtZXNzYWdlXG5cbiAgLy9yZXR1cm4gdGhlIHJlc3VsdCBhcyBhbiBhcnJheVxuICByZXN1bHQgKz0gdGVtcHJlc3VsdDtcblxuICAvL29ubHkgcmVtb3ZlIHBhZGRpbmcgaWYgZGVjcnlwdGluZyAtIG5vdGUgdGhhdCB5b3UgbmVlZCB0byB1c2UgdGhlIHNhbWUgcGFkZGluZyBvcHRpb24gZm9yIGJvdGggZW5jcnlwdCBhbmQgZGVjcnlwdFxuICBpZiAoIWVuY3J5cHQpIHtcbiAgICByZXN1bHQgPSBkZXNfcmVtb3ZlUGFkZGluZyhyZXN1bHQsIHBhZGRpbmcpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn0gLy9lbmQgb2YgZGVzXG5cblxuXG4vL2Rlc19jcmVhdGVLZXlzXG4vL3RoaXMgdGFrZXMgYXMgaW5wdXQgYSA2NCBiaXQga2V5IChldmVuIHRob3VnaCBvbmx5IDU2IGJpdHMgYXJlIHVzZWQpXG4vL2FzIGFuIGFycmF5IG9mIDIgaW50ZWdlcnMsIGFuZCByZXR1cm5zIDE2IDQ4IGJpdCBrZXlzXG5cbmZ1bmN0aW9uIGRlc19jcmVhdGVLZXlzKGtleSkge1xuICAvL2RlY2xhcmluZyB0aGlzIGxvY2FsbHkgc3BlZWRzIHRoaW5ncyB1cCBhIGJpdFxuICBwYzJieXRlczAgPSBuZXcgQXJyYXkoMCwgMHg0LCAweDIwMDAwMDAwLCAweDIwMDAwMDA0LCAweDEwMDAwLCAweDEwMDA0LCAweDIwMDEwMDAwLCAweDIwMDEwMDA0LCAweDIwMCwgMHgyMDQsXG4gICAgMHgyMDAwMDIwMCwgMHgyMDAwMDIwNCwgMHgxMDIwMCwgMHgxMDIwNCwgMHgyMDAxMDIwMCwgMHgyMDAxMDIwNCk7XG4gIHBjMmJ5dGVzMSA9IG5ldyBBcnJheSgwLCAweDEsIDB4MTAwMDAwLCAweDEwMDAwMSwgMHg0MDAwMDAwLCAweDQwMDAwMDEsIDB4NDEwMDAwMCwgMHg0MTAwMDAxLCAweDEwMCwgMHgxMDEsIDB4MTAwMTAwLFxuICAgIDB4MTAwMTAxLCAweDQwMDAxMDAsIDB4NDAwMDEwMSwgMHg0MTAwMTAwLCAweDQxMDAxMDEpO1xuICBwYzJieXRlczIgPSBuZXcgQXJyYXkoMCwgMHg4LCAweDgwMCwgMHg4MDgsIDB4MTAwMDAwMCwgMHgxMDAwMDA4LCAweDEwMDA4MDAsIDB4MTAwMDgwOCwgMCwgMHg4LCAweDgwMCwgMHg4MDgsXG4gICAgMHgxMDAwMDAwLCAweDEwMDAwMDgsIDB4MTAwMDgwMCwgMHgxMDAwODA4KTtcbiAgcGMyYnl0ZXMzID0gbmV3IEFycmF5KDAsIDB4MjAwMDAwLCAweDgwMDAwMDAsIDB4ODIwMDAwMCwgMHgyMDAwLCAweDIwMjAwMCwgMHg4MDAyMDAwLCAweDgyMDIwMDAsIDB4MjAwMDAsIDB4MjIwMDAwLFxuICAgIDB4ODAyMDAwMCwgMHg4MjIwMDAwLCAweDIyMDAwLCAweDIyMjAwMCwgMHg4MDIyMDAwLCAweDgyMjIwMDApO1xuICBwYzJieXRlczQgPSBuZXcgQXJyYXkoMCwgMHg0MDAwMCwgMHgxMCwgMHg0MDAxMCwgMCwgMHg0MDAwMCwgMHgxMCwgMHg0MDAxMCwgMHgxMDAwLCAweDQxMDAwLCAweDEwMTAsIDB4NDEwMTAsIDB4MTAwMCxcbiAgICAweDQxMDAwLCAweDEwMTAsIDB4NDEwMTApO1xuICBwYzJieXRlczUgPSBuZXcgQXJyYXkoMCwgMHg0MDAsIDB4MjAsIDB4NDIwLCAwLCAweDQwMCwgMHgyMCwgMHg0MjAsIDB4MjAwMDAwMCwgMHgyMDAwNDAwLCAweDIwMDAwMjAsIDB4MjAwMDQyMCxcbiAgICAweDIwMDAwMDAsIDB4MjAwMDQwMCwgMHgyMDAwMDIwLCAweDIwMDA0MjApO1xuICBwYzJieXRlczYgPSBuZXcgQXJyYXkoMCwgMHgxMDAwMDAwMCwgMHg4MDAwMCwgMHgxMDA4MDAwMCwgMHgyLCAweDEwMDAwMDAyLCAweDgwMDAyLCAweDEwMDgwMDAyLCAwLCAweDEwMDAwMDAwLFxuICAgIDB4ODAwMDAsIDB4MTAwODAwMDAsIDB4MiwgMHgxMDAwMDAwMiwgMHg4MDAwMiwgMHgxMDA4MDAwMik7XG4gIHBjMmJ5dGVzNyA9IG5ldyBBcnJheSgwLCAweDEwMDAwLCAweDgwMCwgMHgxMDgwMCwgMHgyMDAwMDAwMCwgMHgyMDAxMDAwMCwgMHgyMDAwMDgwMCwgMHgyMDAxMDgwMCwgMHgyMDAwMCwgMHgzMDAwMCxcbiAgICAweDIwODAwLCAweDMwODAwLCAweDIwMDIwMDAwLCAweDIwMDMwMDAwLCAweDIwMDIwODAwLCAweDIwMDMwODAwKTtcbiAgcGMyYnl0ZXM4ID0gbmV3IEFycmF5KDAsIDB4NDAwMDAsIDAsIDB4NDAwMDAsIDB4MiwgMHg0MDAwMiwgMHgyLCAweDQwMDAyLCAweDIwMDAwMDAsIDB4MjA0MDAwMCwgMHgyMDAwMDAwLCAweDIwNDAwMDAsXG4gICAgMHgyMDAwMDAyLCAweDIwNDAwMDIsIDB4MjAwMDAwMiwgMHgyMDQwMDAyKTtcbiAgcGMyYnl0ZXM5ID0gbmV3IEFycmF5KDAsIDB4MTAwMDAwMDAsIDB4OCwgMHgxMDAwMDAwOCwgMCwgMHgxMDAwMDAwMCwgMHg4LCAweDEwMDAwMDA4LCAweDQwMCwgMHgxMDAwMDQwMCwgMHg0MDgsXG4gICAgMHgxMDAwMDQwOCwgMHg0MDAsIDB4MTAwMDA0MDAsIDB4NDA4LCAweDEwMDAwNDA4KTtcbiAgcGMyYnl0ZXMxMCA9IG5ldyBBcnJheSgwLCAweDIwLCAwLCAweDIwLCAweDEwMDAwMCwgMHgxMDAwMjAsIDB4MTAwMDAwLCAweDEwMDAyMCwgMHgyMDAwLCAweDIwMjAsIDB4MjAwMCwgMHgyMDIwLFxuICAgIDB4MTAyMDAwLCAweDEwMjAyMCwgMHgxMDIwMDAsIDB4MTAyMDIwKTtcbiAgcGMyYnl0ZXMxMSA9IG5ldyBBcnJheSgwLCAweDEwMDAwMDAsIDB4MjAwLCAweDEwMDAyMDAsIDB4MjAwMDAwLCAweDEyMDAwMDAsIDB4MjAwMjAwLCAweDEyMDAyMDAsIDB4NDAwMDAwMCwgMHg1MDAwMDAwLFxuICAgIDB4NDAwMDIwMCwgMHg1MDAwMjAwLCAweDQyMDAwMDAsIDB4NTIwMDAwMCwgMHg0MjAwMjAwLCAweDUyMDAyMDApO1xuICBwYzJieXRlczEyID0gbmV3IEFycmF5KDAsIDB4MTAwMCwgMHg4MDAwMDAwLCAweDgwMDEwMDAsIDB4ODAwMDAsIDB4ODEwMDAsIDB4ODA4MDAwMCwgMHg4MDgxMDAwLCAweDEwLCAweDEwMTAsXG4gICAgMHg4MDAwMDEwLCAweDgwMDEwMTAsIDB4ODAwMTAsIDB4ODEwMTAsIDB4ODA4MDAxMCwgMHg4MDgxMDEwKTtcbiAgcGMyYnl0ZXMxMyA9IG5ldyBBcnJheSgwLCAweDQsIDB4MTAwLCAweDEwNCwgMCwgMHg0LCAweDEwMCwgMHgxMDQsIDB4MSwgMHg1LCAweDEwMSwgMHgxMDUsIDB4MSwgMHg1LCAweDEwMSwgMHgxMDUpO1xuXG4gIC8vaG93IG1hbnkgaXRlcmF0aW9ucyAoMSBmb3IgZGVzLCAzIGZvciB0cmlwbGUgZGVzKVxuICB2YXIgaXRlcmF0aW9ucyA9IGtleS5sZW5ndGggPiA4ID8gMyA6IDE7IC8vY2hhbmdlZCBieSBQYXVsIDE2LzYvMjAwNyB0byB1c2UgVHJpcGxlIERFUyBmb3IgOSsgYnl0ZSBrZXlzXG4gIC8vc3RvcmVzIHRoZSByZXR1cm4ga2V5c1xuICB2YXIga2V5cyA9IG5ldyBBcnJheSgzMiAqIGl0ZXJhdGlvbnMpO1xuICAvL25vdyBkZWZpbmUgdGhlIGxlZnQgc2hpZnRzIHdoaWNoIG5lZWQgdG8gYmUgZG9uZVxuICB2YXIgc2hpZnRzID0gbmV3IEFycmF5KDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDApO1xuICAvL290aGVyIHZhcmlhYmxlc1xuICB2YXIgbGVmdHRlbXAsIHJpZ2h0dGVtcCwgbSA9IDAsXG4gICAgbiA9IDAsXG4gICAgdGVtcDtcblxuICBmb3IgKHZhciBqID0gMDsgaiA8IGl0ZXJhdGlvbnM7IGorKykgeyAvL2VpdGhlciAxIG9yIDMgaXRlcmF0aW9uc1xuICAgIGxlZnQgPSAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGtleS5jaGFyQ29kZUF0KG0rKyk7XG4gICAgcmlnaHQgPSAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGtleS5jaGFyQ29kZUF0KG0rKyk7XG5cbiAgICB0ZW1wID0gKChsZWZ0ID4+PiA0KSBeIHJpZ2h0KSAmIDB4MGYwZjBmMGY7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDQpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiAtMTYpIF4gbGVmdCkgJiAweDAwMDBmZmZmO1xuICAgIGxlZnQgXj0gdGVtcDtcbiAgICByaWdodCBePSAodGVtcCA8PCAtMTYpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDIpIF4gcmlnaHQpICYgMHgzMzMzMzMzMztcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgMik7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IC0xNikgXiBsZWZ0KSAmIDB4MDAwMGZmZmY7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IC0xNik7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1O1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxKTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IDgpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDEpIF4gcmlnaHQpICYgMHg1NTU1NTU1NTtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgMSk7XG5cbiAgICAvL3RoZSByaWdodCBzaWRlIG5lZWRzIHRvIGJlIHNoaWZ0ZWQgYW5kIHRvIGdldCB0aGUgbGFzdCBmb3VyIGJpdHMgb2YgdGhlIGxlZnQgc2lkZVxuICAgIHRlbXAgPSAobGVmdCA8PCA4KSB8ICgocmlnaHQgPj4+IDIwKSAmIDB4MDAwMDAwZjApO1xuICAgIC8vbGVmdCBuZWVkcyB0byBiZSBwdXQgdXBzaWRlIGRvd25cbiAgICBsZWZ0ID0gKHJpZ2h0IDw8IDI0KSB8ICgocmlnaHQgPDwgOCkgJiAweGZmMDAwMCkgfCAoKHJpZ2h0ID4+PiA4KSAmIDB4ZmYwMCkgfCAoKHJpZ2h0ID4+PiAyNCkgJiAweGYwKTtcbiAgICByaWdodCA9IHRlbXA7XG5cbiAgICAvL25vdyBnbyB0aHJvdWdoIGFuZCBwZXJmb3JtIHRoZXNlIHNoaWZ0cyBvbiB0aGUgbGVmdCBhbmQgcmlnaHQga2V5c1xuICAgIGZvciAoaSA9IDA7IGkgPCBzaGlmdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIC8vc2hpZnQgdGhlIGtleXMgZWl0aGVyIG9uZSBvciB0d28gYml0cyB0byB0aGUgbGVmdFxuICAgICAgaWYgKHNoaWZ0c1tpXSkge1xuICAgICAgICBsZWZ0ID0gKGxlZnQgPDwgMikgfCAobGVmdCA+Pj4gMjYpO1xuICAgICAgICByaWdodCA9IChyaWdodCA8PCAyKSB8IChyaWdodCA+Pj4gMjYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGVmdCA9IChsZWZ0IDw8IDEpIHwgKGxlZnQgPj4+IDI3KTtcbiAgICAgICAgcmlnaHQgPSAocmlnaHQgPDwgMSkgfCAocmlnaHQgPj4+IDI3KTtcbiAgICAgIH1cbiAgICAgIGxlZnQgJj0gLTB4ZjtcbiAgICAgIHJpZ2h0ICY9IC0weGY7XG5cbiAgICAgIC8vbm93IGFwcGx5IFBDLTIsIGluIHN1Y2ggYSB3YXkgdGhhdCBFIGlzIGVhc2llciB3aGVuIGVuY3J5cHRpbmcgb3IgZGVjcnlwdGluZ1xuICAgICAgLy90aGlzIGNvbnZlcnNpb24gd2lsbCBsb29rIGxpa2UgUEMtMiBleGNlcHQgb25seSB0aGUgbGFzdCA2IGJpdHMgb2YgZWFjaCBieXRlIGFyZSB1c2VkXG4gICAgICAvL3JhdGhlciB0aGFuIDQ4IGNvbnNlY3V0aXZlIGJpdHMgYW5kIHRoZSBvcmRlciBvZiBsaW5lcyB3aWxsIGJlIGFjY29yZGluZyB0byBcbiAgICAgIC8vaG93IHRoZSBTIHNlbGVjdGlvbiBmdW5jdGlvbnMgd2lsbCBiZSBhcHBsaWVkOiBTMiwgUzQsIFM2LCBTOCwgUzEsIFMzLCBTNSwgUzdcbiAgICAgIGxlZnR0ZW1wID0gcGMyYnl0ZXMwW2xlZnQgPj4+IDI4XSB8IHBjMmJ5dGVzMVsobGVmdCA+Pj4gMjQpICYgMHhmXSB8IHBjMmJ5dGVzMlsobGVmdCA+Pj4gMjApICYgMHhmXSB8IHBjMmJ5dGVzM1soXG4gICAgICAgIGxlZnQgPj4+IDE2KSAmIDB4Zl0gfCBwYzJieXRlczRbKGxlZnQgPj4+IDEyKSAmIDB4Zl0gfCBwYzJieXRlczVbKGxlZnQgPj4+IDgpICYgMHhmXSB8IHBjMmJ5dGVzNlsobGVmdCA+Pj4gNCkgJlxuICAgICAgICAweGZdO1xuICAgICAgcmlnaHR0ZW1wID0gcGMyYnl0ZXM3W3JpZ2h0ID4+PiAyOF0gfCBwYzJieXRlczhbKHJpZ2h0ID4+PiAyNCkgJiAweGZdIHwgcGMyYnl0ZXM5WyhyaWdodCA+Pj4gMjApICYgMHhmXSB8XG4gICAgICAgIHBjMmJ5dGVzMTBbKHJpZ2h0ID4+PiAxNikgJiAweGZdIHwgcGMyYnl0ZXMxMVsocmlnaHQgPj4+IDEyKSAmIDB4Zl0gfCBwYzJieXRlczEyWyhyaWdodCA+Pj4gOCkgJiAweGZdIHxcbiAgICAgICAgcGMyYnl0ZXMxM1socmlnaHQgPj4+IDQpICYgMHhmXTtcbiAgICAgIHRlbXAgPSAoKHJpZ2h0dGVtcCA+Pj4gMTYpIF4gbGVmdHRlbXApICYgMHgwMDAwZmZmZjtcbiAgICAgIGtleXNbbisrXSA9IGxlZnR0ZW1wIF4gdGVtcDtcbiAgICAgIGtleXNbbisrXSA9IHJpZ2h0dGVtcCBeICh0ZW1wIDw8IDE2KTtcbiAgICB9XG4gIH0gLy9mb3IgZWFjaCBpdGVyYXRpb25zXG4gIC8vcmV0dXJuIHRoZSBrZXlzIHdlJ3ZlIGNyZWF0ZWRcbiAgcmV0dXJuIGtleXM7XG59IC8vZW5kIG9mIGRlc19jcmVhdGVLZXlzXG5cblxuZnVuY3Rpb24gZGVzX2FkZFBhZGRpbmcobWVzc2FnZSwgcGFkZGluZykge1xuICB2YXIgcGFkTGVuZ3RoID0gOCAtIChtZXNzYWdlLmxlbmd0aCAlIDgpO1xuICBpZiAoKHBhZGRpbmcgPT0gMikgJiYgKHBhZExlbmd0aCA8IDgpKSB7IC8vcGFkIHRoZSBtZXNzYWdlIHdpdGggc3BhY2VzXG4gICAgbWVzc2FnZSArPSBcIiAgICAgICAgXCIuc3Vic3RyKDAsIHBhZExlbmd0aCk7XG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PSAxKSB7IC8vUEtDUzcgcGFkZGluZ1xuICAgIG1lc3NhZ2UgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwYWRMZW5ndGgsIHBhZExlbmd0aCwgcGFkTGVuZ3RoLCBwYWRMZW5ndGgsIHBhZExlbmd0aCwgcGFkTGVuZ3RoLCBwYWRMZW5ndGgsXG4gICAgICBwYWRMZW5ndGgpLnN1YnN0cigwLCBwYWRMZW5ndGgpO1xuICB9IGVsc2UgaWYgKCFwYWRkaW5nICYmIChwYWRMZW5ndGggPCA4KSkgeyAvL3BhZCB0aGUgbWVzc2FnZSBvdXQgd2l0aCBudWxsIGJ5dGVzXG4gICAgbWVzc2FnZSArPSBcIlxcMFxcMFxcMFxcMFxcMFxcMFxcMFxcMFwiLnN1YnN0cigwLCBwYWRMZW5ndGgpO1xuICB9XG4gIHJldHVybiBtZXNzYWdlO1xufVxuXG5mdW5jdGlvbiBkZXNfcmVtb3ZlUGFkZGluZyhtZXNzYWdlLCBwYWRkaW5nKSB7XG4gIGlmIChwYWRkaW5nID09IDIpIHsgLy8gc3BhY2UgcGFkZGVkXG4gICAgbWVzc2FnZSA9IG1lc3NhZ2UucmVwbGFjZSgvICokL2csIFwiXCIpO1xuICB9IGVsc2UgaWYgKHBhZGRpbmcgPT0gMSkgeyAvLyBQS0NTN1xuICAgIHZhciBwYWRDb3VudCA9IG1lc3NhZ2UuY2hhckNvZGVBdChtZXNzYWdlLmxlbmd0aCAtIDEpO1xuICAgIG1lc3NhZ2UgPSBtZXNzYWdlLnN1YnN0cigwLCBtZXNzYWdlLmxlbmd0aCAtIHBhZENvdW50KTtcbiAgfSBlbHNlIGlmICghcGFkZGluZykgeyAvLyBudWxsIHBhZGRpbmdcbiAgICBtZXNzYWdlID0gbWVzc2FnZS5yZXBsYWNlKC9cXDAqJC9nLCBcIlwiKTtcbiAgfVxuICByZXR1cm4gbWVzc2FnZTtcbn1cblxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuLy8gYWRkZWQgYnkgUmVjdXJpdHkgTGFic1xuXG5mdW5jdGlvbiBEZXMoa2V5KSB7XG4gIHRoaXMua2V5ID0gW107XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAzOyBpKyspIHtcbiAgICB0aGlzLmtleS5wdXNoKGtleS5zdWJzdHIoaSAqIDgsIDgpKTtcbiAgfVxuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG4gICAgcmV0dXJuIHV0aWwuc3RyMmJpbihkZXMoZGVzX2NyZWF0ZUtleXModGhpcy5rZXlbMl0pLFxuICAgICAgZGVzKGRlc19jcmVhdGVLZXlzKHRoaXMua2V5WzFdKSxcbiAgICAgIGRlcyhkZXNfY3JlYXRlS2V5cyh0aGlzLmtleVswXSksXG4gICAgICB1dGlsLmJpbjJzdHIoYmxvY2spLCB0cnVlLCAwLCBudWxsLCBudWxsKSxcbiAgICAgIGZhbHNlLCAwLCBudWxsLCBudWxsKSwgdHJ1ZSwgMCwgbnVsbCwgbnVsbCkpO1xuICB9XG59XG5cbkRlcy5rZXlTaXplID0gRGVzLnByb3RvdHlwZS5rZXlTaXplID0gMjQ7XG5EZXMuYmxvY2tTaXplID0gRGVzLnByb3RvdHlwZS5ibG9ja1NpemUgPSA4O1xuXG4vLyBUaGlzIGlzIFwib3JpZ2luYWxcIiBERVMgLSBEZXMgaXMgYWN0dWFsbHkgVHJpcGxlIERFUy5cbi8vIFRoaXMgaXMgb25seSBleHBvcnRlZCBzbyB3ZSBjYW4gdW5pdCB0ZXN0LlxuXG5mdW5jdGlvbiBPcmlnaW5hbERlcyhrZXkpIHtcbiAgdGhpcy5rZXkgPSBrZXk7XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYmxvY2ssIHBhZGRpbmcpIHtcbiAgICB2YXIga2V5cyA9IGRlc19jcmVhdGVLZXlzKHRoaXMua2V5KTtcbiAgICByZXR1cm4gdXRpbC5zdHIyYmluKGRlcyhrZXlzLCB1dGlsLmJpbjJzdHIoYmxvY2spLCB0cnVlLCAwLCBudWxsLCBwYWRkaW5nKSk7XG4gIH1cblxuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihibG9jaywgcGFkZGluZykge1xuICAgIHZhciBrZXlzID0gZGVzX2NyZWF0ZUtleXModGhpcy5rZXkpO1xuICAgIHJldHVybiB1dGlsLnN0cjJiaW4oZGVzKGtleXMsIHV0aWwuYmluMnN0cihibG9jayksIGZhbHNlLCAwLCBudWxsLCBwYWRkaW5nKSk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGRlczogRGVzLFxuICBvcmlnaW5hbERlczogT3JpZ2luYWxEZXNcbn1cbiIsInZhciBkZXNNb2R1bGUgPSByZXF1aXJlKCcuL2Rlcy5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZGVzOiBkZXNNb2R1bGVbJ2RlcyddLFxuICBvcmlnaW5hbERlczogZGVzTW9kdWxlWydvcmlnaW5hbERlcyddLFxuICBjYXN0NTogcmVxdWlyZSgnLi9jYXN0NS5qcycpLFxuICB0d29maXNoOiByZXF1aXJlKCcuL3R3b2Zpc2guanMnKSxcbiAgYmxvd2Zpc2g6IHJlcXVpcmUoJy4vYmxvd2Zpc2guanMnKVxufVxuXG52YXIgYWVzID0gcmVxdWlyZSgnLi9hZXMuanMnKTtcblxuZm9yICh2YXIgaSBpbiBhZXMpIHtcbiAgbW9kdWxlLmV4cG9ydHNbJ2FlcycgKyBpXSA9IGFlc1tpXTtcbn1cbiIsIi8qIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSCBcbiAqIFxuICogQ2lwaGVyLmpzXG4gKiBBIGJsb2NrLWNpcGhlciBhbGdvcml0aG0gaW1wbGVtZW50YXRpb24gb24gSmF2YVNjcmlwdFxuICogU2VlIENpcGhlci5yZWFkbWUudHh0IGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLlxuICpcbiAqIENvcHlyaWdodChjKSAyMDA5IEF0c3VzaGkgT2thIFsgaHR0cDovL29rYS5udS8gXVxuICogVGhpcyBzY3JpcHQgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTEdQTFxuICpcbiAqIEFDS05PV0xFREdNRU5UXG4gKlxuICogICAgIFRoZSBtYWluIHN1YnJvdXRpbmVzIGFyZSB3cml0dGVuIGJ5IE1pY2hpZWwgdmFuIEV2ZXJkaW5nZW4uXG4gKiBcbiAqICAgICBNaWNoaWVsIHZhbiBFdmVyZGluZ2VuXG4gKiAgICAgaHR0cDovL2hvbWUudmVyc2F0ZWwubmwvTUF2YW5FdmVyZGluZ2VuL2luZGV4Lmh0bWxcbiAqIFxuICogICAgIEFsbCByaWdodHMgZm9yIHRoZXNlIHJvdXRpbmVzIGFyZSByZXNlcnZlZCB0byBNaWNoaWVsIHZhbiBFdmVyZGluZ2VuLlxuICpcbiAqL1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vL01hdGhcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG52YXIgTUFYSU5UID0gMHhGRkZGRkZGRjtcblxuZnVuY3Rpb24gcm90YihiLCBuKSB7XG4gIHJldHVybiAoYiA8PCBuIHwgYiA+Pj4gKDggLSBuKSkgJiAweEZGO1xufVxuXG5mdW5jdGlvbiByb3R3KHcsIG4pIHtcbiAgcmV0dXJuICh3IDw8IG4gfCB3ID4+PiAoMzIgLSBuKSkgJiBNQVhJTlQ7XG59XG5cbmZ1bmN0aW9uIGdldFcoYSwgaSkge1xuICByZXR1cm4gYVtpXSB8IGFbaSArIDFdIDw8IDggfCBhW2kgKyAyXSA8PCAxNiB8IGFbaSArIDNdIDw8IDI0O1xufVxuXG5mdW5jdGlvbiBzZXRXKGEsIGksIHcpIHtcbiAgYS5zcGxpY2UoaSwgNCwgdyAmIDB4RkYsICh3ID4+PiA4KSAmIDB4RkYsICh3ID4+PiAxNikgJiAweEZGLCAodyA+Pj4gMjQpICYgMHhGRik7XG59XG5cbmZ1bmN0aW9uIHNldFdJbnYoYSwgaSwgdykge1xuICBhLnNwbGljZShpLCA0LCAodyA+Pj4gMjQpICYgMHhGRiwgKHcgPj4+IDE2KSAmIDB4RkYsICh3ID4+PiA4KSAmIDB4RkYsIHcgJiAweEZGKTtcbn1cblxuZnVuY3Rpb24gZ2V0Qih4LCBuKSB7XG4gIHJldHVybiAoeCA+Pj4gKG4gKiA4KSkgJiAweEZGO1xufVxuXG5mdW5jdGlvbiBnZXROckJpdHMoaSkge1xuICB2YXIgbiA9IDA7XG4gIHdoaWxlIChpID4gMCkge1xuICAgIG4rKztcbiAgICBpID4+Pj0gMTtcbiAgfVxuICByZXR1cm4gbjtcbn1cblxuZnVuY3Rpb24gZ2V0TWFzayhuKSB7XG4gIHJldHVybiAoMSA8PCBuKSAtIDE7XG59XG5cbi8vYWRkZWQgMjAwOC8xMS8xMyBYWFggTVVTVCBVU0UgT05FLVdBWSBIQVNIIEZVTkNUSU9OIEZPUiBTRUNVUklUWSBSRUFTT05cblxuZnVuY3Rpb24gcmFuZEJ5dGUoKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAyNTYpO1xufVxuLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gVHdvZmlzaFxuLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBjcmVhdGVUd29maXNoKCkge1xuICAvL1xuICB2YXIga2V5Qnl0ZXMgPSBudWxsO1xuICB2YXIgZGF0YUJ5dGVzID0gbnVsbDtcbiAgdmFyIGRhdGFPZmZzZXQgPSAtMTtcbiAgLy8gdmFyIGRhdGFMZW5ndGggPSAtMTtcbiAgdmFyIGFsZ29yaXRobU5hbWUgPSBudWxsO1xuICAvLyB2YXIgaWR4MiA9IC0xO1xuICAvL1xuXG4gIGFsZ29yaXRobU5hbWUgPSBcInR3b2Zpc2hcIjtcblxuICB2YXIgdGZzS2V5ID0gW107XG4gIHZhciB0ZnNNID0gW1xuICAgIFtdLFxuICAgIFtdLFxuICAgIFtdLFxuICAgIFtdXG4gIF07XG5cbiAgZnVuY3Rpb24gdGZzSW5pdChrZXkpIHtcbiAgICBrZXlCeXRlcyA9IGtleTtcbiAgICB2YXIgaSwgYSwgYiwgYywgZCwgbWVLZXkgPSBbXSxcbiAgICAgIG1vS2V5ID0gW10sXG4gICAgICBpbktleSA9IFtdO1xuICAgIHZhciBrTGVuO1xuICAgIHZhciBzS2V5ID0gW107XG4gICAgdmFyIGYwMSwgZjViLCBmZWY7XG5cbiAgICB2YXIgcTAgPSBbXG4gICAgICBbOCwgMSwgNywgMTMsIDYsIDE1LCAzLCAyLCAwLCAxMSwgNSwgOSwgMTQsIDEyLCAxMCwgNF0sXG4gICAgICBbMiwgOCwgMTEsIDEzLCAxNSwgNywgNiwgMTQsIDMsIDEsIDksIDQsIDAsIDEwLCAxMiwgNV1cbiAgICBdO1xuICAgIHZhciBxMSA9IFtcbiAgICAgIFsxNCwgMTIsIDExLCA4LCAxLCAyLCAzLCA1LCAxNSwgNCwgMTAsIDYsIDcsIDAsIDksIDEzXSxcbiAgICAgIFsxLCAxNCwgMiwgMTEsIDQsIDEyLCAzLCA3LCA2LCAxMywgMTAsIDUsIDE1LCA5LCAwLCA4XVxuICAgIF07XG4gICAgdmFyIHEyID0gW1xuICAgICAgWzExLCAxMCwgNSwgMTQsIDYsIDEzLCA5LCAwLCAxMiwgOCwgMTUsIDMsIDIsIDQsIDcsIDFdLFxuICAgICAgWzQsIDEyLCA3LCA1LCAxLCA2LCA5LCAxMCwgMCwgMTQsIDEzLCA4LCAyLCAxMSwgMywgMTVdXG4gICAgXTtcbiAgICB2YXIgcTMgPSBbXG4gICAgICBbMTMsIDcsIDE1LCA0LCAxLCAyLCA2LCAxNCwgOSwgMTEsIDMsIDAsIDgsIDUsIDEyLCAxMF0sXG4gICAgICBbMTEsIDksIDUsIDEsIDEyLCAzLCAxMywgMTQsIDYsIDQsIDcsIDE1LCAyLCAwLCA4LCAxMF1cbiAgICBdO1xuICAgIHZhciByb3I0ID0gWzAsIDgsIDEsIDksIDIsIDEwLCAzLCAxMSwgNCwgMTIsIDUsIDEzLCA2LCAxNCwgNywgMTVdO1xuICAgIHZhciBhc2h4ID0gWzAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMiwgNSwgMTQsIDddO1xuICAgIHZhciBxID0gW1xuICAgICAgW10sXG4gICAgICBbXVxuICAgIF07XG4gICAgdmFyIG0gPSBbXG4gICAgICBbXSxcbiAgICAgIFtdLFxuICAgICAgW10sXG4gICAgICBbXVxuICAgIF07XG5cbiAgICBmdW5jdGlvbiBmZm01Yih4KSB7XG4gICAgICByZXR1cm4geCBeICh4ID4+IDIpIF4gWzAsIDkwLCAxODAsIDIzOF1beCAmIDNdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZmbUVmKHgpIHtcbiAgICAgIHJldHVybiB4IF4gKHggPj4gMSkgXiAoeCA+PiAyKSBeIFswLCAyMzgsIDE4MCwgOTBdW3ggJiAzXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtZHNSZW0ocCwgcSkge1xuICAgICAgdmFyIGksIHQsIHU7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgODsgaSsrKSB7XG4gICAgICAgIHQgPSBxID4+PiAyNDtcbiAgICAgICAgcSA9ICgocSA8PCA4KSAmIE1BWElOVCkgfCBwID4+PiAyNDtcbiAgICAgICAgcCA9IChwIDw8IDgpICYgTUFYSU5UO1xuICAgICAgICB1ID0gdCA8PCAxO1xuICAgICAgICBpZiAodCAmIDEyOCkge1xuICAgICAgICAgIHUgXj0gMzMzO1xuICAgICAgICB9XG4gICAgICAgIHEgXj0gdCBeICh1IDw8IDE2KTtcbiAgICAgICAgdSBePSB0ID4+PiAxO1xuICAgICAgICBpZiAodCAmIDEpIHtcbiAgICAgICAgICB1IF49IDE2NjtcbiAgICAgICAgfVxuICAgICAgICBxIF49IHUgPDwgMjQgfCB1IDw8IDg7XG4gICAgICB9XG4gICAgICByZXR1cm4gcTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBxcChuLCB4KSB7XG4gICAgICB2YXIgYSwgYiwgYywgZDtcbiAgICAgIGEgPSB4ID4+IDQ7XG4gICAgICBiID0geCAmIDE1O1xuICAgICAgYyA9IHEwW25dW2EgXiBiXTtcbiAgICAgIGQgPSBxMVtuXVtyb3I0W2JdIF4gYXNoeFthXV07XG4gICAgICByZXR1cm4gcTNbbl1bcm9yNFtkXSBeIGFzaHhbY11dIDw8IDQgfCBxMltuXVtjIF4gZF07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaEZ1bih4LCBrZXkpIHtcbiAgICAgIHZhciBhID0gZ2V0Qih4LCAwKSxcbiAgICAgICAgYiA9IGdldEIoeCwgMSksXG4gICAgICAgIGMgPSBnZXRCKHgsIDIpLFxuICAgICAgICBkID0gZ2V0Qih4LCAzKTtcbiAgICAgIHN3aXRjaCAoa0xlbikge1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgYSA9IHFbMV1bYV0gXiBnZXRCKGtleVszXSwgMCk7XG4gICAgICAgICAgYiA9IHFbMF1bYl0gXiBnZXRCKGtleVszXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMF1bY10gXiBnZXRCKGtleVszXSwgMik7XG4gICAgICAgICAgZCA9IHFbMV1bZF0gXiBnZXRCKGtleVszXSwgMyk7XG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBhID0gcVsxXVthXSBeIGdldEIoa2V5WzJdLCAwKTtcbiAgICAgICAgICBiID0gcVsxXVtiXSBeIGdldEIoa2V5WzJdLCAxKTtcbiAgICAgICAgICBjID0gcVswXVtjXSBeIGdldEIoa2V5WzJdLCAyKTtcbiAgICAgICAgICBkID0gcVswXVtkXSBeIGdldEIoa2V5WzJdLCAzKTtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIGEgPSBxWzBdW3FbMF1bYV0gXiBnZXRCKGtleVsxXSwgMCldIF4gZ2V0QihrZXlbMF0sIDApO1xuICAgICAgICAgIGIgPSBxWzBdW3FbMV1bYl0gXiBnZXRCKGtleVsxXSwgMSldIF4gZ2V0QihrZXlbMF0sIDEpO1xuICAgICAgICAgIGMgPSBxWzFdW3FbMF1bY10gXiBnZXRCKGtleVsxXSwgMildIF4gZ2V0QihrZXlbMF0sIDIpO1xuICAgICAgICAgIGQgPSBxWzFdW3FbMV1bZF0gXiBnZXRCKGtleVsxXSwgMyldIF4gZ2V0QihrZXlbMF0sIDMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1bMF1bYV0gXiBtWzFdW2JdIF4gbVsyXVtjXSBeIG1bM11bZF07XG4gICAgfVxuXG4gICAga2V5Qnl0ZXMgPSBrZXlCeXRlcy5zbGljZSgwLCAzMik7XG4gICAgaSA9IGtleUJ5dGVzLmxlbmd0aDtcbiAgICB3aGlsZSAoaSAhPSAxNiAmJiBpICE9IDI0ICYmIGkgIT0gMzIpXG4gICAgICBrZXlCeXRlc1tpKytdID0gMDtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBrZXlCeXRlcy5sZW5ndGg7IGkgKz0gNCkge1xuICAgICAgaW5LZXlbaSA+PiAyXSA9IGdldFcoa2V5Qnl0ZXMsIGkpO1xuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcbiAgICAgIHFbMF1baV0gPSBxcCgwLCBpKTtcbiAgICAgIHFbMV1baV0gPSBxcCgxLCBpKTtcbiAgICB9XG4gICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7XG4gICAgICBmMDEgPSBxWzFdW2ldO1xuICAgICAgZjViID0gZmZtNWIoZjAxKTtcbiAgICAgIGZlZiA9IGZmbUVmKGYwMSk7XG4gICAgICBtWzBdW2ldID0gZjAxICsgKGY1YiA8PCA4KSArIChmZWYgPDwgMTYpICsgKGZlZiA8PCAyNCk7XG4gICAgICBtWzJdW2ldID0gZjViICsgKGZlZiA8PCA4KSArIChmMDEgPDwgMTYpICsgKGZlZiA8PCAyNCk7XG4gICAgICBmMDEgPSBxWzBdW2ldO1xuICAgICAgZjViID0gZmZtNWIoZjAxKTtcbiAgICAgIGZlZiA9IGZmbUVmKGYwMSk7XG4gICAgICBtWzFdW2ldID0gZmVmICsgKGZlZiA8PCA4KSArIChmNWIgPDwgMTYpICsgKGYwMSA8PCAyNCk7XG4gICAgICBtWzNdW2ldID0gZjViICsgKGYwMSA8PCA4KSArIChmZWYgPDwgMTYpICsgKGY1YiA8PCAyNCk7XG4gICAgfVxuXG4gICAga0xlbiA9IGluS2V5Lmxlbmd0aCAvIDI7XG4gICAgZm9yIChpID0gMDsgaSA8IGtMZW47IGkrKykge1xuICAgICAgYSA9IGluS2V5W2kgKyBpXTtcbiAgICAgIG1lS2V5W2ldID0gYTtcbiAgICAgIGIgPSBpbktleVtpICsgaSArIDFdO1xuICAgICAgbW9LZXlbaV0gPSBiO1xuICAgICAgc0tleVtrTGVuIC0gaSAtIDFdID0gbWRzUmVtKGEsIGIpO1xuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgNDA7IGkgKz0gMikge1xuICAgICAgYSA9IDB4MTAxMDEwMSAqIGk7XG4gICAgICBiID0gYSArIDB4MTAxMDEwMTtcbiAgICAgIGEgPSBoRnVuKGEsIG1lS2V5KTtcbiAgICAgIGIgPSByb3R3KGhGdW4oYiwgbW9LZXkpLCA4KTtcbiAgICAgIHRmc0tleVtpXSA9IChhICsgYikgJiBNQVhJTlQ7XG4gICAgICB0ZnNLZXlbaSArIDFdID0gcm90dyhhICsgMiAqIGIsIDkpO1xuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcbiAgICAgIGEgPSBiID0gYyA9IGQgPSBpO1xuICAgICAgc3dpdGNoIChrTGVuKSB7XG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBhID0gcVsxXVthXSBeIGdldEIoc0tleVszXSwgMCk7XG4gICAgICAgICAgYiA9IHFbMF1bYl0gXiBnZXRCKHNLZXlbM10sIDEpO1xuICAgICAgICAgIGMgPSBxWzBdW2NdIF4gZ2V0QihzS2V5WzNdLCAyKTtcbiAgICAgICAgICBkID0gcVsxXVtkXSBeIGdldEIoc0tleVszXSwgMyk7XG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBhID0gcVsxXVthXSBeIGdldEIoc0tleVsyXSwgMCk7XG4gICAgICAgICAgYiA9IHFbMV1bYl0gXiBnZXRCKHNLZXlbMl0sIDEpO1xuICAgICAgICAgIGMgPSBxWzBdW2NdIF4gZ2V0QihzS2V5WzJdLCAyKTtcbiAgICAgICAgICBkID0gcVswXVtkXSBeIGdldEIoc0tleVsyXSwgMyk7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICB0ZnNNWzBdW2ldID0gbVswXVtxWzBdW3FbMF1bYV0gXiBnZXRCKHNLZXlbMV0sIDApXSBeIGdldEIoc0tleVswXSwgMCldO1xuICAgICAgICAgIHRmc01bMV1baV0gPSBtWzFdW3FbMF1bcVsxXVtiXSBeIGdldEIoc0tleVsxXSwgMSldIF4gZ2V0QihzS2V5WzBdLCAxKV07XG4gICAgICAgICAgdGZzTVsyXVtpXSA9IG1bMl1bcVsxXVtxWzBdW2NdIF4gZ2V0QihzS2V5WzFdLCAyKV0gXiBnZXRCKHNLZXlbMF0sIDIpXTtcbiAgICAgICAgICB0ZnNNWzNdW2ldID0gbVszXVtxWzFdW3FbMV1bZF0gXiBnZXRCKHNLZXlbMV0sIDMpXSBeIGdldEIoc0tleVswXSwgMyldO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHRmc0cwKHgpIHtcbiAgICByZXR1cm4gdGZzTVswXVtnZXRCKHgsIDApXSBeIHRmc01bMV1bZ2V0Qih4LCAxKV0gXiB0ZnNNWzJdW2dldEIoeCwgMildIF4gdGZzTVszXVtnZXRCKHgsIDMpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRmc0cxKHgpIHtcbiAgICByZXR1cm4gdGZzTVswXVtnZXRCKHgsIDMpXSBeIHRmc01bMV1bZ2V0Qih4LCAwKV0gXiB0ZnNNWzJdW2dldEIoeCwgMSldIF4gdGZzTVszXVtnZXRCKHgsIDIpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRmc0ZybmQociwgYmxrKSB7XG4gICAgdmFyIGEgPSB0ZnNHMChibGtbMF0pO1xuICAgIHZhciBiID0gdGZzRzEoYmxrWzFdKTtcbiAgICBibGtbMl0gPSByb3R3KGJsa1syXSBeIChhICsgYiArIHRmc0tleVs0ICogciArIDhdKSAmIE1BWElOVCwgMzEpO1xuICAgIGJsa1szXSA9IHJvdHcoYmxrWzNdLCAxKSBeIChhICsgMiAqIGIgKyB0ZnNLZXlbNCAqIHIgKyA5XSkgJiBNQVhJTlQ7XG4gICAgYSA9IHRmc0cwKGJsa1syXSk7XG4gICAgYiA9IHRmc0cxKGJsa1szXSk7XG4gICAgYmxrWzBdID0gcm90dyhibGtbMF0gXiAoYSArIGIgKyB0ZnNLZXlbNCAqIHIgKyAxMF0pICYgTUFYSU5ULCAzMSk7XG4gICAgYmxrWzFdID0gcm90dyhibGtbMV0sIDEpIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogciArIDExXSkgJiBNQVhJTlQ7XG4gIH1cblxuICBmdW5jdGlvbiB0ZnNJcm5kKGksIGJsaykge1xuICAgIHZhciBhID0gdGZzRzAoYmxrWzBdKTtcbiAgICB2YXIgYiA9IHRmc0cxKGJsa1sxXSk7XG4gICAgYmxrWzJdID0gcm90dyhibGtbMl0sIDEpIF4gKGEgKyBiICsgdGZzS2V5WzQgKiBpICsgMTBdKSAmIE1BWElOVDtcbiAgICBibGtbM10gPSByb3R3KGJsa1szXSBeIChhICsgMiAqIGIgKyB0ZnNLZXlbNCAqIGkgKyAxMV0pICYgTUFYSU5ULCAzMSk7XG4gICAgYSA9IHRmc0cwKGJsa1syXSk7XG4gICAgYiA9IHRmc0cxKGJsa1szXSk7XG4gICAgYmxrWzBdID0gcm90dyhibGtbMF0sIDEpIF4gKGEgKyBiICsgdGZzS2V5WzQgKiBpICsgOF0pICYgTUFYSU5UO1xuICAgIGJsa1sxXSA9IHJvdHcoYmxrWzFdIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogaSArIDldKSAmIE1BWElOVCwgMzEpO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzQ2xvc2UoKSB7XG4gICAgdGZzS2V5ID0gW107XG4gICAgdGZzTSA9IFtcbiAgICAgIFtdLFxuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdXG4gICAgXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRmc0VuY3J5cHQoZGF0YSwgb2Zmc2V0KSB7XG4gICAgZGF0YUJ5dGVzID0gZGF0YTtcbiAgICBkYXRhT2Zmc2V0ID0gb2Zmc2V0O1xuICAgIHZhciBibGsgPSBbZ2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQpIF4gdGZzS2V5WzBdLFxuICAgICAgICBnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDQpIF4gdGZzS2V5WzFdLFxuICAgICAgICBnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDgpIF4gdGZzS2V5WzJdLFxuICAgICAgICBnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDEyKSBeIHRmc0tleVszXVxuICAgIF07XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCA4OyBqKyspIHtcbiAgICAgIHRmc0ZybmQoaiwgYmxrKTtcbiAgICB9XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQsIGJsa1syXSBeIHRmc0tleVs0XSk7XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA0LCBibGtbM10gXiB0ZnNLZXlbNV0pO1xuICAgIHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCwgYmxrWzBdIF4gdGZzS2V5WzZdKTtcbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDEyLCBibGtbMV0gXiB0ZnNLZXlbN10pO1xuICAgIGRhdGFPZmZzZXQgKz0gMTY7XG4gICAgcmV0dXJuIGRhdGFCeXRlcztcbiAgfVxuXG4gIGZ1bmN0aW9uIHRmc0RlY3J5cHQoZGF0YSwgb2Zmc2V0KSB7XG4gICAgZGF0YUJ5dGVzID0gZGF0YTtcbiAgICBkYXRhT2Zmc2V0ID0gb2Zmc2V0O1xuICAgIHZhciBibGsgPSBbZ2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQpIF4gdGZzS2V5WzRdLFxuICAgICAgICBnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDQpIF4gdGZzS2V5WzVdLFxuICAgICAgICBnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDgpIF4gdGZzS2V5WzZdLFxuICAgICAgICBnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDEyKSBeIHRmc0tleVs3XVxuICAgIF07XG4gICAgZm9yICh2YXIgaiA9IDc7IGogPj0gMDsgai0tKSB7XG4gICAgICB0ZnNJcm5kKGosIGJsayk7XG4gICAgfVxuICAgIHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0LCBibGtbMl0gXiB0ZnNLZXlbMF0pO1xuICAgIHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgNCwgYmxrWzNdIF4gdGZzS2V5WzFdKTtcbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDgsIGJsa1swXSBeIHRmc0tleVsyXSk7XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyAxMiwgYmxrWzFdIF4gdGZzS2V5WzNdKTtcbiAgICBkYXRhT2Zmc2V0ICs9IDE2O1xuICB9XG5cbiAgLy8gYWRkZWQgYnkgUmVjdXJpdHkgTGFic1xuXG4gIGZ1bmN0aW9uIHRmc0ZpbmFsKCkge1xuICAgIHJldHVybiBkYXRhQnl0ZXM7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5hbWU6IFwidHdvZmlzaFwiLFxuICAgIGJsb2Nrc2l6ZTogMTI4IC8gOCxcbiAgICBvcGVuOiB0ZnNJbml0LFxuICAgIGNsb3NlOiB0ZnNDbG9zZSxcbiAgICBlbmNyeXB0OiB0ZnNFbmNyeXB0LFxuICAgIGRlY3J5cHQ6IHRmc0RlY3J5cHQsXG4gICAgLy8gYWRkZWQgYnkgUmVjdXJpdHkgTGFic1xuICAgIGZpbmFsaXplOiB0ZnNGaW5hbFxuICB9O1xufVxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuLy8gYWRkZWQgYnkgUmVjdXJpdHkgTGFic1xuXG5mdW5jdGlvbiBURmVuY3J5cHQoYmxvY2ssIGtleSkge1xuICB2YXIgYmxvY2tfY29weSA9IFtdLmNvbmNhdChibG9jayk7XG4gIHZhciB0ZiA9IGNyZWF0ZVR3b2Zpc2goKTtcbiAgdGYub3Blbih1dGlsLnN0cjJiaW4oa2V5KSwgMCk7XG4gIHZhciByZXN1bHQgPSB0Zi5lbmNyeXB0KGJsb2NrX2NvcHksIDApO1xuICB0Zi5jbG9zZSgpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBURihrZXkpIHtcbiAgdGhpcy50ZiA9IGNyZWF0ZVR3b2Zpc2goKTtcbiAgdGhpcy50Zi5vcGVuKHV0aWwuc3RyMmJpbihrZXkpLCAwKTtcblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaykge1xuICAgIHJldHVybiB0aGlzLnRmLmVuY3J5cHQoW10uY29uY2F0KGJsb2NrKSwgMCk7XG4gIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IFRGO1xubW9kdWxlLmV4cG9ydHMua2V5U2l6ZSA9IFRGLnByb3RvdHlwZS5rZXlTaXplID0gMzI7XG5tb2R1bGUuZXhwb3J0cy5ibG9ja1NpemUgPSBURi5wcm90b3R5cGUuYmxvY2tTaXplID0gMTY7XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQSBcblxuLy8gVGhlIEdQRzRCcm93c2VycyBjcnlwdG8gaW50ZXJmYWNlXG5cbnZhciByYW5kb20gPSByZXF1aXJlKCcuL3JhbmRvbS5qcycpLFxuICBjaXBoZXIgPSByZXF1aXJlKCcuL2NpcGhlcicpLFxuICBwdWJsaWNLZXkgPSByZXF1aXJlKCcuL3B1YmxpY19rZXknKSxcbiAgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgLyoqXG4gICAqIEVuY3J5cHRzIGRhdGEgdXNpbmcgdGhlIHNwZWNpZmllZCBwdWJsaWMga2V5IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICAgKiBhbmQgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBbGdvcml0aG0gdG8gYmUgdXNlZCAoU2VlIFJGQzQ4ODAgOS4xKVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gcHVibGljTVBJcyBBbGdvcml0aG0gZGVwZW5kZW50IG11bHRpcHJlY2lzaW9uIGludGVnZXJzXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waX0gZGF0YSBEYXRhIHRvIGJlIGVuY3J5cHRlZCBhcyBNUElcbiAgICogQHJldHVybiB7b3BlbnBncF90eXBlX21waVtdfSBpZiBSU0EgYW4gb3BlbnBncF90eXBlX21waTsgXG4gICAqIGlmIGVsZ2FtYWwgZW5jcnlwdGlvbiBhbiBhcnJheSBvZiB0d28gb3BlbnBncF90eXBlX21waSBpcyByZXR1cm5lZDsgb3RoZXJ3aXNlIG51bGxcbiAgICovXG4gIHB1YmxpY0tleUVuY3J5cHQ6IGZ1bmN0aW9uKGFsZ28sIHB1YmxpY01QSXMsIGRhdGEpIHtcbiAgICB2YXIgcmVzdWx0ID0gKGZ1bmN0aW9uKCkge1xuICAgICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICAgICAgdmFyIHJzYSA9IG5ldyBwdWJsaWNLZXkucnNhKCk7XG4gICAgICAgICAgdmFyIG4gPSBwdWJsaWNNUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBlID0gcHVibGljTVBJc1sxXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgbSA9IGRhdGEudG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgcmV0dXJuIFtyc2EuZW5jcnlwdChtLCBlLCBuKV07XG5cbiAgICAgICAgY2FzZSAnZWxnYW1hbCc6XG4gICAgICAgICAgdmFyIGVsZ2FtYWwgPSBuZXcgcHVibGljS2V5LmVsZ2FtYWwoKTtcbiAgICAgICAgICB2YXIgcCA9IHB1YmxpY01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIGcgPSBwdWJsaWNNUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciB5ID0gcHVibGljTVBJc1syXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgbSA9IGRhdGEudG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgcmV0dXJuIGVsZ2FtYWwuZW5jcnlwdChtLCBnLCBwLCB5KTtcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgcmV0dXJuIHJlc3VsdC5tYXAoZnVuY3Rpb24oYm4pIHtcbiAgICAgIHZhciBtcGkgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICAgIG1waS5mcm9tQmlnSW50ZWdlcihibik7XG4gICAgICByZXR1cm4gbXBpO1xuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBEZWNyeXB0cyBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHVibGljIGtleSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBvZiB0aGUgcHJpdmF0ZSBrZXksXG4gICAqIHRoZSBzcGVjaWZpZWQgc2VjcmV0TVBJcyBvZiB0aGUgcHJpdmF0ZSBrZXkgYW5kIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLlxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIGJlIHVzZWQgKFNlZSBSRkM0ODgwIDkuMSlcbiAgICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpW119IHB1YmxpY01QSXMgQWxnb3JpdGhtIGRlcGVuZGVudCBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBcbiAgICogb2YgdGhlIHB1YmxpYyBrZXkgcGFydCBvZiB0aGUgcHJpdmF0ZSBrZXlcbiAgICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpW119IHNlY3JldE1QSXMgQWxnb3JpdGhtIGRlcGVuZGVudCBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBcbiAgICogb2YgdGhlIHByaXZhdGUga2V5IHVzZWRcbiAgICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpfSBkYXRhIERhdGEgdG8gYmUgZW5jcnlwdGVkIGFzIE1QSVxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3R5cGVfbXBpfSByZXR1cm5zIGEgYmlnIGludGVnZXIgY29udGFpbmluZyB0aGUgZGVjcnlwdGVkIGRhdGE7IG90aGVyd2lzZSBudWxsXG4gICAqL1xuXG4gIHB1YmxpY0tleURlY3J5cHQ6IGZ1bmN0aW9uKGFsZ28sIGtleUludGVnZXJzLCBkYXRhSW50ZWdlcnMpIHtcbiAgICB2YXIgYm4gPSAoZnVuY3Rpb24oKSB7XG4gICAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgICAgICB2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcbiAgICAgICAgICAvLyAwIGFuZCAxIGFyZSB0aGUgcHVibGljIGtleS5cbiAgICAgICAgICB2YXIgZCA9IGtleUludGVnZXJzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBwID0ga2V5SW50ZWdlcnNbM10udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIHEgPSBrZXlJbnRlZ2Vyc1s0XS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgdSA9IGtleUludGVnZXJzWzVdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBtID0gZGF0YUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHJldHVybiByc2EuZGVjcnlwdChtLCBkLCBwLCBxLCB1KTtcbiAgICAgICAgY2FzZSAnZWxnYW1hbCc6XG4gICAgICAgICAgdmFyIGVsZ2FtYWwgPSBuZXcgcHVibGljS2V5LmVsZ2FtYWwoKTtcbiAgICAgICAgICB2YXIgeCA9IGtleUludGVnZXJzWzNdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBjMSA9IGRhdGFJbnRlZ2Vyc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgYzIgPSBkYXRhSW50ZWdlcnNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIHAgPSBrZXlJbnRlZ2Vyc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICByZXR1cm4gZWxnYW1hbC5kZWNyeXB0KGMxLCBjMiwgcCwgeCk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfSkoKTtcblxuICAgIHZhciByZXN1bHQgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICByZXN1bHQuZnJvbUJpZ0ludGVnZXIoYm4pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqIFJldHVybnMgdGhlIG51bWJlciBvZiBpbnRlZ2VycyBjb21wcmlzaW5nIHRoZSBwcml2YXRlIGtleSBvZiBhbiBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtvcGVucGdwLnB1YmxpY2tleX0gYWxnbyBUaGUgcHVibGljIGtleSBhbGdvcml0aG1cbiAgICogQHJldHVybiB7SW50ZWdlcn0gVGhlIG51bWJlciBvZiBpbnRlZ2Vycy5cbiAgICovXG4gIGdldFByaXZhdGVNcGlDb3VudDogZnVuY3Rpb24oYWxnbykge1xuICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICBjYXNlICdyc2Ffc2lnbic6XG4gICAgICAgIC8vICAgQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgUlNBIHNlY3JldCBrZXlzOlxuICAgICAgICAvLyAgIC0gbXVsdGlwcmVjaXNpb24gaW50ZWdlciAoTVBJKSBvZiBSU0Egc2VjcmV0IGV4cG9uZW50IGQuXG4gICAgICAgIC8vICAgLSBNUEkgb2YgUlNBIHNlY3JldCBwcmltZSB2YWx1ZSBwLlxuICAgICAgICAvLyAgIC0gTVBJIG9mIFJTQSBzZWNyZXQgcHJpbWUgdmFsdWUgcSAocCA8IHEpLlxuICAgICAgICAvLyAgIC0gTVBJIG9mIHUsIHRoZSBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlIG9mIHAsIG1vZCBxLlxuICAgICAgICByZXR1cm4gNDtcbiAgICAgIGNhc2UgJ2VsZ2FtYWwnOlxuICAgICAgICAvLyBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBFbGdhbWFsIHNlY3JldCBrZXlzOlxuICAgICAgICAvLyAgIC0gTVBJIG9mIEVsZ2FtYWwgc2VjcmV0IGV4cG9uZW50IHguXG4gICAgICAgIHJldHVybiAxO1xuICAgICAgY2FzZSAnZHNhJzpcbiAgICAgICAgLy8gQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRFNBIHNlY3JldCBrZXlzOlxuICAgICAgICAvLyAgIC0gTVBJIG9mIERTQSBzZWNyZXQgZXhwb25lbnQgeC5cbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gYWxnb3JpdGhtJyk7XG4gICAgfVxuICB9LFxuXG4gIGdldFB1YmxpY01waUNvdW50OiBmdW5jdGlvbihhbGdvKSB7XG4gICAgLy8gLSBBIHNlcmllcyBvZiBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBjb21wcmlzaW5nIHRoZSBrZXkgbWF0ZXJpYWw6XG4gICAgLy8gICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBSU0EgcHVibGljIGtleXM6XG4gICAgLy8gICAgICAgLSBhIG11bHRpcHJlY2lzaW9uIGludGVnZXIgKE1QSSkgb2YgUlNBIHB1YmxpYyBtb2R1bHVzIG47XG4gICAgLy8gICAgICAgLSBhbiBNUEkgb2YgUlNBIHB1YmxpYyBlbmNyeXB0aW9uIGV4cG9uZW50IGUuXG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlICdyc2FfZW5jcnlwdCc6XG4gICAgICBjYXNlICdyc2FfZW5jcnlwdF9zaWduJzpcbiAgICAgIGNhc2UgJ3JzYV9zaWduJzpcbiAgICAgICAgcmV0dXJuIDI7XG5cbiAgICAgICAgLy8gICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBFbGdhbWFsIHB1YmxpYyBrZXlzOlxuICAgICAgICAvLyAgICAgLSBNUEkgb2YgRWxnYW1hbCBwcmltZSBwO1xuICAgICAgICAvLyAgICAgLSBNUEkgb2YgRWxnYW1hbCBncm91cCBnZW5lcmF0b3IgZztcbiAgICAgICAgLy8gICAgIC0gTVBJIG9mIEVsZ2FtYWwgcHVibGljIGtleSB2YWx1ZSB5ICg9IGcqKnggbW9kIHAgd2hlcmUgeCAgaXMgc2VjcmV0KS5cbiAgICAgIGNhc2UgJ2VsZ2FtYWwnOlxuICAgICAgICByZXR1cm4gMztcblxuICAgICAgICAvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIERTQSBwdWJsaWMga2V5czpcbiAgICAgICAgLy8gICAgICAgLSBNUEkgb2YgRFNBIHByaW1lIHA7XG4gICAgICAgIC8vICAgICAgIC0gTVBJIG9mIERTQSBncm91cCBvcmRlciBxIChxIGlzIGEgcHJpbWUgZGl2aXNvciBvZiBwLTEpO1xuICAgICAgICAvLyAgICAgICAtIE1QSSBvZiBEU0EgZ3JvdXAgZ2VuZXJhdG9yIGc7XG4gICAgICAgIC8vICAgICAgIC0gTVBJIG9mIERTQSBwdWJsaWMta2V5IHZhbHVlIHkgKD0gZyoqeCBtb2QgcCB3aGVyZSB4ICBpcyBzZWNyZXQpLlxuICAgICAgY2FzZSAnZHNhJzpcbiAgICAgICAgcmV0dXJuIDQ7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBhbGdvcml0aG0uJyk7XG4gICAgfVxuICB9LFxuXG4gIGdlbmVyYXRlTXBpOiBmdW5jdGlvbihhbGdvLCBiaXRzKSB7XG4gICAgdmFyIHJlc3VsdCA9IChmdW5jdGlvbigpIHtcbiAgICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgICBjYXNlICdyc2FfZW5jcnlwdCc6XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0X3NpZ24nOlxuICAgICAgICBjYXNlICdyc2Ffc2lnbic6XG4gICAgICAgICAgLy9yZW1lbWJlciBcInB1YmxpY0tleVwiIHJlZmVycyB0byB0aGUgY3J5cHRvL3B1YmxpY19rZXkgZGlyXG4gICAgICAgICAgdmFyIHJzYSA9IG5ldyBwdWJsaWNLZXkucnNhKCk7XG4gICAgICAgICAgdmFyIGtleU9iamVjdCA9IHJzYS5nZW5lcmF0ZShiaXRzLCBcIjEwMDAxXCIpO1xuICAgICAgICAgIHZhciBvdXRwdXQgPSBbXTtcbiAgICAgICAgICBvdXRwdXQucHVzaChrZXlPYmplY3Qubik7XG4gICAgICAgICAgb3V0cHV0LnB1c2goa2V5T2JqZWN0LmVlKTtcbiAgICAgICAgICBvdXRwdXQucHVzaChrZXlPYmplY3QuZCk7XG4gICAgICAgICAgb3V0cHV0LnB1c2goa2V5T2JqZWN0LnApO1xuICAgICAgICAgIG91dHB1dC5wdXNoKGtleU9iamVjdC5xKTtcbiAgICAgICAgICBvdXRwdXQucHVzaChrZXlPYmplY3QudSk7XG4gICAgICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGFsZ29yaXRobSBmb3Iga2V5IGdlbmVyYXRpb24uJyk7XG4gICAgICB9XG4gICAgfSkoKTtcblxuICAgIHJldHVybiByZXN1bHQubWFwKGZ1bmN0aW9uKGJuKSB7XG4gICAgICB2YXIgbXBpID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgICBtcGkuZnJvbUJpZ0ludGVnZXIoYm4pO1xuICAgICAgcmV0dXJuIG1waTtcbiAgICB9KTtcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBnZW5lcmF0ZSByYW5kb20gYnl0ZSBwcmVmaXggYXMgc3RyaW5nIGZvciB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIHVzZSAoc2VlIFJGQzQ4ODAgOS4yKVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFJhbmRvbSBieXRlcyB3aXRoIGxlbmd0aCBlcXVhbCB0byB0aGUgYmxvY2tcbiAgICogc2l6ZSBvZiB0aGUgY2lwaGVyXG4gICAqL1xuICBnZXRQcmVmaXhSYW5kb206IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICByZXR1cm4gcmFuZG9tLmdldFJhbmRvbUJ5dGVzKGNpcGhlclthbGdvXS5ibG9ja1NpemUpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZW5lcmF0aW5nIGEgc2Vzc2lvbiBrZXkgZm9yIHRoZSBzcGVjaWZpZWQgc3ltbWV0cmljIGFsZ29yaXRobVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIHVzZSAoc2VlIFJGQzQ4ODAgOS4yKVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFJhbmRvbSBieXRlcyBhcyBhIHN0cmluZyB0byBiZSB1c2VkIGFzIGEga2V5XG4gICAqL1xuICBnZW5lcmF0ZVNlc3Npb25LZXk6IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICByZXR1cm4gcmFuZG9tLmdldFJhbmRvbUJ5dGVzKGNpcGhlclthbGdvXS5rZXlTaXplKTtcbiAgfSxcblxufTtcbiIsInZhciBzaGEgPSByZXF1aXJlKCcuL3NoYS5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbWQ1OiByZXF1aXJlKCcuL21kNS5qcycpLFxuICBzaGExOiBzaGEuc2hhMSxcbiAgc2hhMjU2OiBzaGEuc2hhMjU2LFxuICBzaGEyMjQ6IHNoYS5zaGEyMjQsXG4gIHNoYTM4NDogc2hhLnNoYTM4NCxcbiAgc2hhNTEyOiBzaGEuc2hhNTEyLFxuICByaXBlbWQ6IHJlcXVpcmUoJy4vcmlwZS1tZC5qcycpLFxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBoYXNoIG9uIHRoZSBzcGVjaWZpZWQgZGF0YSB1c2luZyB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gSGFzaCBhbGdvcml0aG0gdHlwZSAoc2VlIFJGQzQ4ODAgOS40KVxuICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGJlIGhhc2hlZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGhhc2ggdmFsdWVcbiAgICovXG4gIGRpZ2VzdDogZnVuY3Rpb24oYWxnbywgZGF0YSkge1xuICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgY2FzZSAxOlxuICAgICAgICAvLyAtIE1ENSBbSEFDXVxuICAgICAgICByZXR1cm4gdGhpcy5tZDUoZGF0YSk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIC8vIC0gU0hBLTEgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiB0aGlzLnNoYTEoZGF0YSk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIC8vIC0gUklQRS1NRC8xNjAgW0hBQ11cbiAgICAgICAgcmV0dXJuIHRoaXMucmlwZW1kKGRhdGEpO1xuICAgICAgY2FzZSA4OlxuICAgICAgICAvLyAtIFNIQTI1NiBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2hhMjU2KGRhdGEpO1xuICAgICAgY2FzZSA5OlxuICAgICAgICAvLyAtIFNIQTM4NCBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2hhMzg0KGRhdGEpO1xuICAgICAgY2FzZSAxMDpcbiAgICAgICAgLy8gLSBTSEE1MTIgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiB0aGlzLnNoYTUxMihkYXRhKTtcbiAgICAgIGNhc2UgMTE6XG4gICAgICAgIC8vIC0gU0hBMjI0IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gdGhpcy5zaGEyMjQoZGF0YSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGFzaCBmdW5jdGlvbi4nKTtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGhhc2ggc2l6ZSBpbiBieXRlcyBvZiB0aGUgc3BlY2lmaWVkIGhhc2ggYWxnb3JpdGhtIHR5cGVcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEhhc2ggYWxnb3JpdGhtIHR5cGUgKFNlZSBSRkM0ODgwIDkuNClcbiAgICogQHJldHVybiB7SW50ZWdlcn0gU2l6ZSBpbiBieXRlcyBvZiB0aGUgcmVzdWx0aW5nIGhhc2hcbiAgICovXG4gIGdldEhhc2hCeXRlTGVuZ3RoOiBmdW5jdGlvbihhbGdvKSB7XG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIC8vIC0gTUQ1IFtIQUNdXG4gICAgICAgIHJldHVybiAxNjtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gLSBTSEEtMSBbRklQUzE4MF1cbiAgICAgIGNhc2UgMzpcbiAgICAgICAgLy8gLSBSSVBFLU1ELzE2MCBbSEFDXVxuICAgICAgICByZXR1cm4gMjA7XG4gICAgICBjYXNlIDg6XG4gICAgICAgIC8vIC0gU0hBMjU2IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gMzI7XG4gICAgICBjYXNlIDk6XG4gICAgICAgIC8vIC0gU0hBMzg0IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gNDhcbiAgICAgIGNhc2UgMTA6XG4gICAgICAgIC8vIC0gU0hBNTEyIFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gNjQ7XG4gICAgICBjYXNlIDExOlxuICAgICAgICAvLyAtIFNIQTIyNCBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIDI4O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhhc2ggYWxnb3JpdGhtLicpO1xuICAgIH1cbiAgfVxuXG59XG4iLCIvKipcbiAqIEEgZmFzdCBNRDUgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvblxuICogQ29weXJpZ2h0IChjKSAyMDEyIEpvc2VwaCBNeWVyc1xuICogaHR0cDovL3d3dy5teWVyc2RhaWx5Lm9yZy9qb3NlcGgvamF2YXNjcmlwdC9tZDUtdGV4dC5odG1sXG4gKlxuICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZVxuICogYW5kIGl0cyBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZXMgYW5kIHdpdGhvdXRcbiAqIGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCBwcm92aWRlZCB0aGF0IHRoaXMgY29weXJpZ2h0IG5vdGljZVxuICogYXBwZWFycyBpbiBhbGwgY29waWVzLlxuICpcbiAqIE9mIGNvdXJzZSwgdGhpcyBzb2Z0IGlzIHByb3ZpZGVkIFwiYXMgaXNcIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZFxuICogd2FycmFudHkgb2YgYW55IGtpbmQuXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsL3V0aWwuanMnKTtcblxuZnVuY3Rpb24gTUQ1KGVudHJlZSkge1xuICB2YXIgaGV4ID0gbWQ1KGVudHJlZSk7XG4gIHZhciBiaW4gPSB1dGlsLmhleDJiaW4oaGV4KTtcbiAgcmV0dXJuIGJpbjtcbn1cblxuZnVuY3Rpb24gbWQ1Y3ljbGUoeCwgaykge1xuICB2YXIgYSA9IHhbMF0sXG4gICAgYiA9IHhbMV0sXG4gICAgYyA9IHhbMl0sXG4gICAgZCA9IHhbM107XG5cbiAgYSA9IGZmKGEsIGIsIGMsIGQsIGtbMF0sIDcsIC02ODA4NzY5MzYpO1xuICBkID0gZmYoZCwgYSwgYiwgYywga1sxXSwgMTIsIC0zODk1NjQ1ODYpO1xuICBjID0gZmYoYywgZCwgYSwgYiwga1syXSwgMTcsIDYwNjEwNTgxOSk7XG4gIGIgPSBmZihiLCBjLCBkLCBhLCBrWzNdLCAyMiwgLTEwNDQ1MjUzMzApO1xuICBhID0gZmYoYSwgYiwgYywgZCwga1s0XSwgNywgLTE3NjQxODg5Nyk7XG4gIGQgPSBmZihkLCBhLCBiLCBjLCBrWzVdLCAxMiwgMTIwMDA4MDQyNik7XG4gIGMgPSBmZihjLCBkLCBhLCBiLCBrWzZdLCAxNywgLTE0NzMyMzEzNDEpO1xuICBiID0gZmYoYiwgYywgZCwgYSwga1s3XSwgMjIsIC00NTcwNTk4Myk7XG4gIGEgPSBmZihhLCBiLCBjLCBkLCBrWzhdLCA3LCAxNzcwMDM1NDE2KTtcbiAgZCA9IGZmKGQsIGEsIGIsIGMsIGtbOV0sIDEyLCAtMTk1ODQxNDQxNyk7XG4gIGMgPSBmZihjLCBkLCBhLCBiLCBrWzEwXSwgMTcsIC00MjA2Myk7XG4gIGIgPSBmZihiLCBjLCBkLCBhLCBrWzExXSwgMjIsIC0xOTkwNDA0MTYyKTtcbiAgYSA9IGZmKGEsIGIsIGMsIGQsIGtbMTJdLCA3LCAxODA0NjAzNjgyKTtcbiAgZCA9IGZmKGQsIGEsIGIsIGMsIGtbMTNdLCAxMiwgLTQwMzQxMTAxKTtcbiAgYyA9IGZmKGMsIGQsIGEsIGIsIGtbMTRdLCAxNywgLTE1MDIwMDIyOTApO1xuICBiID0gZmYoYiwgYywgZCwgYSwga1sxNV0sIDIyLCAxMjM2NTM1MzI5KTtcblxuICBhID0gZ2coYSwgYiwgYywgZCwga1sxXSwgNSwgLTE2NTc5NjUxMCk7XG4gIGQgPSBnZyhkLCBhLCBiLCBjLCBrWzZdLCA5LCAtMTA2OTUwMTYzMik7XG4gIGMgPSBnZyhjLCBkLCBhLCBiLCBrWzExXSwgMTQsIDY0MzcxNzcxMyk7XG4gIGIgPSBnZyhiLCBjLCBkLCBhLCBrWzBdLCAyMCwgLTM3Mzg5NzMwMik7XG4gIGEgPSBnZyhhLCBiLCBjLCBkLCBrWzVdLCA1LCAtNzAxNTU4NjkxKTtcbiAgZCA9IGdnKGQsIGEsIGIsIGMsIGtbMTBdLCA5LCAzODAxNjA4Myk7XG4gIGMgPSBnZyhjLCBkLCBhLCBiLCBrWzE1XSwgMTQsIC02NjA0NzgzMzUpO1xuICBiID0gZ2coYiwgYywgZCwgYSwga1s0XSwgMjAsIC00MDU1Mzc4NDgpO1xuICBhID0gZ2coYSwgYiwgYywgZCwga1s5XSwgNSwgNTY4NDQ2NDM4KTtcbiAgZCA9IGdnKGQsIGEsIGIsIGMsIGtbMTRdLCA5LCAtMTAxOTgwMzY5MCk7XG4gIGMgPSBnZyhjLCBkLCBhLCBiLCBrWzNdLCAxNCwgLTE4NzM2Mzk2MSk7XG4gIGIgPSBnZyhiLCBjLCBkLCBhLCBrWzhdLCAyMCwgMTE2MzUzMTUwMSk7XG4gIGEgPSBnZyhhLCBiLCBjLCBkLCBrWzEzXSwgNSwgLTE0NDQ2ODE0NjcpO1xuICBkID0gZ2coZCwgYSwgYiwgYywga1syXSwgOSwgLTUxNDAzNzg0KTtcbiAgYyA9IGdnKGMsIGQsIGEsIGIsIGtbN10sIDE0LCAxNzM1MzI4NDczKTtcbiAgYiA9IGdnKGIsIGMsIGQsIGEsIGtbMTJdLCAyMCwgLTE5MjY2MDc3MzQpO1xuXG4gIGEgPSBoaChhLCBiLCBjLCBkLCBrWzVdLCA0LCAtMzc4NTU4KTtcbiAgZCA9IGhoKGQsIGEsIGIsIGMsIGtbOF0sIDExLCAtMjAyMjU3NDQ2Myk7XG4gIGMgPSBoaChjLCBkLCBhLCBiLCBrWzExXSwgMTYsIDE4MzkwMzA1NjIpO1xuICBiID0gaGgoYiwgYywgZCwgYSwga1sxNF0sIDIzLCAtMzUzMDk1NTYpO1xuICBhID0gaGgoYSwgYiwgYywgZCwga1sxXSwgNCwgLTE1MzA5OTIwNjApO1xuICBkID0gaGgoZCwgYSwgYiwgYywga1s0XSwgMTEsIDEyNzI4OTMzNTMpO1xuICBjID0gaGgoYywgZCwgYSwgYiwga1s3XSwgMTYsIC0xNTU0OTc2MzIpO1xuICBiID0gaGgoYiwgYywgZCwgYSwga1sxMF0sIDIzLCAtMTA5NDczMDY0MCk7XG4gIGEgPSBoaChhLCBiLCBjLCBkLCBrWzEzXSwgNCwgNjgxMjc5MTc0KTtcbiAgZCA9IGhoKGQsIGEsIGIsIGMsIGtbMF0sIDExLCAtMzU4NTM3MjIyKTtcbiAgYyA9IGhoKGMsIGQsIGEsIGIsIGtbM10sIDE2LCAtNzIyNTIxOTc5KTtcbiAgYiA9IGhoKGIsIGMsIGQsIGEsIGtbNl0sIDIzLCA3NjAyOTE4OSk7XG4gIGEgPSBoaChhLCBiLCBjLCBkLCBrWzldLCA0LCAtNjQwMzY0NDg3KTtcbiAgZCA9IGhoKGQsIGEsIGIsIGMsIGtbMTJdLCAxMSwgLTQyMTgxNTgzNSk7XG4gIGMgPSBoaChjLCBkLCBhLCBiLCBrWzE1XSwgMTYsIDUzMDc0MjUyMCk7XG4gIGIgPSBoaChiLCBjLCBkLCBhLCBrWzJdLCAyMywgLTk5NTMzODY1MSk7XG5cbiAgYSA9IGlpKGEsIGIsIGMsIGQsIGtbMF0sIDYsIC0xOTg2MzA4NDQpO1xuICBkID0gaWkoZCwgYSwgYiwgYywga1s3XSwgMTAsIDExMjY4OTE0MTUpO1xuICBjID0gaWkoYywgZCwgYSwgYiwga1sxNF0sIDE1LCAtMTQxNjM1NDkwNSk7XG4gIGIgPSBpaShiLCBjLCBkLCBhLCBrWzVdLCAyMSwgLTU3NDM0MDU1KTtcbiAgYSA9IGlpKGEsIGIsIGMsIGQsIGtbMTJdLCA2LCAxNzAwNDg1NTcxKTtcbiAgZCA9IGlpKGQsIGEsIGIsIGMsIGtbM10sIDEwLCAtMTg5NDk4NjYwNik7XG4gIGMgPSBpaShjLCBkLCBhLCBiLCBrWzEwXSwgMTUsIC0xMDUxNTIzKTtcbiAgYiA9IGlpKGIsIGMsIGQsIGEsIGtbMV0sIDIxLCAtMjA1NDkyMjc5OSk7XG4gIGEgPSBpaShhLCBiLCBjLCBkLCBrWzhdLCA2LCAxODczMzEzMzU5KTtcbiAgZCA9IGlpKGQsIGEsIGIsIGMsIGtbMTVdLCAxMCwgLTMwNjExNzQ0KTtcbiAgYyA9IGlpKGMsIGQsIGEsIGIsIGtbNl0sIDE1LCAtMTU2MDE5ODM4MCk7XG4gIGIgPSBpaShiLCBjLCBkLCBhLCBrWzEzXSwgMjEsIDEzMDkxNTE2NDkpO1xuICBhID0gaWkoYSwgYiwgYywgZCwga1s0XSwgNiwgLTE0NTUyMzA3MCk7XG4gIGQgPSBpaShkLCBhLCBiLCBjLCBrWzExXSwgMTAsIC0xMTIwMjEwMzc5KTtcbiAgYyA9IGlpKGMsIGQsIGEsIGIsIGtbMl0sIDE1LCA3MTg3ODcyNTkpO1xuICBiID0gaWkoYiwgYywgZCwgYSwga1s5XSwgMjEsIC0zNDM0ODU1NTEpO1xuXG4gIHhbMF0gPSBhZGQzMihhLCB4WzBdKTtcbiAgeFsxXSA9IGFkZDMyKGIsIHhbMV0pO1xuICB4WzJdID0gYWRkMzIoYywgeFsyXSk7XG4gIHhbM10gPSBhZGQzMihkLCB4WzNdKTtcblxufVxuXG5mdW5jdGlvbiBjbW4ocSwgYSwgYiwgeCwgcywgdCkge1xuICBhID0gYWRkMzIoYWRkMzIoYSwgcSksIGFkZDMyKHgsIHQpKTtcbiAgcmV0dXJuIGFkZDMyKChhIDw8IHMpIHwgKGEgPj4+ICgzMiAtIHMpKSwgYik7XG59XG5cbmZ1bmN0aW9uIGZmKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIGNtbigoYiAmIGMpIHwgKCh+YikgJiBkKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIGdnKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIGNtbigoYiAmIGQpIHwgKGMgJiAofmQpKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIGhoKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIGNtbihiIF4gYyBeIGQsIGEsIGIsIHgsIHMsIHQpO1xufVxuXG5mdW5jdGlvbiBpaShhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBjbW4oYyBeIChiIHwgKH5kKSksIGEsIGIsIHgsIHMsIHQpO1xufVxuXG5mdW5jdGlvbiBtZDUxKHMpIHtcbiAgdHh0ID0gJyc7XG4gIHZhciBuID0gcy5sZW5ndGgsXG4gICAgc3RhdGUgPSBbMTczMjU4NDE5MywgLTI3MTczMzg3OSwgLTE3MzI1ODQxOTQsIDI3MTczMzg3OF0sXG4gICAgaTtcbiAgZm9yIChpID0gNjQ7IGkgPD0gcy5sZW5ndGg7IGkgKz0gNjQpIHtcbiAgICBtZDVjeWNsZShzdGF0ZSwgbWQ1YmxrKHMuc3Vic3RyaW5nKGkgLSA2NCwgaSkpKTtcbiAgfVxuICBzID0gcy5zdWJzdHJpbmcoaSAtIDY0KTtcbiAgdmFyIHRhaWwgPSBbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMF07XG4gIGZvciAoaSA9IDA7IGkgPCBzLmxlbmd0aDsgaSsrKVxuICAgIHRhaWxbaSA+PiAyXSB8PSBzLmNoYXJDb2RlQXQoaSkgPDwgKChpICUgNCkgPDwgMyk7XG4gIHRhaWxbaSA+PiAyXSB8PSAweDgwIDw8ICgoaSAlIDQpIDw8IDMpO1xuICBpZiAoaSA+IDU1KSB7XG4gICAgbWQ1Y3ljbGUoc3RhdGUsIHRhaWwpO1xuICAgIGZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSB0YWlsW2ldID0gMDtcbiAgfVxuICB0YWlsWzE0XSA9IG4gKiA4O1xuICBtZDVjeWNsZShzdGF0ZSwgdGFpbCk7XG4gIHJldHVybiBzdGF0ZTtcbn1cblxuLyogdGhlcmUgbmVlZHMgdG8gYmUgc3VwcG9ydCBmb3IgVW5pY29kZSBoZXJlLFxuICogdW5sZXNzIHdlIHByZXRlbmQgdGhhdCB3ZSBjYW4gcmVkZWZpbmUgdGhlIE1ELTVcbiAqIGFsZ29yaXRobSBmb3IgbXVsdGktYnl0ZSBjaGFyYWN0ZXJzIChwZXJoYXBzXG4gKiBieSBhZGRpbmcgZXZlcnkgZm91ciAxNi1iaXQgY2hhcmFjdGVycyBhbmRcbiAqIHNob3J0ZW5pbmcgdGhlIHN1bSB0byAzMiBiaXRzKS4gT3RoZXJ3aXNlXG4gKiBJIHN1Z2dlc3QgcGVyZm9ybWluZyBNRC01IGFzIGlmIGV2ZXJ5IGNoYXJhY3RlclxuICogd2FzIHR3byBieXRlcy0tZS5nLiwgMDA0MCAwMDI1ID0gQCUtLWJ1dCB0aGVuXG4gKiBob3cgd2lsbCBhbiBvcmRpbmFyeSBNRC01IHN1bSBiZSBtYXRjaGVkP1xuICogVGhlcmUgaXMgbm8gd2F5IHRvIHN0YW5kYXJkaXplIHRleHQgdG8gc29tZXRoaW5nXG4gKiBsaWtlIFVURi04IGJlZm9yZSB0cmFuc2Zvcm1hdGlvbjsgc3BlZWQgY29zdCBpc1xuICogdXR0ZXJseSBwcm9oaWJpdGl2ZS4gVGhlIEphdmFTY3JpcHQgc3RhbmRhcmRcbiAqIGl0c2VsZiBuZWVkcyB0byBsb29rIGF0IHRoaXM6IGl0IHNob3VsZCBzdGFydFxuICogcHJvdmlkaW5nIGFjY2VzcyB0byBzdHJpbmdzIGFzIHByZWZvcm1lZCBVVEYtOFxuICogOC1iaXQgdW5zaWduZWQgdmFsdWUgYXJyYXlzLlxuICovXG5mdW5jdGlvbiBtZDVibGsocykgeyAvKiBJIGZpZ3VyZWQgZ2xvYmFsIHdhcyBmYXN0ZXIuICAgKi9cbiAgdmFyIG1kNWJsa3MgPSBbXSxcbiAgICBpOyAvKiBBbmR5IEtpbmcgc2FpZCBkbyBpdCB0aGlzIHdheS4gKi9cbiAgZm9yIChpID0gMDsgaSA8IDY0OyBpICs9IDQpIHtcbiAgICBtZDVibGtzW2kgPj4gMl0gPSBzLmNoYXJDb2RlQXQoaSkgKyAocy5jaGFyQ29kZUF0KGkgKyAxKSA8PCA4KSArIChzLmNoYXJDb2RlQXQoaSArIDIpIDw8IDE2KSArIChzLmNoYXJDb2RlQXQoaSArIDMpIDw8XG4gICAgICAyNCk7XG4gIH1cbiAgcmV0dXJuIG1kNWJsa3M7XG59XG5cbnZhciBoZXhfY2hyID0gJzAxMjM0NTY3ODlhYmNkZWYnLnNwbGl0KCcnKTtcblxuZnVuY3Rpb24gcmhleChuKSB7XG4gIHZhciBzID0gJycsXG4gICAgaiA9IDA7XG4gIGZvciAoOyBqIDwgNDsgaisrKVxuICAgIHMgKz0gaGV4X2NoclsobiA+PiAoaiAqIDggKyA0KSkgJiAweDBGXSArIGhleF9jaHJbKG4gPj4gKGogKiA4KSkgJiAweDBGXTtcbiAgcmV0dXJuIHM7XG59XG5cbmZ1bmN0aW9uIGhleCh4KSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKylcbiAgICB4W2ldID0gcmhleCh4W2ldKTtcbiAgcmV0dXJuIHguam9pbignJyk7XG59XG5cbmZ1bmN0aW9uIG1kNShzKSB7XG4gIHJldHVybiBoZXgobWQ1MShzKSk7XG59XG5cbi8qIHRoaXMgZnVuY3Rpb24gaXMgbXVjaCBmYXN0ZXIsXG5zbyBpZiBwb3NzaWJsZSB3ZSB1c2UgaXQuIFNvbWUgSUVzXG5hcmUgdGhlIG9ubHkgb25lcyBJIGtub3cgb2YgdGhhdFxubmVlZCB0aGUgaWRpb3RpYyBzZWNvbmQgZnVuY3Rpb24sXG5nZW5lcmF0ZWQgYnkgYW4gaWYgY2xhdXNlLiAgKi9cblxuZnVuY3Rpb24gYWRkMzIoYSwgYikge1xuICByZXR1cm4gKGEgKyBiKSAmIDB4RkZGRkZGRkY7XG59XG5cbmlmIChtZDUoJ2hlbGxvJykgIT0gJzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJykge1xuICBmdW5jdGlvbiBhZGQzMih4LCB5KSB7XG4gICAgdmFyIGxzdyA9ICh4ICYgMHhGRkZGKSArICh5ICYgMHhGRkZGKSxcbiAgICAgIG1zdyA9ICh4ID4+IDE2KSArICh5ID4+IDE2KSArIChsc3cgPj4gMTYpO1xuICAgIHJldHVybiAobXN3IDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gTUQ1XG4iLCIvKlxuICogQ3J5cHRvTVggVG9vbHNcbiAqIENvcHlyaWdodCAoQykgMjAwNCAtIDIwMDYgRGVyZWsgQnVpdGVuaHVpc1xuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3JcbiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMlxuICogb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNywgVVNBLlxuICovXG5cbi8qIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSFxuICovXG5cbnZhciBSTURzaXplID0gMTYwO1xudmFyIFggPSBuZXcgQXJyYXkoKTtcblxuZnVuY3Rpb24gUk9MKHgsIG4pIHtcbiAgcmV0dXJuIG5ldyBOdW1iZXIoKHggPDwgbikgfCAoeCA+Pj4gKDMyIC0gbikpKTtcbn1cblxuZnVuY3Rpb24gRih4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgTnVtYmVyKHggXiB5IF4geik7XG59XG5cbmZ1bmN0aW9uIEcoeCwgeSwgeikge1xuICByZXR1cm4gbmV3IE51bWJlcigoeCAmIHkpIHwgKH54ICYgeikpO1xufVxuXG5mdW5jdGlvbiBIKHgsIHksIHopIHtcbiAgcmV0dXJuIG5ldyBOdW1iZXIoKHggfCB+eSkgXiB6KTtcbn1cblxuZnVuY3Rpb24gSSh4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgTnVtYmVyKCh4ICYgeikgfCAoeSAmIH56KSk7XG59XG5cbmZ1bmN0aW9uIEooeCwgeSwgeikge1xuICByZXR1cm4gbmV3IE51bWJlcih4IF4gKHkgfCB+eikpO1xufVxuXG5mdW5jdGlvbiBtaXhPbmVSb3VuZChhLCBiLCBjLCBkLCBlLCB4LCBzLCByb3VuZE51bWJlcikge1xuICBzd2l0Y2ggKHJvdW5kTnVtYmVyKSB7XG4gICAgY2FzZSAwOlxuICAgICAgYSArPSBGKGIsIGMsIGQpICsgeCArIDB4MDAwMDAwMDA7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDE6XG4gICAgICBhICs9IEcoYiwgYywgZCkgKyB4ICsgMHg1YTgyNzk5OTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGEgKz0gSChiLCBjLCBkKSArIHggKyAweDZlZDllYmExO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAzOlxuICAgICAgYSArPSBJKGIsIGMsIGQpICsgeCArIDB4OGYxYmJjZGM7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDQ6XG4gICAgICBhICs9IEooYiwgYywgZCkgKyB4ICsgMHhhOTUzZmQ0ZTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNTpcbiAgICAgIGEgKz0gSihiLCBjLCBkKSArIHggKyAweDUwYTI4YmU2O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA2OlxuICAgICAgYSArPSBJKGIsIGMsIGQpICsgeCArIDB4NWM0ZGQxMjQ7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDc6XG4gICAgICBhICs9IEgoYiwgYywgZCkgKyB4ICsgMHg2ZDcwM2VmMztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgODpcbiAgICAgIGEgKz0gRyhiLCBjLCBkKSArIHggKyAweDdhNmQ3NmU5O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA5OlxuICAgICAgYSArPSBGKGIsIGMsIGQpICsgeCArIDB4MDAwMDAwMDA7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBkb2N1bWVudC53cml0ZShcIkJvZ3VzIHJvdW5kIG51bWJlclwiKTtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgYSA9IFJPTChhLCBzKSArIGU7XG4gIGMgPSBST0woYywgMTApO1xuXG4gIGEgJj0gMHhmZmZmZmZmZjtcbiAgYiAmPSAweGZmZmZmZmZmO1xuICBjICY9IDB4ZmZmZmZmZmY7XG4gIGQgJj0gMHhmZmZmZmZmZjtcbiAgZSAmPSAweGZmZmZmZmZmO1xuXG4gIHZhciByZXRCbG9jayA9IG5ldyBBcnJheSgpO1xuICByZXRCbG9ja1swXSA9IGE7XG4gIHJldEJsb2NrWzFdID0gYjtcbiAgcmV0QmxvY2tbMl0gPSBjO1xuICByZXRCbG9ja1szXSA9IGQ7XG4gIHJldEJsb2NrWzRdID0gZTtcbiAgcmV0QmxvY2tbNV0gPSB4O1xuICByZXRCbG9ja1s2XSA9IHM7XG5cbiAgcmV0dXJuIHJldEJsb2NrO1xufVxuXG5mdW5jdGlvbiBNRGluaXQoTURidWYpIHtcbiAgTURidWZbMF0gPSAweDY3NDUyMzAxO1xuICBNRGJ1ZlsxXSA9IDB4ZWZjZGFiODk7XG4gIE1EYnVmWzJdID0gMHg5OGJhZGNmZTtcbiAgTURidWZbM10gPSAweDEwMzI1NDc2O1xuICBNRGJ1Zls0XSA9IDB4YzNkMmUxZjA7XG59XG5cbnZhciBST0xzID0gW1xuICBbMTEsIDE0LCAxNSwgMTIsIDUsIDgsIDcsIDksIDExLCAxMywgMTQsIDE1LCA2LCA3LCA5LCA4XSxcbiAgWzcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMl0sXG4gIFsxMSwgMTMsIDYsIDcsIDE0LCA5LCAxMywgMTUsIDE0LCA4LCAxMywgNiwgNSwgMTIsIDcsIDVdLFxuICBbMTEsIDEyLCAxNCwgMTUsIDE0LCAxNSwgOSwgOCwgOSwgMTQsIDUsIDYsIDgsIDYsIDUsIDEyXSxcbiAgWzksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNl0sXG4gIFs4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDZdLFxuICBbOSwgMTMsIDE1LCA3LCAxMiwgOCwgOSwgMTEsIDcsIDcsIDEyLCA3LCA2LCAxNSwgMTMsIDExXSxcbiAgWzksIDcsIDE1LCAxMSwgOCwgNiwgNiwgMTQsIDEyLCAxMywgNSwgMTQsIDEzLCAxMywgNywgNV0sXG4gIFsxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDhdLFxuICBbOCwgNSwgMTIsIDksIDEyLCA1LCAxNCwgNiwgOCwgMTMsIDYsIDUsIDE1LCAxMywgMTEsIDExXVxuXTtcblxudmFyIGluZGV4ZXMgPSBbXG4gIFswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1XSxcbiAgWzcsIDQsIDEzLCAxLCAxMCwgNiwgMTUsIDMsIDEyLCAwLCA5LCA1LCAyLCAxNCwgMTEsIDhdLFxuICBbMywgMTAsIDE0LCA0LCA5LCAxNSwgOCwgMSwgMiwgNywgMCwgNiwgMTMsIDExLCA1LCAxMl0sXG4gIFsxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyXSxcbiAgWzQsIDAsIDUsIDksIDcsIDEyLCAyLCAxMCwgMTQsIDEsIDMsIDgsIDExLCA2LCAxNSwgMTNdLFxuICBbNSwgMTQsIDcsIDAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMl0sXG4gIFs2LCAxMSwgMywgNywgMCwgMTMsIDUsIDEwLCAxNCwgMTUsIDgsIDEyLCA0LCA5LCAxLCAyXSxcbiAgWzE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTNdLFxuICBbOCwgNiwgNCwgMSwgMywgMTEsIDE1LCAwLCA1LCAxMiwgMiwgMTMsIDksIDcsIDEwLCAxNF0sXG4gIFsxMiwgMTUsIDEwLCA0LCAxLCA1LCA4LCA3LCA2LCAyLCAxMywgMTQsIDAsIDMsIDksIDExXVxuXTtcblxuZnVuY3Rpb24gY29tcHJlc3MoTURidWYsIFgpIHtcbiAgYmxvY2tBID0gbmV3IEFycmF5KCk7XG4gIGJsb2NrQiA9IG5ldyBBcnJheSgpO1xuXG4gIHZhciByZXRCbG9jaztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDU7IGkrKykge1xuICAgIGJsb2NrQVtpXSA9IG5ldyBOdW1iZXIoTURidWZbaV0pO1xuICAgIGJsb2NrQltpXSA9IG5ldyBOdW1iZXIoTURidWZbaV0pO1xuICB9XG5cbiAgdmFyIHN0ZXAgPSAwO1xuICBmb3IgKHZhciBqID0gMDsgaiA8IDU7IGorKykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgcmV0QmxvY2sgPSBtaXhPbmVSb3VuZChcbiAgICAgICAgYmxvY2tBWyhzdGVwICsgMCkgJSA1XSxcbiAgICAgICAgYmxvY2tBWyhzdGVwICsgMSkgJSA1XSxcbiAgICAgICAgYmxvY2tBWyhzdGVwICsgMikgJSA1XSxcbiAgICAgICAgYmxvY2tBWyhzdGVwICsgMykgJSA1XSxcbiAgICAgICAgYmxvY2tBWyhzdGVwICsgNCkgJSA1XSxcbiAgICAgICAgWFtpbmRleGVzW2pdW2ldXSxcbiAgICAgICAgUk9Mc1tqXVtpXSxcbiAgICAgICAgaik7XG5cbiAgICAgIGJsb2NrQVsoc3RlcCArIDApICUgNV0gPSByZXRCbG9ja1swXTtcbiAgICAgIGJsb2NrQVsoc3RlcCArIDEpICUgNV0gPSByZXRCbG9ja1sxXTtcbiAgICAgIGJsb2NrQVsoc3RlcCArIDIpICUgNV0gPSByZXRCbG9ja1syXTtcbiAgICAgIGJsb2NrQVsoc3RlcCArIDMpICUgNV0gPSByZXRCbG9ja1szXTtcbiAgICAgIGJsb2NrQVsoc3RlcCArIDQpICUgNV0gPSByZXRCbG9ja1s0XTtcblxuICAgICAgc3RlcCArPSA0O1xuICAgIH1cbiAgfVxuXG4gIHN0ZXAgPSAwO1xuICBmb3IgKHZhciBqID0gNTsgaiA8IDEwOyBqKyspIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICAgIHJldEJsb2NrID0gbWl4T25lUm91bmQoXG4gICAgICAgIGJsb2NrQlsoc3RlcCArIDApICUgNV0sXG4gICAgICAgIGJsb2NrQlsoc3RlcCArIDEpICUgNV0sXG4gICAgICAgIGJsb2NrQlsoc3RlcCArIDIpICUgNV0sXG4gICAgICAgIGJsb2NrQlsoc3RlcCArIDMpICUgNV0sXG4gICAgICAgIGJsb2NrQlsoc3RlcCArIDQpICUgNV0sXG4gICAgICAgIFhbaW5kZXhlc1tqXVtpXV0sXG4gICAgICAgIFJPTHNbal1baV0sXG4gICAgICAgIGopO1xuXG4gICAgICBibG9ja0JbKHN0ZXAgKyAwKSAlIDVdID0gcmV0QmxvY2tbMF07XG4gICAgICBibG9ja0JbKHN0ZXAgKyAxKSAlIDVdID0gcmV0QmxvY2tbMV07XG4gICAgICBibG9ja0JbKHN0ZXAgKyAyKSAlIDVdID0gcmV0QmxvY2tbMl07XG4gICAgICBibG9ja0JbKHN0ZXAgKyAzKSAlIDVdID0gcmV0QmxvY2tbM107XG4gICAgICBibG9ja0JbKHN0ZXAgKyA0KSAlIDVdID0gcmV0QmxvY2tbNF07XG5cbiAgICAgIHN0ZXAgKz0gNDtcbiAgICB9XG4gIH1cblxuICBibG9ja0JbM10gKz0gYmxvY2tBWzJdICsgTURidWZbMV07XG4gIE1EYnVmWzFdID0gTURidWZbMl0gKyBibG9ja0FbM10gKyBibG9ja0JbNF07XG4gIE1EYnVmWzJdID0gTURidWZbM10gKyBibG9ja0FbNF0gKyBibG9ja0JbMF07XG4gIE1EYnVmWzNdID0gTURidWZbNF0gKyBibG9ja0FbMF0gKyBibG9ja0JbMV07XG4gIE1EYnVmWzRdID0gTURidWZbMF0gKyBibG9ja0FbMV0gKyBibG9ja0JbMl07XG4gIE1EYnVmWzBdID0gYmxvY2tCWzNdO1xufVxuXG5mdW5jdGlvbiB6ZXJvWChYKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIFhbaV0gPSAwO1xuICB9XG59XG5cbmZ1bmN0aW9uIE1EZmluaXNoKE1EYnVmLCBzdHJwdHIsIGxzd2xlbiwgbXN3bGVuKSB7XG4gIHZhciBYID0gbmV3IEFycmF5KDE2KTtcbiAgemVyb1goWCk7XG5cbiAgdmFyIGogPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IChsc3dsZW4gJiA2Myk7IGkrKykge1xuICAgIFhbaSA+Pj4gMl0gXj0gKHN0cnB0ci5jaGFyQ29kZUF0KGorKykgJiAyNTUpIDw8ICg4ICogKGkgJiAzKSk7XG4gIH1cblxuICBYWyhsc3dsZW4gPj4+IDIpICYgMTVdIF49IDEgPDwgKDggKiAobHN3bGVuICYgMykgKyA3KTtcblxuICBpZiAoKGxzd2xlbiAmIDYzKSA+IDU1KSB7XG4gICAgY29tcHJlc3MoTURidWYsIFgpO1xuICAgIHZhciBYID0gbmV3IEFycmF5KDE2KTtcbiAgICB6ZXJvWChYKTtcbiAgfVxuXG4gIFhbMTRdID0gbHN3bGVuIDw8IDM7XG4gIFhbMTVdID0gKGxzd2xlbiA+Pj4gMjkpIHwgKG1zd2xlbiA8PCAzKTtcblxuICBjb21wcmVzcyhNRGJ1ZiwgWCk7XG59XG5cbmZ1bmN0aW9uIEJZVEVTX1RPX0RXT1JEKGZvdXJDaGFycykge1xuICB2YXIgdG1wID0gKGZvdXJDaGFycy5jaGFyQ29kZUF0KDMpICYgMjU1KSA8PCAyNDtcbiAgdG1wIHw9IChmb3VyQ2hhcnMuY2hhckNvZGVBdCgyKSAmIDI1NSkgPDwgMTY7XG4gIHRtcCB8PSAoZm91ckNoYXJzLmNoYXJDb2RlQXQoMSkgJiAyNTUpIDw8IDg7XG4gIHRtcCB8PSAoZm91ckNoYXJzLmNoYXJDb2RlQXQoMCkgJiAyNTUpO1xuXG4gIHJldHVybiB0bXA7XG59XG5cbmZ1bmN0aW9uIFJNRChtZXNzYWdlKSB7XG4gIHZhciBNRGJ1ZiA9IG5ldyBBcnJheShSTURzaXplIC8gMzIpO1xuICB2YXIgaGFzaGNvZGUgPSBuZXcgQXJyYXkoUk1Ec2l6ZSAvIDgpO1xuICB2YXIgbGVuZ3RoO1xuICB2YXIgbmJ5dGVzO1xuXG4gIE1EaW5pdChNRGJ1Zik7XG4gIGxlbmd0aCA9IG1lc3NhZ2UubGVuZ3RoO1xuXG4gIHZhciBYID0gbmV3IEFycmF5KDE2KTtcbiAgemVyb1goWCk7XG5cbiAgdmFyIGogPSAwO1xuICBmb3IgKHZhciBuYnl0ZXMgPSBsZW5ndGg7IG5ieXRlcyA+IDYzOyBuYnl0ZXMgLT0gNjQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICAgIFhbaV0gPSBCWVRFU19UT19EV09SRChtZXNzYWdlLnN1YnN0cihqLCA0KSk7XG4gICAgICBqICs9IDQ7XG4gICAgfVxuICAgIGNvbXByZXNzKE1EYnVmLCBYKTtcbiAgfVxuXG4gIE1EZmluaXNoKE1EYnVmLCBtZXNzYWdlLnN1YnN0cihqKSwgbGVuZ3RoLCAwKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IFJNRHNpemUgLyA4OyBpICs9IDQpIHtcbiAgICBoYXNoY29kZVtpXSA9IE1EYnVmW2kgPj4+IDJdICYgMjU1O1xuICAgIGhhc2hjb2RlW2kgKyAxXSA9IChNRGJ1ZltpID4+PiAyXSA+Pj4gOCkgJiAyNTU7XG4gICAgaGFzaGNvZGVbaSArIDJdID0gKE1EYnVmW2kgPj4+IDJdID4+PiAxNikgJiAyNTU7XG4gICAgaGFzaGNvZGVbaSArIDNdID0gKE1EYnVmW2kgPj4+IDJdID4+PiAyNCkgJiAyNTU7XG4gIH1cblxuICByZXR1cm4gaGFzaGNvZGU7XG59XG5cblxuZnVuY3Rpb24gUk1Ec3RyaW5nKG1lc3NhZ2UpIHtcbiAgdmFyIGhhc2hjb2RlID0gUk1EKG1lc3NhZ2UpO1xuICB2YXIgcmV0U3RyaW5nID0gXCJcIjtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IFJNRHNpemUgLyA4OyBpKyspIHtcbiAgICByZXRTdHJpbmcgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShoYXNoY29kZVtpXSk7XG4gIH1cblxuICByZXR1cm4gcmV0U3RyaW5nO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJNRHN0cmluZztcbiIsIi8qIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU0hBIGZhbWlseSBvZiBoYXNoZXMsIGFzIGRlZmluZWQgaW4gRklQUyBcbiAqIFBVQiAxODAtMiBhcyB3ZWxsIGFzIHRoZSBjb3JyZXNwb25kaW5nIEhNQUMgaW1wbGVtZW50YXRpb24gYXMgZGVmaW5lZCBpblxuICogRklQUyBQVUIgMTk4YVxuICpcbiAqIFZlcnNpb24gMS4zIENvcHlyaWdodCBCcmlhbiBUdXJlayAyMDA4LTIwMTBcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9qc3NoYS5zb3VyY2Vmb3JnZS5uZXQvIGZvciBtb3JlIGluZm9ybWF0aW9uXG4gKlxuICogU2V2ZXJhbCBmdW5jdGlvbnMgdGFrZW4gZnJvbSBQYXVsIEpvaG5zb25cbiAqL1xuXG4vKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkhcbiAqIFxuICogVGhpcyBjb2RlIGhhcyBiZWVuIHNsaWdodGx5IG1vZGlmaWVkIGRpcmVjdCBzdHJpbmcgb3V0cHV0OlxuICogLSBiaW4yYnN0ciBoYXMgYmVlbiBhZGRlZFxuICogLSBmb2xsb3dpbmcgd3JhcHBlcnMgb2YgdGhpcyBsaWJyYXJ5IGhhdmUgYmVlbiBhZGRlZDpcbiAqICAgLSBzdHJfc2hhMVxuICogICAtIHN0cl9zaGEyNTZcbiAqICAgLSBzdHJfc2hhMjI0XG4gKiAgIC0gc3RyX3NoYTM4NFxuICogICAtIHN0cl9zaGE1MTJcbiAqL1xuXG52YXIganNTSEEgPSAoZnVuY3Rpb24oKSB7XG5cbiAgLypcbiAgICogQ29uZmlndXJhYmxlIHZhcmlhYmxlcy4gRGVmYXVsdHMgdHlwaWNhbGx5IHdvcmtcbiAgICovXG4gIC8qIE51bWJlciBvZiBCaXRzIFBlciBjaGFyYWN0ZXIgKDggZm9yIEFTQ0lJLCAxNiBmb3IgVW5pY29kZSkgKi9cbiAgdmFyIGNoYXJTaXplID0gOCxcbiAgICAvKiBiYXNlLTY0IHBhZCBjaGFyYWN0ZXIuIFwiPVwiIGZvciBzdHJpY3QgUkZDIGNvbXBsaWFuY2UgKi9cbiAgICBiNjRwYWQgPSBcIlwiLFxuICAgIC8qIGhleCBvdXRwdXQgZm9ybWF0LiAwIC0gbG93ZXJjYXNlOyAxIC0gdXBwZXJjYXNlICovXG4gICAgaGV4Q2FzZSA9IDAsXG5cbiAgICAvKlxuICAgICAqIEludF82NCBpcyBhIG9iamVjdCBmb3IgMiAzMi1iaXQgbnVtYmVycyBlbXVsYXRpbmcgYSA2NC1iaXQgbnVtYmVyXG4gICAgICpcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbXNpbnRfMzIgVGhlIG1vc3Qgc2lnbmlmaWNhbnQgMzItYml0cyBvZiBhIDY0LWJpdCBudW1iZXJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbHNpbnRfMzIgVGhlIGxlYXN0IHNpZ25pZmljYW50IDMyLWJpdHMgb2YgYSA2NC1iaXQgbnVtYmVyXG4gICAgICovXG4gICAgSW50XzY0ID0gZnVuY3Rpb24obXNpbnRfMzIsIGxzaW50XzMyKSB7XG4gICAgICB0aGlzLmhpZ2hPcmRlciA9IG1zaW50XzMyO1xuICAgICAgdGhpcy5sb3dPcmRlciA9IGxzaW50XzMyO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIENvbnZlcnQgYSBzdHJpbmcgdG8gYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3Jkc1xuICAgICAqIElmIGNoYXJTaXplIGlzIEFTQ0lJLCBjaGFyYWN0ZXJzID4yNTUgaGF2ZSB0aGVpciBoaS1ieXRlIHNpbGVudGx5XG4gICAgICogaWdub3JlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGJlIGNvbnZlcnRlZCB0byBiaW5hcnkgcmVwcmVzZW50YXRpb25cbiAgICAgKiBAcmV0dXJuIEludGVnZXIgYXJyYXkgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhcmFtZXRlclxuICAgICAqL1xuICAgIHN0cjJiaW5iID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgICB2YXIgYmluID0gW10sXG4gICAgICAgIG1hc2sgPSAoMSA8PCBjaGFyU2l6ZSkgLSAxLFxuICAgICAgICBsZW5ndGggPSBzdHIubGVuZ3RoICogY2hhclNpemUsXG4gICAgICAgIGk7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gY2hhclNpemUpIHtcbiAgICAgICAgYmluW2kgPj4gNV0gfD0gKHN0ci5jaGFyQ29kZUF0KGkgLyBjaGFyU2l6ZSkgJiBtYXNrKSA8PFxuICAgICAgICAgICgzMiAtIGNoYXJTaXplIC0gKGkgJSAzMikpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYmluO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIENvbnZlcnQgYSBoZXggc3RyaW5nIHRvIGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHNcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGJlIGNvbnZlcnRlZCB0byBiaW5hcnkgcmVwcmVzZW50YXRpb25cbiAgICAgKiBAcmV0dXJuIEludGVnZXIgYXJyYXkgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhcmFtZXRlclxuICAgICAqL1xuICAgIGhleDJiaW5iID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgICB2YXIgYmluID0gW10sXG4gICAgICAgIGxlbmd0aCA9IHN0ci5sZW5ndGgsXG4gICAgICAgIGksIG51bTtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgIG51bSA9IHBhcnNlSW50KHN0ci5zdWJzdHIoaSwgMiksIDE2KTtcbiAgICAgICAgaWYgKCFpc05hTihudW0pKSB7XG4gICAgICAgICAgYmluW2kgPj4gM10gfD0gbnVtIDw8ICgyNCAtICg0ICogKGkgJSA4KSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBcIklOVkFMSUQgSEVYIFNUUklOR1wiO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBiaW47XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ29udmVydCBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzIHRvIGEgaGV4IHN0cmluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYmluYXJyYXkgQXJyYXkgb2YgaW50ZWdlcnMgdG8gYmUgY29udmVydGVkIHRvIGhleGlkZWNpbWFsXG4gICAgICpcdCByZXByZXNlbnRhdGlvblxuICAgICAqIEByZXR1cm4gSGV4aWRlY2ltYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhcmFtZXRlciBpbiBTdHJpbmcgZm9ybVxuICAgICAqL1xuICAgIGJpbmIyaGV4ID0gZnVuY3Rpb24oYmluYXJyYXkpIHtcbiAgICAgIHZhciBoZXhfdGFiID0gKGhleENhc2UpID8gXCIwMTIzNDU2Nzg5QUJDREVGXCIgOiBcIjAxMjM0NTY3ODlhYmNkZWZcIixcbiAgICAgICAgc3RyID0gXCJcIixcbiAgICAgICAgbGVuZ3RoID0gYmluYXJyYXkubGVuZ3RoICogNCxcbiAgICAgICAgaSwgc3JjQnl0ZTtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHNyY0J5dGUgPSBiaW5hcnJheVtpID4+IDJdID4+ICgoMyAtIChpICUgNCkpICogOCk7XG4gICAgICAgIHN0ciArPSBoZXhfdGFiLmNoYXJBdCgoc3JjQnl0ZSA+PiA0KSAmIDB4RikgK1xuICAgICAgICAgIGhleF90YWIuY2hhckF0KHNyY0J5dGUgJiAweEYpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc3RyO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIENvbnZlcnQgYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3JkcyB0byBhIGJhc2UtNjQgc3RyaW5nXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGJpbmFycmF5IEFycmF5IG9mIGludGVnZXJzIHRvIGJlIGNvbnZlcnRlZCB0byBiYXNlLTY0XG4gICAgICpcdCByZXByZXNlbnRhdGlvblxuICAgICAqIEByZXR1cm4gQmFzZS02NCBlbmNvZGVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYXJhbWV0ZXIgaW4gU3RyaW5nIGZvcm1cbiAgICAgKi9cbiAgICBiaW5iMmI2NCA9IGZ1bmN0aW9uKGJpbmFycmF5KSB7XG4gICAgICB2YXIgdGFiID0gXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6XCIgK1xuICAgICAgICBcIjAxMjM0NTY3ODkrL1wiLFxuICAgICAgICBzdHIgPSBcIlwiLFxuICAgICAgICBsZW5ndGggPSBiaW5hcnJheS5sZW5ndGggKiA0LFxuICAgICAgICBpLCBqLFxuICAgICAgICB0cmlwbGV0O1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgdHJpcGxldCA9ICgoKGJpbmFycmF5W2kgPj4gMl0gPj4gOCAqICgzIC0gaSAlIDQpKSAmIDB4RkYpIDw8IDE2KSB8XG4gICAgICAgICAgKCgoYmluYXJyYXlbaSArIDEgPj4gMl0gPj4gOCAqICgzIC0gKGkgKyAxKSAlIDQpKSAmIDB4RkYpIDw8IDgpIHxcbiAgICAgICAgICAoKGJpbmFycmF5W2kgKyAyID4+IDJdID4+IDggKiAoMyAtIChpICsgMikgJSA0KSkgJiAweEZGKTtcbiAgICAgICAgZm9yIChqID0gMDsgaiA8IDQ7IGogKz0gMSkge1xuICAgICAgICAgIGlmIChpICogOCArIGogKiA2IDw9IGJpbmFycmF5Lmxlbmd0aCAqIDMyKSB7XG4gICAgICAgICAgICBzdHIgKz0gdGFiLmNoYXJBdCgodHJpcGxldCA+PiA2ICogKDMgLSBqKSkgJiAweDNGKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RyICs9IGI2NHBhZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBzdHI7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ29udmVydCBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzIHRvIGEgc3RyaW5nXG4gICAgICovXG4gICAgYmluYjJzdHIgPSBmdW5jdGlvbihiaW4pIHtcbiAgICAgIHZhciBzdHIgPSBcIlwiO1xuICAgICAgdmFyIG1hc2sgPSAoMSA8PCA4KSAtIDE7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJpbi5sZW5ndGggKiAzMjsgaSArPSA4KVxuICAgICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoYmluW2kgPj4gNV0gPj4+ICgyNCAtIGkgJSAzMikpICYgbWFzayk7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH0sXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIGNpcmN1bGFyIHJvdGF0ZSBsZWZ0XG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdFxuICAgICAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBjaXJjdWxhcmx5IGJ5IG4gYml0c1xuICAgICAqL1xuICAgIHJvdGxfMzIgPSBmdW5jdGlvbih4LCBuKSB7XG4gICAgICByZXR1cm4gKHggPDwgbikgfCAoeCA+Pj4gKDMyIC0gbikpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgY2lyY3VsYXIgcm90YXRlIHJpZ2h0XG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdFxuICAgICAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBjaXJjdWxhcmx5IGJ5IG4gYml0c1xuICAgICAqL1xuICAgIHJvdHJfMzIgPSBmdW5jdGlvbih4LCBuKSB7XG4gICAgICByZXR1cm4gKHggPj4+IG4pIHwgKHggPDwgKDMyIC0gbikpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgY2lyY3VsYXIgcm90YXRlIHJpZ2h0XG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdFxuICAgICAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBjaXJjdWxhcmx5IGJ5IG4gYml0c1xuICAgICAqL1xuICAgIHJvdHJfNjQgPSBmdW5jdGlvbih4LCBuKSB7XG4gICAgICBpZiAobiA8PSAzMikge1xuICAgICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgKHguaGlnaE9yZGVyID4+PiBuKSB8ICh4Lmxvd09yZGVyIDw8ICgzMiAtIG4pKSwgKHgubG93T3JkZXIgPj4+IG4pIHwgKHguaGlnaE9yZGVyIDw8ICgzMiAtIG4pKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgKHgubG93T3JkZXIgPj4+IG4pIHwgKHguaGlnaE9yZGVyIDw8ICgzMiAtIG4pKSwgKHguaGlnaE9yZGVyID4+PiBuKSB8ICh4Lmxvd09yZGVyIDw8ICgzMiAtIG4pKSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBzaGlmdCByaWdodFxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnRcbiAgICAgKiBAcmV0dXJuIFRoZSB4IHNoaWZ0ZWQgYnkgbiBiaXRzXG4gICAgICovXG4gICAgc2hyXzMyID0gZnVuY3Rpb24oeCwgbikge1xuICAgICAgcmV0dXJuIHggPj4+IG47XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBzaGlmdCByaWdodFxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnRcbiAgICAgKiBAcmV0dXJuIFRoZSB4IHNoaWZ0ZWQgYnkgbiBiaXRzXG4gICAgICovXG4gICAgc2hyXzY0ID0gZnVuY3Rpb24oeCwgbikge1xuICAgICAgaWYgKG4gPD0gMzIpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoXG4gICAgICAgICAgeC5oaWdoT3JkZXIgPj4+IG4sXG4gICAgICAgICAgeC5sb3dPcmRlciA+Pj4gbiB8ICh4LmhpZ2hPcmRlciA8PCAoMzIgLSBuKSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoXG4gICAgICAgICAgMCxcbiAgICAgICAgICB4LmhpZ2hPcmRlciA8PCAoMzIgLSBuKSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgUGFyaXR5IGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geiBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgcGFyaXR5XzMyID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICAgICAgcmV0dXJuIHggXiB5IF4gejtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBDaCBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgZmlyc3QgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHogVGhlIHRoaXJkIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIGNoXzMyID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICAgICAgcmV0dXJuICh4ICYgeSkgXiAofnggJiB6KTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBDaCBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geSBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHogVGhlIHRoaXJkIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIGNoXzY0ID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoXG4gICAgICAoeC5oaWdoT3JkZXIgJiB5LmhpZ2hPcmRlcikgXiAofnguaGlnaE9yZGVyICYgei5oaWdoT3JkZXIpLCAoeC5sb3dPcmRlciAmIHkubG93T3JkZXIpIF4gKH54Lmxvd09yZGVyICYgei5sb3dPcmRlcikpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIE1haiBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgZmlyc3QgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHogVGhlIHRoaXJkIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIG1hal8zMiA9IGZ1bmN0aW9uKHgsIHksIHopIHtcbiAgICAgIHJldHVybiAoeCAmIHkpIF4gKHggJiB6KSBeICh5ICYgeik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgTWFqIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSBmaXJzdCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB5IFRoZSBzZWNvbmQgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geiBUaGUgdGhpcmQgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgbWFqXzY0ID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoXG4gICAgICAoeC5oaWdoT3JkZXIgJiB5LmhpZ2hPcmRlcikgXlxuICAgICAgICAoeC5oaWdoT3JkZXIgJiB6LmhpZ2hPcmRlcikgXlxuICAgICAgICAoeS5oaWdoT3JkZXIgJiB6LmhpZ2hPcmRlciksICh4Lmxvd09yZGVyICYgeS5sb3dPcmRlcikgXlxuICAgICAgICAoeC5sb3dPcmRlciAmIHoubG93T3JkZXIpIF5cbiAgICAgICAgKHkubG93T3JkZXIgJiB6Lmxvd09yZGVyKSk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgU2lnbWEwIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBzaWdtYTBfMzIgPSBmdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4gcm90cl8zMih4LCAyKSBeIHJvdHJfMzIoeCwgMTMpIF4gcm90cl8zMih4LCAyMik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgU2lnbWEwIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBzaWdtYTBfNjQgPSBmdW5jdGlvbih4KSB7XG4gICAgICB2YXIgcm90cjI4ID0gcm90cl82NCh4LCAyOCksXG4gICAgICAgIHJvdHIzNCA9IHJvdHJfNjQoeCwgMzQpLFxuICAgICAgICByb3RyMzkgPSByb3RyXzY0KHgsIDM5KTtcblxuICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoXG4gICAgICAgIHJvdHIyOC5oaWdoT3JkZXIgXiByb3RyMzQuaGlnaE9yZGVyIF4gcm90cjM5LmhpZ2hPcmRlcixcbiAgICAgICAgcm90cjI4Lmxvd09yZGVyIF4gcm90cjM0Lmxvd09yZGVyIF4gcm90cjM5Lmxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBTaWdtYTEgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIHNpZ21hMV8zMiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiByb3RyXzMyKHgsIDYpIF4gcm90cl8zMih4LCAxMSkgXiByb3RyXzMyKHgsIDI1KTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBTaWdtYTEgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIHNpZ21hMV82NCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHZhciByb3RyMTQgPSByb3RyXzY0KHgsIDE0KSxcbiAgICAgICAgcm90cjE4ID0gcm90cl82NCh4LCAxOCksXG4gICAgICAgIHJvdHI0MSA9IHJvdHJfNjQoeCwgNDEpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgcm90cjE0LmhpZ2hPcmRlciBeIHJvdHIxOC5oaWdoT3JkZXIgXiByb3RyNDEuaGlnaE9yZGVyLFxuICAgICAgICByb3RyMTQubG93T3JkZXIgXiByb3RyMTgubG93T3JkZXIgXiByb3RyNDEubG93T3JkZXIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIEdhbW1hMCBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgZ2FtbWEwXzMyID0gZnVuY3Rpb24oeCkge1xuICAgICAgcmV0dXJuIHJvdHJfMzIoeCwgNykgXiByb3RyXzMyKHgsIDE4KSBeIHNocl8zMih4LCAzKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTAgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIGdhbW1hMF82NCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHZhciByb3RyMSA9IHJvdHJfNjQoeCwgMSksXG4gICAgICAgIHJvdHI4ID0gcm90cl82NCh4LCA4KSxcbiAgICAgICAgc2hyNyA9IHNocl82NCh4LCA3KTtcblxuICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoXG4gICAgICAgIHJvdHIxLmhpZ2hPcmRlciBeIHJvdHI4LmhpZ2hPcmRlciBeIHNocjcuaGlnaE9yZGVyLFxuICAgICAgICByb3RyMS5sb3dPcmRlciBeIHJvdHI4Lmxvd09yZGVyIF4gc2hyNy5sb3dPcmRlcik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgR2FtbWExIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBnYW1tYTFfMzIgPSBmdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4gcm90cl8zMih4LCAxNykgXiByb3RyXzMyKHgsIDE5KSBeIHNocl8zMih4LCAxMCk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgR2FtbWExIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBnYW1tYTFfNjQgPSBmdW5jdGlvbih4KSB7XG4gICAgICB2YXIgcm90cjE5ID0gcm90cl82NCh4LCAxOSksXG4gICAgICAgIHJvdHI2MSA9IHJvdHJfNjQoeCwgNjEpLFxuICAgICAgICBzaHI2ID0gc2hyXzY0KHgsIDYpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgcm90cjE5LmhpZ2hPcmRlciBeIHJvdHI2MS5oaWdoT3JkZXIgXiBzaHI2LmhpZ2hPcmRlcixcbiAgICAgICAgcm90cjE5Lmxvd09yZGVyIF4gcm90cjYxLmxvd09yZGVyIF4gc2hyNi5sb3dPcmRlcik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQWRkIHR3byAzMi1iaXQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9uc1xuICAgICAqIGludGVybmFsbHkgdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEByZXR1cm4gVGhlIHN1bSBvZiB4ICsgeVxuICAgICAqL1xuICAgIHNhZmVBZGRfMzJfMiA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgIHZhciBsc3cgPSAoeCAmIDB4RkZGRikgKyAoeSAmIDB4RkZGRiksXG4gICAgICAgIG1zdyA9ICh4ID4+PiAxNikgKyAoeSA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuXG4gICAgICByZXR1cm4gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIEFkZCBmb3VyIDMyLWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYSBUaGUgZmlyc3QgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYiBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGMgVGhlIHRoaXJkIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGQgVGhlIGZvdXJ0aCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEByZXR1cm4gVGhlIHN1bSBvZiBhICsgYiArIGMgKyBkXG4gICAgICovXG4gICAgc2FmZUFkZF8zMl80ID0gZnVuY3Rpb24oYSwgYiwgYywgZCkge1xuICAgICAgdmFyIGxzdyA9IChhICYgMHhGRkZGKSArIChiICYgMHhGRkZGKSArIChjICYgMHhGRkZGKSArIChkICYgMHhGRkZGKSxcbiAgICAgICAgbXN3ID0gKGEgPj4+IDE2KSArIChiID4+PiAxNikgKyAoYyA+Pj4gMTYpICsgKGQgPj4+IDE2KSArXG4gICAgICAgICAgKGxzdyA+Pj4gMTYpO1xuXG4gICAgICByZXR1cm4gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIEFkZCBmaXZlIDMyLWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYSBUaGUgZmlyc3QgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYiBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGMgVGhlIHRoaXJkIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGQgVGhlIGZvdXJ0aCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBlIFRoZSBmaWZ0aCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEByZXR1cm4gVGhlIHN1bSBvZiBhICsgYiArIGMgKyBkICsgZVxuICAgICAqL1xuICAgIHNhZmVBZGRfMzJfNSA9IGZ1bmN0aW9uKGEsIGIsIGMsIGQsIGUpIHtcbiAgICAgIHZhciBsc3cgPSAoYSAmIDB4RkZGRikgKyAoYiAmIDB4RkZGRikgKyAoYyAmIDB4RkZGRikgKyAoZCAmIDB4RkZGRikgK1xuICAgICAgICAoZSAmIDB4RkZGRiksXG4gICAgICAgIG1zdyA9IChhID4+PiAxNikgKyAoYiA+Pj4gMTYpICsgKGMgPj4+IDE2KSArIChkID4+PiAxNikgK1xuICAgICAgICAgIChlID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG5cbiAgICAgIHJldHVybiAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQWRkIHR3byA2NC1iaXQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeNjQuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9uc1xuICAgICAqIGludGVybmFsbHkgdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIGZpcnN0IDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHkgVGhlIHNlY29uZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEByZXR1cm4gVGhlIHN1bSBvZiB4ICsgeVxuICAgICAqL1xuICAgIHNhZmVBZGRfNjRfMiA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgIHZhciBsc3csIG1zdywgbG93T3JkZXIsIGhpZ2hPcmRlcjtcblxuICAgICAgbHN3ID0gKHgubG93T3JkZXIgJiAweEZGRkYpICsgKHkubG93T3JkZXIgJiAweEZGRkYpO1xuICAgICAgbXN3ID0gKHgubG93T3JkZXIgPj4+IDE2KSArICh5Lmxvd09yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG4gICAgICBsb3dPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuICAgICAgbHN3ID0gKHguaGlnaE9yZGVyICYgMHhGRkZGKSArICh5LmhpZ2hPcmRlciAmIDB4RkZGRikgKyAobXN3ID4+PiAxNik7XG4gICAgICBtc3cgPSAoeC5oaWdoT3JkZXIgPj4+IDE2KSArICh5LmhpZ2hPcmRlciA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuICAgICAgaGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChoaWdoT3JkZXIsIGxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgZm91ciA2NC1iaXQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeNjQuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9uc1xuICAgICAqIGludGVybmFsbHkgdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGEgVGhlIGZpcnN0IDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGIgVGhlIHNlY29uZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBjIFRoZSB0aGlyZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBkIFRoZSBmb3V0aCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEByZXR1cm4gVGhlIHN1bSBvZiBhICsgYiArIGMgKyBkXG4gICAgICovXG4gICAgc2FmZUFkZF82NF80ID0gZnVuY3Rpb24oYSwgYiwgYywgZCkge1xuICAgICAgdmFyIGxzdywgbXN3LCBsb3dPcmRlciwgaGlnaE9yZGVyO1xuXG4gICAgICBsc3cgPSAoYS5sb3dPcmRlciAmIDB4RkZGRikgKyAoYi5sb3dPcmRlciAmIDB4RkZGRikgK1xuICAgICAgICAoYy5sb3dPcmRlciAmIDB4RkZGRikgKyAoZC5sb3dPcmRlciAmIDB4RkZGRik7XG4gICAgICBtc3cgPSAoYS5sb3dPcmRlciA+Pj4gMTYpICsgKGIubG93T3JkZXIgPj4+IDE2KSArXG4gICAgICAgIChjLmxvd09yZGVyID4+PiAxNikgKyAoZC5sb3dPcmRlciA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuICAgICAgbG93T3JkZXIgPSAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG5cbiAgICAgIGxzdyA9IChhLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAoYi5oaWdoT3JkZXIgJiAweEZGRkYpICtcbiAgICAgICAgKGMuaGlnaE9yZGVyICYgMHhGRkZGKSArIChkLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAobXN3ID4+PiAxNik7XG4gICAgICBtc3cgPSAoYS5oaWdoT3JkZXIgPj4+IDE2KSArIChiLmhpZ2hPcmRlciA+Pj4gMTYpICtcbiAgICAgICAgKGMuaGlnaE9yZGVyID4+PiAxNikgKyAoZC5oaWdoT3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcbiAgICAgIGhpZ2hPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoaGlnaE9yZGVyLCBsb3dPcmRlcik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQWRkIGZpdmUgNjQtYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjY0LiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcbiAgICAgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBhIFRoZSBmaXJzdCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBiIFRoZSBzZWNvbmQgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gYyBUaGUgdGhpcmQgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gZCBUaGUgZm91dGggNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gZSBUaGUgZm91dGggNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcmV0dXJuIFRoZSBzdW0gb2YgYSArIGIgKyBjICsgZCArIGVcbiAgICAgKi9cbiAgICBzYWZlQWRkXzY0XzUgPSBmdW5jdGlvbihhLCBiLCBjLCBkLCBlKSB7XG4gICAgICB2YXIgbHN3LCBtc3csIGxvd09yZGVyLCBoaWdoT3JkZXI7XG5cbiAgICAgIGxzdyA9IChhLmxvd09yZGVyICYgMHhGRkZGKSArIChiLmxvd09yZGVyICYgMHhGRkZGKSArXG4gICAgICAgIChjLmxvd09yZGVyICYgMHhGRkZGKSArIChkLmxvd09yZGVyICYgMHhGRkZGKSArXG4gICAgICAgIChlLmxvd09yZGVyICYgMHhGRkZGKTtcbiAgICAgIG1zdyA9IChhLmxvd09yZGVyID4+PiAxNikgKyAoYi5sb3dPcmRlciA+Pj4gMTYpICtcbiAgICAgICAgKGMubG93T3JkZXIgPj4+IDE2KSArIChkLmxvd09yZGVyID4+PiAxNikgKyAoZS5sb3dPcmRlciA+Pj4gMTYpICtcbiAgICAgICAgKGxzdyA+Pj4gMTYpO1xuICAgICAgbG93T3JkZXIgPSAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG5cbiAgICAgIGxzdyA9IChhLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAoYi5oaWdoT3JkZXIgJiAweEZGRkYpICtcbiAgICAgICAgKGMuaGlnaE9yZGVyICYgMHhGRkZGKSArIChkLmhpZ2hPcmRlciAmIDB4RkZGRikgK1xuICAgICAgICAoZS5oaWdoT3JkZXIgJiAweEZGRkYpICsgKG1zdyA+Pj4gMTYpO1xuICAgICAgbXN3ID0gKGEuaGlnaE9yZGVyID4+PiAxNikgKyAoYi5oaWdoT3JkZXIgPj4+IDE2KSArXG4gICAgICAgIChjLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGQuaGlnaE9yZGVyID4+PiAxNikgK1xuICAgICAgICAoZS5oaWdoT3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcbiAgICAgIGhpZ2hPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoaGlnaE9yZGVyLCBsb3dPcmRlcik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgU0hBLTEgaGFzaCBvZiB0aGUgc3RyaW5nIHNldCBhdCBpbnN0YW50aWF0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IG1lc3NhZ2UgVGhlIGJpbmFyeSBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3RyaW5nIHRvXG4gICAgICpcdCBoYXNoXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG1lc3NhZ2VMZW4gVGhlIG51bWJlciBvZiBiaXRzIGluIHRoZSBtZXNzYWdlXG4gICAgICogQHJldHVybiBUaGUgYXJyYXkgb2YgaW50ZWdlcnMgcmVwcmVzZW50aW5nIHRoZSBTSEEtMSBoYXNoIG9mIG1lc3NhZ2VcbiAgICAgKi9cbiAgICBjb3JlU0hBMSA9IGZ1bmN0aW9uKG1lc3NhZ2UsIG1lc3NhZ2VMZW4pIHtcbiAgICAgIHZhciBXID0gW10sXG4gICAgICAgIGEsIGIsIGMsIGQsIGUsIFQsIGNoID0gY2hfMzIsXG4gICAgICAgIHBhcml0eSA9IHBhcml0eV8zMixcbiAgICAgICAgbWFqID0gbWFqXzMyLFxuICAgICAgICByb3RsID0gcm90bF8zMixcbiAgICAgICAgc2FmZUFkZF8yID0gc2FmZUFkZF8zMl8yLFxuICAgICAgICBpLCB0LFxuICAgICAgICBzYWZlQWRkXzUgPSBzYWZlQWRkXzMyXzUsXG4gICAgICAgIGFwcGVuZGVkTWVzc2FnZUxlbmd0aCxcbiAgICAgICAgSCA9IFtcbiAgICAgICAgICAgIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjBcbiAgICAgICAgXSxcbiAgICAgICAgSyA9IFtcbiAgICAgICAgICAgIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksXG4gICAgICAgICAgICAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LFxuICAgICAgICAgICAgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcbiAgICAgICAgICAgIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksXG4gICAgICAgICAgICAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LFxuICAgICAgICAgICAgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcbiAgICAgICAgICAgIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsXG4gICAgICAgICAgICAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLFxuICAgICAgICAgICAgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcbiAgICAgICAgICAgIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsXG4gICAgICAgICAgICAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLFxuICAgICAgICAgICAgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcbiAgICAgICAgICAgIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsXG4gICAgICAgICAgICAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLFxuICAgICAgICAgICAgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcbiAgICAgICAgICAgIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsXG4gICAgICAgICAgICAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LFxuICAgICAgICAgICAgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcbiAgICAgICAgICAgIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsXG4gICAgICAgICAgICAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2XG4gICAgICAgIF07XG5cbiAgICAgIC8qIEFwcGVuZCAnMScgYXQgdGhlIGVuZCBvZiB0aGUgYmluYXJ5IHN0cmluZyAqL1xuICAgICAgbWVzc2FnZVttZXNzYWdlTGVuID4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gKG1lc3NhZ2VMZW4gJSAzMikpO1xuICAgICAgLyogQXBwZW5kIGxlbmd0aCBvZiBiaW5hcnkgc3RyaW5nIGluIHRoZSBwb3NpdGlvbiBzdWNoIHRoYXQgdGhlIG5ld1xuXHRcdGxlbmd0aCBpcyBhIG11bHRpcGxlIG9mIDUxMi4gIExvZ2ljIGRvZXMgbm90IHdvcmsgZm9yIGV2ZW4gbXVsdGlwbGVzXG5cdFx0b2YgNTEyIGJ1dCB0aGVyZSBjYW4gbmV2ZXIgYmUgZXZlbiBtdWx0aXBsZXMgb2YgNTEyICovXG4gICAgICBtZXNzYWdlWygoKG1lc3NhZ2VMZW4gKyA2NSkgPj4gOSkgPDwgNCkgKyAxNV0gPSBtZXNzYWdlTGVuO1xuXG4gICAgICBhcHBlbmRlZE1lc3NhZ2VMZW5ndGggPSBtZXNzYWdlLmxlbmd0aDtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGFwcGVuZGVkTWVzc2FnZUxlbmd0aDsgaSArPSAxNikge1xuICAgICAgICBhID0gSFswXTtcbiAgICAgICAgYiA9IEhbMV07XG4gICAgICAgIGMgPSBIWzJdO1xuICAgICAgICBkID0gSFszXTtcbiAgICAgICAgZSA9IEhbNF07XG5cbiAgICAgICAgZm9yICh0ID0gMDsgdCA8IDgwOyB0ICs9IDEpIHtcbiAgICAgICAgICBpZiAodCA8IDE2KSB7XG4gICAgICAgICAgICBXW3RdID0gbWVzc2FnZVt0ICsgaV07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIFdbdF0gPSByb3RsKFdbdCAtIDNdIF4gV1t0IC0gOF0gXiBXW3QgLSAxNF0gXiBXW3QgLSAxNl0sIDEpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0IDwgMjApIHtcbiAgICAgICAgICAgIFQgPSBzYWZlQWRkXzUocm90bChhLCA1KSwgY2goYiwgYywgZCksIGUsIEtbdF0sIFdbdF0pO1xuICAgICAgICAgIH0gZWxzZSBpZiAodCA8IDQwKSB7XG4gICAgICAgICAgICBUID0gc2FmZUFkZF81KHJvdGwoYSwgNSksIHBhcml0eShiLCBjLCBkKSwgZSwgS1t0XSwgV1t0XSk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0IDwgNjApIHtcbiAgICAgICAgICAgIFQgPSBzYWZlQWRkXzUocm90bChhLCA1KSwgbWFqKGIsIGMsIGQpLCBlLCBLW3RdLCBXW3RdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgVCA9IHNhZmVBZGRfNShyb3RsKGEsIDUpLCBwYXJpdHkoYiwgYywgZCksIGUsIEtbdF0sIFdbdF0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGUgPSBkO1xuICAgICAgICAgIGQgPSBjO1xuICAgICAgICAgIGMgPSByb3RsKGIsIDMwKTtcbiAgICAgICAgICBiID0gYTtcbiAgICAgICAgICBhID0gVDtcbiAgICAgICAgfVxuXG4gICAgICAgIEhbMF0gPSBzYWZlQWRkXzIoYSwgSFswXSk7XG4gICAgICAgIEhbMV0gPSBzYWZlQWRkXzIoYiwgSFsxXSk7XG4gICAgICAgIEhbMl0gPSBzYWZlQWRkXzIoYywgSFsyXSk7XG4gICAgICAgIEhbM10gPSBzYWZlQWRkXzIoZCwgSFszXSk7XG4gICAgICAgIEhbNF0gPSBzYWZlQWRkXzIoZSwgSFs0XSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBIO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIENhbGN1bGF0ZXMgdGhlIGRlc2lyZWQgU0hBLTIgaGFzaCBvZiB0aGUgc3RyaW5nIHNldCBhdCBpbnN0YW50aWF0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFRoZSBiaW5hcnkgYXJyYXkgcmVwcmVzZW50YXRpb24gb2YgdGhlIHN0cmluZyB0byBoYXNoXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IFRoZSBudW1iZXIgb2YgYml0cyBpbiBtZXNzYWdlXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHZhcmlhbnQgVGhlIGRlc2lyZWQgU0hBLTIgdmFyaWFudFxuICAgICAqIEByZXR1cm4gVGhlIGFycmF5IG9mIGludGVnZXJzIHJlcHJlc2VudGluZyB0aGUgU0hBLTIgaGFzaCBvZiBtZXNzYWdlXG4gICAgICovXG4gICAgY29yZVNIQTIgPSBmdW5jdGlvbihtZXNzYWdlLCBtZXNzYWdlTGVuLCB2YXJpYW50KSB7XG4gICAgICB2YXIgYSwgYiwgYywgZCwgZSwgZiwgZywgaCwgVDEsIFQyLCBILCBudW1Sb3VuZHMsIGxlbmd0aFBvc2l0aW9uLCBpLCB0LFxuICAgICAgICBiaW5hcnlTdHJpbmdJbmMsIGJpbmFyeVN0cmluZ011bHQsIHNhZmVBZGRfMiwgc2FmZUFkZF80LCBzYWZlQWRkXzUsXG4gICAgICAgIGdhbW1hMCwgZ2FtbWExLCBzaWdtYTAsIHNpZ21hMSwgY2gsIG1haiwgSW50LCBLLCBXID0gW10sXG4gICAgICAgIGFwcGVuZGVkTWVzc2FnZUxlbmd0aDtcblxuICAgICAgLyogU2V0IHVwIHRoZSB2YXJpb3VzIGZ1bmN0aW9uIGhhbmRsZXMgYW5kIHZhcmlhYmxlIGZvciB0aGUgc3BlY2lmaWMgXG4gICAgICAgKiB2YXJpYW50ICovXG4gICAgICBpZiAodmFyaWFudCA9PT0gXCJTSEEtMjI0XCIgfHwgdmFyaWFudCA9PT0gXCJTSEEtMjU2XCIpIHtcbiAgICAgICAgLyogMzItYml0IHZhcmlhbnQgKi9cbiAgICAgICAgbnVtUm91bmRzID0gNjQ7XG4gICAgICAgIGxlbmd0aFBvc2l0aW9uID0gKCgobWVzc2FnZUxlbiArIDY1KSA+PiA5KSA8PCA0KSArIDE1O1xuICAgICAgICBiaW5hcnlTdHJpbmdJbmMgPSAxNjtcbiAgICAgICAgYmluYXJ5U3RyaW5nTXVsdCA9IDE7XG4gICAgICAgIEludCA9IE51bWJlcjtcbiAgICAgICAgc2FmZUFkZF8yID0gc2FmZUFkZF8zMl8yO1xuICAgICAgICBzYWZlQWRkXzQgPSBzYWZlQWRkXzMyXzQ7XG4gICAgICAgIHNhZmVBZGRfNSA9IHNhZmVBZGRfMzJfNTtcbiAgICAgICAgZ2FtbWEwID0gZ2FtbWEwXzMyO1xuICAgICAgICBnYW1tYTEgPSBnYW1tYTFfMzI7XG4gICAgICAgIHNpZ21hMCA9IHNpZ21hMF8zMjtcbiAgICAgICAgc2lnbWExID0gc2lnbWExXzMyO1xuICAgICAgICBtYWogPSBtYWpfMzI7XG4gICAgICAgIGNoID0gY2hfMzI7XG4gICAgICAgIEsgPSBbXG4gICAgICAgICAgICAweDQyOEEyRjk4LCAweDcxMzc0NDkxLCAweEI1QzBGQkNGLCAweEU5QjVEQkE1LFxuICAgICAgICAgICAgMHgzOTU2QzI1QiwgMHg1OUYxMTFGMSwgMHg5MjNGODJBNCwgMHhBQjFDNUVENSxcbiAgICAgICAgICAgIDB4RDgwN0FBOTgsIDB4MTI4MzVCMDEsIDB4MjQzMTg1QkUsIDB4NTUwQzdEQzMsXG4gICAgICAgICAgICAweDcyQkU1RDc0LCAweDgwREVCMUZFLCAweDlCREMwNkE3LCAweEMxOUJGMTc0LFxuICAgICAgICAgICAgMHhFNDlCNjlDMSwgMHhFRkJFNDc4NiwgMHgwRkMxOURDNiwgMHgyNDBDQTFDQyxcbiAgICAgICAgICAgIDB4MkRFOTJDNkYsIDB4NEE3NDg0QUEsIDB4NUNCMEE5REMsIDB4NzZGOTg4REEsXG4gICAgICAgICAgICAweDk4M0U1MTUyLCAweEE4MzFDNjZELCAweEIwMDMyN0M4LCAweEJGNTk3RkM3LFxuICAgICAgICAgICAgMHhDNkUwMEJGMywgMHhENUE3OTE0NywgMHgwNkNBNjM1MSwgMHgxNDI5Mjk2NyxcbiAgICAgICAgICAgIDB4MjdCNzBBODUsIDB4MkUxQjIxMzgsIDB4NEQyQzZERkMsIDB4NTMzODBEMTMsXG4gICAgICAgICAgICAweDY1MEE3MzU0LCAweDc2NkEwQUJCLCAweDgxQzJDOTJFLCAweDkyNzIyQzg1LFxuICAgICAgICAgICAgMHhBMkJGRThBMSwgMHhBODFBNjY0QiwgMHhDMjRCOEI3MCwgMHhDNzZDNTFBMyxcbiAgICAgICAgICAgIDB4RDE5MkU4MTksIDB4RDY5OTA2MjQsIDB4RjQwRTM1ODUsIDB4MTA2QUEwNzAsXG4gICAgICAgICAgICAweDE5QTRDMTE2LCAweDFFMzc2QzA4LCAweDI3NDg3NzRDLCAweDM0QjBCQ0I1LFxuICAgICAgICAgICAgMHgzOTFDMENCMywgMHg0RUQ4QUE0QSwgMHg1QjlDQ0E0RiwgMHg2ODJFNkZGMyxcbiAgICAgICAgICAgIDB4NzQ4RjgyRUUsIDB4NzhBNTYzNkYsIDB4ODRDODc4MTQsIDB4OENDNzAyMDgsXG4gICAgICAgICAgICAweDkwQkVGRkZBLCAweEE0NTA2Q0VCLCAweEJFRjlBM0Y3LCAweEM2NzE3OEYyXG4gICAgICAgIF07XG5cbiAgICAgICAgaWYgKHZhcmlhbnQgPT09IFwiU0hBLTIyNFwiKSB7XG4gICAgICAgICAgSCA9IFtcbiAgICAgICAgICAgICAgMHhjMTA1OWVkOCwgMHgzNjdjZDUwNywgMHgzMDcwZGQxNywgMHhmNzBlNTkzOSxcbiAgICAgICAgICAgICAgMHhmZmMwMGIzMSwgMHg2ODU4MTUxMSwgMHg2NGY5OGZhNywgMHhiZWZhNGZhNFxuICAgICAgICAgIF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgSCA9IFtcbiAgICAgICAgICAgICAgMHg2QTA5RTY2NywgMHhCQjY3QUU4NSwgMHgzQzZFRjM3MiwgMHhBNTRGRjUzQSxcbiAgICAgICAgICAgICAgMHg1MTBFNTI3RiwgMHg5QjA1Njg4QywgMHgxRjgzRDlBQiwgMHg1QkUwQ0QxOVxuICAgICAgICAgIF07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodmFyaWFudCA9PT0gXCJTSEEtMzg0XCIgfHwgdmFyaWFudCA9PT0gXCJTSEEtNTEyXCIpIHtcbiAgICAgICAgLyogNjQtYml0IHZhcmlhbnQgKi9cbiAgICAgICAgbnVtUm91bmRzID0gODA7XG4gICAgICAgIGxlbmd0aFBvc2l0aW9uID0gKCgobWVzc2FnZUxlbiArIDEyOCkgPj4gMTApIDw8IDUpICsgMzE7XG4gICAgICAgIGJpbmFyeVN0cmluZ0luYyA9IDMyO1xuICAgICAgICBiaW5hcnlTdHJpbmdNdWx0ID0gMjtcbiAgICAgICAgSW50ID0gSW50XzY0O1xuICAgICAgICBzYWZlQWRkXzIgPSBzYWZlQWRkXzY0XzI7XG4gICAgICAgIHNhZmVBZGRfNCA9IHNhZmVBZGRfNjRfNDtcbiAgICAgICAgc2FmZUFkZF81ID0gc2FmZUFkZF82NF81O1xuICAgICAgICBnYW1tYTAgPSBnYW1tYTBfNjQ7XG4gICAgICAgIGdhbW1hMSA9IGdhbW1hMV82NDtcbiAgICAgICAgc2lnbWEwID0gc2lnbWEwXzY0O1xuICAgICAgICBzaWdtYTEgPSBzaWdtYTFfNjQ7XG4gICAgICAgIG1haiA9IG1hal82NDtcbiAgICAgICAgY2ggPSBjaF82NDtcblxuICAgICAgICBLID0gW1xuICAgICAgICAgICAgbmV3IEludCgweDQyOGEyZjk4LCAweGQ3MjhhZTIyKSwgbmV3IEludCgweDcxMzc0NDkxLCAweDIzZWY2NWNkKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiksIG5ldyBJbnQoMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyksXG4gICAgICAgICAgICBuZXcgSW50KDB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzgpLCBuZXcgSW50KDB4NTlmMTExZjEsIDB4YjYwNWQwMTkpLFxuICAgICAgICAgICAgbmV3IEludCgweDkyM2Y4MmE0LCAweGFmMTk0ZjliKSwgbmV3IEludCgweGFiMWM1ZWQ1LCAweGRhNmQ4MTE4KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhkODA3YWE5OCwgMHhhMzAzMDI0MiksIG5ldyBJbnQoMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSksXG4gICAgICAgICAgICBuZXcgSW50KDB4MjQzMTg1YmUsIDB4NGVlNGIyOGMpLCBuZXcgSW50KDB4NTUwYzdkYzMsIDB4ZDVmZmI0ZTIpLFxuICAgICAgICAgICAgbmV3IEludCgweDcyYmU1ZDc0LCAweGYyN2I4OTZmKSwgbmV3IEludCgweDgwZGViMWZlLCAweDNiMTY5NmIxKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg5YmRjMDZhNywgMHgyNWM3MTIzNSksIG5ldyBJbnQoMHhjMTliZjE3NCwgMHhjZjY5MjY5NCksXG4gICAgICAgICAgICBuZXcgSW50KDB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDIpLCBuZXcgSW50KDB4ZWZiZTQ3ODYsIDB4Mzg0ZjI1ZTMpLFxuICAgICAgICAgICAgbmV3IEludCgweDBmYzE5ZGM2LCAweDhiOGNkNWI1KSwgbmV3IEludCgweDI0MGNhMWNjLCAweDc3YWM5YzY1KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSksIG5ldyBJbnQoMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyksXG4gICAgICAgICAgICBuZXcgSW50KDB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDQpLCBuZXcgSW50KDB4NzZmOTg4ZGEsIDB4ODMxMTUzYjUpLFxuICAgICAgICAgICAgbmV3IEludCgweDk4M2U1MTUyLCAweGVlNjZkZmFiKSwgbmV3IEludCgweGE4MzFjNjZkLCAweDJkYjQzMjEwKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiksIG5ldyBJbnQoMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCksXG4gICAgICAgICAgICBuZXcgSW50KDB4YzZlMDBiZjMsIDB4M2RhODhmYzIpLCBuZXcgSW50KDB4ZDVhNzkxNDcsIDB4OTMwYWE3MjUpLFxuICAgICAgICAgICAgbmV3IEludCgweDA2Y2E2MzUxLCAweGUwMDM4MjZmKSwgbmV3IEludCgweDE0MjkyOTY3LCAweDBhMGU2ZTcwKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgyN2I3MGE4NSwgMHg0NmQyMmZmYyksIG5ldyBJbnQoMHgyZTFiMjEzOCwgMHg1YzI2YzkyNiksXG4gICAgICAgICAgICBuZXcgSW50KDB4NGQyYzZkZmMsIDB4NWFjNDJhZWQpLCBuZXcgSW50KDB4NTMzODBkMTMsIDB4OWQ5NWIzZGYpLFxuICAgICAgICAgICAgbmV3IEludCgweDY1MGE3MzU0LCAweDhiYWY2M2RlKSwgbmV3IEludCgweDc2NmEwYWJiLCAweDNjNzdiMmE4KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiksIG5ldyBJbnQoMHg5MjcyMmM4NSwgMHgxNDgyMzUzYiksXG4gICAgICAgICAgICBuZXcgSW50KDB4YTJiZmU4YTEsIDB4NGNmMTAzNjQpLCBuZXcgSW50KDB4YTgxYTY2NGIsIDB4YmM0MjMwMDEpLFxuICAgICAgICAgICAgbmV3IEludCgweGMyNGI4YjcwLCAweGQwZjg5NzkxKSwgbmV3IEludCgweGM3NmM1MWEzLCAweDA2NTRiZTMwKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCksIG5ldyBJbnQoMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCksXG4gICAgICAgICAgICBuZXcgSW50KDB4ZjQwZTM1ODUsIDB4NTc3MTIwMmEpLCBuZXcgSW50KDB4MTA2YWEwNzAsIDB4MzJiYmQxYjgpLFxuICAgICAgICAgICAgbmV3IEludCgweDE5YTRjMTE2LCAweGI4ZDJkMGM4KSwgbmV3IEludCgweDFlMzc2YzA4LCAweDUxNDFhYjUzKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSksIG5ldyBJbnQoMHgzNGIwYmNiNSwgMHhlMTliNDhhOCksXG4gICAgICAgICAgICBuZXcgSW50KDB4MzkxYzBjYjMsIDB4YzVjOTVhNjMpLCBuZXcgSW50KDB4NGVkOGFhNGEsIDB4ZTM0MThhY2IpLFxuICAgICAgICAgICAgbmV3IEludCgweDViOWNjYTRmLCAweDc3NjNlMzczKSwgbmV3IEludCgweDY4MmU2ZmYzLCAweGQ2YjJiOGEzKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg3NDhmODJlZSwgMHg1ZGVmYjJmYyksIG5ldyBJbnQoMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCksXG4gICAgICAgICAgICBuZXcgSW50KDB4ODRjODc4MTQsIDB4YTFmMGFiNzIpLCBuZXcgSW50KDB4OGNjNzAyMDgsIDB4MWE2NDM5ZWMpLFxuICAgICAgICAgICAgbmV3IEludCgweDkwYmVmZmZhLCAweDIzNjMxZTI4KSwgbmV3IEludCgweGE0NTA2Y2ViLCAweGRlODJiZGU5KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhiZWY5YTNmNywgMHhiMmM2NzkxNSksIG5ldyBJbnQoMHhjNjcxNzhmMiwgMHhlMzcyNTMyYiksXG4gICAgICAgICAgICBuZXcgSW50KDB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWMpLCBuZXcgSW50KDB4ZDE4NmI4YzcsIDB4MjFjMGMyMDcpLFxuICAgICAgICAgICAgbmV3IEludCgweGVhZGE3ZGQ2LCAweGNkZTBlYjFlKSwgbmV3IEludCgweGY1N2Q0ZjdmLCAweGVlNmVkMTc4KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSksIG5ldyBJbnQoMHgwYTYzN2RjNSwgMHhhMmM4OThhNiksXG4gICAgICAgICAgICBuZXcgSW50KDB4MTEzZjk4MDQsIDB4YmVmOTBkYWUpLCBuZXcgSW50KDB4MWI3MTBiMzUsIDB4MTMxYzQ3MWIpLFxuICAgICAgICAgICAgbmV3IEludCgweDI4ZGI3N2Y1LCAweDIzMDQ3ZDg0KSwgbmV3IEludCgweDMyY2FhYjdiLCAweDQwYzcyNDkzKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgzYzllYmUwYSwgMHgxNWM5YmViYyksIG5ldyBJbnQoMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyksXG4gICAgICAgICAgICBuZXcgSW50KDB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjYpLCBuZXcgSW50KDB4NTk3ZjI5OWMsIDB4ZmM2NTdlMmEpLFxuICAgICAgICAgICAgbmV3IEludCgweDVmY2I2ZmFiLCAweDNhZDZmYWVjKSwgbmV3IEludCgweDZjNDQxOThjLCAweDRhNDc1ODE3KVxuICAgICAgICBdO1xuXG4gICAgICAgIGlmICh2YXJpYW50ID09PSBcIlNIQS0zODRcIikge1xuICAgICAgICAgIEggPSBbXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOCksIG5ldyBJbnQoMHgwNjI5YTI5MmEsIDB4MzY3Y2Q1MDcpLFxuICAgICAgICAgICAgICBuZXcgSW50KDB4OTE1OTAxNWEsIDB4MzA3MGRkMTcpLCBuZXcgSW50KDB4MDE1MmZlY2Q4LCAweGY3MGU1OTM5KSxcbiAgICAgICAgICAgICAgbmV3IEludCgweDY3MzMyNjY3LCAweGZmYzAwYjMxKSwgbmV3IEludCgweDk4ZWI0NGE4NywgMHg2ODU4MTUxMSksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHhkYjBjMmUwZCwgMHg2NGY5OGZhNyksIG5ldyBJbnQoMHgwNDdiNTQ4MWQsIDB4YmVmYTRmYTQpXG4gICAgICAgICAgXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBIID0gW1xuICAgICAgICAgICAgICBuZXcgSW50KDB4NmEwOWU2NjcsIDB4ZjNiY2M5MDgpLCBuZXcgSW50KDB4YmI2N2FlODUsIDB4ODRjYWE3M2IpLFxuICAgICAgICAgICAgICBuZXcgSW50KDB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmIpLCBuZXcgSW50KDB4YTU0ZmY1M2EsIDB4NWYxZDM2ZjEpLFxuICAgICAgICAgICAgICBuZXcgSW50KDB4NTEwZTUyN2YsIDB4YWRlNjgyZDEpLCBuZXcgSW50KDB4OWIwNTY4OGMsIDB4MmIzZTZjMWYpLFxuICAgICAgICAgICAgICBuZXcgSW50KDB4MWY4M2Q5YWIsIDB4ZmI0MWJkNmIpLCBuZXcgSW50KDB4NWJlMGNkMTksIDB4MTM3ZTIxNzkpXG4gICAgICAgICAgXTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvKiBBcHBlbmQgJzEnIGF0IHRoZSBlbmQgb2YgdGhlIGJpbmFyeSBzdHJpbmcgKi9cbiAgICAgIG1lc3NhZ2VbbWVzc2FnZUxlbiA+PiA1XSB8PSAweDgwIDw8ICgyNCAtIG1lc3NhZ2VMZW4gJSAzMik7XG4gICAgICAvKiBBcHBlbmQgbGVuZ3RoIG9mIGJpbmFyeSBzdHJpbmcgaW4gdGhlIHBvc2l0aW9uIHN1Y2ggdGhhdCB0aGUgbmV3XG4gICAgICAgKiBsZW5ndGggaXMgY29ycmVjdCAqL1xuICAgICAgbWVzc2FnZVtsZW5ndGhQb3NpdGlvbl0gPSBtZXNzYWdlTGVuO1xuXG4gICAgICBhcHBlbmRlZE1lc3NhZ2VMZW5ndGggPSBtZXNzYWdlLmxlbmd0aDtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGFwcGVuZGVkTWVzc2FnZUxlbmd0aDsgaSArPSBiaW5hcnlTdHJpbmdJbmMpIHtcbiAgICAgICAgYSA9IEhbMF07XG4gICAgICAgIGIgPSBIWzFdO1xuICAgICAgICBjID0gSFsyXTtcbiAgICAgICAgZCA9IEhbM107XG4gICAgICAgIGUgPSBIWzRdO1xuICAgICAgICBmID0gSFs1XTtcbiAgICAgICAgZyA9IEhbNl07XG4gICAgICAgIGggPSBIWzddO1xuXG4gICAgICAgIGZvciAodCA9IDA7IHQgPCBudW1Sb3VuZHM7IHQgKz0gMSkge1xuICAgICAgICAgIGlmICh0IDwgMTYpIHtcbiAgICAgICAgICAgIC8qIEJpdCBvZiBhIGhhY2sgLSBmb3IgMzItYml0LCB0aGUgc2Vjb25kIHRlcm0gaXMgaWdub3JlZCAqL1xuICAgICAgICAgICAgV1t0XSA9IG5ldyBJbnQobWVzc2FnZVt0ICogYmluYXJ5U3RyaW5nTXVsdCArIGldLFxuICAgICAgICAgICAgICBtZXNzYWdlW3QgKiBiaW5hcnlTdHJpbmdNdWx0ICsgaSArIDFdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgV1t0XSA9IHNhZmVBZGRfNChcbiAgICAgICAgICAgICAgZ2FtbWExKFdbdCAtIDJdKSwgV1t0IC0gN10sXG4gICAgICAgICAgICAgIGdhbW1hMChXW3QgLSAxNV0pLCBXW3QgLSAxNl0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIFQxID0gc2FmZUFkZF81KGgsIHNpZ21hMShlKSwgY2goZSwgZiwgZyksIEtbdF0sIFdbdF0pO1xuICAgICAgICAgIFQyID0gc2FmZUFkZF8yKHNpZ21hMChhKSwgbWFqKGEsIGIsIGMpKTtcbiAgICAgICAgICBoID0gZztcbiAgICAgICAgICBnID0gZjtcbiAgICAgICAgICBmID0gZTtcbiAgICAgICAgICBlID0gc2FmZUFkZF8yKGQsIFQxKTtcbiAgICAgICAgICBkID0gYztcbiAgICAgICAgICBjID0gYjtcbiAgICAgICAgICBiID0gYTtcbiAgICAgICAgICBhID0gc2FmZUFkZF8yKFQxLCBUMik7XG4gICAgICAgIH1cblxuICAgICAgICBIWzBdID0gc2FmZUFkZF8yKGEsIEhbMF0pO1xuICAgICAgICBIWzFdID0gc2FmZUFkZF8yKGIsIEhbMV0pO1xuICAgICAgICBIWzJdID0gc2FmZUFkZF8yKGMsIEhbMl0pO1xuICAgICAgICBIWzNdID0gc2FmZUFkZF8yKGQsIEhbM10pO1xuICAgICAgICBIWzRdID0gc2FmZUFkZF8yKGUsIEhbNF0pO1xuICAgICAgICBIWzVdID0gc2FmZUFkZF8yKGYsIEhbNV0pO1xuICAgICAgICBIWzZdID0gc2FmZUFkZF8yKGcsIEhbNl0pO1xuICAgICAgICBIWzddID0gc2FmZUFkZF8yKGgsIEhbN10pO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHZhcmlhbnQpIHtcbiAgICAgICAgY2FzZSBcIlNIQS0yMjRcIjpcbiAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgSFswXSwgSFsxXSwgSFsyXSwgSFszXSxcbiAgICAgICAgICAgIEhbNF0sIEhbNV0sIEhbNl1dO1xuICAgICAgICBjYXNlIFwiU0hBLTI1NlwiOlxuICAgICAgICAgIHJldHVybiBIO1xuICAgICAgICBjYXNlIFwiU0hBLTM4NFwiOlxuICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBIWzBdLmhpZ2hPcmRlciwgSFswXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbMV0uaGlnaE9yZGVyLCBIWzFdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFsyXS5oaWdoT3JkZXIsIEhbMl0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzNdLmhpZ2hPcmRlciwgSFszXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbNF0uaGlnaE9yZGVyLCBIWzRdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs1XS5oaWdoT3JkZXIsIEhbNV0ubG93T3JkZXJdO1xuICAgICAgICBjYXNlIFwiU0hBLTUxMlwiOlxuICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBIWzBdLmhpZ2hPcmRlciwgSFswXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbMV0uaGlnaE9yZGVyLCBIWzFdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFsyXS5oaWdoT3JkZXIsIEhbMl0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzNdLmhpZ2hPcmRlciwgSFszXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbNF0uaGlnaE9yZGVyLCBIWzRdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs1XS5oaWdoT3JkZXIsIEhbNV0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzZdLmhpZ2hPcmRlciwgSFs2XS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbN10uaGlnaE9yZGVyLCBIWzddLmxvd09yZGVyXTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvKiBUaGlzIHNob3VsZCBuZXZlciBiZSByZWFjaGVkICovXG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIGpzU0hBIGlzIHRoZSB3b3JraG9yc2Ugb2YgdGhlIGxpYnJhcnkuICBJbnN0YW50aWF0ZSBpdCB3aXRoIHRoZSBzdHJpbmcgdG9cbiAgICAgKiBiZSBoYXNoZWQgYXMgdGhlIHBhcmFtZXRlclxuICAgICAqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHNyY1N0cmluZyBUaGUgc3RyaW5nIHRvIGJlIGhhc2hlZFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dEZvcm1hdCBUaGUgZm9ybWF0IG9mIHNyY1N0cmluZywgQVNDSUkgb3IgSEVYXG4gICAgICovXG4gICAganNTSEEgPSBmdW5jdGlvbihzcmNTdHJpbmcsIGlucHV0Rm9ybWF0KSB7XG5cbiAgICAgIHRoaXMuc2hhMSA9IG51bGw7XG4gICAgICB0aGlzLnNoYTIyNCA9IG51bGw7XG4gICAgICB0aGlzLnNoYTI1NiA9IG51bGw7XG4gICAgICB0aGlzLnNoYTM4NCA9IG51bGw7XG4gICAgICB0aGlzLnNoYTUxMiA9IG51bGw7XG5cbiAgICAgIHRoaXMuc3RyQmluTGVuID0gbnVsbDtcbiAgICAgIHRoaXMuc3RyVG9IYXNoID0gbnVsbDtcblxuICAgICAgLyogQ29udmVydCB0aGUgaW5wdXQgc3RyaW5nIGludG8gdGhlIGNvcnJlY3QgdHlwZSAqL1xuICAgICAgaWYgKFwiSEVYXCIgPT09IGlucHV0Rm9ybWF0KSB7XG4gICAgICAgIGlmICgwICE9PSAoc3JjU3RyaW5nLmxlbmd0aCAlIDIpKSB7XG4gICAgICAgICAgcmV0dXJuIFwiVEVYVCBNVVNUIEJFIElOIEJZVEUgSU5DUkVNRU5UU1wiO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyQmluTGVuID0gc3JjU3RyaW5nLmxlbmd0aCAqIDQ7XG4gICAgICAgIHRoaXMuc3RyVG9IYXNoID0gaGV4MmJpbmIoc3JjU3RyaW5nKTtcbiAgICAgIH0gZWxzZSBpZiAoKFwiQVNDSUlcIiA9PT0gaW5wdXRGb3JtYXQpIHx8XG4gICAgICAgICgndW5kZWZpbmVkJyA9PT0gdHlwZW9mKGlucHV0Rm9ybWF0KSkpIHtcbiAgICAgICAgdGhpcy5zdHJCaW5MZW4gPSBzcmNTdHJpbmcubGVuZ3RoICogY2hhclNpemU7XG4gICAgICAgIHRoaXMuc3RyVG9IYXNoID0gc3RyMmJpbmIoc3JjU3RyaW5nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBcIlVOS05PV04gVEVYVCBJTlBVVCBUWVBFXCI7XG4gICAgICB9XG4gICAgfTtcblxuICBqc1NIQS5wcm90b3R5cGUgPSB7XG4gICAgLypcbiAgICAgKiBSZXR1cm5zIHRoZSBkZXNpcmVkIFNIQSBoYXNoIG9mIHRoZSBzdHJpbmcgc3BlY2lmaWVkIGF0IGluc3RhbnRpYXRpb25cbiAgICAgKiB1c2luZyB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnNcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB2YXJpYW50IFRoZSBkZXNpcmVkIFNIQSB2YXJpYW50IChTSEEtMSwgU0hBLTIyNCxcbiAgICAgKlx0IFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIpXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGZvcm1hdCBUaGUgZGVzaXJlZCBvdXRwdXQgZm9ybWF0dGluZyAoQjY0IG9yIEhFWClcbiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGhhc2ggaW4gdGhlIGZvcm1hdCBzcGVjaWZpZWRcbiAgICAgKi9cbiAgICBnZXRIYXNoOiBmdW5jdGlvbih2YXJpYW50LCBmb3JtYXQpIHtcbiAgICAgIHZhciBmb3JtYXRGdW5jID0gbnVsbCxcbiAgICAgICAgbWVzc2FnZSA9IHRoaXMuc3RyVG9IYXNoLnNsaWNlKCk7XG5cbiAgICAgIHN3aXRjaCAoZm9ybWF0KSB7XG4gICAgICAgIGNhc2UgXCJIRVhcIjpcbiAgICAgICAgICBmb3JtYXRGdW5jID0gYmluYjJoZXg7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJCNjRcIjpcbiAgICAgICAgICBmb3JtYXRGdW5jID0gYmluYjJiNjQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJBU0NJSVwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMnN0cjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gXCJGT1JNQVQgTk9UIFJFQ09HTklaRURcIjtcbiAgICAgIH1cblxuICAgICAgc3dpdGNoICh2YXJpYW50KSB7XG4gICAgICAgIGNhc2UgXCJTSEEtMVwiOlxuICAgICAgICAgIGlmIChudWxsID09PSB0aGlzLnNoYTEpIHtcbiAgICAgICAgICAgIHRoaXMuc2hhMSA9IGNvcmVTSEExKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGZvcm1hdEZ1bmModGhpcy5zaGExKTtcbiAgICAgICAgY2FzZSBcIlNIQS0yMjRcIjpcbiAgICAgICAgICBpZiAobnVsbCA9PT0gdGhpcy5zaGEyMjQpIHtcbiAgICAgICAgICAgIHRoaXMuc2hhMjI0ID0gY29yZVNIQTIobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4sIHZhcmlhbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTIyNCk7XG4gICAgICAgIGNhc2UgXCJTSEEtMjU2XCI6XG4gICAgICAgICAgaWYgKG51bGwgPT09IHRoaXMuc2hhMjU2KSB7XG4gICAgICAgICAgICB0aGlzLnNoYTI1NiA9IGNvcmVTSEEyKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGZvcm1hdEZ1bmModGhpcy5zaGEyNTYpO1xuICAgICAgICBjYXNlIFwiU0hBLTM4NFwiOlxuICAgICAgICAgIGlmIChudWxsID09PSB0aGlzLnNoYTM4NCkge1xuICAgICAgICAgICAgdGhpcy5zaGEzODQgPSBjb3JlU0hBMihtZXNzYWdlLCB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmb3JtYXRGdW5jKHRoaXMuc2hhMzg0KTtcbiAgICAgICAgY2FzZSBcIlNIQS01MTJcIjpcbiAgICAgICAgICBpZiAobnVsbCA9PT0gdGhpcy5zaGE1MTIpIHtcbiAgICAgICAgICAgIHRoaXMuc2hhNTEyID0gY29yZVNIQTIobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4sIHZhcmlhbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTUxMik7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIFwiSEFTSCBOT1QgUkVDT0dOSVpFRFwiO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFJldHVybnMgdGhlIGRlc2lyZWQgSE1BQyBvZiB0aGUgc3RyaW5nIHNwZWNpZmllZCBhdCBpbnN0YW50aWF0aW9uXG4gICAgICogdXNpbmcgdGhlIGtleSBhbmQgdmFyaWFudCBwYXJhbS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgVGhlIGtleSB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgSE1BQ1xuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dEZvcm1hdCBUaGUgZm9ybWF0IG9mIGtleSwgQVNDSUkgb3IgSEVYXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHZhcmlhbnQgVGhlIGRlc2lyZWQgU0hBIHZhcmlhbnQgKFNIQS0xLCBTSEEtMjI0LFxuICAgICAqXHQgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMilcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gb3V0cHV0Rm9ybWF0IFRoZSBkZXNpcmVkIG91dHB1dCBmb3JtYXR0aW5nXG4gICAgICpcdCAoQjY0IG9yIEhFWClcbiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGhhc2ggaW4gdGhlIGZvcm1hdCBzcGVjaWZpZWRcbiAgICAgKi9cbiAgICBnZXRITUFDOiBmdW5jdGlvbihrZXksIGlucHV0Rm9ybWF0LCB2YXJpYW50LCBvdXRwdXRGb3JtYXQpIHtcbiAgICAgIHZhciBmb3JtYXRGdW5jLCBrZXlUb1VzZSwgYmxvY2tCeXRlU2l6ZSwgYmxvY2tCaXRTaXplLCBpLFxuICAgICAgICByZXRWYWwsIGxhc3RBcnJheUluZGV4LCBrZXlCaW5MZW4sIGhhc2hCaXRTaXplLFxuICAgICAgICBrZXlXaXRoSVBhZCA9IFtdLFxuICAgICAgICBrZXlXaXRoT1BhZCA9IFtdO1xuXG4gICAgICAvKiBWYWxpZGF0ZSB0aGUgb3V0cHV0IGZvcm1hdCBzZWxlY3Rpb24gKi9cbiAgICAgIHN3aXRjaCAob3V0cHV0Rm9ybWF0KSB7XG4gICAgICAgIGNhc2UgXCJIRVhcIjpcbiAgICAgICAgICBmb3JtYXRGdW5jID0gYmluYjJoZXg7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJCNjRcIjpcbiAgICAgICAgICBmb3JtYXRGdW5jID0gYmluYjJiNjQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJBU0NJSVwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMnN0cjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gXCJGT1JNQVQgTk9UIFJFQ09HTklaRURcIjtcbiAgICAgIH1cblxuICAgICAgLyogVmFsaWRhdGUgdGhlIGhhc2ggdmFyaWFudCBzZWxlY3Rpb24gYW5kIHNldCBuZWVkZWQgdmFyaWFibGVzICovXG4gICAgICBzd2l0Y2ggKHZhcmlhbnQpIHtcbiAgICAgICAgY2FzZSBcIlNIQS0xXCI6XG4gICAgICAgICAgYmxvY2tCeXRlU2l6ZSA9IDY0O1xuICAgICAgICAgIGhhc2hCaXRTaXplID0gMTYwO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiU0hBLTIyNFwiOlxuICAgICAgICAgIGJsb2NrQnl0ZVNpemUgPSA2NDtcbiAgICAgICAgICBoYXNoQml0U2l6ZSA9IDIyNDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIlNIQS0yNTZcIjpcbiAgICAgICAgICBibG9ja0J5dGVTaXplID0gNjQ7XG4gICAgICAgICAgaGFzaEJpdFNpemUgPSAyNTY7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJTSEEtMzg0XCI6XG4gICAgICAgICAgYmxvY2tCeXRlU2l6ZSA9IDEyODtcbiAgICAgICAgICBoYXNoQml0U2l6ZSA9IDM4NDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIlNIQS01MTJcIjpcbiAgICAgICAgICBibG9ja0J5dGVTaXplID0gMTI4O1xuICAgICAgICAgIGhhc2hCaXRTaXplID0gNTEyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBcIkhBU0ggTk9UIFJFQ09HTklaRURcIjtcbiAgICAgIH1cblxuICAgICAgLyogVmFsaWRhdGUgaW5wdXQgZm9ybWF0IHNlbGVjdGlvbiAqL1xuICAgICAgaWYgKFwiSEVYXCIgPT09IGlucHV0Rm9ybWF0KSB7XG4gICAgICAgIC8qIE5pYmJsZXMgbXVzdCBjb21lIGluIHBhaXJzICovXG4gICAgICAgIGlmICgwICE9PSAoa2V5Lmxlbmd0aCAlIDIpKSB7XG4gICAgICAgICAgcmV0dXJuIFwiS0VZIE1VU1QgQkUgSU4gQllURSBJTkNSRU1FTlRTXCI7XG4gICAgICAgIH1cbiAgICAgICAga2V5VG9Vc2UgPSBoZXgyYmluYihrZXkpO1xuICAgICAgICBrZXlCaW5MZW4gPSBrZXkubGVuZ3RoICogNDtcbiAgICAgIH0gZWxzZSBpZiAoXCJBU0NJSVwiID09PSBpbnB1dEZvcm1hdCkge1xuICAgICAgICBrZXlUb1VzZSA9IHN0cjJiaW5iKGtleSk7XG4gICAgICAgIGtleUJpbkxlbiA9IGtleS5sZW5ndGggKiBjaGFyU2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBcIlVOS05PV04gS0VZIElOUFVUIFRZUEVcIjtcbiAgICAgIH1cblxuICAgICAgLyogVGhlc2UgYXJlIHVzZWQgbXVsdGlwbGUgdGltZXMsIGNhbGN1bGF0ZSBhbmQgc3RvcmUgdGhlbSAqL1xuICAgICAgYmxvY2tCaXRTaXplID0gYmxvY2tCeXRlU2l6ZSAqIDg7XG4gICAgICBsYXN0QXJyYXlJbmRleCA9IChibG9ja0J5dGVTaXplIC8gNCkgLSAxO1xuXG4gICAgICAvKiBGaWd1cmUgb3V0IHdoYXQgdG8gZG8gd2l0aCB0aGUga2V5IGJhc2VkIG9uIGl0cyBzaXplIHJlbGF0aXZlIHRvXG4gICAgICAgKiB0aGUgaGFzaCdzIGJsb2NrIHNpemUgKi9cbiAgICAgIGlmIChibG9ja0J5dGVTaXplIDwgKGtleUJpbkxlbiAvIDgpKSB7XG4gICAgICAgIGlmIChcIlNIQS0xXCIgPT09IHZhcmlhbnQpIHtcbiAgICAgICAgICBrZXlUb1VzZSA9IGNvcmVTSEExKGtleVRvVXNlLCBrZXlCaW5MZW4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGtleVRvVXNlID0gY29yZVNIQTIoa2V5VG9Vc2UsIGtleUJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgIH1cbiAgICAgICAgLyogRm9yIGFsbCB2YXJpYW50cywgdGhlIGJsb2NrIHNpemUgaXMgYmlnZ2VyIHRoYW4gdGhlIG91dHB1dFxuICAgICAgICAgKiBzaXplIHNvIHRoZXJlIHdpbGwgbmV2ZXIgYmUgYSB1c2VmdWwgYnl0ZSBhdCB0aGUgZW5kIG9mIHRoZVxuICAgICAgICAgKiBzdHJpbmcgKi9cbiAgICAgICAga2V5VG9Vc2VbbGFzdEFycmF5SW5kZXhdICY9IDB4RkZGRkZGMDA7XG4gICAgICB9IGVsc2UgaWYgKGJsb2NrQnl0ZVNpemUgPiAoa2V5QmluTGVuIC8gOCkpIHtcbiAgICAgICAgLyogSWYgdGhlIGJsb2NrQnl0ZVNpemUgaXMgZ3JlYXRlciB0aGFuIHRoZSBrZXkgbGVuZ3RoLCB0aGVyZVxuICAgICAgICAgKiB3aWxsIGFsd2F5cyBiZSBhdCBMRUFTVCBvbmUgXCJ1c2VsZXNzXCIgYnl0ZSBhdCB0aGUgZW5kIG9mIHRoZVxuICAgICAgICAgKiBzdHJpbmcgKi9cbiAgICAgICAga2V5VG9Vc2VbbGFzdEFycmF5SW5kZXhdICY9IDB4RkZGRkZGMDA7XG4gICAgICB9XG5cbiAgICAgIC8qIENyZWF0ZSBpcGFkIGFuZCBvcGFkICovXG4gICAgICBmb3IgKGkgPSAwOyBpIDw9IGxhc3RBcnJheUluZGV4OyBpICs9IDEpIHtcbiAgICAgICAga2V5V2l0aElQYWRbaV0gPSBrZXlUb1VzZVtpXSBeIDB4MzYzNjM2MzY7XG4gICAgICAgIGtleVdpdGhPUGFkW2ldID0ga2V5VG9Vc2VbaV0gXiAweDVDNUM1QzVDO1xuICAgICAgfVxuXG4gICAgICAvKiBDYWxjdWxhdGUgdGhlIEhNQUMgKi9cbiAgICAgIGlmIChcIlNIQS0xXCIgPT09IHZhcmlhbnQpIHtcbiAgICAgICAgcmV0VmFsID0gY29yZVNIQTEoXG4gICAgICAgICAga2V5V2l0aElQYWQuY29uY2F0KHRoaXMuc3RyVG9IYXNoKSxcbiAgICAgICAgICBibG9ja0JpdFNpemUgKyB0aGlzLnN0ckJpbkxlbik7XG4gICAgICAgIHJldFZhbCA9IGNvcmVTSEExKFxuICAgICAgICAgIGtleVdpdGhPUGFkLmNvbmNhdChyZXRWYWwpLFxuICAgICAgICAgIGJsb2NrQml0U2l6ZSArIGhhc2hCaXRTaXplKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldFZhbCA9IGNvcmVTSEEyKFxuICAgICAgICAgIGtleVdpdGhJUGFkLmNvbmNhdCh0aGlzLnN0clRvSGFzaCksXG4gICAgICAgICAgYmxvY2tCaXRTaXplICsgdGhpcy5zdHJCaW5MZW4sIHZhcmlhbnQpO1xuICAgICAgICByZXRWYWwgPSBjb3JlU0hBMihcbiAgICAgICAgICBrZXlXaXRoT1BhZC5jb25jYXQocmV0VmFsKSxcbiAgICAgICAgICBibG9ja0JpdFNpemUgKyBoYXNoQml0U2l6ZSwgdmFyaWFudCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiAoZm9ybWF0RnVuYyhyZXRWYWwpKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIGpzU0hBO1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNoYTE6IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCBcIkFTQ0lJXCIpO1xuICAgIHJldHVybiBzaGFPYmouZ2V0SGFzaChcIlNIQS0xXCIsIFwiQVNDSUlcIik7XG4gIH0sXG4gIHNoYTIyNDogZnVuY3Rpb24oc3RyKSB7XG4gICAgdmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsIFwiQVNDSUlcIik7XG4gICAgcmV0dXJuIHNoYU9iai5nZXRIYXNoKFwiU0hBLTIyNFwiLCBcIkFTQ0lJXCIpO1xuICB9LFxuICBzaGEyNTY6IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCBcIkFTQ0lJXCIpO1xuICAgIHJldHVybiBzaGFPYmouZ2V0SGFzaChcIlNIQS0yNTZcIiwgXCJBU0NJSVwiKTtcbiAgfSxcbiAgc2hhMzg0OiBmdW5jdGlvbihzdHIpIHtcbiAgICB2YXIgc2hhT2JqID0gbmV3IGpzU0hBKHN0ciwgXCJBU0NJSVwiKTtcbiAgICByZXR1cm4gc2hhT2JqLmdldEhhc2goXCJTSEEtMzg0XCIsIFwiQVNDSUlcIik7XG5cbiAgfSxcbiAgc2hhNTEyOiBmdW5jdGlvbihzdHIpIHtcbiAgICB2YXIgc2hhT2JqID0gbmV3IGpzU0hBKHN0ciwgXCJBU0NJSVwiKTtcbiAgICByZXR1cm4gc2hhT2JqLmdldEhhc2goXCJTSEEtNTEyXCIsIFwiQVNDSUlcIik7XG4gIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBjaXBoZXI6IHJlcXVpcmUoJy4vY2lwaGVyJyksXG4gIGhhc2g6IHJlcXVpcmUoJy4vaGFzaCcpLFxuICBjZmI6IHJlcXVpcmUoJy4vY2ZiLmpzJyksXG4gIHB1YmxpY0tleTogcmVxdWlyZSgnLi9wdWJsaWNfa2V5JyksXG4gIHNpZ25hdHVyZTogcmVxdWlyZSgnLi9zaWduYXR1cmUuanMnKSxcbiAgcmFuZG9tOiByZXF1aXJlKCcuL3JhbmRvbS5qcycpLFxuICBwa2NzMTogcmVxdWlyZSgnLi9wa2NzMS5qcycpXG5cbn1cblxudmFyIGNyeXB0byA9IHJlcXVpcmUoJy4vY3J5cHRvLmpzJyk7XG5cbmZvciAodmFyIGkgaW4gY3J5cHRvKVxuICBtb2R1bGUuZXhwb3J0c1tpXSA9IGNyeXB0b1tpXTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogQVNOMSBvYmplY3QgaWRlbnRpZmllcnMgZm9yIGhhc2hlcyAoU2VlIFJGQzQ4ODAgNS4yLjIpXG4gKi9cbmhhc2hfaGVhZGVycyA9IG5ldyBBcnJheSgpO1xuaGFzaF9oZWFkZXJzWzFdID0gWzB4MzAsIDB4MjAsIDB4MzAsIDB4MGMsIDB4MDYsIDB4MDgsIDB4MmEsIDB4ODYsIDB4NDgsIDB4ODYsIDB4ZjcsIDB4MGQsIDB4MDIsIDB4MDUsIDB4MDUsIDB4MDAsIDB4MDQsXG4gICAgMHgxMFxuXTtcbmhhc2hfaGVhZGVyc1szXSA9IFsweDMwLCAweDIxLCAweDMwLCAweDA5LCAweDA2LCAweDA1LCAweDJCLCAweDI0LCAweDAzLCAweDAyLCAweDAxLCAweDA1LCAweDAwLCAweDA0LCAweDE0XTtcbmhhc2hfaGVhZGVyc1syXSA9IFsweDMwLCAweDIxLCAweDMwLCAweDA5LCAweDA2LCAweDA1LCAweDJiLCAweDBlLCAweDAzLCAweDAyLCAweDFhLCAweDA1LCAweDAwLCAweDA0LCAweDE0XTtcbmhhc2hfaGVhZGVyc1s4XSA9IFsweDMwLCAweDMxLCAweDMwLCAweDBkLCAweDA2LCAweDA5LCAweDYwLCAweDg2LCAweDQ4LCAweDAxLCAweDY1LCAweDAzLCAweDA0LCAweDAyLCAweDAxLCAweDA1LCAweDAwLFxuICAgIDB4MDQsIDB4MjBcbl07XG5oYXNoX2hlYWRlcnNbOV0gPSBbMHgzMCwgMHg0MSwgMHgzMCwgMHgwZCwgMHgwNiwgMHgwOSwgMHg2MCwgMHg4NiwgMHg0OCwgMHgwMSwgMHg2NSwgMHgwMywgMHgwNCwgMHgwMiwgMHgwMiwgMHgwNSwgMHgwMCxcbiAgICAweDA0LCAweDMwXG5dO1xuaGFzaF9oZWFkZXJzWzEwXSA9IFsweDMwLCAweDUxLCAweDMwLCAweDBkLCAweDA2LCAweDA5LCAweDYwLCAweDg2LCAweDQ4LCAweDAxLCAweDY1LCAweDAzLCAweDA0LCAweDAyLCAweDAzLCAweDA1LFxuICAgIDB4MDAsIDB4MDQsIDB4NDBcbl07XG5oYXNoX2hlYWRlcnNbMTFdID0gWzB4MzAsIDB4MzEsIDB4MzAsIDB4MGQsIDB4MDYsIDB4MDksIDB4NjAsIDB4ODYsIDB4NDgsIDB4MDEsIDB4NjUsIDB4MDMsIDB4MDQsIDB4MDIsIDB4MDQsIDB4MDUsXG4gICAgMHgwMCwgMHgwNCwgMHgxQ1xuXTtcblxuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnLi9jcnlwdG8uanMnKSxcbiAgcmFuZG9tID0gcmVxdWlyZSgnLi9yYW5kb20uanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vcHVibGljX2tleS9qc2JuLmpzJyksXG4gIGhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGVtZToge1xuICAgIC8qKlxuICAgICAqIGNyZWF0ZSBhIEVNRS1QS0NTMS12MV81IHBhZGRpbmcgKFNlZSBSRkM0ODgwIDEzLjEuMSlcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBtZXNzYWdlIHRvIGJlIHBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIExlbmd0aCB0byB0aGUgcmVzdWx0aW5nIG1lc3NhZ2VcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IEVNRS1QS0NTMSBwYWRkZWQgbWVzc2FnZVxuICAgICAqL1xuICAgIGVuY29kZTogZnVuY3Rpb24obWVzc2FnZSwgbGVuZ3RoKSB7XG4gICAgICBpZiAobWVzc2FnZS5sZW5ndGggPiBsZW5ndGggLSAxMSlcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDIpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGggLSBtZXNzYWdlLmxlbmd0aCAtIDM7IGkrKykge1xuICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShyYW5kb20uZ2V0UHNldWRvUmFuZG9tKDEsIDI1NSkpO1xuICAgICAgfVxuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG4gICAgICByZXN1bHQgKz0gbWVzc2FnZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGRlY29kZXMgYSBFTUUtUEtDUzEtdjFfNSBwYWRkaW5nIChTZWUgUkZDNDg4MCAxMy4xLjIpXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgRU1FLVBLQ1MxIHBhZGRlZCBtZXNzYWdlXG4gICAgICogQHJldHVybiB7U3RyaW5nfSBkZWNvZGVkIG1lc3NhZ2UgXG4gICAgICovXG4gICAgZGVjb2RlOiBmdW5jdGlvbihtZXNzYWdlLCBsZW4pIHtcbiAgICAgIGlmIChtZXNzYWdlLmxlbmd0aCA8IGxlbilcbiAgICAgICAgbWVzc2FnZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCkgKyBtZXNzYWdlO1xuICAgICAgaWYgKG1lc3NhZ2UubGVuZ3RoIDwgMTIgfHwgbWVzc2FnZS5jaGFyQ29kZUF0KDApICE9IDAgfHwgbWVzc2FnZS5jaGFyQ29kZUF0KDEpICE9IDIpXG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIHZhciBpID0gMjtcbiAgICAgIHdoaWxlIChtZXNzYWdlLmNoYXJDb2RlQXQoaSkgIT0gMCAmJiBtZXNzYWdlLmxlbmd0aCA+IGkpXG4gICAgICAgIGkrKztcbiAgICAgIHJldHVybiBtZXNzYWdlLnN1YnN0cmluZyhpICsgMSwgbWVzc2FnZS5sZW5ndGgpO1xuICAgIH0sXG4gIH0sXG5cbiAgZW1zYToge1xuXG4gICAgLyoqXG4gICAgICogY3JlYXRlIGEgRU1TQS1QS0NTMS12MV81IHBhZGRpbmcgKFNlZSBSRkM0ODgwIDEzLjEuMylcbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gSGFzaCBhbGdvcml0aG0gdHlwZSB1c2VkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBiZSBoYXNoZWRcbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGtleWxlbmd0aCBLZXkgc2l6ZSBvZiB0aGUgcHVibGljIG1waSBpbiBieXRlc1xuICAgICAqIEByZXR1cm5zIHtTdHJpbmd9IEhhc2hjb2RlIHdpdGggcGtjczFwYWRkaW5nIGFzIHN0cmluZ1xuICAgICAqL1xuICAgIGVuY29kZTogZnVuY3Rpb24oYWxnbywgZGF0YSwga2V5bGVuZ3RoKSB7XG4gICAgICB2YXIgZGF0YTIgPSBcIlwiO1xuICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKTtcbiAgICAgIGRhdGEyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IChrZXlsZW5ndGggLSBoYXNoX2hlYWRlcnNbYWxnb10ubGVuZ3RoIC0gMyAtXG4gICAgICAgIGhhc2guZ2V0SGFzaEJ5dGVMZW5ndGgoYWxnbykpOyBpKyspXG5cbiAgICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweGZmKTtcblxuICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXNoX2hlYWRlcnNbYWxnb10ubGVuZ3RoOyBpKyspXG4gICAgICAgIGRhdGEyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoaGFzaF9oZWFkZXJzW2FsZ29dW2ldKTtcblxuICAgICAgZGF0YTIgKz0gaGFzaC5kaWdlc3QoYWxnbywgZGF0YSk7XG4gICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIodXRpbC5oZXhzdHJkdW1wKGRhdGEyKSwgMTYpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBleHRyYWN0IHRoZSBoYXNoIG91dCBvZiBhbiBFTVNBLVBLQ1MxLXYxLjUgcGFkZGluZyAoU2VlIFJGQzQ4ODAgMTMuMS4zKSBcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBIYXNoIGluIHBrY3MxIGVuY29kaW5nXG4gICAgICogQHJldHVybnMge1N0cmluZ30gVGhlIGhhc2ggYXMgc3RyaW5nXG4gICAgICovXG4gICAgZGVjb2RlOiBmdW5jdGlvbihhbGdvLCBkYXRhKSB7XG4gICAgICB2YXIgaSA9IDA7XG4gICAgICBpZiAoZGF0YS5jaGFyQ29kZUF0KDApID09IDApIGkrKztcbiAgICAgIGVsc2UgaWYgKGRhdGEuY2hhckNvZGVBdCgwKSAhPSAxKSByZXR1cm4gLTE7XG4gICAgICBlbHNlIGkrKztcblxuICAgICAgd2hpbGUgKGRhdGEuY2hhckNvZGVBdChpKSA9PSAweEZGKSBpKys7XG4gICAgICBpZiAoZGF0YS5jaGFyQ29kZUF0KGkrKykgIT0gMCkgcmV0dXJuIC0xO1xuICAgICAgdmFyIGogPSAwO1xuICAgICAgZm9yIChqID0gMDsgaiA8IGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGggJiYgaiArIGkgPCBkYXRhLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChkYXRhLmNoYXJDb2RlQXQoaiArIGkpICE9IGhhc2hfaGVhZGVyc1thbGdvXVtqXSkgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgaSArPSBqO1xuICAgICAgaWYgKGRhdGEuc3Vic3RyaW5nKGkpLmxlbmd0aCA8IGhhc2guZ2V0SGFzaEJ5dGVMZW5ndGgoYWxnbykpIHJldHVybiAtMTtcbiAgICAgIHJldHVybiBkYXRhLnN1YnN0cmluZyhpKTtcbiAgICB9XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG4vL1xuLy8gQSBEaWdpdGFsIHNpZ25hdHVyZSBhbGdvcml0aG0gaW1wbGVtZW50YXRpb25cblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuL2pzYm4uanMnKSxcbiAgcmFuZG9tID0gcmVxdWlyZSgnLi4vcmFuZG9tLmpzJyksXG4gIGhhc2hNb2R1bGUgPSByZXF1aXJlKCcuLi9oYXNoJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbmZ1bmN0aW9uIERTQSgpIHtcbiAgLy8gczEgPSAoKGcqKnMpIG1vZCBwKSBtb2QgcVxuICAvLyBzMSA9ICgocyoqLTEpKihzaGEtMShtKSsoczEqeCkgbW9kIHEpXG4gIGZ1bmN0aW9uIHNpZ24oaGFzaGFsZ28sIG0sIGcsIHAsIHEsIHgpIHtcbiAgICAvLyBJZiB0aGUgb3V0cHV0IHNpemUgb2YgdGhlIGNob3NlbiBoYXNoIGlzIGxhcmdlciB0aGFuIHRoZSBudW1iZXIgb2ZcbiAgICAvLyBiaXRzIG9mIHEsIHRoZSBoYXNoIHJlc3VsdCBpcyB0cnVuY2F0ZWQgdG8gZml0IGJ5IHRha2luZyB0aGUgbnVtYmVyXG4gICAgLy8gb2YgbGVmdG1vc3QgYml0cyBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGJpdHMgb2YgcS4gIFRoaXMgKHBvc3NpYmx5XG4gICAgLy8gdHJ1bmNhdGVkKSBoYXNoIGZ1bmN0aW9uIHJlc3VsdCBpcyB0cmVhdGVkIGFzIGEgbnVtYmVyIGFuZCB1c2VkXG4gICAgLy8gZGlyZWN0bHkgaW4gdGhlIERTQSBzaWduYXR1cmUgYWxnb3JpdGhtLlxuICAgIHZhciBoYXNoZWRfZGF0YSA9IHV0aWwuZ2V0TGVmdE5CaXRzKGhhc2hNb2R1bGUuZGlnZXN0KGhhc2hhbGdvLCBtKSwgcS5iaXRMZW5ndGgoKSk7XG4gICAgdmFyIGhhc2ggPSBuZXcgQmlnSW50ZWdlcih1dGlsLmhleHN0cmR1bXAoaGFzaGVkX2RhdGEpLCAxNik7XG4gICAgdmFyIGsgPSByYW5kb20uZ2V0UmFuZG9tQmlnSW50ZWdlckluUmFuZ2UoQmlnSW50ZWdlci5PTkUuYWRkKEJpZ0ludGVnZXIuT05FKSwgcS5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkpO1xuICAgIHZhciBzMSA9IChnLm1vZFBvdyhrLCBwKSkubW9kKHEpO1xuICAgIHZhciBzMiA9IChrLm1vZEludmVyc2UocSkubXVsdGlwbHkoaGFzaC5hZGQoeC5tdWx0aXBseShzMSkpKSkubW9kKHEpO1xuICAgIHZhciByZXN1bHQgPSBuZXcgQXJyYXkoKTtcbiAgICByZXN1bHRbMF0gPSBzMS50b01QSSgpO1xuICAgIHJlc3VsdFsxXSA9IHMyLnRvTVBJKCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNlbGVjdF9oYXNoX2FsZ29yaXRobShxKSB7XG4gICAgdmFyIHVzZXJzZXR0aW5nID0gb3BlbnBncC5jb25maWcuY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobTtcbiAgICAvKlxuICAgICAqIDEwMjQtYml0IGtleSwgMTYwLWJpdCBxLCBTSEEtMSwgU0hBLTIyNCwgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMiBoYXNoXG4gICAgICogMjA0OC1iaXQga2V5LCAyMjQtYml0IHEsIFNIQS0yMjQsIFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIgaGFzaFxuICAgICAqIDIwNDgtYml0IGtleSwgMjU2LWJpdCBxLCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyIGhhc2hcbiAgICAgKiAzMDcyLWJpdCBrZXksIDI1Ni1iaXQgcSwgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMiBoYXNoXG4gICAgICovXG4gICAgc3dpdGNoIChNYXRoLnJvdW5kKHEuYml0TGVuZ3RoKCkgLyA4KSkge1xuICAgICAgY2FzZSAyMDpcbiAgICAgICAgLy8gMTAyNCBiaXRcbiAgICAgICAgaWYgKHVzZXJzZXR0aW5nICE9IDIgJiZcbiAgICAgICAgICB1c2Vyc2V0dGluZyA+IDExICYmXG4gICAgICAgICAgdXNlcnNldHRpbmcgIT0gMTAgJiZcbiAgICAgICAgICB1c2Vyc2V0dGluZyA8IDgpXG4gICAgICAgICAgcmV0dXJuIDI7IC8vIHByZWZlciBzaGExXG4gICAgICAgIHJldHVybiB1c2Vyc2V0dGluZztcbiAgICAgIGNhc2UgMjg6XG4gICAgICAgIC8vIDIwNDggYml0XG4gICAgICAgIGlmICh1c2Vyc2V0dGluZyA+IDExICYmXG4gICAgICAgICAgdXNlcnNldHRpbmcgPCA4KVxuICAgICAgICAgIHJldHVybiAxMTtcbiAgICAgICAgcmV0dXJuIHVzZXJzZXR0aW5nO1xuICAgICAgY2FzZSAzMjpcbiAgICAgICAgLy8gNDA5NiBiaXQgLy8gcHJlZmVyIHNoYTIyNFxuICAgICAgICBpZiAodXNlcnNldHRpbmcgPiAxMCAmJlxuICAgICAgICAgIHVzZXJzZXR0aW5nIDwgOClcbiAgICAgICAgICByZXR1cm4gODsgLy8gcHJlZmVyIHNoYTI1NlxuICAgICAgICByZXR1cm4gdXNlcnNldHRpbmc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB1dGlsLnByaW50X2RlYnVnKFwiRFNBIHNlbGVjdCBoYXNoIGFsZ29yaXRobTogcmV0dXJuaW5nIG51bGwgZm9yIGFuIHVua25vd24gbGVuZ3RoIG9mIHFcIik7XG4gICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgfVxuICB9XG4gIHRoaXMuc2VsZWN0X2hhc2hfYWxnb3JpdGhtID0gc2VsZWN0X2hhc2hfYWxnb3JpdGhtO1xuXG4gIGZ1bmN0aW9uIHZlcmlmeShoYXNoYWxnbywgczEsIHMyLCBtLCBwLCBxLCBnLCB5KSB7XG4gICAgdmFyIGhhc2hlZF9kYXRhID0gdXRpbC5nZXRMZWZ0TkJpdHMoaGFzaE1vZHVsZS5kaWdlc3QoaGFzaGFsZ28sIG0pLCBxLmJpdExlbmd0aCgpKTtcbiAgICB2YXIgaGFzaCA9IG5ldyBCaWdJbnRlZ2VyKHV0aWwuaGV4c3RyZHVtcChoYXNoZWRfZGF0YSksIDE2KTtcbiAgICBpZiAoQmlnSW50ZWdlci5aRVJPLmNvbXBhcmVUbyhzMSkgPiAwIHx8XG4gICAgICBzMS5jb21wYXJlVG8ocSkgPiAwIHx8XG4gICAgICBCaWdJbnRlZ2VyLlpFUk8uY29tcGFyZVRvKHMyKSA+IDAgfHxcbiAgICAgIHMyLmNvbXBhcmVUbyhxKSA+IDApIHtcbiAgICAgIHV0aWwucHJpbnRfZXJyb3IoXCJpbnZhbGlkIERTQSBTaWduYXR1cmVcIik7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdmFyIHcgPSBzMi5tb2RJbnZlcnNlKHEpO1xuICAgIHZhciB1MSA9IGhhc2gubXVsdGlwbHkodykubW9kKHEpO1xuICAgIHZhciB1MiA9IHMxLm11bHRpcGx5KHcpLm1vZChxKTtcbiAgICByZXR1cm4gZy5tb2RQb3codTEsIHApLm11bHRpcGx5KHkubW9kUG93KHUyLCBwKSkubW9kKHApLm1vZChxKTtcbiAgfVxuXG4gIC8qXG5cdCAqIHVudXNlZCBjb2RlLiBUaGlzIGNhbiBiZSB1c2VkIGFzIGEgc3RhcnQgdG8gd3JpdGUgYSBrZXkgZ2VuZXJhdG9yXG5cdCAqIGZ1bmN0aW9uLlxuXHRcblx0ZnVuY3Rpb24gZ2VuZXJhdGVLZXkoYml0Y291bnQpIHtcblx0ICAgIHZhciBxaSA9IG5ldyBCaWdJbnRlZ2VyKGJpdGNvdW50LCBwcmltZUNlbnRlcmllKTtcblx0ICAgIHZhciBwaSA9IGdlbmVyYXRlUChxLCA1MTIpO1xuXHQgICAgdmFyIGdpID0gZ2VuZXJhdGVHKHAsIHEsIGJpdGNvdW50KTtcblx0ICAgIHZhciB4aTtcblx0ICAgIGRvIHtcblx0ICAgICAgICB4aSA9IG5ldyBCaWdJbnRlZ2VyKHEuYml0Q291bnQoKSwgcmFuZCk7XG5cdCAgICB9IHdoaWxlICh4LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pICE9IDEgJiYgeC5jb21wYXJlVG8ocSkgIT0gLTEpO1xuXHQgICAgdmFyIHlpID0gZy5tb2RQb3coeCwgcCk7XG5cdCAgICByZXR1cm4ge3g6IHhpLCBxOiBxaSwgcDogcGksIGc6IGdpLCB5OiB5aX07XG5cdH1cblxuXHRmdW5jdGlvbiBnZW5lcmF0ZVAocSwgYml0bGVuZ3RoLCByYW5kb21mbikge1xuXHQgICAgaWYgKGJpdGxlbmd0aCAlIDY0ICE9IDApIHtcblx0ICAgIFx0cmV0dXJuIGZhbHNlO1xuXHQgICAgfVxuXHQgICAgdmFyIHBUZW1wO1xuXHQgICAgdmFyIHBUZW1wMjtcblx0ICAgIGRvIHtcblx0ICAgICAgICBwVGVtcCA9IHJhbmRvbWZuKGJpdGNvdW50LCB0cnVlKTtcblx0ICAgICAgICBwVGVtcDIgPSBwVGVtcC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG5cdCAgICAgICAgcFRlbXAgPSBwVGVtcC5zdWJ0cmFjdChwVGVtcDIucmVtYWluZGVyKHEpKTtcblx0ICAgIH0gd2hpbGUgKCFwVGVtcC5pc1Byb2JhYmxlUHJpbWUocHJpbWVDZW50ZXJpZSkgfHwgcFRlbXAuYml0TGVuZ3RoKCkgIT0gbCk7XG5cdCAgICByZXR1cm4gcFRlbXA7XG5cdH1cblx0XG5cdGZ1bmN0aW9uIGdlbmVyYXRlRyhwLCBxLCBiaXRsZW5ndGgsIHJhbmRvbWZuKSB7XG5cdCAgICB2YXIgYXV4ID0gcC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG5cdCAgICB2YXIgcG93ID0gYXV4LmRpdmlkZShxKTtcblx0ICAgIHZhciBnVGVtcDtcblx0ICAgIGRvIHtcblx0ICAgICAgICBnVGVtcCA9IHJhbmRvbWZuKGJpdGxlbmd0aCk7XG5cdCAgICB9IHdoaWxlIChnVGVtcC5jb21wYXJlVG8oYXV4KSAhPSAtMSAmJiBnVGVtcC5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDEpO1xuXHQgICAgcmV0dXJuIGdUZW1wLm1vZFBvdyhwb3csIHApO1xuXHR9XG5cblx0ZnVuY3Rpb24gZ2VuZXJhdGVLKHEsIGJpdGxlbmd0aCwgcmFuZG9tZm4pIHtcblx0ICAgIHZhciB0ZW1wSztcblx0ICAgIGRvIHtcblx0ICAgICAgICB0ZW1wSyA9IHJhbmRvbWZuKGJpdGxlbmd0aCwgZmFsc2UpO1xuXHQgICAgfSB3aGlsZSAodGVtcEsuY29tcGFyZVRvKHEpICE9IC0xICYmIHRlbXBLLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pICE9IDEpO1xuXHQgICAgcmV0dXJuIHRlbXBLO1xuXHR9XG5cblx0ZnVuY3Rpb24gZ2VuZXJhdGVSKHEscCkge1xuXHQgICAgayA9IGdlbmVyYXRlSyhxKTtcblx0ICAgIHZhciByID0gZy5tb2RQb3coaywgcCkubW9kKHEpO1xuXHQgICAgcmV0dXJuIHI7XG5cdH1cblxuXHRmdW5jdGlvbiBnZW5lcmF0ZVMoaGFzaGZuLGsscixtLHEseCkge1xuICAgICAgICB2YXIgaGFzaCA9IGhhc2hmbihtKTtcbiAgICAgICAgcyA9IChrLm1vZEludmVyc2UocSkubXVsdGlwbHkoaGFzaC5hZGQoeC5tdWx0aXBseShyKSkpKS5tb2QocSk7XG5cdCAgICByZXR1cm4gcztcblx0fSAqL1xuICB0aGlzLnNpZ24gPSBzaWduO1xuICB0aGlzLnZlcmlmeSA9IHZlcmlmeTtcbiAgLy8gdGhpcy5nZW5lcmF0ZSA9IGdlbmVyYXRlS2V5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IERTQTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG4vL1xuLy8gRWxHYW1hbCBpbXBsZW1lbnRhdGlvblxuXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vanNibi5qcycpLFxuICByYW5kb20gPSByZXF1aXJlKCcuLi9yYW5kb20uanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuZnVuY3Rpb24gRWxnYW1hbCgpIHtcblxuICBmdW5jdGlvbiBlbmNyeXB0KG0sIGcsIHAsIHkpIHtcbiAgICAvLyAgY2hvb3NlIGsgaW4gezIsLi4uLHAtMn1cbiAgICB2YXIgdHdvID0gQmlnSW50ZWdlci5PTkUuYWRkKEJpZ0ludGVnZXIuT05FKTtcbiAgICB2YXIgcE1pbnVzMiA9IHAuc3VidHJhY3QodHdvKTtcbiAgICB2YXIgayA9IHJhbmRvbS5nZXRSYW5kb21CaWdJbnRlZ2VySW5SYW5nZSh0d28sIHBNaW51czIpO1xuICAgIGsgPSBrLm1vZChwTWludXMyKS5hZGQoQmlnSW50ZWdlci5PTkUpO1xuICAgIHZhciBjID0gW107XG4gICAgY1swXSA9IGcubW9kUG93KGssIHApO1xuICAgIGNbMV0gPSB5Lm1vZFBvdyhrLCBwKS5tdWx0aXBseShtKS5tb2QocCk7XG4gICAgcmV0dXJuIGM7XG4gIH1cblxuICBmdW5jdGlvbiBkZWNyeXB0KGMxLCBjMiwgcCwgeCkge1xuICAgIHV0aWwucHJpbnRfZGVidWcoXCJFbGdhbWFsIERlY3J5cHQ6XFxuYzE6XCIgKyB1dGlsLmhleHN0cmR1bXAoYzEudG9NUEkoKSkgKyBcIlxcblwiICtcbiAgICAgIFwiYzI6XCIgKyB1dGlsLmhleHN0cmR1bXAoYzIudG9NUEkoKSkgKyBcIlxcblwiICtcbiAgICAgIFwicDpcIiArIHV0aWwuaGV4c3RyZHVtcChwLnRvTVBJKCkpICsgXCJcXG5cIiArXG4gICAgICBcIng6XCIgKyB1dGlsLmhleHN0cmR1bXAoeC50b01QSSgpKSk7XG4gICAgcmV0dXJuIChjMS5tb2RQb3coeCwgcCkubW9kSW52ZXJzZShwKSkubXVsdGlwbHkoYzIpLm1vZChwKTtcbiAgICAvL3ZhciBjID0gYzEucG93KHgpLm1vZEludmVyc2UocCk7IC8vIGMwXi1hIG1vZCBwXG4gICAgLy9yZXR1cm4gYy5tdWx0aXBseShjMikubW9kKHApO1xuICB9XG5cbiAgLy8gc2lnbmluZyBhbmQgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiB1c2luZyBFbGdhbWFsIGlzIG5vdCByZXF1aXJlZCBieSBPcGVuUEdQLlxuICB0aGlzLmVuY3J5cHQgPSBlbmNyeXB0O1xuICB0aGlzLmRlY3J5cHQgPSBkZWNyeXB0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEVsZ2FtYWw7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgcnNhOiByZXF1aXJlKCcuL3JzYS5qcycpLFxuICBlbGdhbWFsOiByZXF1aXJlKCcuL2VsZ2FtYWwuanMnKSxcbiAgZHNhOiByZXF1aXJlKCcuL2RzYS5qcycpXG59XG4iLCIvKlxuICogQ29weXJpZ2h0IChjKSAyMDAzLTIwMDUgIFRvbSBXdSAodGp3QGNzLlN0YW5mb3JkLkVEVSkgXG4gKiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSCBcbiAqIFxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nXG4gKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbiAqIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuICogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvXG4gKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG9cbiAqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZVxuICogaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMtSVNcIiBBTkQgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgXG4gKiBFWFBSRVNTLCBJTVBMSUVEIE9SIE9USEVSV0lTRSwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiwgQU5ZIFxuICogV0FSUkFOVFkgT0YgTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgXG4gKlxuICogSU4gTk8gRVZFTlQgU0hBTEwgVE9NIFdVIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElOQ0lERU5UQUwsXG4gKiBJTkRJUkVDVCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT0YgQU5ZIEtJTkQsIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVJcbiAqIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgT1IgTk9UIEFEVklTRUQgT0ZcbiAqIFRIRSBQT1NTSUJJTElUWSBPRiBEQU1BR0UsIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgQVJJU0lORyBPVVRcbiAqIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXG4gKlxuICogSW4gYWRkaXRpb24sIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uIGFwcGxpZXM6XG4gKlxuICogQWxsIHJlZGlzdHJpYnV0aW9ucyBtdXN0IHJldGFpbiBhbiBpbnRhY3QgY29weSBvZiB0aGlzIGNvcHlyaWdodCBub3RpY2VcbiAqIGFuZCBkaXNjbGFpbWVyLlxuICovXG5cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbi8vIEJhc2ljIEphdmFTY3JpcHQgQk4gbGlicmFyeSAtIHN1YnNldCB1c2VmdWwgZm9yIFJTQSBlbmNyeXB0aW9uLlxuXG4vLyBCaXRzIHBlciBkaWdpdFxudmFyIGRiaXRzO1xuXG4vLyBKYXZhU2NyaXB0IGVuZ2luZSBhbmFseXNpc1xudmFyIGNhbmFyeSA9IDB4ZGVhZGJlZWZjYWZlO1xudmFyIGpfbG0gPSAoKGNhbmFyeSAmIDB4ZmZmZmZmKSA9PSAweGVmY2FmZSk7XG5cbi8vIChwdWJsaWMpIENvbnN0cnVjdG9yXG5cbmZ1bmN0aW9uIEJpZ0ludGVnZXIoYSwgYiwgYykge1xuICBpZiAoYSAhPSBudWxsKVxuICAgIGlmIChcIm51bWJlclwiID09IHR5cGVvZiBhKSB0aGlzLmZyb21OdW1iZXIoYSwgYiwgYyk7XG4gICAgZWxzZSBpZiAoYiA9PSBudWxsICYmIFwic3RyaW5nXCIgIT0gdHlwZW9mIGEpIHRoaXMuZnJvbVN0cmluZyhhLCAyNTYpO1xuICBlbHNlIHRoaXMuZnJvbVN0cmluZyhhLCBiKTtcbn1cblxuLy8gcmV0dXJuIG5ldywgdW5zZXQgQmlnSW50ZWdlclxuXG5mdW5jdGlvbiBuYmkoKSB7XG4gIHJldHVybiBuZXcgQmlnSW50ZWdlcihudWxsKTtcbn1cblxuLy8gYW06IENvbXB1dGUgd19qICs9ICh4KnRoaXNfaSksIHByb3BhZ2F0ZSBjYXJyaWVzLFxuLy8gYyBpcyBpbml0aWFsIGNhcnJ5LCByZXR1cm5zIGZpbmFsIGNhcnJ5LlxuLy8gYyA8IDMqZHZhbHVlLCB4IDwgMipkdmFsdWUsIHRoaXNfaSA8IGR2YWx1ZVxuLy8gV2UgbmVlZCB0byBzZWxlY3QgdGhlIGZhc3Rlc3Qgb25lIHRoYXQgd29ya3MgaW4gdGhpcyBlbnZpcm9ubWVudC5cblxuLy8gYW0xOiB1c2UgYSBzaW5nbGUgbXVsdCBhbmQgZGl2aWRlIHRvIGdldCB0aGUgaGlnaCBiaXRzLFxuLy8gbWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDI2IGJlY2F1c2Vcbi8vIG1heCBpbnRlcm5hbCB2YWx1ZSA9IDIqZHZhbHVlXjItMipkdmFsdWUgKDwgMl41MylcblxuZnVuY3Rpb24gYW0xKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgdmFyIHYgPSB4ICogdGhpc1tpKytdICsgd1tqXSArIGM7XG4gICAgYyA9IE1hdGguZmxvb3IodiAvIDB4NDAwMDAwMCk7XG4gICAgd1tqKytdID0gdiAmIDB4M2ZmZmZmZjtcbiAgfVxuICByZXR1cm4gYztcbn1cbi8vIGFtMiBhdm9pZHMgYSBiaWcgbXVsdC1hbmQtZXh0cmFjdCBjb21wbGV0ZWx5LlxuLy8gTWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDw9IDMwIGJlY2F1c2Ugd2UgZG8gYml0d2lzZSBvcHNcbi8vIG9uIHZhbHVlcyB1cCB0byAyKmhkdmFsdWVeMi1oZHZhbHVlLTEgKDwgMl4zMSlcblxuZnVuY3Rpb24gYW0yKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgdmFyIHhsID0geCAmIDB4N2ZmZixcbiAgICB4aCA9IHggPj4gMTU7XG4gIHdoaWxlICgtLW4gPj0gMCkge1xuICAgIHZhciBsID0gdGhpc1tpXSAmIDB4N2ZmZjtcbiAgICB2YXIgaCA9IHRoaXNbaSsrXSA+PiAxNTtcbiAgICB2YXIgbSA9IHhoICogbCArIGggKiB4bDtcbiAgICBsID0geGwgKiBsICsgKChtICYgMHg3ZmZmKSA8PCAxNSkgKyB3W2pdICsgKGMgJiAweDNmZmZmZmZmKTtcbiAgICBjID0gKGwgPj4+IDMwKSArIChtID4+PiAxNSkgKyB4aCAqIGggKyAoYyA+Pj4gMzApO1xuICAgIHdbaisrXSA9IGwgJiAweDNmZmZmZmZmO1xuICB9XG4gIHJldHVybiBjO1xufVxuLy8gQWx0ZXJuYXRlbHksIHNldCBtYXggZGlnaXQgYml0cyB0byAyOCBzaW5jZSBzb21lXG4vLyBicm93c2VycyBzbG93IGRvd24gd2hlbiBkZWFsaW5nIHdpdGggMzItYml0IG51bWJlcnMuXG5cbmZ1bmN0aW9uIGFtMyhpLCB4LCB3LCBqLCBjLCBuKSB7XG4gIHZhciB4bCA9IHggJiAweDNmZmYsXG4gICAgeGggPSB4ID4+IDE0O1xuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICB2YXIgbCA9IHRoaXNbaV0gJiAweDNmZmY7XG4gICAgdmFyIGggPSB0aGlzW2krK10gPj4gMTQ7XG4gICAgdmFyIG0gPSB4aCAqIGwgKyBoICogeGw7XG4gICAgbCA9IHhsICogbCArICgobSAmIDB4M2ZmZikgPDwgMTQpICsgd1tqXSArIGM7XG4gICAgYyA9IChsID4+IDI4KSArIChtID4+IDE0KSArIHhoICogaDtcbiAgICB3W2orK10gPSBsICYgMHhmZmZmZmZmO1xuICB9XG4gIHJldHVybiBjO1xufVxuLyppZihqX2xtICYmIChuYXZpZ2F0b3IgIT0gdW5kZWZpbmVkICYmIFxuXHRuYXZpZ2F0b3IuYXBwTmFtZSA9PSBcIk1pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlclwiKSkge1xuICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMjtcbiAgZGJpdHMgPSAzMDtcbn1cbmVsc2UgaWYoal9sbSAmJiAobmF2aWdhdG9yICE9IHVuZGVmaW5lZCAmJiBuYXZpZ2F0b3IuYXBwTmFtZSAhPSBcIk5ldHNjYXBlXCIpKSB7Ki9cbkJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0xO1xuZGJpdHMgPSAyNjtcbi8qfVxuZWxzZSB7IC8vIE1vemlsbGEvTmV0c2NhcGUgc2VlbXMgdG8gcHJlZmVyIGFtM1xuICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMztcbiAgZGJpdHMgPSAyODtcbn0qL1xuXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5EQiA9IGRiaXRzO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuRE0gPSAoKDEgPDwgZGJpdHMpIC0gMSk7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5EViA9ICgxIDw8IGRiaXRzKTtcblxudmFyIEJJX0ZQID0gNTI7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5GViA9IE1hdGgucG93KDIsIEJJX0ZQKTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLkYxID0gQklfRlAgLSBkYml0cztcbkJpZ0ludGVnZXIucHJvdG90eXBlLkYyID0gMiAqIGRiaXRzIC0gQklfRlA7XG5cbi8vIERpZ2l0IGNvbnZlcnNpb25zXG52YXIgQklfUk0gPSBcIjAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elwiO1xudmFyIEJJX1JDID0gbmV3IEFycmF5KCk7XG52YXIgcnIsIHZ2O1xucnIgPSBcIjBcIi5jaGFyQ29kZUF0KDApO1xuZm9yICh2diA9IDA7IHZ2IDw9IDk7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7XG5yciA9IFwiYVwiLmNoYXJDb2RlQXQoMCk7XG5mb3IgKHZ2ID0gMTA7IHZ2IDwgMzY7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7XG5yciA9IFwiQVwiLmNoYXJDb2RlQXQoMCk7XG5mb3IgKHZ2ID0gMTA7IHZ2IDwgMzY7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7XG5cbmZ1bmN0aW9uIGludDJjaGFyKG4pIHtcbiAgcmV0dXJuIEJJX1JNLmNoYXJBdChuKTtcbn1cblxuZnVuY3Rpb24gaW50QXQocywgaSkge1xuICB2YXIgYyA9IEJJX1JDW3MuY2hhckNvZGVBdChpKV07XG4gIHJldHVybiAoYyA9PSBudWxsKSA/IC0xIDogYztcbn1cblxuLy8gKHByb3RlY3RlZCkgY29weSB0aGlzIHRvIHJcblxuZnVuY3Rpb24gYm5wQ29weVRvKHIpIHtcbiAgZm9yICh2YXIgaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByW2ldID0gdGhpc1tpXTtcbiAgci50ID0gdGhpcy50O1xuICByLnMgPSB0aGlzLnM7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIGludGVnZXIgdmFsdWUgeCwgLURWIDw9IHggPCBEVlxuXG5mdW5jdGlvbiBibnBGcm9tSW50KHgpIHtcbiAgdGhpcy50ID0gMTtcbiAgdGhpcy5zID0gKHggPCAwKSA/IC0xIDogMDtcbiAgaWYgKHggPiAwKSB0aGlzWzBdID0geDtcbiAgZWxzZSBpZiAoeCA8IC0xKSB0aGlzWzBdID0geCArIERWO1xuICBlbHNlIHRoaXMudCA9IDA7XG59XG5cbi8vIHJldHVybiBiaWdpbnQgaW5pdGlhbGl6ZWQgdG8gdmFsdWVcblxuZnVuY3Rpb24gbmJ2KGkpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgci5mcm9tSW50KGkpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gc3RyaW5nIGFuZCByYWRpeFxuXG5mdW5jdGlvbiBibnBGcm9tU3RyaW5nKHMsIGIpIHtcbiAgdmFyIGs7XG4gIGlmIChiID09IDE2KSBrID0gNDtcbiAgZWxzZSBpZiAoYiA9PSA4KSBrID0gMztcbiAgZWxzZSBpZiAoYiA9PSAyNTYpIGsgPSA4OyAvLyBieXRlIGFycmF5XG4gIGVsc2UgaWYgKGIgPT0gMikgayA9IDE7XG4gIGVsc2UgaWYgKGIgPT0gMzIpIGsgPSA1O1xuICBlbHNlIGlmIChiID09IDQpIGsgPSAyO1xuICBlbHNlIHtcbiAgICB0aGlzLmZyb21SYWRpeChzLCBiKTtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhpcy50ID0gMDtcbiAgdGhpcy5zID0gMDtcbiAgdmFyIGkgPSBzLmxlbmd0aCxcbiAgICBtaSA9IGZhbHNlLFxuICAgIHNoID0gMDtcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgdmFyIHggPSAoayA9PSA4KSA/IHNbaV0gJiAweGZmIDogaW50QXQocywgaSk7XG4gICAgaWYgKHggPCAwKSB7XG4gICAgICBpZiAocy5jaGFyQXQoaSkgPT0gXCItXCIpIG1pID0gdHJ1ZTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBtaSA9IGZhbHNlO1xuICAgIGlmIChzaCA9PSAwKVxuICAgICAgdGhpc1t0aGlzLnQrK10gPSB4O1xuICAgIGVsc2UgaWYgKHNoICsgayA+IHRoaXMuREIpIHtcbiAgICAgIHRoaXNbdGhpcy50IC0gMV0gfD0gKHggJiAoKDEgPDwgKHRoaXMuREIgLSBzaCkpIC0gMSkpIDw8IHNoO1xuICAgICAgdGhpc1t0aGlzLnQrK10gPSAoeCA+PiAodGhpcy5EQiAtIHNoKSk7XG4gICAgfSBlbHNlXG4gICAgICB0aGlzW3RoaXMudCAtIDFdIHw9IHggPDwgc2g7XG4gICAgc2ggKz0gaztcbiAgICBpZiAoc2ggPj0gdGhpcy5EQikgc2ggLT0gdGhpcy5EQjtcbiAgfVxuICBpZiAoayA9PSA4ICYmIChzWzBdICYgMHg4MCkgIT0gMCkge1xuICAgIHRoaXMucyA9IC0xO1xuICAgIGlmIChzaCA+IDApIHRoaXNbdGhpcy50IC0gMV0gfD0gKCgxIDw8ICh0aGlzLkRCIC0gc2gpKSAtIDEpIDw8IHNoO1xuICB9XG4gIHRoaXMuY2xhbXAoKTtcbiAgaWYgKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcywgdGhpcyk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIGNsYW1wIG9mZiBleGNlc3MgaGlnaCB3b3Jkc1xuXG5mdW5jdGlvbiBibnBDbGFtcCgpIHtcbiAgdmFyIGMgPSB0aGlzLnMgJiB0aGlzLkRNO1xuICB3aGlsZSAodGhpcy50ID4gMCAmJiB0aGlzW3RoaXMudCAtIDFdID09IGMpLS10aGlzLnQ7XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gaW4gZ2l2ZW4gcmFkaXhcblxuZnVuY3Rpb24gYm5Ub1N0cmluZyhiKSB7XG4gIGlmICh0aGlzLnMgPCAwKSByZXR1cm4gXCItXCIgKyB0aGlzLm5lZ2F0ZSgpLnRvU3RyaW5nKGIpO1xuICB2YXIgaztcbiAgaWYgKGIgPT0gMTYpIGsgPSA0O1xuICBlbHNlIGlmIChiID09IDgpIGsgPSAzO1xuICBlbHNlIGlmIChiID09IDIpIGsgPSAxO1xuICBlbHNlIGlmIChiID09IDMyKSBrID0gNTtcbiAgZWxzZSBpZiAoYiA9PSA0KSBrID0gMjtcbiAgZWxzZSByZXR1cm4gdGhpcy50b1JhZGl4KGIpO1xuICB2YXIga20gPSAoMSA8PCBrKSAtIDEsXG4gICAgZCwgbSA9IGZhbHNlLFxuICAgIHIgPSBcIlwiLFxuICAgIGkgPSB0aGlzLnQ7XG4gIHZhciBwID0gdGhpcy5EQiAtIChpICogdGhpcy5EQikgJSBrO1xuICBpZiAoaS0tID4gMCkge1xuICAgIGlmIChwIDwgdGhpcy5EQiAmJiAoZCA9IHRoaXNbaV0gPj4gcCkgPiAwKSB7XG4gICAgICBtID0gdHJ1ZTtcbiAgICAgIHIgPSBpbnQyY2hhcihkKTtcbiAgICB9XG4gICAgd2hpbGUgKGkgPj0gMCkge1xuICAgICAgaWYgKHAgPCBrKSB7XG4gICAgICAgIGQgPSAodGhpc1tpXSAmICgoMSA8PCBwKSAtIDEpKSA8PCAoayAtIHApO1xuICAgICAgICBkIHw9IHRoaXNbLS1pXSA+PiAocCArPSB0aGlzLkRCIC0gayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkID0gKHRoaXNbaV0gPj4gKHAgLT0gaykpICYga207XG4gICAgICAgIGlmIChwIDw9IDApIHtcbiAgICAgICAgICBwICs9IHRoaXMuREI7XG4gICAgICAgICAgLS1pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZCA+IDApIG0gPSB0cnVlO1xuICAgICAgaWYgKG0pIHIgKz0gaW50MmNoYXIoZCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBtID8gciA6IFwiMFwiO1xufVxuXG4vLyAocHVibGljKSAtdGhpc1xuXG5mdW5jdGlvbiBibk5lZ2F0ZSgpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgfHRoaXN8XG5cbmZ1bmN0aW9uIGJuQWJzKCkge1xuICByZXR1cm4gKHRoaXMucyA8IDApID8gdGhpcy5uZWdhdGUoKSA6IHRoaXM7XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiArIGlmIHRoaXMgPiBhLCAtIGlmIHRoaXMgPCBhLCAwIGlmIGVxdWFsXG5cbmZ1bmN0aW9uIGJuQ29tcGFyZVRvKGEpIHtcbiAgdmFyIHIgPSB0aGlzLnMgLSBhLnM7XG4gIGlmIChyICE9IDApIHJldHVybiByO1xuICB2YXIgaSA9IHRoaXMudDtcbiAgciA9IGkgLSBhLnQ7XG4gIGlmIChyICE9IDApIHJldHVybiByO1xuICB3aGlsZSAoLS1pID49IDApIGlmICgociA9IHRoaXNbaV0gLSBhW2ldKSAhPSAwKSByZXR1cm4gcjtcbiAgcmV0dXJuIDA7XG59XG5cbi8vIHJldHVybnMgYml0IGxlbmd0aCBvZiB0aGUgaW50ZWdlciB4XG5cbmZ1bmN0aW9uIG5iaXRzKHgpIHtcbiAgdmFyIHIgPSAxLFxuICAgIHQ7XG4gIGlmICgodCA9IHggPj4+IDE2KSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgciArPSAxNjtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDgpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICByICs9IDg7XG4gIH1cbiAgaWYgKCh0ID0geCA+PiA0KSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgciArPSA0O1xuICB9XG4gIGlmICgodCA9IHggPj4gMikgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIHIgKz0gMjtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDEpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICByICs9IDE7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gXCJ0aGlzXCJcblxuZnVuY3Rpb24gYm5CaXRMZW5ndGgoKSB7XG4gIGlmICh0aGlzLnQgPD0gMCkgcmV0dXJuIDA7XG4gIHJldHVybiB0aGlzLkRCICogKHRoaXMudCAtIDEpICsgbmJpdHModGhpc1t0aGlzLnQgLSAxXSBeICh0aGlzLnMgJiB0aGlzLkRNKSk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG4qREJcblxuZnVuY3Rpb24gYm5wRExTaGlmdFRvKG4sIHIpIHtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByW2kgKyBuXSA9IHRoaXNbaV07XG4gIGZvciAoaSA9IG4gLSAxOyBpID49IDA7IC0taSkgcltpXSA9IDA7XG4gIHIudCA9IHRoaXMudCArIG47XG4gIHIucyA9IHRoaXMucztcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gbipEQlxuXG5mdW5jdGlvbiBibnBEUlNoaWZ0VG8obiwgcikge1xuICBmb3IgKHZhciBpID0gbjsgaSA8IHRoaXMudDsgKytpKSByW2kgLSBuXSA9IHRoaXNbaV07XG4gIHIudCA9IE1hdGgubWF4KHRoaXMudCAtIG4sIDApO1xuICByLnMgPSB0aGlzLnM7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG5cblxuZnVuY3Rpb24gYm5wTFNoaWZ0VG8obiwgcikge1xuICB2YXIgYnMgPSBuICUgdGhpcy5EQjtcbiAgdmFyIGNicyA9IHRoaXMuREIgLSBicztcbiAgdmFyIGJtID0gKDEgPDwgY2JzKSAtIDE7XG4gIHZhciBkcyA9IE1hdGguZmxvb3IobiAvIHRoaXMuREIpLFxuICAgIGMgPSAodGhpcy5zIDw8IGJzKSAmIHRoaXMuRE0sXG4gICAgaTtcbiAgZm9yIChpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICByW2kgKyBkcyArIDFdID0gKHRoaXNbaV0gPj4gY2JzKSB8IGM7XG4gICAgYyA9ICh0aGlzW2ldICYgYm0pIDw8IGJzO1xuICB9XG4gIGZvciAoaSA9IGRzIC0gMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSAwO1xuICByW2RzXSA9IGM7XG4gIHIudCA9IHRoaXMudCArIGRzICsgMTtcbiAgci5zID0gdGhpcy5zO1xuICByLmNsYW1wKCk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzID4+IG5cblxuZnVuY3Rpb24gYm5wUlNoaWZ0VG8obiwgcikge1xuICByLnMgPSB0aGlzLnM7XG4gIHZhciBkcyA9IE1hdGguZmxvb3IobiAvIHRoaXMuREIpO1xuICBpZiAoZHMgPj0gdGhpcy50KSB7XG4gICAgci50ID0gMDtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGJzID0gbiAlIHRoaXMuREI7XG4gIHZhciBjYnMgPSB0aGlzLkRCIC0gYnM7XG4gIHZhciBibSA9ICgxIDw8IGJzKSAtIDE7XG4gIHJbMF0gPSB0aGlzW2RzXSA+PiBicztcbiAgZm9yICh2YXIgaSA9IGRzICsgMTsgaSA8IHRoaXMudDsgKytpKSB7XG4gICAgcltpIC0gZHMgLSAxXSB8PSAodGhpc1tpXSAmIGJtKSA8PCBjYnM7XG4gICAgcltpIC0gZHNdID0gdGhpc1tpXSA+PiBicztcbiAgfVxuICBpZiAoYnMgPiAwKSByW3RoaXMudCAtIGRzIC0gMV0gfD0gKHRoaXMucyAmIGJtKSA8PCBjYnM7XG4gIHIudCA9IHRoaXMudCAtIGRzO1xuICByLmNsYW1wKCk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIC0gYVxuXG5mdW5jdGlvbiBibnBTdWJUbyhhLCByKSB7XG4gIHZhciBpID0gMCxcbiAgICBjID0gMCxcbiAgICBtID0gTWF0aC5taW4oYS50LCB0aGlzLnQpO1xuICB3aGlsZSAoaSA8IG0pIHtcbiAgICBjICs9IHRoaXNbaV0gLSBhW2ldO1xuICAgIHJbaSsrXSA9IGMgJiB0aGlzLkRNO1xuICAgIGMgPj49IHRoaXMuREI7XG4gIH1cbiAgaWYgKGEudCA8IHRoaXMudCkge1xuICAgIGMgLT0gYS5zO1xuICAgIHdoaWxlIChpIDwgdGhpcy50KSB7XG4gICAgICBjICs9IHRoaXNbaV07XG4gICAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgKz0gdGhpcy5zO1xuICB9IGVsc2Uge1xuICAgIGMgKz0gdGhpcy5zO1xuICAgIHdoaWxlIChpIDwgYS50KSB7XG4gICAgICBjIC09IGFbaV07XG4gICAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgLT0gYS5zO1xuICB9XG4gIHIucyA9IChjIDwgMCkgPyAtMSA6IDA7XG4gIGlmIChjIDwgLTEpIHJbaSsrXSA9IHRoaXMuRFYgKyBjO1xuICBlbHNlIGlmIChjID4gMCkgcltpKytdID0gYztcbiAgci50ID0gaTtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyAqIGEsIHIgIT0gdGhpcyxhIChIQUMgMTQuMTIpXG4vLyBcInRoaXNcIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuXG5cbmZ1bmN0aW9uIGJucE11bHRpcGx5VG8oYSwgcikge1xuICB2YXIgeCA9IHRoaXMuYWJzKCksXG4gICAgeSA9IGEuYWJzKCk7XG4gIHZhciBpID0geC50O1xuICByLnQgPSBpICsgeS50O1xuICB3aGlsZSAoLS1pID49IDApIHJbaV0gPSAwO1xuICBmb3IgKGkgPSAwOyBpIDwgeS50OyArK2kpIHJbaSArIHgudF0gPSB4LmFtKDAsIHlbaV0sIHIsIGksIDAsIHgudCk7XG4gIHIucyA9IDA7XG4gIHIuY2xhbXAoKTtcbiAgaWYgKHRoaXMucyAhPSBhLnMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhyLCByKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXNeMiwgciAhPSB0aGlzIChIQUMgMTQuMTYpXG5cbmZ1bmN0aW9uIGJucFNxdWFyZVRvKHIpIHtcbiAgdmFyIHggPSB0aGlzLmFicygpO1xuICB2YXIgaSA9IHIudCA9IDIgKiB4LnQ7XG4gIHdoaWxlICgtLWkgPj0gMCkgcltpXSA9IDA7XG4gIGZvciAoaSA9IDA7IGkgPCB4LnQgLSAxOyArK2kpIHtcbiAgICB2YXIgYyA9IHguYW0oaSwgeFtpXSwgciwgMiAqIGksIDAsIDEpO1xuICAgIGlmICgocltpICsgeC50XSArPSB4LmFtKGkgKyAxLCAyICogeFtpXSwgciwgMiAqIGkgKyAxLCBjLCB4LnQgLSBpIC0gMSkpID49IHguRFYpIHtcbiAgICAgIHJbaSArIHgudF0gLT0geC5EVjtcbiAgICAgIHJbaSArIHgudCArIDFdID0gMTtcbiAgICB9XG4gIH1cbiAgaWYgKHIudCA+IDApIHJbci50IC0gMV0gKz0geC5hbShpLCB4W2ldLCByLCAyICogaSwgMCwgMSk7XG4gIHIucyA9IDA7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgZGl2aWRlIHRoaXMgYnkgbSwgcXVvdGllbnQgYW5kIHJlbWFpbmRlciB0byBxLCByIChIQUMgMTQuMjApXG4vLyByICE9IHEsIHRoaXMgIT0gbS4gIHEgb3IgciBtYXkgYmUgbnVsbC5cblxuZnVuY3Rpb24gYm5wRGl2UmVtVG8obSwgcSwgcikge1xuICB2YXIgcG0gPSBtLmFicygpO1xuICBpZiAocG0udCA8PSAwKSByZXR1cm47XG4gIHZhciBwdCA9IHRoaXMuYWJzKCk7XG4gIGlmIChwdC50IDwgcG0udCkge1xuICAgIGlmIChxICE9IG51bGwpIHEuZnJvbUludCgwKTtcbiAgICBpZiAociAhPSBudWxsKSB0aGlzLmNvcHlUbyhyKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHIgPT0gbnVsbCkgciA9IG5iaSgpO1xuICB2YXIgeSA9IG5iaSgpLFxuICAgIHRzID0gdGhpcy5zLFxuICAgIG1zID0gbS5zO1xuICB2YXIgbnNoID0gdGhpcy5EQiAtIG5iaXRzKHBtW3BtLnQgLSAxXSk7IC8vIG5vcm1hbGl6ZSBtb2R1bHVzXG4gIGlmIChuc2ggPiAwKSB7XG4gICAgcG0ubFNoaWZ0VG8obnNoLCB5KTtcbiAgICBwdC5sU2hpZnRUbyhuc2gsIHIpO1xuICB9IGVsc2Uge1xuICAgIHBtLmNvcHlUbyh5KTtcbiAgICBwdC5jb3B5VG8ocik7XG4gIH1cbiAgdmFyIHlzID0geS50O1xuICB2YXIgeTAgPSB5W3lzIC0gMV07XG4gIGlmICh5MCA9PSAwKSByZXR1cm47XG4gIHZhciB5dCA9IHkwICogKDEgPDwgdGhpcy5GMSkgKyAoKHlzID4gMSkgPyB5W3lzIC0gMl0gPj4gdGhpcy5GMiA6IDApO1xuICB2YXIgZDEgPSB0aGlzLkZWIC8geXQsXG4gICAgZDIgPSAoMSA8PCB0aGlzLkYxKSAvIHl0LFxuICAgIGUgPSAxIDw8IHRoaXMuRjI7XG4gIHZhciBpID0gci50LFxuICAgIGogPSBpIC0geXMsXG4gICAgdCA9IChxID09IG51bGwpID8gbmJpKCkgOiBxO1xuICB5LmRsU2hpZnRUbyhqLCB0KTtcbiAgaWYgKHIuY29tcGFyZVRvKHQpID49IDApIHtcbiAgICByW3IudCsrXSA9IDE7XG4gICAgci5zdWJUbyh0LCByKTtcbiAgfVxuICBCaWdJbnRlZ2VyLk9ORS5kbFNoaWZ0VG8oeXMsIHQpO1xuICB0LnN1YlRvKHksIHkpOyAvLyBcIm5lZ2F0aXZlXCIgeSBzbyB3ZSBjYW4gcmVwbGFjZSBzdWIgd2l0aCBhbSBsYXRlclxuICB3aGlsZSAoeS50IDwgeXMpIHlbeS50KytdID0gMDtcbiAgd2hpbGUgKC0taiA+PSAwKSB7XG4gICAgLy8gRXN0aW1hdGUgcXVvdGllbnQgZGlnaXRcbiAgICB2YXIgcWQgPSAoclstLWldID09IHkwKSA/IHRoaXMuRE0gOiBNYXRoLmZsb29yKHJbaV0gKiBkMSArIChyW2kgLSAxXSArIGUpICogZDIpO1xuICAgIGlmICgocltpXSArPSB5LmFtKDAsIHFkLCByLCBqLCAwLCB5cykpIDwgcWQpIHsgLy8gVHJ5IGl0IG91dFxuICAgICAgeS5kbFNoaWZ0VG8oaiwgdCk7XG4gICAgICByLnN1YlRvKHQsIHIpO1xuICAgICAgd2hpbGUgKHJbaV0gPCAtLXFkKSByLnN1YlRvKHQsIHIpO1xuICAgIH1cbiAgfVxuICBpZiAocSAhPSBudWxsKSB7XG4gICAgci5kclNoaWZ0VG8oeXMsIHEpO1xuICAgIGlmICh0cyAhPSBtcykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHEsIHEpO1xuICB9XG4gIHIudCA9IHlzO1xuICByLmNsYW1wKCk7XG4gIGlmIChuc2ggPiAwKSByLnJTaGlmdFRvKG5zaCwgcik7IC8vIERlbm9ybWFsaXplIHJlbWFpbmRlclxuICBpZiAodHMgPCAwKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ociwgcik7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgbW9kIGFcblxuZnVuY3Rpb24gYm5Nb2QoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmFicygpLmRpdlJlbVRvKGEsIG51bGwsIHIpO1xuICBpZiAodGhpcy5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgYS5zdWJUbyhyLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIE1vZHVsYXIgcmVkdWN0aW9uIHVzaW5nIFwiY2xhc3NpY1wiIGFsZ29yaXRobVxuXG5mdW5jdGlvbiBDbGFzc2ljKG0pIHtcbiAgdGhpcy5tID0gbTtcbn1cblxuZnVuY3Rpb24gY0NvbnZlcnQoeCkge1xuICBpZiAoeC5zIDwgMCB8fCB4LmNvbXBhcmVUbyh0aGlzLm0pID49IDApIHJldHVybiB4Lm1vZCh0aGlzLm0pO1xuICBlbHNlIHJldHVybiB4O1xufVxuXG5mdW5jdGlvbiBjUmV2ZXJ0KHgpIHtcbiAgcmV0dXJuIHg7XG59XG5cbmZ1bmN0aW9uIGNSZWR1Y2UoeCkge1xuICB4LmRpdlJlbVRvKHRoaXMubSwgbnVsbCwgeCk7XG59XG5cbmZ1bmN0aW9uIGNNdWxUbyh4LCB5LCByKSB7XG4gIHgubXVsdGlwbHlUbyh5LCByKTtcbiAgdGhpcy5yZWR1Y2Uocik7XG59XG5cbmZ1bmN0aW9uIGNTcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocik7XG4gIHRoaXMucmVkdWNlKHIpO1xufVxuXG5DbGFzc2ljLnByb3RvdHlwZS5jb252ZXJ0ID0gY0NvbnZlcnQ7XG5DbGFzc2ljLnByb3RvdHlwZS5yZXZlcnQgPSBjUmV2ZXJ0O1xuQ2xhc3NpYy5wcm90b3R5cGUucmVkdWNlID0gY1JlZHVjZTtcbkNsYXNzaWMucHJvdG90eXBlLm11bFRvID0gY011bFRvO1xuQ2xhc3NpYy5wcm90b3R5cGUuc3FyVG8gPSBjU3FyVG87XG5cbi8vIChwcm90ZWN0ZWQpIHJldHVybiBcIi0xL3RoaXMgJSAyXkRCXCI7IHVzZWZ1bCBmb3IgTW9udC4gcmVkdWN0aW9uXG4vLyBqdXN0aWZpY2F0aW9uOlxuLy8gICAgICAgICB4eSA9PSAxIChtb2QgbSlcbi8vICAgICAgICAgeHkgPSAgMStrbVxuLy8gICB4eSgyLXh5KSA9ICgxK2ttKSgxLWttKVxuLy8geFt5KDIteHkpXSA9IDEta14ybV4yXG4vLyB4W3koMi14eSldID09IDEgKG1vZCBtXjIpXG4vLyBpZiB5IGlzIDEveCBtb2QgbSwgdGhlbiB5KDIteHkpIGlzIDEveCBtb2QgbV4yXG4vLyBzaG91bGQgcmVkdWNlIHggYW5kIHkoMi14eSkgYnkgbV4yIGF0IGVhY2ggc3RlcCB0byBrZWVwIHNpemUgYm91bmRlZC5cbi8vIEpTIG11bHRpcGx5IFwib3ZlcmZsb3dzXCIgZGlmZmVyZW50bHkgZnJvbSBDL0MrKywgc28gY2FyZSBpcyBuZWVkZWQgaGVyZS5cblxuZnVuY3Rpb24gYm5wSW52RGlnaXQoKSB7XG4gIGlmICh0aGlzLnQgPCAxKSByZXR1cm4gMDtcbiAgdmFyIHggPSB0aGlzWzBdO1xuICBpZiAoKHggJiAxKSA9PSAwKSByZXR1cm4gMDtcbiAgdmFyIHkgPSB4ICYgMzsgLy8geSA9PSAxL3ggbW9kIDJeMlxuICB5ID0gKHkgKiAoMiAtICh4ICYgMHhmKSAqIHkpKSAmIDB4ZjsgLy8geSA9PSAxL3ggbW9kIDJeNFxuICB5ID0gKHkgKiAoMiAtICh4ICYgMHhmZikgKiB5KSkgJiAweGZmOyAvLyB5ID09IDEveCBtb2QgMl44XG4gIHkgPSAoeSAqICgyIC0gKCgoeCAmIDB4ZmZmZikgKiB5KSAmIDB4ZmZmZikpKSAmIDB4ZmZmZjsgLy8geSA9PSAxL3ggbW9kIDJeMTZcbiAgLy8gbGFzdCBzdGVwIC0gY2FsY3VsYXRlIGludmVyc2UgbW9kIERWIGRpcmVjdGx5O1xuICAvLyBhc3N1bWVzIDE2IDwgREIgPD0gMzIgYW5kIGFzc3VtZXMgYWJpbGl0eSB0byBoYW5kbGUgNDgtYml0IGludHNcbiAgeSA9ICh5ICogKDIgLSB4ICogeSAlIHRoaXMuRFYpKSAlIHRoaXMuRFY7IC8vIHkgPT0gMS94IG1vZCAyXmRiaXRzXG4gIC8vIHdlIHJlYWxseSB3YW50IHRoZSBuZWdhdGl2ZSBpbnZlcnNlLCBhbmQgLURWIDwgeSA8IERWXG4gIHJldHVybiAoeSA+IDApID8gdGhpcy5EViAtIHkgOiAteTtcbn1cblxuLy8gTW9udGdvbWVyeSByZWR1Y3Rpb25cblxuZnVuY3Rpb24gTW9udGdvbWVyeShtKSB7XG4gIHRoaXMubSA9IG07XG4gIHRoaXMubXAgPSBtLmludkRpZ2l0KCk7XG4gIHRoaXMubXBsID0gdGhpcy5tcCAmIDB4N2ZmZjtcbiAgdGhpcy5tcGggPSB0aGlzLm1wID4+IDE1O1xuICB0aGlzLnVtID0gKDEgPDwgKG0uREIgLSAxNSkpIC0gMTtcbiAgdGhpcy5tdDIgPSAyICogbS50O1xufVxuXG4vLyB4UiBtb2QgbVxuXG5mdW5jdGlvbiBtb250Q29udmVydCh4KSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHguYWJzKCkuZGxTaGlmdFRvKHRoaXMubS50LCByKTtcbiAgci5kaXZSZW1Ubyh0aGlzLm0sIG51bGwsIHIpO1xuICBpZiAoeC5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgdGhpcy5tLnN1YlRvKHIsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8geC9SIG1vZCBtXG5cbmZ1bmN0aW9uIG1vbnRSZXZlcnQoeCkge1xuICB2YXIgciA9IG5iaSgpO1xuICB4LmNvcHlUbyhyKTtcbiAgdGhpcy5yZWR1Y2Uocik7XG4gIHJldHVybiByO1xufVxuXG4vLyB4ID0geC9SIG1vZCBtIChIQUMgMTQuMzIpXG5cbmZ1bmN0aW9uIG1vbnRSZWR1Y2UoeCkge1xuICB3aGlsZSAoeC50IDw9IHRoaXMubXQyKSAvLyBwYWQgeCBzbyBhbSBoYXMgZW5vdWdoIHJvb20gbGF0ZXJcbiAgICB4W3gudCsrXSA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tLnQ7ICsraSkge1xuICAgIC8vIGZhc3RlciB3YXkgb2YgY2FsY3VsYXRpbmcgdTAgPSB4W2ldKm1wIG1vZCBEVlxuICAgIHZhciBqID0geFtpXSAmIDB4N2ZmZjtcbiAgICB2YXIgdTAgPSAoaiAqIHRoaXMubXBsICsgKCgoaiAqIHRoaXMubXBoICsgKHhbaV0gPj4gMTUpICogdGhpcy5tcGwpICYgdGhpcy51bSkgPDwgMTUpKSAmIHguRE07XG4gICAgLy8gdXNlIGFtIHRvIGNvbWJpbmUgdGhlIG11bHRpcGx5LXNoaWZ0LWFkZCBpbnRvIG9uZSBjYWxsXG4gICAgaiA9IGkgKyB0aGlzLm0udDtcbiAgICB4W2pdICs9IHRoaXMubS5hbSgwLCB1MCwgeCwgaSwgMCwgdGhpcy5tLnQpO1xuICAgIC8vIHByb3BhZ2F0ZSBjYXJyeVxuICAgIHdoaWxlICh4W2pdID49IHguRFYpIHtcbiAgICAgIHhbal0gLT0geC5EVjtcbiAgICAgIHhbKytqXSsrO1xuICAgIH1cbiAgfVxuICB4LmNsYW1wKCk7XG4gIHguZHJTaGlmdFRvKHRoaXMubS50LCB4KTtcbiAgaWYgKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0sIHgpO1xufVxuXG4vLyByID0gXCJ4XjIvUiBtb2QgbVwiOyB4ICE9IHJcblxuZnVuY3Rpb24gbW9udFNxclRvKHgsIHIpIHtcbiAgeC5zcXVhcmVUbyhyKTtcbiAgdGhpcy5yZWR1Y2Uocik7XG59XG5cbi8vIHIgPSBcInh5L1IgbW9kIG1cIjsgeCx5ICE9IHJcblxuZnVuY3Rpb24gbW9udE11bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuTW9udGdvbWVyeS5wcm90b3R5cGUuY29udmVydCA9IG1vbnRDb252ZXJ0O1xuTW9udGdvbWVyeS5wcm90b3R5cGUucmV2ZXJ0ID0gbW9udFJldmVydDtcbk1vbnRnb21lcnkucHJvdG90eXBlLnJlZHVjZSA9IG1vbnRSZWR1Y2U7XG5Nb250Z29tZXJ5LnByb3RvdHlwZS5tdWxUbyA9IG1vbnRNdWxUbztcbk1vbnRnb21lcnkucHJvdG90eXBlLnNxclRvID0gbW9udFNxclRvO1xuXG4vLyAocHJvdGVjdGVkKSB0cnVlIGlmZiB0aGlzIGlzIGV2ZW5cblxuZnVuY3Rpb24gYm5wSXNFdmVuKCkge1xuICByZXR1cm4gKCh0aGlzLnQgPiAwKSA/ICh0aGlzWzBdICYgMSkgOiB0aGlzLnMpID09IDA7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXNeZSwgZSA8IDJeMzIsIGRvaW5nIHNxciBhbmQgbXVsIHdpdGggXCJyXCIgKEhBQyAxNC43OSlcblxuZnVuY3Rpb24gYm5wRXhwKGUsIHopIHtcbiAgaWYgKGUgPiAweGZmZmZmZmZmIHx8IGUgPCAxKSByZXR1cm4gQmlnSW50ZWdlci5PTkU7XG4gIHZhciByID0gbmJpKCksXG4gICAgcjIgPSBuYmkoKSxcbiAgICBnID0gei5jb252ZXJ0KHRoaXMpLFxuICAgIGkgPSBuYml0cyhlKSAtIDE7XG4gIGcuY29weVRvKHIpO1xuICB3aGlsZSAoLS1pID49IDApIHtcbiAgICB6LnNxclRvKHIsIHIyKTtcbiAgICBpZiAoKGUgJiAoMSA8PCBpKSkgPiAwKSB6Lm11bFRvKHIyLCBnLCByKTtcbiAgICBlbHNlIHtcbiAgICAgIHZhciB0ID0gcjtcbiAgICAgIHIgPSByMjtcbiAgICAgIHIyID0gdDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHoucmV2ZXJ0KHIpO1xufVxuXG4vLyAocHVibGljKSB0aGlzXmUgJSBtLCAwIDw9IGUgPCAyXjMyXG5cbmZ1bmN0aW9uIGJuTW9kUG93SW50KGUsIG0pIHtcbiAgdmFyIHo7XG4gIGlmIChlIDwgMjU2IHx8IG0uaXNFdmVuKCkpIHogPSBuZXcgQ2xhc3NpYyhtKTtcbiAgZWxzZSB6ID0gbmV3IE1vbnRnb21lcnkobSk7XG4gIHJldHVybiB0aGlzLmV4cChlLCB6KTtcbn1cblxuLy8gcHJvdGVjdGVkXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jb3B5VG8gPSBibnBDb3B5VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tSW50ID0gYm5wRnJvbUludDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21TdHJpbmcgPSBibnBGcm9tU3RyaW5nO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuY2xhbXAgPSBibnBDbGFtcDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRsU2hpZnRUbyA9IGJucERMU2hpZnRUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRyU2hpZnRUbyA9IGJucERSU2hpZnRUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmxTaGlmdFRvID0gYm5wTFNoaWZ0VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5yU2hpZnRUbyA9IGJucFJTaGlmdFRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc3ViVG8gPSBibnBTdWJUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VG8gPSBibnBNdWx0aXBseVRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc3F1YXJlVG8gPSBibnBTcXVhcmVUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRpdlJlbVRvID0gYm5wRGl2UmVtVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5pbnZEaWdpdCA9IGJucEludkRpZ2l0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuaXNFdmVuID0gYm5wSXNFdmVuO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZXhwID0gYm5wRXhwO1xuXG4vLyBwdWJsaWNcbkJpZ0ludGVnZXIucHJvdG90eXBlLnRvU3RyaW5nID0gYm5Ub1N0cmluZztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm5lZ2F0ZSA9IGJuTmVnYXRlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYWJzID0gYm5BYnM7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jb21wYXJlVG8gPSBibkNvbXBhcmVUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmJpdExlbmd0aCA9IGJuQml0TGVuZ3RoO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubW9kID0gYm5Nb2Q7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RQb3dJbnQgPSBibk1vZFBvd0ludDtcblxuLy8gXCJjb25zdGFudHNcIlxuQmlnSW50ZWdlci5aRVJPID0gbmJ2KDApO1xuQmlnSW50ZWdlci5PTkUgPSBuYnYoMSk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmlnSW50ZWdlcjtcblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuLypcbiAqIENvcHlyaWdodCAoYykgMjAwMy0yMDA1ICBUb20gV3UgKHRqd0Bjcy5TdGFuZm9yZC5FRFUpIFxuICogQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkhcbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmdcbiAqIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuICogXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4gKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4gKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG9cbiAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0b1xuICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlXG4gKiBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUy1JU1wiIEFORCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBcbiAqIEVYUFJFU1MsIElNUExJRUQgT1IgT1RIRVJXSVNFLCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkgXG4gKiBXQVJSQU5UWSBPRiBNRVJDSEFOVEFCSUxJVFkgT1IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBcbiAqXG4gKiBJTiBOTyBFVkVOVCBTSEFMTCBUT00gV1UgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5DSURFTlRBTCxcbiAqIElORElSRUNUIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPRiBBTlkgS0lORCwgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUlxuICogUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBPUiBOT1QgQURWSVNFRCBPRlxuICogVEhFIFBPU1NJQklMSVRZIE9GIERBTUFHRSwgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBBUklTSU5HIE9VVFxuICogT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cbiAqXG4gKiBJbiBhZGRpdGlvbiwgdGhlIGZvbGxvd2luZyBjb25kaXRpb24gYXBwbGllczpcbiAqXG4gKiBBbGwgcmVkaXN0cmlidXRpb25zIG11c3QgcmV0YWluIGFuIGludGFjdCBjb3B5IG9mIHRoaXMgY29weXJpZ2h0IG5vdGljZVxuICogYW5kIGRpc2NsYWltZXIuXG4gKi9cblxuXG4vLyBFeHRlbmRlZCBKYXZhU2NyaXB0IEJOIGZ1bmN0aW9ucywgcmVxdWlyZWQgZm9yIFJTQSBwcml2YXRlIG9wcy5cblxuLy8gVmVyc2lvbiAxLjE6IG5ldyBCaWdJbnRlZ2VyKFwiMFwiLCAxMCkgcmV0dXJucyBcInByb3BlclwiIHplcm9cbi8vIFZlcnNpb24gMS4yOiBzcXVhcmUoKSBBUEksIGlzUHJvYmFibGVQcmltZSBmaXhcblxuLy8gKHB1YmxpYylcbmZ1bmN0aW9uIGJuQ2xvbmUoKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuY29weVRvKHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGludGVnZXJcblxuZnVuY3Rpb24gYm5JbnRWYWx1ZSgpIHtcbiAgaWYgKHRoaXMucyA8IDApIHtcbiAgICBpZiAodGhpcy50ID09IDEpIHJldHVybiB0aGlzWzBdIC0gdGhpcy5EVjtcbiAgICBlbHNlIGlmICh0aGlzLnQgPT0gMCkgcmV0dXJuIC0xO1xuICB9IGVsc2UgaWYgKHRoaXMudCA9PSAxKSByZXR1cm4gdGhpc1swXTtcbiAgZWxzZSBpZiAodGhpcy50ID09IDApIHJldHVybiAwO1xuICAvLyBhc3N1bWVzIDE2IDwgREIgPCAzMlxuICByZXR1cm4gKCh0aGlzWzFdICYgKCgxIDw8ICgzMiAtIHRoaXMuREIpKSAtIDEpKSA8PCB0aGlzLkRCKSB8IHRoaXNbMF07XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBieXRlXG5cbmZ1bmN0aW9uIGJuQnl0ZVZhbHVlKCkge1xuICByZXR1cm4gKHRoaXMudCA9PSAwKSA/IHRoaXMucyA6ICh0aGlzWzBdIDw8IDI0KSA+PiAyNDtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIHNob3J0IChhc3N1bWVzIERCPj0xNilcblxuZnVuY3Rpb24gYm5TaG9ydFZhbHVlKCkge1xuICByZXR1cm4gKHRoaXMudCA9PSAwKSA/IHRoaXMucyA6ICh0aGlzWzBdIDw8IDE2KSA+PiAxNjtcbn1cblxuLy8gKHByb3RlY3RlZCkgcmV0dXJuIHggcy50LiByXnggPCBEVlxuXG5mdW5jdGlvbiBibnBDaHVua1NpemUocikge1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLkxOMiAqIHRoaXMuREIgLyBNYXRoLmxvZyhyKSk7XG59XG5cbi8vIChwdWJsaWMpIDAgaWYgdGhpcyA9PSAwLCAxIGlmIHRoaXMgPiAwXG5cbmZ1bmN0aW9uIGJuU2lnTnVtKCkge1xuICBpZiAodGhpcy5zIDwgMCkgcmV0dXJuIC0xO1xuICBlbHNlIGlmICh0aGlzLnQgPD0gMCB8fCAodGhpcy50ID09IDEgJiYgdGhpc1swXSA8PSAwKSkgcmV0dXJuIDA7XG4gIGVsc2UgcmV0dXJuIDE7XG59XG5cbi8vIChwcm90ZWN0ZWQpIGNvbnZlcnQgdG8gcmFkaXggc3RyaW5nXG5cbmZ1bmN0aW9uIGJucFRvUmFkaXgoYikge1xuICBpZiAoYiA9PSBudWxsKSBiID0gMTA7XG4gIGlmICh0aGlzLnNpZ251bSgpID09IDAgfHwgYiA8IDIgfHwgYiA+IDM2KSByZXR1cm4gXCIwXCI7XG4gIHZhciBjcyA9IHRoaXMuY2h1bmtTaXplKGIpO1xuICB2YXIgYSA9IE1hdGgucG93KGIsIGNzKTtcbiAgdmFyIGQgPSBuYnYoYSksXG4gICAgeSA9IG5iaSgpLFxuICAgIHogPSBuYmkoKSxcbiAgICByID0gXCJcIjtcbiAgdGhpcy5kaXZSZW1UbyhkLCB5LCB6KTtcbiAgd2hpbGUgKHkuc2lnbnVtKCkgPiAwKSB7XG4gICAgciA9IChhICsgei5pbnRWYWx1ZSgpKS50b1N0cmluZyhiKS5zdWJzdHIoMSkgKyByO1xuICAgIHkuZGl2UmVtVG8oZCwgeSwgeik7XG4gIH1cbiAgcmV0dXJuIHouaW50VmFsdWUoKS50b1N0cmluZyhiKSArIHI7XG59XG5cbi8vIChwcm90ZWN0ZWQpIGNvbnZlcnQgZnJvbSByYWRpeCBzdHJpbmdcblxuZnVuY3Rpb24gYm5wRnJvbVJhZGl4KHMsIGIpIHtcbiAgdGhpcy5mcm9tSW50KDApO1xuICBpZiAoYiA9PSBudWxsKSBiID0gMTA7XG4gIHZhciBjcyA9IHRoaXMuY2h1bmtTaXplKGIpO1xuICB2YXIgZCA9IE1hdGgucG93KGIsIGNzKSxcbiAgICBtaSA9IGZhbHNlLFxuICAgIGogPSAwLFxuICAgIHcgPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHMubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgeCA9IGludEF0KHMsIGkpO1xuICAgIGlmICh4IDwgMCkge1xuICAgICAgaWYgKHMuY2hhckF0KGkpID09IFwiLVwiICYmIHRoaXMuc2lnbnVtKCkgPT0gMCkgbWkgPSB0cnVlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHcgPSBiICogdyArIHg7XG4gICAgaWYgKCsraiA+PSBjcykge1xuICAgICAgdGhpcy5kTXVsdGlwbHkoZCk7XG4gICAgICB0aGlzLmRBZGRPZmZzZXQodywgMCk7XG4gICAgICBqID0gMDtcbiAgICAgIHcgPSAwO1xuICAgIH1cbiAgfVxuICBpZiAoaiA+IDApIHtcbiAgICB0aGlzLmRNdWx0aXBseShNYXRoLnBvdyhiLCBqKSk7XG4gICAgdGhpcy5kQWRkT2Zmc2V0KHcsIDApO1xuICB9XG4gIGlmIChtaSkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsIHRoaXMpO1xufVxuXG4vLyAocHJvdGVjdGVkKSBhbHRlcm5hdGUgY29uc3RydWN0b3JcblxuZnVuY3Rpb24gYm5wRnJvbU51bWJlcihhLCBiLCBjKSB7XG4gIGlmIChcIm51bWJlclwiID09IHR5cGVvZiBiKSB7XG4gICAgLy8gbmV3IEJpZ0ludGVnZXIoaW50LGludCxSTkcpXG4gICAgaWYgKGEgPCAyKSB0aGlzLmZyb21JbnQoMSk7XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLmZyb21OdW1iZXIoYSwgYyk7XG4gICAgICBpZiAoIXRoaXMudGVzdEJpdChhIC0gMSkpIC8vIGZvcmNlIE1TQiBzZXRcbiAgICAgICAgdGhpcy5iaXR3aXNlVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGEgLSAxKSwgb3Bfb3IsIHRoaXMpO1xuICAgICAgaWYgKHRoaXMuaXNFdmVuKCkpIHRoaXMuZEFkZE9mZnNldCgxLCAwKTsgLy8gZm9yY2Ugb2RkXG4gICAgICB3aGlsZSAoIXRoaXMuaXNQcm9iYWJsZVByaW1lKGIpKSB7XG4gICAgICAgIHRoaXMuZEFkZE9mZnNldCgyLCAwKTtcbiAgICAgICAgaWYgKHRoaXMuYml0TGVuZ3RoKCkgPiBhKSB0aGlzLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhIC0gMSksIHRoaXMpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBuZXcgQmlnSW50ZWdlcihpbnQsUk5HKVxuICAgIHZhciB4ID0gbmV3IEFycmF5KCksXG4gICAgICB0ID0gYSAmIDc7XG4gICAgeC5sZW5ndGggPSAoYSA+PiAzKSArIDE7XG4gICAgYi5uZXh0Qnl0ZXMoeCk7XG4gICAgaWYgKHQgPiAwKSB4WzBdICY9ICgoMSA8PCB0KSAtIDEpO1xuICAgIGVsc2UgeFswXSA9IDA7XG4gICAgdGhpcy5mcm9tU3RyaW5nKHgsIDI1Nik7XG4gIH1cbn1cblxuLy8gKHB1YmxpYykgY29udmVydCB0byBiaWdlbmRpYW4gYnl0ZSBhcnJheVxuXG5mdW5jdGlvbiBiblRvQnl0ZUFycmF5KCkge1xuICB2YXIgaSA9IHRoaXMudCxcbiAgICByID0gbmV3IEFycmF5KCk7XG4gIHJbMF0gPSB0aGlzLnM7XG4gIHZhciBwID0gdGhpcy5EQiAtIChpICogdGhpcy5EQikgJSA4LFxuICAgIGQsIGsgPSAwO1xuICBpZiAoaS0tID4gMCkge1xuICAgIGlmIChwIDwgdGhpcy5EQiAmJiAoZCA9IHRoaXNbaV0gPj4gcCkgIT0gKHRoaXMucyAmIHRoaXMuRE0pID4+IHApXG4gICAgICByW2srK10gPSBkIHwgKHRoaXMucyA8PCAodGhpcy5EQiAtIHApKTtcbiAgICB3aGlsZSAoaSA+PSAwKSB7XG4gICAgICBpZiAocCA8IDgpIHtcbiAgICAgICAgZCA9ICh0aGlzW2ldICYgKCgxIDw8IHApIC0gMSkpIDw8ICg4IC0gcCk7XG4gICAgICAgIGQgfD0gdGhpc1stLWldID4+IChwICs9IHRoaXMuREIgLSA4KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGQgPSAodGhpc1tpXSA+PiAocCAtPSA4KSkgJiAweGZmO1xuICAgICAgICBpZiAocCA8PSAwKSB7XG4gICAgICAgICAgcCArPSB0aGlzLkRCO1xuICAgICAgICAgIC0taTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy9pZigoZCYweDgwKSAhPSAwKSBkIHw9IC0yNTY7XG4gICAgICAvL2lmKGsgPT0gMCAmJiAodGhpcy5zJjB4ODApICE9IChkJjB4ODApKSArK2s7XG4gICAgICBpZiAoayA+IDAgfHwgZCAhPSB0aGlzLnMpIHJbaysrXSA9IGQ7XG4gICAgfVxuICB9XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBibkVxdWFscyhhKSB7XG4gIHJldHVybiAodGhpcy5jb21wYXJlVG8oYSkgPT0gMCk7XG59XG5cbmZ1bmN0aW9uIGJuTWluKGEpIHtcbiAgcmV0dXJuICh0aGlzLmNvbXBhcmVUbyhhKSA8IDApID8gdGhpcyA6IGE7XG59XG5cbmZ1bmN0aW9uIGJuTWF4KGEpIHtcbiAgcmV0dXJuICh0aGlzLmNvbXBhcmVUbyhhKSA+IDApID8gdGhpcyA6IGE7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIG9wIGEgKGJpdHdpc2UpXG5cbmZ1bmN0aW9uIGJucEJpdHdpc2VUbyhhLCBvcCwgcikge1xuICB2YXIgaSwgZiwgbSA9IE1hdGgubWluKGEudCwgdGhpcy50KTtcbiAgZm9yIChpID0gMDsgaSA8IG07ICsraSkgcltpXSA9IG9wKHRoaXNbaV0sIGFbaV0pO1xuICBpZiAoYS50IDwgdGhpcy50KSB7XG4gICAgZiA9IGEucyAmIHRoaXMuRE07XG4gICAgZm9yIChpID0gbTsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gb3AodGhpc1tpXSwgZik7XG4gICAgci50ID0gdGhpcy50O1xuICB9IGVsc2Uge1xuICAgIGYgPSB0aGlzLnMgJiB0aGlzLkRNO1xuICAgIGZvciAoaSA9IG07IGkgPCBhLnQ7ICsraSkgcltpXSA9IG9wKGYsIGFbaV0pO1xuICAgIHIudCA9IGEudDtcbiAgfVxuICByLnMgPSBvcCh0aGlzLnMsIGEucyk7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAmIGFcblxuZnVuY3Rpb24gb3BfYW5kKHgsIHkpIHtcbiAgcmV0dXJuIHggJiB5O1xufVxuXG5mdW5jdGlvbiBibkFuZChhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYml0d2lzZVRvKGEsIG9wX2FuZCwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIHwgYVxuXG5mdW5jdGlvbiBvcF9vcih4LCB5KSB7XG4gIHJldHVybiB4IHwgeTtcbn1cblxuZnVuY3Rpb24gYm5PcihhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYml0d2lzZVRvKGEsIG9wX29yLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgXiBhXG5cbmZ1bmN0aW9uIG9wX3hvcih4LCB5KSB7XG4gIHJldHVybiB4IF4geTtcbn1cblxuZnVuY3Rpb24gYm5Yb3IoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmJpdHdpc2VUbyhhLCBvcF94b3IsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAmIH5hXG5cbmZ1bmN0aW9uIG9wX2FuZG5vdCh4LCB5KSB7XG4gIHJldHVybiB4ICYgfnk7XG59XG5cbmZ1bmN0aW9uIGJuQW5kTm90KGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3BfYW5kbm90LCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIH50aGlzXG5cbmZ1bmN0aW9uIGJuTm90KCkge1xuICB2YXIgciA9IG5iaSgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gdGhpcy5ETSAmIH50aGlzW2ldO1xuICByLnQgPSB0aGlzLnQ7XG4gIHIucyA9IH50aGlzLnM7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIDw8IG5cblxuZnVuY3Rpb24gYm5TaGlmdExlZnQobikge1xuICB2YXIgciA9IG5iaSgpO1xuICBpZiAobiA8IDApIHRoaXMuclNoaWZ0VG8oLW4sIHIpO1xuICBlbHNlIHRoaXMubFNoaWZ0VG8obiwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzID4+IG5cblxuZnVuY3Rpb24gYm5TaGlmdFJpZ2h0KG4pIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgaWYgKG4gPCAwKSB0aGlzLmxTaGlmdFRvKC1uLCByKTtcbiAgZWxzZSB0aGlzLnJTaGlmdFRvKG4sIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gcmV0dXJuIGluZGV4IG9mIGxvd2VzdCAxLWJpdCBpbiB4LCB4IDwgMl4zMVxuXG5mdW5jdGlvbiBsYml0KHgpIHtcbiAgaWYgKHggPT0gMCkgcmV0dXJuIC0xO1xuICB2YXIgciA9IDA7XG4gIGlmICgoeCAmIDB4ZmZmZikgPT0gMCkge1xuICAgIHggPj49IDE2O1xuICAgIHIgKz0gMTY7XG4gIH1cbiAgaWYgKCh4ICYgMHhmZikgPT0gMCkge1xuICAgIHggPj49IDg7XG4gICAgciArPSA4O1xuICB9XG4gIGlmICgoeCAmIDB4ZikgPT0gMCkge1xuICAgIHggPj49IDQ7XG4gICAgciArPSA0O1xuICB9XG4gIGlmICgoeCAmIDMpID09IDApIHtcbiAgICB4ID4+PSAyO1xuICAgIHIgKz0gMjtcbiAgfVxuICBpZiAoKHggJiAxKSA9PSAwKSsrcjtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHJldHVybnMgaW5kZXggb2YgbG93ZXN0IDEtYml0IChvciAtMSBpZiBub25lKVxuXG5mdW5jdGlvbiBibkdldExvd2VzdFNldEJpdCgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnQ7ICsraSlcbiAgICBpZiAodGhpc1tpXSAhPSAwKSByZXR1cm4gaSAqIHRoaXMuREIgKyBsYml0KHRoaXNbaV0pO1xuICBpZiAodGhpcy5zIDwgMCkgcmV0dXJuIHRoaXMudCAqIHRoaXMuREI7XG4gIHJldHVybiAtMTtcbn1cblxuLy8gcmV0dXJuIG51bWJlciBvZiAxIGJpdHMgaW4geFxuXG5mdW5jdGlvbiBjYml0KHgpIHtcbiAgdmFyIHIgPSAwO1xuICB3aGlsZSAoeCAhPSAwKSB7XG4gICAgeCAmPSB4IC0gMTtcbiAgICArK3I7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiBudW1iZXIgb2Ygc2V0IGJpdHNcblxuZnVuY3Rpb24gYm5CaXRDb3VudCgpIHtcbiAgdmFyIHIgPSAwLFxuICAgIHggPSB0aGlzLnMgJiB0aGlzLkRNO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByICs9IGNiaXQodGhpc1tpXSBeIHgpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdHJ1ZSBpZmYgbnRoIGJpdCBpcyBzZXRcblxuZnVuY3Rpb24gYm5UZXN0Qml0KG4pIHtcbiAgdmFyIGogPSBNYXRoLmZsb29yKG4gLyB0aGlzLkRCKTtcbiAgaWYgKGogPj0gdGhpcy50KSByZXR1cm4gKHRoaXMucyAhPSAwKTtcbiAgcmV0dXJuICgodGhpc1tqXSAmICgxIDw8IChuICUgdGhpcy5EQikpKSAhPSAwKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyBvcCAoMTw8bilcblxuZnVuY3Rpb24gYm5wQ2hhbmdlQml0KG4sIG9wKSB7XG4gIHZhciByID0gQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KG4pO1xuICB0aGlzLmJpdHdpc2VUbyhyLCBvcCwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIHwgKDE8PG4pXG5cbmZ1bmN0aW9uIGJuU2V0Qml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX29yKTtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAmIH4oMTw8bilcblxuZnVuY3Rpb24gYm5DbGVhckJpdChuKSB7XG4gIHJldHVybiB0aGlzLmNoYW5nZUJpdChuLCBvcF9hbmRub3QpO1xufVxuXG4vLyAocHVibGljKSB0aGlzIF4gKDE8PG4pXG5cbmZ1bmN0aW9uIGJuRmxpcEJpdChuKSB7XG4gIHJldHVybiB0aGlzLmNoYW5nZUJpdChuLCBvcF94b3IpO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyArIGFcblxuZnVuY3Rpb24gYm5wQWRkVG8oYSwgcikge1xuICB2YXIgaSA9IDAsXG4gICAgYyA9IDAsXG4gICAgbSA9IE1hdGgubWluKGEudCwgdGhpcy50KTtcbiAgd2hpbGUgKGkgPCBtKSB7XG4gICAgYyArPSB0aGlzW2ldICsgYVtpXTtcbiAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICBjID4+PSB0aGlzLkRCO1xuICB9XG4gIGlmIChhLnQgPCB0aGlzLnQpIHtcbiAgICBjICs9IGEucztcbiAgICB3aGlsZSAoaSA8IHRoaXMudCkge1xuICAgICAgYyArPSB0aGlzW2ldO1xuICAgICAgcltpKytdID0gYyAmIHRoaXMuRE07XG4gICAgICBjID4+PSB0aGlzLkRCO1xuICAgIH1cbiAgICBjICs9IHRoaXMucztcbiAgfSBlbHNlIHtcbiAgICBjICs9IHRoaXMucztcbiAgICB3aGlsZSAoaSA8IGEudCkge1xuICAgICAgYyArPSBhW2ldO1xuICAgICAgcltpKytdID0gYyAmIHRoaXMuRE07XG4gICAgICBjID4+PSB0aGlzLkRCO1xuICAgIH1cbiAgICBjICs9IGEucztcbiAgfVxuICByLnMgPSAoYyA8IDApID8gLTEgOiAwO1xuICBpZiAoYyA+IDApIHJbaSsrXSA9IGM7XG4gIGVsc2UgaWYgKGMgPCAtMSkgcltpKytdID0gdGhpcy5EViArIGM7XG4gIHIudCA9IGk7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyArIGFcblxuZnVuY3Rpb24gYm5BZGQoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmFkZFRvKGEsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAtIGFcblxuZnVuY3Rpb24gYm5TdWJ0cmFjdChhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuc3ViVG8oYSwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzICogYVxuXG5mdW5jdGlvbiBibk11bHRpcGx5KGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5tdWx0aXBseVRvKGEsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpc14yXG5cbmZ1bmN0aW9uIGJuU3F1YXJlKCkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLnNxdWFyZVRvKHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAvIGFcblxuZnVuY3Rpb24gYm5EaXZpZGUoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmRpdlJlbVRvKGEsIHIsIG51bGwpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAlIGFcblxuZnVuY3Rpb24gYm5SZW1haW5kZXIoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmRpdlJlbVRvKGEsIG51bGwsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgW3RoaXMvYSx0aGlzJWFdXG5cbmZ1bmN0aW9uIGJuRGl2aWRlQW5kUmVtYWluZGVyKGEpIHtcbiAgdmFyIHEgPSBuYmkoKSxcbiAgICByID0gbmJpKCk7XG4gIHRoaXMuZGl2UmVtVG8oYSwgcSwgcik7XG4gIHJldHVybiBuZXcgQXJyYXkocSwgcik7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgKj0gbiwgdGhpcyA+PSAwLCAxIDwgbiA8IERWXG5cbmZ1bmN0aW9uIGJucERNdWx0aXBseShuKSB7XG4gIHRoaXNbdGhpcy50XSA9IHRoaXMuYW0oMCwgbiAtIDEsIHRoaXMsIDAsIDAsIHRoaXMudCk7XG4gICsrdGhpcy50O1xuICB0aGlzLmNsYW1wKCk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgKz0gbiA8PCB3IHdvcmRzLCB0aGlzID49IDBcblxuZnVuY3Rpb24gYm5wREFkZE9mZnNldChuLCB3KSB7XG4gIGlmIChuID09IDApIHJldHVybjtcbiAgd2hpbGUgKHRoaXMudCA8PSB3KSB0aGlzW3RoaXMudCsrXSA9IDA7XG4gIHRoaXNbd10gKz0gbjtcbiAgd2hpbGUgKHRoaXNbd10gPj0gdGhpcy5EVikge1xuICAgIHRoaXNbd10gLT0gdGhpcy5EVjtcbiAgICBpZiAoKyt3ID49IHRoaXMudCkgdGhpc1t0aGlzLnQrK10gPSAwO1xuICAgICsrdGhpc1t3XTtcbiAgfVxufVxuXG4vLyBBIFwibnVsbFwiIHJlZHVjZXJcblxuZnVuY3Rpb24gTnVsbEV4cCgpIHt9XG5cbmZ1bmN0aW9uIG5Ob3AoeCkge1xuICByZXR1cm4geDtcbn1cblxuZnVuY3Rpb24gbk11bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpO1xufVxuXG5mdW5jdGlvbiBuU3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpO1xufVxuXG5OdWxsRXhwLnByb3RvdHlwZS5jb252ZXJ0ID0gbk5vcDtcbk51bGxFeHAucHJvdG90eXBlLnJldmVydCA9IG5Ob3A7XG5OdWxsRXhwLnByb3RvdHlwZS5tdWxUbyA9IG5NdWxUbztcbk51bGxFeHAucHJvdG90eXBlLnNxclRvID0gblNxclRvO1xuXG4vLyAocHVibGljKSB0aGlzXmVcblxuZnVuY3Rpb24gYm5Qb3coZSkge1xuICByZXR1cm4gdGhpcy5leHAoZSwgbmV3IE51bGxFeHAoKSk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSBsb3dlciBuIHdvcmRzIG9mIFwidGhpcyAqIGFcIiwgYS50IDw9IG5cbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cblxuZnVuY3Rpb24gYm5wTXVsdGlwbHlMb3dlclRvKGEsIG4sIHIpIHtcbiAgdmFyIGkgPSBNYXRoLm1pbih0aGlzLnQgKyBhLnQsIG4pO1xuICByLnMgPSAwOyAvLyBhc3N1bWVzIGEsdGhpcyA+PSAwXG4gIHIudCA9IGk7XG4gIHdoaWxlIChpID4gMCkgclstLWldID0gMDtcbiAgdmFyIGo7XG4gIGZvciAoaiA9IHIudCAtIHRoaXMudDsgaSA8IGo7ICsraSkgcltpICsgdGhpcy50XSA9IHRoaXMuYW0oMCwgYVtpXSwgciwgaSwgMCwgdGhpcy50KTtcbiAgZm9yIChqID0gTWF0aC5taW4oYS50LCBuKTsgaSA8IGo7ICsraSkgdGhpcy5hbSgwLCBhW2ldLCByLCBpLCAwLCBuIC0gaSk7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IFwidGhpcyAqIGFcIiB3aXRob3V0IGxvd2VyIG4gd29yZHMsIG4gPiAwXG4vLyBcInRoaXNcIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuXG5cbmZ1bmN0aW9uIGJucE11bHRpcGx5VXBwZXJUbyhhLCBuLCByKSB7XG4gIC0tbjtcbiAgdmFyIGkgPSByLnQgPSB0aGlzLnQgKyBhLnQgLSBuO1xuICByLnMgPSAwOyAvLyBhc3N1bWVzIGEsdGhpcyA+PSAwXG4gIHdoaWxlICgtLWkgPj0gMCkgcltpXSA9IDA7XG4gIGZvciAoaSA9IE1hdGgubWF4KG4gLSB0aGlzLnQsIDApOyBpIDwgYS50OyArK2kpXG4gICAgclt0aGlzLnQgKyBpIC0gbl0gPSB0aGlzLmFtKG4gLSBpLCBhW2ldLCByLCAwLCAwLCB0aGlzLnQgKyBpIC0gbik7XG4gIHIuY2xhbXAoKTtcbiAgci5kclNoaWZ0VG8oMSwgcik7XG59XG5cbi8vIEJhcnJldHQgbW9kdWxhciByZWR1Y3Rpb25cblxuZnVuY3Rpb24gQmFycmV0dChtKSB7XG4gIC8vIHNldHVwIEJhcnJldHRcbiAgdGhpcy5yMiA9IG5iaSgpO1xuICB0aGlzLnEzID0gbmJpKCk7XG4gIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbygyICogbS50LCB0aGlzLnIyKTtcbiAgdGhpcy5tdSA9IHRoaXMucjIuZGl2aWRlKG0pO1xuICB0aGlzLm0gPSBtO1xufVxuXG5mdW5jdGlvbiBiYXJyZXR0Q29udmVydCh4KSB7XG4gIGlmICh4LnMgPCAwIHx8IHgudCA+IDIgKiB0aGlzLm0udCkgcmV0dXJuIHgubW9kKHRoaXMubSk7XG4gIGVsc2UgaWYgKHguY29tcGFyZVRvKHRoaXMubSkgPCAwKSByZXR1cm4geDtcbiAgZWxzZSB7XG4gICAgdmFyIHIgPSBuYmkoKTtcbiAgICB4LmNvcHlUbyhyKTtcbiAgICB0aGlzLnJlZHVjZShyKTtcbiAgICByZXR1cm4gcjtcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXJyZXR0UmV2ZXJ0KHgpIHtcbiAgcmV0dXJuIHg7XG59XG5cbi8vIHggPSB4IG1vZCBtIChIQUMgMTQuNDIpXG5cbmZ1bmN0aW9uIGJhcnJldHRSZWR1Y2UoeCkge1xuICB4LmRyU2hpZnRUbyh0aGlzLm0udCAtIDEsIHRoaXMucjIpO1xuICBpZiAoeC50ID4gdGhpcy5tLnQgKyAxKSB7XG4gICAgeC50ID0gdGhpcy5tLnQgKyAxO1xuICAgIHguY2xhbXAoKTtcbiAgfVxuICB0aGlzLm11Lm11bHRpcGx5VXBwZXJUbyh0aGlzLnIyLCB0aGlzLm0udCArIDEsIHRoaXMucTMpO1xuICB0aGlzLm0ubXVsdGlwbHlMb3dlclRvKHRoaXMucTMsIHRoaXMubS50ICsgMSwgdGhpcy5yMik7XG4gIHdoaWxlICh4LmNvbXBhcmVUbyh0aGlzLnIyKSA8IDApIHguZEFkZE9mZnNldCgxLCB0aGlzLm0udCArIDEpO1xuICB4LnN1YlRvKHRoaXMucjIsIHgpO1xuICB3aGlsZSAoeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSB4LnN1YlRvKHRoaXMubSwgeCk7XG59XG5cbi8vIHIgPSB4XjIgbW9kIG07IHggIT0gclxuXG5mdW5jdGlvbiBiYXJyZXR0U3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuLy8gciA9IHgqeSBtb2QgbTsgeCx5ICE9IHJcblxuZnVuY3Rpb24gYmFycmV0dE11bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuQmFycmV0dC5wcm90b3R5cGUuY29udmVydCA9IGJhcnJldHRDb252ZXJ0O1xuQmFycmV0dC5wcm90b3R5cGUucmV2ZXJ0ID0gYmFycmV0dFJldmVydDtcbkJhcnJldHQucHJvdG90eXBlLnJlZHVjZSA9IGJhcnJldHRSZWR1Y2U7XG5CYXJyZXR0LnByb3RvdHlwZS5tdWxUbyA9IGJhcnJldHRNdWxUbztcbkJhcnJldHQucHJvdG90eXBlLnNxclRvID0gYmFycmV0dFNxclRvO1xuXG4vLyAocHVibGljKSB0aGlzXmUgJSBtIChIQUMgMTQuODUpXG5cbmZ1bmN0aW9uIGJuTW9kUG93KGUsIG0pIHtcbiAgdmFyIGkgPSBlLmJpdExlbmd0aCgpLFxuICAgIGssIHIgPSBuYnYoMSksXG4gICAgejtcbiAgaWYgKGkgPD0gMCkgcmV0dXJuIHI7XG4gIGVsc2UgaWYgKGkgPCAxOCkgayA9IDE7XG4gIGVsc2UgaWYgKGkgPCA0OCkgayA9IDM7XG4gIGVsc2UgaWYgKGkgPCAxNDQpIGsgPSA0O1xuICBlbHNlIGlmIChpIDwgNzY4KSBrID0gNTtcbiAgZWxzZSBrID0gNjtcbiAgaWYgKGkgPCA4KVxuICAgIHogPSBuZXcgQ2xhc3NpYyhtKTtcbiAgZWxzZSBpZiAobS5pc0V2ZW4oKSlcbiAgICB6ID0gbmV3IEJhcnJldHQobSk7XG4gIGVsc2VcbiAgICB6ID0gbmV3IE1vbnRnb21lcnkobSk7XG5cbiAgLy8gcHJlY29tcHV0YXRpb25cbiAgdmFyIGcgPSBuZXcgQXJyYXkoKSxcbiAgICBuID0gMyxcbiAgICBrMSA9IGsgLSAxLFxuICAgIGttID0gKDEgPDwgaykgLSAxO1xuICBnWzFdID0gei5jb252ZXJ0KHRoaXMpO1xuICBpZiAoayA+IDEpIHtcbiAgICB2YXIgZzIgPSBuYmkoKTtcbiAgICB6LnNxclRvKGdbMV0sIGcyKTtcbiAgICB3aGlsZSAobiA8PSBrbSkge1xuICAgICAgZ1tuXSA9IG5iaSgpO1xuICAgICAgei5tdWxUbyhnMiwgZ1tuIC0gMl0sIGdbbl0pO1xuICAgICAgbiArPSAyO1xuICAgIH1cbiAgfVxuXG4gIHZhciBqID0gZS50IC0gMSxcbiAgICB3LCBpczEgPSB0cnVlLFxuICAgIHIyID0gbmJpKCksXG4gICAgdDtcbiAgaSA9IG5iaXRzKGVbal0pIC0gMTtcbiAgd2hpbGUgKGogPj0gMCkge1xuICAgIGlmIChpID49IGsxKSB3ID0gKGVbal0gPj4gKGkgLSBrMSkpICYga207XG4gICAgZWxzZSB7XG4gICAgICB3ID0gKGVbal0gJiAoKDEgPDwgKGkgKyAxKSkgLSAxKSkgPDwgKGsxIC0gaSk7XG4gICAgICBpZiAoaiA+IDApIHcgfD0gZVtqIC0gMV0gPj4gKHRoaXMuREIgKyBpIC0gazEpO1xuICAgIH1cblxuICAgIG4gPSBrO1xuICAgIHdoaWxlICgodyAmIDEpID09IDApIHtcbiAgICAgIHcgPj49IDE7XG4gICAgICAtLW47XG4gICAgfVxuICAgIGlmICgoaSAtPSBuKSA8IDApIHtcbiAgICAgIGkgKz0gdGhpcy5EQjtcbiAgICAgIC0tajtcbiAgICB9XG4gICAgaWYgKGlzMSkgeyAvLyByZXQgPT0gMSwgZG9uJ3QgYm90aGVyIHNxdWFyaW5nIG9yIG11bHRpcGx5aW5nIGl0XG4gICAgICBnW3ddLmNvcHlUbyhyKTtcbiAgICAgIGlzMSA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aGlsZSAobiA+IDEpIHtcbiAgICAgICAgei5zcXJUbyhyLCByMik7XG4gICAgICAgIHouc3FyVG8ocjIsIHIpO1xuICAgICAgICBuIC09IDI7XG4gICAgICB9XG4gICAgICBpZiAobiA+IDApIHouc3FyVG8ociwgcjIpO1xuICAgICAgZWxzZSB7XG4gICAgICAgIHQgPSByO1xuICAgICAgICByID0gcjI7XG4gICAgICAgIHIyID0gdDtcbiAgICAgIH1cbiAgICAgIHoubXVsVG8ocjIsIGdbd10sIHIpO1xuICAgIH1cblxuICAgIHdoaWxlIChqID49IDAgJiYgKGVbal0gJiAoMSA8PCBpKSkgPT0gMCkge1xuICAgICAgei5zcXJUbyhyLCByMik7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSByMjtcbiAgICAgIHIyID0gdDtcbiAgICAgIGlmICgtLWkgPCAwKSB7XG4gICAgICAgIGkgPSB0aGlzLkRCIC0gMTtcbiAgICAgICAgLS1qO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gei5yZXZlcnQocik7XG59XG5cbi8vIChwdWJsaWMpIGdjZCh0aGlzLGEpIChIQUMgMTQuNTQpXG5cbmZ1bmN0aW9uIGJuR0NEKGEpIHtcbiAgdmFyIHggPSAodGhpcy5zIDwgMCkgPyB0aGlzLm5lZ2F0ZSgpIDogdGhpcy5jbG9uZSgpO1xuICB2YXIgeSA9IChhLnMgPCAwKSA/IGEubmVnYXRlKCkgOiBhLmNsb25lKCk7XG4gIGlmICh4LmNvbXBhcmVUbyh5KSA8IDApIHtcbiAgICB2YXIgdCA9IHg7XG4gICAgeCA9IHk7XG4gICAgeSA9IHQ7XG4gIH1cbiAgdmFyIGkgPSB4LmdldExvd2VzdFNldEJpdCgpLFxuICAgIGcgPSB5LmdldExvd2VzdFNldEJpdCgpO1xuICBpZiAoZyA8IDApIHJldHVybiB4O1xuICBpZiAoaSA8IGcpIGcgPSBpO1xuICBpZiAoZyA+IDApIHtcbiAgICB4LnJTaGlmdFRvKGcsIHgpO1xuICAgIHkuclNoaWZ0VG8oZywgeSk7XG4gIH1cbiAgd2hpbGUgKHguc2lnbnVtKCkgPiAwKSB7XG4gICAgaWYgKChpID0geC5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB4LnJTaGlmdFRvKGksIHgpO1xuICAgIGlmICgoaSA9IHkuZ2V0TG93ZXN0U2V0Qml0KCkpID4gMCkgeS5yU2hpZnRUbyhpLCB5KTtcbiAgICBpZiAoeC5jb21wYXJlVG8oeSkgPj0gMCkge1xuICAgICAgeC5zdWJUbyh5LCB4KTtcbiAgICAgIHguclNoaWZ0VG8oMSwgeCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHkuc3ViVG8oeCwgeSk7XG4gICAgICB5LnJTaGlmdFRvKDEsIHkpO1xuICAgIH1cbiAgfVxuICBpZiAoZyA+IDApIHkubFNoaWZ0VG8oZywgeSk7XG4gIHJldHVybiB5O1xufVxuXG4vLyAocHJvdGVjdGVkKSB0aGlzICUgbiwgbiA8IDJeMjZcblxuZnVuY3Rpb24gYm5wTW9kSW50KG4pIHtcbiAgaWYgKG4gPD0gMCkgcmV0dXJuIDA7XG4gIHZhciBkID0gdGhpcy5EViAlIG4sXG4gICAgciA9ICh0aGlzLnMgPCAwKSA/IG4gLSAxIDogMDtcbiAgaWYgKHRoaXMudCA+IDApXG4gICAgaWYgKGQgPT0gMCkgciA9IHRoaXNbMF0gJSBuO1xuICAgIGVsc2UgZm9yICh2YXIgaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByID0gKGQgKiByICsgdGhpc1tpXSkgJSBuO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgMS90aGlzICUgbSAoSEFDIDE0LjYxKVxuXG5mdW5jdGlvbiBibk1vZEludmVyc2UobSkge1xuICB2YXIgYWMgPSBtLmlzRXZlbigpO1xuICBpZiAoKHRoaXMuaXNFdmVuKCkgJiYgYWMpIHx8IG0uc2lnbnVtKCkgPT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVSTztcbiAgdmFyIHUgPSBtLmNsb25lKCksXG4gICAgdiA9IHRoaXMuY2xvbmUoKTtcbiAgdmFyIGEgPSBuYnYoMSksXG4gICAgYiA9IG5idigwKSxcbiAgICBjID0gbmJ2KDApLFxuICAgIGQgPSBuYnYoMSk7XG4gIHdoaWxlICh1LnNpZ251bSgpICE9IDApIHtcbiAgICB3aGlsZSAodS5pc0V2ZW4oKSkge1xuICAgICAgdS5yU2hpZnRUbygxLCB1KTtcbiAgICAgIGlmIChhYykge1xuICAgICAgICBpZiAoIWEuaXNFdmVuKCkgfHwgIWIuaXNFdmVuKCkpIHtcbiAgICAgICAgICBhLmFkZFRvKHRoaXMsIGEpO1xuICAgICAgICAgIGIuc3ViVG8obSwgYik7XG4gICAgICAgIH1cbiAgICAgICAgYS5yU2hpZnRUbygxLCBhKTtcbiAgICAgIH0gZWxzZSBpZiAoIWIuaXNFdmVuKCkpIGIuc3ViVG8obSwgYik7XG4gICAgICBiLnJTaGlmdFRvKDEsIGIpO1xuICAgIH1cbiAgICB3aGlsZSAodi5pc0V2ZW4oKSkge1xuICAgICAgdi5yU2hpZnRUbygxLCB2KTtcbiAgICAgIGlmIChhYykge1xuICAgICAgICBpZiAoIWMuaXNFdmVuKCkgfHwgIWQuaXNFdmVuKCkpIHtcbiAgICAgICAgICBjLmFkZFRvKHRoaXMsIGMpO1xuICAgICAgICAgIGQuc3ViVG8obSwgZCk7XG4gICAgICAgIH1cbiAgICAgICAgYy5yU2hpZnRUbygxLCBjKTtcbiAgICAgIH0gZWxzZSBpZiAoIWQuaXNFdmVuKCkpIGQuc3ViVG8obSwgZCk7XG4gICAgICBkLnJTaGlmdFRvKDEsIGQpO1xuICAgIH1cbiAgICBpZiAodS5jb21wYXJlVG8odikgPj0gMCkge1xuICAgICAgdS5zdWJUbyh2LCB1KTtcbiAgICAgIGlmIChhYykgYS5zdWJUbyhjLCBhKTtcbiAgICAgIGIuc3ViVG8oZCwgYik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHYuc3ViVG8odSwgdik7XG4gICAgICBpZiAoYWMpIGMuc3ViVG8oYSwgYyk7XG4gICAgICBkLnN1YlRvKGIsIGQpO1xuICAgIH1cbiAgfVxuICBpZiAodi5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDApIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87XG4gIGlmIChkLmNvbXBhcmVUbyhtKSA+PSAwKSByZXR1cm4gZC5zdWJ0cmFjdChtKTtcbiAgaWYgKGQuc2lnbnVtKCkgPCAwKSBkLmFkZFRvKG0sIGQpO1xuICBlbHNlIHJldHVybiBkO1xuICBpZiAoZC5zaWdudW0oKSA8IDApIHJldHVybiBkLmFkZChtKTtcbiAgZWxzZSByZXR1cm4gZDtcbn1cblxudmFyIGxvd3ByaW1lcyA9IFsyLCAzLCA1LCA3LCAxMSwgMTMsIDE3LCAxOSwgMjMsIDI5LCAzMSwgMzcsIDQxLCA0MywgNDcsIDUzLCA1OSwgNjEsIDY3LCA3MSwgNzMsIDc5LCA4MywgODksIDk3LCAxMDEsXG4gICAgMTAzLCAxMDcsIDEwOSwgMTEzLCAxMjcsIDEzMSwgMTM3LCAxMzksIDE0OSwgMTUxLCAxNTcsIDE2MywgMTY3LCAxNzMsIDE3OSwgMTgxLCAxOTEsIDE5MywgMTk3LCAxOTksIDIxMSwgMjIzLCAyMjcsXG4gICAgMjI5LCAyMzMsIDIzOSwgMjQxLCAyNTEsIDI1NywgMjYzLCAyNjksIDI3MSwgMjc3LCAyODEsIDI4MywgMjkzLCAzMDcsIDMxMSwgMzEzLCAzMTcsIDMzMSwgMzM3LCAzNDcsIDM0OSwgMzUzLCAzNTksXG4gICAgMzY3LCAzNzMsIDM3OSwgMzgzLCAzODksIDM5NywgNDAxLCA0MDksIDQxOSwgNDIxLCA0MzEsIDQzMywgNDM5LCA0NDMsIDQ0OSwgNDU3LCA0NjEsIDQ2MywgNDY3LCA0NzksIDQ4NywgNDkxLCA0OTksXG4gICAgNTAzLCA1MDksIDUyMSwgNTIzLCA1NDEsIDU0NywgNTU3LCA1NjMsIDU2OSwgNTcxLCA1NzcsIDU4NywgNTkzLCA1OTksIDYwMSwgNjA3LCA2MTMsIDYxNywgNjE5LCA2MzEsIDY0MSwgNjQzLCA2NDcsXG4gICAgNjUzLCA2NTksIDY2MSwgNjczLCA2NzcsIDY4MywgNjkxLCA3MDEsIDcwOSwgNzE5LCA3MjcsIDczMywgNzM5LCA3NDMsIDc1MSwgNzU3LCA3NjEsIDc2OSwgNzczLCA3ODcsIDc5NywgODA5LCA4MTEsXG4gICAgODIxLCA4MjMsIDgyNywgODI5LCA4MzksIDg1MywgODU3LCA4NTksIDg2MywgODc3LCA4ODEsIDg4MywgODg3LCA5MDcsIDkxMSwgOTE5LCA5MjksIDkzNywgOTQxLCA5NDcsIDk1MywgOTY3LCA5NzEsXG4gICAgOTc3LCA5ODMsIDk5MSwgOTk3XG5dO1xudmFyIGxwbGltID0gKDEgPDwgMjYpIC8gbG93cHJpbWVzW2xvd3ByaW1lcy5sZW5ndGggLSAxXTtcblxuLy8gKHB1YmxpYykgdGVzdCBwcmltYWxpdHkgd2l0aCBjZXJ0YWludHkgPj0gMS0uNV50XG5cbmZ1bmN0aW9uIGJuSXNQcm9iYWJsZVByaW1lKHQpIHtcbiAgdmFyIGksIHggPSB0aGlzLmFicygpO1xuICBpZiAoeC50ID09IDEgJiYgeFswXSA8PSBsb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aCAtIDFdKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IGxvd3ByaW1lcy5sZW5ndGg7ICsraSlcbiAgICAgIGlmICh4WzBdID09IGxvd3ByaW1lc1tpXSkgcmV0dXJuIHRydWU7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh4LmlzRXZlbigpKSByZXR1cm4gZmFsc2U7XG4gIGkgPSAxO1xuICB3aGlsZSAoaSA8IGxvd3ByaW1lcy5sZW5ndGgpIHtcbiAgICB2YXIgbSA9IGxvd3ByaW1lc1tpXSxcbiAgICAgIGogPSBpICsgMTtcbiAgICB3aGlsZSAoaiA8IGxvd3ByaW1lcy5sZW5ndGggJiYgbSA8IGxwbGltKSBtICo9IGxvd3ByaW1lc1tqKytdO1xuICAgIG0gPSB4Lm1vZEludChtKTtcbiAgICB3aGlsZSAoaSA8IGopIGlmIChtICUgbG93cHJpbWVzW2krK10gPT0gMCkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB4Lm1pbGxlclJhYmluKHQpO1xufVxuXG4vKiBhZGRlZCBieSBSZWN1cml0eSBMYWJzICovXG5cbmZ1bmN0aW9uIG5iaXRzKHgpIHtcbiAgdmFyIG4gPSAxLFxuICAgIHQ7XG4gIGlmICgodCA9IHggPj4+IDE2KSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgbiArPSAxNjtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDgpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICBuICs9IDg7XG4gIH1cbiAgaWYgKCh0ID0geCA+PiA0KSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgbiArPSA0O1xuICB9XG4gIGlmICgodCA9IHggPj4gMikgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIG4gKz0gMjtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDEpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICBuICs9IDE7XG4gIH1cbiAgcmV0dXJuIG47XG59XG5cbmZ1bmN0aW9uIGJuVG9NUEkoKSB7XG4gIHZhciBiYSA9IHRoaXMudG9CeXRlQXJyYXkoKTtcbiAgdmFyIHNpemUgPSAoYmEubGVuZ3RoIC0gMSkgKiA4ICsgbmJpdHMoYmFbMF0pO1xuICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKHNpemUgJiAweEZGMDApID4+IDgpO1xuICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShzaXplICYgMHhGRik7XG4gIHJlc3VsdCArPSB1dGlsLmJpbjJzdHIoYmEpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuLyogRU5EIG9mIGFkZGl0aW9uICovXG5cbi8vIChwcm90ZWN0ZWQpIHRydWUgaWYgcHJvYmFibHkgcHJpbWUgKEhBQyA0LjI0LCBNaWxsZXItUmFiaW4pXG5mdW5jdGlvbiBibnBNaWxsZXJSYWJpbih0KSB7XG4gIHZhciBuMSA9IHRoaXMuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuICB2YXIgayA9IG4xLmdldExvd2VzdFNldEJpdCgpO1xuICBpZiAoayA8PSAwKSByZXR1cm4gZmFsc2U7XG4gIHZhciByID0gbjEuc2hpZnRSaWdodChrKTtcbiAgdCA9ICh0ICsgMSkgPj4gMTtcbiAgaWYgKHQgPiBsb3dwcmltZXMubGVuZ3RoKSB0ID0gbG93cHJpbWVzLmxlbmd0aDtcbiAgdmFyIGEgPSBuYmkoKTtcbiAgdmFyIGosIGJhc2VzID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdDsgKytpKSB7XG4gICAgLy9QaWNrIGJhc2VzIGF0IHJhbmRvbSwgaW5zdGVhZCBvZiBzdGFydGluZyBhdCAyXG4gICAgZm9yICg7Oykge1xuICAgICAgaiA9IGxvd3ByaW1lc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBsb3dwcmltZXMubGVuZ3RoKV07XG4gICAgICBpZiAoYmFzZXMuaW5kZXhPZihqKSA9PSAtMSkgYnJlYWs7XG4gICAgfVxuICAgIGJhc2VzLnB1c2goaik7XG4gICAgYS5mcm9tSW50KGopO1xuICAgIHZhciB5ID0gYS5tb2RQb3cociwgdGhpcyk7XG4gICAgaWYgKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAwICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7XG4gICAgICB2YXIgaiA9IDE7XG4gICAgICB3aGlsZSAoaisrIDwgayAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkge1xuICAgICAgICB5ID0geS5tb2RQb3dJbnQoMiwgdGhpcyk7XG4gICAgICAgIGlmICh5LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCkgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKHkuY29tcGFyZVRvKG4xKSAhPSAwKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vanNibi5qcycpO1xuXG4vLyBwcm90ZWN0ZWRcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNodW5rU2l6ZSA9IGJucENodW5rU2l6ZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnRvUmFkaXggPSBibnBUb1JhZGl4O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbVJhZGl4ID0gYm5wRnJvbVJhZGl4O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbU51bWJlciA9IGJucEZyb21OdW1iZXI7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXR3aXNlVG8gPSBibnBCaXR3aXNlVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jaGFuZ2VCaXQgPSBibnBDaGFuZ2VCaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGRUbyA9IGJucEFkZFRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZE11bHRpcGx5ID0gYm5wRE11bHRpcGx5O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZEFkZE9mZnNldCA9IGJucERBZGRPZmZzZXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseUxvd2VyVG8gPSBibnBNdWx0aXBseUxvd2VyVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseVVwcGVyVG8gPSBibnBNdWx0aXBseVVwcGVyVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RJbnQgPSBibnBNb2RJbnQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5taWxsZXJSYWJpbiA9IGJucE1pbGxlclJhYmluO1xuXG4vLyBwdWJsaWNcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNsb25lID0gYm5DbG9uZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmludFZhbHVlID0gYm5JbnRWYWx1ZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmJ5dGVWYWx1ZSA9IGJuQnl0ZVZhbHVlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc2hvcnRWYWx1ZSA9IGJuU2hvcnRWYWx1ZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNpZ251bSA9IGJuU2lnTnVtO1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9CeXRlQXJyYXkgPSBiblRvQnl0ZUFycmF5O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZXF1YWxzID0gYm5FcXVhbHM7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5taW4gPSBibk1pbjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1heCA9IGJuTWF4O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kID0gYm5BbmQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5vciA9IGJuT3I7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS54b3IgPSBiblhvcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmFuZE5vdCA9IGJuQW5kTm90O1xuQmlnSW50ZWdlci5wcm90b3R5cGUubm90ID0gYm5Ob3Q7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zaGlmdExlZnQgPSBiblNoaWZ0TGVmdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0UmlnaHQgPSBiblNoaWZ0UmlnaHQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5nZXRMb3dlc3RTZXRCaXQgPSBibkdldExvd2VzdFNldEJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmJpdENvdW50ID0gYm5CaXRDb3VudDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnRlc3RCaXQgPSBiblRlc3RCaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zZXRCaXQgPSBiblNldEJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNsZWFyQml0ID0gYm5DbGVhckJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmZsaXBCaXQgPSBibkZsaXBCaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGQgPSBibkFkZDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnN1YnRyYWN0ID0gYm5TdWJ0cmFjdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5ID0gYm5NdWx0aXBseTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZSA9IGJuRGl2aWRlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUucmVtYWluZGVyID0gYm5SZW1haW5kZXI7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZpZGVBbmRSZW1haW5kZXIgPSBibkRpdmlkZUFuZFJlbWFpbmRlcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZFBvdyA9IGJuTW9kUG93O1xuQmlnSW50ZWdlci5wcm90b3R5cGUubW9kSW52ZXJzZSA9IGJuTW9kSW52ZXJzZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnBvdyA9IGJuUG93O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZ2NkID0gYm5HQ0Q7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5pc1Byb2JhYmxlUHJpbWUgPSBibklzUHJvYmFibGVQcmltZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnRvTVBJID0gYm5Ub01QSTtcblxuLy8gSlNCTi1zcGVjaWZpYyBleHRlbnNpb25cbkJpZ0ludGVnZXIucHJvdG90eXBlLnNxdWFyZSA9IGJuU3F1YXJlO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0Fcbi8vXG4vLyBSU0EgaW1wbGVtZW50YXRpb25cblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuL2pzYm4uanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKSxcbiAgcmFuZG9tID0gcmVxdWlyZSgnLi4vcmFuZG9tLmpzJyk7XG5cbmZ1bmN0aW9uIFNlY3VyZVJhbmRvbSgpIHtcbiAgZnVuY3Rpb24gbmV4dEJ5dGVzKGJ5dGVBcnJheSkge1xuICAgIGZvciAodmFyIG4gPSAwOyBuIDwgYnl0ZUFycmF5Lmxlbmd0aDsgbisrKSB7XG4gICAgICBieXRlQXJyYXlbbl0gPSByYW5kb20uZ2V0U2VjdXJlUmFuZG9tT2N0ZXQoKTtcbiAgICB9XG4gIH1cbiAgdGhpcy5uZXh0Qnl0ZXMgPSBuZXh0Qnl0ZXM7XG59XG5cbmZ1bmN0aW9uIFJTQSgpIHtcbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gdXNlcyBqc2JuIEJpZyBOdW0gbGlicmFyeSB0byBkZWNyeXB0IFJTQVxuICAgKiBAcGFyYW0gbVxuICAgKiAgICAgICAgICAgIG1lc3NhZ2VcbiAgICogQHBhcmFtIGRcbiAgICogICAgICAgICAgICBSU0EgZCBhcyBCaWdJbnRlZ2VyXG4gICAqIEBwYXJhbSBwXG4gICAqICAgICAgICAgICAgUlNBIHAgYXMgQmlnSW50ZWdlclxuICAgKiBAcGFyYW0gcVxuICAgKiAgICAgICAgICAgIFJTQSBxIGFzIEJpZ0ludGVnZXJcbiAgICogQHBhcmFtIHVcbiAgICogICAgICAgICAgICBSU0EgdSBhcyBCaWdJbnRlZ2VyXG4gICAqIEByZXR1cm4ge0JpZ0ludGVnZXJ9IFRoZSBkZWNyeXB0ZWQgdmFsdWUgb2YgdGhlIG1lc3NhZ2VcbiAgICovXG4gIGZ1bmN0aW9uIGRlY3J5cHQobSwgZCwgcCwgcSwgdSkge1xuICAgIHZhciB4cCA9IG0ubW9kKHApLm1vZFBvdyhkLm1vZChwLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKSksIHApO1xuICAgIHZhciB4cSA9IG0ubW9kKHEpLm1vZFBvdyhkLm1vZChxLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKSksIHEpO1xuICAgIHV0aWwucHJpbnRfZGVidWcoXCJyc2EuanMgZGVjcnlwdFxcbnhwbjpcIiArIHV0aWwuaGV4c3RyZHVtcCh4cC50b01QSSgpKSArIFwiXFxueHFuOlwiICsgdXRpbC5oZXhzdHJkdW1wKHhxLnRvTVBJKCkpKTtcblxuICAgIHZhciB0ID0geHEuc3VidHJhY3QoeHApO1xuICAgIGlmICh0WzBdID09IDApIHtcbiAgICAgIHQgPSB4cC5zdWJ0cmFjdCh4cSk7XG4gICAgICB0ID0gdC5tdWx0aXBseSh1KS5tb2QocSk7XG4gICAgICB0ID0gcS5zdWJ0cmFjdCh0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdCA9IHQubXVsdGlwbHkodSkubW9kKHEpO1xuICAgIH1cbiAgICByZXR1cm4gdC5tdWx0aXBseShwKS5hZGQoeHApO1xuICB9XG5cbiAgLyoqXG4gICAqIGVuY3J5cHQgbWVzc2FnZVxuICAgKiBAcGFyYW0gbSBtZXNzYWdlIGFzIEJpZ0ludGVnZXJcbiAgICogQHBhcmFtIGUgcHVibGljIE1QSSBwYXJ0IGFzIEJpZ0ludGVnZXJcbiAgICogQHBhcmFtIG4gcHVibGljIE1QSSBwYXJ0IGFzIEJpZ0ludGVnZXJcbiAgICogQHJldHVybiBCaWdJbnRlZ2VyXG4gICAqL1xuICBmdW5jdGlvbiBlbmNyeXB0KG0sIGUsIG4pIHtcbiAgICByZXR1cm4gbS5tb2RQb3dJbnQoZSwgbik7XG4gIH1cblxuICAvKiBTaWduIGFuZCBWZXJpZnkgKi9cbiAgZnVuY3Rpb24gc2lnbihtLCBkLCBuKSB7XG4gICAgcmV0dXJuIG0ubW9kUG93KGQsIG4pO1xuICB9XG5cbiAgZnVuY3Rpb24gdmVyaWZ5KHgsIGUsIG4pIHtcbiAgICByZXR1cm4geC5tb2RQb3dJbnQoZSwgbik7XG4gIH1cblxuICAvLyBcImVtcHR5XCIgUlNBIGtleSBjb25zdHJ1Y3RvclxuXG4gIGZ1bmN0aW9uIGtleU9iamVjdCgpIHtcbiAgICB0aGlzLm4gPSBudWxsO1xuICAgIHRoaXMuZSA9IDA7XG4gICAgdGhpcy5lZSA9IG51bGw7XG4gICAgdGhpcy5kID0gbnVsbDtcbiAgICB0aGlzLnAgPSBudWxsO1xuICAgIHRoaXMucSA9IG51bGw7XG4gICAgdGhpcy5kbXAxID0gbnVsbDtcbiAgICB0aGlzLmRtcTEgPSBudWxsO1xuICAgIHRoaXMudSA9IG51bGw7XG4gIH1cblxuICAvLyBHZW5lcmF0ZSBhIG5ldyByYW5kb20gcHJpdmF0ZSBrZXkgQiBiaXRzIGxvbmcsIHVzaW5nIHB1YmxpYyBleHB0IEVcblxuICBmdW5jdGlvbiBnZW5lcmF0ZShCLCBFKSB7XG4gICAgdmFyIGtleSA9IG5ldyBrZXlPYmplY3QoKTtcbiAgICB2YXIgcm5nID0gbmV3IFNlY3VyZVJhbmRvbSgpO1xuICAgIHZhciBxcyA9IEIgPj4gMTtcbiAgICBrZXkuZSA9IHBhcnNlSW50KEUsIDE2KTtcbiAgICBrZXkuZWUgPSBuZXcgQmlnSW50ZWdlcihFLCAxNik7XG4gICAgZm9yICg7Oykge1xuICAgICAgZm9yICg7Oykge1xuICAgICAgICBrZXkucCA9IG5ldyBCaWdJbnRlZ2VyKEIgLSBxcywgMSwgcm5nKTtcbiAgICAgICAgaWYgKGtleS5wLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKS5nY2Qoa2V5LmVlKS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpID09IDAgJiYga2V5LnAuaXNQcm9iYWJsZVByaW1lKDEwKSlcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGZvciAoOzspIHtcbiAgICAgICAga2V5LnEgPSBuZXcgQmlnSW50ZWdlcihxcywgMSwgcm5nKTtcbiAgICAgICAgaWYgKGtleS5xLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKS5nY2Qoa2V5LmVlKS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpID09IDAgJiYga2V5LnEuaXNQcm9iYWJsZVByaW1lKDEwKSlcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChrZXkucC5jb21wYXJlVG8oa2V5LnEpIDw9IDApIHtcbiAgICAgICAgdmFyIHQgPSBrZXkucDtcbiAgICAgICAga2V5LnAgPSBrZXkucTtcbiAgICAgICAga2V5LnEgPSB0O1xuICAgICAgfVxuICAgICAgdmFyIHAxID0ga2V5LnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuICAgICAgdmFyIHExID0ga2V5LnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuICAgICAgdmFyIHBoaSA9IHAxLm11bHRpcGx5KHExKTtcbiAgICAgIGlmIChwaGkuZ2NkKGtleS5lZSkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSB7XG4gICAgICAgIGtleS5uID0ga2V5LnAubXVsdGlwbHkoa2V5LnEpO1xuICAgICAgICBrZXkuZCA9IGtleS5lZS5tb2RJbnZlcnNlKHBoaSk7XG4gICAgICAgIGtleS5kbXAxID0ga2V5LmQubW9kKHAxKTtcbiAgICAgICAga2V5LmRtcTEgPSBrZXkuZC5tb2QocTEpO1xuICAgICAgICBrZXkudSA9IGtleS5wLm1vZEludmVyc2Uoa2V5LnEpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleTtcbiAgfVxuXG4gIHRoaXMuZW5jcnlwdCA9IGVuY3J5cHQ7XG4gIHRoaXMuZGVjcnlwdCA9IGRlY3J5cHQ7XG4gIHRoaXMudmVyaWZ5ID0gdmVyaWZ5O1xuICB0aGlzLnNpZ24gPSBzaWduO1xuICB0aGlzLmdlbmVyYXRlID0gZ2VuZXJhdGU7XG4gIHRoaXMua2V5T2JqZWN0ID0ga2V5T2JqZWN0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJTQTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBIFxuXG4vLyBUaGUgR1BHNEJyb3dzZXJzIGNyeXB0byBpbnRlcmZhY2VcblxudmFyIHR5cGVfbXBpID0gcmVxdWlyZSgnLi4vdHlwZS9tcGkuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBzZWN1cmUgcmFuZG9tIGJ5dGUgc3RyaW5nIG9mIHRoZSBzcGVjaWZpZWQgbGVuZ3RoXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIExlbmd0aCBpbiBieXRlcyB0byBnZW5lcmF0ZVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFJhbmRvbSBieXRlIHN0cmluZ1xuICAgKi9cbiAgZ2V0UmFuZG9tQnl0ZXM6IGZ1bmN0aW9uKGxlbmd0aCkge1xuICAgIHZhciByZXN1bHQgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmdldFNlY3VyZVJhbmRvbU9jdGV0KCkpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBwc2V1ZG8tcmFuZG9tIG51bWJlciBpbiB0aGUgc3BlY2lmaWVkIHJhbmdlXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gZnJvbSBNaW4gb2YgdGhlIHJhbmRvbSBudW1iZXJcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSB0byBNYXggb2YgdGhlIHJhbmRvbSBudW1iZXIgKG1heCAzMmJpdClcbiAgICogQHJldHVybiB7SW50ZWdlcn0gQSBwc2V1ZG8gcmFuZG9tIG51bWJlclxuICAgKi9cbiAgZ2V0UHNldWRvUmFuZG9tOiBmdW5jdGlvbihmcm9tLCB0bykge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkgKiAodG8gLSBmcm9tKSkgKyBmcm9tO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBzZWN1cmUgcmFuZG9tIG51bWJlciBpbiB0aGUgc3BlY2lmaWVkIHJhbmdlXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gZnJvbSBNaW4gb2YgdGhlIHJhbmRvbSBudW1iZXJcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSB0byBNYXggb2YgdGhlIHJhbmRvbSBudW1iZXIgKG1heCAzMmJpdClcbiAgICogQHJldHVybiB7SW50ZWdlcn0gQSBzZWN1cmUgcmFuZG9tIG51bWJlclxuICAgKi9cbiAgZ2V0U2VjdXJlUmFuZG9tOiBmdW5jdGlvbihmcm9tLCB0bykge1xuICAgIHZhciBidWYgPSBuZXcgVWludDMyQXJyYXkoMSk7XG4gICAgd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMoYnVmKTtcbiAgICB2YXIgYml0cyA9ICgodG8gLSBmcm9tKSkudG9TdHJpbmcoMikubGVuZ3RoO1xuICAgIHdoaWxlICgoYnVmWzBdICYgKE1hdGgucG93KDIsIGJpdHMpIC0gMSkpID4gKHRvIC0gZnJvbSkpXG4gICAgICB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpO1xuICAgIHJldHVybiBmcm9tICsgKE1hdGguYWJzKGJ1ZlswXSAmIChNYXRoLnBvdygyLCBiaXRzKSAtIDEpKSk7XG4gIH0sXG5cbiAgZ2V0U2VjdXJlUmFuZG9tT2N0ZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBidWYgPSBuZXcgVWludDMyQXJyYXkoMSk7XG4gICAgd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMoYnVmKTtcbiAgICByZXR1cm4gYnVmWzBdICYgMHhGRjtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlIGEgc2VjdXJlIHJhbmRvbSBiaWcgaW50ZWdlciBvZiBiaXRzIGxlbmd0aFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGJpdHMgQml0IGxlbmd0aCBvZiB0aGUgTVBJIHRvIGNyZWF0ZVxuICAgKiBAcmV0dXJuIHtCaWdJbnRlZ2VyfSBSZXN1bHRpbmcgYmlnIGludGVnZXJcbiAgICovXG4gIGdldFJhbmRvbUJpZ0ludGVnZXI6IGZ1bmN0aW9uKGJpdHMpIHtcbiAgICBpZiAoYml0cyA8IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgbnVtQnl0ZXMgPSBNYXRoLmZsb29yKChiaXRzICsgNykgLyA4KTtcblxuICAgIHZhciByYW5kb21CaXRzID0gdGhpcy5nZXRSYW5kb21CeXRlcyhudW1CeXRlcyk7XG4gICAgaWYgKGJpdHMgJSA4ID4gMCkge1xuXG4gICAgICByYW5kb21CaXRzID0gU3RyaW5nLmZyb21DaGFyQ29kZShcbiAgICAgIChNYXRoLnBvdygyLCBiaXRzICUgOCkgLSAxKSAmXG4gICAgICAgIHJhbmRvbUJpdHMuY2hhckNvZGVBdCgwKSkgK1xuICAgICAgICByYW5kb21CaXRzLnN1YnN0cmluZygxKTtcbiAgICB9XG4gICAgdmFyIG1waSA9IG5ldyB0eXBlX21waSgpO1xuICAgIG1waS5mcm9tQnl0ZXMocmFuZG9tQml0cyk7XG4gICAgcmV0dXJuIG1waS50b0JpZ0ludGVnZXIoKTtcbiAgfSxcblxuICBnZXRSYW5kb21CaWdJbnRlZ2VySW5SYW5nZTogZnVuY3Rpb24obWluLCBtYXgpIHtcbiAgICBpZiAobWF4LmNvbXBhcmVUbyhtaW4pIDw9IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcmFuZ2UgPSBtYXguc3VidHJhY3QobWluKTtcbiAgICB2YXIgciA9IHRoaXMuZ2V0UmFuZG9tQmlnSW50ZWdlcihyYW5nZS5iaXRMZW5ndGgoKSk7XG4gICAgd2hpbGUgKHIgPiByYW5nZSkge1xuICAgICAgciA9IHRoaXMuZ2V0UmFuZG9tQmlnSW50ZWdlcihyYW5nZS5iaXRMZW5ndGgoKSk7XG4gICAgfVxuICAgIHJldHVybiBtaW4uYWRkKHIpO1xuICB9XG5cbn07XG4iLCJ2YXIgcHVibGljS2V5ID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5JyksXG4gIHBrY3MxID0gcmVxdWlyZSgnLi9wa2NzMS5qcycpLFxuICBoYXNoTW9kdWxlID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAvKipcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBwdWJsaWMgS2V5IGFsZ29yaXRobVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGhhc2hfYWxnbyBIYXNoIGFsZ29yaXRobVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gbXNnX01QSXMgU2lnbmF0dXJlIG11bHRpcHJlY2lzaW9uIGludGVnZXJzXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBwdWJsaWNrZXlfTVBJcyBQdWJsaWMga2V5IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIG9uIHdoZXJlIHRoZSBzaWduYXR1cmUgd2FzIGNvbXB1dGVkIG9uLlxuICAgKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIHNpZ25hdHVyZSAoc2lnX2RhdGEgd2FzIGVxdWFsIHRvIGRhdGEgb3ZlciBoYXNoKVxuICAgKi9cbiAgdmVyaWZ5OiBmdW5jdGlvbihhbGdvLCBoYXNoX2FsZ28sIG1zZ19NUElzLCBwdWJsaWNrZXlfTVBJcywgZGF0YSkge1xuICAgIHZhciBjYWxjX2hhc2ggPSBoYXNoTW9kdWxlLmRpZ2VzdChoYXNoX2FsZ28sIGRhdGEpO1xuXG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIC8vIFJTQSAoRW5jcnlwdCBvciBTaWduKSBbSEFDXSAgXG4gICAgICBjYXNlIDI6XG4gICAgICAgIC8vIFJTQSBFbmNyeXB0LU9ubHkgW0hBQ11cbiAgICAgIGNhc2UgMzpcbiAgICAgICAgLy8gUlNBIFNpZ24tT25seSBbSEFDXVxuICAgICAgICB2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcbiAgICAgICAgdmFyIG4gPSBwdWJsaWNrZXlfTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIGUgPSBwdWJsaWNrZXlfTVBJc1sxXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIHggPSBtc2dfTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIGRvcHVibGljID0gcnNhLnZlcmlmeSh4LCBlLCBuKTtcbiAgICAgICAgdmFyIGhhc2ggPSBwa2NzMS5lbXNhLmRlY29kZShoYXNoX2FsZ28sIGRvcHVibGljLnRvTVBJKCkuc3Vic3RyaW5nKDIpKTtcbiAgICAgICAgaWYgKGhhc2ggPT0gLTEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BLQ1MxIHBhZGRpbmcgaW4gbWVzc2FnZSBvciBrZXkgaW5jb3JyZWN0LiBBYm9ydGluZy4uLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoYXNoID09IGNhbGNfaGFzaDtcblxuICAgICAgY2FzZSAxNjpcbiAgICAgICAgLy8gRWxnYW1hbCAoRW5jcnlwdC1Pbmx5KSBbRUxHQU1BTF0gW0hBQ11cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwic2lnbmluZyB3aXRoIEVsZ2FtYWwgaXMgbm90IGRlZmluZWQgaW4gdGhlIE9wZW5QR1Agc3RhbmRhcmQuXCIpO1xuICAgICAgY2FzZSAxNzpcbiAgICAgICAgLy8gRFNBIChEaWdpdGFsIFNpZ25hdHVyZSBBbGdvcml0aG0pIFtGSVBTMTg2XSBbSEFDXVxuICAgICAgICB2YXIgZHNhID0gbmV3IHB1YmxpY0tleS5kc2EoKTtcbiAgICAgICAgdmFyIHMxID0gbXNnX01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBzMiA9IG1zZ19NUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgcCA9IHB1YmxpY2tleV9NUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgcSA9IHB1YmxpY2tleV9NUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgZyA9IHB1YmxpY2tleV9NUElzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgeSA9IHB1YmxpY2tleV9NUElzWzNdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgbSA9IGRhdGE7XG4gICAgICAgIHZhciBkb3B1YmxpYyA9IGRzYS52ZXJpZnkoaGFzaF9hbGdvLCBzMSwgczIsIG0sIHAsIHEsIGcsIHkpO1xuICAgICAgICByZXR1cm4gZG9wdWJsaWMuY29tcGFyZVRvKHMxKSA9PSAwO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZSBhbGdvcml0aG0uJyk7XG4gICAgfVxuXG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHNpZ25hdHVyZSBvbiBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaGFzaF9hbGdvIGhhc2ggQWxnb3JpdGhtIHRvIHVzZSAoU2VlIFJGQzQ4ODAgOS40KVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQXN5bW1ldHJpYyBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZSAoU2VlIFJGQzQ4ODAgOS4xKVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gcHVibGljTVBJcyBQdWJsaWMga2V5IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICAgKiBvZiB0aGUgcHJpdmF0ZSBrZXkgXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBzZWNyZXRNUElzIFByaXZhdGUga2V5IG11bHRpcHJlY2lzaW9uIFxuICAgKiBpbnRlZ2VycyB3aGljaCBpcyB1c2VkIHRvIHNpZ24gdGhlIGRhdGFcbiAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBiZSBzaWduZWRcbiAgICogQHJldHVybiB7b3BlbnBncF90eXBlX21waVtdfVxuICAgKi9cbiAgc2lnbjogZnVuY3Rpb24oaGFzaF9hbGdvLCBhbGdvLCBrZXlJbnRlZ2VycywgZGF0YSkge1xuXG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIC8vIFJTQSAoRW5jcnlwdCBvciBTaWduKSBbSEFDXSAgXG4gICAgICBjYXNlIDI6XG4gICAgICAgIC8vIFJTQSBFbmNyeXB0LU9ubHkgW0hBQ11cbiAgICAgIGNhc2UgMzpcbiAgICAgICAgLy8gUlNBIFNpZ24tT25seSBbSEFDXVxuICAgICAgICB2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcbiAgICAgICAgdmFyIGQgPSBrZXlJbnRlZ2Vyc1syXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIG4gPSBrZXlJbnRlZ2Vyc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIG0gPSBwa2NzMS5lbXNhLmVuY29kZShoYXNoX2FsZ28sXG4gICAgICAgICAgZGF0YSwga2V5SW50ZWdlcnNbMF0uYnl0ZUxlbmd0aCgpKTtcblxuICAgICAgICByZXR1cm4gcnNhLnNpZ24obSwgZCwgbikudG9NUEkoKTtcblxuICAgICAgY2FzZSAxNzpcbiAgICAgICAgLy8gRFNBIChEaWdpdGFsIFNpZ25hdHVyZSBBbGdvcml0aG0pIFtGSVBTMTg2XSBbSEFDXVxuICAgICAgICB2YXIgZHNhID0gbmV3IHB1YmxpY0tleS5kc2EoKTtcblxuICAgICAgICB2YXIgcCA9IGtleUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgcSA9IGtleUludGVnZXJzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgZyA9IGtleUludGVnZXJzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgeSA9IGtleUludGVnZXJzWzNdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgeCA9IGtleUludGVnZXJzWzRdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgbSA9IGRhdGE7XG4gICAgICAgIHZhciByZXN1bHQgPSBkc2Euc2lnbihoYXNoX2FsZ28sIG0sIGcsIHAsIHEsIHgpO1xuXG4gICAgICAgIHJldHVybiByZXN1bHRbMF0udG9TdHJpbmcoKSArIHJlc3VsdFsxXS50b1N0cmluZygpO1xuICAgICAgY2FzZSAxNjpcbiAgICAgICAgLy8gRWxnYW1hbCAoRW5jcnlwdC1Pbmx5KSBbRUxHQU1BTF0gW0hBQ11cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTaWduaW5nIHdpdGggRWxnYW1hbCBpcyBub3QgZGVmaW5lZCBpbiB0aGUgT3BlblBHUCBzdGFuZGFyZC4nKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzaWduYXR1cmUgYWxnb3JpdGhtLicpO1xuICAgIH1cbiAgfVxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vL1xuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJy4vYmFzZTY0LmpzJyk7XG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpO1xudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpO1xuXG4vKipcbiAqIEZpbmRzIG91dCB3aGljaCBBc2NpaSBBcm1vcmluZyB0eXBlIGlzIHVzZWQuIFRoaXMgaXMgYW4gaW50ZXJuYWwgZnVuY3Rpb25cbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IFtTdHJpbmddIGFzY2lpIGFybW9yZWQgdGV4dFxuICogQHJldHVybnMge0ludGVnZXJ9IDAgPSBNRVNTQUdFIFBBUlQgbiBvZiBtXG4gKiAgICAgICAgIDEgPSBNRVNTQUdFIFBBUlQgblxuICogICAgICAgICAyID0gU0lHTkVEIE1FU1NBR0VcbiAqICAgICAgICAgMyA9IFBHUCBNRVNTQUdFXG4gKiAgICAgICAgIDQgPSBQVUJMSUMgS0VZIEJMT0NLXG4gKiAgICAgICAgIDUgPSBQUklWQVRFIEtFWSBCTE9DS1xuICogICAgICAgICBudWxsID0gdW5rbm93blxuICovXG5mdW5jdGlvbiBnZXRfdHlwZSh0ZXh0KSB7XG4gIHZhciByZUhlYWRlciA9IC9eLS0tLS0oW14tXSspLS0tLS0kXFxuL207XG5cbiAgdmFyIGhlYWRlciA9IHRleHQubWF0Y2gocmVIZWFkZXIpO1xuXG4gIC8vIEJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFgvWVxuICAvLyBVc2VkIGZvciBtdWx0aS1wYXJ0IG1lc3NhZ2VzLCB3aGVyZSB0aGUgYXJtb3IgaXMgc3BsaXQgYW1vbmdzdCBZXG4gIC8vIHBhcnRzLCBhbmQgdGhpcyBpcyB0aGUgWHRoIHBhcnQgb3V0IG9mIFkuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFxcZCtcXC9cXGQrLykpIHtcbiAgICByZXR1cm4gZW51bXMuYXJtb3IubXVsdGlwYXJ0X3NlY3Rpb247XG4gIH0gZWxzZVxuICAvLyBCRUdJTiBQR1AgTUVTU0FHRSwgUEFSVCBYXG4gIC8vIFVzZWQgZm9yIG11bHRpLXBhcnQgbWVzc2FnZXMsIHdoZXJlIHRoaXMgaXMgdGhlIFh0aCBwYXJ0IG9mIGFuXG4gIC8vIHVuc3BlY2lmaWVkIG51bWJlciBvZiBwYXJ0cy4gUmVxdWlyZXMgdGhlIE1FU1NBR0UtSUQgQXJtb3JcbiAgLy8gSGVhZGVyIHRvIGJlIHVzZWQuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFxcZCsvKSkge1xuICAgIHJldHVybiBlbnVtcy5hcm1vci5tdWx0aXBhcnRfbGFzdDtcblxuICB9IGVsc2VcbiAgLy8gQkVHSU4gUEdQIFNJR05BVFVSRVxuICAvLyBVc2VkIGZvciBkZXRhY2hlZCBzaWduYXR1cmVzLCBPcGVuUEdQL01JTUUgc2lnbmF0dXJlcywgYW5kXG4gIC8vIGNsZWFydGV4dCBzaWduYXR1cmVzLiBOb3RlIHRoYXQgUEdQIDIueCB1c2VzIEJFR0lOIFBHUCBNRVNTQUdFXG4gIC8vIGZvciBkZXRhY2hlZCBzaWduYXR1cmVzLlxuICBpZiAoaGVhZGVyWzFdLm1hdGNoKC9CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UvKSkge1xuICAgIHJldHVybiBlbnVtcy5hcm1vci5zaWduZWQ7XG5cbiAgfSBlbHNlXG4gIC8vIEJFR0lOIFBHUCBNRVNTQUdFXG4gIC8vIFVzZWQgZm9yIHNpZ25lZCwgZW5jcnlwdGVkLCBvciBjb21wcmVzc2VkIGZpbGVzLlxuICBpZiAoaGVhZGVyWzFdLm1hdGNoKC9CRUdJTiBQR1AgTUVTU0FHRS8pKSB7XG4gICAgcmV0dXJuIGVudW1zLmFybW9yLm1lc3NhZ2U7XG5cbiAgfSBlbHNlXG4gIC8vIEJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLXG4gIC8vIFVzZWQgZm9yIGFybW9yaW5nIHB1YmxpYyBrZXlzLlxuICBpZiAoaGVhZGVyWzFdLm1hdGNoKC9CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy8pKSB7XG4gICAgcmV0dXJuIGVudW1zLmFybW9yLnB1YmxpY19rZXk7XG5cbiAgfSBlbHNlXG4gIC8vIEJFR0lOIFBHUCBQUklWQVRFIEtFWSBCTE9DS1xuICAvLyBVc2VkIGZvciBhcm1vcmluZyBwcml2YXRlIGtleXMuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBQUklWQVRFIEtFWSBCTE9DSy8pKSB7XG4gICAgcmV0dXJuIGVudW1zLmFybW9yLnByaXZhdGVfa2V5O1xuICB9XG59XG5cbi8qKlxuICogQWRkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdG8gdGhlIGFybW9yIHZlcnNpb24gb2YgYW4gT3BlblBHUCBiaW5hcnlcbiAqIHBhY2tldCBibG9jay5cbiAqIEBhdXRob3IgIEFsZXhcbiAqIEB2ZXJzaW9uIDIwMTEtMTItMTZcbiAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBoZWFkZXIgaW5mb3JtYXRpb25cbiAqL1xuZnVuY3Rpb24gYXJtb3JfYWRkaGVhZGVyKCkge1xuICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgaWYgKGNvbmZpZy5zaG93X3ZlcnNpb24pIHtcbiAgICByZXN1bHQgKz0gXCJWZXJzaW9uOiBcIiArIGNvbmZpZy52ZXJzaW9uc3RyaW5nICsgJ1xcclxcbic7XG4gIH1cbiAgaWYgKGNvbmZpZy5zaG93X2NvbW1lbnQpIHtcbiAgICByZXN1bHQgKz0gXCJDb21tZW50OiBcIiArIGNvbmZpZy5jb21tZW50c3RyaW5nICsgJ1xcclxcbic7XG4gIH1cbiAgcmVzdWx0ICs9ICdcXHJcXG4nO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5cblxuLyoqXG4gKiBDYWxjdWxhdGVzIGEgY2hlY2tzdW0gb3ZlciB0aGUgZ2l2ZW4gZGF0YSBhbmQgcmV0dXJucyBpdCBiYXNlNjQgZW5jb2RlZFxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBjcmVhdGUgYSBDUkMtMjQgY2hlY2tzdW0gZm9yXG4gKiBAcmV0dXJuIHtTdHJpbmd9IEJhc2U2NCBlbmNvZGVkIGNoZWNrc3VtXG4gKi9cbmZ1bmN0aW9uIGdldENoZWNrU3VtKGRhdGEpIHtcbiAgdmFyIGMgPSBjcmVhdGVjcmMyNChkYXRhKTtcbiAgdmFyIHN0ciA9IFwiXCIgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGMgPj4gMTYpICtcbiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKChjID4+IDgpICYgMHhGRikgK1xuICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoYyAmIDB4RkYpO1xuICByZXR1cm4gYmFzZTY0LmVuY29kZShzdHIpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGNoZWNrc3VtIG92ZXIgdGhlIGdpdmVuIGRhdGEgYW5kIGNvbXBhcmVzIGl0IHdpdGggdGhlXG4gKiBnaXZlbiBiYXNlNjQgZW5jb2RlZCBjaGVja3N1bVxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBjcmVhdGUgYSBDUkMtMjQgY2hlY2tzdW0gZm9yXG4gKiBAcGFyYW0ge1N0cmluZ30gY2hlY2tzdW0gQmFzZTY0IGVuY29kZWQgY2hlY2tzdW1cbiAqIEByZXR1cm4ge0Jvb2xlYW59IFRydWUgaWYgdGhlIGdpdmVuIGNoZWNrc3VtIGlzIGNvcnJlY3Q7IG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiB2ZXJpZnlDaGVja1N1bShkYXRhLCBjaGVja3N1bSkge1xuICB2YXIgYyA9IGdldENoZWNrU3VtKGRhdGEpO1xuICB2YXIgZCA9IGNoZWNrc3VtO1xuICByZXR1cm4gY1swXSA9PSBkWzBdICYmIGNbMV0gPT0gZFsxXSAmJiBjWzJdID09IGRbMl07XG59XG4vKipcbiAqIEludGVybmFsIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBhIENSQy0yNCBjaGVja3N1bSBvdmVyIGEgZ2l2ZW4gc3RyaW5nIChkYXRhKVxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBjcmVhdGUgYSBDUkMtMjQgY2hlY2tzdW0gZm9yXG4gKiBAcmV0dXJuIHtJbnRlZ2VyfSBUaGUgQ1JDLTI0IGNoZWNrc3VtIGFzIG51bWJlclxuICovXG52YXIgY3JjX3RhYmxlID0gW1xuICAgIDB4MDAwMDAwMDAsIDB4MDA4NjRjZmIsIDB4MDE4YWQ1MGQsIDB4MDEwYzk5ZjYsIDB4MDM5M2U2ZTEsIDB4MDMxNWFhMWEsIDB4MDIxOTMzZWMsIDB4MDI5ZjdmMTcsIDB4MDdhMTgxMzksXG4gICAgMHgwNzI3Y2RjMiwgMHgwNjJiNTQzNCwgMHgwNmFkMThjZiwgMHgwNDMyNjdkOCwgMHgwNGI0MmIyMywgMHgwNWI4YjJkNSwgMHgwNTNlZmUyZSwgMHgwZmM1NGU4OSwgMHgwZjQzMDI3MixcbiAgICAweDBlNGY5Yjg0LCAweDBlYzlkNzdmLCAweDBjNTZhODY4LCAweDBjZDBlNDkzLCAweDBkZGM3ZDY1LCAweDBkNWEzMTllLCAweDA4NjRjZmIwLCAweDA4ZTI4MzRiLCAweDA5ZWUxYWJkLFxuICAgIDB4MDk2ODU2NDYsIDB4MGJmNzI5NTEsIDB4MGI3MTY1YWEsIDB4MGE3ZGZjNWMsIDB4MGFmYmIwYTcsIDB4MWYwY2QxZTksIDB4MWY4YTlkMTIsIDB4MWU4NjA0ZTQsIDB4MWUwMDQ4MWYsXG4gICAgMHgxYzlmMzcwOCwgMHgxYzE5N2JmMywgMHgxZDE1ZTIwNSwgMHgxZDkzYWVmZSwgMHgxOGFkNTBkMCwgMHgxODJiMWMyYiwgMHgxOTI3ODVkZCwgMHgxOWExYzkyNiwgMHgxYjNlYjYzMSxcbiAgICAweDFiYjhmYWNhLCAweDFhYjQ2MzNjLCAweDFhMzIyZmM3LCAweDEwYzk5ZjYwLCAweDEwNGZkMzliLCAweDExNDM0YTZkLCAweDExYzUwNjk2LCAweDEzNWE3OTgxLCAweDEzZGMzNTdhLFxuICAgIDB4MTJkMGFjOGMsIDB4MTI1NmUwNzcsIDB4MTc2ODFlNTksIDB4MTdlZTUyYTIsIDB4MTZlMmNiNTQsIDB4MTY2NDg3YWYsIDB4MTRmYmY4YjgsIDB4MTQ3ZGI0NDMsIDB4MTU3MTJkYjUsXG4gICAgMHgxNWY3NjE0ZSwgMHgzZTE5YTNkMiwgMHgzZTlmZWYyOSwgMHgzZjkzNzZkZiwgMHgzZjE1M2EyNCwgMHgzZDhhNDUzMywgMHgzZDBjMDljOCwgMHgzYzAwOTAzZSwgMHgzYzg2ZGNjNSxcbiAgICAweDM5YjgyMmViLCAweDM5M2U2ZTEwLCAweDM4MzJmN2U2LCAweDM4YjRiYjFkLCAweDNhMmJjNDBhLCAweDNhYWQ4OGYxLCAweDNiYTExMTA3LCAweDNiMjc1ZGZjLCAweDMxZGNlZDViLFxuICAgIDB4MzE1YWExYTAsXG4gICAgMHgzMDU2Mzg1NiwgMHgzMGQwNzRhZCwgMHgzMjRmMGJiYSwgMHgzMmM5NDc0MSwgMHgzM2M1ZGViNywgMHgzMzQzOTI0YywgMHgzNjdkNmM2MiwgMHgzNmZiMjA5OSwgMHgzN2Y3Yjk2ZixcbiAgICAweDM3NzFmNTk0LCAweDM1ZWU4YTgzLCAweDM1NjhjNjc4LCAweDM0NjQ1ZjhlLCAweDM0ZTIxMzc1LCAweDIxMTU3MjNiLCAweDIxOTMzZWMwLCAweDIwOWZhNzM2LCAweDIwMTllYmNkLFxuICAgIDB4MjI4Njk0ZGEsIDB4MjIwMGQ4MjEsIDB4MjMwYzQxZDcsIDB4MjM4YTBkMmMsIDB4MjZiNGYzMDIsIDB4MjYzMmJmZjksIDB4MjczZTI2MGYsIDB4MjdiODZhZjQsIDB4MjUyNzE1ZTMsXG4gICAgMHgyNWExNTkxOCwgMHgyNGFkYzBlZSwgMHgyNDJiOGMxNSwgMHgyZWQwM2NiMiwgMHgyZTU2NzA0OSwgMHgyZjVhZTliZiwgMHgyZmRjYTU0NCwgMHgyZDQzZGE1MywgMHgyZGM1OTZhOCxcbiAgICAweDJjYzkwZjVlLCAweDJjNGY0M2E1LCAweDI5NzFiZDhiLCAweDI5ZjdmMTcwLCAweDI4ZmI2ODg2LCAweDI4N2QyNDdkLCAweDJhZTI1YjZhLCAweDJhNjQxNzkxLCAweDJiNjg4ZTY3LFxuICAgIDB4MmJlZWMyOWMsIDB4N2MzMzQ3YTQsIDB4N2NiNTBiNWYsIDB4N2RiOTkyYTksIDB4N2QzZmRlNTIsIDB4N2ZhMGExNDUsIDB4N2YyNmVkYmUsIDB4N2UyYTc0NDgsIDB4N2VhYzM4YjMsXG4gICAgMHg3YjkyYzY5ZCwgMHg3YjE0OGE2NiwgMHg3YTE4MTM5MCwgMHg3YTllNWY2YiwgMHg3ODAxMjA3YywgMHg3ODg3NmM4NywgMHg3OThiZjU3MSwgMHg3OTBkYjk4YSwgMHg3M2Y2MDkyZCxcbiAgICAweDczNzA0NWQ2LCAweDcyN2NkYzIwLCAweDcyZmE5MGRiLCAweDcwNjVlZmNjLCAweDcwZTNhMzM3LCAweDcxZWYzYWMxLCAweDcxNjk3NjNhLCAweDc0NTc4ODE0LCAweDc0ZDFjNGVmLFxuICAgIDB4NzVkZDVkMTksIDB4NzU1YjExZTIsIDB4NzdjNDZlZjUsIDB4Nzc0MjIyMGUsIDB4NzY0ZWJiZjgsIDB4NzZjOGY3MDMsIDB4NjMzZjk2NGQsIDB4NjNiOWRhYjYsIDB4NjJiNTQzNDAsXG4gICAgMHg2MjMzMGZiYixcbiAgICAweDYwYWM3MGFjLCAweDYwMmEzYzU3LCAweDYxMjZhNWExLCAweDYxYTBlOTVhLCAweDY0OWUxNzc0LCAweDY0MTg1YjhmLCAweDY1MTRjMjc5LCAweDY1OTI4ZTgyLCAweDY3MGRmMTk1LFxuICAgIDB4Njc4YmJkNmUsIDB4NjY4NzI0OTgsIDB4NjYwMTY4NjMsIDB4NmNmYWQ4YzQsIDB4NmM3Yzk0M2YsIDB4NmQ3MDBkYzksIDB4NmRmNjQxMzIsIDB4NmY2OTNlMjUsIDB4NmZlZjcyZGUsXG4gICAgMHg2ZWUzZWIyOCwgMHg2ZTY1YTdkMywgMHg2YjViNTlmZCwgMHg2YmRkMTUwNiwgMHg2YWQxOGNmMCwgMHg2YTU3YzAwYiwgMHg2OGM4YmYxYywgMHg2ODRlZjNlNywgMHg2OTQyNmExMSxcbiAgICAweDY5YzQyNmVhLCAweDQyMmFlNDc2LCAweDQyYWNhODhkLCAweDQzYTAzMTdiLCAweDQzMjY3ZDgwLCAweDQxYjkwMjk3LCAweDQxM2Y0ZTZjLCAweDQwMzNkNzlhLCAweDQwYjU5YjYxLFxuICAgIDB4NDU4YjY1NGYsIDB4NDUwZDI5YjQsIDB4NDQwMWIwNDIsIDB4NDQ4N2ZjYjksIDB4NDYxODgzYWUsIDB4NDY5ZWNmNTUsIDB4NDc5MjU2YTMsIDB4NDcxNDFhNTgsIDB4NGRlZmFhZmYsXG4gICAgMHg0ZDY5ZTYwNCwgMHg0YzY1N2ZmMiwgMHg0Y2UzMzMwOSwgMHg0ZTdjNGMxZSwgMHg0ZWZhMDBlNSwgMHg0ZmY2OTkxMywgMHg0ZjcwZDVlOCwgMHg0YTRlMmJjNiwgMHg0YWM4NjczZCxcbiAgICAweDRiYzRmZWNiLCAweDRiNDJiMjMwLCAweDQ5ZGRjZDI3LCAweDQ5NWI4MWRjLCAweDQ4NTcxODJhLCAweDQ4ZDE1NGQxLCAweDVkMjYzNTlmLCAweDVkYTA3OTY0LCAweDVjYWNlMDkyLFxuICAgIDB4NWMyYWFjNjksIDB4NWViNWQzN2UsIDB4NWUzMzlmODUsIDB4NWYzZjA2NzMsIDB4NWZiOTRhODgsIDB4NWE4N2I0YTYsIDB4NWEwMWY4NWQsIDB4NWIwZDYxYWIsIDB4NWI4YjJkNTAsXG4gICAgMHg1OTE0NTI0NywgMHg1OTkyMWViYywgMHg1ODllODc0YSwgMHg1ODE4Y2JiMSwgMHg1MmUzN2IxNiwgMHg1MjY1MzdlZCwgMHg1MzY5YWUxYiwgMHg1M2VmZTJlMCwgMHg1MTcwOWRmNyxcbiAgICAweDUxZjZkMTBjLFxuICAgIDB4NTBmYTQ4ZmEsIDB4NTA3YzA0MDEsIDB4NTU0MmZhMmYsIDB4NTVjNGI2ZDQsIDB4NTRjODJmMjIsIDB4NTQ0ZTYzZDksIDB4NTZkMTFjY2UsIDB4NTY1NzUwMzUsIDB4NTc1YmM5YzMsXG4gICAgMHg1N2RkODUzOFxuXTtcblxuZnVuY3Rpb24gY3JlYXRlY3JjMjQoaW5wdXQpIHtcbiAgdmFyIGNyYyA9IDB4QjcwNENFO1xuICB2YXIgaW5kZXggPSAwO1xuXG4gIHdoaWxlICgoaW5wdXQubGVuZ3RoIC0gaW5kZXgpID4gMTYpIHtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDEpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDIpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDMpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDQpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDUpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDYpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDcpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDgpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDkpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDEwKSkgJiAweGZmXTtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXggKyAxMSkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMTIpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDEzKSkgJiAweGZmXTtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXggKyAxNCkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMTUpKSAmIDB4ZmZdO1xuICAgIGluZGV4ICs9IDE2O1xuICB9XG5cbiAgZm9yICh2YXIgaiA9IGluZGV4OyBqIDwgaW5wdXQubGVuZ3RoOyBqKyspIHtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrKykpICYgMHhmZl07XG4gIH1cbiAgcmV0dXJuIGNyYyAmIDB4ZmZmZmZmO1xufVxuXG4vKipcbiAqIFNwbGl0cyBhIG1lc3NhZ2UgaW50byB0d28gcGFydHMsIHRoZSBoZWFkZXJzIGFuZCB0aGUgYm9keS4gVGhpcyBpcyBhbiBpbnRlcm5hbCBmdW5jdGlvblxuICogQHBhcmFtIHtTdHJpbmd9IHRleHQgT3BlblBHUCBhcm1vcmVkIG1lc3NhZ2UgcGFydFxuICogQHJldHVybnMgeyhCb29sZWFufE9iamVjdCl9IEVpdGhlciBmYWxzZSBpbiBjYXNlIG9mIGFuIGVycm9yXG4gKiBvciBhbiBvYmplY3Qgd2l0aCBhdHRyaWJ1dGUgXCJoZWFkZXJzXCIgY29udGFpbmluZyB0aGUgaGVhZGVycyBhbmRcbiAqIGFuZCBhbiBhdHRyaWJ1dGUgXCJib2R5XCIgY29udGFpbmluZyB0aGUgYm9keS5cbiAqL1xuZnVuY3Rpb24gc3BsaXRfaGVhZGVycyh0ZXh0KSB7XG4gIHZhciByZUVtcHR5TGluZSA9IC9eW1xcdCBdKlxcbi9tO1xuICB2YXIgaGVhZGVycyA9IFwiXCI7XG4gIHZhciBib2R5ID0gdGV4dDtcblxuICB2YXIgbWF0Y2hSZXN1bHQgPSByZUVtcHR5TGluZS5leGVjKHRleHQpO1xuXG4gIGlmIChtYXRjaFJlc3VsdCAhPSBudWxsKSB7XG4gICAgaGVhZGVycyA9IHRleHQuc2xpY2UoMCwgbWF0Y2hSZXN1bHQuaW5kZXgpO1xuICAgIGJvZHkgPSB0ZXh0LnNsaWNlKG1hdGNoUmVzdWx0LmluZGV4ICsgbWF0Y2hSZXN1bHRbMF0ubGVuZ3RoKTtcbiAgfVxuXG4gIHJldHVybiB7IGhlYWRlcnM6IGhlYWRlcnMsIGJvZHk6IGJvZHkgfTtcbn1cblxuLyoqXG4gKiBTcGxpdHMgYSBtZXNzYWdlIGludG8gdHdvIHBhcnRzLCB0aGUgYm9keSBhbmQgdGhlIGNoZWNrc3VtLiBUaGlzIGlzIGFuIGludGVybmFsIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1N0cmluZ30gdGV4dCBPcGVuUEdQIGFybW9yZWQgbWVzc2FnZSBwYXJ0XG4gKiBAcmV0dXJucyB7KEJvb2xlYW58T2JqZWN0KX0gRWl0aGVyIGZhbHNlIGluIGNhc2Ugb2YgYW4gZXJyb3JcbiAqIG9yIGFuIG9iamVjdCB3aXRoIGF0dHJpYnV0ZSBcImJvZHlcIiBjb250YWluaW5nIHRoZSBib2R5XG4gKiBhbmQgYW4gYXR0cmlidXRlIFwiY2hlY2tzdW1cIiBjb250YWluaW5nIHRoZSBjaGVja3N1bS5cbiAqL1xuZnVuY3Rpb24gc3BsaXRfY2hlY2tzdW0odGV4dCkge1xuICB2YXIgcmVDaGVja3N1bVN0YXJ0ID0gL149L207XG4gIHZhciBib2R5ID0gdGV4dDtcbiAgdmFyIGNoZWNrc3VtID0gXCJcIjtcblxuICB2YXIgbWF0Y2hSZXN1bHQgPSByZUNoZWNrc3VtU3RhcnQuZXhlYyh0ZXh0KTtcblxuICBpZiAobWF0Y2hSZXN1bHQgIT0gbnVsbCkge1xuICAgIGJvZHkgPSB0ZXh0LnNsaWNlKDAsIG1hdGNoUmVzdWx0LmluZGV4KTtcbiAgICBjaGVja3N1bSA9IHRleHQuc2xpY2UobWF0Y2hSZXN1bHQuaW5kZXggKyAxKTtcbiAgfVxuXG4gIHJldHVybiB7IGJvZHk6IGJvZHksIGNoZWNrc3VtOiBjaGVja3N1bSB9O1xufVxuXG4vKipcbiAqIERlQXJtb3IgYW4gT3BlblBHUCBhcm1vcmVkIG1lc3NhZ2U7IHZlcmlmeSB0aGUgY2hlY2tzdW0gYW5kIHJldHVyblxuICogdGhlIGVuY29kZWQgYnl0ZXNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IE9wZW5QR1AgYXJtb3JlZCBtZXNzYWdlXG4gKiBAcmV0dXJucyB7KEJvb2xlYW58T2JqZWN0KX0gRWl0aGVyIGZhbHNlIGluIGNhc2Ugb2YgYW4gZXJyb3JcbiAqIG9yIGFuIG9iamVjdCB3aXRoIGF0dHJpYnV0ZSBcInRleHRcIiBjb250YWluaW5nIHRoZSBtZXNzYWdlIHRleHRcbiAqIGFuZCBhbiBhdHRyaWJ1dGUgXCJkYXRhXCIgY29udGFpbmluZyB0aGUgYnl0ZXMuXG4gKi9cbmZ1bmN0aW9uIGRlYXJtb3IodGV4dCkge1xuICB2YXIgcmVTcGxpdCA9IC9eLS0tLS1bXi1dKy0tLS0tJFxcbi9tO1xuXG4gIHRleHQgPSB0ZXh0LnJlcGxhY2UoL1xcci9nLCAnJyk7XG5cbiAgdmFyIHR5cGUgPSBnZXRfdHlwZSh0ZXh0KTtcblxuICB2YXIgc3BsaXR0ZXh0ID0gdGV4dC5zcGxpdChyZVNwbGl0KTtcblxuICAvLyBJRSBoYXMgYSBidWcgaW4gc3BsaXQgd2l0aCBhIHJlLiBJZiB0aGUgcGF0dGVybiBtYXRjaGVzIHRoZSBiZWdpbm5pbmcgb2YgdGhlXG4gIC8vIHN0cmluZyBpdCBkb2Vzbid0IGNyZWF0ZSBhbiBlbXB0eSBhcnJheSBlbGVtZW50IDAuIFNvIHdlIG5lZWQgdG8gZGV0ZWN0IHRoaXNcbiAgLy8gc28gd2Uga25vdyB0aGUgaW5kZXggb2YgdGhlIGRhdGEgd2UgYXJlIGludGVyZXN0ZWQgaW4uXG4gIHZhciBpbmRleEJhc2UgPSAxO1xuXG4gIHZhciByZXN1bHQsIGNoZWNrc3VtO1xuXG4gIGlmICh0ZXh0LnNlYXJjaChyZVNwbGl0KSAhPSBzcGxpdHRleHRbMF0ubGVuZ3RoKSB7XG4gICAgaW5kZXhCYXNlID0gMDtcbiAgfVxuXG4gIGlmICh0eXBlICE9IDIpIHtcbiAgICB2YXIgbXNnID0gc3BsaXRfaGVhZGVycyhzcGxpdHRleHRbaW5kZXhCYXNlXSk7XG4gICAgdmFyIG1zZ19zdW0gPSBzcGxpdF9jaGVja3N1bShtc2cuYm9keSk7XG5cbiAgICByZXN1bHQgPSB7XG4gICAgICBkYXRhOiBiYXNlNjQuZGVjb2RlKG1zZ19zdW0uYm9keSksXG4gICAgICB0eXBlOiB0eXBlXG4gICAgfTtcblxuICAgIGNoZWNrc3VtID0gbXNnX3N1bS5jaGVja3N1bTtcbiAgfSBlbHNlIHtcbiAgICAvLyBSZXZlcnNlIGRhc2gtZXNjYXBpbmcgZm9yIG1zZyBhbmQgcmVtb3ZlIHRyYWlsaW5nIHdoaXRlc3BhY2UgYXQgZW5kIG9mIGxpbmVcbiAgICB2YXIgbXNnID0gc3BsaXRfaGVhZGVycyhzcGxpdHRleHRbaW5kZXhCYXNlXS5yZXBsYWNlKC9eLSAvbWcsICcnKS5yZXBsYWNlKC9bXFx0IF0rXFxuL2csIFwiXFxuXCIpKTtcbiAgICB2YXIgc2lnID0gc3BsaXRfaGVhZGVycyhzcGxpdHRleHRbaW5kZXhCYXNlICsgMV0ucmVwbGFjZSgvXi0gL21nLCAnJykpO1xuICAgIHZhciBzaWdfc3VtID0gc3BsaXRfY2hlY2tzdW0oc2lnLmJvZHkpO1xuXG4gICAgcmVzdWx0ID0ge1xuICAgICAgdGV4dDogIG1zZy5ib2R5LnJlcGxhY2UoL1xcbiQvLCAnJykucmVwbGFjZSgvXFxuL2csIFwiXFxyXFxuXCIpLFxuICAgICAgZGF0YTogYmFzZTY0LmRlY29kZShzaWdfc3VtLmJvZHkpLFxuICAgICAgdHlwZTogdHlwZVxuICAgIH07XG5cbiAgICBjaGVja3N1bSA9IHNpZ19zdW0uY2hlY2tzdW07XG4gIH1cblxuICBpZiAoIXZlcmlmeUNoZWNrU3VtKHJlc3VsdC5kYXRhLCBjaGVja3N1bSkpIHtcbiAgICB1dGlsLnByaW50X2Vycm9yKFwiQXNjaWkgYXJtb3IgaW50ZWdyaXR5IGNoZWNrIG9uIG1lc3NhZ2UgZmFpbGVkOiAnXCJcbiAgICAgICsgY2hlY2tzdW1cbiAgICAgICsgXCInIHNob3VsZCBiZSAnXCJcbiAgICAgICsgZ2V0Q2hlY2tTdW0ocmVzdWx0KSArIFwiJ1wiKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuXG5cbi8qKlxuICogQXJtb3IgYW4gT3BlblBHUCBiaW5hcnkgcGFja2V0IGJsb2NrXG4gKiBAcGFyYW0ge0ludGVnZXJ9IG1lc3NhZ2V0eXBlIHR5cGUgb2YgdGhlIG1lc3NhZ2VcbiAqIEBwYXJhbSBib2R5XG4gKiBAcGFyYW0ge0ludGVnZXJ9IHBhcnRpbmRleFxuICogQHBhcmFtIHtJbnRlZ2VyfSBwYXJ0dG90YWxcbiAqIEByZXR1cm5zIHtTdHJpbmd9IEFybW9yZWQgdGV4dFxuICovXG5mdW5jdGlvbiBhcm1vcihtZXNzYWdldHlwZSwgYm9keSwgcGFydGluZGV4LCBwYXJ0dG90YWwpIHtcbiAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gIHN3aXRjaCAobWVzc2FnZXR5cGUpIHtcbiAgICBjYXNlIGVudW1zLmFybW9yLm11bHRpcGFydF9zZWN0aW9uOlxuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1CRUdJTiBQR1AgTUVTU0FHRSwgUEFSVCBcIiArIHBhcnRpbmRleCArIFwiL1wiICsgcGFydHRvdGFsICsgXCItLS0tLVxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IGFybW9yX2FkZGhlYWRlcigpO1xuICAgICAgcmVzdWx0ICs9IGJhc2U2NC5lbmNvZGUoYm9keSk7XG4gICAgICByZXN1bHQgKz0gXCJcXHJcXG49XCIgKyBnZXRDaGVja1N1bShib2R5KSArIFwiXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUVORCBQR1AgTUVTU0FHRSwgUEFSVCBcIiArIHBhcnRpbmRleCArIFwiL1wiICsgcGFydHRvdGFsICsgXCItLS0tLVxcclxcblwiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBlbnVtcy5hcm1vci5tdXRsaXBhcnRfbGFzdDpcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgXCIgKyBwYXJ0aW5kZXggKyBcIi0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG4gICAgICByZXN1bHQgKz0gYmFzZTY0LmVuY29kZShib2R5KTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbj1cIiArIGdldENoZWNrU3VtKGJvZHkpICsgXCJcXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tRU5EIFBHUCBNRVNTQUdFLCBQQVJUIFwiICsgcGFydGluZGV4ICsgXCItLS0tLVxcclxcblwiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBlbnVtcy5hcm1vci5zaWduZWQ6XG4gICAgICByZXN1bHQgKz0gXCJcXHJcXG4tLS0tLUJFR0lOIFBHUCBTSUdORUQgTUVTU0FHRS0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gXCJIYXNoOiBcIiArIGJvZHkuaGFzaCArIFwiXFxyXFxuXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYm9keS50ZXh0LnJlcGxhY2UoL1xcbi0vZywgXCJcXG4tIC1cIik7XG4gICAgICByZXN1bHQgKz0gXCJcXHJcXG4tLS0tLUJFR0lOIFBHUCBTSUdOQVRVUkUtLS0tLVxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IGFybW9yX2FkZGhlYWRlcigpO1xuICAgICAgcmVzdWx0ICs9IGJhc2U2NC5lbmNvZGUoYm9keS5kYXRhKTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbj1cIiArIGdldENoZWNrU3VtKGJvZHkuZGF0YSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIFNJR05BVFVSRS0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgICBjYXNlIGVudW1zLmFybW9yLm1lc3NhZ2U6XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhcm1vcl9hZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGJvZHkpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLVxcclxcblwiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBlbnVtcy5hcm1vci5wdWJsaWNfa2V5OlxuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG4gICAgICByZXN1bHQgKz0gYmFzZTY0LmVuY29kZShib2R5KTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbj1cIiArIGdldENoZWNrU3VtKGJvZHkpICsgXCJcXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXHJcXG5cXHJcXG5cIjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgZW51bXMuYXJtb3IucHJpdmF0ZV9rZXk6XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUJFR0lOIFBHUCBQUklWQVRFIEtFWSBCTE9DSy0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG4gICAgICByZXN1bHQgKz0gYmFzZTY0LmVuY29kZShib2R5KTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbj1cIiArIGdldENoZWNrU3VtKGJvZHkpICsgXCJcXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tRU5EIFBHUCBQUklWQVRFIEtFWSBCTE9DSy0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBlbmNvZGU6IGFybW9yLFxuICBkZWNvZGU6IGRlYXJtb3Jcbn07XG4iLCIvKiBPcGVuUEdQIHJhZGl4LTY0L2Jhc2U2NCBzdHJpbmcgZW5jb2RpbmcvZGVjb2RpbmdcbiAqIENvcHlyaWdodCAyMDA1IEhlcmJlcnQgSGFuZXdpbmtlbCwgd3d3LmhhbmVXSU4uZGVcbiAqIHZlcnNpb24gMS4wLCBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uXG4gKlxuICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCBhcy1pcywgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuICBcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUgb3Igc2VsbCB0aGlzIHNvZnR3YXJlLCB3aXRoIG9yXG4gKiB3aXRob3V0IGZlZSwgZm9yIGFueSBwdXJwb3NlIGFuZCBieSBhbnkgaW5kaXZpZHVhbCBvciBvcmdhbml6YXRpb24sIGlzIGhlcmVieVxuICogZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwYXJhZ3JhcGggYXBwZWFyIFxuICogaW4gYWxsIGNvcGllcy4gRGlzdHJpYnV0aW9uIGFzIGEgcGFydCBvZiBhbiBhcHBsaWNhdGlvbiBvciBiaW5hcnkgbXVzdFxuICogaW5jbHVkZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzXG4gKiBwcm92aWRlZCB3aXRoIHRoZSBhcHBsaWNhdGlvbiBvciBkaXN0cmlidXRpb24uXG4gKi9cblxudmFyIGI2NHMgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7XG5cbmZ1bmN0aW9uIHMycih0KSB7XG4gIHZhciBhLCBjLCBuO1xuICB2YXIgciA9ICcnLFxuICAgIGwgPSAwLFxuICAgIHMgPSAwO1xuICB2YXIgdGwgPSB0Lmxlbmd0aDtcblxuICBmb3IgKG4gPSAwOyBuIDwgdGw7IG4rKykge1xuICAgIGMgPSB0LmNoYXJDb2RlQXQobik7XG4gICAgaWYgKHMgPT0gMCkge1xuICAgICAgciArPSBiNjRzLmNoYXJBdCgoYyA+PiAyKSAmIDYzKTtcbiAgICAgIGEgPSAoYyAmIDMpIDw8IDQ7XG4gICAgfSBlbHNlIGlmIChzID09IDEpIHtcbiAgICAgIHIgKz0gYjY0cy5jaGFyQXQoKGEgfCAoYyA+PiA0KSAmIDE1KSk7XG4gICAgICBhID0gKGMgJiAxNSkgPDwgMjtcbiAgICB9IGVsc2UgaWYgKHMgPT0gMikge1xuICAgICAgciArPSBiNjRzLmNoYXJBdChhIHwgKChjID4+IDYpICYgMykpO1xuICAgICAgbCArPSAxO1xuICAgICAgaWYgKChsICUgNjApID09IDApXG4gICAgICAgIHIgKz0gXCJcXG5cIjtcbiAgICAgIHIgKz0gYjY0cy5jaGFyQXQoYyAmIDYzKTtcbiAgICB9XG4gICAgbCArPSAxO1xuICAgIGlmICgobCAlIDYwKSA9PSAwKVxuICAgICAgciArPSBcIlxcblwiO1xuXG4gICAgcyArPSAxO1xuICAgIGlmIChzID09IDMpXG4gICAgICBzID0gMDtcbiAgfVxuICBpZiAocyA+IDApIHtcbiAgICByICs9IGI2NHMuY2hhckF0KGEpO1xuICAgIGwgKz0gMTtcbiAgICBpZiAoKGwgJSA2MCkgPT0gMClcbiAgICAgIHIgKz0gXCJcXG5cIjtcbiAgICByICs9ICc9JztcbiAgICBsICs9IDE7XG4gIH1cbiAgaWYgKHMgPT0gMSkge1xuICAgIGlmICgobCAlIDYwKSA9PSAwKVxuICAgICAgciArPSBcIlxcblwiO1xuICAgIHIgKz0gJz0nO1xuICB9XG5cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHIycyh0KSB7XG4gIHZhciBjLCBuO1xuICB2YXIgciA9ICcnLFxuICAgIHMgPSAwLFxuICAgIGEgPSAwO1xuICB2YXIgdGwgPSB0Lmxlbmd0aDtcblxuICBmb3IgKG4gPSAwOyBuIDwgdGw7IG4rKykge1xuICAgIGMgPSBiNjRzLmluZGV4T2YodC5jaGFyQXQobikpO1xuICAgIGlmIChjID49IDApIHtcbiAgICAgIGlmIChzKVxuICAgICAgICByICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYSB8IChjID4+ICg2IC0gcykpICYgMjU1KTtcbiAgICAgIHMgPSAocyArIDIpICYgNztcbiAgICAgIGEgPSAoYyA8PCBzKSAmIDI1NTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBlbmNvZGU6IHMycixcbiAgZGVjb2RlOiByMnNcbn1cbiIsInZhciBlbnVtcyA9IHtcblxuICAvKiogQSBzdHJpbmcgdG8ga2V5IHNwZWNpZmllciB0eXBlXG4gICAqIEBlbnVtIHtJbnRlZ2VyfVxuICAgKi9cbiAgczJrOiB7XG4gICAgc2ltcGxlOiAwLFxuICAgIHNhbHRlZDogMSxcbiAgICBpdGVyYXRlZDogMyxcbiAgICBnbnU6IDEwMVxuICB9LFxuXG4gIC8qKiBSRkM0ODgwLCBzZWN0aW9uIDkuMSBcbiAgICogQGVudW0ge1N0cmluZ31cbiAgICovXG4gIHB1YmxpY0tleToge1xuICAgIHJzYV9lbmNyeXB0X3NpZ246IDEsXG4gICAgcnNhX2VuY3J5cHQ6IDIsXG4gICAgcnNhX3NpZ246IDMsXG4gICAgZWxnYW1hbDogMTYsXG4gICAgZHNhOiAxN1xuICB9LFxuXG4gIC8qKiBSRkM0ODgwLCBzZWN0aW9uIDkuMiBcbiAgICogQGVudW0ge1N0cmluZ31cbiAgICovXG4gIHN5bW1ldHJpYzoge1xuICAgIHBsYWludGV4dDogMCxcbiAgICAvKiogTm90IGltcGxlbWVudGVkISAqL1xuICAgIGlkZWE6IDEsXG4gICAgdHJpcGxlZGVzOiAyLFxuICAgIGNhc3Q1OiAzLFxuICAgIGJsb3dmaXNoOiA0LFxuICAgIGFlczEyODogNyxcbiAgICBhZXMxOTI6IDgsXG4gICAgYWVzMjU2OiA5LFxuICAgIHR3b2Zpc2g6IDEwXG4gIH0sXG5cbiAgLyoqIFJGQzQ4ODAsIHNlY3Rpb24gOS4zXG4gICAqIEBlbnVtIHtTdHJpbmd9XG4gICAqL1xuICBjb21wcmVzc2lvbjoge1xuICAgIHVuY29tcHJlc3NlZDogMCxcbiAgICAvKiogUkZDMTk1MSAqL1xuICAgIHppcDogMSxcbiAgICAvKiogUkZDMTk1MCAqL1xuICAgIHpsaWI6IDIsXG4gICAgYnppcDI6IDNcbiAgfSxcblxuICAvKiogUkZDNDg4MCwgc2VjdGlvbiA5LjRcbiAgICogQGVudW0ge1N0cmluZ31cbiAgICovXG4gIGhhc2g6IHtcbiAgICBtZDU6IDEsXG4gICAgc2hhMTogMixcbiAgICByaXBlbWQ6IDMsXG4gICAgc2hhMjU2OiA4LFxuICAgIHNoYTM4NDogOSxcbiAgICBzaGE1MTI6IDEwLFxuICAgIHNoYTIyNDogMTFcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBAZW51bSB7U3RyaW5nfVxuICAgKiBBIGxpc3Qgb2YgcGFja2V0IHR5cGVzIGFuZCBudW1lcmljIHRhZ3MgYXNzb2NpYXRlZCB3aXRoIHRoZW0uXG4gICAqL1xuICBwYWNrZXQ6IHtcbiAgICBwdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleTogMSxcbiAgICBzaWduYXR1cmU6IDIsXG4gICAgc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleTogMyxcbiAgICBvbmVfcGFzc19zaWduYXR1cmU6IDQsXG4gICAgc2VjcmV0X2tleTogNSxcbiAgICBwdWJsaWNfa2V5OiA2LFxuICAgIHNlY3JldF9zdWJrZXk6IDcsXG4gICAgY29tcHJlc3NlZDogOCxcbiAgICBzeW1tZXRyaWNhbGx5X2VuY3J5cHRlZDogOSxcbiAgICBtYXJrZXI6IDEwLFxuICAgIGxpdGVyYWw6IDExLFxuICAgIHRydXN0OiAxMixcbiAgICB1c2VyaWQ6IDEzLFxuICAgIHB1YmxpY19zdWJrZXk6IDE0LFxuICAgIHVzZXJfYXR0cmlidXRlOiAxNyxcbiAgICBzeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQ6IDE4LFxuICAgIG1vZGlmaWNhdGlvbl9kZXRlY3Rpb25fY29kZTogMTlcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBEYXRhIHR5cGVzIGluIHRoZSBsaXRlcmFsIHBhY2tldFxuICAgKiBAcmVhZG9ubHlcbiAgICogQGVudW0ge1N0cmluZ31cbiAgICovXG4gIGxpdGVyYWw6IHtcbiAgICAvKiogQmluYXJ5IGRhdGEgKi9cbiAgICBiaW5hcnk6ICdiJy5jaGFyQ29kZUF0KCksXG4gICAgLyoqIFRleHQgZGF0YSAqL1xuICAgIHRleHQ6ICd0Jy5jaGFyQ29kZUF0KCksXG4gICAgLyoqIFV0ZjggZGF0YSAqL1xuICAgIHV0Zjg6ICd1Jy5jaGFyQ29kZUF0KClcbiAgfSxcblxuXG4gIC8qKiBPbmUgcGFzcyBzaWduYXR1cmUgcGFja2V0IHR5cGVcbiAgICogQGVudW0ge1N0cmluZ30gKi9cbiAgc2lnbmF0dXJlOiB7XG4gICAgLyoqIDB4MDA6IFNpZ25hdHVyZSBvZiBhIGJpbmFyeSBkb2N1bWVudC4gKi9cbiAgICBiaW5hcnk6IDAsXG4gICAgLyoqIDB4MDE6IFNpZ25hdHVyZSBvZiBhIGNhbm9uaWNhbCB0ZXh0IGRvY3VtZW50LlxuICAgICAqIENhbm9uaWNhbHl6aW5nIHRoZSBkb2N1bWVudCBieSBjb252ZXJ0aW5nIGxpbmUgZW5kaW5ncy4gKi9cbiAgICB0ZXh0OiAxLFxuICAgIC8qKiAweDAyOiBTdGFuZGFsb25lIHNpZ25hdHVyZS5cbiAgICAgKiBUaGlzIHNpZ25hdHVyZSBpcyBhIHNpZ25hdHVyZSBvZiBvbmx5IGl0cyBvd24gc3VicGFja2V0IGNvbnRlbnRzLlxuICAgICAqIEl0IGlzIGNhbGN1bGF0ZWQgaWRlbnRpY2FsbHkgdG8gYSBzaWduYXR1cmUgb3ZlciBhIHplcm8tbGVuZ2hcbiAgICAgKiBiaW5hcnkgZG9jdW1lbnQuICBOb3RlIHRoYXQgaXQgZG9lc24ndCBtYWtlIHNlbnNlIHRvIGhhdmUgYSBWM1xuICAgICAqIHN0YW5kYWxvbmUgc2lnbmF0dXJlLiAqL1xuICAgIHN0YW5kYWxvbmU6IDIsXG4gICAgLyoqIDB4MTA6IEdlbmVyaWMgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQgYW5kIFB1YmxpYy1LZXkgcGFja2V0LlxuICAgICAqIFRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIGRvZXMgbm90IG1ha2UgYW55IHBhcnRpY3VsYXJcbiAgICAgKiBhc3NlcnRpb24gYXMgdG8gaG93IHdlbGwgdGhlIGNlcnRpZmllciBoYXMgY2hlY2tlZCB0aGF0IHRoZSBvd25lclxuICAgICAqIG9mIHRoZSBrZXkgaXMgaW4gZmFjdCB0aGUgcGVyc29uIGRlc2NyaWJlZCBieSB0aGUgVXNlciBJRC4gKi9cbiAgICBjZXJ0X2dlbmVyaWM6IDE2LFxuICAgIC8qKiAweDExOiBQZXJzb25hIGNlcnRpZmljYXRpb24gb2YgYSBVc2VyIElEIGFuZCBQdWJsaWMtS2V5IHBhY2tldC5cbiAgICAgKiBUaGUgaXNzdWVyIG9mIHRoaXMgY2VydGlmaWNhdGlvbiBoYXMgbm90IGRvbmUgYW55IHZlcmlmaWNhdGlvbiBvZlxuICAgICAqIHRoZSBjbGFpbSB0aGF0IHRoZSBvd25lciBvZiB0aGlzIGtleSBpcyB0aGUgVXNlciBJRCBzcGVjaWZpZWQuICovXG4gICAgY2VydF9wZXJzb25hOiAxNyxcbiAgICAvKiogMHgxMjogQ2FzdWFsIGNlcnRpZmljYXRpb24gb2YgYSBVc2VyIElEIGFuZCBQdWJsaWMtS2V5IHBhY2tldC5cbiAgICAgKiBUaGUgaXNzdWVyIG9mIHRoaXMgY2VydGlmaWNhdGlvbiBoYXMgZG9uZSBzb21lIGNhc3VhbFxuICAgICAqIHZlcmlmaWNhdGlvbiBvZiB0aGUgY2xhaW0gb2YgaWRlbnRpdHkuICovXG4gICAgY2VydF9jYXN1YWw6IDE4LFxuICAgIC8qKiAweDEzOiBQb3NpdGl2ZSBjZXJ0aWZpY2F0aW9uIG9mIGEgVXNlciBJRCBhbmQgUHVibGljLUtleSBwYWNrZXQuXG4gICAgICogVGhlIGlzc3VlciBvZiB0aGlzIGNlcnRpZmljYXRpb24gaGFzIGRvbmUgc3Vic3RhbnRpYWxcbiAgICAgKiB2ZXJpZmljYXRpb24gb2YgdGhlIGNsYWltIG9mIGlkZW50aXR5LlxuICAgICAqIFxuICAgICAqIE1vc3QgT3BlblBHUCBpbXBsZW1lbnRhdGlvbnMgbWFrZSB0aGVpciBcImtleSBzaWduYXR1cmVzXCIgYXMgMHgxMFxuICAgICAqIGNlcnRpZmljYXRpb25zLiAgU29tZSBpbXBsZW1lbnRhdGlvbnMgY2FuIGlzc3VlIDB4MTEtMHgxM1xuICAgICAqIGNlcnRpZmljYXRpb25zLCBidXQgZmV3IGRpZmZlcmVudGlhdGUgYmV0d2VlbiB0aGUgdHlwZXMuICovXG4gICAgY2VydF9wb3NpdGl2ZTogMTksXG4gICAgLyoqIDB4MzA6IENlcnRpZmljYXRpb24gcmV2b2NhdGlvbiBzaWduYXR1cmVcbiAgICAgKiBUaGlzIHNpZ25hdHVyZSByZXZva2VzIGFuIGVhcmxpZXIgVXNlciBJRCBjZXJ0aWZpY2F0aW9uIHNpZ25hdHVyZVxuICAgICAqIChzaWduYXR1cmUgY2xhc3MgMHgxMCB0aHJvdWdoIDB4MTMpIG9yIGRpcmVjdC1rZXkgc2lnbmF0dXJlXG4gICAgICogKDB4MUYpLiAgSXQgc2hvdWxkIGJlIGlzc3VlZCBieSB0aGUgc2FtZSBrZXkgdGhhdCBpc3N1ZWQgdGhlXG4gICAgICogcmV2b2tlZCBzaWduYXR1cmUgb3IgYW4gYXV0aG9yaXplZCByZXZvY2F0aW9uIGtleS4gIFRoZSBzaWduYXR1cmVcbiAgICAgKiBpcyBjb21wdXRlZCBvdmVyIHRoZSBzYW1lIGRhdGEgYXMgdGhlIGNlcnRpZmljYXRlIHRoYXQgaXRcbiAgICAgKiByZXZva2VzLCBhbmQgc2hvdWxkIGhhdmUgYSBsYXRlciBjcmVhdGlvbiBkYXRlIHRoYW4gdGhhdFxuICAgICAqIGNlcnRpZmljYXRlLiAqL1xuICAgIGNlcnRfcmV2b2NhdGlvbjogNDgsXG4gICAgLyoqIDB4MTg6IFN1YmtleSBCaW5kaW5nIFNpZ25hdHVyZVxuICAgICAqIFRoaXMgc2lnbmF0dXJlIGlzIGEgc3RhdGVtZW50IGJ5IHRoZSB0b3AtbGV2ZWwgc2lnbmluZyBrZXkgdGhhdFxuICAgICAqIGluZGljYXRlcyB0aGF0IGl0IG93bnMgdGhlIHN1YmtleS4gIFRoaXMgc2lnbmF0dXJlIGlzIGNhbGN1bGF0ZWRcbiAgICAgKiBkaXJlY3RseSBvbiB0aGUgcHJpbWFyeSBrZXkgYW5kIHN1YmtleSwgYW5kIG5vdCBvbiBhbnkgVXNlciBJRCBvclxuICAgICAqIG90aGVyIHBhY2tldHMuICBBIHNpZ25hdHVyZSB0aGF0IGJpbmRzIGEgc2lnbmluZyBzdWJrZXkgTVVTVCBoYXZlXG4gICAgICogYW4gRW1iZWRkZWQgU2lnbmF0dXJlIHN1YnBhY2tldCBpbiB0aGlzIGJpbmRpbmcgc2lnbmF0dXJlIHRoYXRcbiAgICAgKiBjb250YWlucyBhIDB4MTkgc2lnbmF0dXJlIG1hZGUgYnkgdGhlIHNpZ25pbmcgc3Via2V5IG9uIHRoZVxuICAgICAqIHByaW1hcnkga2V5IGFuZCBzdWJrZXkuICovXG4gICAgc3Via2V5X2JpbmRpbmc6IDI0LFxuICAgIC8qKiAweDE5OiBQcmltYXJ5IEtleSBCaW5kaW5nIFNpZ25hdHVyZVxuXHRcdCogVGhpcyBzaWduYXR1cmUgaXMgYSBzdGF0ZW1lbnQgYnkgYSBzaWduaW5nIHN1YmtleSwgaW5kaWNhdGluZ1xuXHRcdCogdGhhdCBpdCBpcyBvd25lZCBieSB0aGUgcHJpbWFyeSBrZXkgYW5kIHN1YmtleS4gIFRoaXMgc2lnbmF0dXJlXG5cdFx0KiBpcyBjYWxjdWxhdGVkIHRoZSBzYW1lIHdheSBhcyBhIDB4MTggc2lnbmF0dXJlOiBkaXJlY3RseSBvbiB0aGVcblx0XHQqIHByaW1hcnkga2V5IGFuZCBzdWJrZXksIGFuZCBub3Qgb24gYW55IFVzZXIgSUQgb3Igb3RoZXIgcGFja2V0cy5cblx0XHRcblx0XHQqIFdoZW4gYSBzaWduYXR1cmUgaXMgbWFkZSBvdmVyIGEga2V5LCB0aGUgaGFzaCBkYXRhIHN0YXJ0cyB3aXRoIHRoZVxuXHRcdCogb2N0ZXQgMHg5OSwgZm9sbG93ZWQgYnkgYSB0d28tb2N0ZXQgbGVuZ3RoIG9mIHRoZSBrZXksIGFuZCB0aGVuIGJvZHlcblx0XHQqIG9mIHRoZSBrZXkgcGFja2V0LiAgKE5vdGUgdGhhdCB0aGlzIGlzIGFuIG9sZC1zdHlsZSBwYWNrZXQgaGVhZGVyIGZvclxuXHRcdCogYSBrZXkgcGFja2V0IHdpdGggdHdvLW9jdGV0IGxlbmd0aC4pICBBIHN1YmtleSBiaW5kaW5nIHNpZ25hdHVyZVxuXHRcdCogKHR5cGUgMHgxOCkgb3IgcHJpbWFyeSBrZXkgYmluZGluZyBzaWduYXR1cmUgKHR5cGUgMHgxOSkgdGhlbiBoYXNoZXNcblx0XHQqIHRoZSBzdWJrZXkgdXNpbmcgdGhlIHNhbWUgZm9ybWF0IGFzIHRoZSBtYWluIGtleSAoYWxzbyB1c2luZyAweDk5IGFzXG5cdFx0KiB0aGUgZmlyc3Qgb2N0ZXQpLiAqL1xuICAgIGtleV9iaW5kaW5nOiAyNSxcbiAgICAvKiogMHgxRjogU2lnbmF0dXJlIGRpcmVjdGx5IG9uIGEga2V5XG4gICAgICogVGhpcyBzaWduYXR1cmUgaXMgY2FsY3VsYXRlZCBkaXJlY3RseSBvbiBhIGtleS4gIEl0IGJpbmRzIHRoZVxuICAgICAqIGluZm9ybWF0aW9uIGluIHRoZSBTaWduYXR1cmUgc3VicGFja2V0cyB0byB0aGUga2V5LCBhbmQgaXNcbiAgICAgKiBhcHByb3ByaWF0ZSB0byBiZSB1c2VkIGZvciBzdWJwYWNrZXRzIHRoYXQgcHJvdmlkZSBpbmZvcm1hdGlvblxuICAgICAqIGFib3V0IHRoZSBrZXksIHN1Y2ggYXMgdGhlIFJldm9jYXRpb24gS2V5IHN1YnBhY2tldC4gIEl0IGlzIGFsc29cbiAgICAgKiBhcHByb3ByaWF0ZSBmb3Igc3RhdGVtZW50cyB0aGF0IG5vbi1zZWxmIGNlcnRpZmllcnMgd2FudCB0byBtYWtlXG4gICAgICogYWJvdXQgdGhlIGtleSBpdHNlbGYsIHJhdGhlciB0aGFuIHRoZSBiaW5kaW5nIGJldHdlZW4gYSBrZXkgYW5kIGFcbiAgICAgKiBuYW1lLiAqL1xuICAgIGtleTogMzEsXG4gICAgLyoqIDB4MjA6IEtleSByZXZvY2F0aW9uIHNpZ25hdHVyZVxuICAgICAqIFRoZSBzaWduYXR1cmUgaXMgY2FsY3VsYXRlZCBkaXJlY3RseSBvbiB0aGUga2V5IGJlaW5nIHJldm9rZWQuICBBXG4gICAgICogcmV2b2tlZCBrZXkgaXMgbm90IHRvIGJlIHVzZWQuICBPbmx5IHJldm9jYXRpb24gc2lnbmF0dXJlcyBieSB0aGVcbiAgICAgKiBrZXkgYmVpbmcgcmV2b2tlZCwgb3IgYnkgYW4gYXV0aG9yaXplZCByZXZvY2F0aW9uIGtleSwgc2hvdWxkIGJlXG4gICAgICogY29uc2lkZXJlZCB2YWxpZCByZXZvY2F0aW9uIHNpZ25hdHVyZXMuYSAqL1xuICAgIGtleV9yZXZvY2F0aW9uOiAzMixcbiAgICAvKiogMHgyODogU3Via2V5IHJldm9jYXRpb24gc2lnbmF0dXJlXG4gICAgICogVGhlIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkIGRpcmVjdGx5IG9uIHRoZSBzdWJrZXkgYmVpbmcgcmV2b2tlZC5cbiAgICAgKiBBIHJldm9rZWQgc3Via2V5IGlzIG5vdCB0byBiZSB1c2VkLiAgT25seSByZXZvY2F0aW9uIHNpZ25hdHVyZXNcbiAgICAgKiBieSB0aGUgdG9wLWxldmVsIHNpZ25hdHVyZSBrZXkgdGhhdCBpcyBib3VuZCB0byB0aGlzIHN1YmtleSwgb3JcbiAgICAgKiBieSBhbiBhdXRob3JpemVkIHJldm9jYXRpb24ga2V5LCBzaG91bGQgYmUgY29uc2lkZXJlZCB2YWxpZFxuICAgICAqIHJldm9jYXRpb24gc2lnbmF0dXJlcy5cbiAgICAgKiBLZXkgcmV2b2NhdGlvbiBzaWduYXR1cmVzICh0eXBlcyAweDIwIGFuZCAweDI4KVxuICAgICAqIGhhc2ggb25seSB0aGUga2V5IGJlaW5nIHJldm9rZWQuICovXG4gICAgc3Via2V5X3Jldm9jYXRpb246IDQwLFxuICAgIC8qKiAweDQwOiBUaW1lc3RhbXAgc2lnbmF0dXJlLlxuICAgICAqIFRoaXMgc2lnbmF0dXJlIGlzIG9ubHkgbWVhbmluZ2Z1bCBmb3IgdGhlIHRpbWVzdGFtcCBjb250YWluZWQgaW5cbiAgICAgKiBpdC4gKi9cbiAgICB0aW1lc3RhbXA6IDY0LFxuICAgIC8qKiAgICAweDUwOiBUaGlyZC1QYXJ0eSBDb25maXJtYXRpb24gc2lnbmF0dXJlLlxuICAgICAqIFRoaXMgc2lnbmF0dXJlIGlzIGEgc2lnbmF0dXJlIG92ZXIgc29tZSBvdGhlciBPcGVuUEdQIFNpZ25hdHVyZVxuICAgICAqIHBhY2tldChzKS4gIEl0IGlzIGFuYWxvZ291cyB0byBhIG5vdGFyeSBzZWFsIG9uIHRoZSBzaWduZWQgZGF0YS5cbiAgICAgKiBBIHRoaXJkLXBhcnR5IHNpZ25hdHVyZSBTSE9VTEQgaW5jbHVkZSBTaWduYXR1cmUgVGFyZ2V0XG4gICAgICogc3VicGFja2V0KHMpIHRvIGdpdmUgZWFzeSBpZGVudGlmaWNhdGlvbi4gIE5vdGUgdGhhdCB3ZSByZWFsbHkgZG9cbiAgICAgKiBtZWFuIFNIT1VMRC4gIFRoZXJlIGFyZSBwbGF1c2libGUgdXNlcyBmb3IgdGhpcyAoc3VjaCBhcyBhIGJsaW5kXG4gICAgICogcGFydHkgdGhhdCBvbmx5IHNlZXMgdGhlIHNpZ25hdHVyZSwgbm90IHRoZSBrZXkgb3Igc291cmNlXG4gICAgICogZG9jdW1lbnQpIHRoYXQgY2Fubm90IGluY2x1ZGUgYSB0YXJnZXQgc3VicGFja2V0LiAqL1xuICAgIHRoaXJkX3BhcnR5OiA4MFxuICB9LFxuXG4gIHNpZ25hdHVyZVN1YnBhY2tldDoge1xuICAgIHNpZ25hdHVyZV9jcmVhdGlvbl90aW1lOiAyLFxuICAgIHNpZ25hdHVyZV9leHBpcmF0aW9uX3RpbWU6IDMsXG4gICAgZXhwb3J0YWJsZV9jZXJ0aWZpY2F0aW9uOiA0LFxuICAgIHRydXN0X3NpZ25hdHVyZTogNSxcbiAgICByZWd1bGFyX2V4cHJlc3Npb246IDYsXG4gICAgcmV2b2NhYmxlOiA3LFxuICAgIGtleV9leHBpcmF0aW9uX3RpbWU6IDksXG4gICAgcGxhY2Vob2xkZXJfYmFja3dhcmRzX2NvbXBhdGliaWxpdHk6IDEwLFxuICAgIHByZWZlcnJlZF9zeW1tZXRyaWNfYWxnb3JpdGhtczogMTEsXG4gICAgcmV2b2NhdGlvbl9rZXk6IDEyLFxuICAgIGlzc3VlcjogMTYsXG4gICAgbm90YXRpb25fZGF0YTogMjAsXG4gICAgcHJlZmVycmVkX2hhc2hfYWxnb3JpdGhtczogMjEsXG4gICAgcHJlZmVycmVkX2NvbXByZXNzaW9uX2FsZ29yaXRobXM6IDIyLFxuICAgIGtleV9zZXJ2ZXJfcHJlZmVyZW5jZXM6IDIzLFxuICAgIHByZWZlcnJlZF9rZXlfc2VydmVyOiAyNCxcbiAgICBwcmltYXJ5X3VzZXJfaWQ6IDI1LFxuICAgIHBvbGljeV91cmk6IDI2LFxuICAgIGtleV9mbGFnczogMjcsXG4gICAgc2lnbmVyc191c2VyX2lkOiAyOCxcbiAgICByZWFzb25fZm9yX3Jldm9jYXRpb246IDI5LFxuICAgIGZlYXR1cmVzOiAzMCxcbiAgICBzaWduYXR1cmVfdGFyZ2V0OiAzMSxcbiAgICBlbWJlZGRlZF9zaWduYXR1cmU6IDMyXG4gIH0sXG5cbiAga2V5RmxhZ3M6IHtcbiAgICAvLyAweDAxIC0gVGhpcyBrZXkgbWF5IGJlIHVzZWQgdG8gY2VydGlmeSBvdGhlciBrZXlzLlxuICAgIGNlcnRpZnlfa2V5czogMSxcbiAgICAvLyAweDAyIC0gVGhpcyBrZXkgbWF5IGJlIHVzZWQgdG8gc2lnbiBkYXRhLlxuICAgIHNpZ25fZGF0YTogMixcbiAgICAvLyAweDA0IC0gVGhpcyBrZXkgbWF5IGJlIHVzZWQgdG8gZW5jcnlwdCBjb21tdW5pY2F0aW9ucy5cbiAgICBlbmNyeXB0X2NvbW11bmljYXRpb246IDQsXG4gICAgLy8gMHgwOCAtIFRoaXMga2V5IG1heSBiZSB1c2VkIHRvIGVuY3J5cHQgc3RvcmFnZS5cbiAgICBlbmNyeXB0X3N0b3JhZ2U6IDgsXG4gICAgLy8gMHgxMCAtIFRoZSBwcml2YXRlIGNvbXBvbmVudCBvZiB0aGlzIGtleSBtYXkgaGF2ZSBiZWVuIHNwbGl0XG4gICAgLy8gICAgICAgIGJ5IGEgc2VjcmV0LXNoYXJpbmcgbWVjaGFuaXNtLlxuICAgIHNwbGl0X3ByaXZhdGVfa2V5OiAxNixcbiAgICAvLyAweDIwIC0gVGhpcyBrZXkgbWF5IGJlIHVzZWQgZm9yIGF1dGhlbnRpY2F0aW9uLlxuICAgIGF1dGhlbnRpY2F0aW9uOiAzMixcbiAgICAvLyAweDgwIC0gVGhlIHByaXZhdGUgY29tcG9uZW50IG9mIHRoaXMga2V5IG1heSBiZSBpbiB0aGVcbiAgICAvLyAgICAgICAgcG9zc2Vzc2lvbiBvZiBtb3JlIHRoYW4gb25lIHBlcnNvbi5cbiAgICBzaGFyZWRfcHJpdmF0ZV9rZXk6IDEyOFxuICB9LFxuXG4gIGFybW9yOiB7XG4gICAgbXVsdGlwYXJ0X3NlY3Rpb246IDAsXG4gICAgbXVsdGlwYXJ0X2xhc3Q6IDEsXG4gICAgc2lnbmVkOiAyLFxuICAgIG1lc3NhZ2U6IDMsXG4gICAgcHVibGljX2tleTogNCxcbiAgICBwcml2YXRlX2tleTogNVxuICB9LFxuXG4gIC8vIEFzc2VydHMgdmFsaWRpdHkgYW5kIGNvbnZlcnRzIGZyb20gc3RyaW5nL2ludGVnZXIgdG8gaW50ZWdlci5cbiAgd3JpdGU6IGZ1bmN0aW9uKHR5cGUsIGUpIHtcbiAgICBpZiAodHlwZW9mIGUgPT0gJ251bWJlcicpIHtcbiAgICAgIGUgPSB0aGlzLnJlYWQodHlwZSwgZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVbZV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHR5cGVbZV07XG4gICAgfSBlbHNlIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBlbnVtIHZhbHVlLicpO1xuICB9LFxuICAvLyBDb252ZXJ0cyBmcm9tIGFuIGludGVnZXIgdG8gc3RyaW5nLlxuICByZWFkOiBmdW5jdGlvbih0eXBlLCBlKSB7XG4gICAgZm9yICh2YXIgaSBpbiB0eXBlKVxuICAgICAgaWYgKHR5cGVbaV0gPT0gZSkgcmV0dXJuIGk7XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZW51bSB2YWx1ZS4nKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVudW1zO1xuIiwiXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vb3BlbnBncC5qcycpO1xubW9kdWxlLmV4cG9ydHMua2V5ID0gcmVxdWlyZSgnLi9rZXkuanMnKTtcbm1vZHVsZS5leHBvcnRzLm1lc3NhZ2UgPSByZXF1aXJlKCcuL21lc3NhZ2UuanMnKTtcbm1vZHVsZS5leHBvcnRzLmNsZWFydGV4dCA9IHJlcXVpcmUoJy4vY2xlYXJ0ZXh0LmpzJyk7XG5tb2R1bGUuZXhwb3J0cy51dGlsID0gcmVxdWlyZSgnLi91dGlsJyk7XG5tb2R1bGUuZXhwb3J0cy5wYWNrZXQgPSByZXF1aXJlKCcuL3BhY2tldCcpO1xubW9kdWxlLmV4cG9ydHMubXBpID0gcmVxdWlyZSgnLi90eXBlL21waS5qcycpO1xubW9kdWxlLmV4cG9ydHMuczJrID0gcmVxdWlyZSgnLi90eXBlL3Myay5qcycpO1xubW9kdWxlLmV4cG9ydHMua2V5aWQgPSByZXF1aXJlKCcuL3R5cGUva2V5aWQuanMnKTtcbm1vZHVsZS5leHBvcnRzLmFybW9yID0gcmVxdWlyZSgnLi9lbmNvZGluZy9hcm1vci5qcycpO1xubW9kdWxlLmV4cG9ydHMuZW51bXMgPSByZXF1aXJlKCcuL2VudW1zLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5jb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZycpO1xubW9kdWxlLmV4cG9ydHMuY3J5cHRvID0gcmVxdWlyZSgnLi9jcnlwdG8nKTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBwYWNrZXQgPSByZXF1aXJlKCcuL3BhY2tldCcpO1xudmFyIGVudW1zID0gcmVxdWlyZSgnLi9lbnVtcy5qcycpO1xudmFyIGFybW9yID0gcmVxdWlyZSgnLi9lbmNvZGluZy9hcm1vci5qcycpO1xudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhbiBPcGVuUEdQIGtleS4gTXVzdCBjb250YWluIGEgcHJpbWFyeSBrZXkuXG4gKiBDYW4gY29udGFpbiBhZGRpdGlvbmFsIHN1YmtleXMsIHNpZ25hdHVyZXMsIHVzZXIgaWRzLCB1c2VyIGF0dHJpYnV0ZXMuXG4gKiBAcGFyYW0gIHtwYWNrZXRsaXN0fSBwYWNrZXRsaXN0IFRoZSBwYWNrZXRzIHRoYXQgZm9ybSB0aGlzIGtleVxuICovXG5cbmZ1bmN0aW9uIEtleShwYWNrZXRsaXN0KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBLZXkpKSB7XG4gICAgcmV0dXJuIG5ldyBLZXkocGFja2V0bGlzdCk7XG4gIH1cbiAgdGhpcy5wYWNrZXRzID0gcGFja2V0bGlzdCB8fCBuZXcgcGFja2V0Lmxpc3QoKTtcbn1cblxuLyoqIFxuICogUmV0dXJucyB0aGUgcHJpbWFyeSBrZXkgcGFja2V0IChzZWNyZXQgb3IgcHVibGljKVxuICogQHJldHVybnMge3BhY2tldF9zZWNyZXRfa2V5fHBhY2tldF9wdWJsaWNfa2V5fG51bGx9IFxuICovXG5LZXkucHJvdG90eXBlLmdldEtleVBhY2tldCA9IGZ1bmN0aW9uKCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFja2V0cy5sZW5ndGg7IGkrKykge1xuICAgIGlmICh0aGlzLnBhY2tldHNbaV0udGFnID09IGVudW1zLnBhY2tldC5wdWJsaWNfa2V5IHx8XG4gICAgICB0aGlzLnBhY2tldHNbaV0udGFnID09IGVudW1zLnBhY2tldC5zZWNyZXRfa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5wYWNrZXRzW2ldO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn07XG5cbi8qKiBcbiAqIFJldHVybnMgYWxsIHRoZSBwcml2YXRlIGFuZCBwdWJsaWMgc3Via2V5IHBhY2tldHNcbiAqIEByZXR1cm5zIHtbcHVibGljX3N1YmtleXxzZWNyZXRfc3Via2V5XX0gXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0U3Via2V5UGFja2V0cyA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBzdWJrZXlzID0gW107XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBhY2tldHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAodGhpcy5wYWNrZXRzW2ldLnRhZyA9PSBlbnVtcy5wYWNrZXQucHVibGljX3N1YmtleSB8fFxuICAgICAgdGhpcy5wYWNrZXRzW2ldLnRhZyA9PSBlbnVtcy5wYWNrZXQuc2VjcmV0X3N1YmtleSkge1xuICAgICAgc3Via2V5cy5wdXNoKHRoaXMucGFja2V0c1tpXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHN1YmtleXM7XG59O1xuXG4vKiogXG4gKiBSZXR1cm5zIGFsbCB0aGUgcHJpdmF0ZSBhbmQgcHVibGljIGtleSBhbmQgc3Via2V5IHBhY2tldHNcbiAqIEByZXR1cm5zIHtbcHVibGljX3N1YmtleXxzZWNyZXRfc3Via2V5fHBhY2tldF9zZWNyZXRfa2V5fHBhY2tldF9wdWJsaWNfa2V5XX0gXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0QWxsS2V5UGFja2V0cyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gW3RoaXMuZ2V0S2V5UGFja2V0KCldLmNvbmNhdCh0aGlzLmdldFN1YmtleVBhY2tldHMoKSk7XG59O1xuXG4vKiogXG4gKiBSZXR1cm5zIGtleSBJRHMgb2YgYWxsIGtleSBwYWNrZXRzXG4gKiBAcmV0dXJucyB7W2tleWlkXX0gXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0S2V5SWRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrZXlJZHMgPSBbXTtcbiAgdmFyIGtleXMgPSB0aGlzLmdldEFsbEtleVBhY2tldHMoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAga2V5SWRzLnB1c2goa2V5c1tpXS5nZXRLZXlJZCgpKTtcbiAgfVxuICByZXR1cm4ga2V5SWRzO1xufTtcblxuZnVuY3Rpb24gZmluZEtleShrZXlzLCBrZXlJZHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGtleUlkID0ga2V5c1tpXS5nZXRLZXlJZCgpOyBcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleUlkcy5sZW5ndGg7IGorKykge1xuICAgICAgaWYgKGtleUlkLmVxdWFscyhrZXlJZHNbal0pKSB7XG4gICAgICAgIHJldHVybiBrZXlzW2ldO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGZpcnN0IHB1YmxpYyBrZXkgcGFja2V0IGZvciBnaXZlbiBhcnJheSBvZiBrZXkgSURzXG4gKiBAcGFyYW0gIHtba2V5aWRdfSBrZXlJZHMgXG4gKiBAcmV0dXJuIHtwdWJsaWNfc3Via2V5fHBhY2tldF9wdWJsaWNfa2V5fG51bGx9ICAgICAgIFxuICovXG5LZXkucHJvdG90eXBlLmdldFB1YmxpY0tleVBhY2tldCA9IGZ1bmN0aW9uKGtleUlkcykge1xuICB2YXIga2V5cyA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQucHVibGljX2tleSwgZW51bXMucGFja2V0LnB1YmxpY19zdWJrZXkpO1xuICByZXR1cm4gZmluZEtleShrZXlzLCBrZXlJZHMpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGZpcnN0IHByaXZhdGUga2V5IHBhY2tldCBmb3IgZ2l2ZW4gYXJyYXkgb2Yga2V5IElEc1xuICogQHBhcmFtICB7W2tleWlkXX0ga2V5SWRzXG4gKiBAcmV0dXJuIHtzZWNyZXRfc3Via2V5fHBhY2tldF9zZWNyZXRfa2V5fG51bGx9ICAgICAgIFxuICovXG5LZXkucHJvdG90eXBlLmdldFByaXZhdGVLZXlQYWNrZXQgPSBmdW5jdGlvbihrZXlJZHMpIHtcbiAgdmFyIGtleXMgPSB0aGlzLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnNlY3JldF9rZXksIGVudW1zLnBhY2tldC5zZWNyZXRfc3Via2V5KTtcbiAgcmV0dXJuIGZpbmRLZXkoa2V5cywga2V5SWRzKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYSBwdWJsaWMga2V5XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5LZXkucHJvdG90eXBlLmlzUHVibGljID0gZnVuY3Rpb24oKSB7XG4gIHZhciBwdWJsaWNLZXlQYWNrZXRzID0gdGhpcy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5wdWJsaWNfa2V5KTtcbiAgcmV0dXJuIHB1YmxpY0tleVBhY2tldHMubGVuZ3RoID8gdHJ1ZSA6IGZhbHNlO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIHByaXZhdGUga2V5XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5LZXkucHJvdG90eXBlLmlzUHJpdmF0ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcHJpdmF0ZUtleVBhY2tldHMgPSB0aGlzLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnByaXZhdGVfa2V5KTtcbiAgcmV0dXJuIHByaXZhdGVLZXlQYWNrZXRzLmxlbmd0aCA/IHRydWUgOiBmYWxzZTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBrZXkgYXMgcHVibGljIGtleVxuICogQHJldHVybiB7a2V5fSBwdWJsaWMga2V5XG4gKi9cbktleS5wcm90b3R5cGUudG9QdWJsaWMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBhY2tldHMubGVuZ3RoOyBpKyspIHtcbiAgICBzd2l0Y2ggKHRoaXMucGFja2V0c1tpXS50YWcpIHtcbiAgICAgIGNhc2UgZW51bXMucGFja2V0LnNlY3JldF9rZXk6XG4gICAgICAgIHZhciBieXRlcyA9IHRoaXMucGFja2V0c1tpXS53cml0ZVB1YmxpY0tleSgpO1xuICAgICAgICB2YXIgcHViS2V5UGFja2V0ID0gbmV3IHBhY2tldC5wdWJsaWNfa2V5KCk7XG4gICAgICAgIHB1YktleVBhY2tldC5yZWFkKGJ5dGVzKTtcbiAgICAgICAgcGFja2V0bGlzdC5wdXNoKHB1YktleVBhY2tldCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBlbnVtcy5wYWNrZXQuc2VjcmV0X3N1YmtleTpcbiAgICAgICAgdmFyIGJ5dGVzID0gdGhpcy5wYWNrZXRzW2ldLndyaXRlUHVibGljS2V5KCk7XG4gICAgICAgIHZhciBwdWJTdWJrZXlQYWNrZXQgPSBuZXcgcGFja2V0LnB1YmxpY19zdWJrZXkoKTtcbiAgICAgICAgcHViU3Via2V5UGFja2V0LnJlYWQoYnl0ZXMpO1xuICAgICAgICBwYWNrZXRsaXN0LnB1c2gocHViU3Via2V5UGFja2V0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBwYWNrZXRsaXN0LnB1c2godGhpcy5wYWNrZXRzW2ldKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5ldyBLZXkocGFja2V0bGlzdCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgQVNDSUkgYXJtb3JlZCB0ZXh0IG9mIGtleVxuICogQHJldHVybiB7U3RyaW5nfSBBU0NJSSBhcm1vclxuICovXG5LZXkucHJvdG90eXBlLmFybW9yID0gZnVuY3Rpb24oKSB7XG4gIHZhciB0eXBlID0gdGhpcy5pc1B1YmxpYygpID8gZW51bXMuYXJtb3IucHVibGljX2tleSA6IGVudW1zLmFybW9yLnByaXZhdGVfa2V5O1xuICByZXR1cm4gYXJtb3IuZW5jb2RlKHR5cGUsIHRoaXMucGFja2V0cy53cml0ZSgpKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBmaXJzdCBrZXkgcGFja2V0IHRoYXQgaXMgYXZhaWxhYmxlIGZvciBzaWduaW5nXG4gKiBAcmV0dXJuIHtwdWJsaWNfc3Via2V5fHNlY3JldF9zdWJrZXl8cGFja2V0X3NlY3JldF9rZXl8cGFja2V0X3B1YmxpY19rZXl8bnVsbH1cbiAqL1xuS2V5LnByb3RvdHlwZS5nZXRTaWduaW5nS2V5UGFja2V0ID0gZnVuY3Rpb24oKSB7XG5cbiAgdmFyIHNpZ25pbmcgPSBbIGVudW1zLnB1YmxpY0tleS5yc2FfZW5jcnlwdF9zaWduLCBlbnVtcy5wdWJsaWNLZXkucnNhX3NpZ24sIGVudW1zLnB1YmxpY0tleS5kc2FdO1xuXG4gIHNpZ25pbmcgPSBzaWduaW5nLm1hcChmdW5jdGlvbihzKSB7XG4gICAgcmV0dXJuIGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBzKTtcbiAgfSk7XG5cbiAgdmFyIGtleXMgPSB0aGlzLmdldEFsbEtleVBhY2tldHMoKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoc2lnbmluZy5pbmRleE9mKGtleXNbaV0uYWxnb3JpdGhtKSAhPT0gLTEpIHtcbiAgICAgIHJldHVybiBrZXlzW2ldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHByZWZlcnJlZCBzaWduYXR1cmUgaGFzaCBhbGdvcml0aG0gb2YgdGhpcyBrZXlcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuS2V5LnByb3RvdHlwZS5nZXRQcmVmZXJyZWRTaWduYXR1cmVIYXNoQWxnb3JpdGhtID0gZnVuY3Rpb24oKSB7XG4gIC8vVE9ETyBpbXBsZW1lbnQ6IGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0ODgwI3NlY3Rpb24tNS4yLjMuOFxuICAvL3NlcGFyYXRlIHByaXZhdGUga2V5IHByZWZlcmVuY2UgZnJvbSBkaWdlc3QgcHJlZmVyZW5jZXNcbiAgcmV0dXJuIGNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG07XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IHZhbGlkIGVuY3J5cHRpb24ga2V5IHBhY2tldCBmb3IgdGhpcyBrZXlcbiAqIEByZXR1cm5zIHtwdWJsaWNfc3Via2V5fHNlY3JldF9zdWJrZXl8cGFja2V0X3NlY3JldF9rZXl8cGFja2V0X3B1YmxpY19rZXl8bnVsbH0ga2V5IHBhY2tldCBvciBudWxsIGlmIG5vIGVuY3J5cHRpb24ga2V5IGhhcyBiZWVuIGZvdW5kXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0RW5jcnlwdGlvbktleVBhY2tldCA9IGZ1bmN0aW9uKCkge1xuICAvLyBWNDogYnkgY29udmVudGlvbiBzdWJrZXlzIGFyZSBwcmVmZXJlZCBmb3IgZW5jcnlwdGlvbiBzZXJ2aWNlXG4gIC8vIFYzOiBrZXlzIE1VU1QgTk9UIGhhdmUgc3Via2V5c1xuICB2YXIgaXNWYWxpZEVuY3J5cHRpb25LZXkgPSBmdW5jdGlvbihrZXkpIHtcbiAgICAvL1RPRE8gZXZhbHVhdGUga2V5IGZsYWdzOiBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0ODgwI3NlY3Rpb24tNS4yLjMuMjFcbiAgICByZXR1cm4ga2V5LmFsZ29yaXRobSAhPSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSwgZW51bXMucHVibGljS2V5LmRzYSkgJiYga2V5LmFsZ29yaXRobSAhPSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSxcbiAgICAgIGVudW1zLnB1YmxpY0tleS5yc2Ffc2lnbik7XG4gICAgLy9UT0RPIHZlcmlmeSBrZXlcbiAgICAvLyYmIGtleXMudmVyaWZ5S2V5KClcbiAgfTtcblxuICB2YXIgc3Via2V5cyA9IHRoaXMuZ2V0U3Via2V5UGFja2V0cygpO1xuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgc3Via2V5cy5sZW5ndGg7IGorKykge1xuICAgIGlmIChpc1ZhbGlkRW5jcnlwdGlvbktleShzdWJrZXlzW2pdKSkge1xuICAgICAgcmV0dXJuIHN1YmtleXNbal07XG4gICAgfVxuICB9XG4gIC8vIGlmIG5vIHZhbGlkIHN1YmtleSBmb3IgZW5jcnlwdGlvbiwgdXNlIHByaW1hcnkga2V5XG4gIHZhciBwcmltYXJ5S2V5ID0gdGhpcy5nZXRLZXlQYWNrZXQoKTtcbiAgaWYgKGlzVmFsaWRFbmNyeXB0aW9uS2V5KHByaW1hcnlLZXkpKSB7XG4gICAgcmV0dXJuIHByaW1hcnlLZXk7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIERlY3J5cHRzIGFsbCBzZWNyZXQga2V5IGFuZCBzdWJrZXkgcGFja2V0c1xuICogQHBhcmFtICB7U3RyaW5nfSBwYXNzcGhyYXNlIFxuICogQHJldHVybiB7Qm9vbGVhbn0gdHJ1ZSBpZiBhbGwga2V5IGFuZCBzdWJrZXkgcGFja2V0cyBkZWNyeXB0ZWQgc3VjY2Vzc2Z1bGx5XG4gKi9cbktleS5wcm90b3R5cGUuZGVjcnlwdCA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UpIHtcbiAgdmFyIGtleXMgPSB0aGlzLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnNlY3JldF9rZXksIGVudW1zLnBhY2tldC5zZWNyZXRfc3Via2V5KTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHN1Y2Nlc3MgPSBrZXlzW2ldLmRlY3J5cHQocGFzc3BocmFzZSk7XG4gICAgaWYgKCFzdWNjZXNzKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIERlY3J5cHRzIHNwZWNpZmljIGtleSBwYWNrZXRzIGJ5IGtleSBJRFxuICogQHBhcmFtICB7W2tleWlkXX0ga2V5SWRzXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHBhc3NwaHJhc2UgXG4gKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIGFsbCBrZXkgcGFja2V0cyBkZWNyeXB0ZWQgc3VjY2Vzc2Z1bGx5XG4gKi9cbktleS5wcm90b3R5cGUuZGVjcnlwdEtleVBhY2tldCA9IGZ1bmN0aW9uKGtleUlkcywgcGFzc3BocmFzZSkge1xuICAvL1RPRE8gcmV0dXJuIHZhbHVlXG4gIHZhciBrZXlzID0gdGhpcy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5zZWNyZXRfa2V5LCBlbnVtcy5wYWNrZXQuc2VjcmV0X3N1YmtleSk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBrZXlJZCA9IGtleXNbaV0uZ2V0S2V5SWQoKTsgXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBrZXlJZHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGlmIChrZXlJZC5lcXVhbHMoa2V5SWRzW2pdKSkge1xuICAgICAgICB2YXIgc3VjY2VzcyA9IGtleXNbaV0uZGVjcnlwdChwYXNzcGhyYXNlKTtcbiAgICAgICAgaWYgKCFzdWNjZXNzKSByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuLy8gVE9ET1xuS2V5LnByb3RvdHlwZS52ZXJpZnkgPSBmdW5jdGlvbigpIHtcblxufTtcbi8vIFRPRE9cbktleS5wcm90b3R5cGUucmV2b2tlID0gZnVuY3Rpb24oKSB7XG5cbn07XG5cbi8qKlxuICogUmVhZHMgYW4gT3BlblBHUCBhcm1vcmVkIHRleHQgYW5kIHJldHVybnMgYSBrZXkgb2JqZWN0XG4gKiBAcGFyYW0ge1N0cmluZ30gYXJtb3JlZFRleHQgdGV4dCB0byBiZSBwYXJzZWRcbiAqIEByZXR1cm4ge2tleX0gbmV3IGtleSBvYmplY3RcbiAqL1xuZnVuY3Rpb24gcmVhZEFybW9yZWQoYXJtb3JlZFRleHQpIHtcbiAgdmFyIGlucHV0ID0gYXJtb3IuZGVjb2RlKGFybW9yZWRUZXh0KTtcbiAgaWYgKCEoaW5wdXQudHlwZSA9PSBlbnVtcy5hcm1vci5wdWJsaWNfa2V5IHx8IGlucHV0LnR5cGUgPT0gZW51bXMuYXJtb3IucHJpdmF0ZV9rZXkpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBcm1vcmVkIHRleHQgbm90IG9mIHR5cGUga2V5Jyk7XG4gIH1cbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgcGFja2V0bGlzdC5yZWFkKGlucHV0LmRhdGEpO1xuICB2YXIgbmV3S2V5ID0gbmV3IEtleShwYWNrZXRsaXN0KTtcbiAgcmV0dXJuIG5ld0tleTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBuZXcgT3BlblBHUCBrZXkuIEN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIFJTQSBrZXlzLlxuICogUHJpbWFyeSBhbmQgc3Via2V5IHdpbGwgYmUgb2Ygc2FtZSB0eXBlLlxuICogQHBhcmFtIHtJbnRlZ2VyfSBrZXlUeXBlICAgIHRvIGluZGljYXRlIHdoYXQgdHlwZSBvZiBrZXkgdG8gbWFrZS4gXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlNBIGlzIDEuIFNlZSBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0ODgwI3NlY3Rpb24tOS4xXG4gKiBAcGFyYW0ge0ludGVnZXJ9IG51bUJpdHMgICAgbnVtYmVyIG9mIGJpdHMgZm9yIHRoZSBrZXkgY3JlYXRpb24uXG4gKiBAcGFyYW0ge1N0cmluZ30gIHVzZXJJZCAgICAgYXNzdW1lcyBhbHJlYWR5IGluIGZvcm0gb2YgXCJVc2VyIE5hbWUgPHVzZXJuYW1lQGVtYWlsLmNvbT5cIlxuICogQHBhcmFtIHtTdHJpbmd9ICBwYXNzcGhyYXNlIFRoZSBwYXNzcGhyYXNlIHVzZWQgdG8gZW5jcnlwdCB0aGUgcmVzdWx0aW5nIHByaXZhdGUga2V5XG4gKiBAcmV0dXJuIHtLZXl9XG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlKGtleVR5cGUsIG51bUJpdHMsIHVzZXJJZCwgcGFzc3BocmFzZSkge1xuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuXG4gIHZhciBzZWNyZXRLZXlQYWNrZXQgPSBuZXcgcGFja2V0LnNlY3JldF9rZXkoKTtcbiAgc2VjcmV0S2V5UGFja2V0LmFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBrZXlUeXBlKTtcbiAgc2VjcmV0S2V5UGFja2V0LmdlbmVyYXRlKG51bUJpdHMpO1xuICBzZWNyZXRLZXlQYWNrZXQuZW5jcnlwdChwYXNzcGhyYXNlKTtcblxuICB2YXIgdXNlcklkUGFja2V0ID0gbmV3IHBhY2tldC51c2VyaWQoKTtcbiAgdXNlcklkUGFja2V0LnJlYWQodXNlcklkKTtcblxuICB2YXIgZGF0YVRvU2lnbiA9IHt9O1xuICBkYXRhVG9TaWduLnVzZXJpZCA9IHVzZXJJZFBhY2tldDtcbiAgZGF0YVRvU2lnbi5rZXkgPSBzZWNyZXRLZXlQYWNrZXQ7XG4gIHZhciBzaWduYXR1cmVQYWNrZXQgPSBuZXcgcGFja2V0LnNpZ25hdHVyZSgpO1xuICBzaWduYXR1cmVQYWNrZXQuc2lnbmF0dXJlVHlwZSA9IGVudW1zLnNpZ25hdHVyZS5jZXJ0X2dlbmVyaWM7XG4gIHNpZ25hdHVyZVBhY2tldC5wdWJsaWNLZXlBbGdvcml0aG0gPSBrZXlUeXBlO1xuICAvL1RPRE8gd2Ugc2hvdWxkIGxvYWQgcHJlZmVycmVkIGhhc2ggZnJvbSBjb25maWcsIG9yIGFzIGlucHV0IHRvIHRoaXMgZnVuY3Rpb25cbiAgc2lnbmF0dXJlUGFja2V0Lmhhc2hBbGdvcml0aG0gPSBlbnVtcy5oYXNoLnNoYTI1NjtcbiAgc2lnbmF0dXJlUGFja2V0LmtleUZsYWdzID0gW2VudW1zLmtleUZsYWdzLmNlcnRpZnlfa2V5cyB8IGVudW1zLmtleUZsYWdzLnNpZ25fZGF0YV07XG4gIHNpZ25hdHVyZVBhY2tldC5zaWduKHNlY3JldEtleVBhY2tldCwgZGF0YVRvU2lnbik7XG5cbiAgdmFyIHNlY3JldFN1YmtleVBhY2tldCA9IG5ldyBwYWNrZXQuc2VjcmV0X3N1YmtleSgpO1xuICBzZWNyZXRTdWJrZXlQYWNrZXQuYWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIGtleVR5cGUpO1xuICBzZWNyZXRTdWJrZXlQYWNrZXQuZ2VuZXJhdGUobnVtQml0cyk7XG4gIHNlY3JldFN1YmtleVBhY2tldC5lbmNyeXB0KHBhc3NwaHJhc2UpO1xuXG4gIGRhdGFUb1NpZ24gPSB7fTtcbiAgZGF0YVRvU2lnbi5rZXkgPSBzZWNyZXRLZXlQYWNrZXQ7XG4gIGRhdGFUb1NpZ24uYmluZCA9IHNlY3JldFN1YmtleVBhY2tldDtcbiAgdmFyIHN1YmtleVNpZ25hdHVyZVBhY2tldCA9IG5ldyBwYWNrZXQuc2lnbmF0dXJlKCk7XG4gIHN1YmtleVNpZ25hdHVyZVBhY2tldC5zaWduYXR1cmVUeXBlID0gZW51bXMuc2lnbmF0dXJlLnN1YmtleV9iaW5kaW5nO1xuICBzdWJrZXlTaWduYXR1cmVQYWNrZXQucHVibGljS2V5QWxnb3JpdGhtID0ga2V5VHlwZTtcbiAgLy9UT0RPIHdlIHNob3VsZCBsb2FkIHByZWZlcnJlZCBoYXNoIGZyb20gY29uZmlnLCBvciBhcyBpbnB1dCB0byB0aGlzIGZ1bmN0aW9uXG4gIHN1YmtleVNpZ25hdHVyZVBhY2tldC5oYXNoQWxnb3JpdGhtID0gZW51bXMuaGFzaC5zaGEyNTY7XG4gIHN1YmtleVNpZ25hdHVyZVBhY2tldC5rZXlGbGFncyA9IFtlbnVtcy5rZXlGbGFncy5lbmNyeXB0X2NvbW11bmljYXRpb24gfCBlbnVtcy5rZXlGbGFncy5lbmNyeXB0X3N0b3JhZ2VdO1xuICBzdWJrZXlTaWduYXR1cmVQYWNrZXQuc2lnbihzZWNyZXRLZXlQYWNrZXQsIGRhdGFUb1NpZ24pO1xuXG4gIHBhY2tldGxpc3QucHVzaChzZWNyZXRLZXlQYWNrZXQpO1xuICBwYWNrZXRsaXN0LnB1c2godXNlcklkUGFja2V0KTtcbiAgcGFja2V0bGlzdC5wdXNoKHNpZ25hdHVyZVBhY2tldCk7XG4gIHBhY2tldGxpc3QucHVzaChzZWNyZXRTdWJrZXlQYWNrZXQpO1xuICBwYWNrZXRsaXN0LnB1c2goc3Via2V5U2lnbmF0dXJlUGFja2V0KTtcblxuICByZXR1cm4gbmV3IEtleShwYWNrZXRsaXN0KTtcbn1cblxuZXhwb3J0cy5LZXkgPSBLZXk7XG5leHBvcnRzLnJlYWRBcm1vcmVkID0gcmVhZEFybW9yZWQ7XG5leHBvcnRzLmdlbmVyYXRlID0gZ2VuZXJhdGU7XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgcGFja2V0ID0gcmVxdWlyZSgnLi9wYWNrZXQnKTtcbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4vZW51bXMuanMnKTtcbnZhciBhcm1vciA9IHJlcXVpcmUoJy4vZW5jb2RpbmcvYXJtb3IuanMnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgVGhlIGNsYXNzIHRoYXQgZGVhbHMgd2l0aCBzdG9yYWdlIG9mIHRoZSBrZXlyaW5nLiBDdXJyZW50bHkgdGhlIG9ubHkgb3B0aW9uIGlzIHRvIHVzZSBIVE1MNSBsb2NhbCBzdG9yYWdlLlxuICovXG52YXIga2V5cmluZyA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmFybW9yZWRQYWNrZXRsaXN0cyA9IFtdO1xuICB0aGlzLnBhcnNlZFBhY2tldGxpc3RzID0gW107XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemF0aW9uIHJvdXRpbmUgZm9yIHRoZSBrZXlyaW5nLiBUaGlzIG1ldGhvZCByZWFkcyB0aGUgXG4gICAqIGtleXJpbmcgZnJvbSBIVE1MNSBsb2NhbCBzdG9yYWdlIGFuZCBpbml0aWFsaXplcyB0aGlzIGluc3RhbmNlLlxuICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgb3BlbnBncC5pbml0KCkuXG4gICAqL1xuICBmdW5jdGlvbiBpbml0KCkge1xuICAgIHZhciBhcm1vcmVkUGFja2V0bGlzdHMgPSBKU09OLnBhcnNlKHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShcImFybW9yZWRQYWNrZXRsaXN0c1wiKSk7XG4gICAgaWYgKGFybW9yZWRQYWNrZXRsaXN0cyA9PT0gbnVsbCB8fCBhcm1vcmVkUGFja2V0bGlzdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBhcm1vcmVkUGFja2V0bGlzdHMgPSBbXTtcbiAgICB9XG4gICAgdGhpcy5hcm1vcmVkUGFja2V0bGlzdHMgPSBhcm1vcmVkUGFja2V0bGlzdHM7XG5cbiAgICB2YXIgcGFja2V0bGlzdDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFybW9yZWRQYWNrZXRsaXN0cy5sZW5ndGg7IGkrKykge1xuICAgICAgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICAgICAgcGFja2V0bGlzdC5yZWFkKGFybW9yZWRQYWNrZXRsaXN0c1tpXSk7XG4gICAgICB0aGlzLnBhcnNlZFBhY2tldGxpc3RzLnB1c2gocGFja2V0bGlzdCk7XG4gICAgfVxuICB9XG4gIHRoaXMuaW5pdCA9IGluaXQ7XG5cbiAgLyoqXG4gICAqIFNhdmVzIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBrZXlyaW5nIHRvIEhUTUw1IGxvY2FsIHN0b3JhZ2UuXG4gICAqIFRoZSBwcml2YXRlS2V5cyBhcnJheSBhbmQgcHVibGljS2V5cyBhcnJheSBnZXRzIFN0cmluZ2lmaWVkIHVzaW5nIEpTT05cbiAgICovXG4gIGZ1bmN0aW9uIHN0b3JlKCkge1xuICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShcImFybW9yZWRQYWNrZXRsaXN0c1wiLCBKU09OLnN0cmluZ2lmeSh0aGlzLmFybW9yZWRQYWNrZXRsaXN0cykpO1xuICB9XG4gIHRoaXMuc3RvcmUgPSBzdG9yZTtcblxuICBmdW5jdGlvbiBlbWFpbFBhY2tldENoZWNrKHBhY2tldCwgZW1haWwpIHtcbiAgICB2YXIgZW1haWxNYXRjaCA9IGZhbHNlO1xuICAgIHZhciBwYWNrZXRFbWFpbDtcbiAgICBlbWFpbCA9IGVtYWlsLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKHBhY2tldC50YWcgPT0gZW51bXMucGFja2V0LnVzZXJpZCkge1xuICAgICAgcGFja2V0RW1haWwgPSBwYWNrZXQudXNlcmlkO1xuICAgICAgLy93ZSBuZWVkIHRvIGdldCBqdXN0IHRoZSBlbWFpbCBmcm9tIHRoZSB1c2VyaWQgcGFja2V0XG4gICAgICBwYWNrZXRFbWFpbCA9IHBhY2tldEVtYWlsLnNwbGl0KCc8JylbMV0uc3BsaXQoJzwnKVswXS50cmltLnRvTG93ZXJDYXNlKCk7XG4gICAgICBpZiAocGFja2V0RW1haWwgPT0gZW1haWwpIHtcbiAgICAgICAgZW1haWxNYXRjaCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBlbWFpbE1hdGNoO1xuICB9XG5cbiAgZnVuY3Rpb24gaWRQYWNrZXRDaGVjayhwYWNrZXQsIGlkKSB7XG4gICAgaWYgKHBhY2tldC5nZXRLZXlJZCAmJiBwYWNrZXQuZ2V0S2V5SWQoKS53cml0ZSgpID09IGlkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gaGVscGVyQ2hlY2tJZGVudGl0eUFuZFBhY2tldE1hdGNoKGlkZW50aXR5RnVuY3Rpb24sIGlkZW50aXR5SW5wdXQsIHBhY2tldFR5cGUsIHBhY2tldGxpc3QpIHtcbiAgICB2YXIgcGFja2V0O1xuICAgIGZvciAodmFyIGwgPSAwOyBsIDwgcGFja2V0bGlzdC5sZW5ndGg7IGwrKykge1xuICAgICAgcGFja2V0ID0gcGFja2V0bGlzdFtsXTtcbiAgICAgIGlkZW50aXR5TWF0Y2ggPSBpZGVudGl0eUZ1bmN0aW9uKHBhY2tldCwgaWRlbnRpdHlJbnB1dCk7XG4gICAgICBpZiAoIXBhY2tldFR5cGUpIHtcbiAgICAgICAgcGFja2V0TWF0Y2ggPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmIChwYWNrZXQudGFnID09IHBhY2tldFR5cGUpIHtcbiAgICAgICAgcGFja2V0TWF0Y2ggPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHBhY2tldE1hdGNoICYmIGlkZW50aXR5TWF0Y2gpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNoZWNrRm9ySWRlbnRpdHlBbmRQYWNrZXRNYXRjaChpZGVudGl0eUZ1bmN0aW9uLCBpZGVudGl0eUlucHV0LCBwYWNrZXRUeXBlKSB7XG4gICAgdmFyIHJlc3VsdHMgPSBbXTtcbiAgICB2YXIgcGFja2V0bGlzdDtcbiAgICB2YXIgaWRlbnRpdHlNYXRjaDtcbiAgICB2YXIgcGFja2V0TWF0Y2g7XG4gICAgZm9yICh2YXIgcCA9IDA7IHAgPCB0aGlzLnBhcnNlZFBhY2tldGxpc3RzLmxlbmd0aDsgcCsrKSB7XG4gICAgICBpZGVudGl0eU1hdGNoID0gZmFsc2U7XG4gICAgICBwYWNrZXRNYXRjaCA9IGZhbHNlO1xuICAgICAgcGFja2V0bGlzdCA9IHRoaXMucGFyc2VkUGFja2V0bGlzdHNbcF07XG4gICAgICBpZiAoaGVscGVyQ2hlY2tJZGVudGl0eUFuZFBhY2tldE1hdGNoKGlkZW50aXR5RnVuY3Rpb24sIGlkZW50aXR5SW5wdXQsIHBhY2tldFR5cGUsIHBhY2tldGxpc3QpKSB7XG4gICAgICAgIHJlc3VsdHMucHVzaChwYWNrZXRsaXN0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cbiAgdGhpcy5jaGVja0ZvcklkZW50aXR5QW5kUGFja2V0TWF0Y2ggPSBjaGVja0ZvcklkZW50aXR5QW5kUGFja2V0TWF0Y2g7XG5cbiAgLyoqXG4gICAqIHNlYXJjaGVzIGFsbCBwdWJsaWMga2V5cyBpbiB0aGUga2V5cmluZyBtYXRjaGluZyB0aGUgYWRkcmVzcyBvciBhZGRyZXNzIHBhcnQgb2YgdGhlIHVzZXIgaWRzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBlbWFpbF9hZGRyZXNzXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfbXNnX3B1YmxpY2tleVtdfSBUaGUgcHVibGljIGtleXMgYXNzb2NpYXRlZCB3aXRoIHByb3ZpZGVkIGVtYWlsIGFkZHJlc3MuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRQdWJsaWNLZXlGb3JBZGRyZXNzKGVtYWlsKSB7XG4gICAgcmV0dXJuIGNoZWNrRm9ySWRlbnRpdHlBbmRQYWNrZXRNYXRjaChlbWFpbFBhY2tldENoZWNrLCBlbWFpbCwgZW51bXMucGFja2V0LnB1YmxpY19rZXkpO1xuICB9XG4gIHRoaXMuZ2V0UHVibGljS2V5Rm9yQWRkcmVzcyA9IGdldFB1YmxpY0tleUZvckFkZHJlc3M7XG5cbiAgLyoqXG4gICAqIFNlYXJjaGVzIHRoZSBrZXlyaW5nIGZvciBhIHByaXZhdGUga2V5IGNvbnRhaW5pbmcgdGhlIHNwZWNpZmllZCBlbWFpbCBhZGRyZXNzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBlbWFpbF9hZGRyZXNzIGVtYWlsIGFkZHJlc3MgdG8gc2VhcmNoIGZvclxuICAgKiBAcmV0dXJuIHtvcGVucGdwX21zZ19wcml2YXRla2V5W119IHByaXZhdGUga2V5cyBmb3VuZFxuICAgKi9cbiAgZnVuY3Rpb24gZ2V0UHJpdmF0ZUtleUZvckFkZHJlc3MoZW1haWxfYWRkcmVzcykge1xuICAgIHJldHVybiBjaGVja0ZvcklkZW50aXR5QW5kUGFja2V0TWF0Y2goZW1haWxQYWNrZXRDaGVjaywgZW1haWwsIGVudW1zLnBhY2tldC5zZWNyZXRfa2V5KTtcbiAgfVxuICB0aGlzLmdldFByaXZhdGVLZXlGb3JBZGRyZXNzID0gZ2V0UHJpdmF0ZUtleUZvckFkZHJlc3M7XG5cbiAgLyoqXG4gICAqIFNlYXJjaGVzIHRoZSBrZXlyaW5nIGZvciBwdWJsaWMga2V5cyBoYXZpbmcgdGhlIHNwZWNpZmllZCBrZXkgaWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IGtleUlkIHByb3ZpZGVkIGFzIHN0cmluZyBvZiBoZXggbnVtYmVyIChsb3dlcmNhc2UpXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXlbXX0gcHVibGljIGtleXMgZm91bmRcbiAgICovXG4gIGZ1bmN0aW9uIGdldFBhY2tldGxpc3RzRm9yS2V5SWQoa2V5SWQpIHtcbiAgICByZXR1cm4gdGhpcy5jaGVja0ZvcklkZW50aXR5QW5kUGFja2V0TWF0Y2goaWRQYWNrZXRDaGVjaywga2V5SWQpO1xuICB9XG4gIHRoaXMuZ2V0UGFja2V0bGlzdHNGb3JLZXlJZCA9IGdldFBhY2tldGxpc3RzRm9yS2V5SWQ7XG5cbiAgLyoqXG4gICAqIEltcG9ydHMgYSBwYWNrZXQgbGlzdCAocHVibGljIG9yIHByaXZhdGUga2V5IGJsb2NrKSBmcm9tIGFuIGFzY2lpIGFybW9yZWQgbWVzc2FnZSBcbiAgICogQHBhcmFtIHtTdHJpbmd9IGFybW9yZWQgbWVzc2FnZSB0byByZWFkIHRoZSBwYWNrZXRzL2tleSBmcm9tXG4gICAqL1xuICBmdW5jdGlvbiBpbXBvcnRQYWNrZXRsaXN0KGFybW9yZWQpIHtcbiAgICB0aGlzLmFybW9yZWRQYWNrZXRsaXN0cy5wdXNoKGFybW9yZWQpO1xuXG4gICAgdmFyIGRlYXJtb3JlZCA9IGFybW9yLmRlY29kZShhcm1vcmVkLnJlcGxhY2UoL1xcci9nLCAnJykpLmRhdGE7XG5cbiAgICBwYWNrZXRsaXN0ID0gbmV3IHBhY2tldC5saXN0KCk7XG4gICAgcGFja2V0bGlzdC5yZWFkKGRlYXJtb3JlZCk7XG4gICAgdGhpcy5wYXJzZWRQYWNrZXRsaXN0cy5wdXNoKHBhY2tldGxpc3QpO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgdGhpcy5pbXBvcnRQYWNrZXRsaXN0ID0gaW1wb3J0UGFja2V0bGlzdDtcblxuICAvKipcbiAgICogVE9ET1xuICAgKiByZXR1cm5zIHRoZSBvcGVucGdwX21zZ19wcml2YXRla2V5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwdWJsaWMga2V5IGF0IHB1YmxpYyBrZXkgcmluZyBpbmRleCAgXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBwdWJsaWMga2V5IHdpdGhpbiB0aGUgcHVibGljS2V5cyBhcnJheVxuICAgKiBAcmV0dXJuIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSB0aGUgcHVibGljIGtleSBvYmplY3RcbiAgICovXG4gIGZ1bmN0aW9uIGV4cG9ydFB1YmxpY0tleShpbmRleCkge1xuICAgIHJldHVybiB0aGlzLnB1YmxpY0tleVtpbmRleF07XG4gIH1cbiAgdGhpcy5leHBvcnRQdWJsaWNLZXkgPSBleHBvcnRQdWJsaWNLZXk7XG5cbiAgLyoqXG4gICAqIFRPRE9cbiAgICogUmVtb3ZlcyBhIHB1YmxpYyBrZXkgZnJvbSB0aGUgcHVibGljIGtleSBrZXlyaW5nIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBwdWJsaWMga2V5IHdpdGhpbiB0aGUgcHVibGljS2V5cyBhcnJheVxuICAgKiBAcmV0dXJuIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBUaGUgcHVibGljIGtleSBvYmplY3Qgd2hpY2ggaGFzIGJlZW4gcmVtb3ZlZFxuICAgKi9cbiAgZnVuY3Rpb24gcmVtb3ZlUHVibGljS2V5KGluZGV4KSB7XG4gICAgdmFyIHJlbW92ZWQgPSB0aGlzLnB1YmxpY0tleXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB0aGlzLnN0b3JlKCk7XG4gICAgcmV0dXJuIHJlbW92ZWQ7XG4gIH1cbiAgdGhpcy5yZW1vdmVQdWJsaWNLZXkgPSByZW1vdmVQdWJsaWNLZXk7XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IGtleXJpbmcoKTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBwYWNrZXQgPSByZXF1aXJlKCcuL3BhY2tldCcpO1xudmFyIGVudW1zID0gcmVxdWlyZSgnLi9lbnVtcy5qcycpO1xudmFyIGFybW9yID0gcmVxdWlyZSgnLi9lbmNvZGluZy9hcm1vci5qcycpO1xudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7XG52YXIgY3J5cHRvID0gcmVxdWlyZSgnLi9jcnlwdG8nKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi91dGlsJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhbiBPcGVuUEdQIG1lc3NhZ2UuXG4gKiBDYW4gYmUgYW4gZW5jcnlwdGVkIG1lc3NhZ2UsIHNpZ25lZCBtZXNzYWdlLCBjb21wcmVzc2VkIG1lc3NhZ2Ugb3IgbGl0ZXJhbCBtZXNzYWdlXG4gKiBAcGFyYW0gIHtwYWNrZXRsaXN0fSBwYWNrZXRsaXN0IFRoZSBwYWNrZXRzIHRoYXQgZm9ybSB0aGlzIG1lc3NhZ2VcbiAqIFNlZSBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0ODgwI3NlY3Rpb24tMTEuM1xuICovXG5cbmZ1bmN0aW9uIE1lc3NhZ2UocGFja2V0bGlzdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTWVzc2FnZSkpIHtcbiAgICByZXR1cm4gbmV3IE1lc3NhZ2UocGFja2V0bGlzdCk7XG4gIH1cbiAgdGhpcy5wYWNrZXRzID0gcGFja2V0bGlzdCB8fCBuZXcgcGFja2V0Lmxpc3QoKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBrZXkgSURzIG9mIHRoZSBrZXlzIHRvIHdoaWNoIHRoZSBzZXNzaW9uIGtleSBpcyBlbmNyeXB0ZWRcbiAqIEByZXR1cm4ge1trZXlJZF19IGFycmF5IG9mIGtleWlkIG9iamVjdHNcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUuZ2V0RW5jcnlwdGlvbktleUlkcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIga2V5SWRzID0gW107XG4gIHZhciBwa0VTS2V5UGFja2V0bGlzdCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQucHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkpO1xuICBwa0VTS2V5UGFja2V0bGlzdC5mb3JFYWNoKGZ1bmN0aW9uKHBhY2tldCkge1xuICAgIGtleUlkcy5wdXNoKHBhY2tldC5wdWJsaWNLZXlJZCk7XG4gIH0pO1xuICByZXR1cm4ga2V5SWRzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBrZXkgSURzIG9mIHRoZSBrZXlzIHRoYXQgc2lnbmVkIHRoZSBtZXNzYWdlXG4gKiBAcmV0dXJuIHtba2V5SWRdfSBhcnJheSBvZiBrZXlpZCBvYmplY3RzXG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLmdldFNpZ25pbmdLZXlJZHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGtleUlkcyA9IFtdO1xuICB2YXIgbXNnID0gdGhpcy51bndyYXBDb21wcmVzc2VkKCk7XG4gIC8vIHNlYXJjaCBmb3Igb25lIHBhc3Mgc2lnbmF0dXJlc1xuICB2YXIgb25lUGFzc1NpZ0xpc3QgPSBtc2cucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQub25lX3Bhc3Nfc2lnbmF0dXJlKTtcbiAgb25lUGFzc1NpZ0xpc3QuZm9yRWFjaChmdW5jdGlvbihwYWNrZXQpIHtcbiAgICBrZXlJZHMucHVzaChwYWNrZXQuc2lnbmluZ0tleUlkKTtcbiAgfSk7XG4gIC8vIGlmIG5vdGhpbmcgZm91bmQgbG9vayBmb3Igc2lnbmF0dXJlIHBhY2tldHNcbiAgaWYgKCFrZXlJZHMubGVuZ3RoKSB7XG4gICAgdmFyIHNpZ25hdHVyZUxpc3QgPSBtc2cucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuc2lnbmF0dXJlKTtcbiAgICBzaWduYXR1cmVMaXN0LmZvckVhY2goZnVuY3Rpb24ocGFja2V0KSB7XG4gICAgICBrZXlJZHMucHVzaChwYWNrZXQuaXNzdWVyS2V5SWQpO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBrZXlJZHM7XG59O1xuXG4vKipcbiAqIERlY3J5cHQgdGhlIG1lc3NhZ2VcbiAqIEBwYXJhbSB7a2V5fSBwcml2YXRlS2V5IHByaXZhdGUga2V5IHdpdGggZGVjcnlwdGVkIHNlY3JldCBkYXRhICAgICAgICAgICBcbiAqIEByZXR1cm4ge1ttZXNzYWdlXX0gbmV3IG1lc3NhZ2Ugd2l0aCBkZWNyeXB0ZWQgY29udGVudFxuICovXG5NZXNzYWdlLnByb3RvdHlwZS5kZWNyeXB0ID0gZnVuY3Rpb24ocHJpdmF0ZUtleSkge1xuICB2YXIgZW5jcnlwdGlvbktleUlkcyA9IHRoaXMuZ2V0RW5jcnlwdGlvbktleUlkcygpO1xuICBpZiAoIWVuY3J5cHRpb25LZXlJZHMubGVuZ3RoKSB7XG4gICAgLy8gbm90aGluZyB0byBkZWNyeXB0IHJldHVybiB1bm1vZGlmaWVkIG1lc3NhZ2VcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB2YXIgcHJpdmF0ZUtleVBhY2tldCA9IHByaXZhdGVLZXkuZ2V0UHJpdmF0ZUtleVBhY2tldChlbmNyeXB0aW9uS2V5SWRzKTtcbiAgaWYgKCFwcml2YXRlS2V5UGFja2V0LmlzRGVjcnlwdGVkKSB0aHJvdyBuZXcgRXJyb3IoJ1ByaXZhdGUga2V5IGlzIG5vdCBkZWNyeXB0ZWQuJyk7XG4gIHZhciBwa0VTS2V5UGFja2V0bGlzdCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQucHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkpO1xuICB2YXIgcGtFU0tleVBhY2tldDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwa0VTS2V5UGFja2V0bGlzdC5sZW5ndGg7IGkrKykge1xuICAgIGlmIChwa0VTS2V5UGFja2V0bGlzdFtpXS5wdWJsaWNLZXlJZC5lcXVhbHMocHJpdmF0ZUtleVBhY2tldC5nZXRLZXlJZCgpKSkge1xuICAgICAgcGtFU0tleVBhY2tldCA9IHBrRVNLZXlQYWNrZXRsaXN0W2ldO1xuICAgICAgcGtFU0tleVBhY2tldC5kZWNyeXB0KHByaXZhdGVLZXlQYWNrZXQpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChwa0VTS2V5UGFja2V0KSB7XG4gICAgdmFyIHN5bUVuY3J5cHRlZFBhY2tldGxpc3QgPSB0aGlzLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkLCBlbnVtcy5wYWNrZXQuc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkKTtcbiAgICBpZiAoc3ltRW5jcnlwdGVkUGFja2V0bGlzdC5sZW5ndGggIT09IDApIHtcbiAgICAgIHZhciBzeW1FbmNyeXB0ZWRQYWNrZXQgPSBzeW1FbmNyeXB0ZWRQYWNrZXRsaXN0WzBdO1xuICAgICAgc3ltRW5jcnlwdGVkUGFja2V0LmRlY3J5cHQocGtFU0tleVBhY2tldC5zZXNzaW9uS2V5QWxnb3JpdGhtLCBwa0VTS2V5UGFja2V0LnNlc3Npb25LZXkpO1xuICAgICAgcmV0dXJuIG5ldyBNZXNzYWdlKHN5bUVuY3J5cHRlZFBhY2tldC5wYWNrZXRzKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IGxpdGVyYWwgZGF0YSB0aGF0IGlzIHRoZSBib2R5IG9mIHRoZSBtZXNzYWdlXG4gKiBAcmV0dXJuIHtTdHJpbmd8bnVsbH0gbGl0ZXJhbCBib2R5IG9mIHRoZSBtZXNzYWdlIGFzIHN0cmluZ1xuICovXG5NZXNzYWdlLnByb3RvdHlwZS5nZXRMaXRlcmFsRGF0YSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbGl0ZXJhbCA9IHRoaXMucGFja2V0cy5maW5kUGFja2V0KGVudW1zLnBhY2tldC5saXRlcmFsKTtcbiAgcmV0dXJuIGxpdGVyYWwgJiYgbGl0ZXJhbC5kYXRhIHx8IG51bGw7XG59O1xuXG4vKipcbiAqIEdldCBsaXRlcmFsIGRhdGEgYXMgdGV4dFxuICogQHJldHVybiB7U3RyaW5nfG51bGx9IGxpdGVyYWwgYm9keSBvZiB0aGUgbWVzc2FnZSBpbnRlcnByZXRlZCBhcyB0ZXh0XG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLmdldFRleHQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGxpdGVyYWwgPSB0aGlzLnBhY2tldHMuZmluZFBhY2tldChlbnVtcy5wYWNrZXQubGl0ZXJhbCk7XG4gIGlmIChsaXRlcmFsKSB7XG4gICAgcmV0dXJuIGxpdGVyYWwuZ2V0VGV4dCgpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59O1xuXG4vKipcbiAqIEVuY3J5cHQgdGhlIG1lc3NhZ2VcbiAqIEBwYXJhbSAge1trZXldfSBrZXlzIGFycmF5IG9mIGtleXMsIHVzZWQgdG8gZW5jcnlwdCB0aGUgbWVzc2FnZVxuICogQHJldHVybiB7W21lc3NhZ2VdfSBuZXcgbWVzc2FnZSB3aXRoIGVuY3J5cHRlZCBjb250ZW50XG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLmVuY3J5cHQgPSBmdW5jdGlvbihrZXlzKSB7XG4gIHZhciBwYWNrZXRsaXN0ID0gbmV3IHBhY2tldC5saXN0KCk7XG4gIC8vVE9ETyBnZXQgcHJlZmVycmVkIGFsZ28gZnJvbSBzaWduYXR1cmVcbiAgdmFyIHNlc3Npb25LZXkgPSBjcnlwdG8uZ2VuZXJhdGVTZXNzaW9uS2V5KGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBjb25maWcuZW5jcnlwdGlvbl9jaXBoZXIpKTtcbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciBlbmNyeXB0aW9uS2V5UGFja2V0ID0ga2V5LmdldEVuY3J5cHRpb25LZXlQYWNrZXQoKTtcbiAgICBpZiAoZW5jcnlwdGlvbktleVBhY2tldCkge1xuICAgICAgdmFyIHBrRVNLZXlQYWNrZXQgPSBuZXcgcGFja2V0LnB1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5KCk7XG4gICAgICBwa0VTS2V5UGFja2V0LnB1YmxpY0tleUlkID0gZW5jcnlwdGlvbktleVBhY2tldC5nZXRLZXlJZCgpO1xuICAgICAgcGtFU0tleVBhY2tldC5wdWJsaWNLZXlBbGdvcml0aG0gPSBlbmNyeXB0aW9uS2V5UGFja2V0LmFsZ29yaXRobTtcbiAgICAgIHBrRVNLZXlQYWNrZXQuc2Vzc2lvbktleSA9IHNlc3Npb25LZXk7XG4gICAgICAvL1RPRE8gZ2V0IHByZWZlcnJlZCBhbGdvIGZyb20gc2lnbmF0dXJlXG4gICAgICBwa0VTS2V5UGFja2V0LnNlc3Npb25LZXlBbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYywgY29uZmlnLmVuY3J5cHRpb25fY2lwaGVyKTtcbiAgICAgIHBrRVNLZXlQYWNrZXQuZW5jcnlwdChlbmNyeXB0aW9uS2V5UGFja2V0KTtcbiAgICAgIHBhY2tldGxpc3QucHVzaChwa0VTS2V5UGFja2V0KTtcbiAgICB9XG4gIH0pO1xuICB2YXIgc3ltRW5jcnlwdGVkUGFja2V0O1xuICBpZiAoY29uZmlnLmludGVncml0eV9wcm90ZWN0KSB7XG4gICAgc3ltRW5jcnlwdGVkUGFja2V0ID0gbmV3IHBhY2tldC5zeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQoKTtcbiAgfSBlbHNlIHtcbiAgICBzeW1FbmNyeXB0ZWRQYWNrZXQgPSBuZXcgcGFja2V0LnN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkKCk7XG4gIH1cbiAgc3ltRW5jcnlwdGVkUGFja2V0LnBhY2tldHMgPSB0aGlzLnBhY2tldHM7XG4gIC8vVE9ETyBnZXQgcHJlZmVycmVkIGFsZ28gZnJvbSBzaWduYXR1cmVcbiAgc3ltRW5jcnlwdGVkUGFja2V0LmVuY3J5cHQoZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIGNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlciksIHNlc3Npb25LZXkpO1xuICBwYWNrZXRsaXN0LnB1c2goc3ltRW5jcnlwdGVkUGFja2V0KTtcbiAgcmV0dXJuIG5ldyBNZXNzYWdlKHBhY2tldGxpc3QpO1xufTtcblxuLyoqXG4gKiBTaWduIHRoZSBtZXNzYWdlICh0aGUgbGl0ZXJhbCBkYXRhIHBhY2tldCBvZiB0aGUgbWVzc2FnZSlcbiAqIEBwYXJhbSAge1trZXldfSBwcml2YXRlS2V5IHByaXZhdGUga2V5cyB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGEgZm9yIHNpZ25pbmdcbiAqIEByZXR1cm4ge21lc3NhZ2V9ICAgICAgbmV3IG1lc3NhZ2Ugd2l0aCBzaWduZWQgY29udGVudFxuICovXG5NZXNzYWdlLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24ocHJpdmF0ZUtleXMpIHtcblxuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuXG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldCA9IHRoaXMucGFja2V0cy5maW5kUGFja2V0KGVudW1zLnBhY2tldC5saXRlcmFsKTtcbiAgaWYgKCFsaXRlcmFsRGF0YVBhY2tldCkgdGhyb3cgbmV3IEVycm9yKCdObyBsaXRlcmFsIGRhdGEgcGFja2V0IHRvIHNpZ24uJyk7XG4gIFxuICB2YXIgbGl0ZXJhbEZvcm1hdCA9IGVudW1zLndyaXRlKGVudW1zLmxpdGVyYWwsIGxpdGVyYWxEYXRhUGFja2V0LmZvcm1hdCk7XG4gIHZhciBzaWduYXR1cmVUeXBlID0gbGl0ZXJhbEZvcm1hdCA9PSBlbnVtcy5saXRlcmFsLmJpbmFyeSBcbiAgICAgICAgICAgICAgICAgICAgICA/IGVudW1zLnNpZ25hdHVyZS5iaW5hcnkgOiBlbnVtcy5zaWduYXR1cmUudGV4dDsgXG4gIFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHByaXZhdGVLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG9uZVBhc3NTaWcgPSBuZXcgcGFja2V0Lm9uZV9wYXNzX3NpZ25hdHVyZSgpO1xuICAgIG9uZVBhc3NTaWcudHlwZSA9IHNpZ25hdHVyZVR5cGU7XG4gICAgLy9UT0RPIGdldCBwcmVmZXJyZWQgaGFzaGcgYWxnbyBmcm9tIGtleSBzaWduYXR1cmVcbiAgICBvbmVQYXNzU2lnLmhhc2hBbGdvcml0aG0gPSBjb25maWcucHJlZmVyX2hhc2hfYWxnb3JpdGhtO1xuICAgIHZhciBzaWduaW5nS2V5UGFja2V0ID0gcHJpdmF0ZUtleXNbaV0uZ2V0U2lnbmluZ0tleVBhY2tldCgpO1xuICAgIG9uZVBhc3NTaWcucHVibGljS2V5QWxnb3JpdGhtID0gc2lnbmluZ0tleVBhY2tldC5hbGdvcml0aG07XG4gICAgb25lUGFzc1NpZy5zaWduaW5nS2V5SWQgPSBzaWduaW5nS2V5UGFja2V0LmdldEtleUlkKCk7XG4gICAgcGFja2V0bGlzdC5wdXNoKG9uZVBhc3NTaWcpO1xuICB9XG5cbiAgcGFja2V0bGlzdC5wdXNoKGxpdGVyYWxEYXRhUGFja2V0KTtcbiAgXG4gIGZvciAodmFyIGkgPSBwcml2YXRlS2V5cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIHZhciBzaWduYXR1cmVQYWNrZXQgPSBuZXcgcGFja2V0LnNpZ25hdHVyZSgpO1xuICAgIHNpZ25hdHVyZVBhY2tldC5zaWduYXR1cmVUeXBlID0gc2lnbmF0dXJlVHlwZTtcbiAgICBzaWduYXR1cmVQYWNrZXQuaGFzaEFsZ29yaXRobSA9IGNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG07XG4gICAgc2lnbmF0dXJlUGFja2V0LnB1YmxpY0tleUFsZ29yaXRobSA9IHNpZ25pbmdLZXlQYWNrZXQuYWxnb3JpdGhtO1xuICAgIGlmICghc2lnbmluZ0tleVBhY2tldC5pc0RlY3J5cHRlZCkgdGhyb3cgbmV3IEVycm9yKCdQcml2YXRlIGtleSBpcyBub3QgZGVjcnlwdGVkLicpO1xuICAgIHNpZ25hdHVyZVBhY2tldC5zaWduKHNpZ25pbmdLZXlQYWNrZXQsIGxpdGVyYWxEYXRhUGFja2V0KTtcbiAgICBwYWNrZXRsaXN0LnB1c2goc2lnbmF0dXJlUGFja2V0KTtcbiAgfVxuXG4gIHJldHVybiBuZXcgTWVzc2FnZShwYWNrZXRsaXN0KTtcbn07XG5cbi8qKlxuICogVmVyaWZ5IG1lc3NhZ2Ugc2lnbmF0dXJlc1xuICogQHBhcmFtIHtba2V5XX0gcHVibGljS2V5cyBwdWJsaWMga2V5cyB0byB2ZXJpZnkgc2lnbmF0dXJlc1xuICogQHJldHVybiB7W3sna2V5aWQnOiBrZXlpZCwgJ3ZhbGlkJzogQm9vbGVhbn1dfSBsaXN0IG9mIHNpZ25lcidzIGtleWlkIGFuZCB2YWxpZGl0eSBvZiBzaWduYXR1cmVcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24ocHVibGljS2V5cykge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBtc2cgPSB0aGlzLnVud3JhcENvbXByZXNzZWQoKTtcbiAgdmFyIGxpdGVyYWxEYXRhTGlzdCA9IG1zZy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5saXRlcmFsKTtcbiAgaWYgKGxpdGVyYWxEYXRhTGlzdC5sZW5ndGggIT09IDEpIHRocm93IG5ldyBFcnJvcignQ2FuIG9ubHkgdmVyaWZ5IG1lc3NhZ2Ugd2l0aCBvbmUgbGl0ZXJhbCBkYXRhIHBhY2tldC4nKTtcbiAgdmFyIHNpZ25hdHVyZUxpc3QgPSBtc2cucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuc2lnbmF0dXJlKTtcbiAgcHVibGljS2V5cy5mb3JFYWNoKGZ1bmN0aW9uKHB1YktleSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnbmF0dXJlTGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHB1YmxpY0tleVBhY2tldCA9IHB1YktleS5nZXRQdWJsaWNLZXlQYWNrZXQoW3NpZ25hdHVyZUxpc3RbaV0uaXNzdWVyS2V5SWRdKTtcbiAgICAgIGlmIChwdWJsaWNLZXlQYWNrZXQpIHtcbiAgICAgICAgdmFyIHZlcmlmaWVkU2lnID0ge307XG4gICAgICAgIHZlcmlmaWVkU2lnLmtleWlkID0gc2lnbmF0dXJlTGlzdFtpXS5pc3N1ZXJLZXlJZDtcbiAgICAgICAgdmVyaWZpZWRTaWcuc3RhdHVzID0gc2lnbmF0dXJlTGlzdFtpXS52ZXJpZnkocHVibGljS2V5UGFja2V0LCBsaXRlcmFsRGF0YUxpc3RbMF0pO1xuICAgICAgICByZXN1bHQucHVzaCh2ZXJpZmllZFNpZyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIFVud3JhcCBjb21wcmVzc2VkIG1lc3NhZ2VcbiAqIEByZXR1cm4ge21lc3NhZ2V9IG1lc3NhZ2UgQ29udGVudCBvZiBjb21wcmVzc2VkIG1lc3NhZ2VcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUudW53cmFwQ29tcHJlc3NlZCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29tcHJlc3NlZCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuY29tcHJlc3NlZCk7XG4gIGlmIChjb21wcmVzc2VkLmxlbmd0aCkge1xuICAgIHJldHVybiBuZXcgTWVzc2FnZShjb21wcmVzc2VkWzBdLnBhY2tldHMpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59O1xuXG4vKipcbiAqIFJldHVybnMgQVNDSUkgYXJtb3JlZCB0ZXh0IG9mIG1lc3NhZ2VcbiAqIEByZXR1cm4ge1N0cmluZ30gQVNDSUkgYXJtb3JcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUuYXJtb3IgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGFybW9yLmVuY29kZShlbnVtcy5hcm1vci5tZXNzYWdlLCB0aGlzLnBhY2tldHMud3JpdGUoKSk7XG59O1xuXG4vKipcbiAqIHJlYWRzIGFuIE9wZW5QR1AgYXJtb3JlZCBtZXNzYWdlIGFuZCByZXR1cm5zIGEgbWVzc2FnZSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBhcm1vcmVkVGV4dCB0ZXh0IHRvIGJlIHBhcnNlZFxuICogQHJldHVybiB7bWVzc2FnZX0gbmV3IG1lc3NhZ2Ugb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIHJlYWRBcm1vcmVkKGFybW9yZWRUZXh0KSB7XG4gIC8vVE9ETyBob3cgZG8gd2Ugd2FudCB0byBoYW5kbGUgYmFkIHRleHQ/IEV4Y2VwdGlvbiB0aHJvd2luZ1xuICAvL1RPRE8gZG9uJ3QgYWNjZXB0IG5vbi1tZXNzYWdlIGFybW9yZWQgdGV4dHNcbiAgdmFyIGlucHV0ID0gYXJtb3IuZGVjb2RlKGFybW9yZWRUZXh0KS5kYXRhO1xuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICBwYWNrZXRsaXN0LnJlYWQoaW5wdXQpO1xuICB2YXIgbmV3TWVzc2FnZSA9IG5ldyBNZXNzYWdlKHBhY2tldGxpc3QpO1xuICByZXR1cm4gbmV3TWVzc2FnZTtcbn1cblxuLyoqXG4gKiBjcmVhdGVzIG5ldyBtZXNzYWdlIG9iamVjdCBmcm9tIHRleHRcbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0XG4gKiBAcmV0dXJuIHttZXNzYWdlfSBuZXcgbWVzc2FnZSBvYmplY3RcbiAqL1xuZnVuY3Rpb24gZnJvbVRleHQodGV4dCkge1xuICB2YXIgbGl0ZXJhbERhdGFQYWNrZXQgPSBuZXcgcGFja2V0LmxpdGVyYWwoKTtcbiAgLy8gdGV4dCB3aWxsIGJlIGNvbnZlcnRlZCB0byBVVEY4XG4gIGxpdGVyYWxEYXRhUGFja2V0LnNldFRleHQodGV4dCk7XG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgbGl0ZXJhbERhdGFQYWNrZXRsaXN0LnB1c2gobGl0ZXJhbERhdGFQYWNrZXQpO1xuICB2YXIgbmV3TWVzc2FnZSA9IG5ldyBNZXNzYWdlKGxpdGVyYWxEYXRhUGFja2V0bGlzdCk7XG4gIHJldHVybiBuZXdNZXNzYWdlO1xufVxuXG4vKipcbiAqIGNyZWF0ZXMgbmV3IG1lc3NhZ2Ugb2JqZWN0IGZyb20gYmluYXJ5IGRhdGFcbiAqIEBwYXJhbSB7U3RyaW5nfSBieXRlc1xuICogQHJldHVybiB7bWVzc2FnZX0gbmV3IG1lc3NhZ2Ugb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIGZyb21CaW5hcnkoYnl0ZXMpIHtcbiAgdmFyIGxpdGVyYWxEYXRhUGFja2V0ID0gbmV3IHBhY2tldC5saXRlcmFsKCk7XG4gIGxpdGVyYWxEYXRhUGFja2V0LnNldEJ5dGVzKGJ5dGVzLCBlbnVtcy5yZWFkKGVudW1zLmxpdGVyYWwsIGVudW1zLmxpdGVyYWwuYmluYXJ5KSk7XG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgbGl0ZXJhbERhdGFQYWNrZXRsaXN0LnB1c2gobGl0ZXJhbERhdGFQYWNrZXQpO1xuICB2YXIgbmV3TWVzc2FnZSA9IG5ldyBNZXNzYWdlKGxpdGVyYWxEYXRhUGFja2V0bGlzdCk7XG4gIHJldHVybiBuZXdNZXNzYWdlO1xufVxuXG5leHBvcnRzLk1lc3NhZ2UgPSBNZXNzYWdlO1xuZXhwb3J0cy5yZWFkQXJtb3JlZCA9IHJlYWRBcm1vcmVkO1xuZXhwb3J0cy5mcm9tVGV4dCA9IGZyb21UZXh0O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IFRoZSBvcGVucGdwIGJhc2UgbW9kdWxlIHNob3VsZCBwcm92aWRlIGFsbCBvZiB0aGUgZnVuY3Rpb25hbGl0eSBcbiAqIHRvIGNvbnN1bWUgdGhlIG9wZW5wZ3AuanMgbGlicmFyeS4gQWxsIGFkZGl0aW9uYWwgY2xhc3NlcyBhcmUgZG9jdW1lbnRlZCBcbiAqIGZvciBleHRlbmRpbmcgYW5kIGRldmVsb3Bpbmcgb24gdG9wIG9mIHRoZSBiYXNlIGxpYnJhcnkuXG4gKi9cblxudmFyIGFybW9yID0gcmVxdWlyZSgnLi9lbmNvZGluZy9hcm1vci5qcycpO1xudmFyIHBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0Jyk7XG52YXIgZW51bXMgPSByZXF1aXJlKCcuL2VudW1zLmpzJyk7XG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKTtcbnZhciBtZXNzYWdlID0gcmVxdWlyZSgnLi9tZXNzYWdlLmpzJyk7XG52YXIgY2xlYXJ0ZXh0ID0gcmVxdWlyZSgnLi9jbGVhcnRleHQuanMnKTtcbnZhciBrZXkgPSByZXF1aXJlKCcuL2tleS5qcycpO1xuXG5cbi8qKlxuICogRW5jcnlwdHMgbWVzc2FnZSB0ZXh0IHdpdGgga2V5c1xuICogQHBhcmFtICB7W2tleV19ICBrZXlzIGFycmF5IG9mIGtleXMsIHVzZWQgdG8gZW5jcnlwdCB0aGUgbWVzc2FnZVxuICogQHBhcmFtICB7U3RyaW5nfSB0ZXh0IG1lc3NhZ2UgYXMgbmF0aXZlIEphdmFTY3JpcHQgc3RyaW5nXG4gKiBAcmV0dXJuIHtTdHJpbmd9ICAgICAgZW5jcnlwdGVkIEFTQ0lJIGFybW9yZWQgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBlbmNyeXB0TWVzc2FnZShrZXlzLCB0ZXh0KSB7XG4gIHZhciBtc2cgPSBtZXNzYWdlLmZyb21UZXh0KHRleHQpO1xuICBtc2cgPSBtc2cuZW5jcnlwdChrZXlzKTtcbiAgdmFyIGFybW9yZWQgPSBhcm1vci5lbmNvZGUoZW51bXMuYXJtb3IubWVzc2FnZSwgbXNnLnBhY2tldHMud3JpdGUoKSk7XG4gIHJldHVybiBhcm1vcmVkO1xufVxuXG4vKipcbiAqIFNpZ25zIG1lc3NhZ2UgdGV4dCBhbmQgZW5jcnlwdHMgaXRcbiAqIEBwYXJhbSAge1trZXldfSAgcHVibGljS2V5cyBhcnJheSBvZiBrZXlzLCB1c2VkIHRvIGVuY3J5cHQgdGhlIG1lc3NhZ2VcbiAqIEBwYXJhbSAge2tleX0gICAgcHJpdmF0ZUtleSBwcml2YXRlIGtleSB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGEgZm9yIHNpZ25pbmdcbiAqIEBwYXJhbSAge1N0cmluZ30gdGV4dCAgICAgICBtZXNzYWdlIGFzIG5hdGl2ZSBKYXZhU2NyaXB0IHN0cmluZ1xuICogQHJldHVybiB7U3RyaW5nfSAgICAgICAgICAgIGVuY3J5cHRlZCBBU0NJSSBhcm1vcmVkIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gc2lnbkFuZEVuY3J5cHRNZXNzYWdlKHB1YmxpY0tleXMsIHByaXZhdGVLZXksIHRleHQpIHtcbiAgdmFyIG1zZyA9IG1lc3NhZ2UuZnJvbVRleHQodGV4dCk7XG4gIG1zZyA9IG1zZy5zaWduKFtwcml2YXRlS2V5XSk7XG4gIG1zZyA9IG1zZy5lbmNyeXB0KHB1YmxpY0tleXMpO1xuICB2YXIgYXJtb3JlZCA9IGFybW9yLmVuY29kZShlbnVtcy5hcm1vci5tZXNzYWdlLCBtc2cucGFja2V0cy53cml0ZSgpKTtcbiAgcmV0dXJuIGFybW9yZWQ7XG59XG5cbi8qKlxuICogRGVjcnlwdHMgbWVzc2FnZVxuICogQHBhcmFtICB7a2V5fSAgICAgcHJpdmF0ZUtleSBwcml2YXRlIGtleSB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGFcbiAqIEBwYXJhbSAge21lc3NhZ2V9IG1lc3NhZ2UgICAgdGhlIG1lc3NhZ2Ugb2JqZWN0IHdpdGggdGhlIGVuY3J5cHRlZCBkYXRhXG4gKiBAcmV0dXJuIHtTdHJpbmd8bnVsbH0gICAgICAgIGRlY3J5cHRlZCBtZXNzYWdlIGFzIGFzIG5hdGl2ZSBKYXZhU2NyaXB0IHN0cmluZ1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciBudWxsIGlmIG5vIGxpdGVyYWwgZGF0YSBmb3VuZFxuICovXG5mdW5jdGlvbiBkZWNyeXB0TWVzc2FnZShwcml2YXRlS2V5LCBtZXNzYWdlKSB7XG4gIG1lc3NhZ2UgPSBtZXNzYWdlLmRlY3J5cHQocHJpdmF0ZUtleSk7XG4gIHJldHVybiBtZXNzYWdlLmdldFRleHQoKTtcbn1cblxuLyoqXG4gKiBEZWNyeXB0cyBtZXNzYWdlIGFuZCB2ZXJpZmllcyBzaWduYXR1cmVzXG4gKiBAcGFyYW0gIHtrZXl9ICAgICBwcml2YXRlS2V5IHByaXZhdGUga2V5IHdpdGggZGVjcnlwdGVkIHNlY3JldCBrZXkgZGF0YVxuICogQHBhcmFtICB7W2tleV19ICAgcHVibGljS2V5cyBwdWJsaWMga2V5cyB0byB2ZXJpZnkgc2lnbmF0dXJlc1xuICogQHBhcmFtICB7bWVzc2FnZX0gbWVzc2FnZSAgICB0aGUgbWVzc2FnZSBvYmplY3Qgd2l0aCBzaWduZWQgYW5kIGVuY3J5cHRlZCBkYXRhXG4gKiBAcmV0dXJuIHt7J3RleHQnOiBTdHJpbmcsIHNpZ25hdHVyZXM6IFt7J2tleWlkJzoga2V5aWQsICdzdGF0dXMnOiBCb29sZWFufV19fVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNyeXB0ZWQgbWVzc2FnZSBhcyBhcyBuYXRpdmUgSmF2YVNjcmlwdCBzdHJpbmdcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCB2ZXJpZmllZCBzaWduYXR1cmVzIG9yIG51bGwgaWYgbm8gbGl0ZXJhbCBkYXRhIGZvdW5kXG4gKi9cbmZ1bmN0aW9uIGRlY3J5cHRBbmRWZXJpZnlNZXNzYWdlKHByaXZhdGVLZXksIHB1YmxpY0tleXMsIG1lc3NhZ2UpIHtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuICBtZXNzYWdlID0gbWVzc2FnZS5kZWNyeXB0KHByaXZhdGVLZXkpO1xuICByZXN1bHQudGV4dCA9IG1lc3NhZ2UuZ2V0VGV4dCgpO1xuICBpZiAocmVzdWx0LnRleHQpIHtcbiAgICByZXN1bHQuc2lnbmF0dXJlcyA9IG1lc3NhZ2UudmVyaWZ5KHB1YmxpY0tleXMpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogU2lnbnMgYSBjbGVhcnRleHQgbWVzc2FnZVxuICogQHBhcmFtICB7W0tleV19ICBwcml2YXRlS2V5cyBwcml2YXRlIGtleSB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGEgdG8gc2lnbiBjbGVhcnRleHRcbiAqIEBwYXJhbSAge1N0cmluZ30gdGV4dCAgICAgICAgY2xlYXJ0ZXh0XG4gKiBAcmV0dXJuIHtTdHJpbmd9ICAgICAgICAgICAgIEFTQ0lJIGFybW9yZWQgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBzaWduQ2xlYXJNZXNzYWdlKHByaXZhdGVLZXlzLCB0ZXh0KSB7XG4gIHZhciBjbGVhcnRleHRNZXNzYWdlID0gbmV3IGNsZWFydGV4dC5DbGVhcnRleHRNZXNzYWdlKHRleHQpO1xuICBjbGVhcnRleHRNZXNzYWdlLnNpZ24ocHJpdmF0ZUtleXMpO1xuICByZXR1cm4gY2xlYXJ0ZXh0TWVzc2FnZS5hcm1vcigpO1xufVxuXG4vKipcbiAqIFZlcmlmaWVzIHNpZ25hdHVyZXMgb2YgY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlXG4gKiBAcGFyYW0gIHtbS2V5XX0gICAgICAgICAgICBwdWJsaWNLZXlzIHB1YmxpYyBrZXlzIHRvIHZlcmlmeSBzaWduYXR1cmVzXG4gKiBAcGFyYW0gIHtDbGVhcnRleHRNZXNzYWdlfSBtZXNzYWdlICAgIGNsZWFydGV4dCBtZXNzYWdlIG9iamVjdCB3aXRoIHNpZ25hdHVyZXNcbiAqIEByZXR1cm4ge3sndGV4dCc6IFN0cmluZywgc2lnbmF0dXJlczogW3sna2V5aWQnOiBrZXlpZCwgJ3N0YXR1cyc6IEJvb2xlYW59XX19XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFydGV4dCB3aXRoIHN0YXR1cyBvZiB2ZXJpZmllZCBzaWduYXR1cmVzXG4gKi9cbmZ1bmN0aW9uIHZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZShwdWJsaWNLZXlzLCBtZXNzYWdlKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcbiAgaWYgKCEobWVzc2FnZSBpbnN0YW5jZW9mIGNsZWFydGV4dC5DbGVhcnRleHRNZXNzYWdlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGFyYW1ldGVyIFttZXNzYWdlXSBuZWVkcyB0byBiZSBvZiB0eXBlIENsZWFydGV4dE1lc3NhZ2UuJyk7XG4gIH1cbiAgcmVzdWx0LnRleHQgPSBtZXNzYWdlLmdldFRleHQoKTtcbiAgcmVzdWx0LnNpZ25hdHVyZXMgPSBtZXNzYWdlLnZlcmlmeShwdWJsaWNLZXlzKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBuZXcgT3BlblBHUCBrZXkgcGFpci4gQ3VycmVudGx5IG9ubHkgc3VwcG9ydHMgUlNBIGtleXMuXG4gKiBQcmltYXJ5IGFuZCBzdWJrZXkgd2lsbCBiZSBvZiBzYW1lIHR5cGUuXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGtleVR5cGUgICAgdG8gaW5kaWNhdGUgd2hhdCB0eXBlIG9mIGtleSB0byBtYWtlLiBcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSU0EgaXMgMS4gU2VlIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQ4ODAjc2VjdGlvbi05LjFcbiAqIEBwYXJhbSB7SW50ZWdlcn0gbnVtQml0cyAgICBudW1iZXIgb2YgYml0cyBmb3IgdGhlIGtleSBjcmVhdGlvbi4gKHNob3VsZCBiZSAxMDI0KywgZ2VuZXJhbGx5KVxuICogQHBhcmFtIHtTdHJpbmd9ICB1c2VySWQgICAgIGFzc3VtZXMgYWxyZWFkeSBpbiBmb3JtIG9mIFwiVXNlciBOYW1lIDx1c2VybmFtZUBlbWFpbC5jb20+XCJcbiAqIEBwYXJhbSB7U3RyaW5nfSAgcGFzc3BocmFzZSBUaGUgcGFzc3BocmFzZSB1c2VkIHRvIGVuY3J5cHQgdGhlIHJlc3VsdGluZyBwcml2YXRlIGtleVxuICogQHJldHVybiB7T2JqZWN0fSB7a2V5OiBbS2V5XSwgcHJpdmF0ZUtleUFybW9yZWQ6IFtTdHJpbmddLCBwdWJsaWNLZXlBcm1vcmVkOiBbU3RyaW5nXX1cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVLZXlQYWlyKGtleVR5cGUsIG51bUJpdHMsIHVzZXJJZCwgcGFzc3BocmFzZSkge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIHZhciBuZXdLZXkgPSBrZXkuZ2VuZXJhdGUoa2V5VHlwZSwgbnVtQml0cywgdXNlcklkLCBwYXNzcGhyYXNlKTtcbiAgcmVzdWx0LmtleSA9IG5ld0tleTtcbiAgcmVzdWx0LnByaXZhdGVLZXlBcm1vcmVkID0gbmV3S2V5LmFybW9yKCk7XG4gIHJlc3VsdC5wdWJsaWNLZXlBcm1vcmVkID0gbmV3S2V5LnRvUHVibGljKCkuYXJtb3IoKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0cy5lbmNyeXB0TWVzc2FnZSA9IGVuY3J5cHRNZXNzYWdlO1xuZXhwb3J0cy5zaWduQW5kRW5jcnlwdE1lc3NhZ2UgPSBzaWduQW5kRW5jcnlwdE1lc3NhZ2U7XG5leHBvcnRzLmRlY3J5cHRNZXNzYWdlID0gZGVjcnlwdE1lc3NhZ2U7XG5leHBvcnRzLmRlY3J5cHRBbmRWZXJpZnlNZXNzYWdlID0gZGVjcnlwdEFuZFZlcmlmeU1lc3NhZ2VcbmV4cG9ydHMuc2lnbkNsZWFyTWVzc2FnZSA9IHNpZ25DbGVhck1lc3NhZ2U7XG5leHBvcnRzLnZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZSA9IHZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZTtcbmV4cG9ydHMuZ2VuZXJhdGVLZXlQYWlyID0gZ2VuZXJhdGVLZXlQYWlyO1xuIiwidmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxuLy8gVGhpcyBpcyBwcmV0dHkgdWdseSwgYnV0IGJyb3dzZXJpZnkgbmVlZHMgdG8gaGF2ZSB0aGUgcmVxdWlyZXMgZXhwbGljaXRseSB3cml0dGVuLlxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGNvbXByZXNzZWQ6IHJlcXVpcmUoJy4vY29tcHJlc3NlZC5qcycpLFxuICBzeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQ6IHJlcXVpcmUoJy4vc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkLmpzJyksXG4gIHB1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5OiByZXF1aXJlKCcuL3B1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5LmpzJyksXG4gIHN5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXk6IHJlcXVpcmUoJy4vc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleS5qcycpLFxuICBsaXRlcmFsOiByZXF1aXJlKCcuL2xpdGVyYWwuanMnKSxcbiAgcHVibGljX2tleTogcmVxdWlyZSgnLi9wdWJsaWNfa2V5LmpzJyksXG4gIHN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkOiByZXF1aXJlKCcuL3N5bW1ldHJpY2FsbHlfZW5jcnlwdGVkLmpzJyksXG4gIG1hcmtlcjogcmVxdWlyZSgnLi9tYXJrZXIuanMnKSxcbiAgcHVibGljX3N1YmtleTogcmVxdWlyZSgnLi9wdWJsaWNfc3Via2V5LmpzJyksXG4gIHVzZXJfYXR0cmlidXRlOiByZXF1aXJlKCcuL3VzZXJfYXR0cmlidXRlLmpzJyksXG4gIG9uZV9wYXNzX3NpZ25hdHVyZTogcmVxdWlyZSgnLi9vbmVfcGFzc19zaWduYXR1cmUuanMnKSxcbiAgc2VjcmV0X2tleTogcmVxdWlyZSgnLi9zZWNyZXRfa2V5LmpzJyksXG4gIHVzZXJpZDogcmVxdWlyZSgnLi91c2VyaWQuanMnKSxcbiAgc2VjcmV0X3N1YmtleTogcmVxdWlyZSgnLi9zZWNyZXRfc3Via2V5LmpzJyksXG4gIHNpZ25hdHVyZTogcmVxdWlyZSgnLi9zaWduYXR1cmUuanMnKSxcbiAgdHJ1c3Q6IHJlcXVpcmUoJy4vdHJ1c3QuanMnKVxufVxuXG5mb3IgKHZhciBpIGluIGVudW1zLnBhY2tldCkge1xuICB2YXIgcGFja2V0Q2xhc3MgPSBtb2R1bGUuZXhwb3J0c1tpXTtcblxuICBpZiAocGFja2V0Q2xhc3MgIT0gdW5kZWZpbmVkKVxuICAgIHBhY2tldENsYXNzLnByb3RvdHlwZS50YWcgPSBlbnVtcy5wYWNrZXRbaV07XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBKWEcgPSByZXF1aXJlKCcuLi9jb21wcmVzc2lvbi9qeGcuanMnKSxcbiAgYmFzZTY0ID0gcmVxdWlyZSgnLi4vZW5jb2RpbmcvYmFzZTY0LmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBDb21wcmVzc2VkIERhdGEgUGFja2V0IChUYWcgOClcbiAqIFxuICogUkZDNDg4MCA1LjY6XG4gKiBUaGUgQ29tcHJlc3NlZCBEYXRhIHBhY2tldCBjb250YWlucyBjb21wcmVzc2VkIGRhdGEuICBUeXBpY2FsbHksIHRoaXNcbiAqIHBhY2tldCBpcyBmb3VuZCBhcyB0aGUgY29udGVudHMgb2YgYW4gZW5jcnlwdGVkIHBhY2tldCwgb3IgZm9sbG93aW5nXG4gKiBhIFNpZ25hdHVyZSBvciBPbmUtUGFzcyBTaWduYXR1cmUgcGFja2V0LCBhbmQgY29udGFpbnMgYSBsaXRlcmFsIGRhdGFcbiAqIHBhY2tldC5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfY29tcHJlc3NlZCgpIHtcbiAgLyoqIEB0eXBlIHtwYWNrZXRsaXN0fSAqL1xuICB0aGlzLnBhY2tldHM7XG4gIC8qKiBAdHlwZSB7Y29tcHJlc3Npb259ICovXG4gIHRoaXMuYWxnb3JpdGhtID0gJ3VuY29tcHJlc3NlZCc7XG5cbiAgdGhpcy5jb21wcmVzc2VkID0gbnVsbDtcblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciB0aGUgcGFja2V0LlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyA4IHBhY2tldFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJBTSB7aU5URUdFUn0gTEVOIGxFTkdUSCBPRiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mIFxuICAgKiBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9jb21wcmVzc2VkfSBPYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgLy8gT25lIG9jdGV0IHRoYXQgZ2l2ZXMgdGhlIGFsZ29yaXRobSB1c2VkIHRvIGNvbXByZXNzIHRoZSBwYWNrZXQuXG4gICAgdGhpcy5hbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLmNvbXByZXNzaW9uLCBieXRlcy5jaGFyQ29kZUF0KDApKTtcblxuICAgIC8vIENvbXByZXNzZWQgZGF0YSwgd2hpY2ggbWFrZXMgdXAgdGhlIHJlbWFpbmRlciBvZiB0aGUgcGFja2V0LlxuICAgIHRoaXMuY29tcHJlc3NlZCA9IGJ5dGVzLnN1YnN0cigxKTtcblxuICAgIHRoaXMuZGVjb21wcmVzcygpO1xuICB9XG5cblxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5jb21wcmVzc2VkID09IG51bGwpXG4gICAgICB0aGlzLmNvbXByZXNzKCk7XG5cbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5jb21wcmVzc2lvbiwgdGhpcy5hbGdvcml0aG0pKSArIHRoaXMuY29tcHJlc3NlZDtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIERlY29tcHJlc3Npb24gbWV0aG9kIGZvciBkZWNvbXByZXNzaW5nIHRoZSBjb21wcmVzc2VkIGRhdGFcbiAgICogcmVhZCBieSByZWFkX3BhY2tldFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBkZWNvbXByZXNzZWQgZGF0YVxuICAgKi9cbiAgdGhpcy5kZWNvbXByZXNzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGRlY29tcHJlc3NlZDtcblxuICAgIHN3aXRjaCAodGhpcy5hbGdvcml0aG0pIHtcbiAgICAgIGNhc2UgJ3VuY29tcHJlc3NlZCc6XG4gICAgICAgIGRlY29tcHJlc3NlZCA9IHRoaXMuY29tcHJlc3NlZDtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3ppcCc6XG4gICAgICAgIHZhciBjb21wRGF0YSA9IHRoaXMuY29tcHJlc3NlZDtcblxuICAgICAgICB2YXIgcmFkaXggPSBiYXNlNjQuZW5jb2RlKGNvbXBEYXRhKS5yZXBsYWNlKC9cXG4vZywgXCJcIik7XG4gICAgICAgIC8vIG5vIGhlYWRlciBpbiB0aGlzIGNhc2UsIGRpcmVjdGx5IGNhbGwgZGVmbGF0ZVxuICAgICAgICB2YXIganhnX29iaiA9IG5ldyBKWEcuVXRpbC5VbnppcChKWEcuVXRpbC5CYXNlNjQuZGVjb2RlQXNBcnJheShyYWRpeCkpO1xuXG4gICAgICAgIGRlY29tcHJlc3NlZCA9IHVuZXNjYXBlKGp4Z19vYmouZGVmbGF0ZSgpWzBdWzBdKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3psaWInOlxuICAgICAgICAvL1JGQyAxOTUwLiBCaXRzIDAtMyBDb21wcmVzc2lvbiBNZXRob2RcbiAgICAgICAgdmFyIGNvbXByZXNzaW9uTWV0aG9kID0gdGhpcy5jb21wcmVzc2VkLmNoYXJDb2RlQXQoMCkgJSAweDEwO1xuXG4gICAgICAgIC8vQml0cyA0LTcgUkZDIDE5NTAgYXJlIExaNzcgV2luZG93LiBHZW5lcmFsbHkgdGhpcyB2YWx1ZSBpcyA3ID09IDMyayB3aW5kb3cgc2l6ZS5cbiAgICAgICAgLy8gMm5kIEJ5dGUgaW4gUkZDIDE5NTAgaXMgZm9yIFwiRkxBR3NcIiBBbGxvd3MgZm9yIGEgRGljdGlvbmFyeSBcbiAgICAgICAgLy8gKGhvdyBpcyB0aGlzIGRlZmluZWQpLiBCYXNpYyBjaGVja3N1bSwgYW5kIGNvbXByZXNzaW9uIGxldmVsLlxuXG4gICAgICAgIGlmIChjb21wcmVzc2lvbk1ldGhvZCA9PSA4KSB7IC8vQ00gOCBpcyBmb3IgREVGTEFURSwgUkZDIDE5NTFcbiAgICAgICAgICAvLyByZW1vdmUgNCBieXRlcyBBRExFUjMyIGNoZWNrc3VtIGZyb20gdGhlIGVuZFxuICAgICAgICAgIHZhciBjb21wRGF0YSA9IHRoaXMuY29tcHJlc3NlZC5zdWJzdHJpbmcoMCwgdGhpcy5jb21wcmVzc2VkLmxlbmd0aCAtIDQpO1xuICAgICAgICAgIHZhciByYWRpeCA9IGJhc2U2NC5lbmNvZGUoY29tcERhdGEpLnJlcGxhY2UoL1xcbi9nLCBcIlwiKTtcbiAgICAgICAgICAvL1RPRE8gY2hlY2sgQURMRVIzMiBjaGVja3N1bVxuICAgICAgICAgIGRlY29tcHJlc3NlZCA9IEpYRy5kZWNvbXByZXNzKHJhZGl4KTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHV0aWwucHJpbnRfZXJyb3IoXCJDb21wcmVzc2lvbiBhbGdvcml0aG0gWkxJQiBvbmx5IHN1cHBvcnRzIFwiICtcbiAgICAgICAgICAgIFwiREVGTEFURSBjb21wcmVzc2lvbiBtZXRob2QuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdiemlwMic6XG4gICAgICAgIC8vIFRPRE86IG5lZWQgdG8gaW1wbGVtZW50IHRoaXNcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb21wcmVzc2lvbiBhbGdvcml0aG0gQlppcDIgW0JaMl0gaXMgbm90IGltcGxlbWVudGVkLicpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIHVua25vd24gOlwiICsgdGhpcy5hbG9ncml0aG0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLnBhY2tldHMucmVhZChkZWNvbXByZXNzZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXByZXNzIHRoZSBwYWNrZXQgZGF0YSAobWVtYmVyIGRlY29tcHJlc3NlZERhdGEpXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gdHlwZSBBbGdvcml0aG0gdG8gYmUgdXNlZCAvLyBTZWUgUkZDIDQ4ODAgOS4zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgY29tcHJlc3NlZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBjb21wcmVzc2VkIGRhdGEgc3RvcmVkIGluIGF0dHJpYnV0ZSBjb21wcmVzc2VkRGF0YVxuICAgKi9cbiAgdGhpcy5jb21wcmVzcyA9IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5hbGdvcml0aG0pIHtcblxuICAgICAgY2FzZSAndW5jb21wcmVzc2VkJzpcbiAgICAgICAgLy8gLSBVbmNvbXByZXNzZWRcbiAgICAgICAgdGhpcy5jb21wcmVzc2VkID0gdGhpcy5wYWNrZXRzLndyaXRlKCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd6aXAnOlxuICAgICAgICAvLyAtIFpJUCBbUkZDMTk1MV1cbiAgICAgICAgdXRpbC5wcmludF9lcnJvcihcIkNvbXByZXNzaW9uIGFsZ29yaXRobSBaSVAgW1JGQzE5NTFdIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd6bGliJzpcbiAgICAgICAgLy8gLSBaTElCIFtSRkMxOTUwXVxuICAgICAgICAvLyBUT0RPOiBuZWVkIHRvIGltcGxlbWVudCB0aGlzXG4gICAgICAgIHV0aWwucHJpbnRfZXJyb3IoXCJDb21wcmVzc2lvbiBhbGdvcml0aG0gWkxJQiBbUkZDMTk1MF0gaXMgbm90IGltcGxlbWVudGVkLlwiKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2J6aXAyJzpcbiAgICAgICAgLy8gIC0gQlppcDIgW0JaMl1cbiAgICAgICAgLy8gVE9ETzogbmVlZCB0byBpbXBsZW1lbnQgdGhpc1xuICAgICAgICB1dGlsLnByaW50X2Vycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIEJaaXAyIFtCWjJdIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB1dGlsLnByaW50X2Vycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIHVua25vd24gOlwiICsgdGhpcy50eXBlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59O1xuIiwidmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGxpc3Q6IHJlcXVpcmUoJy4vcGFja2V0bGlzdC5qcycpLFxufTtcblxudmFyIHBhY2tldHMgPSByZXF1aXJlKCcuL2FsbF9wYWNrZXRzLmpzJyk7XG5cbmZvciAodmFyIGkgaW4gcGFja2V0cylcbiAgbW9kdWxlLmV4cG9ydHNbaV0gPSBwYWNrZXRzW2ldO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIExpdGVyYWwgRGF0YSBQYWNrZXQgKFRhZyAxMSlcbiAqIFxuICogUkZDNDg4MCA1Ljk6IEEgTGl0ZXJhbCBEYXRhIHBhY2tldCBjb250YWlucyB0aGUgYm9keSBvZiBhIG1lc3NhZ2U7IGRhdGEgdGhhdFxuICogaXMgbm90IHRvIGJlIGZ1cnRoZXIgaW50ZXJwcmV0ZWQuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X2xpdGVyYWwoKSB7XG4gIHRoaXMuZm9ybWF0ID0gJ3V0ZjgnOyAvLyBkZWZhdWx0IGZvcm1hdCBmb3IgbGl0ZXJhbCBkYXRhIHBhY2tldHNcbiAgdGhpcy5kYXRhID0gJyc7IC8vIGxpdGVyYWwgZGF0YSByZXByZXNlbnRhdGlvbiBhcyBuYXRpdmUgSmF2YVNjcmlwdCBzdHJpbmcgb3IgYnl0ZXNcbiAgdGhpcy5kYXRlID0gbmV3IERhdGUoKTtcblxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHBhY2tldCBkYXRhIHRvIGEgamF2YXNjcmlwdCBuYXRpdmUgc3RyaW5nLCBlbmQgb2YgbGluZSBcbiAgICogd2lsbCBiZSBub3JtYWxpemVkIHRvIFxcclxcbiBhbmQgYnkgZGVmYXVsdCB0ZXh0IGlzIGNvbnZlcnRlZCB0byBVVEY4XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IEFueSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmdcbiAgICovXG4gIHRoaXMuc2V0VGV4dCA9IGZ1bmN0aW9uKHRleHQpIHtcbiAgICAvLyBub3JtYWxpemUgRU9MIHRvIFxcclxcblxuICAgIHRleHQgPSB0ZXh0LnJlcGxhY2UoL1xcci9nLCAnJykucmVwbGFjZSgvXFxuL2csICdcXHJcXG4nKTtcbiAgICAvLyBlbmNvZGUgVVRGOFxuICAgIHRoaXMuZGF0YSA9IHRoaXMuZm9ybWF0ID09ICd1dGY4JyA/IHV0aWwuZW5jb2RlX3V0ZjgodGV4dCkgOiB0ZXh0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgbGl0ZXJhbCBkYXRhIHBhY2tldHMgYXMgbmF0aXZlIEphdmFTY3JpcHQgc3RyaW5nXG4gICAqIHdpdGggbm9ybWFsaXplZCBlbmQgb2YgbGluZSB0byBcXG5cbiAgICogQHJldHVybiB7U3RyaW5nfSBsaXRlcmFsIGRhdGEgYXMgdGV4dFxuICAgKi9cbiAgdGhpcy5nZXRUZXh0ID0gZnVuY3Rpb24oKSB7XG4gICAgLy8gZGVjb2RlIFVURjhcbiAgICB2YXIgdGV4dCA9IHV0aWwuZGVjb2RlX3V0ZjgodGhpcy5kYXRhKTtcbiAgICAvLyBub3JtYWxpemUgRU9MIHRvIFxcblxuICAgIHJldHVybiB0ZXh0LnJlcGxhY2UoL1xcclxcbi9nLCAnXFxuJyk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBwYWNrZXQgZGF0YSB0byB2YWx1ZSByZXByZXNlbnRlZCBieSB0aGUgcHJvdmlkZWQgc3RyaW5nIG9mIGJ5dGVzLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gYnl0ZXMgVGhlIHN0cmluZyBvZiBieXRlc1xuICAgKiBAcGFyYW0geyd1dGY4fCdiaW5hcnknfCd0ZXh0J30gZm9ybWF0IFRoZSBmb3JtYXQgb2YgdGhlIHN0cmluZyBvZiBieXRlc1xuICAgKi9cbiAgdGhpcy5zZXRCeXRlcyA9IGZ1bmN0aW9uKGJ5dGVzLCBmb3JtYXQpIHtcbiAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICB0aGlzLmRhdGEgPSBieXRlcztcbiAgfVxuXG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYnl0ZSBzZXF1ZW5jZSByZXByZXNlbnRpbmcgdGhlIGxpdGVyYWwgcGFja2V0IGRhdGFcbiAgICogQHJldHVybnMge1N0cmluZ30gQSBzZXF1ZW5jZSBvZiBieXRlc1xuICAgKi9cbiAgdGhpcy5nZXRCeXRlcyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGE7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgKHRhZyAxMSkuXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxMSBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvblxuICAgKiAgICAgICAgICAgIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuXG4gICAqICAgICAgICAgICAgTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2ZcbiAgICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBvYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgLy8gLSBBIG9uZS1vY3RldCBmaWVsZCB0aGF0IGRlc2NyaWJlcyBob3cgdGhlIGRhdGEgaXMgZm9ybWF0dGVkLlxuXG4gICAgdmFyIGZvcm1hdCA9IGVudW1zLnJlYWQoZW51bXMubGl0ZXJhbCwgYnl0ZXMuY2hhckNvZGVBdCgwKSk7XG5cbiAgICB2YXIgZmlsZW5hbWVfbGVuID0gYnl0ZXMuY2hhckNvZGVBdCgxKTtcbiAgICB0aGlzLmZpbGVuYW1lID0gdXRpbC5kZWNvZGVfdXRmOChieXRlcy5zdWJzdHIoMiwgZmlsZW5hbWVfbGVuKSk7XG5cbiAgICB0aGlzLmRhdGUgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cigyICsgZmlsZW5hbWVfbGVuLCA0KSk7XG5cbiAgICB2YXIgZGF0YSA9IGJ5dGVzLnN1YnN0cmluZyg2ICsgZmlsZW5hbWVfbGVuKTtcblxuICAgIHRoaXMuc2V0Qnl0ZXMoZGF0YSwgZm9ybWF0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYWNrZXRcbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIGJlIGluc2VydGVkIGFzIGJvZHlcbiAgICogQHJldHVybiB7U3RyaW5nfSBzdHJpbmctcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhY2tldFxuICAgKi9cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBmaWxlbmFtZSA9IHV0aWwuZW5jb2RlX3V0ZjgoXCJtc2cudHh0XCIpO1xuXG4gICAgdmFyIGRhdGEgPSB0aGlzLmdldEJ5dGVzKCk7XG5cbiAgICB2YXIgcmVzdWx0ID0gJyc7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMubGl0ZXJhbCwgdGhpcy5mb3JtYXQpKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShmaWxlbmFtZS5sZW5ndGgpO1xuICAgIHJlc3VsdCArPSBmaWxlbmFtZTtcbiAgICByZXN1bHQgKz0gdXRpbC53cml0ZURhdGUodGhpcy5kYXRlKTtcbiAgICByZXN1bHQgKz0gZGF0YTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgc3RyYW5nZSBcIk1hcmtlciBwYWNrZXRcIiAoVGFnIDEwKVxuICogXG4gKiBSRkM0ODgwIDUuODogQW4gZXhwZXJpbWVudGFsIHZlcnNpb24gb2YgUEdQIHVzZWQgdGhpcyBwYWNrZXQgYXMgdGhlIExpdGVyYWxcbiAqIHBhY2tldCwgYnV0IG5vIHJlbGVhc2VkIHZlcnNpb24gb2YgUEdQIGdlbmVyYXRlZCBMaXRlcmFsIHBhY2tldHMgd2l0aCB0aGlzXG4gKiB0YWcuIFdpdGggUEdQIDUueCwgdGhpcyBwYWNrZXQgaGFzIGJlZW4gcmVhc3NpZ25lZCBhbmQgaXMgcmVzZXJ2ZWQgZm9yIHVzZSBhc1xuICogdGhlIE1hcmtlciBwYWNrZXQuXG4gKiBcbiAqIFN1Y2ggYSBwYWNrZXQgTVVTVCBiZSBpZ25vcmVkIHdoZW4gcmVjZWl2ZWQuXG4gKi9cbmZ1bmN0aW9uIHBhY2tldF9tYXJrZXIoKSB7XG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgKHRhZyAxMCkuXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxMCBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvblxuICAgKiAgICAgICAgICAgIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuXG4gICAqICAgICAgICAgICAgTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2ZcbiAgICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBPYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgaWYgKGJ5dGVzLmNoYXJDb2RlQXQoMCkgPT0gMHg1MCAmJiAvLyBQXG4gICAgYnl0ZXMuY2hhckNvZGVBdCgxKSA9PSAweDQ3ICYmIC8vIEdcbiAgICBieXRlcy5jaGFyQ29kZUF0KDIpID09IDB4NTApIC8vIFBcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIC8vIG1hcmtlciBwYWNrZXQgZG9lcyBub3QgY29udGFpbiBcIlBHUFwiXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcGFja2V0X21hcmtlcjtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBPbmUtUGFzcyBTaWduYXR1cmUgUGFja2V0cyAoVGFnIDQpXG4gKiBcbiAqIFJGQzQ4ODAgNS40OlxuICogVGhlIE9uZS1QYXNzIFNpZ25hdHVyZSBwYWNrZXQgcHJlY2VkZXMgdGhlIHNpZ25lZCBkYXRhIGFuZCBjb250YWluc1xuICogZW5vdWdoIGluZm9ybWF0aW9uIHRvIGFsbG93IHRoZSByZWNlaXZlciB0byBiZWdpbiBjYWxjdWxhdGluZyBhbnlcbiAqIGhhc2hlcyBuZWVkZWQgdG8gdmVyaWZ5IHRoZSBzaWduYXR1cmUuICBJdCBhbGxvd3MgdGhlIFNpZ25hdHVyZVxuICogcGFja2V0IHRvIGJlIHBsYWNlZCBhdCB0aGUgZW5kIG9mIHRoZSBtZXNzYWdlLCBzbyB0aGF0IHRoZSBzaWduZXJcbiAqIGNhbiBjb21wdXRlIHRoZSBlbnRpcmUgc2lnbmVkIG1lc3NhZ2UgaW4gb25lIHBhc3MuXG4gKi9cblxudmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKSxcbiAgdHlwZV9rZXlpZCA9IHJlcXVpcmUoJy4uL3R5cGUva2V5aWQuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfb25lX3Bhc3Nfc2lnbmF0dXJlKCkge1xuICB0aGlzLnZlcnNpb24gPSBudWxsOyAvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gIFRoZSBjdXJyZW50IHZlcnNpb24gaXMgMy5cbiAgdGhpcy50eXBlID0gbnVsbDsgLy8gQSBvbmUtb2N0ZXQgc2lnbmF0dXJlIHR5cGUuICBTaWduYXR1cmUgdHlwZXMgYXJlIGRlc2NyaWJlZCBpbiBSRkM0ODgwIFNlY3Rpb24gNS4yLjEuXG4gIHRoaXMuaGFzaEFsZ29yaXRobSA9IG51bGw7IC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBoYXNoIGFsZ29yaXRobSB1c2VkLiAoU2VlIFJGQzQ4ODAgOS40KVxuICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IG51bGw7IC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBwdWJsaWMta2V5IGFsZ29yaXRobSB1c2VkLiAoU2VlIFJGQzQ4ODAgOS4xKVxuICB0aGlzLnNpZ25pbmdLZXlJZCA9IG51bGw7IC8vIEFuIGVpZ2h0LW9jdGV0IG51bWJlciBob2xkaW5nIHRoZSBLZXkgSUQgb2YgdGhlIHNpZ25pbmcga2V5LlxuICB0aGlzLmZsYWdzID0gbnVsbDsgLy8gIEEgb25lLW9jdGV0IG51bWJlciBob2xkaW5nIGEgZmxhZyBzaG93aW5nIHdoZXRoZXIgdGhlIHNpZ25hdHVyZSBpcyBuZXN0ZWQuICBBIHplcm8gdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcGFja2V0IGlzIGFub3RoZXIgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCB0aGF0IGRlc2NyaWJlcyBhbm90aGVyIHNpZ25hdHVyZSB0byBiZSBhcHBsaWVkIHRvIHRoZSBzYW1lIG1lc3NhZ2UgZGF0YS5cblxuICAvKipcbiAgICogcGFyc2luZyBmdW5jdGlvbiBmb3IgYSBvbmUtcGFzcyBzaWduYXR1cmUgcGFja2V0ICh0YWcgNCkuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBwYXlsb2FkIG9mIGEgdGFnIDQgcGFja2V0XG4gICAqIEByZXR1cm4ge3BhY2tldF9vbmVfcGFzc19zaWduYXR1cmV9IG9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgbXlwb3MgPSAwO1xuICAgIC8vIEEgb25lLW9jdGV0IHZlcnNpb24gbnVtYmVyLiAgVGhlIGN1cnJlbnQgdmVyc2lvbiBpcyAzLlxuICAgIHRoaXMudmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBzaWduYXR1cmUgdHlwZS4gIFNpZ25hdHVyZSB0eXBlcyBhcmUgZGVzY3JpYmVkIGluXG4gICAgLy8gICBTZWN0aW9uIDUuMi4xLlxuICAgIHRoaXMudHlwZSA9IGVudW1zLnJlYWQoZW51bXMuc2lnbmF0dXJlLCBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspKTtcblxuICAgIC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBoYXNoIGFsZ29yaXRobSB1c2VkLlxuICAgIHRoaXMuaGFzaEFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMuaGFzaCwgYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKSk7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgcHVibGljLWtleSBhbGdvcml0aG0gdXNlZC5cbiAgICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspKTtcblxuICAgIC8vIEFuIGVpZ2h0LW9jdGV0IG51bWJlciBob2xkaW5nIHRoZSBLZXkgSUQgb2YgdGhlIHNpZ25pbmcga2V5LlxuICAgIHRoaXMuc2lnbmluZ0tleUlkID0gbmV3IHR5cGVfa2V5aWQoKTtcbiAgICB0aGlzLnNpZ25pbmdLZXlJZC5yZWFkKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgIG15cG9zICs9IDg7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgaG9sZGluZyBhIGZsYWcgc2hvd2luZyB3aGV0aGVyIHRoZSBzaWduYXR1cmVcbiAgICAvLyAgIGlzIG5lc3RlZC4gIEEgemVybyB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCB0aGUgbmV4dCBwYWNrZXQgaXNcbiAgICAvLyAgIGFub3RoZXIgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCB0aGF0IGRlc2NyaWJlcyBhbm90aGVyXG4gICAgLy8gICBzaWduYXR1cmUgdG8gYmUgYXBwbGllZCB0byB0aGUgc2FtZSBtZXNzYWdlIGRhdGEuXG4gICAgdGhpcy5mbGFncyA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogY3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIG9uZS1wYXNzIHNpZ25hdHVyZSBwYWNrZXRcbiAgICogQHJldHVybiB7U3RyaW5nfSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIG9uZS1wYXNzIHNpZ25hdHVyZSBwYWNrZXRcbiAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcblxuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDMpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnNpZ25hdHVyZSwgdGhpcy50eXBlKSk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMuaGFzaCwgdGhpcy5oYXNoQWxnb3JpdGhtKSk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMucHVibGljS2V5LCB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSkpO1xuICAgIHJlc3VsdCArPSB0aGlzLnNpZ25pbmdLZXlJZC53cml0ZSgpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZmxhZ3MpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJlYWRTaW1wbGVMZW5ndGg6IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIGxlbiA9IDAsXG4gICAgICBvZmZzZXQsXG4gICAgICB0eXBlID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcblxuXG4gICAgaWYgKHR5cGUgPCAxOTIpIHtcbiAgICAgIGxlbiA9IGJ5dGVzLmNoYXJDb2RlQXQoMCk7XG4gICAgICBvZmZzZXQgPSAxO1xuICAgIH0gZWxzZSBpZiAodHlwZSA8IDI1NSkge1xuICAgICAgbGVuID0gKChieXRlcy5jaGFyQ29kZUF0KDApIC0gMTkyKSA8PCA4KSArIChieXRlcy5jaGFyQ29kZUF0KDEpKSArIDE5MjtcbiAgICAgIG9mZnNldCA9IDI7XG4gICAgfSBlbHNlIGlmICh0eXBlID09IDI1NSkge1xuICAgICAgbGVuID0gdXRpbC5yZWFkTnVtYmVyKGJ5dGVzLnN1YnN0cigxLCA0KSk7XG4gICAgICBvZmZzZXQgPSA1O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBsZW46IGxlbixcbiAgICAgIG9mZnNldDogb2Zmc2V0XG4gICAgfTtcbiAgfSxcblxuICAvKipcbiAgICogRW5jb2RlcyBhIGdpdmVuIGludGVnZXIgb2YgbGVuZ3RoIHRvIHRoZSBvcGVucGdwIGxlbmd0aCBzcGVjaWZpZXIgdG8gYVxuICAgKiBzdHJpbmdcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIFRoZSBsZW5ndGggdG8gZW5jb2RlXG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIHdpdGggb3BlbnBncCBsZW5ndGggcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHdyaXRlU2ltcGxlTGVuZ3RoOiBmdW5jdGlvbihsZW5ndGgpIHtcbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICBpZiAobGVuZ3RoIDwgMTkyKSB7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW5ndGgpO1xuICAgIH0gZWxzZSBpZiAobGVuZ3RoID4gMTkxICYmIGxlbmd0aCA8IDgzODQpIHtcbiAgICAgIC8qXG4gICAgICAgKiBsZXQgYSA9ICh0b3RhbCBkYXRhIHBhY2tldCBsZW5ndGgpIC0gMTkyIGxldCBiYyA9IHR3byBvY3RldFxuICAgICAgICogcmVwcmVzZW50YXRpb24gb2YgYSBsZXQgZCA9IGIgKyAxOTJcbiAgICAgICAqL1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChsZW5ndGggLSAxOTIpID4+IDgpICsgMTkyKTtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChsZW5ndGggLSAxOTIpICYgMHhGRik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDI1NSk7XG4gICAgICByZXN1bHQgKz0gdXRpbC53cml0ZU51bWJlcihsZW5ndGgsIDQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LFxuXG4gIC8qKlxuICAgKiBXcml0ZXMgYSBwYWNrZXQgaGVhZGVyIHZlcnNpb24gNCB3aXRoIHRoZSBnaXZlbiB0YWdfdHlwZSBhbmQgbGVuZ3RoIHRvIGFcbiAgICogc3RyaW5nXG4gICAqIFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRhZ190eXBlIFRhZyB0eXBlXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIExlbmd0aCBvZiB0aGUgcGF5bG9hZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyBvZiB0aGUgaGVhZGVyXG4gICAqL1xuICB3cml0ZUhlYWRlcjogZnVuY3Rpb24odGFnX3R5cGUsIGxlbmd0aCkge1xuICAgIC8qIHdlJ3JlIG9ubHkgZ2VuZXJhdGluZyB2NCBwYWNrZXQgaGVhZGVycyBoZXJlICovXG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHhDMCB8IHRhZ190eXBlKTtcbiAgICByZXN1bHQgKz0gdGhpcy53cml0ZVNpbXBsZUxlbmd0aChsZW5ndGgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHBhY2tldCBoZWFkZXIgVmVyc2lvbiAzIHdpdGggdGhlIGdpdmVuIHRhZ190eXBlIGFuZCBsZW5ndGggdG8gYVxuICAgKiBzdHJpbmdcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gdGFnX3R5cGUgVGFnIHR5cGVcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIG9mIHRoZSBwYXlsb2FkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIG9mIHRoZSBoZWFkZXJcbiAgICovXG4gIHdyaXRlT2xkSGVhZGVyOiBmdW5jdGlvbih0YWdfdHlwZSwgbGVuZ3RoKSB7XG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgaWYgKGxlbmd0aCA8IDI1Nikge1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg4MCB8ICh0YWdfdHlwZSA8PCAyKSk7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW5ndGgpO1xuICAgIH0gZWxzZSBpZiAobGVuZ3RoIDwgNjU1MzYpIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ODAgfCAodGFnX3R5cGUgPDwgMikgfCAxKTtcbiAgICAgIHJlc3VsdCArPSB1dGlsLndyaXRlTnVtYmVyKGxlbmd0aCwgMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ODAgfCAodGFnX3R5cGUgPDwgMikgfCAyKTtcbiAgICAgIHJlc3VsdCArPSB1dGlsLndyaXRlTnVtYmVyKGxlbmd0aCwgNCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdlbmVyaWMgc3RhdGljIFBhY2tldCBQYXJzZXIgZnVuY3Rpb25cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCBzdHJlYW0gYXMgc3RyaW5nXG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcGFyc2luZ1xuICAgKiBAcGFyYW0ge2ludGVnZXJ9IGxlbiBMZW5ndGggb2YgdGhlIGlucHV0IGZyb20gcG9zaXRpb24gb25cbiAgICogQHJldHVybiB7T2JqZWN0fSBSZXR1cm5zIGEgcGFyc2VkIG9wZW5wZ3BfcGFja2V0XG4gICAqL1xuICByZWFkOiBmdW5jdGlvbihpbnB1dCwgcG9zaXRpb24sIGxlbikge1xuICAgIC8vIHNvbWUgc2FuaXR5IGNoZWNrc1xuICAgIGlmIChpbnB1dCA9PSBudWxsIHx8IGlucHV0Lmxlbmd0aCA8PSBwb3NpdGlvbiB8fCBpbnB1dC5zdWJzdHJpbmcocG9zaXRpb24pLmxlbmd0aCA8IDIgfHwgKGlucHV0LmNoYXJDb2RlQXQocG9zaXRpb24pICZcbiAgICAgIDB4ODApID09IDApIHtcbiAgICAgIHV0aWxcbiAgICAgICAgLnByaW50X2Vycm9yKFwiRXJyb3IgZHVyaW5nIHBhcnNpbmcuIFRoaXMgbWVzc2FnZSAvIGtleSBpcyBwcm9iYWJseSBub3QgY29udGFpbmluZyBhIHZhbGlkIE9wZW5QR1AgZm9ybWF0LlwiKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgbXlwb3MgPSBwb3NpdGlvbjtcbiAgICB2YXIgdGFnID0gLTE7XG4gICAgdmFyIGZvcm1hdCA9IC0xO1xuICAgIHZhciBwYWNrZXRfbGVuZ3RoO1xuXG4gICAgZm9ybWF0ID0gMDsgLy8gMCA9IG9sZCBmb3JtYXQ7IDEgPSBuZXcgZm9ybWF0XG4gICAgaWYgKChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSAmIDB4NDApICE9IDApIHtcbiAgICAgIGZvcm1hdCA9IDE7XG4gICAgfVxuXG4gICAgdmFyIHBhY2tldF9sZW5ndGhfdHlwZTtcbiAgICBpZiAoZm9ybWF0KSB7XG4gICAgICAvLyBuZXcgZm9ybWF0IGhlYWRlclxuICAgICAgdGFnID0gaW5wdXQuY2hhckNvZGVBdChteXBvcykgJiAweDNGOyAvLyBiaXQgNS0wXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG9sZCBmb3JtYXQgaGVhZGVyXG4gICAgICB0YWcgPSAoaW5wdXQuY2hhckNvZGVBdChteXBvcykgJiAweDNGKSA+PiAyOyAvLyBiaXQgNS0yXG4gICAgICBwYWNrZXRfbGVuZ3RoX3R5cGUgPSBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSAmIDB4MDM7IC8vIGJpdCAxLTBcbiAgICB9XG5cbiAgICAvLyBoZWFkZXIgb2N0ZXQgcGFyc2luZyBkb25lXG4gICAgbXlwb3MrKztcblxuICAgIC8vIHBhcnNlZCBsZW5ndGggZnJvbSBsZW5ndGggZmllbGRcbiAgICB2YXIgYm9keWRhdGEgPSBudWxsO1xuXG4gICAgLy8gdXNlZCBmb3IgcGFydGlhbCBib2R5IGxlbmd0aHNcbiAgICB2YXIgcmVhbF9wYWNrZXRfbGVuZ3RoID0gLTE7XG4gICAgaWYgKCFmb3JtYXQpIHtcbiAgICAgIC8vIDQuMi4xLiBPbGQgRm9ybWF0IFBhY2tldCBMZW5ndGhzXG4gICAgICBzd2l0Y2ggKHBhY2tldF9sZW5ndGhfdHlwZSkge1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgLy8gVGhlIHBhY2tldCBoYXMgYSBvbmUtb2N0ZXQgbGVuZ3RoLiBUaGUgaGVhZGVyIGlzIDIgb2N0ZXRzXG4gICAgICAgICAgLy8gbG9uZy5cbiAgICAgICAgICBwYWNrZXRfbGVuZ3RoID0gaW5wdXQuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIC8vIFRoZSBwYWNrZXQgaGFzIGEgdHdvLW9jdGV0IGxlbmd0aC4gVGhlIGhlYWRlciBpcyAzIG9jdGV0c1xuICAgICAgICAgIC8vIGxvbmcuXG4gICAgICAgICAgcGFja2V0X2xlbmd0aCA9IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspIDw8IDgpIHwgaW5wdXQuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIC8vIFRoZSBwYWNrZXQgaGFzIGEgZm91ci1vY3RldCBsZW5ndGguIFRoZSBoZWFkZXIgaXMgNVxuICAgICAgICAgIC8vIG9jdGV0cyBsb25nLlxuICAgICAgICAgIHBhY2tldF9sZW5ndGggPSAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSA8PCAyNCkgfCAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSA8PCAxNikgfCAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSA8PFxuICAgICAgICAgICAgOCkgfCBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8vIDMgLSBUaGUgcGFja2V0IGlzIG9mIGluZGV0ZXJtaW5hdGUgbGVuZ3RoLiBUaGUgaGVhZGVyIGlzIDFcbiAgICAgICAgICAvLyBvY3RldCBsb25nLCBhbmQgdGhlIGltcGxlbWVudGF0aW9uIG11c3QgZGV0ZXJtaW5lIGhvdyBsb25nXG4gICAgICAgICAgLy8gdGhlIHBhY2tldCBpcy4gSWYgdGhlIHBhY2tldCBpcyBpbiBhIGZpbGUsIHRoaXMgbWVhbnMgdGhhdFxuICAgICAgICAgIC8vIHRoZSBwYWNrZXQgZXh0ZW5kcyB1bnRpbCB0aGUgZW5kIG9mIHRoZSBmaWxlLiBJbiBnZW5lcmFsLCBcbiAgICAgICAgICAvLyBhbiBpbXBsZW1lbnRhdGlvbiBTSE9VTEQgTk9UIHVzZSBpbmRldGVybWluYXRlLWxlbmd0aCBcbiAgICAgICAgICAvLyBwYWNrZXRzIGV4Y2VwdCB3aGVyZSB0aGUgZW5kIG9mIHRoZSBkYXRhIHdpbGwgYmUgY2xlYXIgXG4gICAgICAgICAgLy8gZnJvbSB0aGUgY29udGV4dCwgYW5kIGV2ZW4gdGhlbiBpdCBpcyBiZXR0ZXIgdG8gdXNlIGEgXG4gICAgICAgICAgLy8gZGVmaW5pdGUgbGVuZ3RoLCBvciBhIG5ldyBmb3JtYXQgaGVhZGVyLiBUaGUgbmV3IGZvcm1hdCBcbiAgICAgICAgICAvLyBoZWFkZXJzIGRlc2NyaWJlZCBiZWxvdyBoYXZlIGEgbWVjaGFuaXNtIGZvciBwcmVjaXNlbHlcbiAgICAgICAgICAvLyBlbmNvZGluZyBkYXRhIG9mIGluZGV0ZXJtaW5hdGUgbGVuZ3RoLlxuICAgICAgICAgIHBhY2tldF9sZW5ndGggPSBsZW47XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgLy8gNC4yLjIuIE5ldyBGb3JtYXQgUGFja2V0IExlbmd0aHNcbiAgICB7XG5cbiAgICAgIC8vIDQuMi4yLjEuIE9uZS1PY3RldCBMZW5ndGhzXG4gICAgICBpZiAoaW5wdXQuY2hhckNvZGVBdChteXBvcykgPCAxOTIpIHtcbiAgICAgICAgcGFja2V0X2xlbmd0aCA9IGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCIxIGJ5dGUgbGVuZ3RoOlwiICsgcGFja2V0X2xlbmd0aCk7XG4gICAgICAgIC8vIDQuMi4yLjIuIFR3by1PY3RldCBMZW5ndGhzXG4gICAgICB9IGVsc2UgaWYgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MpID49IDE5MiAmJiBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSA8IDIyNCkge1xuICAgICAgICBwYWNrZXRfbGVuZ3RoID0gKChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspIC0gMTkyKSA8PCA4KSArIChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspKSArIDE5MjtcbiAgICAgICAgdXRpbC5wcmludF9kZWJ1ZyhcIjIgYnl0ZSBsZW5ndGg6XCIgKyBwYWNrZXRfbGVuZ3RoKTtcbiAgICAgICAgLy8gNC4yLjIuNC4gUGFydGlhbCBCb2R5IExlbmd0aHNcbiAgICAgIH0gZWxzZSBpZiAoaW5wdXQuY2hhckNvZGVBdChteXBvcykgPiAyMjMgJiYgaW5wdXQuY2hhckNvZGVBdChteXBvcykgPCAyNTUpIHtcbiAgICAgICAgcGFja2V0X2xlbmd0aCA9IDEgPDwgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgJiAweDFGKTtcbiAgICAgICAgdXRpbC5wcmludF9kZWJ1ZyhcIjQgYnl0ZSBsZW5ndGg6XCIgKyBwYWNrZXRfbGVuZ3RoKTtcbiAgICAgICAgLy8gRUVFSywgd2UncmUgcmVhZGluZyB0aGUgZnVsbCBkYXRhIGhlcmUuLi5cbiAgICAgICAgdmFyIG15cG9zMiA9IG15cG9zICsgcGFja2V0X2xlbmd0aDtcbiAgICAgICAgYm9keWRhdGEgPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MsIG15cG9zICsgcGFja2V0X2xlbmd0aCk7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgaWYgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKSA8IDE5Mikge1xuICAgICAgICAgICAgdmFyIHRtcGxlbiA9IGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKyspO1xuICAgICAgICAgICAgcGFja2V0X2xlbmd0aCArPSB0bXBsZW47XG4gICAgICAgICAgICBib2R5ZGF0YSArPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MyLCBteXBvczIgKyB0bXBsZW4pO1xuICAgICAgICAgICAgbXlwb3MyICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaW5wdXQuY2hhckNvZGVBdChteXBvczIpID49IDE5MiAmJiBpbnB1dC5jaGFyQ29kZUF0KG15cG9zMikgPCAyMjQpIHtcbiAgICAgICAgICAgIHZhciB0bXBsZW4gPSAoKGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKyspIC0gMTkyKSA8PCA4KSArIChpbnB1dC5jaGFyQ29kZUF0KG15cG9zMisrKSkgKyAxOTI7XG4gICAgICAgICAgICBwYWNrZXRfbGVuZ3RoICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJvZHlkYXRhICs9IGlucHV0LnN1YnN0cmluZyhteXBvczIsIG15cG9zMiArIHRtcGxlbik7XG4gICAgICAgICAgICBteXBvczIgKz0gdG1wbGVuO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfSBlbHNlIGlmIChpbnB1dC5jaGFyQ29kZUF0KG15cG9zMikgPiAyMjMgJiYgaW5wdXQuY2hhckNvZGVBdChteXBvczIpIDwgMjU1KSB7XG4gICAgICAgICAgICB2YXIgdG1wbGVuID0gMSA8PCAoaW5wdXQuY2hhckNvZGVBdChteXBvczIrKykgJiAweDFGKTtcbiAgICAgICAgICAgIHBhY2tldF9sZW5ndGggKz0gdG1wbGVuO1xuICAgICAgICAgICAgYm9keWRhdGEgKz0gaW5wdXQuc3Vic3RyaW5nKG15cG9zMiwgbXlwb3MyICsgdG1wbGVuKTtcbiAgICAgICAgICAgIG15cG9zMiArPSB0bXBsZW47XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG15cG9zMisrO1xuICAgICAgICAgICAgdmFyIHRtcGxlbiA9IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zMisrKSA8PCAyNCkgfCAoaW5wdXQuY2hhckNvZGVBdChteXBvczIrKykgPDwgMTYpIHwgKGlucHV0W215cG9zMisrXVxuICAgICAgICAgICAgICAuY2hhckNvZGVBdCgpIDw8IDgpIHwgaW5wdXQuY2hhckNvZGVBdChteXBvczIrKyk7XG4gICAgICAgICAgICBib2R5ZGF0YSArPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MyLCBteXBvczIgKyB0bXBsZW4pO1xuICAgICAgICAgICAgcGFja2V0X2xlbmd0aCArPSB0bXBsZW47XG4gICAgICAgICAgICBteXBvczIgKz0gdG1wbGVuO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJlYWxfcGFja2V0X2xlbmd0aCA9IG15cG9zMjtcbiAgICAgICAgLy8gNC4yLjIuMy4gRml2ZS1PY3RldCBMZW5ndGhzXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBteXBvcysrO1xuICAgICAgICBwYWNrZXRfbGVuZ3RoID0gKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgPDwgMjQpIHwgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgPDwgMTYpIHwgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgPDxcbiAgICAgICAgICA4KSB8IGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gaWYgdGhlcmUgd2FzJ250IGEgcGFydGlhbCBib2R5IGxlbmd0aDogdXNlIHRoZSBzcGVjaWZpZWRcbiAgICAvLyBwYWNrZXRfbGVuZ3RoXG4gICAgaWYgKHJlYWxfcGFja2V0X2xlbmd0aCA9PSAtMSkge1xuICAgICAgcmVhbF9wYWNrZXRfbGVuZ3RoID0gcGFja2V0X2xlbmd0aDtcbiAgICB9XG5cbiAgICBpZiAoYm9keWRhdGEgPT0gbnVsbCkge1xuICAgICAgYm9keWRhdGEgPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MsIG15cG9zICsgcmVhbF9wYWNrZXRfbGVuZ3RoKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdGFnOiB0YWcsXG4gICAgICBwYWNrZXQ6IGJvZHlkYXRhLFxuICAgICAgb2Zmc2V0OiBteXBvcyArIHJlYWxfcGFja2V0X2xlbmd0aFxuICAgIH07XG4gIH1cbn1cbiIsInZhciBwYWNrZXRQYXJzZXIgPSByZXF1aXJlKCcuL3BhY2tldC5qcycpLFxuICBwYWNrZXRzID0gcmVxdWlyZSgnLi9hbGxfcGFja2V0cy5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIGxpc3Qgb2Ygb3BlbnBncCBwYWNrZXRzLlxuICogVGFrZSBjYXJlIHdoZW4gaXRlcmF0aW5nIG92ZXIgaXQgLSB0aGUgcGFja2V0cyB0aGVtc2VsdmVzXG4gKiBhcmUgc3RvcmVkIGFzIG51bWVyaWNhbCBpbmRpY2VzLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldGxpc3QoKSB7XG4gIC8qKiBUaGUgbnVtYmVyIG9mIHBhY2tldHMgY29udGFpbmVkIHdpdGhpbiB0aGUgbGlzdC5cbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtJbnRlZ2VyfSAqL1xuICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgLyoqXG4gICAqIFJlYWRzIGEgc3RyZWFtIG9mIGJpbmFyeSBkYXRhIGFuZCBpbnRlcnByZW50cyBpdCBhcyBhIGxpc3Qgb2YgcGFja2V0cy5cbiAgICogQHBhcmFtIHtvcGVucGdwX2J5dGVhcnJheX0gQW4gYXJyYXkgb2YgYnl0ZXMuXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBpID0gMDtcblxuICAgIHdoaWxlIChpIDwgYnl0ZXMubGVuZ3RoKSB7XG4gICAgICB2YXIgcGFyc2VkID0gcGFja2V0UGFyc2VyLnJlYWQoYnl0ZXMsIGksIGJ5dGVzLmxlbmd0aCAtIGkpO1xuICAgICAgaSA9IHBhcnNlZC5vZmZzZXQ7XG5cbiAgICAgIHZhciB0YWcgPSBlbnVtcy5yZWFkKGVudW1zLnBhY2tldCwgcGFyc2VkLnRhZyk7XG4gICAgICB2YXIgcGFja2V0ID0gbmV3IHBhY2tldHNbdGFnXSgpO1xuXG4gICAgICB0aGlzLnB1c2gocGFja2V0KTtcblxuICAgICAgcGFja2V0LnJlYWQocGFyc2VkLnBhY2tldCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBiaW5hcnkgcmVwcmVzZW50YXRpb24gb2Ygb3BlbnBncCBvYmplY3RzIGNvbnRhaW5lZCB3aXRoaW4gdGhlXG4gICAqIGNsYXNzIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7b3BlbnBncF9ieXRlYXJyYXl9IEFuIGFycmF5IG9mIGJ5dGVzIGNvbnRhaW5pbmcgdmFsaWQgb3BlbnBncCBwYWNrZXRzLlxuICAgKi9cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBieXRlcyA9ICcnO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcGFja2V0Ynl0ZXMgPSB0aGlzW2ldLndyaXRlKCk7XG4gICAgICBieXRlcyArPSBwYWNrZXRQYXJzZXIud3JpdGVIZWFkZXIodGhpc1tpXS50YWcsIHBhY2tldGJ5dGVzLmxlbmd0aCk7XG4gICAgICBieXRlcyArPSBwYWNrZXRieXRlcztcbiAgICB9XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHBhY2tldCB0byB0aGUgbGlzdC4gVGhpcyBpcyB0aGUgb25seSBzdXBwb3J0ZWQgbWV0aG9kIG9mIGRvaW5nIHNvO1xuICAgKiB3cml0aW5nIHRvIHBhY2tldGxpc3RbaV0gZGlyZWN0bHkgd2lsbCByZXN1bHQgaW4gYW4gZXJyb3IuXG4gICAqL1xuICB0aGlzLnB1c2ggPSBmdW5jdGlvbihwYWNrZXQpIHtcbiAgICBwYWNrZXQucGFja2V0cyA9IHBhY2tldC5wYWNrZXRzIHx8IG5ldyBwYWNrZXRsaXN0KCk7XG5cbiAgICB0aGlzW3RoaXMubGVuZ3RoXSA9IHBhY2tldDtcbiAgICB0aGlzLmxlbmd0aCsrO1xuICB9XG5cbiAgLyoqXG4gICogQ3JlYXRlcyBhIG5ldyBwYWNrZXRMaXN0IHdpdGggYWxsIHBhY2tldHMgdGhhdCBwYXNzIHRoZSB0ZXN0IGltcGxlbWVudGVkIGJ5IHRoZSBwcm92aWRlZCBmdW5jdGlvbi5cbiAgKi9cbiAgdGhpcy5maWx0ZXIgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuXG4gICAgdmFyIGZpbHRlcmVkID0gbmV3IHBhY2tldGxpc3QoKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGNhbGxiYWNrKHRoaXNbaV0sIGksIHRoaXMpKSB7XG4gICAgICAgIGZpbHRlcmVkLnB1c2godGhpc1tpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbHRlcmVkO1xuICB9XG5cbiAgLyoqXG4gICogQ3JlYXRlcyBhIG5ldyBwYWNrZXRMaXN0IHdpdGggYWxsIHBhY2tldHMgZnJvbSB0aGUgZ2l2ZW4gdHlwZXNcbiAgKi9cbiAgdGhpcy5maWx0ZXJCeVRhZyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICB2YXIgZmlsdGVyZWQgPSBuZXcgcGFja2V0bGlzdCgpO1xuICAgIHZhciB0aGF0ID0gdGhpcztcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFyZ3Muc29tZShmdW5jdGlvbihwYWNrZXRUeXBlKSB7cmV0dXJuIHRoYXRbaV0udGFnID09IHBhY2tldFR5cGV9KSkge1xuICAgICAgICBmaWx0ZXJlZC5wdXNoKHRoaXNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXJlZDtcbiAgfSBcblxuICAvKipcbiAgKiBFeGVjdXRlcyB0aGUgcHJvdmlkZWQgY2FsbGJhY2sgb25jZSBmb3IgZWFjaCBlbGVtZW50XG4gICovXG4gIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjYWxsYmFjayh0aGlzW2ldKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVHJhdmVyc2VzIHBhY2tldCB0cmVlIGFuZCByZXR1cm5zIGZpcnN0IG1hdGNoaW5nIHBhY2tldFxuICAgKiBAcGFyYW0gIHtlbnVtcy5wYWNrZXR9IHR5cGUgVGhlIHBhY2tldCB0eXBlXG4gICAqIEByZXR1cm4ge3BhY2tldHxudWxsfSAgICAgIFxuICAgKi9cbiAgdGhpcy5maW5kUGFja2V0ID0gZnVuY3Rpb24odHlwZSkge1xuICAgIHZhciBwYWNrZXRsaXN0ID0gdGhpcy5maWx0ZXJCeVRhZyh0eXBlKTtcbiAgICBpZiAocGFja2V0bGlzdC5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBwYWNrZXRsaXN0WzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZm91bmQgPSBudWxsO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzW2ldLnBhY2tldHMubGVuZ3RoKSB7XG4gICAgICAgICAgZm91bmQgPSB0aGlzW2ldLnBhY2tldHMuZmluZFBhY2tldCh0eXBlKTtcbiAgICAgICAgICBpZiAoZm91bmQpIHJldHVybiBmb3VuZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpLFxuICB0eXBlX2tleWlkID0gcmVxdWlyZSgnLi4vdHlwZS9rZXlpZC5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgS2V5IE1hdGVyaWFsIFBhY2tldCAoVGFnIDUsNiw3LDE0KVxuICogICBcbiAqIFJGQzQ0ODAgNS41OlxuICogQSBrZXkgbWF0ZXJpYWwgcGFja2V0IGNvbnRhaW5zIGFsbCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgYSBwdWJsaWMgb3JcbiAqIHByaXZhdGUga2V5LiAgVGhlcmUgYXJlIGZvdXIgdmFyaWFudHMgb2YgdGhpcyBwYWNrZXQgdHlwZSwgYW5kIHR3b1xuICogbWFqb3IgdmVyc2lvbnMuICBDb25zZXF1ZW50bHksIHRoaXMgc2VjdGlvbiBpcyBjb21wbGV4LlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9wdWJsaWNfa2V5KCkge1xuICAvKiogS2V5IGNyZWF0aW9uIGRhdGUuXG4gICAqIEB0eXBlIHtEYXRlfSAqL1xuICB0aGlzLmNyZWF0ZWQgPSBuZXcgRGF0ZSgpO1xuICAvKiogQSBsaXN0IG9mIG11bHRpcHJlY2lzaW9uIGludGVnZXJzXG4gICAqIEB0eXBlIHtvcGVucGdwX3R5cGVfbXBpfSAqL1xuICB0aGlzLm1waSA9IFtdO1xuICAvKiogUHVibGljIGtleSBhbGdvcml0aG1cbiAgICogQHR5cGUge29wZW5wZ3AucHVibGlja2V5fSAqL1xuICB0aGlzLmFsZ29yaXRobSA9ICdyc2Ffc2lnbic7XG5cblxuICAvKipcbiAgICogSW50ZXJuYWwgUGFyc2VyIGZvciBwdWJsaWMga2V5cyBhcyBzcGVjaWZpZWQgaW4gUkZDIDQ4ODAgc2VjdGlvbiBcbiAgICogNS41LjIgUHVibGljLUtleSBQYWNrZXQgRm9ybWF0c1xuICAgKiBjYWxsZWQgYnkgcmVhZF90YWcmbHQ7bnVtJmd0O1xuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgSW5wdXQgc3RyaW5nIHRvIHJlYWQgdGhlIHBhY2tldCBmcm9tXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gU3RhcnQgcG9zaXRpb24gZm9yIHRoZSBwYXJzZXJcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoaXMgb2JqZWN0IHdpdGggYXR0cmlidXRlcyBzZXQgYnkgdGhlIHBhcnNlclxuICAgKi9cbiAgdGhpcy5yZWFkUHVibGljS2V5ID0gdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlciAoMyBvciA0KS5cbiAgICB2YXIgdmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQoMCk7XG5cbiAgICBpZiAodmVyc2lvbiA9PSA0KSB7XG4gICAgICAvLyAtIEEgZm91ci1vY3RldCBudW1iZXIgZGVub3RpbmcgdGhlIHRpbWUgdGhhdCB0aGUga2V5IHdhcyBjcmVhdGVkLlxuICAgICAgdGhpcy5jcmVhdGVkID0gdXRpbC5yZWFkRGF0ZShieXRlcy5zdWJzdHIoMSwgNCkpO1xuXG4gICAgICAvLyAtIEEgb25lLW9jdGV0IG51bWJlciBkZW5vdGluZyB0aGUgcHVibGljLWtleSBhbGdvcml0aG0gb2YgdGhpcyBrZXkuXG4gICAgICB0aGlzLmFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBieXRlcy5jaGFyQ29kZUF0KDUpKTtcblxuICAgICAgdmFyIG1waWNvdW50ID0gY3J5cHRvLmdldFB1YmxpY01waUNvdW50KHRoaXMuYWxnb3JpdGhtKTtcbiAgICAgIHRoaXMubXBpID0gW107XG5cbiAgICAgIHZhciBibXBpID0gYnl0ZXMuc3Vic3RyKDYpO1xuICAgICAgdmFyIHAgPSAwO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1waWNvdW50ICYmIHAgPCBibXBpLmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgdGhpcy5tcGlbaV0gPSBuZXcgdHlwZV9tcGkoKTtcblxuICAgICAgICBwICs9IHRoaXMubXBpW2ldLnJlYWQoYm1waS5zdWJzdHIocCkpXG5cbiAgICAgICAgaWYgKHAgPiBibXBpLmxlbmd0aClcbiAgICAgICAgICB1dGlsLnByaW50X2Vycm9yKFwib3BlbnBncC5wYWNrZXQua2V5bWF0ZXJpYWwuanNcXG5cIiArICdlcnJvciByZWFkaW5nIE1QSSBAOicgKyBwKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHAgKyA2O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZlcnNpb24gJyArIHZlcnNpb24gKyAnIG9mIHRoZSBrZXkgcGFja2V0IGlzIHVuc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICAqIFNhbWUgYXMgd3JpdGVfcHJpdmF0ZV9rZXksIGJ1dCBoYXMgbGVzcyBpbmZvcm1hdGlvbiBiZWNhdXNlIG9mIFxuICAgKiBwdWJsaWMga2V5LlxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGtleVR5cGUgRm9sbG93cyB0aGUgT3BlblBHUCBhbGdvcml0aG0gc3RhbmRhcmQsIFxuICAgKiBJRSAxIGNvcnJlc3BvbmRzIHRvIFJTQS5cbiAgICogQHBhcmFtIHtSU0Eua2V5T2JqZWN0fSBrZXlcbiAgICogQHBhcmFtIHRpbWVQYWNrZXRcbiAgICogQHJldHVybiB7T2JqZWN0fSB7Ym9keTogW3N0cmluZ11PcGVuUEdQIHBhY2tldCBib2R5IGNvbnRlbnRzLCBcbiAgICogaGVhZGVyOiBbc3RyaW5nXSBPcGVuUEdQIHBhY2tldCBoZWFkZXIsIHN0cmluZzogW3N0cmluZ10gaGVhZGVyK2JvZHl9XG4gICAqL1xuICB0aGlzLndyaXRlUHVibGljS2V5ID0gdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIC8vIFZlcnNpb25cbiAgICB2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSg0KTtcbiAgICByZXN1bHQgKz0gdXRpbC53cml0ZURhdGUodGhpcy5jcmVhdGVkKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMuYWxnb3JpdGhtKSk7XG5cbiAgICB2YXIgbXBpY291bnQgPSBjcnlwdG8uZ2V0UHVibGljTXBpQ291bnQodGhpcy5hbGdvcml0aG0pO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtcGljb3VudDsgaSsrKSB7XG4gICAgICByZXN1bHQgKz0gdGhpcy5tcGlbaV0ud3JpdGUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gV3JpdGUgYW4gb2xkIHZlcnNpb24gcGFja2V0IC0gaXQncyB1c2VkIGJ5IHNvbWUgb2YgdGhlIGludGVybmFsIHJvdXRpbmVzLlxuICB0aGlzLndyaXRlT2xkID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy53cml0ZVB1YmxpY0tleSgpO1xuXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoMHg5OSkgK1xuICAgICAgdXRpbC53cml0ZU51bWJlcihieXRlcy5sZW5ndGgsIDIpICtcbiAgICAgIGJ5dGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIGtleSBpZCBvZiB0aGUga2V5IFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEEgOCBieXRlIGtleSBpZFxuICAgKi9cbiAgdGhpcy5nZXRLZXlJZCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBrZXlpZCA9IG5ldyB0eXBlX2tleWlkKCk7XG4gICAga2V5aWQucmVhZCh0aGlzLmdldEZpbmdlcnByaW50KCkuc3Vic3RyKDEyLCA4KSk7XG4gICAgcmV0dXJuIGtleWlkO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIGZpbmdlcnByaW50IG9mIHRoZSBrZXlcbiAgICogQHJldHVybiB7U3RyaW5nfSBBIHN0cmluZyBjb250YWluaW5nIHRoZSBmaW5nZXJwcmludFxuICAgKi9cbiAgdGhpcy5nZXRGaW5nZXJwcmludCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0b0hhc2ggPSB0aGlzLndyaXRlT2xkKCk7XG4gICAgcmV0dXJuIGNyeXB0by5oYXNoLnNoYTEodG9IYXNoLCB0b0hhc2gubGVuZ3RoKTtcbiAgfVxuXG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdHlwZV9rZXlpZCA9IHJlcXVpcmUoJy4uL3R5cGUva2V5aWQuanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IFBhY2tldHMgKFRhZyAxKVxuICogXG4gKiBSRkM0ODgwIDUuMTogQSBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXQgaG9sZHMgdGhlIHNlc3Npb24ga2V5XG4gKiB1c2VkIHRvIGVuY3J5cHQgYSBtZXNzYWdlLiBaZXJvIG9yIG1vcmUgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXlcbiAqIHBhY2tldHMgYW5kL29yIFN5bW1ldHJpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldHMgbWF5IHByZWNlZGUgYVxuICogU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQsIHdoaWNoIGhvbGRzIGFuIGVuY3J5cHRlZCBtZXNzYWdlLiBUaGVcbiAqIG1lc3NhZ2UgaXMgZW5jcnlwdGVkIHdpdGggdGhlIHNlc3Npb24ga2V5LCBhbmQgdGhlIHNlc3Npb24ga2V5IGlzIGl0c2VsZlxuICogZW5jcnlwdGVkIGFuZCBzdG9yZWQgaW4gdGhlIEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXQocykuIFRoZVxuICogU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQgaXMgcHJlY2VkZWQgYnkgb25lIFB1YmxpYy1LZXkgRW5jcnlwdGVkXG4gKiBTZXNzaW9uIEtleSBwYWNrZXQgZm9yIGVhY2ggT3BlblBHUCBrZXkgdG8gd2hpY2ggdGhlIG1lc3NhZ2UgaXMgZW5jcnlwdGVkLlxuICogVGhlIHJlY2lwaWVudCBvZiB0aGUgbWVzc2FnZSBmaW5kcyBhIHNlc3Npb24ga2V5IHRoYXQgaXMgZW5jcnlwdGVkIHRvIHRoZWlyXG4gKiBwdWJsaWMga2V5LCBkZWNyeXB0cyB0aGUgc2Vzc2lvbiBrZXksIGFuZCB0aGVuIHVzZXMgdGhlIHNlc3Npb24ga2V5IHRvXG4gKiBkZWNyeXB0IHRoZSBtZXNzYWdlLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9wdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleSgpIHtcbiAgdGhpcy52ZXJzaW9uID0gMztcblxuICB0aGlzLnB1YmxpY0tleUlkID0gbmV3IHR5cGVfa2V5aWQoKTtcbiAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSAncnNhX2VuY3J5cHQnO1xuXG4gIHRoaXMuc2Vzc2lvbktleSA9IG51bGw7XG4gIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9ICdhZXMyNTYnO1xuXG4gIC8qKiBAdHlwZSB7b3BlbnBncF90eXBlX21waVtdfSAqL1xuICB0aGlzLmVuY3J5cHRlZCA9IFtdO1xuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHB1YmxpY2tleSBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXkgcGFja2V0ICh0YWcgMSkuXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxIHBhY2tldFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mXG4gICAqICAgICAgICAgICAgaW5wdXQgYXQgcG9zaXRpb25cbiAgICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YX0gT2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuXG4gICAgdGhpcy52ZXJzaW9uID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcbiAgICB0aGlzLnB1YmxpY0tleUlkLnJlYWQoYnl0ZXMuc3Vic3RyKDEpKTtcbiAgICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBieXRlcy5jaGFyQ29kZUF0KDkpKTtcblxuICAgIHZhciBpID0gMTA7XG5cbiAgICB2YXIgaW50ZWdlckNvdW50ID0gKGZ1bmN0aW9uKGFsZ28pIHtcbiAgICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgICBjYXNlICdyc2FfZW5jcnlwdCc6XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0X3NpZ24nOlxuICAgICAgICAgIHJldHVybiAxO1xuXG4gICAgICAgIGNhc2UgJ2VsZ2FtYWwnOlxuICAgICAgICAgIHJldHVybiAyO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBhbGdvcml0aG0uXCIpO1xuICAgICAgfVxuICAgIH0pKHRoaXMucHVibGljS2V5QWxnb3JpdGhtKTtcblxuICAgIHRoaXMuZW5jcnlwdGVkID0gW107XG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGludGVnZXJDb3VudDsgaisrKSB7XG4gICAgICB2YXIgbXBpID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgICBpICs9IG1waS5yZWFkKGJ5dGVzLnN1YnN0cihpKSk7XG4gICAgICB0aGlzLmVuY3J5cHRlZC5wdXNoKG1waSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHRhZyAxIHBhY2tldFxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IHB1YmxpY0tleUlkXG4gICAqICAgICAgICAgICAgIFRoZSBwdWJsaWMga2V5IGlkIGNvcnJlc3BvbmRpbmcgdG8gcHVibGljTVBJcyBrZXkgYXMgc3RyaW5nXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBwdWJsaWNNUElzXG4gICAqICAgICAgICAgICAgTXVsdGlwcmVjaXNpb24gaW50ZWdlciBvYmplY3RzIGRlc2NyaWJpbmcgdGhlIHB1YmxpYyBrZXlcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwdWJhbGdvXG4gICAqICAgICAgICAgICAgVGhlIGNvcnJlc3BvbmRpbmcgcHVibGljIGtleSBhbGdvcml0aG0gLy8gU2VlIFJGQzQ4ODAgOS4xXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gc3ltbWFsZ29cbiAgICogICAgICAgICAgICBUaGUgc3ltbWV0cmljIGNpcGhlciBhbGdvcml0aG0gdXNlZCB0byBlbmNyeXB0IHRoZSBkYXRhIFxuICAgKiAgICAgICAgICAgIHdpdGhpbiBhbiBlbmNyeXB0ZWRkYXRhcGFja2V0IG9yIGVuY3J5cHRlZGludGVncml0eS1cbiAgICogICAgICAgICAgICBwcm90ZWN0ZWRkYXRhcGFja2V0IFxuICAgKiAgICAgICAgICAgIGZvbGxvd2luZyB0aGlzIHBhY2tldCAvL1NlZSBSRkM0ODgwIDkuMlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc2Vzc2lvbmtleVxuICAgKiAgICAgICAgICAgIEEgc3RyaW5nIG9mIHJhbmRvbWJ5dGVzIHJlcHJlc2VudGluZyB0aGUgc2Vzc2lvbiBrZXlcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG5cbiAgICB2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnZlcnNpb24pO1xuICAgIHJlc3VsdCArPSB0aGlzLnB1YmxpY0tleUlkLndyaXRlKCk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICBlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMucHVibGljS2V5QWxnb3JpdGhtKSk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZW5jcnlwdGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHQgKz0gdGhpcy5lbmNyeXB0ZWRbaV0ud3JpdGUoKVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihrZXkpIHtcbiAgICB2YXIgZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICBlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSkpO1xuXG4gICAgZGF0YSArPSB0aGlzLnNlc3Npb25LZXk7XG4gICAgdmFyIGNoZWNrc3VtID0gdXRpbC5jYWxjX2NoZWNrc3VtKHRoaXMuc2Vzc2lvbktleSk7XG4gICAgZGF0YSArPSB1dGlsLndyaXRlTnVtYmVyKGNoZWNrc3VtLCAyKTtcblxuICAgIHZhciBtcGkgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICBtcGkuZnJvbUJ5dGVzKGNyeXB0by5wa2NzMS5lbWUuZW5jb2RlKFxuICAgICAgZGF0YSxcbiAgICAgIGtleS5tcGlbMF0uYnl0ZUxlbmd0aCgpKSk7XG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5wdWJsaWNLZXlFbmNyeXB0KFxuICAgICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0sXG4gICAgICBrZXkubXBpLFxuICAgICAgbXBpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNyeXB0cyB0aGUgc2Vzc2lvbiBrZXkgKG9ubHkgZm9yIHB1YmxpYyBrZXkgZW5jcnlwdGVkIHNlc3Npb24ga2V5XG4gICAqIHBhY2tldHMgKHRhZyAxKVxuICAgKiBcbiAgICogQHBhcmFtIHtvcGVucGdwX21zZ19tZXNzYWdlfSBtc2dcbiAgICogICAgICAgICAgICBUaGUgbWVzc2FnZSBvYmplY3QgKHdpdGggbWVtYmVyIGVuY3J5cHRlZERhdGFcbiAgICogQHBhcmFtIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBrZXlcbiAgICogICAgICAgICAgICBQcml2YXRlIGtleSB3aXRoIHNlY01QSXMgdW5sb2NrZWRcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgdW5lbmNyeXB0ZWQgc2Vzc2lvbiBrZXlcbiAgICovXG4gIHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciByZXN1bHQgPSBjcnlwdG8ucHVibGljS2V5RGVjcnlwdChcbiAgICAgIHRoaXMucHVibGljS2V5QWxnb3JpdGhtLFxuICAgICAga2V5Lm1waSxcbiAgICAgIHRoaXMuZW5jcnlwdGVkKS50b0J5dGVzKCk7XG5cbiAgICB2YXIgY2hlY2tzdW0gPSB1dGlsLnJlYWROdW1iZXIocmVzdWx0LnN1YnN0cihyZXN1bHQubGVuZ3RoIC0gMikpO1xuXG4gICAgdmFyIGRlY29kZWQgPSBjcnlwdG8ucGtjczEuZW1lLmRlY29kZShcbiAgICAgIHJlc3VsdCxcbiAgICAgIGtleS5tcGlbMF0uYnl0ZUxlbmd0aCgpKTtcblxuICAgIHZhciBrZXkgPSBkZWNvZGVkLnN1YnN0cmluZygxLCBkZWNvZGVkLmxlbmd0aCAtIDIpO1xuXG4gICAgaWYgKGNoZWNrc3VtICE9IHV0aWwuY2FsY19jaGVja3N1bShrZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NoZWNrc3VtIG1pc21hdGNoJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2Vzc2lvbktleSA9IGtleTtcbiAgICAgIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9XG4gICAgICAgIGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBkZWNvZGVkLmNoYXJDb2RlQXQoMCkpO1xuICAgIH1cbiAgfVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBwdWJsaWNfa2V5ID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5LmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcHVibGljX3N1YmtleSgpIHtcbiAgcHVibGljX2tleS5jYWxsKHRoaXMpO1xufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHB1YmxpY0tleSA9IHJlcXVpcmUoJy4vcHVibGljX2tleS5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpLFxuICB0eXBlX21waSA9IHJlcXVpcmUoJy4uL3R5cGUvbXBpLmpzJyksXG4gIHR5cGVfczJrID0gcmVxdWlyZSgnLi4vdHlwZS9zMmsuanMnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIEtleSBNYXRlcmlhbCBQYWNrZXQgKFRhZyA1LDYsNywxNClcbiAqICAgXG4gKiBSRkM0NDgwIDUuNTpcbiAqIEEga2V5IG1hdGVyaWFsIHBhY2tldCBjb250YWlucyBhbGwgdGhlIGluZm9ybWF0aW9uIGFib3V0IGEgcHVibGljIG9yXG4gKiBwcml2YXRlIGtleS4gIFRoZXJlIGFyZSBmb3VyIHZhcmlhbnRzIG9mIHRoaXMgcGFja2V0IHR5cGUsIGFuZCB0d29cbiAqIG1ham9yIHZlcnNpb25zLiAgQ29uc2VxdWVudGx5LCB0aGlzIHNlY3Rpb24gaXMgY29tcGxleC5cbiAqL1xuZnVuY3Rpb24gcGFja2V0X3NlY3JldF9rZXkoKSB7XG4gIHB1YmxpY0tleS5jYWxsKHRoaXMpO1xuICAvLyBlbmNyeXB0ZWQgc2VjcmV0LWtleSBkYXRhXG4gIHRoaXMuZW5jcnlwdGVkID0gbnVsbDtcbiAgLy8gaW5kaWNhdG9yIGlmIHNlY3JldC1rZXkgZGF0YSBpcyBhdmFpbGFibGUgaW4gZGVjcnlwdGVkIGZvcm1cbiAgdGhpcy5pc0RlY3J5cHRlZCA9IGZhbHNlO1xuXG5cbiAgZnVuY3Rpb24gZ2V0X2hhc2hfbGVuKGhhc2gpIHtcbiAgICBpZiAoaGFzaCA9PSAnc2hhMScpXG4gICAgICByZXR1cm4gMjA7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIDI7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRfaGFzaF9mbihoYXNoKSB7XG4gICAgaWYgKGhhc2ggPT0gJ3NoYTEnKVxuICAgICAgcmV0dXJuIGNyeXB0by5oYXNoLnNoYTE7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGMpIHtcbiAgICAgICAgcmV0dXJuIHV0aWwud3JpdGVOdW1iZXIodXRpbC5jYWxjX2NoZWNrc3VtKGMpLCAyKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gSGVscGVyIGZ1bmN0aW9uXG5cbiAgZnVuY3Rpb24gcGFyc2VfY2xlYXJ0ZXh0X21waShoYXNoX2FsZ29yaXRobSwgY2xlYXJ0ZXh0LCBhbGdvcml0aG0pIHtcbiAgICB2YXIgaGFzaGxlbiA9IGdldF9oYXNoX2xlbihoYXNoX2FsZ29yaXRobSksXG4gICAgICBoYXNoZm4gPSBnZXRfaGFzaF9mbihoYXNoX2FsZ29yaXRobSk7XG5cbiAgICB2YXIgaGFzaHRleHQgPSBjbGVhcnRleHQuc3Vic3RyKGNsZWFydGV4dC5sZW5ndGggLSBoYXNobGVuKTtcbiAgICBjbGVhcnRleHQgPSBjbGVhcnRleHQuc3Vic3RyKDAsIGNsZWFydGV4dC5sZW5ndGggLSBoYXNobGVuKTtcblxuICAgIHZhciBoYXNoID0gaGFzaGZuKGNsZWFydGV4dCk7XG5cbiAgICBpZiAoaGFzaCAhPSBoYXNodGV4dClcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoXCJIYXNoIG1pc21hdGNoLlwiKTtcblxuICAgIHZhciBtcGlzID0gY3J5cHRvLmdldFByaXZhdGVNcGlDb3VudChhbGdvcml0aG0pO1xuXG4gICAgdmFyIGogPSAwO1xuICAgIHZhciBtcGkgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXBpcyAmJiBqIDwgY2xlYXJ0ZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBtcGlbaV0gPSBuZXcgdHlwZV9tcGkoKTtcbiAgICAgIGogKz0gbXBpW2ldLnJlYWQoY2xlYXJ0ZXh0LnN1YnN0cihqKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1waTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdyaXRlX2NsZWFydGV4dF9tcGkoaGFzaF9hbGdvcml0aG0sIGFsZ29yaXRobSwgbXBpKSB7XG4gICAgdmFyIGJ5dGVzID0gJyc7XG4gICAgdmFyIGRpc2NhcmQgPSBjcnlwdG8uZ2V0UHVibGljTXBpQ291bnQoYWxnb3JpdGhtKTtcblxuICAgIGZvciAodmFyIGkgPSBkaXNjYXJkOyBpIDwgbXBpLmxlbmd0aDsgaSsrKSB7XG4gICAgICBieXRlcyArPSBtcGlbaV0ud3JpdGUoKTtcbiAgICB9XG5cblxuICAgIGJ5dGVzICs9IGdldF9oYXNoX2ZuKGhhc2hfYWxnb3JpdGhtKShieXRlcyk7XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuXG4gIC8vIDUuNS4zLiAgU2VjcmV0LUtleSBQYWNrZXQgRm9ybWF0c1xuXG4gIC8qKlxuICAgKiBJbnRlcm5hbCBwYXJzZXIgZm9yIHByaXZhdGUga2V5cyBhcyBzcGVjaWZpZWQgaW4gUkZDIDQ4ODAgc2VjdGlvbiA1LjUuM1xuICAgKiBAcGFyYW0ge1N0cmluZ30gYnl0ZXMgSW5wdXQgc3RyaW5nIHRvIHJlYWQgdGhlIHBhY2tldCBmcm9tXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIC8vIC0gQSBQdWJsaWMtS2V5IG9yIFB1YmxpYy1TdWJrZXkgcGFja2V0LCBhcyBkZXNjcmliZWQgYWJvdmUuXG4gICAgdmFyIGxlbiA9IHRoaXMucmVhZFB1YmxpY0tleShieXRlcyk7XG5cbiAgICBieXRlcyA9IGJ5dGVzLnN1YnN0cihsZW4pO1xuXG5cbiAgICAvLyAtIE9uZSBvY3RldCBpbmRpY2F0aW5nIHN0cmluZy10by1rZXkgdXNhZ2UgY29udmVudGlvbnMuICBaZXJvXG4gICAgLy8gICBpbmRpY2F0ZXMgdGhhdCB0aGUgc2VjcmV0LWtleSBkYXRhIGlzIG5vdCBlbmNyeXB0ZWQuICAyNTUgb3IgMjU0XG4gICAgLy8gICBpbmRpY2F0ZXMgdGhhdCBhIHN0cmluZy10by1rZXkgc3BlY2lmaWVyIGlzIGJlaW5nIGdpdmVuLiAgQW55XG4gICAgLy8gICBvdGhlciB2YWx1ZSBpcyBhIHN5bW1ldHJpYy1rZXkgZW5jcnlwdGlvbiBhbGdvcml0aG0gaWRlbnRpZmllci5cbiAgICB2YXIgaXNFbmNyeXB0ZWQgPSBieXRlcy5jaGFyQ29kZUF0KDApO1xuXG4gICAgaWYgKGlzRW5jcnlwdGVkKSB7XG4gICAgICB0aGlzLmVuY3J5cHRlZCA9IGJ5dGVzO1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIC8vIC0gUGxhaW4gb3IgZW5jcnlwdGVkIG11bHRpcHJlY2lzaW9uIGludGVnZXJzIGNvbXByaXNpbmcgdGhlIHNlY3JldFxuICAgICAgLy8gICBrZXkgZGF0YS4gIFRoZXNlIGFsZ29yaXRobS1zcGVjaWZpYyBmaWVsZHMgYXJlIGFzIGRlc2NyaWJlZFxuICAgICAgLy8gICBiZWxvdy5cbiAgICAgIHZhciBwYXJzZWRNUEkgPSBwYXJzZV9jbGVhcnRleHRfbXBpKCdtb2QnLCBieXRlcy5zdWJzdHIoMSksIHRoaXMuYWxnb3JpdGhtKTtcbiAgICAgIGlmIChwYXJzZWRNUEkgaW5zdGFuY2VvZiBFcnJvcilcbiAgICAgICAgdGhyb3cgcGFyc2VkTVBJO1xuICAgICAgdGhpcy5tcGkgPSB0aGlzLm1waS5jb25jYXQocGFyc2VkTVBJKTtcbiAgICAgIHRoaXMuaXNEZWNyeXB0ZWQgPSB0cnVlO1xuICAgIH1cblxuICB9O1xuXG4gIC8qKiBDcmVhdGVzIGFuIE9wZW5QR1Aga2V5IHBhY2tldCBmb3IgdGhlIGdpdmVuIGtleS5cbiAgICAqIEByZXR1cm4ge1N0cmluZ30gQSBzdHJpbmcgb2YgYnl0ZXMgY29udGFpbmluZyB0aGUgc2VjcmV0IGtleSBPcGVuUEdQIHBhY2tldFxuICAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYnl0ZXMgPSB0aGlzLndyaXRlUHVibGljS2V5KCk7XG5cbiAgICBpZiAoIXRoaXMuZW5jcnlwdGVkKSB7XG4gICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuXG4gICAgICBieXRlcyArPSB3cml0ZV9jbGVhcnRleHRfbXBpKCdtb2QnLCB0aGlzLmFsZ29yaXRobSwgdGhpcy5tcGkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBieXRlcyArPSB0aGlzLmVuY3J5cHRlZDtcbiAgICB9XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH07XG5cblxuXG5cbiAgLyoqIEVuY3J5cHQgdGhlIHBheWxvYWQuIEJ5IGRlZmF1bHQsIHdlIHVzZSBhZXMyNTYgYW5kIGl0ZXJhdGVkLCBzYWx0ZWQgc3RyaW5nXG4gICAqIHRvIGtleSBzcGVjaWZpZXJcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhc3NwaHJhc2VcbiAgICovXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UpIHtcblxuICAgIHZhciBzMmsgPSBuZXcgdHlwZV9zMmsoKSxcbiAgICAgIHN5bW1ldHJpYyA9ICdhZXMyNTYnLFxuICAgICAgY2xlYXJ0ZXh0ID0gd3JpdGVfY2xlYXJ0ZXh0X21waSgnc2hhMScsIHRoaXMuYWxnb3JpdGhtLCB0aGlzLm1waSksXG4gICAgICBrZXkgPSBwcm9kdWNlRW5jcnlwdGlvbktleShzMmssIHBhc3NwaHJhc2UsIHN5bW1ldHJpYyksXG4gICAgICBibG9ja0xlbiA9IGNyeXB0by5jaXBoZXJbc3ltbWV0cmljXS5ibG9ja1NpemUsXG4gICAgICBpdiA9IGNyeXB0by5yYW5kb20uZ2V0UmFuZG9tQnl0ZXMoYmxvY2tMZW4pO1xuXG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9ICcnO1xuICAgIHRoaXMuZW5jcnlwdGVkICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMjU0KTtcbiAgICB0aGlzLmVuY3J5cHRlZCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnN5bW1ldHJpYywgc3ltbWV0cmljKSk7XG4gICAgdGhpcy5lbmNyeXB0ZWQgKz0gczJrLndyaXRlKCk7XG4gICAgdGhpcy5lbmNyeXB0ZWQgKz0gaXY7XG5cbiAgICB0aGlzLmVuY3J5cHRlZCArPSBjcnlwdG8uY2ZiLm5vcm1hbEVuY3J5cHQoc3ltbWV0cmljLCBrZXksIGNsZWFydGV4dCwgaXYpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHByb2R1Y2VFbmNyeXB0aW9uS2V5KHMyaywgcGFzc3BocmFzZSwgYWxnb3JpdGhtKSB7XG4gICAgcmV0dXJuIHMyay5wcm9kdWNlX2tleShwYXNzcGhyYXNlLFxuICAgICAgY3J5cHRvLmNpcGhlclthbGdvcml0aG1dLmtleVNpemUpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBwcml2YXRlIGtleSBNUElzIHdoaWNoIGFyZSBuZWVkZWQgdG8gdXNlIHRoZSBrZXkuXG4gICAqIG9wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsLmhhc1VuZW5jcnlwdGVkU2VjcmV0S2V5RGF0YSBzaG91bGQgYmUgXG4gICAqIGZhbHNlIG90aGVyd2lzZVxuICAgKiBhIGNhbGwgdG8gdGhpcyBmdW5jdGlvbiBpcyBub3QgbmVlZGVkXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyX3Bhc3NwaHJhc2UgVGhlIHBhc3NwaHJhc2UgZm9yIHRoaXMgcHJpdmF0ZSBrZXkgXG4gICAqIGFzIHN0cmluZ1xuICAgKiBAcmV0dXJuIHtCb29sZWFufSBUcnVlIGlmIHRoZSBwYXNzcGhyYXNlIHdhcyBjb3JyZWN0IG9yIE1QSSBhbHJlYWR5XG4gICAqICAgICAgICAgICAgICAgICAgIGRlY3J5cHRlZDsgZmFsc2UgaWYgbm90XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihwYXNzcGhyYXNlKSB7XG4gICAgaWYgKHRoaXMuaXNEZWNyeXB0ZWQpXG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIHZhciBpID0gMCxcbiAgICAgIHN5bW1ldHJpYyxcbiAgICAgIGtleTtcblxuICAgIHZhciBzMmtfdXNhZ2UgPSB0aGlzLmVuY3J5cHRlZC5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAvLyAtIFtPcHRpb25hbF0gSWYgc3RyaW5nLXRvLWtleSB1c2FnZSBvY3RldCB3YXMgMjU1IG9yIDI1NCwgYSBvbmUtXG4gICAgLy8gICBvY3RldCBzeW1tZXRyaWMgZW5jcnlwdGlvbiBhbGdvcml0aG0uXG4gICAgaWYgKHMya191c2FnZSA9PSAyNTUgfHwgczJrX3VzYWdlID09IDI1NCkge1xuICAgICAgc3ltbWV0cmljID0gdGhpcy5lbmNyeXB0ZWQuY2hhckNvZGVBdChpKyspO1xuICAgICAgc3ltbWV0cmljID0gZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIHN5bW1ldHJpYyk7XG5cbiAgICAgIC8vIC0gW09wdGlvbmFsXSBJZiBzdHJpbmctdG8ta2V5IHVzYWdlIG9jdGV0IHdhcyAyNTUgb3IgMjU0LCBhXG4gICAgICAvLyAgIHN0cmluZy10by1rZXkgc3BlY2lmaWVyLiAgVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nLXRvLWtleVxuICAgICAgLy8gICBzcGVjaWZpZXIgaXMgaW1wbGllZCBieSBpdHMgdHlwZSwgYXMgZGVzY3JpYmVkIGFib3ZlLlxuICAgICAgdmFyIHMyayA9IG5ldyB0eXBlX3MyaygpO1xuICAgICAgaSArPSBzMmsucmVhZCh0aGlzLmVuY3J5cHRlZC5zdWJzdHIoaSkpO1xuXG4gICAgICBrZXkgPSBwcm9kdWNlRW5jcnlwdGlvbktleShzMmssIHBhc3NwaHJhc2UsIHN5bW1ldHJpYyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN5bW1ldHJpYyA9IHMya191c2FnZTtcbiAgICAgIHN5bW1ldHJpYyA9IGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBzeW1tZXRyaWMpO1xuICAgICAga2V5ID0gY3J5cHRvLmhhc2gubWQ1KHBhc3NwaHJhc2UpO1xuICAgIH1cblxuXG4gICAgLy8gLSBbT3B0aW9uYWxdIElmIHNlY3JldCBkYXRhIGlzIGVuY3J5cHRlZCAoc3RyaW5nLXRvLWtleSB1c2FnZSBvY3RldFxuICAgIC8vICAgbm90IHplcm8pLCBhbiBJbml0aWFsIFZlY3RvciAoSVYpIG9mIHRoZSBzYW1lIGxlbmd0aCBhcyB0aGVcbiAgICAvLyAgIGNpcGhlcidzIGJsb2NrIHNpemUuXG4gICAgdmFyIGl2ID0gdGhpcy5lbmNyeXB0ZWQuc3Vic3RyKGksXG4gICAgICBjcnlwdG8uY2lwaGVyW3N5bW1ldHJpY10uYmxvY2tTaXplKTtcblxuICAgIGkgKz0gaXYubGVuZ3RoO1xuXG4gICAgdmFyIGNsZWFydGV4dCxcbiAgICAgIGNpcGhlcnRleHQgPSB0aGlzLmVuY3J5cHRlZC5zdWJzdHIoaSk7XG5cbiAgICBjbGVhcnRleHQgPSBjcnlwdG8uY2ZiLm5vcm1hbERlY3J5cHQoc3ltbWV0cmljLCBrZXksIGNpcGhlcnRleHQsIGl2KTtcblxuICAgIHZhciBoYXNoID0gczJrX3VzYWdlID09IDI1NCA/XG4gICAgICAnc2hhMScgOlxuICAgICAgJ21vZCc7XG5cbiAgICB2YXIgcGFyc2VkTVBJID0gcGFyc2VfY2xlYXJ0ZXh0X21waShoYXNoLCBjbGVhcnRleHQsIHRoaXMuYWxnb3JpdGhtKTtcbiAgICBpZiAocGFyc2VkTVBJIGluc3RhbmNlb2YgRXJyb3IpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgdGhpcy5tcGkgPSB0aGlzLm1waS5jb25jYXQocGFyc2VkTVBJKTtcbiAgICB0aGlzLmlzRGVjcnlwdGVkID0gdHJ1ZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICB0aGlzLmdlbmVyYXRlID0gZnVuY3Rpb24oYml0cykge1xuICAgIHRoaXMubXBpID0gY3J5cHRvLmdlbmVyYXRlTXBpKHRoaXMuYWxnb3JpdGhtLCBiaXRzKTtcbiAgICB0aGlzLmlzRGVjcnlwdGVkID0gdHJ1ZTtcbiAgfTtcblxufVxuXG5wYWNrZXRfc2VjcmV0X2tleS5wcm90b3R5cGUgPSBuZXcgcHVibGljS2V5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHBhY2tldF9zZWNyZXRfa2V5O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHNlY3JldF9rZXkgPSByZXF1aXJlKCcuL3NlY3JldF9rZXkuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzZWNyZXRfc3Via2V5KCkge1xuICBzZWNyZXRfa2V5LmNhbGwodGhpcyk7XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgcGFja2V0ID0gcmVxdWlyZSgnLi9wYWNrZXQuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKSxcbiAgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpLFxuICB0eXBlX2tleWlkID0gcmVxdWlyZSgnLi4vdHlwZS9rZXlpZC5qcycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2lnbmF0dXJlIFBhY2tldCAoVGFnIDIpXG4gKiBcbiAqIFJGQzQ0ODAgNS4yOlxuICogQSBTaWduYXR1cmUgcGFja2V0IGRlc2NyaWJlcyBhIGJpbmRpbmcgYmV0d2VlbiBzb21lIHB1YmxpYyBrZXkgYW5kXG4gKiBzb21lIGRhdGEuICBUaGUgbW9zdCBjb21tb24gc2lnbmF0dXJlcyBhcmUgYSBzaWduYXR1cmUgb2YgYSBmaWxlIG9yIGFcbiAqIGJsb2NrIG9mIHRleHQsIGFuZCBhIHNpZ25hdHVyZSB0aGF0IGlzIGEgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3NpZ25hdHVyZSgpIHtcblxuICB0aGlzLnZlcnNpb24gPSBudWxsO1xuICB0aGlzLnNpZ25hdHVyZVR5cGUgPSBudWxsO1xuICB0aGlzLmhhc2hBbGdvcml0aG0gPSBudWxsO1xuICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IG51bGw7XG5cbiAgdGhpcy5zaWduYXR1cmVEYXRhID0gbnVsbDtcbiAgdGhpcy5zaWduZWRIYXNoVmFsdWUgPSBudWxsO1xuICB0aGlzLm1waSA9IG51bGw7XG5cbiAgdGhpcy5jcmVhdGVkID0gbmV3IERhdGUoKTtcbiAgdGhpcy5zaWduYXR1cmVFeHBpcmF0aW9uVGltZSA9IG51bGw7XG4gIHRoaXMuc2lnbmF0dXJlTmV2ZXJFeHBpcmVzID0gbnVsbDtcbiAgdGhpcy5leHBvcnRhYmxlID0gbnVsbDtcbiAgdGhpcy50cnVzdExldmVsID0gbnVsbDtcbiAgdGhpcy50cnVzdEFtb3VudCA9IG51bGw7XG4gIHRoaXMucmVndWxhckV4cHJlc3Npb24gPSBudWxsO1xuICB0aGlzLnJldm9jYWJsZSA9IG51bGw7XG4gIHRoaXMua2V5RXhwaXJhdGlvblRpbWUgPSBudWxsO1xuICB0aGlzLmtleU5ldmVyRXhwaXJlcyA9IG51bGw7XG4gIHRoaXMucHJlZmVycmVkU3ltbWV0cmljQWxnb3JpdGhtcyA9IG51bGw7XG4gIHRoaXMucmV2b2NhdGlvbktleUNsYXNzID0gbnVsbDtcbiAgdGhpcy5yZXZvY2F0aW9uS2V5QWxnb3JpdGhtID0gbnVsbDtcbiAgdGhpcy5yZXZvY2F0aW9uS2V5RmluZ2VycHJpbnQgPSBudWxsO1xuICB0aGlzLmlzc3VlcktleUlkID0gbmV3IHR5cGVfa2V5aWQoKTtcbiAgdGhpcy5ub3RhdGlvbiA9IG51bGw7XG4gIHRoaXMucHJlZmVycmVkSGFzaEFsZ29yaXRobXMgPSBudWxsO1xuICB0aGlzLnByZWZlcnJlZENvbXByZXNzaW9uQWxnb3JpdGhtcyA9IG51bGw7XG4gIHRoaXMua2V5U2VydmVyUHJlZmVyZW5jZXMgPSBudWxsO1xuICB0aGlzLnByZWZlcnJlZEtleVNlcnZlciA9IG51bGw7XG4gIHRoaXMuaXNQcmltYXJ5VXNlcklEID0gbnVsbDtcbiAgdGhpcy5wb2xpY3lVUkkgPSBudWxsO1xuICB0aGlzLmtleUZsYWdzID0gbnVsbDtcbiAgdGhpcy5zaWduZXJzVXNlcklkID0gbnVsbDtcbiAgdGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uRmxhZyA9IG51bGw7XG4gIHRoaXMucmVhc29uRm9yUmV2b2NhdGlvblN0cmluZyA9IG51bGw7XG4gIHRoaXMuZmVhdHVyZXMgPSBudWxsO1xuICB0aGlzLnNpZ25hdHVyZVRhcmdldFB1YmxpY0tleUFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaCA9IG51bGw7XG4gIHRoaXMuZW1iZWRkZWRTaWduYXR1cmUgPSBudWxsO1xuXG4gIHRoaXMudmVyaWZpZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogcGFyc2luZyBmdW5jdGlvbiBmb3IgYSBzaWduYXR1cmUgcGFja2V0ICh0YWcgMikuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBwYXlsb2FkIG9mIGEgdGFnIDIgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gcG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBieXRlcyBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gbGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2YgYnl0ZXMgYXQgcG9zaXRpb25cbiAgICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YX0gb2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBpID0gMDtcblxuICAgIHRoaXMudmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAvLyBzd2l0Y2ggb24gdmVyc2lvbiAoMyBhbmQgNClcbiAgICBzd2l0Y2ggKHRoaXMudmVyc2lvbikge1xuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyBPbmUtb2N0ZXQgbGVuZ3RoIG9mIGZvbGxvd2luZyBoYXNoZWQgbWF0ZXJpYWwuIE1VU1QgYmUgNS5cbiAgICAgICAgaWYgKGJ5dGVzLmNoYXJDb2RlQXQoaSsrKSAhPSA1KVxuICAgICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCJvcGVucGdwLnBhY2tldC5zaWduYXR1cmUuanNcXG5cIiArXG4gICAgICAgICAgICAnaW52YWxpZCBPbmUtb2N0ZXQgbGVuZ3RoIG9mIGZvbGxvd2luZyBoYXNoZWQgbWF0ZXJpYWwuJyArXG4gICAgICAgICAgICAnTVVTVCBiZSA1LiBAOicgKyAoaSAtIDEpKTtcblxuICAgICAgICB2YXIgc2lncG9zID0gaTtcbiAgICAgICAgLy8gT25lLW9jdGV0IHNpZ25hdHVyZSB0eXBlLlxuICAgICAgICB0aGlzLnNpZ25hdHVyZVR5cGUgPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgICAgLy8gRm91ci1vY3RldCBjcmVhdGlvbiB0aW1lLlxuICAgICAgICB0aGlzLmNyZWF0ZWQgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihpLCA0KSk7XG4gICAgICAgIGkgKz0gNDtcblxuICAgICAgICAvLyBzdG9yaW5nIGRhdGEgYXBwZW5kZWQgdG8gZGF0YSB3aGljaCBnZXRzIHZlcmlmaWVkXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlRGF0YSA9IGJ5dGVzLnN1YnN0cmluZyhzaWdwb3MsIGkpO1xuXG4gICAgICAgIC8vIEVpZ2h0LW9jdGV0IEtleSBJRCBvZiBzaWduZXIuXG4gICAgICAgIHRoaXMuaXNzdWVyS2V5SWQucmVhZChieXRlcy5zdWJzdHJpbmcoaSwgaSArIDgpKTtcbiAgICAgICAgaSArPSA4O1xuXG4gICAgICAgIC8vIE9uZS1vY3RldCBwdWJsaWMta2V5IGFsZ29yaXRobS5cbiAgICAgICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgICAgLy8gT25lLW9jdGV0IGhhc2ggYWxnb3JpdGhtLlxuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA0OlxuICAgICAgICB0aGlzLnNpZ25hdHVyZVR5cGUgPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICAgIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gYnl0ZXMuY2hhckNvZGVBdChpKyspO1xuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgICAgZnVuY3Rpb24gc3VicGFja2V0cyhieXRlcykge1xuICAgICAgICAgIC8vIFR3by1vY3RldCBzY2FsYXIgb2N0ZXQgY291bnQgZm9yIGZvbGxvd2luZyBzdWJwYWNrZXQgZGF0YS5cbiAgICAgICAgICB2YXIgc3VicGFja2V0X2xlbmd0aCA9IHV0aWwucmVhZE51bWJlcihcbiAgICAgICAgICAgIGJ5dGVzLnN1YnN0cigwLCAyKSk7XG5cbiAgICAgICAgICB2YXIgaSA9IDI7XG5cbiAgICAgICAgICAvLyBzdWJwYWNrZXQgZGF0YSBzZXQgKHplcm8gb3IgbW9yZSBzdWJwYWNrZXRzKVxuICAgICAgICAgIHZhciBzdWJwYWNrZWRfcmVhZCA9IDA7XG4gICAgICAgICAgd2hpbGUgKGkgPCAyICsgc3VicGFja2V0X2xlbmd0aCkge1xuXG4gICAgICAgICAgICB2YXIgbGVuID0gcGFja2V0LnJlYWRTaW1wbGVMZW5ndGgoYnl0ZXMuc3Vic3RyKGkpKTtcbiAgICAgICAgICAgIGkgKz0gbGVuLm9mZnNldDtcblxuICAgICAgICAgICAgdGhpcy5yZWFkX3N1Yl9wYWNrZXQoYnl0ZXMuc3Vic3RyKGksIGxlbi5sZW4pKTtcblxuICAgICAgICAgICAgaSArPSBsZW4ubGVuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaGFzaGVkIHN1YnBhY2tldHNcbiAgICAgICAgaSArPSBzdWJwYWNrZXRzLmNhbGwodGhpcywgYnl0ZXMuc3Vic3RyKGkpLCB0cnVlKTtcblxuICAgICAgICAvLyBBIFY0IHNpZ25hdHVyZSBoYXNoZXMgdGhlIHBhY2tldCBib2R5XG4gICAgICAgIC8vIHN0YXJ0aW5nIGZyb20gaXRzIGZpcnN0IGZpZWxkLCB0aGUgdmVyc2lvbiBudW1iZXIsIHRocm91Z2ggdGhlIGVuZFxuICAgICAgICAvLyBvZiB0aGUgaGFzaGVkIHN1YnBhY2tldCBkYXRhLiAgVGh1cywgdGhlIGZpZWxkcyBoYXNoZWQgYXJlIHRoZVxuICAgICAgICAvLyBzaWduYXR1cmUgdmVyc2lvbiwgdGhlIHNpZ25hdHVyZSB0eXBlLCB0aGUgcHVibGljLWtleSBhbGdvcml0aG0sIHRoZVxuICAgICAgICAvLyBoYXNoIGFsZ29yaXRobSwgdGhlIGhhc2hlZCBzdWJwYWNrZXQgbGVuZ3RoLCBhbmQgdGhlIGhhc2hlZFxuICAgICAgICAvLyBzdWJwYWNrZXQgYm9keS5cbiAgICAgICAgdGhpcy5zaWduYXR1cmVEYXRhID0gYnl0ZXMuc3Vic3RyKDAsIGkpO1xuXG4gICAgICAgIC8vIHVuaGFzaGVkIHN1YnBhY2tldHNcbiAgICAgICAgaSArPSBzdWJwYWNrZXRzLmNhbGwodGhpcywgYnl0ZXMuc3Vic3RyKGkpLCBmYWxzZSk7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZlcnNpb24gJyArIHZlcnNpb24gKyAnIG9mIHRoZSBzaWduYXR1cmUgaXMgdW5zdXBwb3J0ZWQuJyk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIFR3by1vY3RldCBmaWVsZCBob2xkaW5nIGxlZnQgMTYgYml0cyBvZiBzaWduZWQgaGFzaCB2YWx1ZS5cbiAgICB0aGlzLnNpZ25lZEhhc2hWYWx1ZSA9IGJ5dGVzLnN1YnN0cihpLCAyKTtcbiAgICBpICs9IDI7XG5cbiAgICB0aGlzLnNpZ25hdHVyZSA9IGJ5dGVzLnN1YnN0cihpKTtcbiAgfTtcblxuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuc2lnbmF0dXJlRGF0YSArXG4gICAgICB1dGlsLndyaXRlTnVtYmVyKDAsIDIpICsgLy8gTnVtYmVyIG9mIHVuc2lnbmVkIHN1YnBhY2tldHMuXG4gICAgdGhpcy5zaWduZWRIYXNoVmFsdWUgK1xuICAgICAgdGhpcy5zaWduYXR1cmU7XG4gIH07XG5cbiAgLyoqXG4gICAqIFNpZ25zIHByb3ZpZGVkIGRhdGEuIFRoaXMgbmVlZHMgdG8gYmUgZG9uZSBwcmlvciB0byBzZXJpYWxpemF0aW9uLlxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YSBDb250YWlucyBwYWNrZXRzIHRvIGJlIHNpZ25lZC5cbiAgICogQHBhcmFtIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBwcml2YXRla2V5IHByaXZhdGUga2V5IHVzZWQgdG8gc2lnbiB0aGUgbWVzc2FnZS4gXG4gICAqL1xuICB0aGlzLnNpZ24gPSBmdW5jdGlvbihrZXksIGRhdGEpIHtcbiAgICB2YXIgc2lnbmF0dXJlVHlwZSA9IGVudW1zLndyaXRlKGVudW1zLnNpZ25hdHVyZSwgdGhpcy5zaWduYXR1cmVUeXBlKSxcbiAgICAgIHB1YmxpY0tleUFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLnB1YmxpY0tleSwgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0pLFxuICAgICAgaGFzaEFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLmhhc2gsIHRoaXMuaGFzaEFsZ29yaXRobSk7XG5cbiAgICB2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSg0KTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShzaWduYXR1cmVUeXBlKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwdWJsaWNLZXlBbGdvcml0aG0pO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGhhc2hBbGdvcml0aG0pO1xuXG4gICAgdGhpcy5pc3N1ZXJLZXlJZCA9IGtleS5nZXRLZXlJZCgpO1xuXG4gICAgLy8gQWRkIGhhc2hlZCBzdWJwYWNrZXRzXG4gICAgcmVzdWx0ICs9IHRoaXMud3JpdGVfYWxsX3N1Yl9wYWNrZXRzKCk7XG5cbiAgICB0aGlzLnNpZ25hdHVyZURhdGEgPSByZXN1bHQ7XG5cbiAgICB2YXIgdHJhaWxlciA9IHRoaXMuY2FsY3VsYXRlVHJhaWxlcigpO1xuXG4gICAgdmFyIHRvSGFzaCA9IHRoaXMudG9TaWduKHNpZ25hdHVyZVR5cGUsIGRhdGEpICtcbiAgICAgIHRoaXMuc2lnbmF0dXJlRGF0YSArIHRyYWlsZXI7XG5cbiAgICB2YXIgaGFzaCA9IGNyeXB0by5oYXNoLmRpZ2VzdChoYXNoQWxnb3JpdGhtLCB0b0hhc2gpO1xuXG4gICAgdGhpcy5zaWduZWRIYXNoVmFsdWUgPSBoYXNoLnN1YnN0cigwLCAyKTtcblxuICAgIHRoaXMuc2lnbmF0dXJlID0gY3J5cHRvLnNpZ25hdHVyZS5zaWduKGhhc2hBbGdvcml0aG0sXG4gICAgICBwdWJsaWNLZXlBbGdvcml0aG0sIGtleS5tcGksIHRvSGFzaCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgc3RyaW5nIG9mIGJ5dGVzIHdpdGggYWxsIHN1YnBhY2tldCBkYXRhXG4gICAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmctcmVwcmVzZW50YXRpb24gb2YgYSBhbGwgc3VicGFja2V0IGRhdGFcbiAgICovXG4gIHRoaXMud3JpdGVfYWxsX3N1Yl9wYWNrZXRzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHN1YiA9IGVudW1zLnNpZ25hdHVyZVN1YnBhY2tldDtcbiAgICB2YXIgcmVzdWx0ID0gJyc7XG4gICAgdmFyIGJ5dGVzID0gJyc7XG4gICAgaWYgKHRoaXMuY3JlYXRlZCAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnNpZ25hdHVyZV9jcmVhdGlvbl90aW1lLCB1dGlsLndyaXRlRGF0ZSh0aGlzLmNyZWF0ZWQpKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2lnbmF0dXJlRXhwaXJhdGlvblRpbWUgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5zaWduYXR1cmVfZXhwaXJhdGlvbl90aW1lLCB1dGlsLndyaXRlRGF0ZSh0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmV4cG9ydGFibGUgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5leHBvcnRhYmxlX2NlcnRpZmljYXRpb24sIFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5leHBvcnRhYmxlID8gMSA6IDApKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudHJ1c3RMZXZlbCAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMudHJ1c3RMZXZlbCkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMudHJ1c3RBbW91bnQpO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnRydXN0X3NpZ25hdHVyZSwgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZWd1bGFyRXhwcmVzc2lvbiAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnJlZ3VsYXJfZXhwcmVzc2lvbiwgdGhpcy5yZWd1bGFyRXhwcmVzc2lvbik7XG4gICAgfVxuICAgIGlmICh0aGlzLnJldm9jYWJsZSAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnJldm9jYWJsZSwgU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnJldm9jYWJsZSA/IDEgOiAwKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmtleUV4cGlyYXRpb25UaW1lICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIua2V5X2V4cGlyYXRpb25fdGltZSwgdXRpbC53cml0ZURhdGUodGhpcy5rZXlFeHBpcmF0aW9uVGltZSkpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wcmVmZXJyZWRTeW1tZXRyaWNBbGdvcml0aG1zICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IHV0aWwuYmluMnN0cih0aGlzLnByZWZlcnJlZFN5bW1ldHJpY0FsZ29yaXRobXMpO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnByZWZlcnJlZF9zeW1tZXRyaWNfYWxnb3JpdGhtcywgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZXZvY2F0aW9uS2V5Q2xhc3MgIT09IG51bGwpIHtcbiAgICAgIGJ5dGVzID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnJldm9jYXRpb25LZXlDbGFzcyk7XG4gICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMucmV2b2NhdGlvbktleUFsZ29yaXRobSk7XG4gICAgICBieXRlcyArPSB0aGlzLnJldm9jYXRpb25LZXlGaW5nZXJwcmludDtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5yZXZvY2F0aW9uX2tleSwgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuaXNzdWVyS2V5SWQuaXNOdWxsKCkpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5pc3N1ZXIsIHRoaXMuaXNzdWVyS2V5SWQud3JpdGUoKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLm5vdGF0aW9uICE9PSBudWxsKSB7XG4gICAgICBmb3IgKHZhciBuYW1lIGluIHRoaXMubm90YXRpb24pIHtcbiAgICAgICAgaWYgKHRoaXMubm90YXRpb24uaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLm5vdGF0aW9uW25hbWVdO1xuICAgICAgICAgIGJ5dGVzID0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDgwKTtcbiAgICAgICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuICAgICAgICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG4gICAgICAgICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICAgICAgICAvLyAyIG9jdGV0cyBvZiBuYW1lIGxlbmd0aFxuICAgICAgICAgIGJ5dGVzICs9IHV0aWwud3JpdGVOdW1iZXIobmFtZS5sZW5ndGgsIDIpO1xuICAgICAgICAgIC8vIDIgb2N0ZXRzIG9mIHZhbHVlIGxlbmd0aFxuICAgICAgICAgIGJ5dGVzICs9IHV0aWwud3JpdGVOdW1iZXIodmFsdWUubGVuZ3RoLCAyKTtcbiAgICAgICAgICBieXRlcyArPSBuYW1lICsgdmFsdWU7XG4gICAgICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLm5vdGF0aW9uX2RhdGEsIGJ5dGVzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gXG4gICAgaWYgKHRoaXMucHJlZmVycmVkSGFzaEFsZ29yaXRobXMgIT09IG51bGwpIHtcbiAgICAgIGJ5dGVzID0gdXRpbC5iaW4yc3RyKHRoaXMucHJlZmVycmVkSGFzaEFsZ29yaXRobXMpO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnByZWZlcnJlZF9oYXNoX2FsZ29yaXRobXMsIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucHJlZmVycmVkQ29tcHJlc3Npb25BbGdvcml0aG1zICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IHV0aWwuYmluMnN0cih0aGlzLnByZWZlcnJlZENvbXByZXNzaW9uQWxnb3JpdGhtcyk7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIucHJlZmVycmVkX2hhc2hfYWxnb3JpdGhtcywgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5rZXlTZXJ2ZXJQcmVmZXJlbmNlcyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSB1dGlsLmJpbjJzdHIodGhpcy5rZXlTZXJ2ZXJQcmVmZXJlbmNlcyk7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIua2V5X3NlcnZlcl9wcmVmZXJlbmNlcywgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wcmVmZXJyZWRLZXlTZXJ2ZXIgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5wcmVmZXJyZWRfa2V5X3NlcnZlciwgdGhpcy5wcmVmZXJyZWRLZXlTZXJ2ZXIpO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc1ByaW1hcnlVc2VySUQgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5wcmltYXJ5X3VzZXJfaWQsIFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5pc1ByaW1hcnlVc2VySUQgPyAxIDogMCkpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wb2xpY3lVUkkgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5wb2xpY3lfdXJpLCB0aGlzLnBvbGljeVVSSSk7IFxuICAgIH1cbiAgICBpZiAodGhpcy5rZXlGbGFncyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSB1dGlsLmJpbjJzdHIodGhpcy5rZXlGbGFncyk7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIua2V5X2ZsYWdzLCBieXRlcyk7XG4gICAgfVxuICAgIGlmICh0aGlzLnNpZ25lcnNVc2VySWQgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5zaWduZXJzX3VzZXJfaWQsIHRoaXMuc2lnbmVyc1VzZXJJZCk7IFxuICAgIH1cbiAgICBpZiAodGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uRmxhZyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMucmVhc29uRm9yUmV2b2NhdGlvbkZsYWcpO1xuICAgICAgYnl0ZXMgKz0gdGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uU3RyaW5nO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnJlYXNvbl9mb3JfcmV2b2NhdGlvbiwgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5mZWF0dXJlcyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSB1dGlsLmJpbjJzdHIodGhpcy5mZWF0dXJlcyk7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIuZmVhdHVyZXMsIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2lnbmF0dXJlVGFyZ2V0UHVibGljS2V5QWxnb3JpdGhtICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5zaWduYXR1cmVUYXJnZXRQdWJsaWNLZXlBbGdvcml0aG0pO1xuICAgICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnNpZ25hdHVyZVRhcmdldEhhc2hBbGdvcml0aG0pO1xuICAgICAgYnl0ZXMgKz0gdGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnNpZ25hdHVyZV90YXJnZXQsIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZW1iZWRkZWRTaWduYXR1cmUgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5lbWJlZGRlZF9zaWduYXR1cmUsIHRoaXMuZW1iZWRkZWRTaWduYXR1cmUud3JpdGUoKSk7XG4gICAgfVxuICAgIHJlc3VsdCA9IHV0aWwud3JpdGVOdW1iZXIocmVzdWx0Lmxlbmd0aCwgMikgKyByZXN1bHQ7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvKipcbiAgICogY3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHN1YiBzaWduYXR1cmUgcGFja2V0IChTZWUgUkZDIDQ4ODAgNS4yLjMuMSlcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSB0eXBlIHN1YnBhY2tldCBzaWduYXR1cmUgdHlwZS4gU2lnbmF0dXJlIHR5cGVzIGFzIGRlc2NyaWJlZCBcbiAgICogaW4gUkZDNDg4MCBTZWN0aW9uIDUuMi4zLjJcbiAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgZGF0YSB0byBiZSBpbmNsdWRlZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGEgc3RyaW5nLXJlcHJlc2VudGF0aW9uIG9mIGEgc3ViIHNpZ25hdHVyZSBwYWNrZXQgKFNlZSBSRkMgNDg4MCA1LjIuMy4xKVxuICAgKi9cbiAgZnVuY3Rpb24gd3JpdGVfc3ViX3BhY2tldCh0eXBlLCBkYXRhKSB7XG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgcmVzdWx0ICs9IHBhY2tldC53cml0ZVNpbXBsZUxlbmd0aChkYXRhLmxlbmd0aCArIDEpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHR5cGUpO1xuICAgIHJlc3VsdCArPSBkYXRhO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBWNCBzaWduYXR1cmUgc3ViIHBhY2tldHNcblxuICB0aGlzLnJlYWRfc3ViX3BhY2tldCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIG15cG9zID0gMDtcblxuICAgIGZ1bmN0aW9uIHJlYWRfYXJyYXkocHJvcCwgYnl0ZXMpIHtcbiAgICAgIHRoaXNbcHJvcF0gPSBbXTtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzW3Byb3BdLnB1c2goYnl0ZXMuY2hhckNvZGVBdChpKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVGhlIGxlZnR3b3N0IGJpdCBkZW5vdGVzIGEgXCJjcml0aWNhbFwiIHBhY2tldCwgYnV0IHdlIGlnbm9yZSBpdC5cbiAgICB2YXIgdHlwZSA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKykgJiAweDdGO1xuXG4gICAgLy8gc3VicGFja2V0IHR5cGVcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gU2lnbmF0dXJlIENyZWF0aW9uIFRpbWVcbiAgICAgICAgdGhpcy5jcmVhdGVkID0gdXRpbC5yZWFkRGF0ZShieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIC8vIFNpZ25hdHVyZSBFeHBpcmF0aW9uIFRpbWVcbiAgICAgICAgdmFyIHRpbWUgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlTmV2ZXJFeHBpcmVzID0gdGltZS5nZXRUaW1lKCkgPT0gMDtcbiAgICAgICAgdGhpcy5zaWduYXR1cmVFeHBpcmF0aW9uVGltZSA9IHRpbWU7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIC8vIEV4cG9ydGFibGUgQ2VydGlmaWNhdGlvblxuICAgICAgICB0aGlzLmV4cG9ydGFibGUgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspID09IDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA1OlxuICAgICAgICAvLyBUcnVzdCBTaWduYXR1cmVcbiAgICAgICAgdGhpcy50cnVzdExldmVsID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgdGhpcy50cnVzdEFtb3VudCA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA2OlxuICAgICAgICAvLyBSZWd1bGFyIEV4cHJlc3Npb25cbiAgICAgICAgdGhpcy5yZWd1bGFyRXhwcmVzc2lvbiA9IGJ5dGVzLnN1YnN0cihteXBvcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA3OlxuICAgICAgICAvLyBSZXZvY2FibGVcbiAgICAgICAgdGhpcy5yZXZvY2FibGUgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspID09IDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA5OlxuICAgICAgICAvLyBLZXkgRXhwaXJhdGlvbiBUaW1lXG4gICAgICAgIHZhciB0aW1lID0gdXRpbC5yZWFkRGF0ZShieXRlcy5zdWJzdHIobXlwb3MpKTtcblxuICAgICAgICB0aGlzLmtleUV4cGlyYXRpb25UaW1lID0gdGltZTtcbiAgICAgICAgdGhpcy5rZXlOZXZlckV4cGlyZXMgPSB0aW1lLmdldFRpbWUoKSA9PSAwO1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMTpcbiAgICAgICAgLy8gUHJlZmVycmVkIFN5bW1ldHJpYyBBbGdvcml0aG1zXG4gICAgICAgIHRoaXMucHJlZmVycmVkU3ltbWV0cmljQWxnb3JpdGhtcyA9IFtdO1xuXG4gICAgICAgIHdoaWxlIChteXBvcyAhPSBieXRlcy5sZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLnByZWZlcnJlZFN5bW1ldHJpY0FsZ29yaXRobXMucHVzaChieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMjpcbiAgICAgICAgLy8gUmV2b2NhdGlvbiBLZXlcbiAgICAgICAgLy8gKDEgb2N0ZXQgb2YgY2xhc3MsIDEgb2N0ZXQgb2YgcHVibGljLWtleSBhbGdvcml0aG0gSUQsIDIwXG4gICAgICAgIC8vIG9jdGV0cyBvZlxuICAgICAgICAvLyBmaW5nZXJwcmludClcbiAgICAgICAgdGhpcy5yZXZvY2F0aW9uS2V5Q2xhc3MgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICB0aGlzLnJldm9jYXRpb25LZXlBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICB0aGlzLnJldm9jYXRpb25LZXlGaW5nZXJwcmludCA9IGJ5dGVzLnN1YnN0cihteXBvcywgMjApO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAxNjpcbiAgICAgICAgLy8gSXNzdWVyXG4gICAgICAgIHRoaXMuaXNzdWVyS2V5SWQucmVhZChieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgMjA6XG4gICAgICAgIC8vIE5vdGF0aW9uIERhdGFcbiAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyBob3cgdG8gaGFuZGxlIGFueXRoaW5nIGJ1dCBhIHRleHQgZmxhZ2dlZCBkYXRhLlxuICAgICAgICBpZiAoYnl0ZXMuY2hhckNvZGVBdChteXBvcykgPT0gMHg4MCkge1xuXG4gICAgICAgICAgLy8gV2UgZXh0cmFjdCBrZXkvdmFsdWUgdHVwbGUgZnJvbSB0aGUgYnl0ZSBzdHJlYW0uXG4gICAgICAgICAgbXlwb3MgKz0gNDtcbiAgICAgICAgICB2YXIgbSA9IHV0aWwucmVhZE51bWJlcihieXRlcy5zdWJzdHIobXlwb3MsIDIpKTtcbiAgICAgICAgICBteXBvcyArPSAyXG4gICAgICAgICAgdmFyIG4gPSB1dGlsLnJlYWROdW1iZXIoYnl0ZXMuc3Vic3RyKG15cG9zLCAyKSk7XG4gICAgICAgICAgbXlwb3MgKz0gMlxuXG4gICAgICAgICAgdmFyIG5hbWUgPSBieXRlcy5zdWJzdHIobXlwb3MsIG0pLFxuICAgICAgICAgICAgdmFsdWUgPSBieXRlcy5zdWJzdHIobXlwb3MgKyBtLCBuKTtcblxuICAgICAgICAgIHRoaXMubm90YXRpb24gPSB0aGlzLm5vdGF0aW9uIHx8IHt9O1xuICAgICAgICAgIHRoaXMubm90YXRpb25bbmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgfSBlbHNlIHRocm93IG5ldyBFcnJvcihcIlVuc3VwcG9ydGVkIG5vdGF0aW9uIGZsYWcuXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjE6XG4gICAgICAgIC8vIFByZWZlcnJlZCBIYXNoIEFsZ29yaXRobXNcbiAgICAgICAgcmVhZF9hcnJheS5jYWxsKHRoaXMsICdwcmVmZXJyZWRIYXNoQWxnb3JpdGhtcycsIGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjI6XG4gICAgICAgIC8vIFByZWZlcnJlZCBDb21wcmVzc2lvbiBBbGdvcml0aG1zXG4gICAgICAgIHJlYWRfYXJyYXkuY2FsbCh0aGlzLCAncHJlZmVycmVkQ29tcHJlc3Npb25BbGdvcml0aG1zICcsIGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjM6XG4gICAgICAgIC8vIEtleSBTZXJ2ZXIgUHJlZmVyZW5jZXNcbiAgICAgICAgcmVhZF9hcnJheS5jYWxsKHRoaXMsICdrZXlTZXJ2ZXJQcmVmZXJlbmNlc3MnLCBieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI0OlxuICAgICAgICAvLyBQcmVmZXJyZWQgS2V5IFNlcnZlclxuICAgICAgICB0aGlzLnByZWZlcnJlZEtleVNlcnZlciA9IGJ5dGVzLnN1YnN0cihteXBvcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyNTpcbiAgICAgICAgLy8gUHJpbWFyeSBVc2VyIElEXG4gICAgICAgIHRoaXMuaXNQcmltYXJ5VXNlcklEID0gYnl0ZXNbbXlwb3MrK10gIT0gMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI2OlxuICAgICAgICAvLyBQb2xpY3kgVVJJXG4gICAgICAgIHRoaXMucG9saWN5VVJJID0gYnl0ZXMuc3Vic3RyKG15cG9zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI3OlxuICAgICAgICAvLyBLZXkgRmxhZ3NcbiAgICAgICAgcmVhZF9hcnJheS5jYWxsKHRoaXMsICdrZXlGbGFncycsIGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjg6XG4gICAgICAgIC8vIFNpZ25lcidzIFVzZXIgSURcbiAgICAgICAgdGhpcy5zaWduZXJzVXNlcklkICs9IGJ5dGVzLnN1YnN0cihteXBvcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOTpcbiAgICAgICAgLy8gUmVhc29uIGZvciBSZXZvY2F0aW9uXG4gICAgICAgIHRoaXMucmVhc29uRm9yUmV2b2NhdGlvbkZsYWcgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICB0aGlzLnJlYXNvbkZvclJldm9jYXRpb25TdHJpbmcgPSBieXRlcy5zdWJzdHIobXlwb3MpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzA6XG4gICAgICAgIC8vIEZlYXR1cmVzXG4gICAgICAgIHJlYWRfYXJyYXkuY2FsbCh0aGlzLCAnZmVhdHVyZXMnLCBieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDMxOlxuICAgICAgICAvLyBTaWduYXR1cmUgVGFyZ2V0XG4gICAgICAgIC8vICgxIG9jdGV0IHB1YmxpYy1rZXkgYWxnb3JpdGhtLCAxIG9jdGV0IGhhc2ggYWxnb3JpdGhtLCBOIG9jdGV0cyBoYXNoKVxuICAgICAgICB0aGlzLnNpZ25hdHVyZVRhcmdldFB1YmxpY0tleUFsZ29yaXRobSA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgIHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG5cbiAgICAgICAgdmFyIGxlbiA9IGNyeXB0by5nZXRIYXNoQnl0ZUxlbmd0aCh0aGlzLnNpZ25hdHVyZVRhcmdldEhhc2hBbGdvcml0aG0pO1xuXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaCA9IGJ5dGVzLnN1YnN0cihteXBvcywgbGVuKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDMyOlxuICAgICAgICAvLyBFbWJlZGRlZCBTaWduYXR1cmVcbiAgICAgICAgdGhpcy5lbWJlZGRlZFNpZ25hdHVyZSA9IG5ldyBwYWNrZXRfc2lnbmF0dXJlKCk7XG4gICAgICAgIHRoaXMuZW1iZWRkZWRTaWduYXR1cmUucmVhZChieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB1dGlsLnByaW50X2Vycm9yKFwib3BlbnBncC5wYWNrZXQuc2lnbmF0dXJlLmpzXFxuXCIgK1xuICAgICAgICAgICd1bmtub3duIHNpZ25hdHVyZSBzdWJwYWNrZXQgdHlwZSAnICsgdHlwZSArIFwiIEA6XCIgKyBteXBvcyArXG4gICAgICAgICAgXCIgc3VicGxlbjpcIiArIHN1YnBsZW4gKyBcIiBsZW46XCIgKyBsZW4pO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH07XG5cbiAgLy8gUHJvZHVjZXMgZGF0YSB0byBwcm9kdWNlIHNpZ25hdHVyZSBvblxuICB0aGlzLnRvU2lnbiA9IGZ1bmN0aW9uKHR5cGUsIGRhdGEpIHtcbiAgICB2YXIgdCA9IGVudW1zLnNpZ25hdHVyZTtcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSB0LmJpbmFyeTpcbiAgICAgIGNhc2UgdC50ZXh0OlxuICAgICAgICByZXR1cm4gZGF0YS5nZXRCeXRlcygpO1xuXG4gICAgICBjYXNlIHQuc3RhbmRhbG9uZTpcbiAgICAgICAgcmV0dXJuICcnO1xuXG4gICAgICBjYXNlIHQuY2VydF9nZW5lcmljOlxuICAgICAgY2FzZSB0LmNlcnRfcGVyc29uYTpcbiAgICAgIGNhc2UgdC5jZXJ0X2Nhc3VhbDpcbiAgICAgIGNhc2UgdC5jZXJ0X3Bvc2l0aXZlOlxuICAgICAgY2FzZSB0LmNlcnRfcmV2b2NhdGlvbjpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBwYWNrZXQsIHRhZztcblxuICAgICAgICAgIGlmIChkYXRhLnVzZXJpZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0YWcgPSAweEI0O1xuICAgICAgICAgICAgcGFja2V0ID0gZGF0YS51c2VyaWQ7XG4gICAgICAgICAgfSBlbHNlIGlmIChkYXRhLnVzZXJhdHRyaWJ1dGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGFnID0gMHhEMTtcbiAgICAgICAgICAgIHBhY2tldCA9IGRhdGEudXNlcmF0dHJpYnV0ZTtcbiAgICAgICAgICB9IGVsc2UgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgYSB1c2VyaWQgb3IgdXNlcmF0dHJpYnV0ZSBwYWNrZXQgbmVlZHMgdG8gYmUgJyArXG4gICAgICAgICAgICAgICdzdXBwbGllZCBmb3IgY2VydGlmaWNhdGlvbi4nKTtcblxuICAgICAgICAgIHZhciBieXRlcyA9IHBhY2tldC53cml0ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIHRoaXMudG9TaWduKHQua2V5LCBkYXRhKSArXG4gICAgICAgICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKHRhZykgK1xuICAgICAgICAgICAgdXRpbC53cml0ZU51bWJlcihieXRlcy5sZW5ndGgsIDQpICtcbiAgICAgICAgICAgIGJ5dGVzO1xuICAgICAgICB9XG4gICAgICBjYXNlIHQuc3Via2V5X2JpbmRpbmc6XG4gICAgICBjYXNlIHQua2V5X2JpbmRpbmc6XG4gICAgICAgIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50b1NpZ24odC5rZXksIGRhdGEpICsgdGhpcy50b1NpZ24odC5rZXksIHtcbiAgICAgICAgICAgIGtleTogZGF0YS5iaW5kXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgdC5rZXk6XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoZGF0YS5rZXkgPT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdLZXkgcGFja2V0IGlzIHJlcXVpcmVkIGZvciB0aGlzIHNpZ3RhdHVyZS4nKTtcblxuICAgICAgICAgIHJldHVybiBkYXRhLmtleS53cml0ZU9sZCgpO1xuICAgICAgICB9XG4gICAgICBjYXNlIHQua2V5X3Jldm9jYXRpb246XG4gICAgICBjYXNlIHQuc3Via2V5X3Jldm9jYXRpb246XG4gICAgICAgIHJldHVybiB0aGlzLnRvU2lnbih0LmtleSwgZGF0YSk7XG4gICAgICBjYXNlIHQudGltZXN0YW1wOlxuICAgICAgICByZXR1cm4gJyc7XG4gICAgICBjYXNlIHQudGhpcmRfcGFydHk6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHNpZ25hdHVyZSB0eXBlLicpXG4gICAgfVxuICB9XG5cblxuICB0aGlzLmNhbGN1bGF0ZVRyYWlsZXIgPSBmdW5jdGlvbigpIHtcbiAgICAvLyBjYWxjdWxhdGluZyB0aGUgdHJhaWxlclxuICAgIHZhciB0cmFpbGVyID0gJyc7XG4gICAgLy8gVjMgc2lnbmF0dXJlcyBkb24ndCBoYXZlIGEgdHJhaWxlclxuICAgIGlmICh0aGlzLnZlcnNpb24gPT0gMykgcmV0dXJuIHRyYWlsZXI7XG4gICAgdHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDQpOyAvLyBWZXJzaW9uXG4gICAgdHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkYpO1xuICAgIHRyYWlsZXIgKz0gdXRpbC53cml0ZU51bWJlcih0aGlzLnNpZ25hdHVyZURhdGEubGVuZ3RoLCA0KTtcbiAgICByZXR1cm4gdHJhaWxlclxuICB9XG5cblxuICAvKipcbiAgICogdmVyaWZ5cyB0aGUgc2lnbmF0dXJlIHBhY2tldC4gTm90ZTogbm90IHNpZ25hdHVyZSB0eXBlcyBhcmUgaW1wbGVtZW50ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBkYXRhIGRhdGEgd2hpY2ggb24gdGhlIHNpZ25hdHVyZSBhcHBsaWVzXG4gICAqIEBwYXJhbSB7cHVibGljX3N1YmtleXxwYWNrZXRfcHVibGljX2tleX0ga2V5IHRoZSBwdWJsaWMga2V5IHRvIHZlcmlmeSB0aGUgc2lnbmF0dXJlXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgbWVzc2FnZSBpcyB2ZXJpZmllZCwgZWxzZSBmYWxzZS5cbiAgICovXG4gIHRoaXMudmVyaWZ5ID0gZnVuY3Rpb24oa2V5LCBkYXRhKSB7XG4gICAgdmFyIHNpZ25hdHVyZVR5cGUgPSBlbnVtcy53cml0ZShlbnVtcy5zaWduYXR1cmUsIHRoaXMuc2lnbmF0dXJlVHlwZSksXG4gICAgICBwdWJsaWNLZXlBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMucHVibGljS2V5QWxnb3JpdGhtKSxcbiAgICAgIGhhc2hBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG0pO1xuXG4gICAgdmFyIGJ5dGVzID0gdGhpcy50b1NpZ24oc2lnbmF0dXJlVHlwZSwgZGF0YSksXG4gICAgICB0cmFpbGVyID0gdGhpcy5jYWxjdWxhdGVUcmFpbGVyKCk7XG5cblxuICAgIHZhciBtcGljb3VudCA9IDA7XG4gICAgLy8gQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgUlNBIHNpZ25hdHVyZXM6XG4gICAgLy8gXHQgICAgLSBtdWx0aXByZWNpc2lvbiBudW1iZXIgKE1QSSkgb2YgUlNBIHNpZ25hdHVyZSB2YWx1ZSBtKipkIG1vZCBuLlxuICAgIGlmIChwdWJsaWNLZXlBbGdvcml0aG0gPiAwICYmIHB1YmxpY0tleUFsZ29yaXRobSA8IDQpXG4gICAgICBtcGljb3VudCA9IDE7XG4gICAgLy8gICAgQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRFNBIHNpZ25hdHVyZXM6XG4gICAgLy8gICAgICAtIE1QSSBvZiBEU0EgdmFsdWUgci5cbiAgICAvLyAgICAgIC0gTVBJIG9mIERTQSB2YWx1ZSBzLlxuICAgIGVsc2UgaWYgKHB1YmxpY0tleUFsZ29yaXRobSA9PSAxNylcbiAgICAgIG1waWNvdW50ID0gMjtcblxuICAgIHZhciBtcGkgPSBbXSxcbiAgICAgIGkgPSAwO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbXBpY291bnQ7IGorKykge1xuICAgICAgbXBpW2pdID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgICBpICs9IG1waVtqXS5yZWFkKHRoaXMuc2lnbmF0dXJlLnN1YnN0cihpKSk7XG4gICAgfVxuXG4gICAgdGhpcy52ZXJpZmllZCA9IGNyeXB0by5zaWduYXR1cmUudmVyaWZ5KHB1YmxpY0tleUFsZ29yaXRobSxcbiAgICAgIGhhc2hBbGdvcml0aG0sIG1waSwga2V5Lm1waSxcbiAgICAgIGJ5dGVzICsgdGhpcy5zaWduYXR1cmVEYXRhICsgdHJhaWxlcik7XG5cbiAgICByZXR1cm4gdGhpcy52ZXJpZmllZDtcbiAgfVxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3ltLiBFbmNyeXB0ZWQgSW50ZWdyaXR5IFByb3RlY3RlZCBEYXRhIFxuICogUGFja2V0IChUYWcgMTgpXG4gKiBcbiAqIFJGQzQ4ODAgNS4xMzogVGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQgRGF0YSBwYWNrZXQgaXNcbiAqIGEgdmFyaWFudCBvZiB0aGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXQuIEl0IGlzIGEgbmV3IGZlYXR1cmVcbiAqIGNyZWF0ZWQgZm9yIE9wZW5QR1AgdGhhdCBhZGRyZXNzZXMgdGhlIHByb2JsZW0gb2YgZGV0ZWN0aW5nIGEgbW9kaWZpY2F0aW9uIHRvXG4gKiBlbmNyeXB0ZWQgZGF0YS4gSXQgaXMgdXNlZCBpbiBjb21iaW5hdGlvbiB3aXRoIGEgTW9kaWZpY2F0aW9uIERldGVjdGlvbiBDb2RlXG4gKiBwYWNrZXQuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkKCkge1xuICAvKiogVGhlIGVuY3J5cHRlZCBwYXlsb2FkLiAqL1xuICB0aGlzLmVuY3J5cHRlZCA9IG51bGw7IC8vIHN0cmluZ1xuICAvKiogQHR5cGUge0Jvb2xlYW59XG4gICAqIElmIGFmdGVyIGRlY3J5cHRpbmcgdGhlIHBhY2tldCB0aGlzIGlzIHNldCB0byB0cnVlLFxuICAgKiBhIG1vZGlmaWNhdGlvbiBoYXMgYmVlbiBkZXRlY3RlZCBhbmQgdGh1cyB0aGUgY29udGVudHNcbiAgICogc2hvdWxkIGJlIGRpc2NhcmRlZC5cbiAgICovXG4gIHRoaXMubW9kaWZpY2F0aW9uID0gZmFsc2U7XG4gIHRoaXMucGFja2V0cztcblxuXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgLy8gLSBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gVGhlIG9ubHkgY3VycmVudGx5IGRlZmluZWQgdmFsdWUgaXNcbiAgICAvLyAxLlxuICAgIHZhciB2ZXJzaW9uID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcblxuICAgIGlmICh2ZXJzaW9uICE9IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBwYWNrZXQgdmVyc2lvbi4nKTtcbiAgICB9XG5cbiAgICAvLyAtIEVuY3J5cHRlZCBkYXRhLCB0aGUgb3V0cHV0IG9mIHRoZSBzZWxlY3RlZCBzeW1tZXRyaWMta2V5IGNpcGhlclxuICAgIC8vICAgb3BlcmF0aW5nIGluIENpcGhlciBGZWVkYmFjayBtb2RlIHdpdGggc2hpZnQgYW1vdW50IGVxdWFsIHRvIHRoZVxuICAgIC8vICAgYmxvY2sgc2l6ZSBvZiB0aGUgY2lwaGVyIChDRkItbiB3aGVyZSBuIGlzIHRoZSBibG9jayBzaXplKS5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGJ5dGVzLnN1YnN0cigxKTtcbiAgfVxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcblxuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDEpIC8vIFZlcnNpb25cbiAgICArIHRoaXMuZW5jcnlwdGVkO1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oc2Vzc2lvbktleUFsZ29yaXRobSwga2V5KSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy5wYWNrZXRzLndyaXRlKClcblxuICAgIHZhciBwcmVmaXhyYW5kb20gPSBjcnlwdG8uZ2V0UHJlZml4UmFuZG9tKHNlc3Npb25LZXlBbGdvcml0aG0pO1xuICAgIHZhciBwcmVmaXggPSBwcmVmaXhyYW5kb20gKyBwcmVmaXhyYW5kb20uY2hhckF0KHByZWZpeHJhbmRvbS5sZW5ndGggLSAyKSArIHByZWZpeHJhbmRvbS5jaGFyQXQocHJlZml4cmFuZG9tLmxlbmd0aCAtXG4gICAgICAxKVxuXG4gICAgdmFyIHRvaGFzaCA9IGJ5dGVzO1xuXG5cbiAgICAvLyBNb2RpZmljYXRpb24gZGV0ZWN0aW9uIGNvZGUgcGFja2V0LlxuICAgIHRvaGFzaCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RDMpO1xuICAgIHRvaGFzaCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MTQpO1xuXG5cbiAgICB0b2hhc2ggKz0gY3J5cHRvLmhhc2guc2hhMShwcmVmaXggKyB0b2hhc2gpO1xuXG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5jZmIuZW5jcnlwdChwcmVmaXhyYW5kb20sXG4gICAgICBzZXNzaW9uS2V5QWxnb3JpdGhtLCB0b2hhc2gsIGtleSwgZmFsc2UpLnN1YnN0cmluZygwLFxuICAgICAgcHJlZml4Lmxlbmd0aCArIHRvaGFzaC5sZW5ndGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBlbmNyeXB0ZWQgZGF0YSBjb250YWluZWQgaW4gdGhpcyBvYmplY3QgcmVhZF9wYWNrZXQgbXVzdFxuICAgKiBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZVxuICAgKiBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBzZXNzaW9uS2V5QWxnb3JpdGhtXG4gICAqICAgICAgICAgICAgVGhlIHNlbGVjdGVkIHN5bW1ldHJpYyBlbmNyeXB0aW9uIGFsZ29yaXRobSB0byBiZSB1c2VkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgVGhlIGtleSBvZiBjaXBoZXIgYmxvY2tzaXplIGxlbmd0aCB0byBiZSB1c2VkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gVGhlIGRlY3J5cHRlZCBkYXRhIG9mIHRoaXMgcGFja2V0XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihzZXNzaW9uS2V5QWxnb3JpdGhtLCBrZXkpIHtcbiAgICB2YXIgZGVjcnlwdGVkID0gY3J5cHRvLmNmYi5kZWNyeXB0KFxuICAgICAgc2Vzc2lvbktleUFsZ29yaXRobSwga2V5LCB0aGlzLmVuY3J5cHRlZCwgZmFsc2UpO1xuXG5cbiAgICAvLyB0aGVyZSBtdXN0IGJlIGEgbW9kaWZpY2F0aW9uIGRldGVjdGlvbiBjb2RlIHBhY2tldCBhcyB0aGVcbiAgICAvLyBsYXN0IHBhY2tldCBhbmQgZXZlcnl0aGluZyBnZXRzIGhhc2hlZCBleGNlcHQgdGhlIGhhc2ggaXRzZWxmXG4gICAgdGhpcy5oYXNoID0gY3J5cHRvLmhhc2guc2hhMShcbiAgICAgIGNyeXB0by5jZmIubWRjKHNlc3Npb25LZXlBbGdvcml0aG0sIGtleSwgdGhpcy5lbmNyeXB0ZWQpICsgZGVjcnlwdGVkLnN1YnN0cmluZygwLCBkZWNyeXB0ZWQubGVuZ3RoIC0gMjApKTtcblxuXG4gICAgdmFyIG1kYyA9IGRlY3J5cHRlZC5zdWJzdHIoZGVjcnlwdGVkLmxlbmd0aCAtIDIwLCAyMCk7XG5cbiAgICBpZiAodGhpcy5oYXNoICE9IG1kYykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2RpZmljYXRpb24gZGV0ZWN0ZWQuJyk7XG4gICAgfSBlbHNlXG4gICAgICB0aGlzLnBhY2tldHMucmVhZChkZWNyeXB0ZWQuc3Vic3RyKDAsIGRlY3J5cHRlZC5sZW5ndGggLSAyMikpO1xuICB9XG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHR5cGVfczJrID0gcmVxdWlyZSgnLi4vdHlwZS9zMmsuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgUGFja2V0cyAoVGFnIDEpXG4gKiBcbiAqIFJGQzQ4ODAgNS4xOiBBIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldCBob2xkcyB0aGUgc2Vzc2lvbiBrZXlcbiAqIHVzZWQgdG8gZW5jcnlwdCBhIG1lc3NhZ2UuIFplcm8gb3IgbW9yZSBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleVxuICogcGFja2V0cyBhbmQvb3IgU3ltbWV0cmljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgcGFja2V0cyBtYXkgcHJlY2VkZSBhXG4gKiBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCwgd2hpY2ggaG9sZHMgYW4gZW5jcnlwdGVkIG1lc3NhZ2UuIFRoZVxuICogbWVzc2FnZSBpcyBlbmNyeXB0ZWQgd2l0aCB0aGUgc2Vzc2lvbiBrZXksIGFuZCB0aGUgc2Vzc2lvbiBrZXkgaXMgaXRzZWxmXG4gKiBlbmNyeXB0ZWQgYW5kIHN0b3JlZCBpbiB0aGUgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldChzKS4gVGhlXG4gKiBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCBpcyBwcmVjZWRlZCBieSBvbmUgUHVibGljLUtleSBFbmNyeXB0ZWRcbiAqIFNlc3Npb24gS2V5IHBhY2tldCBmb3IgZWFjaCBPcGVuUEdQIGtleSB0byB3aGljaCB0aGUgbWVzc2FnZSBpcyBlbmNyeXB0ZWQuXG4gKiBUaGUgcmVjaXBpZW50IG9mIHRoZSBtZXNzYWdlIGZpbmRzIGEgc2Vzc2lvbiBrZXkgdGhhdCBpcyBlbmNyeXB0ZWQgdG8gdGhlaXJcbiAqIHB1YmxpYyBrZXksIGRlY3J5cHRzIHRoZSBzZXNzaW9uIGtleSwgYW5kIHRoZW4gdXNlcyB0aGUgc2Vzc2lvbiBrZXkgdG9cbiAqIGRlY3J5cHQgdGhlIG1lc3NhZ2UuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3N5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkoKSB7XG4gIHRoaXMudGFnID0gMztcbiAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9ICdhZXMyNTYnO1xuICB0aGlzLmVuY3J5cHRlZCA9IG51bGw7XG4gIHRoaXMuczJrID0gbmV3IHR5cGVfczJrKCk7XG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgc3ltbWV0cmljIGVuY3J5cHRlZCBzZXNzaW9uIGtleSBwYWNrZXQgKHRhZyAzKS5cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDEgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5cbiAgICogICAgICAgICAgICBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZlxuICAgKiAgICAgICAgICAgIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IE9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gVGhlIG9ubHkgY3VycmVudGx5IGRlZmluZWQgdmVyc2lvbiBpcyA0LlxuICAgIHRoaXMudmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQoMCk7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgc3ltbWV0cmljIGFsZ29yaXRobSB1c2VkLlxuICAgIHZhciBhbGdvID0gZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIGJ5dGVzLmNoYXJDb2RlQXQoMSkpO1xuXG4gICAgLy8gQSBzdHJpbmctdG8ta2V5IChTMkspIHNwZWNpZmllciwgbGVuZ3RoIGFzIGRlZmluZWQgYWJvdmUuXG4gICAgdmFyIHMya2xlbmd0aCA9IHRoaXMuczJrLnJlYWQoYnl0ZXMuc3Vic3RyKDIpKTtcblxuICAgIC8vIE9wdGlvbmFsbHksIHRoZSBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXkgaXRzZWxmLCB3aGljaCBpcyBkZWNyeXB0ZWRcbiAgICAvLyB3aXRoIHRoZSBzdHJpbmctdG8ta2V5IG9iamVjdC5cbiAgICB2YXIgZG9uZSA9IHMya2xlbmd0aCArIDI7XG5cbiAgICBpZiAoZG9uZSA8IGJ5dGVzLmxlbmd0aCkge1xuICAgICAgdGhpcy5lbmNyeXB0ZWQgPSBieXRlcy5zdWJzdHIoZG9uZSk7XG4gICAgICB0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtID0gYWxnb1xuICAgIH0gZWxzZVxuICAgICAgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtID0gYWxnbztcbiAgfVxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYWxnbyA9IHRoaXMuZW5jcnlwdGVkID09IG51bGwgP1xuICAgICAgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtIDpcbiAgICAgIHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG07XG5cbiAgICB2YXIgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMudmVyc2lvbikgK1xuICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIGFsZ28pKSArXG4gICAgICB0aGlzLnMyay53cml0ZSgpO1xuXG4gICAgaWYgKHRoaXMuZW5jcnlwdGVkICE9IG51bGwpXG4gICAgICBieXRlcyArPSB0aGlzLmVuY3J5cHRlZDtcbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuICAvKipcbiAgICogRGVjcnlwdHMgdGhlIHNlc3Npb24ga2V5IChvbmx5IGZvciBwdWJsaWMga2V5IGVuY3J5cHRlZCBzZXNzaW9uIGtleVxuICAgKiBwYWNrZXRzICh0YWcgMSlcbiAgICogXG4gICAqIEBwYXJhbSB7b3BlbnBncF9tc2dfbWVzc2FnZX0gbXNnXG4gICAqICAgICAgICAgICAgVGhlIG1lc3NhZ2Ugb2JqZWN0ICh3aXRoIG1lbWJlciBlbmNyeXB0ZWREYXRhXG4gICAqIEBwYXJhbSB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleX0ga2V5XG4gICAqICAgICAgICAgICAgUHJpdmF0ZSBrZXkgd2l0aCBzZWNNUElzIHVubG9ja2VkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gVGhlIHVuZW5jcnlwdGVkIHNlc3Npb24ga2V5XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihwYXNzcGhyYXNlKSB7XG4gICAgdmFyIGFsZ28gPSB0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtICE9IG51bGwgP1xuICAgICAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSA6XG4gICAgICB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG07XG5cblxuICAgIHZhciBsZW5ndGggPSBjcnlwdG8uY2lwaGVyW2FsZ29dLmtleVNpemU7XG4gICAgdmFyIGtleSA9IHRoaXMuczJrLnByb2R1Y2Vfa2V5KHBhc3NwaHJhc2UsIGxlbmd0aCk7XG5cbiAgICBpZiAodGhpcy5lbmNyeXB0ZWQgPT0gbnVsbCkge1xuICAgICAgdGhpcy5zZXNzaW9uS2V5ID0ga2V5O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBkZWNyeXB0ZWQgPSBjcnlwdG8uY2ZiLmRlY3J5cHQoXG4gICAgICAgIHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0sIGtleSwgdGhpcy5lbmNyeXB0ZWQsIHRydWUpO1xuXG4gICAgICB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYyxcbiAgICAgICAgZGVjcnlwdGVkWzBdLmtleUNvZGVBdCgpKTtcblxuICAgICAgdGhpcy5zZXNzaW9uS2V5ID0gZGVjcnlwdGVkLnN1YnN0cigxKTtcbiAgICB9XG4gIH1cblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihwYXNzcGhyYXNlKSB7XG4gICAgdmFyIGxlbmd0aCA9IGNyeXB0by5nZXRLZXlMZW5ndGgodGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSk7XG4gICAgdmFyIGtleSA9IHRoaXMuczJrLnByb2R1Y2Vfa2V5KHBhc3NwaHJhc2UsIGxlbmd0aCk7XG5cbiAgICB2YXIgcHJpdmF0ZV9rZXkgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuICAgICAgZW51bXMud3JpdGUoZW51bXMuc3ltbWV0cmljLCB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0pKSArXG5cbiAgICBjcnlwdG8uZ2V0UmFuZG9tQnl0ZXMoXG4gICAgICBjcnlwdG8uZ2V0S2V5TGVuZ3RoKHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSkpO1xuXG4gICAgdGhpcy5lbmNyeXB0ZWQgPSBjcnlwdG8uY2ZiLmVuY3J5cHQoXG4gICAgICBjcnlwdG8uZ2V0UHJlZml4UmFuZG9tKHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0pLFxuICAgICAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSwga2V5LCBwcml2YXRlX2tleSwgdHJ1ZSk7XG4gIH1cbn07XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnLi4vY3J5cHRvJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCAoVGFnIDkpXG4gKiBcbiAqIFJGQzQ4ODAgNS43OiBUaGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXQgY29udGFpbnMgZGF0YSBlbmNyeXB0ZWRcbiAqIHdpdGggYSBzeW1tZXRyaWMta2V5IGFsZ29yaXRobS4gV2hlbiBpdCBoYXMgYmVlbiBkZWNyeXB0ZWQsIGl0IGNvbnRhaW5zIG90aGVyXG4gKiBwYWNrZXRzICh1c3VhbGx5IGEgbGl0ZXJhbCBkYXRhIHBhY2tldCBvciBjb21wcmVzc2VkIGRhdGEgcGFja2V0LCBidXQgaW5cbiAqIHRoZW9yeSBvdGhlciBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIHBhY2tldHMgb3Igc2VxdWVuY2VzIG9mIHBhY2tldHNcbiAqIHRoYXQgZm9ybSB3aG9sZSBPcGVuUEdQIG1lc3NhZ2VzKS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9zeW1tZXRyaWNhbGx5X2VuY3J5cHRlZCgpIHtcbiAgdGhpcy5lbmNyeXB0ZWQgPSBudWxsO1xuICAvKiogRGVjcnlwdGVkIHBhY2tldHMgY29udGFpbmVkIHdpdGhpbi4gXG4gICAqIEB0eXBlIHtvcGVucGdwX3BhY2tldGxpc3R9ICovXG4gIHRoaXMucGFja2V0cztcblxuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHRoaXMuZW5jcnlwdGVkID0gYnl0ZXM7XG4gIH1cblxuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZW5jcnlwdGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFN5bW1ldHJpY2FsbHkgZGVjcnlwdCB0aGUgcGFja2V0IGRhdGFcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gc2Vzc2lvbktleUFsZ29yaXRobVxuICAgKiAgICAgICAgICAgICBTeW1tZXRyaWMga2V5IGFsZ29yaXRobSB0byB1c2UgLy8gU2VlIFJGQzQ4ODAgOS4yXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAgICogICAgICAgICAgICAgS2V5IGFzIHN0cmluZyB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIGxlbmd0aCB0byB0aGVcbiAgICogICAgICAgICAgICBhbGdvcml0aG1cbiAgICogQHJldHVybiBUaGUgZGVjcnlwdGVkIGRhdGE7XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihzZXNzaW9uS2V5QWxnb3JpdGhtLCBrZXkpIHtcbiAgICB2YXIgZGVjcnlwdGVkID0gY3J5cHRvLmNmYi5kZWNyeXB0KFxuICAgICAgc2Vzc2lvbktleUFsZ29yaXRobSwga2V5LCB0aGlzLmVuY3J5cHRlZCwgdHJ1ZSk7XG5cbiAgICB0aGlzLnBhY2tldHMucmVhZChkZWNyeXB0ZWQpO1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYWxnbywga2V5KSB7XG4gICAgdmFyIGRhdGEgPSB0aGlzLnBhY2tldHMud3JpdGUoKTtcblxuICAgIHRoaXMuZW5jcnlwdGVkID0gY3J5cHRvLmNmYi5lbmNyeXB0KFxuICAgICAgY3J5cHRvLmdldFByZWZpeFJhbmRvbShhbGdvKSwgYWxnbywgZGF0YSwga2V5LCB0cnVlKTtcbiAgfVxufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3RydXN0KCkge1xuXG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIFxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBVc2VyIEF0dHJpYnV0ZSBQYWNrZXQgKFRhZyAxNylcbiAqICBUaGUgVXNlciBBdHRyaWJ1dGUgcGFja2V0IGlzIGEgdmFyaWF0aW9uIG9mIHRoZSBVc2VyIElEIHBhY2tldC4gIEl0XG4gKiAgaXMgY2FwYWJsZSBvZiBzdG9yaW5nIG1vcmUgdHlwZXMgb2YgZGF0YSB0aGFuIHRoZSBVc2VyIElEIHBhY2tldCxcbiAqICB3aGljaCBpcyBsaW1pdGVkIHRvIHRleHQuICBMaWtlIHRoZSBVc2VyIElEIHBhY2tldCwgYSBVc2VyIEF0dHJpYnV0ZVxuICogIHBhY2tldCBtYXkgYmUgY2VydGlmaWVkIGJ5IHRoZSBrZXkgb3duZXIgKFwic2VsZi1zaWduZWRcIikgb3IgYW55IG90aGVyXG4gKiAga2V5IG93bmVyIHdobyBjYXJlcyB0byBjZXJ0aWZ5IGl0LiAgRXhjZXB0IGFzIG5vdGVkLCBhIFVzZXIgQXR0cmlidXRlXG4gKiAgcGFja2V0IG1heSBiZSB1c2VkIGFueXdoZXJlIHRoYXQgYSBVc2VyIElEIHBhY2tldCBtYXkgYmUgdXNlZC5cbiAqXG4gKiAgV2hpbGUgVXNlciBBdHRyaWJ1dGUgcGFja2V0cyBhcmUgbm90IGEgcmVxdWlyZWQgcGFydCBvZiB0aGUgT3BlblBHUFxuICogIHN0YW5kYXJkLCBpbXBsZW1lbnRhdGlvbnMgU0hPVUxEIHByb3ZpZGUgYXQgbGVhc3QgZW5vdWdoXG4gKiAgY29tcGF0aWJpbGl0eSB0byBwcm9wZXJseSBoYW5kbGUgYSBjZXJ0aWZpY2F0aW9uIHNpZ25hdHVyZSBvbiB0aGVcbiAqICBVc2VyIEF0dHJpYnV0ZSBwYWNrZXQuICBBIHNpbXBsZSB3YXkgdG8gZG8gdGhpcyBpcyBieSB0cmVhdGluZyB0aGVcbiAqICBVc2VyIEF0dHJpYnV0ZSBwYWNrZXQgYXMgYSBVc2VyIElEIHBhY2tldCB3aXRoIG9wYXF1ZSBjb250ZW50cywgYnV0XG4gKiAgYW4gaW1wbGVtZW50YXRpb24gbWF5IHVzZSBhbnkgbWV0aG9kIGRlc2lyZWQuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3VzZXJfYXR0cmlidXRlKCkge1xuICB0aGlzLnRhZyA9IDE3O1xuICB0aGlzLmF0dHJpYnV0ZXMgPSBbXTtcblxuICAvKipcbiAgICogcGFyc2luZyBmdW5jdGlvbiBmb3IgYSB1c2VyIGF0dHJpYnV0ZSBwYWNrZXQgKHRhZyAxNykuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBwYXlsb2FkIG9mIGEgdGFnIDE3IHBhY2tldFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIHBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIGxlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IG9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKGkgPCBieXRlcy5sZW5ndGgpIHtcbiAgICAgIHZhciBsZW4gPSBvcGVucGdwX3BhY2tldC5yZWFkX3NpbXBsZV9sZW5ndGgoYnl0ZXMpO1xuXG4gICAgICBpICs9IGxlbi5vZmZzZXQ7XG4gICAgICB0aGlzLmF0dHJpYnV0ZXMucHVzaChieXRlcy5zdWJzdHIoaSwgbGVuLmxlbikpO1xuICAgICAgaSArPSBsZW4ubGVuO1xuICAgIH1cbiAgfVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgVXNlciBJRCBQYWNrZXQgKFRhZyAxMylcbiAqIEEgVXNlciBJRCBwYWNrZXQgY29uc2lzdHMgb2YgVVRGLTggdGV4dCB0aGF0IGlzIGludGVuZGVkIHRvIHJlcHJlc2VudFxuICogdGhlIG5hbWUgYW5kIGVtYWlsIGFkZHJlc3Mgb2YgdGhlIGtleSBob2xkZXIuICBCeSBjb252ZW50aW9uLCBpdFxuICogaW5jbHVkZXMgYW4gUkZDIDI4MjIgW1JGQzI4MjJdIG1haWwgbmFtZS1hZGRyLCBidXQgdGhlcmUgYXJlIG5vXG4gKiByZXN0cmljdGlvbnMgb24gaXRzIGNvbnRlbnQuICBUaGUgcGFja2V0IGxlbmd0aCBpbiB0aGUgaGVhZGVyXG4gKiBzcGVjaWZpZXMgdGhlIGxlbmd0aCBvZiB0aGUgVXNlciBJRC4gXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3VzZXJpZCgpIHtcbiAgLyoqIEB0eXBlIHtTdHJpbmd9IEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHVzZXIgaWQuIFVzdWFsbHkgaW4gdGhlIGZvcm1cbiAgICogSm9obiBEb2UgPGpvaG5AZXhhbXBsZS5jb20+IFxuICAgKi9cbiAgdGhpcy51c2VyaWQgPSAnJztcblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHVzZXIgaWQgcGFja2V0ICh0YWcgMTMpLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgcGF5bG9hZCBvZiBhIHRhZyAxMyBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZ1xuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBsZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dCBcbiAgICogYXQgcG9zaXRpb25cbiAgICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YX0gb2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHRoaXMudXNlcmlkID0gdXRpbC5kZWNvZGVfdXRmOChieXRlcyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdXNlciBpZCBwYWNrZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHVzZXJfaWQgdGhlIHVzZXIgaWQgYXMgc3RyaW5nIChcIkpvaG4gRG9lIDxqb2huLmRvZUBtYWlsLnVzXCIpXG4gICAqIEByZXR1cm4ge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHV0aWwuZW5jb2RlX3V0ZjgodGhpcy51c2VyaWQpO1xuICB9XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdHlwZSBrZXkgaWQgKFJGQzQ4ODAgMy4zKVxuICogIEEgS2V5IElEIGlzIGFuIGVpZ2h0LW9jdGV0IHNjYWxhciB0aGF0IGlkZW50aWZpZXMgYSBrZXkuXG4gICBJbXBsZW1lbnRhdGlvbnMgU0hPVUxEIE5PVCBhc3N1bWUgdGhhdCBLZXkgSURzIGFyZSB1bmlxdWUuICBUaGVcbiAgIHNlY3Rpb24gXCJFbmhhbmNlZCBLZXkgRm9ybWF0c1wiIGJlbG93IGRlc2NyaWJlcyBob3cgS2V5IElEcyBhcmVcbiAgIGZvcm1lZC5cbiAqL1xuZnVuY3Rpb24ga2V5aWQoKSB7XG5cbiAgdGhpcy5ieXRlcyA9ICcnO1xuXG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgbWV0aG9kIGZvciBhIGtleSBpZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgSW5wdXQgdG8gcmVhZCB0aGUga2V5IGlkIGZyb20gXG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gd2hlcmUgdG8gc3RhcnQgcmVhZGluZyB0aGUga2V5IFxuICAgKiBpZCBmcm9tIGlucHV0XG4gICAqIEByZXR1cm4ge29wZW5wZ3BfdHlwZV9rZXlpZH0gVGhpcyBvYmplY3RcbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdGhpcy5ieXRlcyA9IGJ5dGVzLnN1YnN0cigwLCA4KTtcbiAgfVxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5ieXRlcztcbiAgfVxuXG4gIHRoaXMudG9IZXggPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdXRpbC5oZXhzdHJkdW1wKHRoaXMuYnl0ZXMpO1xuICB9XG5cbiAgdGhpcy5lcXVhbHMgPSBmdW5jdGlvbihrZXlpZCkge1xuICAgIHJldHVybiB0aGlzLmJ5dGVzID09IGtleWlkLmJ5dGVzO1xuICB9XG5cbiAgdGhpcy5pc051bGwgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5ieXRlcyA9PT0gJyc7XG4gIH1cbn1cblxua2V5aWQubWFwVG9IZXggPSBmdW5jdGlvbihrZXlpZCkge1xuICByZXR1cm4ga2V5aWQudG9IZXgoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBrZXlpZDtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8vIEhpbnQ6IFdlIGhvbGQgb3VyIE1QSXMgYXMgYW4gYXJyYXkgb2Ygb2N0ZXRzIGluIGJpZyBlbmRpYW4gZm9ybWF0IHByZWNlZWRpbmcgYSB0d29cbi8vIG9jdGV0IHNjYWxhcjogTVBJOiBbYSxiLGMsZCxlLGZdXG4vLyAtIE1QSSBzaXplOiAoYSA8PCA4KSB8IGIgXG4vLyAtIE1QSSA9IGMgfCBkIDw8IDggfCBlIDw8ICgoTVBJLmxlbmd0aCAtMikqOCkgfCBmICgoTVBJLmxlbmd0aCAtMikqOClcblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuLi9jcnlwdG8vcHVibGljX2tleS9qc2JuLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjSW1wbGVtZW50YXRpb24gb2YgdHlwZSBNUEkgKFJGQzQ4ODAgMy4yKVxuICogTXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgKGFsc28gY2FsbGVkIE1QSXMpIGFyZSB1bnNpZ25lZCBpbnRlZ2VycyB1c2VkXG4gKiB0byBob2xkIGxhcmdlIGludGVnZXJzIHN1Y2ggYXMgdGhlIG9uZXMgdXNlZCBpbiBjcnlwdG9ncmFwaGljXG4gKiBjYWxjdWxhdGlvbnMuXG4gKiBBbiBNUEkgY29uc2lzdHMgb2YgdHdvIHBpZWNlczogYSB0d28tb2N0ZXQgc2NhbGFyIHRoYXQgaXMgdGhlIGxlbmd0aFxuICogb2YgdGhlIE1QSSBpbiBiaXRzIGZvbGxvd2VkIGJ5IGEgc3RyaW5nIG9mIG9jdGV0cyB0aGF0IGNvbnRhaW4gdGhlXG4gKiBhY3R1YWwgaW50ZWdlci5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtcGkoKSB7XG4gIC8qKiBBbiBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQgaW50ZWdlciAqL1xuICB0aGlzLmRhdGEgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIG1waSAoUkZDIDQ4ODAgMy4yKS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFBheWxvYWQgb2YgbXBpIGRhdGFcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IFxuICAgKiBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2YgXG4gICAqIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfdHlwZV9tcGl9IE9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgYml0cyA9IChieXRlcy5jaGFyQ29kZUF0KDApIDw8IDgpIHwgYnl0ZXMuY2hhckNvZGVBdCgxKTtcblxuICAgIC8vIEFkZGl0aW9uYWwgcnVsZXM6XG4gICAgLy9cbiAgICAvLyAgICBUaGUgc2l6ZSBvZiBhbiBNUEkgaXMgKChNUEkubGVuZ3RoICsgNykgLyA4KSArIDIgb2N0ZXRzLlxuICAgIC8vXG4gICAgLy8gICAgVGhlIGxlbmd0aCBmaWVsZCBvZiBhbiBNUEkgZGVzY3JpYmVzIHRoZSBsZW5ndGggc3RhcnRpbmcgZnJvbSBpdHNcbiAgICAvL1x0ICBtb3N0IHNpZ25pZmljYW50IG5vbi16ZXJvIGJpdC4gIFRodXMsIHRoZSBNUEkgWzAwIDAyIDAxXSBpcyBub3RcbiAgICAvLyAgICBmb3JtZWQgY29ycmVjdGx5LiAgSXQgc2hvdWxkIGJlIFswMCAwMSAwMV0uXG5cbiAgICAvLyBUT0RPOiBWZXJpZmljYXRpb24gb2YgdGhpcyBzaXplIG1ldGhvZCEgVGhpcyBzaXplIGNhbGN1bGF0aW9uIGFzXG4gICAgLy8gXHRcdCBzcGVjaWZpZWQgYWJvdmUgaXMgbm90IGFwcGxpY2FibGUgaW4gSmF2YVNjcmlwdFxuICAgIHZhciBieXRlbGVuID0gTWF0aC5jZWlsKGJpdHMgLyA4KTtcblxuICAgIHZhciByYXcgPSBieXRlcy5zdWJzdHIoMiwgYnl0ZWxlbik7XG4gICAgdGhpcy5mcm9tQnl0ZXMocmF3KTtcblxuICAgIHJldHVybiAyICsgYnl0ZWxlbjtcbiAgfVxuXG4gIHRoaXMuZnJvbUJ5dGVzID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB0aGlzLmRhdGEgPSBuZXcgQmlnSW50ZWdlcih1dGlsLmhleHN0cmR1bXAoYnl0ZXMpLCAxNik7XG4gIH1cblxuICB0aGlzLnRvQnl0ZXMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy53cml0ZSgpLnN1YnN0cigyKTtcbiAgfVxuXG4gIHRoaXMuYnl0ZUxlbmd0aCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvQnl0ZXMoKS5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgdGhlIG1waSBvYmplY3QgdG8gYSBzdHJpbmcgYXMgc3BlY2lmaWVkIGluIFJGQzQ4ODAgMy4yXG4gICAqIEByZXR1cm4ge1N0cmluZ30gbXBpIEJ5dGUgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhLnRvTVBJKCk7XG4gIH1cblxuICB0aGlzLnRvQmlnSW50ZWdlciA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGEuY2xvbmUoKTtcbiAgfVxuXG4gIHRoaXMuZnJvbUJpZ0ludGVnZXIgPSBmdW5jdGlvbihibikge1xuICAgIHRoaXMuZGF0YSA9IGJuLmNsb25lKCk7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RyaW5nLXRvLWtleSBzcGVjaWZpZXIgKFJGQzQ4ODAgMy43KVxuICogU3RyaW5nLXRvLWtleSAoUzJLKSBzcGVjaWZpZXJzIGFyZSB1c2VkIHRvIGNvbnZlcnQgcGFzc3BocmFzZSBzdHJpbmdzXG4gICBpbnRvIHN5bW1ldHJpYy1rZXkgZW5jcnlwdGlvbi9kZWNyeXB0aW9uIGtleXMuICBUaGV5IGFyZSB1c2VkIGluIHR3b1xuICAgcGxhY2VzLCBjdXJyZW50bHk6IHRvIGVuY3J5cHQgdGhlIHNlY3JldCBwYXJ0IG9mIHByaXZhdGUga2V5cyBpbiB0aGVcbiAgIHByaXZhdGUga2V5cmluZywgYW5kIHRvIGNvbnZlcnQgcGFzc3BocmFzZXMgdG8gZW5jcnlwdGlvbiBrZXlzIGZvclxuICAgc3ltbWV0cmljYWxseSBlbmNyeXB0ZWQgbWVzc2FnZXMuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gczJrKCkge1xuICAvKiogQHR5cGUge29wZW5wZ3AuaGFzaH0gKi9cbiAgdGhpcy5hbGdvcml0aG0gPSAnc2hhMjU2JztcbiAgLyoqIEB0eXBlIHtvcGVucGdwX3R5cGVfczJrLnR5cGV9ICovXG4gIHRoaXMudHlwZSA9ICdpdGVyYXRlZCc7XG4gIHRoaXMuYyA9IDk2O1xuICAvKiogQHR5cGUge29wZW5wZ3BfYnl0ZWFycmF5fSBcbiAgICogRWlnaHQgYnl0ZXMgb2Ygc2FsdC4gKi9cbiAgdGhpcy5zYWx0ID0gY3J5cHRvLnJhbmRvbS5nZXRSYW5kb21CeXRlcyg4KTtcblxuXG4gIC8vIEV4cG9uZW4gYmlhcywgZGVmaW5lZCBpbiBSRkM0ODgwXG4gIHZhciBleHBiaWFzID0gNjtcblxuICB0aGlzLmdldF9jb3VudCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAoMTYgKyAodGhpcy5jICYgMTUpKSA8PCAoKHRoaXMuYyA+PiA0KSArIGV4cGJpYXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgc3RyaW5nLXRvLWtleSBzcGVjaWZpZXIgKFJGQyA0ODgwIDMuNykuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIHN0cmluZy10by1rZXkgc3BlY2lmaWVyXG4gICAqIEByZXR1cm4ge0ludGVnZXJ9IEFjdHVhbCBsZW5ndGggb2YgdGhlIG9iamVjdFxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgaSA9IDA7XG4gICAgdGhpcy50eXBlID0gZW51bXMucmVhZChlbnVtcy5zMmssIGJ5dGVzLmNoYXJDb2RlQXQoaSsrKSk7XG4gICAgdGhpcy5hbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLmhhc2gsIGJ5dGVzLmNoYXJDb2RlQXQoaSsrKSk7XG5cbiAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgY2FzZSAnc2ltcGxlJzpcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3NhbHRlZCc6XG4gICAgICAgIHRoaXMuc2FsdCA9IGJ5dGVzLnN1YnN0cihpLCA4KTtcbiAgICAgICAgaSArPSA4O1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnaXRlcmF0ZWQnOlxuICAgICAgICB0aGlzLnNhbHQgPSBieXRlcy5zdWJzdHIoaSwgOCk7XG4gICAgICAgIGkgKz0gODtcblxuICAgICAgICAvLyBPY3RldCAxMDogY291bnQsIGEgb25lLW9jdGV0LCBjb2RlZCB2YWx1ZVxuICAgICAgICB0aGlzLmMgPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdnbnUnOlxuICAgICAgICBpZiAoYnl0ZXMuc3Vic3RyKGksIDMpID09IFwiR05VXCIpIHtcbiAgICAgICAgICBpICs9IDM7IC8vIEdOVVxuICAgICAgICAgIHZhciBnbnVFeHRUeXBlID0gMTAwMCArIGJ5dGVzLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgICAgICBpZiAoZ251RXh0VHlwZSA9PSAxMDAxKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBnbnVFeHRUeXBlO1xuICAgICAgICAgICAgLy8gR251UEcgZXh0ZW5zaW9uIG1vZGUgMTAwMSAtLSBkb24ndCB3cml0ZSBzZWNyZXQga2V5IGF0IGFsbFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIHMyayBnbnUgcHJvdGVjdGlvbiBtb2RlLlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBzMmsgdHlwZS5cIik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gczJrIHR5cGUuXCIpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICByZXR1cm4gaTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIHdyaXRlcyBhbiBzMmsgaGFzaCBiYXNlZCBvbiB0aGUgaW5wdXRzLlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFByb2R1Y2VkIGtleSBvZiBoYXNoQWxnb3JpdGhtIGhhc2ggbGVuZ3RoXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ5dGVzID0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5zMmssIHRoaXMudHlwZSkpO1xuICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMuaGFzaCwgdGhpcy5hbGdvcml0aG0pKTtcblxuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICBjYXNlICdzaW1wbGUnOlxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3NhbHRlZCc6XG4gICAgICAgIGJ5dGVzICs9IHRoaXMuc2FsdDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpdGVyYXRlZCc6XG4gICAgICAgIGJ5dGVzICs9IHRoaXMuc2FsdDtcbiAgICAgICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmMpO1xuICAgICAgICBicmVhaztcbiAgICB9O1xuXG4gICAgcmV0dXJuIGJ5dGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2R1Y2VzIGEga2V5IHVzaW5nIHRoZSBzcGVjaWZpZWQgcGFzc3BocmFzZSBhbmQgdGhlIGRlZmluZWQgXG4gICAqIGhhc2hBbGdvcml0aG0gXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzcGhyYXNlIFBhc3NwaHJhc2UgY29udGFpbmluZyB1c2VyIGlucHV0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gUHJvZHVjZWQga2V5IHdpdGggYSBsZW5ndGggY29ycmVzcG9uZGluZyB0byBcbiAgICogaGFzaEFsZ29yaXRobSBoYXNoIGxlbmd0aFxuICAgKi9cbiAgdGhpcy5wcm9kdWNlX2tleSA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UsIG51bUJ5dGVzKSB7XG4gICAgcGFzc3BocmFzZSA9IHV0aWwuZW5jb2RlX3V0ZjgocGFzc3BocmFzZSk7XG5cbiAgICBmdW5jdGlvbiByb3VuZChwcmVmaXgsIHMyaykge1xuICAgICAgdmFyIGFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLmhhc2gsIHMyay5hbGdvcml0aG0pO1xuXG4gICAgICBzd2l0Y2ggKHMyay50eXBlKSB7XG4gICAgICAgIGNhc2UgJ3NpbXBsZSc6XG4gICAgICAgICAgcmV0dXJuIGNyeXB0by5oYXNoLmRpZ2VzdChhbGdvcml0aG0sIHByZWZpeCArIHBhc3NwaHJhc2UpO1xuXG4gICAgICAgIGNhc2UgJ3NhbHRlZCc6XG4gICAgICAgICAgcmV0dXJuIGNyeXB0by5oYXNoLmRpZ2VzdChhbGdvcml0aG0sXG4gICAgICAgICAgICBwcmVmaXggKyBzMmsuc2FsdCArIHBhc3NwaHJhc2UpO1xuXG4gICAgICAgIGNhc2UgJ2l0ZXJhdGVkJzpcbiAgICAgICAgICB2YXIgaXNwID0gW10sXG4gICAgICAgICAgICBjb3VudCA9IHMyay5nZXRfY291bnQoKTtcbiAgICAgICAgICBkYXRhID0gczJrLnNhbHQgKyBwYXNzcGhyYXNlO1xuXG4gICAgICAgICAgd2hpbGUgKGlzcC5sZW5ndGggKiBkYXRhLmxlbmd0aCA8IGNvdW50KVxuICAgICAgICAgICAgaXNwLnB1c2goZGF0YSk7XG5cbiAgICAgICAgICBpc3AgPSBpc3Auam9pbignJyk7XG5cbiAgICAgICAgICBpZiAoaXNwLmxlbmd0aCA+IGNvdW50KVxuICAgICAgICAgICAgaXNwID0gaXNwLnN1YnN0cigwLCBjb3VudCk7XG5cbiAgICAgICAgICByZXR1cm4gY3J5cHRvLmhhc2guZGlnZXN0KGFsZ29yaXRobSwgcHJlZml4ICsgaXNwKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHJlc3VsdCA9ICcnLFxuICAgICAgcHJlZml4ID0gJyc7XG5cbiAgICB3aGlsZSAocmVzdWx0Lmxlbmd0aCA8PSBudW1CeXRlcykge1xuICAgICAgcmVzdWx0ICs9IHJvdW5kKHByZWZpeCwgdGhpcyk7XG4gICAgICBwcmVmaXggKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0LnN1YnN0cigwLCBudW1CeXRlcyk7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxudmFyIFV0aWwgPSBmdW5jdGlvbigpIHtcblxuICB0aGlzLnJlYWROdW1iZXIgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBuID0gMDtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG4gPDw9IDg7XG4gICAgICBuICs9IGJ5dGVzLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG47XG4gIH07XG5cbiAgdGhpcy53cml0ZU51bWJlciA9IGZ1bmN0aW9uKG4sIGJ5dGVzKSB7XG4gICAgdmFyIGIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzOyBpKyspIHtcbiAgICAgIGIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgobiA+PiAoOCAqIChieXRlcyAtIGkgLSAxKSkpICYgMHhGRik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGI7XG4gIH07XG5cblxuXG4gIHRoaXMucmVhZERhdGUgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBuID0gdGhpcy5yZWFkTnVtYmVyKGJ5dGVzKTtcbiAgICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gICAgZC5zZXRUaW1lKG4gKiAxMDAwKTtcbiAgICByZXR1cm4gZDtcbiAgfTtcblxuICB0aGlzLndyaXRlRGF0ZSA9IGZ1bmN0aW9uKHRpbWUpIHtcbiAgICB2YXIgbnVtZXJpYyA9IE1hdGgucm91bmQodGltZS5nZXRUaW1lKCkgLyAxMDAwKTtcblxuICAgIHJldHVybiB0aGlzLndyaXRlTnVtYmVyKG51bWVyaWMsIDQpO1xuICB9O1xuXG4gIHRoaXMuZW1haWxSZWdFeCA9IC9eWythLXpBLVowLTlfLi1dK0AoW2EtekEtWjAtOS1dK1xcLikrW2EtekEtWjAtOV17Miw2fSQvO1xuXG4gIHRoaXMuZGVidWcgPSBmYWxzZTtcblxuICB0aGlzLmhleGR1bXAgPSBmdW5jdGlvbihzdHIpIHtcbiAgICB2YXIgciA9IFtdO1xuICAgIHZhciBlID0gc3RyLmxlbmd0aDtcbiAgICB2YXIgYyA9IDA7XG4gICAgdmFyIGg7XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChjIDwgZSkge1xuICAgICAgaCA9IHN0ci5jaGFyQ29kZUF0KGMrKykudG9TdHJpbmcoMTYpO1xuICAgICAgd2hpbGUgKGgubGVuZ3RoIDwgMikgaCA9IFwiMFwiICsgaDtcbiAgICAgIHIucHVzaChcIiBcIiArIGgpO1xuICAgICAgaSsrO1xuICAgICAgaWYgKGkgJSAzMiA9PSAwKVxuICAgICAgICByLnB1c2goXCJcXG4gICAgICAgICAgIFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHIuam9pbignJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBoZXhzdHJpbmcgZnJvbSBhIGJpbmFyeVxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGhleGFkZWNpbWFsIHZhbHVlc1xuICAgKi9cbiAgdGhpcy5oZXhzdHJkdW1wID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgaWYgKHN0ciA9PSBudWxsKVxuICAgICAgcmV0dXJuIFwiXCI7XG4gICAgdmFyIHIgPSBbXTtcbiAgICB2YXIgZSA9IHN0ci5sZW5ndGg7XG4gICAgdmFyIGMgPSAwO1xuICAgIHZhciBoO1xuICAgIHdoaWxlIChjIDwgZSkge1xuICAgICAgaCA9IHN0ci5jaGFyQ29kZUF0KGMrKykudG9TdHJpbmcoMTYpO1xuICAgICAgd2hpbGUgKGgubGVuZ3RoIDwgMikgaCA9IFwiMFwiICsgaDtcbiAgICAgIHIucHVzaChcIlwiICsgaCk7XG4gICAgfVxuICAgIHJldHVybiByLmpvaW4oJycpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYmluYXJ5IHN0cmluZyBmcm9tIGEgaGV4IGVuY29kZWQgc3RyaW5nXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgSGV4IHN0cmluZyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGJpbmFyeSB2YWx1ZXNcbiAgICovXG4gIHRoaXMuaGV4MmJpbiA9IGZ1bmN0aW9uKGhleCkge1xuICAgIHZhciBzdHIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhleC5sZW5ndGg7IGkgKz0gMilcbiAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGhleC5zdWJzdHIoaSwgMiksIDE2KSk7XG4gICAgcmV0dXJuIHN0cjtcbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRpbmcgYSBoZXggc3RyaW5nIGZyb20gYW4gYmluYXJ5IGFycmF5IG9mIGludGVnZXJzICgwLi4yNTUpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgQXJyYXkgb2YgYnl0ZXMgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcnJheVxuICAgKi9cbiAgdGhpcy5oZXhpZHVtcCA9IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciByID0gW107XG4gICAgdmFyIGUgPSBzdHIubGVuZ3RoO1xuICAgIHZhciBjID0gMDtcbiAgICB2YXIgaDtcbiAgICB3aGlsZSAoYyA8IGUpIHtcbiAgICAgIGggPSBzdHJbYysrXS50b1N0cmluZygxNik7XG4gICAgICB3aGlsZSAoaC5sZW5ndGggPCAyKSBoID0gXCIwXCIgKyBoO1xuICAgICAgci5wdXNoKFwiXCIgKyBoKTtcbiAgICB9XG4gICAgcmV0dXJuIHIuam9pbignJyk7XG4gIH07XG5cblxuICAvKipcbiAgICogQ29udmVydCBhIG5hdGl2ZSBqYXZhc2NyaXB0IHN0cmluZyB0byBhIHN0cmluZyBvZiB1dGY4IGJ5dGVzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgVGhlIHN0cmluZyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gQSB2YWxpZCBzcXVlbmNlIG9mIHV0ZjggYnl0ZXNcbiAgICovXG4gIHRoaXMuZW5jb2RlX3V0ZjggPSBmdW5jdGlvbihzdHIpIHtcbiAgICByZXR1cm4gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHN0cikpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgc3RyaW5nIG9mIHV0ZjggYnl0ZXMgdG8gYSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmdcbiAgICogQHBhcmFtIHtTdHJpbmd9IHV0ZjggQSB2YWxpZCBzcXVlbmNlIG9mIHV0ZjggYnl0ZXNcbiAgICogQHJldHVybiB7U3RyaW5nfSBBIG5hdGl2ZSBqYXZhc2NyaXB0IHN0cmluZ1xuICAgKi9cbiAgdGhpcy5kZWNvZGVfdXRmOCA9IGZ1bmN0aW9uKHV0ZjgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUodXRmOCkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB1dGY4O1xuICAgIH1cbiAgfTtcblxuICB2YXIgc3RyMmJpbiA9IGZ1bmN0aW9uKHN0ciwgcmVzdWx0KSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdFtpXSA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgdmFyIGJpbjJzdHIgPSBmdW5jdGlvbihiaW4pIHtcbiAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJpbi5sZW5ndGg7IGkrKykge1xuICAgICAgcmVzdWx0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShiaW5baV0pKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0LmpvaW4oJycpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGFuIGFycmF5IG9mIGludGVnZXJzKDAuMjU1KVxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge0ludGVnZXJbXX0gQW4gYXJyYXkgb2YgKGJpbmFyeSkgaW50ZWdlcnNcbiAgICovXG4gIHRoaXMuc3RyMmJpbiA9IGZ1bmN0aW9uKHN0cikge1xuICAgIHJldHVybiBzdHIyYmluKHN0ciwgbmV3IEFycmF5KHN0ci5sZW5ndGgpKTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGludGVnZXJzKDAuMjU1KSB0byBhIHN0cmluZyBcbiAgICogQHBhcmFtIHtJbnRlZ2VyW119IGJpbiBBbiBhcnJheSBvZiAoYmluYXJ5KSBpbnRlZ2VycyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgYXJyYXlcbiAgICovXG4gIHRoaXMuYmluMnN0ciA9IGJpbjJzdHI7XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBzdHJpbmcgdG8gYSBVaW50OEFycmF5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7VWludDhBcnJheX0gVGhlIGFycmF5IG9mIChiaW5hcnkpIGludGVnZXJzXG4gICAqL1xuICB0aGlzLnN0cjJVaW50OEFycmF5ID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgcmV0dXJuIHN0cjJiaW4oc3RyLCBuZXcgVWludDhBcnJheShuZXcgQXJyYXlCdWZmZXIoc3RyLmxlbmd0aCkpKTtcbiAgfTtcblxuICAvKipcbiAgICogQ29udmVydCBhIFVpbnQ4QXJyYXkgdG8gYSBzdHJpbmcuIFRoaXMgY3VycmVudGx5IGZ1bmN0aW9ucyBcbiAgICogdGhlIHNhbWUgYXMgYmluMnN0ci4gXG4gICAqIEBwYXJhbSB7VWludDhBcnJheX0gYmluIEFuIGFycmF5IG9mIChiaW5hcnkpIGludGVnZXJzIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFycmF5XG4gICAqL1xuICB0aGlzLlVpbnQ4QXJyYXkyc3RyID0gYmluMnN0cjtcblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyBhIDE2Yml0IHN1bSBvZiBhIHN0cmluZyBieSBhZGRpbmcgZWFjaCBjaGFyYWN0ZXIgXG4gICAqIGNvZGVzIG1vZHVsdXMgNjU1MzVcbiAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgU3RyaW5nIHRvIGNyZWF0ZSBhIHN1bSBvZlxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBbiBpbnRlZ2VyIGNvbnRhaW5pbmcgdGhlIHN1bSBvZiBhbGwgY2hhcmFjdGVyIFxuICAgKiBjb2RlcyAlIDY1NTM1XG4gICAqL1xuICB0aGlzLmNhbGNfY2hlY2tzdW0gPSBmdW5jdGlvbih0ZXh0KSB7XG4gICAgdmFyIGNoZWNrc3VtID0ge1xuICAgICAgczogMCxcbiAgICAgIGFkZDogZnVuY3Rpb24oc2FkZCkge1xuICAgICAgICB0aGlzLnMgPSAodGhpcy5zICsgc2FkZCkgJSA2NTUzNjtcbiAgICAgIH1cbiAgICB9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGV4dC5sZW5ndGg7IGkrKykge1xuICAgICAgY2hlY2tzdW0uYWRkKHRleHQuY2hhckNvZGVBdChpKSk7XG4gICAgfVxuICAgIHJldHVybiBjaGVja3N1bS5zO1xuICB9O1xuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gcHJpbnQgYSBkZWJ1ZyBtZXNzYWdlLiBEZWJ1ZyBcbiAgICogbWVzc2FnZXMgYXJlIG9ubHkgcHJpbnRlZCBpZlxuICAgKiBvcGVucGdwLmNvbmZpZy5kZWJ1ZyBpcyBzZXQgdG8gdHJ1ZS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgb2YgdGhlIGRlYnVnIG1lc3NhZ2VcbiAgICovXG4gIHRoaXMucHJpbnRfZGVidWcgPSBmdW5jdGlvbihzdHIpIHtcbiAgICBpZiAoY29uZmlnLmRlYnVnKSB7XG4gICAgICBjb25zb2xlLmxvZyhzdHIpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogSGVscGVyIGZ1bmN0aW9uIHRvIHByaW50IGEgZGVidWcgbWVzc2FnZS4gRGVidWcgXG4gICAqIG1lc3NhZ2VzIGFyZSBvbmx5IHByaW50ZWQgaWZcbiAgICogb3BlbnBncC5jb25maWcuZGVidWcgaXMgc2V0IHRvIHRydWUuXG4gICAqIERpZmZlcmVudCB0aGFuIHByaW50X2RlYnVnIGJlY2F1c2Ugd2lsbCBjYWxsIGhleHN0cmR1bXAgaWZmIG5lY2Vzc2FyeS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgb2YgdGhlIGRlYnVnIG1lc3NhZ2VcbiAgICovXG4gIHRoaXMucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAgPSBmdW5jdGlvbihzdHIsIHN0clRvSGV4KSB7XG4gICAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgICAgc3RyID0gc3RyICsgdGhpcy5oZXhzdHJkdW1wKHN0clRvSGV4KTtcbiAgICAgIGNvbnNvbGUubG9nKHN0cik7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gcHJpbnQgYW4gZXJyb3IgbWVzc2FnZS4gXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBlcnJvciBtZXNzYWdlXG4gICAqL1xuICB0aGlzLnByaW50X2Vycm9yID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgaWYgKGNvbmZpZy5kZWJ1ZylcbiAgICAgIHRocm93IHN0cjtcbiAgICBjb25zb2xlLmxvZyhzdHIpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gcHJpbnQgYW4gaW5mbyBtZXNzYWdlLiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgb2YgdGhlIGluZm8gbWVzc2FnZVxuICAgKi9cbiAgdGhpcy5wcmludF9pbmZvID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgaWYgKGNvbmZpZy5kZWJ1ZylcbiAgICAgIGNvbnNvbGUubG9nKHN0cik7XG4gIH07XG5cbiAgdGhpcy5wcmludF93YXJuaW5nID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgY29uc29sZS5sb2coc3RyKTtcbiAgfTtcblxuICB0aGlzLmdldExlZnROQml0cyA9IGZ1bmN0aW9uKHN0cmluZywgYml0Y291bnQpIHtcbiAgICB2YXIgcmVzdCA9IGJpdGNvdW50ICUgODtcbiAgICBpZiAocmVzdCA9PSAwKVxuICAgICAgcmV0dXJuIHN0cmluZy5zdWJzdHJpbmcoMCwgYml0Y291bnQgLyA4KTtcbiAgICB2YXIgYnl0ZXMgPSAoYml0Y291bnQgLSByZXN0KSAvIDggKyAxO1xuICAgIHZhciByZXN1bHQgPSBzdHJpbmcuc3Vic3RyaW5nKDAsIGJ5dGVzKTtcbiAgICByZXR1cm4gdGhpcy5zaGlmdFJpZ2h0KHJlc3VsdCwgOCAtIHJlc3QpOyAvLyArU3RyaW5nLmZyb21DaGFyQ29kZShzdHJpbmcuY2hhckNvZGVBdChieXRlcyAtMSkgPDwgKDgtcmVzdCkgJiAweEZGKTtcbiAgfTtcblxuICAvKipcbiAgICogU2hpZnRpbmcgYSBzdHJpbmcgdG8gbiBiaXRzIHJpZ2h0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZSBUaGUgc3RyaW5nIHRvIHNoaWZ0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYml0Y291bnQgQW1vdW50IG9mIGJpdHMgdG8gc2hpZnQgKE1VU1QgYmUgc21hbGxlciBcbiAgICogdGhhbiA5KVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFJlc3VsdGluZyBzdHJpbmcuIFxuICAgKi9cbiAgdGhpcy5zaGlmdFJpZ2h0ID0gZnVuY3Rpb24odmFsdWUsIGJpdGNvdW50KSB7XG4gICAgdmFyIHRlbXAgPSB1dGlsLnN0cjJiaW4odmFsdWUpO1xuICAgIGlmIChiaXRjb3VudCAlIDggIT0gMCkge1xuICAgICAgZm9yICh2YXIgaSA9IHRlbXAubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgdGVtcFtpXSA+Pj0gYml0Y291bnQgJSA4O1xuICAgICAgICBpZiAoaSA+IDApXG4gICAgICAgICAgdGVtcFtpXSB8PSAodGVtcFtpIC0gMV0gPDwgKDggLSAoYml0Y291bnQgJSA4KSkpICYgMHhGRjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gdXRpbC5iaW4yc3RyKHRlbXApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGFsZ29yaXRobSB0eXBlIGFzIHN0cmluZ1xuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyByZXByZXNlbnRpbmcgdGhlIG1lc3NhZ2UgdHlwZVxuICAgKi9cbiAgdGhpcy5nZXRfaGFzaEFsZ29yaXRobVN0cmluZyA9IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIFwiTUQ1XCI7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiBcIlNIQTFcIjtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIFwiUklQRU1EMTYwXCI7XG4gICAgICBjYXNlIDg6XG4gICAgICAgIHJldHVybiBcIlNIQTI1NlwiO1xuICAgICAgY2FzZSA5OlxuICAgICAgICByZXR1cm4gXCJTSEEzODRcIjtcbiAgICAgIGNhc2UgMTA6XG4gICAgICAgIHJldHVybiBcIlNIQTUxMlwiO1xuICAgICAgY2FzZSAxMTpcbiAgICAgICAgcmV0dXJuIFwiU0hBMjI0XCI7XG4gICAgfVxuICAgIHJldHVybiBcInVua25vd25cIjtcbiAgfTtcblxufTtcblxuLyoqXG4gKiBhbiBpbnN0YW5jZSB0aGF0IHNob3VsZCBiZSB1c2VkLiBcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBuZXcgVXRpbCgpO1xuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi8uLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJBRVMgUmlqbmRhZWwgY2lwaGVyIHRlc3Qgd2l0aCB0ZXN0IHZlY3RvcnMgZnJvbSBlY2JfdGJsLnR4dFwiLCBmdW5jdGlvbigpIHtcbiAgdmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8uLi8nKTtcbiAgdmFyIHV0aWwgPSBvcGVucGdwLnV0aWw7XG5cbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheSgpO1xuXG4gIGZ1bmN0aW9uIHRlc3RfYWVzKGlucHV0LCBrZXksIG91dHB1dCkge1xuICAgIHZhciBhZXMgPSBuZXcgb3BlbnBncC5jcnlwdG8uY2lwaGVyLmFlczEyOCh1dGlsLmJpbjJzdHIoa2V5KSk7XG5cbiAgICB2YXIgcmVzdWx0ID0gdXRpbC5iaW4yc3RyKGFlcy5lbmNyeXB0KGlucHV0KSk7XG5cbiAgICByZXR1cm4gdXRpbC5oZXhzdHJkdW1wKHJlc3VsdCkgPT0gdXRpbC5oZXhzdHJkdW1wKHV0aWwuYmluMnN0cihvdXRwdXQpKTtcbiAgfTtcblxuICB2YXIgdGVzdHZlY3RvcnMxMjggPSBbW1sweDAwLDB4MDEsMHgwMiwweDAzLDB4MDUsMHgwNiwweDA3LDB4MDgsMHgwQSwweDBCLDB4MEMsMHgwRCwweDBGLDB4MTAsMHgxMSwweDEyXSxbMHg1MCwweDY4LDB4MTIsMHhBNCwweDVGLDB4MDgsMHhDOCwweDg5LDB4QjksMHg3RiwweDU5LDB4ODAsMHgwMywweDhCLDB4ODMsMHg1OV0sWzB4RDgsMHhGNSwweDMyLDB4NTMsMHg4MiwweDg5LDB4RUYsMHg3RCwweDA2LDB4QjUsMHgwNiwweEE0LDB4RkQsMHg1QiwweEU5LDB4QzldXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHgxNCwweDE1LDB4MTYsMHgxNywweDE5LDB4MUEsMHgxQiwweDFDLDB4MUUsMHgxRiwweDIwLDB4MjEsMHgyMywweDI0LDB4MjUsMHgyNl0sWzB4NUMsMHg2RCwweDcxLDB4Q0EsMHgzMCwweERFLDB4OEIsMHg4QiwweDAwLDB4NTQsMHg5OSwweDg0LDB4RDIsMHhFQywweDdELDB4NEJdLFsweDU5LDB4QUIsMHgzMCwweEY0LDB4RDQsMHhFRSwweDZFLDB4NEYsMHhGOSwweDkwLDB4N0UsMHhGNiwweDVCLDB4MUYsMHhCNiwweDhDXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4MjgsMHgyOSwweDJBLDB4MkIsMHgyRCwweDJFLDB4MkYsMHgzMCwweDMyLDB4MzMsMHgzNCwweDM1LDB4MzcsMHgzOCwweDM5LDB4M0FdLFsweDUzLDB4RjMsMHhGNCwweEM2LDB4NEYsMHg4NiwweDE2LDB4RTQsMHhFNywweEM1LDB4NjEsMHg5OSwweEY0LDB4OEYsMHgyMSwweEY2XSxbMHhCRiwweDFFLDB4RDIsMHhGQywweEIyLDB4QUYsMHgzRiwweEQ0LDB4MTQsMHg0MywweEI1LDB4NkQsMHg4NSwweDAyLDB4NUMsMHhCMV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDNDLDB4M0QsMHgzRSwweDNGLDB4NDEsMHg0MiwweDQzLDB4NDQsMHg0NiwweDQ3LDB4NDgsMHg0OSwweDRCLDB4NEMsMHg0RCwweDRFXSxbMHhBMSwweEVCLDB4NjUsMHhBMywweDQ4LDB4NzEsMHg2NSwweEZCLDB4MEYsMHgxQywweDI3LDB4RkYsMHg5OSwweDU5LDB4RjcsMHgwM10sWzB4NzMsMHgxNiwweDYzLDB4MkQsMHg1QywweDMyLDB4MjMsMHgzRSwweERDLDB4QjAsMHg3OCwweDA1LDB4NjAsMHhFQSwweEU4LDB4QjJdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHg1MCwweDUxLDB4NTIsMHg1MywweDU1LDB4NTYsMHg1NywweDU4LDB4NUEsMHg1QiwweDVDLDB4NUQsMHg1RiwweDYwLDB4NjEsMHg2Ml0sWzB4MzUsMHg1MywweEVDLDB4RjAsMHhCMSwweDczLDB4OTUsMHg1OCwweEIwLDB4OEUsMHgzNSwweDBBLDB4OTgsMHhBMywweDlCLDB4RkFdLFsweDQwLDB4OEMsMHgwNywweDNFLDB4M0UsMHgyNSwweDM4LDB4MDcsMHgyQiwweDcyLDB4NjIsMHg1RSwweDY4LDB4QjgsMHgzNiwweDRCXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4NjQsMHg2NSwweDY2LDB4NjcsMHg2OSwweDZBLDB4NkIsMHg2QywweDZFLDB4NkYsMHg3MCwweDcxLDB4NzMsMHg3NCwweDc1LDB4NzZdLFsweDY3LDB4NDIsMHg5OSwweDY5LDB4NDksMHgwQiwweDk3LDB4MTEsMHhBRSwweDJCLDB4MDEsMHhEQywweDQ5LDB4N0EsMHhGRCwweEU4XSxbMHhFMSwweEY5LDB4NEQsMHhGQSwweDc3LDB4NjUsMHg5NywweEJFLDB4QUMsMHhBMiwweDYyLDB4RjIsMHhGNiwweDM2LDB4NkYsMHhFQV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDc4LDB4NzksMHg3QSwweDdCLDB4N0QsMHg3RSwweDdGLDB4ODAsMHg4MiwweDgzLDB4ODQsMHg4NSwweDg3LDB4ODgsMHg4OSwweDhBXSxbMHg5MywweDM4LDB4NUMsMHgxRiwweDJBLDB4RUMsMHg4QiwweEVELDB4MTksMHgyRiwweDVBLDB4OEUsMHgxNiwweDFELDB4RDUsMHgwOF0sWzB4RjIsMHg5RSwweDk4LDB4NkMsMHg2QSwweDFDLDB4MjcsMHhENywweEIyLDB4OUYsMHhGRCwweDdFLDB4RTksMHgyQiwweDc1LDB4RjFdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHg4QywweDhELDB4OEUsMHg4RiwweDkxLDB4OTIsMHg5MywweDk0LDB4OTYsMHg5NywweDk4LDB4OTksMHg5QiwweDlDLDB4OUQsMHg5RV0sWzB4QjUsMHhCRiwweDk0LDB4NkIsMHhFMSwweDlCLDB4RUIsMHg4RCwweEIzLDB4OTgsMHgzQiwweDVGLDB4NEMsMHg2RSwweDhELDB4REJdLFsweDEzLDB4MUMsMHg4OCwweDZBLDB4NTcsMHhGOCwweEMyLDB4RTcsMHgxMywweEFCLDB4QTYsMHg5NSwweDVFLDB4MkIsMHg1NSwweEI1XV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4QTAsMHhBMSwweEEyLDB4QTMsMHhBNSwweEE2LDB4QTcsMHhBOCwweEFBLDB4QUIsMHhBQywweEFELDB4QUYsMHhCMCwweEIxLDB4QjJdLFsweDQxLDB4MzIsMHgxRSwweEUxLDB4MEUsMHgyMSwweEJELDB4OTAsMHg3MiwweDI3LDB4QzQsMHg0NSwweDBGLDB4RjQsMHgyMywweDI0XSxbMHhEMiwweEFCLDB4NzYsMHg2MiwweERGLDB4OUIsMHg4QywweDc0LDB4MDIsMHgxMCwweEU1LDB4RUUsMHhCNiwweDFDLDB4MTksMHg5RF1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweEI0LDB4QjUsMHhCNiwweEI3LDB4QjksMHhCQSwweEJCLDB4QkMsMHhCRSwweEJGLDB4QzAsMHhDMSwweEMzLDB4QzQsMHhDNSwweEM2XSxbMHgwMCwweEE4LDB4MkYsMHg1OSwweEM5LDB4MUMsMHg4NCwweDg2LDB4RDEsMHgyQywweDBBLDB4ODAsMHgxMiwweDRGLDB4NjAsMHg4OV0sWzB4MTQsMHhDMSwweDA1LDB4NTQsMHhCMiwweDg1LDB4OUMsMHg0OCwweDRDLDB4QUIsMHg1OCwweDY5LDB4QkIsMHhFNywweEM0LDB4NzBdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHhDOCwweEM5LDB4Q0EsMHhDQiwweENELDB4Q0UsMHhDRiwweEQwLDB4RDIsMHhEMywweEQ0LDB4RDUsMHhENywweEQ4LDB4RDksMHhEQV0sWzB4N0MsMHhFMCwweEZELDB4MDcsMHg2NywweDU0LDB4NjksMHgxQiwweDRCLDB4QkQsMHg5RiwweEFGLDB4OEEsMHgxMywweDcyLDB4RkVdLFsweERCLDB4NEQsMHg0OSwweDhGLDB4MEEsMHg0OSwweENGLDB4NTUsMHg0NCwweDVELDB4NTAsMHgyQywweDFGLDB4OUEsMHhCMywweEI1XV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4REMsMHhERCwweERFLDB4REYsMHhFMSwweEUyLDB4RTMsMHhFNCwweEU2LDB4RTcsMHhFOCwweEU5LDB4RUIsMHhFQywweEVELDB4RUVdLFsweDIzLDB4NjAsMHg1QSwweDgyLDB4NDMsMHhEMCwweDc3LDB4NjQsMHg1NCwweDFCLDB4QzUsMHhBRCwweDM1LDB4NUIsMHgzMSwweDI5XSxbMHg2RCwweDk2LDB4RkUsMHhGNywweEQ2LDB4NjUsMHg5MCwweEE3LDB4N0EsMHg3NywweEJCLDB4MjAsMHg1NiwweDY2LDB4N0YsMHg3Rl1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweEYwLDB4RjEsMHhGMiwweEYzLDB4RjUsMHhGNiwweEY3LDB4RjgsMHhGQSwweEZCLDB4RkMsMHhGRCwweEZFLDB4MDEsMHgwMCwweDAyXSxbMHgxMiwweEE4LDB4Q0YsMHhBMiwweDNFLDB4QTcsMHg2NCwweEZELDB4ODcsMHg2MiwweDMyLDB4QjQsMHhFOCwweDQyLDB4QkMsMHg0NF0sWzB4MzEsMHg2RiwweEI2LDB4OEUsMHhEQiwweEE3LDB4MzYsMHhDNSwweDNFLDB4NzgsMHg0NywweDdCLDB4RjksMHgxMywweDcyLDB4NUNdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHgwNCwweDA1LDB4MDYsMHgwNywweDA5LDB4MEEsMHgwQiwweDBDLDB4MEUsMHgwRiwweDEwLDB4MTEsMHgxMywweDE0LDB4MTUsMHgxNl0sWzB4QkMsMHhBRiwweDMyLDB4NDEsMHg1RSwweDgzLDB4MDgsMHhCMywweDcyLDB4M0UsMHg1RiwweERELDB4ODUsMHgzQywweENDLDB4ODBdLFsweDY5LDB4MzYsMHhGMiwweEI5LDB4M0EsMHhGOCwweDM5LDB4N0YsMHhEMywweEE3LDB4NzEsMHhGQywweDAxLDB4MUMsMHg4QywweDM3XV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4MkMsMHgyRCwweDJFLDB4MkYsMHgzMSwweDMyLDB4MzMsMHgzNCwweDM2LDB4MzcsMHgzOCwweDM5LDB4M0IsMHgzQywweDNELDB4M0VdLFsweDg5LDB4QUYsMHhBRSwweDY4LDB4NUQsMHg4MCwweDFBLDB4RDcsMHg0NywweEFDLDB4RTksMHgxRiwweEM0LDB4OUEsMHhERCwweEUwXSxbMHhGMywweEY5LDB4MkYsMHg3QSwweDlDLDB4NTksMHgxNywweDlDLDB4MUYsMHhDQywweDJDLDB4MkIsMHhBMCwweEIwLDB4ODIsMHhDRF1dXTtcbiAgXG4gIHZhciB0ZXN0dmVjdG9yczE5MiA9IFtbWzB4MDAsMHgwMSwweDAyLDB4MDMsMHgwNSwweDA2LDB4MDcsMHgwOCwweDBBLDB4MEIsMHgwQywweDBELDB4MEYsMHgxMCwweDExLDB4MTIsMHgxNCwweDE1LDB4MTYsMHgxNywweDE5LDB4MUEsMHgxQiwweDFDXSxbMHgyRCwweDMzLDB4RUUsMHhGMiwweEMwLDB4NDMsMHgwQSwweDhBLDB4OUUsMHhCRiwweDQ1LDB4RTgsMHgwOSwweEM0LDB4MEIsMHhCNl0sWzB4REYsMHhGNCwweDk0LDB4NUUsMHgwMywweDM2LDB4REYsMHg0QywweDFDLDB4NTYsMHhCQywweDcwLDB4MEUsMHhGRiwweDgzLDB4N0ZdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHgxRSwweDFGLDB4MjAsMHgyMSwweDIzLDB4MjQsMHgyNSwweDI2LDB4MjgsMHgyOSwweDJBLDB4MkIsMHgyRCwweDJFLDB4MkYsMHgzMCwweDMyLDB4MzMsMHgzNCwweDM1LDB4MzcsMHgzOCwweDM5LDB4M0FdLFsweDZBLDB4QTMsMHg3NSwweEQxLDB4RkEsMHgxNSwweDVBLDB4NjEsMHhGQiwweDcyLDB4MzUsMHgzRSwweDBBLDB4NUEsMHg4NywweDU2XSxbMHhCNiwweEZELDB4REUsMHhGNCwweDc1LDB4MjcsMHg2NSwweEUzLDB4NDcsMHhENSwweEQyLDB4REMsMHgxOSwweDZELDB4MTIsMHg1Ml1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDNDLDB4M0QsMHgzRSwweDNGLDB4NDEsMHg0MiwweDQzLDB4NDQsMHg0NiwweDQ3LDB4NDgsMHg0OSwweDRCLDB4NEMsMHg0RCwweDRFLDB4NTAsMHg1MSwweDUyLDB4NTMsMHg1NSwweDU2LDB4NTcsMHg1OF0sWzB4QkMsMHgzNywweDM2LDB4NTEsMHg4QiwweDk0LDB4OTAsMHhEQywweEI4LDB4RUQsMHg2MCwweEVCLDB4MjYsMHg3NSwweDhFLDB4RDRdLFsweEQyLDB4MzYsMHg4NCwweEUzLDB4RDksMHg2MywweEIzLDB4QUYsMHhDRiwweDFBLDB4MTEsMHg0QSwweENBLDB4OTAsMHhDQiwweEQ2XV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4NUEsMHg1QiwweDVDLDB4NUQsMHg1RiwweDYwLDB4NjEsMHg2MiwweDY0LDB4NjUsMHg2NiwweDY3LDB4NjksMHg2QSwweDZCLDB4NkMsMHg2RSwweDZGLDB4NzAsMHg3MSwweDczLDB4NzQsMHg3NSwweDc2XSxbMHhBQSwweDIxLDB4NDQsMHgwMiwweEI0LDB4NkMsMHhGRiwweEI5LDB4RjcsMHg2MSwweEVDLDB4MTEsMHgyNiwweDNBLDB4MzEsMHgxRV0sWzB4M0EsMHg3QSwweEMwLDB4MjcsMHg3NSwweDNFLDB4MkEsMHgxOCwweEMyLDB4Q0UsMHhBQiwweDlFLDB4MTcsMHhDMSwweDFGLDB4RDBdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHg3OCwweDc5LDB4N0EsMHg3QiwweDdELDB4N0UsMHg3RiwweDgwLDB4ODIsMHg4MywweDg0LDB4ODUsMHg4NywweDg4LDB4ODksMHg4QSwweDhDLDB4OEQsMHg4RSwweDhGLDB4OTEsMHg5MiwweDkzLDB4OTRdLFsweDAyLDB4QUUsMHhBOCwweDZFLDB4NTcsMHgyRSwweEVBLDB4QjYsMHg2QiwweDJDLDB4M0EsMHhGNSwweEU5LDB4QTQsMHg2RiwweEQ2XSxbMHg4RiwweDY3LDB4ODYsMHhCRCwweDAwLDB4NzUsMHgyOCwweEJBLDB4MjYsMHg2MCwweDNDLDB4MTYsMHgwMSwweENELDB4RDAsMHhEOF1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDk2LDB4OTcsMHg5OCwweDk5LDB4OUIsMHg5QywweDlELDB4OUUsMHhBMCwweEExLDB4QTIsMHhBMywweEE1LDB4QTYsMHhBNywweEE4LDB4QUEsMHhBQiwweEFDLDB4QUQsMHhBRiwweEIwLDB4QjEsMHhCMl0sWzB4RTIsMHhBRSwweEY2LDB4QUMsMHhDMywweDNCLDB4OTYsMHg1QywweDRGLDB4QTEsMHhGOSwweDFDLDB4NzUsMHhGRiwweDZGLDB4MzZdLFsweEQxLDB4N0QsMHgwNywweDNCLDB4MDEsMHhFNywweDE1LDB4MDIsMHhFMiwweDhCLDB4NDcsMHhBQiwweDU1LDB4MTEsMHg2OCwweEIzXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4QjQsMHhCNSwweEI2LDB4QjcsMHhCOSwweEJBLDB4QkIsMHhCQywweEJFLDB4QkYsMHhDMCwweEMxLDB4QzMsMHhDNCwweEM1LDB4QzYsMHhDOCwweEM5LDB4Q0EsMHhDQiwweENELDB4Q0UsMHhDRiwweEQwXSxbMHgwNiwweDU5LDB4REYsMHg0NiwweDQyLDB4NzEsMHg2MiwweEI5LDB4NDMsMHg0OCwweDY1LDB4REQsMHg5NCwweDk5LDB4RjksMHgxRF0sWzB4QTQsMHg2OSwweERBLDB4NTEsMHg3MSwweDE5LDB4RkEsMHhCOSwweDU4LDB4NzYsMHhGNCwweDFELDB4MDYsMHhENCwweDBGLDB4RkFdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHhEMiwweEQzLDB4RDQsMHhENSwweEQ3LDB4RDgsMHhEOSwweERBLDB4REMsMHhERCwweERFLDB4REYsMHhFMSwweEUyLDB4RTMsMHhFNCwweEU2LDB4RTcsMHhFOCwweEU5LDB4RUIsMHhFQywweEVELDB4RUVdLFsweDQ5LDB4QTQsMHg0MiwweDM5LDB4QzcsMHg0OCwweEZFLDB4QjQsMHg1NiwweEY1LDB4OUMsMHgyNywweDZBLDB4NTYsMHg1OCwweERGXSxbMHg2MCwweDkxLDB4QUEsMHgzQiwweDY5LDB4NUMsMHgxMSwweEY1LDB4QzAsMHhCNiwweEFELDB4MjYsMHhEMywweEQ4LDB4NjIsMHhGRl1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweEYwLDB4RjEsMHhGMiwweEYzLDB4RjUsMHhGNiwweEY3LDB4RjgsMHhGQSwweEZCLDB4RkMsMHhGRCwweEZFLDB4MDEsMHgwMCwweDAyLDB4MDQsMHgwNSwweDA2LDB4MDcsMHgwOSwweDBBLDB4MEIsMHgwQ10sWzB4NjYsMHgyMCwweDhGLDB4NkUsMHg5RCwweDA0LDB4NTIsMHg1QiwweERFLDB4REIsMHgyNywweDMzLDB4QjYsMHhBNiwweEJFLDB4MzddLFsweDcwLDB4RjksMHhFNiwweDdGLDB4OUYsMHg4RCwweEYxLDB4MjksMHg0MSwweDMxLDB4NjYsMHgyRCwweEM2LDB4RTYsMHg5MywweDY0XV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4MEUsMHgwRiwweDEwLDB4MTEsMHgxMywweDE0LDB4MTUsMHgxNiwweDE4LDB4MTksMHgxQSwweDFCLDB4MUQsMHgxRSwweDFGLDB4MjAsMHgyMiwweDIzLDB4MjQsMHgyNSwweDI3LDB4MjgsMHgyOSwweDJBXSxbMHgzMywweDkzLDB4RjgsMHhERiwweEM3LDB4MjksMHhDOSwweDdGLDB4NTQsMHg4MCwweEI5LDB4NTAsMHhCQywweDk2LDB4NjYsMHhCMF0sWzB4RDEsMHg1NCwweERDLDB4QUYsMHhBRCwweDhCLDB4MjAsMHg3RiwweEE1LDB4Q0IsMHhDOSwweDVFLDB4OTksMHg5NiwweEI1LDB4NTldXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHgyQywweDJELDB4MkUsMHgyRiwweDMxLDB4MzIsMHgzMywweDM0LDB4MzYsMHgzNywweDM4LDB4MzksMHgzQiwweDNDLDB4M0QsMHgzRSwweDQwLDB4NDEsMHg0MiwweDQzLDB4NDUsMHg0NiwweDQ3LDB4NDhdLFsweDYwLDB4NjgsMHgzNCwweEM4LDB4Q0UsMHgwNiwweDNGLDB4MzIsMHgzNCwweENGLDB4MTEsMHg0NSwweDMyLDB4NUQsMHhCRCwweDcxXSxbMHg0OSwweDM0LDB4RDUsMHg0MSwweEU4LDB4QjQsMHg2RiwweEEzLDB4MzksMHhDOCwweDA1LDB4QTcsMHhBRSwweEI5LDB4RTUsMHhEQV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDRBLDB4NEIsMHg0QywweDRELDB4NEYsMHg1MCwweDUxLDB4NTIsMHg1NCwweDU1LDB4NTYsMHg1NywweDU5LDB4NUEsMHg1QiwweDVDLDB4NUUsMHg1RiwweDYwLDB4NjEsMHg2MywweDY0LDB4NjUsMHg2Nl0sWzB4RkUsMHhDMSwweEMwLDB4NEYsMHg1MiwweDlCLDB4QkQsMHgxNywweEQ4LDB4Q0UsMHhDRiwweENDLDB4NDcsMHgxOCwweEIxLDB4N0ZdLFsweDYyLDB4NTYsMHg0QywweDczLDB4OEYsMHgzRSwweEZFLDB4MTgsMHg2RSwweDFBLDB4MTIsMHg3QSwweDBDLDB4NEQsMHgzQywweDYxXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4NjgsMHg2OSwweDZBLDB4NkIsMHg2RCwweDZFLDB4NkYsMHg3MCwweDcyLDB4NzMsMHg3NCwweDc1LDB4NzcsMHg3OCwweDc5LDB4N0EsMHg3QywweDdELDB4N0UsMHg3RiwweDgxLDB4ODIsMHg4MywweDg0XSxbMHgzMiwweERGLDB4OTksMHhCNCwweDMxLDB4RUQsMHg1RCwweEM1LDB4QUMsMHhGOCwweENBLDB4RjYsMHhEQywweDZDLDB4RTQsMHg3NV0sWzB4MDcsMHg4MCwweDVBLDB4QTAsMHg0MywweDk4LDB4NkUsMHhCMiwweDM2LDB4OTMsMHhFMiwweDNCLDB4RUYsMHg4RiwweDM0LDB4MzhdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHg4NiwweDg3LDB4ODgsMHg4OSwweDhCLDB4OEMsMHg4RCwweDhFLDB4OTAsMHg5MSwweDkyLDB4OTMsMHg5NSwweDk2LDB4OTcsMHg5OCwweDlBLDB4OUIsMHg5QywweDlELDB4OUYsMHhBMCwweEExLDB4QTJdLFsweDdGLDB4REMsMHgyQiwweDc0LDB4NkYsMHgzRiwweDY2LDB4NTIsMHg5NiwweDk0LDB4M0IsMHg4MywweDcxLDB4MEQsMHgxRiwweDgyXSxbMHhERiwweDBCLDB4NDksMHgzMSwweDAzLDB4OEIsMHhBRCwweEU4LDB4NDgsMHhERSwweEUzLDB4QjQsMHhCOCwweDVBLDB4QTQsMHg0Ql1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweEE0LDB4QTUsMHhBNiwweEE3LDB4QTksMHhBQSwweEFCLDB4QUMsMHhBRSwweEFGLDB4QjAsMHhCMSwweEIzLDB4QjQsMHhCNSwweEI2LDB4QjgsMHhCOSwweEJBLDB4QkIsMHhCRCwweEJFLDB4QkYsMHhDMF0sWzB4OEYsMHhCQSwweDE1LDB4MTAsMHhBMywweEM1LDB4QjgsMHg3RSwweDJFLDB4QUEsMHgzRiwweDdBLDB4OTEsMHg0NSwweDVDLDB4QTJdLFsweDU5LDB4MkQsMHg1RiwweERFLDB4RDcsMHg2NSwweDgyLDB4RTQsMHgxNCwweDNDLDB4NjUsMHgwOSwweDkzLDB4MDksMHg0NywweDdDXV1dO1xuICBcbiAgdmFyIHRlc3R2ZWN0b3JzMjU2ID0gW1tbMHgwMCwweDAxLDB4MDIsMHgwMywweDA1LDB4MDYsMHgwNywweDA4LDB4MEEsMHgwQiwweDBDLDB4MEQsMHgwRiwweDEwLDB4MTEsMHgxMiwweDE0LDB4MTUsMHgxNiwweDE3LDB4MTksMHgxQSwweDFCLDB4MUMsMHgxRSwweDFGLDB4MjAsMHgyMSwweDIzLDB4MjQsMHgyNSwweDI2XSxbMHg4MywweDRFLDB4QUQsMHhGQywweENBLDB4QzcsMHhFMSwweEIzLDB4MDYsMHg2NCwweEIxLDB4QUIsMHhBNCwweDQ4LDB4MTUsMHhBQl0sWzB4MTksMHg0NiwweERBLDB4QkYsMHg2QSwweDAzLDB4QTIsMHhBMiwweEMzLDB4RDAsMHhCMCwweDUwLDB4ODAsMHhBRSwweEQ2LDB4RkNdXSxcbiAgICAgICAgICAgICAgW1sweDI4LDB4MjksMHgyQSwweDJCLDB4MkQsMHgyRSwweDJGLDB4MzAsMHgzMiwweDMzLDB4MzQsMHgzNSwweDM3LDB4MzgsMHgzOSwweDNBLDB4M0MsMHgzRCwweDNFLDB4M0YsMHg0MSwweDQyLDB4NDMsMHg0NCwweDQ2LDB4NDcsMHg0OCwweDQ5LDB4NEIsMHg0QywweDRELDB4NEVdLFsweEQ5LDB4REMsMHg0RCwweEJBLDB4MzAsMHgyMSwweEIwLDB4NUQsMHg2NywweEMwLDB4NTEsMHg4RiwweDcyLDB4QjYsMHgyQiwweEYxXSxbMHg1RSwweEQzLDB4MDEsMHhENywweDQ3LDB4RDMsMHhDQywweDcxLDB4NTQsMHg0NSwweEVCLDB4REUsMHhDNiwweDJGLDB4MkYsMHhCNF1dLFxuICAgICAgICAgICAgICBbWzB4NTAsMHg1MSwweDUyLDB4NTMsMHg1NSwweDU2LDB4NTcsMHg1OCwweDVBLDB4NUIsMHg1QywweDVELDB4NUYsMHg2MCwweDYxLDB4NjIsMHg2NCwweDY1LDB4NjYsMHg2NywweDY5LDB4NkEsMHg2QiwweDZDLDB4NkUsMHg2RiwweDcwLDB4NzEsMHg3MywweDc0LDB4NzUsMHg3Nl0sWzB4QTIsMHg5MSwweEQ4LDB4NjMsMHgwMSwweEE0LDB4QTcsMHgzOSwweEY3LDB4MzksMHgyMSwweDczLDB4QUEsMHgzQywweDYwLDB4NENdLFsweDY1LDB4ODUsMHhDOCwweEY0LDB4M0QsMHgxMywweEE2LDB4QkUsMHhBQiwweDY0LDB4MTksMHhGQywweDU5LDB4MzUsMHhCOSwweEQwXV0sXG4gICAgICAgICAgICAgIFtbMHg3OCwweDc5LDB4N0EsMHg3QiwweDdELDB4N0UsMHg3RiwweDgwLDB4ODIsMHg4MywweDg0LDB4ODUsMHg4NywweDg4LDB4ODksMHg4QSwweDhDLDB4OEQsMHg4RSwweDhGLDB4OTEsMHg5MiwweDkzLDB4OTQsMHg5NiwweDk3LDB4OTgsMHg5OSwweDlCLDB4OUMsMHg5RCwweDlFXSxbMHg0MiwweDY0LDB4QjIsMHg2OSwweDY0LDB4OTgsMHhERSwweDRELDB4RjcsMHg5NywweDg4LDB4QTksMHhGOCwweDNFLDB4OTMsMHg5MF0sWzB4MkEsMHg1QiwweDU2LDB4QTUsMHg5NiwweDY4LDB4MEYsMHhDQywweDBFLDB4MDUsMHhGNSwweEUwLDB4RjEsMHg1MSwweEVDLDB4QUVdXSxcbiAgICAgICAgICAgICAgW1sweEEwLDB4QTEsMHhBMiwweEEzLDB4QTUsMHhBNiwweEE3LDB4QTgsMHhBQSwweEFCLDB4QUMsMHhBRCwweEFGLDB4QjAsMHhCMSwweEIyLDB4QjQsMHhCNSwweEI2LDB4QjcsMHhCOSwweEJBLDB4QkIsMHhCQywweEJFLDB4QkYsMHhDMCwweEMxLDB4QzMsMHhDNCwweEM1LDB4QzZdLFsweEVFLDB4OTksMHgzMiwweEIzLDB4NzIsMHgxOCwweDA0LDB4RDUsMHhBOCwweDNFLDB4RjUsMHg5NCwweDkyLDB4NDUsMHhCNiwweEY2XSxbMHhGNSwweEQ2LDB4RkYsMHg0MSwweDRGLDB4RDIsMHhDNiwweDE4LDB4MTQsMHg5NCwweEQyLDB4MEMsMHgzNywweEYyLDB4QjgsMHhDNF1dLFxuICAgICAgICAgICAgICBbWzB4QzgsMHhDOSwweENBLDB4Q0IsMHhDRCwweENFLDB4Q0YsMHhEMCwweEQyLDB4RDMsMHhENCwweEQ1LDB4RDcsMHhEOCwweEQ5LDB4REEsMHhEQywweERELDB4REUsMHhERiwweEUxLDB4RTIsMHhFMywweEU0LDB4RTYsMHhFNywweEU4LDB4RTksMHhFQiwweEVDLDB4RUQsMHhFRV0sWzB4RTYsMHgyNCwweDhGLDB4NTUsMHhDNSwweEZELDB4Q0IsMHhDQSwweDlDLDB4QkIsMHhCMCwweDFDLDB4ODgsMHhBMiwweEVBLDB4NzddLFsweDg1LDB4MzksMHg5QywweDAxLDB4RjUsMHg5RiwweEZGLDB4QjUsMHgyMCwweDRGLDB4MTksMHhGOCwweDQ4LDB4MkYsMHgwMCwweEI4XV0sXG4gICAgICAgICAgICAgIFtbMHhGMCwweEYxLDB4RjIsMHhGMywweEY1LDB4RjYsMHhGNywweEY4LDB4RkEsMHhGQiwweEZDLDB4RkQsMHhGRSwweDAxLDB4MDAsMHgwMiwweDA0LDB4MDUsMHgwNiwweDA3LDB4MDksMHgwQSwweDBCLDB4MEMsMHgwRSwweDBGLDB4MTAsMHgxMSwweDEzLDB4MTQsMHgxNSwweDE2XSxbMHhCOCwweDM1LDB4OEUsMHg0MSwweEI5LDB4REYsMHhGNiwweDVGLDB4RDQsMHg2MSwweEQ1LDB4NUEsMHg5OSwweDI2LDB4NjIsMHg0N10sWzB4OTIsMHgwOSwweDdCLDB4NEMsMHg4OCwweEEwLDB4NDEsMHhERCwweEY5LDB4ODEsMHg0NCwweEJDLDB4OEQsMHgyMiwweEU4LDB4RTddXSxcbiAgICAgICAgICAgICAgW1sweDE4LDB4MTksMHgxQSwweDFCLDB4MUQsMHgxRSwweDFGLDB4MjAsMHgyMiwweDIzLDB4MjQsMHgyNSwweDI3LDB4MjgsMHgyOSwweDJBLDB4MkMsMHgyRCwweDJFLDB4MkYsMHgzMSwweDMyLDB4MzMsMHgzNCwweDM2LDB4MzcsMHgzOCwweDM5LDB4M0IsMHgzQywweDNELDB4M0VdLFsweEYwLDB4RTIsMHhENywweDIyLDB4NjAsMHhBRiwweDU4LDB4RTIsMHgxRSwweDAxLDB4NUEsMHhCMywweEE0LDB4QzAsMHhEOSwweDA2XSxbMHg4OSwweEJELDB4NUIsMHg3MywweEIzLDB4NTYsMHhBQiwweDQxLDB4MkEsMHhFRiwweDlGLDB4NzYsMHhDRSwweEEyLDB4RDYsMHg1Q11dLFxuICAgICAgICAgICAgICBbWzB4NDAsMHg0MSwweDQyLDB4NDMsMHg0NSwweDQ2LDB4NDcsMHg0OCwweDRBLDB4NEIsMHg0QywweDRELDB4NEYsMHg1MCwweDUxLDB4NTIsMHg1NCwweDU1LDB4NTYsMHg1NywweDU5LDB4NUEsMHg1QiwweDVDLDB4NUUsMHg1RiwweDYwLDB4NjEsMHg2MywweDY0LDB4NjUsMHg2Nl0sWzB4NDcsMHg1QiwweDhCLDB4ODIsMHgzQywweEU4LDB4ODksMHgzRCwweEIzLDB4QzQsMHg0QSwweDlGLDB4MkEsMHgzNywweDlGLDB4RjddLFsweDI1LDB4MzYsMHg5NiwweDkwLDB4OTMsMHhDNSwweDVGLDB4RjksMHg0NSwweDQ2LDB4OTIsMHhGMiwweEZBLDB4QzIsMHhGNSwweDMwXV0sXG4gICAgICAgICAgICAgIFtbMHg2OCwweDY5LDB4NkEsMHg2QiwweDZELDB4NkUsMHg2RiwweDcwLDB4NzIsMHg3MywweDc0LDB4NzUsMHg3NywweDc4LDB4NzksMHg3QSwweDdDLDB4N0QsMHg3RSwweDdGLDB4ODEsMHg4MiwweDgzLDB4ODQsMHg4NiwweDg3LDB4ODgsMHg4OSwweDhCLDB4OEMsMHg4RCwweDhFXSxbMHg2OCwweDhGLDB4NTIsMHg4MSwweDk0LDB4NTgsMHgxMiwweDg2LDB4MkYsMHg1RiwweDMwLDB4NzYsMHhDRiwweDgwLDB4NDEsMHgyRl0sWzB4MDcsMHhGQywweDc2LDB4QTgsMHg3MiwweDg0LDB4M0YsMHgzRiwweDZFLDB4MDAsMHg4MSwweEVFLDB4OTMsMHg5NiwweEQ2LDB4MzddXSxcbiAgICAgICAgICAgICAgW1sweDkwLDB4OTEsMHg5MiwweDkzLDB4OTUsMHg5NiwweDk3LDB4OTgsMHg5QSwweDlCLDB4OUMsMHg5RCwweDlGLDB4QTAsMHhBMSwweEEyLDB4QTQsMHhBNSwweEE2LDB4QTcsMHhBOSwweEFBLDB4QUIsMHhBQywweEFFLDB4QUYsMHhCMCwweEIxLDB4QjMsMHhCNCwweEI1LDB4QjZdLFsweDA4LDB4RDEsMHhEMiwweEJDLDB4NzUsMHgwQSwweEY1LDB4NTMsMHgzNiwweDVELDB4MzUsMHhFNywweDVBLDB4RkEsMHhDRSwweEFBXSxbMHhFMywweDhCLDB4QTgsMHhFQywweDJBLDB4QTcsMHg0MSwweDM1LDB4OEQsMHhDQywweDkzLDB4RTgsMHhGMSwweDQxLDB4QzQsMHg5MV1dLFxuICAgICAgICAgICAgICBbWzB4QjgsMHhCOSwweEJBLDB4QkIsMHhCRCwweEJFLDB4QkYsMHhDMCwweEMyLDB4QzMsMHhDNCwweEM1LDB4QzcsMHhDOCwweEM5LDB4Q0EsMHhDQywweENELDB4Q0UsMHhDRiwweEQxLDB4RDIsMHhEMywweEQ0LDB4RDYsMHhENywweEQ4LDB4RDksMHhEQiwweERDLDB4REQsMHhERV0sWzB4ODcsMHgwNywweDEyLDB4MUYsMHg0NywweENDLDB4M0UsMHhGQywweEVDLDB4QTUsMHhGOSwweEE4LDB4NDcsMHg0OSwweDUwLDB4QTFdLFsweEQwLDB4MjgsMHhFRSwweDIzLDB4RTQsMHhBOCwweDkwLDB4NzUsMHhEMCwweEIwLDB4M0UsMHg4NiwweDhELDB4N0QsMHgzQSwweDQyXV0sXG4gICAgICAgICAgICAgIFtbMHhFMCwweEUxLDB4RTIsMHhFMywweEU1LDB4RTYsMHhFNywweEU4LDB4RUEsMHhFQiwweEVDLDB4RUQsMHhFRiwweEYwLDB4RjEsMHhGMiwweEY0LDB4RjUsMHhGNiwweEY3LDB4RjksMHhGQSwweEZCLDB4RkMsMHhGRSwweEZFLDB4MDEsMHgwMSwweDAzLDB4MDQsMHgwNSwweDA2XSxbMHhFNSwweDFBLDB4QTAsMHhCMSwweDM1LDB4REIsMHhBNSwweDY2LDB4OTMsMHg5QywweDNCLDB4NjMsMHg1OSwweEE5LDB4ODAsMHhDNV0sWzB4OEMsMHhEOSwweDQyLDB4M0QsMHhGQywweDQ1LDB4OUUsMHg1NCwweDcxLDB4NTUsMHhDNSwweEQxLDB4RDUsMHgyMiwweEU1LDB4NDBdXSxcbiAgICAgICAgICAgICAgW1sweDA4LDB4MDksMHgwQSwweDBCLDB4MEQsMHgwRSwweDBGLDB4MTAsMHgxMiwweDEzLDB4MTQsMHgxNSwweDE3LDB4MTgsMHgxOSwweDFBLDB4MUMsMHgxRCwweDFFLDB4MUYsMHgyMSwweDIyLDB4MjMsMHgyNCwweDI2LDB4MjcsMHgyOCwweDI5LDB4MkIsMHgyQywweDJELDB4MkVdLFsweDA2LDB4OUEsMHgwMCwweDdGLDB4QzcsMHg2QSwweDQ1LDB4OUYsMHg5OCwweEJBLDB4RjksMHgxNywweEZFLDB4REYsMHg5NSwweDIxXSxbMHgwOCwweDBFLDB4OTUsMHgxNywweEVCLDB4MTYsMHg3NywweDcxLDB4OUEsMHhDRiwweDcyLDB4ODAsMHg4NiwweDA0LDB4MEEsMHhFM11dLFxuICAgICAgICAgICAgICBbWzB4MzAsMHgzMSwweDMyLDB4MzMsMHgzNSwweDM2LDB4MzcsMHgzOCwweDNBLDB4M0IsMHgzQywweDNELDB4M0YsMHg0MCwweDQxLDB4NDIsMHg0NCwweDQ1LDB4NDYsMHg0NywweDQ5LDB4NEEsMHg0QiwweDRDLDB4NEUsMHg0RiwweDUwLDB4NTEsMHg1MywweDU0LDB4NTUsMHg1Nl0sWzB4NzIsMHg2MSwweDY1LDB4QzEsMHg3MiwweDNGLDB4QkMsMHhGNiwweEMwLDB4MjYsMHhENywweEQwLDB4MEIsMHgwOSwweDEwLDB4MjddLFsweDdDLDB4MTcsMHgwMCwweDIxLDB4MUEsMHgzOSwweDkxLDB4RkMsMHgwRSwweENELDB4RUQsMHgwQSwweEIzLDB4RTUsMHg3NiwweEIwXV1dO1xuXG4gIHZhciByZXMgPSB0cnVlO1xuICB2YXIgaiA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGVzdHZlY3RvcnMxMjgubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcmVzMiA9IHRlc3RfYWVzKHRlc3R2ZWN0b3JzMTI4W2ldWzFdLHRlc3R2ZWN0b3JzMTI4W2ldWzBdLHRlc3R2ZWN0b3JzMTI4W2ldWzJdKTtcbiAgICByZXMgJj0gcmVzMjtcbiAgICBpZiAoIXJlczIpIHtcbiAgICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3RpbmcgMTI4IGJpdCBrZXkgdmVjdG9yIHdpdGggYmxvY2sgXCIrXG4gICAgICAgIHV0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnMxMjhbaV1bMV0pK1xuICAgICAgICBcIiBhbmQga2V5IFwiK3V0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnMxMjhbaV1bMF0pK1xuICAgICAgICBcIiBzaG91bGQgYmUgXCIrdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczEyOFtpXVsyXSksXG4gICAgICAgIGZhbHNlKTtcbiAgICAgIGorKztcbiAgICB9XG4gIH1cbiAgaWYgKHJlcykge1xuICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIjEyOCBiaXQga2V5IHRlc3QgdmVjdG9ycyBjb21wbGV0ZWQuXCIsdHJ1ZSlcbiAgICBqKys7XG4gIH1cbiAgXG4gIHJlcyA9IHRydWU7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGVzdHZlY3RvcnMxOTIubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcmVzMiA9IHRlc3RfYWVzKHRlc3R2ZWN0b3JzMTkyW2ldWzFdLHRlc3R2ZWN0b3JzMTkyW2ldWzBdLHRlc3R2ZWN0b3JzMTkyW2ldWzJdKTtcbiAgICByZXMgJj0gcmVzMjtcbiAgICBpZiAoIXJlczIpIHtcbiAgICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3RpbmcgMTkyIGJpdCBrZXkgdmVjdG9yIHdpdGggYmxvY2sgXCIrXG4gICAgICAgIHV0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnMxOTJbaV1bMV0pK1xuICAgICAgICBcIiBhbmQga2V5IFwiK3V0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnMxOTJbaV1bMF0pK1xuICAgICAgICBcIiBzaG91bGQgYmUgXCIrdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczE5MltpXVsyXSksXG4gICAgICAgIGZhbHNlKTtcbiAgICAgIGorKztcbiAgICB9XG4gIH1cbiAgaWYgKHJlcykge1xuICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIjE5MiBiaXQga2V5IHRlc3QgdmVjdG9ycyBjb21wbGV0ZWQuXCIsdHJ1ZSlcbiAgICBqKys7XG4gIH1cblxuICByZXMgPSB0cnVlO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRlc3R2ZWN0b3JzMjU2Lmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHJlczIgPSB0ZXN0X2Flcyh0ZXN0dmVjdG9yczI1NltpXVsxXSx0ZXN0dmVjdG9yczI1NltpXVswXSx0ZXN0dmVjdG9yczI1NltpXVsyXSk7XG4gICAgcmVzICY9IHJlczI7XG4gICAgaWYgKCFyZXMyKSB7XG4gICAgICByZXN1bHRbal0gPSBuZXcgdW5pdC5yZXN1bHQoXCJUZXN0aW5nIDI1NiBiaXQga2V5IHZlY3RvciB3aXRoIGJsb2NrIFwiK1xuICAgICAgICB1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzMjU2W2ldWzFdKStcbiAgICAgICAgXCIgYW5kIGtleSBcIit1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzMjU2W2ldWzBdKStcbiAgICAgICAgXCIgc2hvdWxkIGJlIFwiK3V0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnMyNTZbaV1bMl0pLFxuICAgICAgICBmYWxzZSk7XG4gICAgICBqKys7XG4gICAgfVxuICB9XG4gIGlmIChyZXMpIHtcbiAgICByZXN1bHRbal0gPSBuZXcgdW5pdC5yZXN1bHQoXCIyNTYgYml0IGtleSB0ZXN0IHZlY3RvcnMgY29tcGxldGVkLlwiLCB0cnVlKVxuICAgIGorKztcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59KTtcbiIsInZhciB1bml0ID0gcmVxdWlyZSgnLi4vLi4vdW5pdC5qcycpO1xuXG51bml0LnJlZ2lzdGVyKFwiQmxvd2Zpc2ggY2lwaGVyIHRlc3Qgd2l0aCB0ZXN0IHZlY3RvcnMgZnJvbSBodHRwOi8vd3d3LnNjaG5laWVyLmNvbS9jb2RlL3ZlY3RvcnMudHh0XCIsIGZ1bmN0aW9uKCkge1xuICB2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLy4uLycpLFxuICAgIHV0aWwgPSBvcGVucGdwLnV0aWwsXG4gICAgQkZlbmNyeXB0ID0gb3BlbnBncC5jcnlwdG8uY2lwaGVyLmJsb3dmaXNoO1xuXG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZnVuY3Rpb24gdGVzdF9iZihpbnB1dCwga2V5LCBvdXRwdXQpIHtcbiAgICB2YXIgYmxvd2Zpc2ggPSBuZXcgb3BlbnBncC5jcnlwdG8uY2lwaGVyLmJsb3dmaXNoKHV0aWwuYmluMnN0cihrZXkpKTtcbiAgICB2YXIgcmVzdWx0ID0gdXRpbC5iaW4yc3RyKGJsb3dmaXNoLmVuY3J5cHQoaW5wdXQpKTtcblxuICAgIHJldHVybiAodXRpbC5oZXhzdHJkdW1wKHJlc3VsdCkgPT0gdXRpbC5oZXhzdHJkdW1wKHV0aWwuYmluMnN0cihvdXRwdXQpKSk7XG4gIH1cbiAgdmFyIHRlc3R2ZWN0b3JzID0gW1tbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg0RSwweEY5LDB4OTcsMHg0NSwweDYxLDB4OTgsMHhERCwweDc4XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRl0sWzB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRl0sWzB4NTEsMHg4NiwweDZGLDB4RDUsMHhCOCwweDVFLDB4Q0IsMHg4QV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDMwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDEwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDFdLFsweDdELDB4ODUsMHg2RiwweDlBLDB4NjEsMHgzMCwweDYzLDB4RjJdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExXSxbMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExXSxbMHgyNCwweDY2LDB4REQsMHg4NywweDhCLDB4OTYsMHgzQywweDlEXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDEsMHgyMywweDQ1LDB4NjcsMHg4OSwweEFCLDB4Q0QsMHhFRl0sWzB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMV0sWzB4NjEsMHhGOSwweEMzLDB4ODAsMHgyMiwweDgxLDB4QjAsMHg5Nl1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTFdLFsweDAxLDB4MjMsMHg0NSwweDY3LDB4ODksMHhBQiwweENELDB4RUZdLFsweDdELDB4MEMsMHhDNiwweDMwLDB4QUYsMHhEQSwweDFFLDB4QzddXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg0RSwweEY5LDB4OTcsMHg0NSwweDYxLDB4OTgsMHhERCwweDc4XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4RkUsMHhEQywweEJBLDB4OTgsMHg3NiwweDU0LDB4MzIsMHgxMF0sWzB4MDEsMHgyMywweDQ1LDB4NjcsMHg4OSwweEFCLDB4Q0QsMHhFRl0sWzB4MEEsMHhDRSwweEFCLDB4MEYsMHhDNiwweEEwLDB4QTIsMHg4RF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDdDLDB4QTEsMHgxMCwweDQ1LDB4NEEsMHgxQSwweDZFLDB4NTddLFsweDAxLDB4QTEsMHhENiwweEQwLDB4MzksMHg3NywweDY3LDB4NDJdLFsweDU5LDB4QzYsMHg4MiwweDQ1LDB4RUIsMHgwNSwweDI4LDB4MkJdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMSwweDMxLDB4RDksMHg2MSwweDlELDB4QzEsMHgzNywweDZFXSxbMHg1QywweEQ1LDB4NEMsMHhBOCwweDNELDB4RUYsMHg1NywweERBXSxbMHhCMSwweEI4LDB4Q0MsMHgwQiwweDI1LDB4MEYsMHgwOSwweEEwXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDcsMHhBMSwweDEzLDB4M0UsMHg0QSwweDBCLDB4MjYsMHg4Nl0sWzB4MDIsMHg0OCwweEQ0LDB4MzgsMHgwNiwweEY2LDB4NzEsMHg3Ml0sWzB4MTcsMHgzMCwweEU1LDB4NzcsMHg4QiwweEVBLDB4MUQsMHhBNF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDM4LDB4NDksMHg2NywweDRDLDB4MjYsMHgwMiwweDMxLDB4OUVdLFsweDUxLDB4NDUsMHg0QiwweDU4LDB4MkQsMHhERiwweDQ0LDB4MEFdLFsweEEyLDB4NUUsMHg3OCwweDU2LDB4Q0YsMHgyNiwweDUxLDB4RUJdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwNCwweEI5LDB4MTUsMHhCQSwweDQzLDB4RkUsMHhCNSwweEI2XSxbMHg0MiwweEZELDB4NDQsMHgzMCwweDU5LDB4NTcsMHg3RiwweEEyXSxbMHgzNSwweDM4LDB4ODIsMHhCMSwweDA5LDB4Q0UsMHg4RiwweDFBXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDEsMHgxMywweEI5LDB4NzAsMHhGRCwweDM0LDB4RjIsMHhDRV0sWzB4MDUsMHg5QiwweDVFLDB4MDgsMHg1MSwweENGLDB4MTQsMHgzQV0sWzB4NDgsMHhGNCwweEQwLDB4ODgsMHg0QywweDM3LDB4OTksMHgxOF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAxLDB4NzAsMHhGMSwweDc1LDB4NDYsMHg4RiwweEI1LDB4RTZdLFsweDA3LDB4NTYsMHhEOCwweEUwLDB4NzcsMHg0NywweDYxLDB4RDJdLFsweDQzLDB4MjEsMHg5MywweEI3LDB4ODksMHg1MSwweEZDLDB4OThdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHg0MywweDI5LDB4N0YsMHhBRCwweDM4LDB4RTMsMHg3MywweEZFXSxbMHg3NiwweDI1LDB4MTQsMHhCOCwweDI5LDB4QkYsMHg0OCwweDZBXSxbMHgxMywweEYwLDB4NDEsMHg1NCwweEQ2LDB4OUQsMHgxQSwweEU1XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDcsMHhBNywweDEzLDB4NzAsMHg0NSwweERBLDB4MkEsMHgxNl0sWzB4M0IsMHhERCwweDExLDB4OTAsMHg0OSwweDM3LDB4MjgsMHgwMl0sWzB4MkUsMHhFRCwweERBLDB4OTMsMHhGRiwweEQzLDB4OUMsMHg3OV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDA0LDB4NjgsMHg5MSwweDA0LDB4QzIsMHhGRCwweDNCLDB4MkZdLFsweDI2LDB4OTUsMHg1RiwweDY4LDB4MzUsMHhBRiwweDYwLDB4OUFdLFsweEQ4LDB4ODcsMHhFMCwweDM5LDB4M0MsMHgyRCwweEE2LDB4RTNdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgzNywweEQwLDB4NkIsMHhCNSwweDE2LDB4Q0IsMHg3NSwweDQ2XSxbMHgxNiwweDRELDB4NUUsMHg0MCwweDRGLDB4MjcsMHg1MiwweDMyXSxbMHg1RiwweDk5LDB4RDAsMHg0RiwweDVCLDB4MTYsMHgzOSwweDY5XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MUYsMHgwOCwweDI2LDB4MEQsMHgxQSwweEMyLDB4NDYsMHg1RV0sWzB4NkIsMHgwNSwweDZFLDB4MTgsMHg3NSwweDlGLDB4NUMsMHhDQV0sWzB4NEEsMHgwNSwweDdBLDB4M0IsMHgyNCwweEQzLDB4OTcsMHg3Ql1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDU4LDB4NDAsMHgyMywweDY0LDB4MUEsMHhCQSwweDYxLDB4NzZdLFsweDAwLDB4NEIsMHhENiwweEVGLDB4MDksMHgxNywweDYwLDB4NjJdLFsweDQ1LDB4MjAsMHgzMSwweEMxLDB4RTQsMHhGQSwweERBLDB4OEVdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMiwweDU4LDB4MTYsMHgxNiwweDQ2LDB4MjksMHhCMCwweDA3XSxbMHg0OCwweDBELDB4MzksMHgwMCwweDZFLDB4RTcsMHg2MiwweEYyXSxbMHg3NSwweDU1LDB4QUUsMHgzOSwweEY1LDB4OUIsMHg4NywweEJEXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4NDksMHg3OSwweDNFLDB4QkMsMHg3OSwweEIzLDB4MjUsMHg4Rl0sWzB4NDMsMHg3NSwweDQwLDB4QzgsMHg2OSwweDhGLDB4M0MsMHhGQV0sWzB4NTMsMHhDNSwweDVGLDB4OUMsMHhCNCwweDlGLDB4QzAsMHgxOV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDRGLDB4QjAsMHg1RSwweDE1LDB4MTUsMHhBQiwweDczLDB4QTddLFsweDA3LDB4MkQsMHg0MywweEEwLDB4NzcsMHgwNywweDUyLDB4OTJdLFsweDdBLDB4OEUsMHg3QiwweEZBLDB4OTMsMHg3RSwweDg5LDB4QTNdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHg0OSwweEU5LDB4NUQsMHg2RCwweDRDLDB4QTIsMHgyOSwweEJGXSxbMHgwMiwweEZFLDB4NTUsMHg3NywweDgxLDB4MTcsMHhGMSwweDJBXSxbMHhDRiwweDlDLDB4NUQsMHg3QSwweDQ5LDB4ODYsMHhBRCwweEI1XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDEsMHg4MywweDEwLDB4REMsMHg0MCwweDlCLDB4MjYsMHhENl0sWzB4MUQsMHg5RCwweDVDLDB4NTAsMHgxOCwweEY3LDB4MjgsMHhDMl0sWzB4RDEsMHhBQiwweEIyLDB4OTAsMHg2NSwweDhCLDB4QzcsMHg3OF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDFDLDB4NTgsMHg3RiwweDFDLDB4MTMsMHg5MiwweDRGLDB4RUZdLFsweDMwLDB4NTUsMHgzMiwweDI4LDB4NkQsMHg2RiwweDI5LDB4NUFdLFsweDU1LDB4Q0IsMHgzNywweDc0LDB4RDEsMHgzRSwweEYyLDB4MDFdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMSwweDAxLDB4MDEsMHgwMSwweDAxLDB4MDEsMHgwMSwweDAxXSxbMHgwMSwweDIzLDB4NDUsMHg2NywweDg5LDB4QUIsMHhDRCwweEVGXSxbMHhGQSwweDM0LDB4RUMsMHg0OCwweDQ3LDB4QjIsMHg2OCwweEIyXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MUYsMHgxRiwweDFGLDB4MUYsMHgwRSwweDBFLDB4MEUsMHgwRV0sWzB4MDEsMHgyMywweDQ1LDB4NjcsMHg4OSwweEFCLDB4Q0QsMHhFRl0sWzB4QTcsMHg5MCwweDc5LDB4NTEsMHgwOCwweEVBLDB4M0MsMHhBRV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweEUwLDB4RkUsMHhFMCwweEZFLDB4RjEsMHhGRSwweEYxLDB4RkVdLFsweDAxLDB4MjMsMHg0NSwweDY3LDB4ODksMHhBQiwweENELDB4RUZdLFsweEMzLDB4OUUsMHgwNywweDJELDB4OUYsMHhBQywweDYzLDB4MURdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGXSxbMHgwMSwweDQ5LDB4MzMsMHhFMCwweENELDB4QUYsMHhGNiwweEU0XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRl0sWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RjIsMHgxRSwweDlBLDB4NzcsMHhCNywweDFDLDB4NDksMHhCQ11dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAxLDB4MjMsMHg0NSwweDY3LDB4ODksMHhBQiwweENELDB4RUZdLFsweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDI0LDB4NTksMHg0NiwweDg4LDB4NTcsMHg1NCwweDM2LDB4OUFdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHhGRSwweERDLDB4QkEsMHg5OCwweDc2LDB4NTQsMHgzMiwweDEwXSxbMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGXSxbMHg2QiwweDVDLDB4NUEsMHg5QywweDVELDB4OUUsMHgwQSwweDVBXV1dO1xuXG4gIHZhciByZXMgPSB0cnVlO1xuICB2YXIgaiA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGVzdHZlY3RvcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcmVzMiA9IHRlc3RfYmYodGVzdHZlY3RvcnNbaV1bMV0sdGVzdHZlY3RvcnNbaV1bMF0sdGVzdHZlY3RvcnNbaV1bMl0pO1xuICAgIHJlcyAmPSByZXMyO1xuICAgIGlmICghcmVzMikge1xuICAgICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyB2ZWN0b3IgXCIraStcIiB3aXRoIGJsb2NrIFwiK1xuICAgICAgICB1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzW2ldWzBdKStcbiAgICAgICAgXCIgYW5kIGtleSBcIit1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzW2ldWzFdKStcbiAgICAgICAgXCIgc2hvdWxkIGJlIFwiK3V0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnNbaV1bMl0pLCBmYWxzZSk7XG4gICAgICBqKys7XG4gICAgfVxuICB9XG4gIGlmIChyZXMpIHtcbiAgICByZXN1bHRbal0gPSBuZXcgdW5pdC5yZXN1bHQoXCIzNCB0ZXN0IHZlY3RvcnMgY29tcGxldGVkIFwiLCB0cnVlKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uLy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIkNBU1QtMTI4IGNpcGhlciB0ZXN0IHdpdGggdGVzdCB2ZWN0b3JzIGZyb20gUkZDMjE0NFwiLCBmdW5jdGlvbigpIHtcblx0dmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8uLi8nKSxcblx0XHR1dGlsID0gb3BlbnBncC51dGlsO1xuXG5cdHZhciByZXN1bHQgPSBbXTtcblx0ZnVuY3Rpb24gdGVzdF9jYXN0KGlucHV0LCBrZXksIG91dHB1dCkge1xuXHRcdHZhciBjYXN0NSA9IG5ldyBvcGVucGdwLmNyeXB0by5jaXBoZXIuY2FzdDUodXRpbC5iaW4yc3RyKGtleSkpO1xuXHRcdHZhciByZXN1bHQgPSB1dGlsLmJpbjJzdHIoY2FzdDUuZW5jcnlwdChpbnB1dCkpO1xuXG5cdFx0cmV0dXJuIHV0aWwuaGV4c3RyZHVtcChyZXN1bHQpID09IHV0aWwuaGV4c3RyZHVtcCh1dGlsLmJpbjJzdHIob3V0cHV0KSk7XG5cdH1cblx0XG5cdHZhciB0ZXN0dmVjdG9ycyA9IFtbWzB4MDEsMHgyMywweDQ1LDB4NjcsMHgxMiwweDM0LDB4NTYsMHg3OCwweDIzLDB4NDUsMHg2NywweDg5LDB4MzQsMHg1NiwweDc4LDB4OUFdLFsweDAxLDB4MjMsMHg0NSwweDY3LDB4ODksMHhBQiwweENELDB4RUZdLFsweDIzLDB4OEIsMHg0RiwweEU1LDB4ODQsMHg3RSwweDQ0LDB4QjJdXV07XG5cblx0Zm9yICh2YXIgaSA9IDA7IGkgPCB0ZXN0dmVjdG9ycy5sZW5ndGg7IGkrKykge1xuXHRcdHJlc3VsdFtpXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3RpbmcgdmVjdG9yIHdpdGggYmxvY2sgXCIrXG5cdFx0XHRcdHV0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnNbaV1bMF0pK1xuXHRcdFx0XHRcIiBhbmQga2V5IFwiK3V0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnNbaV1bMV0pK1xuXHRcdFx0XHRcIiBzaG91bGQgYmUgXCIrdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yc1tpXVsyXSksXG5cdFx0XHR0ZXN0X2Nhc3QodGVzdHZlY3RvcnNbaV1bMV0sdGVzdHZlY3RvcnNbaV1bMF0sdGVzdHZlY3RvcnNbaV1bMl0pKTtcblx0fVxuXHRyZXR1cm4gcmVzdWx0O1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uLy4uL3VuaXQuanMnKTtcclxuXHJcbnVuaXQucmVnaXN0ZXIoXCJUcmlwbGVERVMgKEVERSkgY2lwaGVyIHRlc3Qgd2l0aCB0ZXN0IHZlY3RvcnMgZnJvbSBodHRwOi8vY3NyYy5uaXN0Lmdvdi9wdWJsaWNhdGlvbnMvbmlzdHB1YnMvODAwLTIwLzgwMC0yMC5wZGZcIiwgZnVuY3Rpb24oKSB7XHJcbiAgdmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8uLi8nKSxcclxuICAgIHV0aWwgPSBvcGVucGdwLnV0aWw7XHJcblxyXG4gIHZhciByZXN1bHQgPSBbXTtcclxuICB2YXIga2V5ID0gdXRpbC5iaW4yc3RyKFsxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMV0pO1xyXG4gIHZhciB0ZXN0dmVjdG9ycyA9IFtbWzB4ODAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4OTUsMHhGOCwweEE1LDB4RTUsMHhERCwweDMxLDB4RDksMHgwMF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4NDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4REQsMHg3RiwweDEyLDB4MUMsMHhBNSwweDAxLDB4NTYsMHgxOV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MjAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4MkUsMHg4NiwweDUzLDB4MTAsMHg0RiwweDM4LDB4MzQsMHhFQV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MTAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4NEIsMHhEMywweDg4LDB4RkYsMHg2QywweEQ4LDB4MUQsMHg0Rl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDgsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4MjAsMHhCOSwweEU3LDB4NjcsMHhCMiwweEZCLDB4MTQsMHg1Nl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDQsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4NTUsMHg1NywweDkzLDB4ODAsMHhENywweDcxLDB4MzgsMHhFRl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDIsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4NkMsMHhDNSwweERFLDB4RkEsMHhBRiwweDA0LDB4NTEsMHgyRl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDEsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4MEQsMHg5RiwweDI3LDB4OUIsMHhBNSwweEQ4LDB4NzIsMHg2MF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHg4MCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RDksMHgwMywweDFCLDB4MDIsMHg3MSwweEJELDB4NUEsMHgwQV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHg0MCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4NDIsMHg0MiwweDUwLDB4QjMsMHg3QywweDNELDB4RDksMHg1MV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgyMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4QjgsMHgwNiwweDFCLDB4N0UsMHhDRCwweDlBLDB4MjEsMHhFNV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgxMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RjEsMHg1RCwweDBGLDB4MjgsMHg2QiwweDY1LDB4QkQsMHgyOF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwOCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4QUQsMHhEMCwweENDLDB4OEQsMHg2RSwweDVELDB4RUIsMHhBMV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwNCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RTYsMHhENSwweEY4LDB4MjcsMHg1MiwweEFELDB4NjMsMHhEMV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMiwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RUMsMHhCRiwweEUzLDB4QkQsMHgzRiwweDU5LDB4MUEsMHg1RV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMSwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RjMsMHg1NiwweDgzLDB4NDMsMHg3OSwweEQxLDB4NjUsMHhDRF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDgwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4MkIsMHg5RiwweDk4LDB4MkYsMHgyMCwweDAzLDB4N0YsMHhBOV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDQwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4ODgsMHg5RCwweEUwLDB4NjgsMHhBMSwweDZGLDB4MEIsMHhFNl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDIwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RTEsMHg5RSwweDI3LDB4NUQsMHg4NCwweDZBLDB4MTIsMHg5OF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDEwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4MzIsMHg5QSwweDhFLDB4RDUsMHgyMywweEQ3LDB4MUEsMHhFQ11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDA4LDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RTcsMHhGQywweEUyLDB4MjUsMHg1NywweEQyLDB4M0MsMHg5N11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDA0LDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4MTIsMHhBOSwweEY1LDB4ODEsMHg3RiwweEYyLDB4RDYsMHg1RF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAyLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4QTQsMHg4NCwweEMzLDB4QUQsMHgzOCwweERDLDB4OUMsMHgxOV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAxLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RkIsMHhFMCwweDBBLDB4OEEsMHgxRSwweEY4LDB4QUQsMHg3Ml1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4ODAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4NzUsMHgwRCwweDA3LDB4OTQsMHgwNywweDUyLDB4MTMsMHg2M11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4NDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4NjQsMHhGRSwweEVELDB4OUMsMHg3MiwweDRDLDB4MkYsMHhBRl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MjAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RjAsMHgyQiwweDI2LDB4M0IsMHgzMiwweDhFLDB4MkIsMHg2MF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MTAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4OUQsMHg2NCwweDU1LDB4NUEsMHg5QSwweDEwLDB4QjgsMHg1Ml1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDgsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RDEsMHgwNiwweEZGLDB4MEIsMHhFRCwweDUyLDB4NTUsMHhEN11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDQsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RTEsMHg2NSwweDJDLDB4NkIsMHgxMywweDhDLDB4NjQsMHhBNV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDIsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RTQsMHgyOCwweDU4LDB4MTEsMHg4NiwweEVDLDB4OEYsMHg0Nl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDEsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4QUUsMHhCNSwweEY1LDB4RUQsMHhFMiwweDJELDB4MUEsMHgzNl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHg4MCwweDAwLDB4MDAsMHgwMF0sWzB4RTksMHg0MywweEQ3LDB4NTYsMHg4QSwweEVDLDB4MEMsMHg1Q11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHg0MCwweDAwLDB4MDAsMHgwMF0sWzB4REYsMHg5OCwweEM4LDB4MjcsMHg2RiwweDU0LDB4QjAsMHg0Ql1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgyMCwweDAwLDB4MDAsMHgwMF0sWzB4QjEsMHg2MCwweEU0LDB4NjgsMHgwRiwweDZDLDB4NjksMHg2Rl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgxMCwweDAwLDB4MDAsMHgwMF0sWzB4RkEsMHgwNywweDUyLDB4QjAsMHg3RCwweDlDLDB4NEEsMHhCOF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwOCwweDAwLDB4MDAsMHgwMF0sWzB4Q0EsMHgzQSwweDJCLDB4MDMsMHg2RCwweEJDLDB4ODUsMHgwMl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwNCwweDAwLDB4MDAsMHgwMF0sWzB4NUUsMHgwOSwweDA1LDB4NTEsMHg3QiwweEI1LDB4OUIsMHhDRl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMiwweDAwLDB4MDAsMHgwMF0sWzB4ODEsMHg0RSwweEVCLDB4M0IsMHg5MSwweEQ5LDB4MDcsMHgyNl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMSwweDAwLDB4MDAsMHgwMF0sWzB4NEQsMHg0OSwweERCLDB4MTUsMHgzMiwweDkxLDB4OUMsMHg5Rl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDgwLDB4MDAsMHgwMF0sWzB4MjUsMHhFQiwweDVGLDB4QzMsMHhGOCwweENGLDB4MDYsMHgyMV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDQwLDB4MDAsMHgwMF0sWzB4QUIsMHg2QSwweDIwLDB4QzAsMHg2MiwweDBELDB4MUMsMHg2Rl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDIwLDB4MDAsMHgwMF0sWzB4NzksMHhFOSwweDBELDB4QkMsMHg5OCwweEY5LDB4MkMsMHhDQV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDEwLDB4MDAsMHgwMF0sWzB4ODYsMHg2RSwweENFLDB4REQsMHg4MCwweDcyLDB4QkIsMHgwRV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDA4LDB4MDAsMHgwMF0sWzB4OEIsMHg1NCwweDUzLDB4NkYsMHgyRiwweDNFLDB4NjQsMHhBOF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDA0LDB4MDAsMHgwMF0sWzB4RUEsMHg1MSwweEQzLDB4OTcsMHg1NSwweDk1LDB4QjgsMHg2Ql1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAyLDB4MDAsMHgwMF0sWzB4Q0EsMHhGRiwweEM2LDB4QUMsMHg0NSwweDQyLDB4REUsMHgzMV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAxLDB4MDAsMHgwMF0sWzB4OEQsMHhENCwweDVBLDB4MkQsMHhERiwweDkwLDB4NzksMHg2Q11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4ODAsMHgwMF0sWzB4MTAsMHgyOSwweEQ1LDB4NUUsMHg4OCwweDBFLDB4QzIsMHhEMF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4NDAsMHgwMF0sWzB4NUQsMHg4NiwweENCLDB4MjMsMHg2MywweDlELDB4QkUsMHhBOV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MjAsMHgwMF0sWzB4MUQsMHgxQywweEE4LDB4NTMsMHhBRSwweDdDLDB4MEMsMHg1Rl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MTAsMHgwMF0sWzB4Q0UsMHgzMywweDIzLDB4MjksMHgyNCwweDhGLDB4MzIsMHgyOF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDgsMHgwMF0sWzB4ODQsMHgwNSwweEQxLDB4QUIsMHhFMiwweDRGLDB4QjksMHg0Ml1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDQsMHgwMF0sWzB4RTYsMHg0MywweEQ3LDB4ODAsMHg5MCwweENBLDB4NDIsMHgwN11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDIsMHgwMF0sWzB4NDgsMHgyMiwweDFCLDB4OTksMHgzNywweDc0LDB4OEEsMHgyM11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDEsMHgwMF0sWzB4REQsMHg3QywweDBCLDB4QkQsMHg2MSwweEZBLDB4RkQsMHg1NF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHg4MF0sWzB4MkYsMHhCQywweDI5LDB4MUEsMHg1NywweDBELDB4QjUsMHhDNF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHg0MF0sWzB4RTAsMHg3QywweDMwLDB4RDcsMHhFNCwweEUyLDB4NkUsMHgxMl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgyMF0sWzB4MDksMHg1MywweEUyLDB4MjUsMHg4RSwweDhFLDB4OTAsMHhBMV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgxMF0sWzB4NUIsMHg3MSwweDFCLDB4QzQsMHhDRSwweEVCLDB4RjIsMHhFRV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwOF0sWzB4Q0MsMHgwOCwweDNGLDB4MUUsMHg2RCwweDlFLDB4ODUsMHhGNl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwNF0sWzB4RDIsMHhGRCwweDg4LDB4NjcsMHhENSwweDBELDB4MkQsMHhGRV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMl0sWzB4MDYsMHhFNywweEVBLDB4MjIsMHhDRSwweDkyLDB4NzAsMHg4Rl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMV0sWzB4MTYsMHg2QiwweDQwLDB4QjQsMHg0QSwweEJBLDB4NEIsMHhENl1dXTtcclxuXHJcbiAgdmFyIHJlcyA9IHRydWU7XHJcbiAgdmFyIGogPSAwO1xyXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGVzdHZlY3RvcnMubGVuZ3RoOyBpKyspIHtcclxuICAgIHZhciBkZXMgPSBuZXcgb3BlbnBncC5jcnlwdG8uY2lwaGVyLmRlcyhrZXkpO1xyXG5cclxuICAgIHZhciBlbmNyID0gdXRpbC5iaW4yc3RyKGRlcy5lbmNyeXB0KHRlc3R2ZWN0b3JzW2ldWzBdLCBrZXkpKTtcclxuICAgIHZhciByZXMyID0gZW5jciA9PSB1dGlsLmJpbjJzdHIodGVzdHZlY3RvcnNbaV1bMV0pO1xyXG5cclxuICAgIHJlcyAmPSByZXMyO1xyXG5cclxuICAgIGlmICghcmVzMikge1xyXG4gICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyB2ZWN0b3Igd2l0aCBibG9jayBcIiArXHJcbiAgICAgICAgdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yc1tpXVswXSkgK1xyXG4gICAgICAgIFwiIGFuZCBrZXkgXCIgKyB1dGlsLmhleHN0cmR1bXAoa2V5KSArXHJcbiAgICAgICAgXCIgc2hvdWxkIGJlIFwiICsgdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yc1tpXVsxXSkgKyBcIiAhPSBcIiArXHJcbiAgICAgICAgdXRpbC5oZXhpZHVtcChlbmNyKSxcclxuICAgICAgZmFsc2UpO1xyXG4gICAgaisrO1xyXG4gICAgfVxyXG4gIH1cclxuICBpZiAocmVzKSB7XHJcbiAgICByZXN1bHRbal0gPSBuZXcgdW5pdC5yZXN1bHQoXCJBbGwgM0RFUyBFREUgdGVzdCB2ZWN0b3JzIGNvbXBsZXRlZFwiLCB0cnVlKTtcclxuICB9XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufSk7XHJcblxyXG5cclxudW5pdC5yZWdpc3RlcihcIkRFUyBlbmNyeXB0L2RlY3J5cHQgcGFkZGluZyB0ZXN0c1wiLCBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLy4uLycpLFxyXG4gICAgICB1dGlsID0gb3BlbnBncC51dGlsO1xyXG5cclxuICAgIHZhciByZXN1bHQgPSBbXTtcclxuICAgIHZhciBrZXkgPSB1dGlsLmJpbjJzdHIoWzB4MDEsIDB4MjMsIDB4NDUsIDB4NjcsIDB4ODksIDB4QUIsIDB4Q0QsIDB4RUZdKTtcclxuICAgIHZhciB0ZXN0dmVjdG9ycyA9IG5ldyBBcnJheSgpO1xyXG4gICAgdGVzdHZlY3RvcnNbMF0gPSBbW1sweDAxXSwgWzB4MjQsIDB4QzcsIDB4NEEsIDB4OUEsIDB4NzksIDB4NzUsIDB4NEIsIDB4QzddXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDIsIDB4MDNdLCBbMHhBNywgMHg3QSwgMHg5QSwgMHg1OSwgMHg4QSwgMHg4NiwgMHg4NSwgMHhDNV1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwMywgMHgwNCwgMHgwNV0sIFsweDAxLCAweENGLCAweEVCLCAweDZBLCAweDc0LCAweDYwLCAweEY1LCAweDAyXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA0LCAweDA1LCAweDA2LCAweDA3XSwgWzB4QTgsIDB4RjAsIDB4M0QsIDB4NTksIDB4QkEsIDB4NkIsIDB4MEUsIDB4NzZdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDUsIDB4MDYsIDB4MDcsIDB4MDgsIDB4MDldLCBbMHg4NiwgMHg0MCwgMHgzMywgMHg2MSwgMHgzRiwgMHg1NSwgMHg3MywgMHg0OV1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNiwgMHgwNywgMHgwOCwgMHgwOSwgMHgwQSwgMHgwQl0sIFsweDEzLCAweDIxLCAweDNFLCAweDBFLCAweENFLCAweDJDLCAweDk0LCAweDAxXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA3LCAweDA4LCAweDA5LCAweDBBLCAweDBCLCAweDBDLCAweDBEXSwgWzB4MzAsIDB4NDksIDB4OTcsIDB4QzEsIDB4REEsIDB4RDUsIDB4NTksIDB4QTVdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDgsIDB4MDksIDB4MEEsIDB4MEIsIDB4MEMsIDB4MEQsIDB4MEUsIDB4MEZdLCBbMHg4MywgMHgyNSwgMHg3OSwgMHgwNiwgMHg1NCwgMHhBNCwgMHg0NCwgMHhEOV1dXTtcclxuICAgIHRlc3R2ZWN0b3JzWzFdID0gW1tbMHgwMV0sIFsweEYyLCAweEFCLCAweDFDLCAweDlFLCAweDcwLCAweDdELCAweENDLCAweDkyXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDAyLCAweDAzXSwgWzB4NkIsIDB4NEMsIDB4NjcsIDB4MjQsIDB4OUYsIDB4QjcsIDB4NEQsIDB4QUNdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDMsIDB4MDQsIDB4MDVdLCBbMHg2OCwgMHg5NSwgMHhBQiwgMHhBOCwgMHhFQSwgMHg1MywgMHgxMywgMHgyM11dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNCwgMHgwNSwgMHgwNiwgMHgwN10sIFsweEM4LCAweERFLCAweDYwLCAweDhGLCAweEY2LCAweDA5LCAweDkwLCAweEI1XV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA1LCAweDA2LCAweDA3LCAweDA4LCAweDA5XSwgWzB4MTksIDB4MTMsIDB4NTAsIDB4MjAsIDB4NzAsIDB4NDAsIDB4MkUsIDB4MDldXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDYsIDB4MDcsIDB4MDgsIDB4MDksIDB4MEEsIDB4MEJdLCBbMHhBOCwgMHgyMywgMHg0MCwgMHhDNiwgMHgxNywgMHhBNiwgMHgzMSwgMHg0QV1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNywgMHgwOCwgMHgwOSwgMHgwQSwgMHgwQiwgMHgwQywgMHgwRF0sIFsweDM2LCAweDYyLCAweEYyLCAweDk5LCAweDY4LCAweEQ0LCAweEJGLCAweDdDXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA4LCAweDA5LCAweDBBLCAweDBCLCAweDBDLCAweDBELCAweDBFLCAweDBGXSwgWzB4ODMsIDB4MjUsIDB4NzksIDB4MDYsIDB4NTQsIDB4QTQsIDB4NDQsIDB4RDksIDB4MDgsIDB4NkYsIDB4OUEsIDB4MUQsIDB4NzQsIDB4QzksIDB4NEQsIDB4NEVdXV07XHJcbiAgICB0ZXN0dmVjdG9yc1syXSA9IFtbWzB4MDFdLCBbMHg4MywgMHg2OCwgMHhFNCwgMHg5QywgMHg4NCwgMHhDQywgMHhDQiwgMHhGMF1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwMiwgMHgwM10sIFsweEJCLCAweEE4LCAweDBCLCAweDY2LCAweDFCLCAweDYyLCAweEM0LCAweEM4XV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDAzLCAweDA0LCAweDA1XSwgWzB4OUEsIDB4RDcsIDB4NUEsIDB4MjQsIDB4RkQsIDB4M0YsIDB4QkYsIDB4MjJdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDQsIDB4MDUsIDB4MDYsIDB4MDddLCBbMHgxNCwgMHg0RSwgMHg2OCwgMHg2RCwgMHgyRSwgMHhDMSwgMHhCNywgMHg1Ml1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNSwgMHgwNiwgMHgwNywgMHgwOCwgMHgwOV0sIFsweDEyLCAweDBBLCAweDUxLCAweDA4LCAweEY5LCAweEEzLCAweDAzLCAweDc0XV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA2LCAweDA3LCAweDA4LCAweDA5LCAweDBBLCAweDBCXSwgWzB4QjIsIDB4MDcsIDB4RDEsIDB4MDUsIDB4RjYsIDB4NjcsIDB4QUYsIDB4QkFdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDcsIDB4MDgsIDB4MDksIDB4MEEsIDB4MEIsIDB4MEMsIDB4MERdLCBbMHhDQSwgMHg1OSwgMHg2MSwgMHgzQSwgMHg4MywgMHgyMywgMHgyNiwgMHhERF1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwOCwgMHgwOSwgMHgwQSwgMHgwQiwgMHgwQywgMHgwRCwgMHgwRSwgMHgwRl0sIFsweDgzLCAweDI1LCAweDc5LCAweDA2LCAweDU0LCAweEE0LCAweDQ0LCAweEQ5XV1dO1xyXG5cclxuICAgIHZhciBkZXMgPSBuZXcgb3BlbnBncC5jcnlwdG8uY2lwaGVyLm9yaWdpbmFsRGVzKGtleSk7XHJcblxyXG4gICAgdmFyIHJlcyA9IHRydWU7XHJcbiAgICB2YXIgaiA9IDA7XHJcblxyXG4gICAgZm9yICh2YXIgcGFkZGluZyA9IDA7IHBhZGRpbmcgPCAzOyBwYWRkaW5nKyspIHtcclxuICAgICAgICB2YXIgdGhpc1ZlY3RvclNldCA9IHRlc3R2ZWN0b3JzW3BhZGRpbmddO1xyXG5cclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXNWZWN0b3JTZXQubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgdmFyIGVuY3J5cHRlZCA9IGRlcy5lbmNyeXB0KHRoaXNWZWN0b3JTZXRbaV1bMF0sIHBhZGRpbmcpO1xyXG4gICAgICAgICAgICB2YXIgZGVjcnlwdGVkID0gZGVzLmRlY3J5cHQoZW5jcnlwdGVkLCBwYWRkaW5nKTtcclxuXHJcbiAgICAgICAgICAgIHZhciByZXMyID0gKHV0aWwuYmluMnN0cihlbmNyeXB0ZWQpID09IHV0aWwuYmluMnN0cih0aGlzVmVjdG9yU2V0W2ldWzFdKSk7XHJcbiAgICAgICAgICAgIHZhciByZXMzID0gKHV0aWwuYmluMnN0cihkZWNyeXB0ZWQpID09IHV0aWwuYmluMnN0cih0aGlzVmVjdG9yU2V0W2ldWzBdKSk7XHJcbiAgICAgICAgICAgIHJlcyAmPSByZXMyO1xyXG4gICAgICAgICAgICByZXMgJj0gcmVzMztcclxuICAgICAgICAgICAgaWYgKCFyZXMyIHx8ICFyZXMzKSB7XHJcbiAgICAgICAgICAgICAgICByZXN1bHRbal0gPSBuZXcgdW5pdC5yZXN1bHQoXHJcbiAgICAgICAgICAgICAgICAgICAgXCJUZXN0aW5nIHZlY3RvciB3aXRoIGJsb2NrIFtcIiArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwuaGV4aWR1bXAodGhpc1ZlY3RvclNldFtpXVswXSkgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcIl0gYW5kIGtleSBbXCIgKyB1dGlsLmhleHN0cmR1bXAoa2V5KSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiXSBhbmQgcGFkZGluZyBbXCIgKyBwYWRkaW5nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXCJdIHNob3VsZCBiZSBcIiArIHV0aWwuaGV4aWR1bXAodGhpc1ZlY3RvclNldFtpXVsxXSkgKyBcIiAtIEFjdHVhbGx5IFtFTkM6XCIgKyB1dGlsLmhleGlkdW1wKGVuY3J5cHRlZCkgKyBcIiwgREVDOlwiICsgdXRpbC5oZXhpZHVtcChkZWNyeXB0ZWQpICsgXCJdXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgaisrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHJlcykge1xyXG4gICAgICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIkFsbCBERVMgdGVzdCB2ZWN0b3JzIGNvbXBsZXRlZFwiLCB0cnVlKTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn0pO1xyXG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uLy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIlR3b2Zpc2ggdGVzdCB3aXRoIHRlc3QgdmVjdG9ycyBmcm9tIGh0dHA6Ly93d3cuc2NobmVpZXIuY29tL2NvZGUvZWNiX2l2YWwudHh0XCIsIGZ1bmN0aW9uKCkge1xuICB2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLy4uLycpLFxuICAgIHV0aWwgPSBvcGVucGdwLnV0aWw7XG5cbiAgZnVuY3Rpb24gVEZlbmNyeXB0KGJsb2NrLCBrZXkpIHtcbiAgICB2YXIgdGYgPSBuZXcgb3BlbnBncC5jcnlwdG8uY2lwaGVyLnR3b2Zpc2goa2V5KTtcblxuICAgIHJldHVybiB0Zi5lbmNyeXB0KGJsb2NrKTtcbiAgfVxuXG5cbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIgc3RhcnQgPSBbMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwXTtcbiAgdmFyIHN0YXJ0X3Nob3J0ID0gWzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDBdO1xuICB2YXIgdGVzdHZlY3RvcnMgPSBbWzB4NTcsMHhGRiwweDczLDB4OUQsMHg0RCwweEM5LDB4MkMsMHgxQiwweEQ3LDB4RkMsMHgwMSwweDcwLDB4MEMsMHhDOCwweDIxLDB4NkZdLFxuICAgICAgICAgICAgWzB4RDQsMHgzQiwweEI3LDB4NTUsMHg2RSwweEEzLDB4MkUsMHg0NiwweEYyLDB4QTIsMHg4MiwweEI3LDB4RDQsMHg1QiwweDRFLDB4MERdLFxuICAgICAgICAgICAgWzB4OTAsMHhBRiwweEU5LDB4MUIsMHhCMiwweDg4LDB4NTQsMHg0RiwweDJDLDB4MzIsMHhEQywweDIzLDB4OUIsMHgyNiwweDM1LDB4RTZdLFxuICAgICAgICAgICAgWzB4NkMsMHhCNCwweDU2LDB4MUMsMHg0MCwweEJGLDB4MEEsMHg5NywweDA1LDB4OTMsMHgxQywweEI2LDB4RDQsMHgwOCwweEU3LDB4RkFdLFxuICAgICAgICAgICAgWzB4MzAsMHg1OSwweEQ2LDB4RDYsMHgxNywweDUzLDB4QjksMHg1OCwweEQ5LDB4MkYsMHg0NywweDgxLDB4QzgsMHg2NCwweDBFLDB4NThdLFxuICAgICAgICAgICAgWzB4RTYsMHg5NCwweDY1LDB4NzcsMHgwNSwweDA1LDB4RDcsMHhGOCwweDBFLDB4RjYsMHg4QywweEEzLDB4OEEsMHhCMywweEEzLDB4RDZdLFxuICAgICAgICAgICAgWzB4NUEsMHhCNiwweDdBLDB4NUYsMHg4NSwweDM5LDB4QTQsMHhBNSwweEZELDB4OUYsMHgwMywweDczLDB4QkEsMHg0NiwweDM0LDB4NjZdLFxuICAgICAgICAgICAgWzB4REMsMHgwOSwweDZCLDB4Q0QsMHg5OSwweEZDLDB4NzIsMHhGNywweDk5LDB4MzYsMHhENCwweEM3LDB4NDgsMHhFNywweDVBLDB4RjddLFxuICAgICAgICAgICAgWzB4QzUsMHhBMywweEU3LDB4Q0UsMHhFMCwweEYxLDB4QjcsMHgyNiwweDA1LDB4MjgsMHhBNiwweDhGLDB4QjQsMHhFQSwweDA1LDB4RjJdLFxuICAgICAgICAgICAgWzB4NDMsMHhENSwweENFLDB4QzMsMHgyNywweEIyLDB4NEEsMHhCOSwweDBBLDB4RDMsMHg0QSwweDc5LDB4RDAsMHg0NiwweDkxLDB4NTFdXTtcbiAgdGVzdHZlY3RvcnNbNDddID0gIFsweDQzLDB4MTAsMHg1OCwweEY0LDB4REIsMHhDNywweEY3LDB4MzQsMHhEQSwweDRGLDB4MDIsMHhGMCwweDRDLDB4QzQsMHhGNCwweDU5XTtcbiAgdGVzdHZlY3RvcnNbNDhdID0gIFsweDM3LDB4RkUsMHgyNiwweEZGLDB4MUMsMHhGNiwweDYxLDB4NzUsMHhGNSwweERELDB4RjQsMHhDMywweDNCLDB4OTcsMHhBMiwweDA1XTtcbiAgdmFyIHJlcyA9IHRydWU7XG4gIHZhciBqID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OTsgaSsrKSB7XG4gICAgdmFyIHJlczIgPSBmYWxzZTtcbiAgICB2YXIgYmxrLCBrZXksIGN0O1xuICAgIGlmIChpID09PSAwKSB7XG4gICAgICBibGsgPSBzdGFydF9zaG9ydDtcbiAgICAgIGtleSA9IHV0aWwuYmluMnN0cihzdGFydCk7XG4gICAgICBjdCA9IHRlc3R2ZWN0b3JzWzBdO1xuICAgICAgcmVzMiA9ICh1dGlsLmJpbjJzdHIoVEZlbmNyeXB0KGJsayxrZXkpKSA9PSB1dGlsLmJpbjJzdHIoY3QpKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IDEpIHtcbiAgICAgIGJsayA9IHRlc3R2ZWN0b3JzWzBdO1xuICAgICAga2V5ID0gdXRpbC5iaW4yc3RyKHN0YXJ0KTtcbiAgICAgIGN0ID0gdGVzdHZlY3RvcnNbMV07XG4gICAgICByZXMyID0gKHV0aWwuYmluMnN0cihURmVuY3J5cHQoYmxrLGtleSkpID09IHV0aWwuYmluMnN0cihjdCkpO1xuICAgIH0gZWxzZSBpZiAoaSA9PT0gMikge1xuICAgICAgYmxrID0gdGVzdHZlY3RvcnNbaS0xXTtcbiAgICAgIGtleSA9IHV0aWwuYmluMnN0cih0ZXN0dmVjdG9yc1tpLTJdLmNvbmNhdChzdGFydF9zaG9ydCkpO1xuICAgICAgY3QgPSB0ZXN0dmVjdG9yc1tpXTtcbiAgICAgIHJlczIgPSAodXRpbC5iaW4yc3RyKFRGZW5jcnlwdChibGssa2V5KSkgPT0gdXRpbC5iaW4yc3RyKGN0KSk7XG4gICAgfSBlbHNlIGlmIChpIDwgMTAgfHwgaSA+IDQ2KSB7XG4gICAgICBibGsgPSB0ZXN0dmVjdG9yc1tpLTFdO1xuICAgICAga2V5ID0gdXRpbC5iaW4yc3RyKHRlc3R2ZWN0b3JzW2ktMl0uY29uY2F0KHRlc3R2ZWN0b3JzW2ktM10pKTtcbiAgICAgIGN0ID0gdGVzdHZlY3RvcnNbaV07XG4gICAgICByZXMyID0gKHV0aWwuYmluMnN0cihURmVuY3J5cHQoYmxrLGtleSkpID09IHV0aWwuYmluMnN0cihjdCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0ZXN0dmVjdG9yc1tpXSA9IFRGZW5jcnlwdCh0ZXN0dmVjdG9yc1tpLTFdLHV0aWwuYmluMnN0cih0ZXN0dmVjdG9yc1tpLTJdLmNvbmNhdCh0ZXN0dmVjdG9yc1tpLTNdKSkpO1xuICAgICAgcmVzMiA9IHRydWU7XG4gICAgfVxuICAgIHJlcyAmPSByZXMyO1xuICAgIGlmICghcmVzMikge1xuICAgICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyB2ZWN0b3Igd2l0aCBibG9jayBcIit1dGlsLmhleGlkdW1wKGJsaykrXCIgd2l0aCBrZXkgXCIrIHV0aWwuaGV4c3RyZHVtcChrZXkpICtcIiBzaG91bGQgYmUgXCIrdXRpbC5oZXhpZHVtcChjdCkrXCIgYnV0IGlzIFwiK3V0aWwuaGV4aWR1bXAoVEZlbmNyeXB0KGJsayxrZXkpKSwgZmFsc2UpO1xuICAgICAgaisrO1xuICAgIH1cbiAgfVxuICBpZiAocmVzKSB7XG4gICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiNDkgdGVzdCB2ZWN0b3JzIGNvbXBsZXRlZFwiLCB0cnVlKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIkZ1bmN0aW9uYWwgdGVzdGluZyBvZiBvcGVucGdwLmNyeXB0by4qIG1ldGhvZHNcIiwgZnVuY3Rpb24oKSB7XG5cdHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vJyk7XG4gIHZhciB1dGlsID0gb3BlbnBncC51dGlsO1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBSU0FwdWJNUElzdHJzID0gW1xuICAgICAgICAgICAgICB1dGlsLmJpbjJzdHIoWzB4MDgsMHgwMCwweGFjLDB4MTUsMHhiMywweGQ2LDB4ZDIsMHgwZiwweGYwLDB4N2EsMHhkZCwweDIxLDB4YjcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhiZiwweDYxLDB4ZmEsMHhjYSwweDkzLDB4ODYsMHhjOCwweDU1LDB4NWEsMHg0YiwweGE2LDB4YTQsMHgxYSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDYwLDB4YTIsMHgzYSwweDM3LDB4MDYsMHgwOCwweGQ4LDB4MTUsMHg4ZSwweDg1LDB4NDUsMHhhYSwweGI3LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MWQsMHg3YiwweDBiLDB4NzMsMHg5NCwweDU1LDB4MGMsMHg1YywweGVjLDB4YzAsMHgyMiwweDRiLDB4YTEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg2NCwweDIwLDB4N2QsMHg0ZCwweGE4LDB4OTYsMHgxYSwweDY0LDB4MzgsMHg5MywweGNkLDB4ZWMsMHg3MyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDVkLDB4ZjksMHg4OSwweDg4LDB4MjQsMHgzZCwweDQ4LDB4ZmYsMHgzYiwweDg3LDB4NjIsMHhkMCwweDg0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZWEsMHhmZiwweDM5LDB4YjUsMHgyNywweDcwLDB4ZWEsMHg0YSwweGIyLDB4MmUsMHg5ZCwweGYxLDB4N2MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgyMywweGVjLDB4ZjQsMHg1ZSwweGVhLDB4NjEsMHgzZCwweGU1LDB4ZDgsMHgwZCwweGY5LDB4NTksMHg2ZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDI4LDB4MDAsMHhlYiwweGNiLDB4YzksMHg1NSwweDAwLDB4NzIsMHgzMCwweDFmLDB4NjUsMHg5ZCwweGQ2LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTcsMHg1OCwweDVmLDB4YTYsMHg0YSwweGEwLDB4ZGQsMHhlMSwweDc2LDB4ZjIsMHhlZiwweDIxLDB4OWYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4NCwweGZjLDB4YWEsMHg1YiwweDUyLDB4NmUsMHhjMSwweGEyLDB4YjksMHhiZCwweGI5LDB4ZjQsMHg5ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDQ5LDB4OTIsMHhmMiwweGFmLDB4NTcsMHg4NiwweGYyLDB4ZWYsMHg3MCwweGJmLDB4NTEsMHg0MCwweGZkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4YmYsMHg1NiwweDUxLDB4ZTgsMHgyYywweGEyLDB4NGYsMHhmOCwweGE0LDB4ZDcsMHgzNiwweDE4LDB4ODUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhjZSwweDA5LDB4MGQsMHhiYywweDhkLDB4NjUsMHg1ZSwweDhhLDB4MWQsMHg5OCwweGIwLDB4NGQsMHg5ZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGMxLDB4Y2YsMHg4MiwweGUxLDB4YjcsMHg0MywweDVkLDB4NWEsMHg3MiwweGNkLDB4NTUsMHhkMiwweGZmLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4YjEsMHhiNCwweDc4LDB4YmYsMHhhMSwweDdkLDB4YWMsMHhkOSwweDFiLDB4YzQsMHhmYSwweDM5LDB4MzQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg5MiwweDA5LDB4ZjksMHgwOCwweDJhLDB4NmIsMHg5ZCwweDE0LDB4NTYsMHgxMiwweDRjLDB4ZTksMHhhNixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDI5LDB4YzEsMHhmMywweGE5LDB4MGIsMHhmYywweDMxLDB4NzUsMHg1OCwweDc0LDB4MmEsMHg4OCwweGFmLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZWUsMHhjOSwweGE0LDB4Y2QsMHgxNSwweGRjLDB4MWIsMHg4ZCwweDY0LDB4YzEsMHgzNiwweDE3LDB4YzQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4ZCwweDVlLDB4OTksMHg3YSwweDViLDB4OWYsMHgzOSwweGQwLDB4MDAsMHg2ZSwweGY5XSksXG4gICAgICAgICAgICAgIHV0aWwuYmluMnN0cihbMHgwMCwweDExLDB4MDEsMHgwMCwweDAxXSldO1xuICB2YXIgUlNBc2VjTVBJc3RycyA9IFtcbiAgICAgICAgICAgICAgdXRpbC5iaW4yc3RyKFsweDA3LDB4ZmUsMHgyMywweGZmLDB4Y2UsMHg0NSwweDZjLDB4NjAsMHg2NSwweDQwLDB4NmUsMHhhZSwweDM1LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTAsMHg1NiwweDYwLDB4ZWUsMHhhYiwweGZhLDB4MTAsMHg0MiwweGJhLDB4YzcsMHgwNCwweGFmLDB4NjMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhjZCwweDNmLDB4NjIsMHhjYSwweDRiLDB4ZmEsMHhlMSwweGE5LDB4NzAsMHhjZCwweDM0LDB4OGIsMHhjOCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDBlLDB4ZTQsMHhjNCwweGJhLDB4ODMsMHgxNywweDVmLDB4YTQsMHhiOCwweGVhLDB4NjAsMHhjMiwweDRkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OWEsMHhmMiwweGE5LDB4MDMsMHhlYiwweGY2LDB4YWEsMHhjMiwweGI4LDB4OGIsMHg0MywweDEyLDB4ZTksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmNywweDg4LDB4ZDIsMHg1YSwweGE2LDB4YWEsMHgyMywweDcxLDB4MzEsMHg3NCwweGRiLDB4MTksMHgyMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE1LDB4NDEsMHgxYiwweDQzLDB4NjgsMHg2MiwweGQ4LDB4YzAsMHg5MywweDkxLDB4ZTgsMHhmYywweGIxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4YTksMHg5YSwweDUyLDB4NmMsMHhlMCwweGJmLDB4NDMsMHgwMSwweGE4LDB4MzcsMHgxNCwweDI4LDB4YmYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwYiwweDE1LDB4NTYsMHgzZSwweGE1LDB4NzksMHhhMCwweGM0LDB4NDIsMHg4OCwweGVlLDB4ZWIsMHgxYixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGY0LDB4N2EsMHg0YSwweDU4LDB4MzEsMHg1OCwweDgxLDB4ZDIsMHgzZSwweGRlLDB4MDcsMHg2NCwweDkyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZjAsMHg2MCwweGQzLDB4OWEsMHgyOSwweGNhLDB4YzYsMHg2NywweDc1LDB4MDcsMHhjYSwweDkyLDB4MzksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg1NiwweGY2LDB4MTEsMHg4NCwweGJhLDB4NmQsMHg0YiwweGU2LDB4NmYsMHg2NiwweGMyLDB4MTcsMHhlYixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDQ2LDB4NjksMHgxYywweGJiLDB4ZGYsMHhjMCwweDM4LDB4MDAsMHhkNiwweDAxLDB4ZTYsMHg3MCwweDlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NGIsMHg5YiwweDcwLDB4ZWQsMHg1YywweGI4LDB4Y2YsMHhlOCwweDY4LDB4NzEsMHhiZSwweDI0LDB4NmQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhiMSwweGEzLDB4MTMsMHhjYywweGYxLDB4YmMsMHg2NywweGRjLDB4ZTAsMHg2OSwweDA5LDB4ODIsMHgzYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDNiLDB4MGYsMHgxNCwweDk4LDB4NDgsMHgzMCwweGIyLDB4NzAsMHhjNiwweDllLDB4ZmEsMHg0NiwweDhmLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZjEsMHhjMCwweDY1LDB4OGUsMHhjNiwweGFlLDB4ZGMsMHg0NywweDkxLDB4MTMsMHgxZSwweGQ2LDB4NGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmMiwweGFkLDB4ZGEsMHhjMiwweGM3LDB4MzksMHg3OCwweDk5LDB4ZGUsMHg1NywweDE0LDB4NDUsMHg3ZixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDMyLDB4MzgsMHhhMywweDQ0LDB4MGYsMHhlNywweDM5LDB4NGMsMHg2ZiwweDBmLDB4MzIsMHg3ZSwweGYxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NWMsMHg4NCwweDk3LDB4ZGQsMHhhMCwweDBjLDB4ODcsMHg2NiwweDdkLDB4NzUsMHg3OV0pLFxuICAgICAgICAgICAgICB1dGlsLmJpbjJzdHIoWzB4MDQsMHgwMCwweGMyLDB4YmMsMHg3MSwweGY3LDB4NDEsMHg0YSwweDA5LDB4NjYsMHg3MCwweDAyLDB4NjgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4YiwweGViLDB4ZTIsMHgzNCwweGQxLDB4MTIsMHg4MywweDkzLDB4NzUsMHhlOSwweDcxLDB4MzIsMHhlMixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGVkLDB4MTgsMHg2ZiwweDhlLDB4M2EsMHhmZiwweDIyLDB4NzAsMHgyOCwweDAxLDB4YmYsMHg0YSwweDM5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDEsMHhiYiwweDNjLDB4NGEsMHhiYywweGI4LDB4MTMsMHhmYywweDE0LDB4ZjYsMHg3MSwweGExLDB4NDQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxYywweDAyLDB4YTEsMHg3MywweDgxLDB4Y2MsMHhhMCwweDM1LDB4MDIsMHgzZSwweDk3LDB4YjUsMHhjNCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDk0LDB4MzMsMHhmMSwweGQxLDB4ZGYsMHgxNCwweDNmLDB4ZmIsMHg4ZiwweGI5LDB4NzUsMHg3MCwweGRjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NzQsMHgzZiwweDA3LDB4MzUsMHg4ZiwweDUzLDB4YWEsMHhiMiwweGQ2LDB4ODgsMHg1MSwweDcxLDB4NGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMSwweDI0LDB4ZWMsMHg3ZCwweGNhLDB4ZjYsMHhhMiwweGIzLDB4YmIsMHhhZCwweDJlLDB4NjAsMHhmYixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDFjLDB4ZWUsMHg0OSwweGQwLDB4NGUsMHg1YywweGUzLDB4MWYsMHg4OCwweDQ4LDB4ZTQsMHg2OCwweDE0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4M2QsMHg3MSwweGJhLDB4ZDcsMHg0ZCwweDM1LDB4MTAsMHg4NiwweDM3LDB4NjIsMHhlMCwweGE1LDB4MGJdKSxcbiAgICAgICAgICAgICAgdXRpbC5iaW4yc3RyKFsweDA0LDB4MDAsMHhlMiwweDM4LDB4ZjksMHhjOCwweDNjLDB4ZDEsMHhjZiwweDYyLDB4OTMsMHhjMywweDc3LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NzYsMHg5NywweDQ0LDB4ZTgsMHhjOCwweGNhLDB4OTMsMHg5YSwweGVmLDB4ZjAsMHg2MywweDc2LDB4MjUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgzYiwweDFjLDB4NDYsMHhmZiwweDkwLDB4MTMsMHg5MSwweDE1LDB4OTcsMHg3ZSwweDg4LDB4OTUsMHhkNCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDdmLDB4MmYsMHg1MiwweDZlLDB4MGQsMHg1NSwweDU1LDB4MmUsMHhmMSwweDU4LDB4NWMsMHg3ZSwweDU2LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZDQsMHg0OCwweGFhLDB4ZGIsMHg4YywweDQ0LDB4NGQsMHg4NCwweDY5LDB4MzMsMHg4NywweDA3LDB4YjIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg3ZSwweGY1LDB4YTAsMHg2MCwweGZiLDB4NzMsMHg1OSwweDQ2LDB4MjksMHhjYiwweDFlLDB4M2YsMHg3YyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDJmLDB4YTYsMHg1MywweGUzLDB4OGMsMHhlZiwweGQ1LDB4ZWIsMHhiYiwweGM4LDB4OWEsMHg4ZSwweDY2LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NGEsMHg0NywweDJmLDB4ZTEsMHhiYSwweDVlLDB4MzIsMHhkNCwweDUyLDB4MDQsMHg4OCwweDlkLDB4NjMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgzZSwweGJhLDB4NzEsMHgyZCwweGY3LDB4NjEsMHhkNSwweGZjLDB4MjYsMHhiZiwweGQ4LDB4NjAsMHg5MixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDdiLDB4OTQsMHhmOCwweDZmLDB4M2QsMHg5NywweDBiLDB4MGMsMHg1MiwweDhjLDB4YjMsMHhiNiwweDhiXSksXG4gICAgICAgICAgICAgIHV0aWwuYmluMnN0cihbMHgwNCwweDAwLDB4YjcsMHhjNSwweDRkLDB4NmUsMHgyZiwweGRkLDB4ZWYsMHhlYywweDA3LDB4NzAsMHhhMixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDdjLDB4MWMsMHg5ZCwweDhlLDB4NjYsMHg2MCwweDdjLDB4NjEsMHgxZSwweDQ1LDB4ZTksMHhkYywweDgyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MmYsMHhjNSwweDdlLDB4MWEsMHhjNiwweGQwLDB4OTIsMHhjNSwweDIyLDB4OWIsMHg5YSwweGZiLDB4NzMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg5NSwweDk5LDB4ZjIsMHg3YywweGRiLDB4MmEsMHg5MywweDdiLDB4NWEsMHgyOSwweDczLDB4MjQsMHgxNixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDQxLDB4NDksMHhiNSwweGYyLDB4NWYsMHhiZSwweGU3LDB4NjQsMHg0ZCwweGRhLDB4NTIsMHg5ZSwweGMxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDEsMHg0MCwweDVlLDB4MDMsMHg5MiwweDhkLDB4MzksMHg5NSwweDFmLDB4NjgsMHg5ZiwweDAwLDB4MmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwYywweDZmLDB4Y2YsMHhkOSwweDZkLDB4NjgsMHhmNywweDAwLDB4NGYsMHgwZSwweGM4LDB4MGIsMHhmYSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDUxLDB4ZTAsMHgyMiwweGYwLDB4ZmYsMHhhNywweDQyLDB4ZDQsMHhkZSwweDBiLDB4NDcsMHg4ZiwweDJiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZjUsMHg0ZCwweDA0LDB4MzIsMHg5MSwweDg5LDB4NGIsMHgwZSwweDA1LDB4OGQsMHg3MCwweGY5LDB4YmIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhlNywweGQ2LDB4NzYsMHhlYSwweDBlLDB4MWEsMHg5MCwweDMwLDB4ZjUsMHg5OCwweDAxLDB4YzUsMHg3M10pXTtcbiAgXG4gIHZhciBEU0FwdWJNUElzdHJzID0gW1xuICAgICAgICAgIHV0aWwuYmluMnN0cihbMHgwOCwweDAwLDB4YTgsMHg4NSwweDVjLDB4MjgsMHgwNSwweDk0LDB4MDMsMHhiZSwweDA3LDB4NmMsMHgxMywweDNlLDB4NjUsXG4gICAgICAgICAgICAgICAgICAgICAgICAweGZiLDB4YjUsMHhlMSwweDk5LDB4N2MsMHhmYSwweDg0LDB4ZTMsMHhhYywweDQ3LDB4YTUsMHhjNCwweDQ2LDB4ZDgsMHg1ZixcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4NDQsMHhlOSwweGMxLDB4NmIsMHg2OSwweGY3LDB4MTAsMHg3NiwweDQ5LDB4YTcsMHgyNSwweDg1LDB4ZjQsMHgxYiwweGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgMHhjNiwweDYwLDB4YzQsMHg1YiwweGFhLDB4ZDQsMHg4NywweGQ2LDB4OGYsMHg5MiwweDU2LDB4N2QsMHg1NSwweDNmLDB4NDUsXG4gICAgICAgICAgICAgICAgICAgICAgICAweGFlLDB4MTIsMHg3MywweGRhLDB4MjksMHg4YywweGJhLDB4MzIsMHhjYywweGQ3LDB4YTQsMHhkMCwweDI0LDB4YjAsMHg3YyxcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4ZDgsMHgwYywweDNhLDB4OTEsMHg2ZiwweDk4LDB4NDAsMHg5YywweDlhLDB4YTgsMHhjYywweDI4LDB4MjcsMHg5NSwweDBiLFxuICAgICAgICAgICAgICAgICAgICAgICAgMHhlMSwweDViLDB4YjksMHgzYiwweDFjLDB4MWMsMHhkMiwweGVjLDB4YWIsMHgwNywweDI1LDB4OGQsMHg3YSwweDJhLDB4MmIsXG4gICAgICAgICAgICAgICAgICAgICAgICAweDE2LDB4MTQsMHhlOCwweGRhLDB4NzEsMHhkMiwweGFiLDB4YmEsMHg4NSwweDE0LDB4MGQsMHhjNSwweGUwLDB4ODgsMHhlYixcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4YTUsMHhlMiwweGQ1LDB4NDgsMHgzZCwweDc0LDB4MGMsMHg0MSwweGViLDB4ZmQsMHhiNiwweDRlLDB4ZjksMHgyYywweDgyLFxuICAgICAgICAgICAgICAgICAgICAgICAgMHgxNywweGRkLDB4NjQsMHgxZSwweDE5LDB4MzksMHhhMywweDdmLDB4ZjksMHgwMCwweGNkLDB4OWIsMHhkYSwweDJlLDB4YmQsXG4gICAgICAgICAgICAgICAgICAgICAgICAweDcxLDB4MTIsMHhkZiwweDBkLDB4N2MsMHgwYSwweDZiLDB4MmQsMHgyMSwweDNiLDB4OWMsMHg2NiwweDkzLDB4NGEsMHgxZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4OTAsMHg3OSwweGQzLDB4NWEsMHg1YiwweGU1LDB4YjksMHg5NCwweDFiLDB4ZTYsMHg0NywweDk5LDB4MDYsMHg5OCwweGQ4LFxuICAgICAgICAgICAgICAgICAgICAgICAgMHgyYSwweGU1LDB4ZTIsMHhhNiwweDk1LDB4NmEsMHgwNywweGM4LDB4YWMsMHg3YywweGU5LDB4ZmMsMHhhMiwweDZhLDB4MTYsXG4gICAgICAgICAgICAgICAgICAgICAgICAweDJjLDB4OTQsMHg5OCwweGJkLDB4OTEsMHgwYSwweDdjLDB4N2MsMHgyYywweGI5LDB4N2UsMHhhMiwweDUxLDB4OGIsMHg0NSxcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4MWQsMHg0NiwweDM0LDB4YTgsMHg1MiwweDJiLDB4ZGQsMHhkOSwweGE4LDB4YmMsMHg0NiwweDc4LDB4NjYsMHhlMSwweDcyLFxuICAgICAgICAgICAgICAgICAgICAgICAgMHgxMSwweGYxLDB4Y2IsMHgxYSwweGI2LDB4NGUsMHgwNSwweDU0LDB4ZjcsMHhlOSwweGJlLDB4NGMsMHgyNSwweDU5LDB4MDgsXG4gICAgICAgICAgICAgICAgICAgICAgICAweDlmLDB4ZjgsMHhlYSwweDI1LDB4OTcsMHgzMywweGQ2LDB4YzksMHgwZiwweDU5LDB4MGUsMHhmZCwweDlmLDB4ZGMsMHhlMixcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4YzAsMHhjZiwweDJmXSksXG4gICAgICB1dGlsLmJpbjJzdHIoWzB4MDEsMHgwMCwweGUxLDB4NzIsMHgyYywweGQwLDB4YmIsMHgxYSwweDRmLDB4YjYsMHhiNiwweDk1LDB4NzcsMHg3MSwweDJlLFxuICAgICAgICAgICAgICAgICAgICAweDAxLDB4NDgsMHgzZSwweDM1LDB4NTQsMHg2NCwweDJiLDB4ZWQsMHg0MCwweDVmLDB4NjUsMHgwYywweDU3LDB4MjgsMHg1ZixcbiAgICAgICAgICAgICAgICAgICAgMHhmZCwweGZkLDB4ZmYsMHhkN10pLFxuICAgICAgdXRpbC5iaW4yc3RyKFsweDA3LDB4ZmYsMHg1ZCwweDlmLDB4YzQsMHhiNSwweDYzLDB4MjUsMHg5ZCwweDcyLDB4ODgsMHhlNSwweDUzLDB4NDYsMHg5OCxcbiAgICAgICAgICAgICAgICAgICAgMHhlMywweGU5LDB4NjIsMHhjYiwweDBjLDB4YTEsMHhiNywweDc1LDB4OWYsMHgxOCwweDQxLDB4OTQsMHgzMiwweDI4LDB4MjksXG4gICAgICAgICAgICAgICAgICAgIDB4NmQsMHg2OSwweGUwLDB4M2YsMHg3ZCwweDdiLDB4MmIsMHgwNiwweDVhLDB4MzMsMHg1YywweGQ0LDB4MzYsMHgzMSwweDA5LFxuICAgICAgICAgICAgICAgICAgICAweDU0LDB4ODUsMHg5ZCwweGI4LDB4MjAsMHhmZSwweGRhLDB4ZmMsMHhjZCwweDFmLDB4YjEsMHgyYywweDE1LDB4MDgsMHg5ZCxcbiAgICAgICAgICAgICAgICAgICAgMHgzMiwweDUzLDB4MmYsMHhjMSwweDQyLDB4MjIsMHg2OSwweGZmLDB4NjcsMHgyZSwweDM5LDB4OTcsMHg1MCwweDY2LDB4MzksXG4gICAgICAgICAgICAgICAgICAgIDB4ZGEsMHhjZiwweGZkLDB4NjQsMHg2ZiwweDkxLDB4MDUsMHg2NCwweDM3LDB4YzUsMHgwNywweDI0LDB4YWEsMHg0MCwweGEwLFxuICAgICAgICAgICAgICAgICAgICAweDc1LDB4ODIsMHgxZCwweDk3LDB4OTYsMHgxMiwweGYxLDB4YmQsMHg5ZSwweDA5LDB4MjYsMHgzYywweDk3LDB4NWQsMHg1NyxcbiAgICAgICAgICAgICAgICAgICAgMHhiOCwweDVjLDB4N2QsMHg4OSwweDAzLDB4ODIsMHhjZCwweDQwLDB4ZTUsMHgwMywweGU2LDB4NGEsMHhmYiwweGJjLDB4ZDIsXG4gICAgICAgICAgICAgICAgICAgIDB4ZWYsMHg3YSwweDg5LDB4MDIsMHgwOCwweGM4LDB4NTIsMHhmYSwweDk3LDB4NzQsMHg2NiwweDMyLDB4YWUsMHhhNiwweDUyLFxuICAgICAgICAgICAgICAgICAgICAweDRiLDB4ZWYsMHg1ZiwweGNlLDB4OTEsMHgyMywweDNmLDB4YWIsMHg5ZCwweDYyLDB4MjEsMHhlZiwweDQ4LDB4NmQsMHgwNyxcbiAgICAgICAgICAgICAgICAgICAgMHg1YSwweGJhLDB4ZGYsMHgwMCwweDkxLDB4NTQsMHhlYSwweDVjLDB4ZmEsMHg0YiwweDE2LDB4MjgsMHgxYSwweGNlLDB4NDgsXG4gICAgICAgICAgICAgICAgICAgIDB4YjcsMHg1YywweDUwLDB4YTUsMHg1OSwweGE0LDB4YjQsMHhhZiwweDFmLDB4ZWIsMHg4ZCwweDU4LDB4M2YsMHgwYSwweGE1LFxuICAgICAgICAgICAgICAgICAgICAweDk3LDB4MmIsMHg1MSwweDU2LDB4ZTgsMHg4OCwweGY2LDB4MDcsMHhiYywweGRmLDB4ZmEsMHgyYiwweDdiLDB4ODgsMHhlMCxcbiAgICAgICAgICAgICAgICAgICAgMHg0NiwweGM4LDB4N2EsMHgzZSwweGQ4LDB4ODAsMHhkYiwweDRkLDB4ODcsMHg2MSwweDRmLDB4NjQsMHhjZCwweGViLDB4ZTgsXG4gICAgICAgICAgICAgICAgICAgIDB4MGQsMHg4NiwweDE2LDB4Y2MsMHhkZCwweDZjLDB4NzYsMHg2NiwweGMxLDB4NzMsMHhiNywweDA4LDB4OTgsMHg4OSwweDJmLFxuICAgICAgICAgICAgICAgICAgICAweDY3LDB4NjksMHhkMSwweGZjLDB4OTcsMHg0ZCwweGEyLDB4Y2UsMHhhZCwweGJiLDB4NmYsMHhhYiwweGE1LDB4ZDYsMHgxOCxcbiAgICAgICAgICAgICAgICAgICAgMHhiMywweDFhLDB4OTYsMHgwMiwweGJjLDB4MzEsMHg0MiwweGEyLDB4YWQsMHg3NywweGU4LDB4ZTIsMHg0YywweDk5LDB4ZjksXG4gICAgICAgICAgICAgICAgICAgIDB4ZGQsMHhiZSwweGNkXSksXG4gICAgICB1dGlsLmJpbjJzdHIoWzB4MDcsMHhmZiwweDVkLDB4ZmUsMHg5YywweDk4LDB4ZWYsMHgzYSwweGE2LDB4NDksMHhmMCwweDEwLDB4NjcsMHg3OSwweDJhLFxuICAgICAgICAgICAgICAgICAgICAweDlkLDB4NzksMHg0MywweDA2LDB4YTQsMHhhOCwweDZiLDB4MWEsMHg2ZCwweDFmLDB4NzcsMHg2ZSwweDAwLDB4MzEsMHhiOSxcbiAgICAgICAgICAgICAgICAgICAgMHhlZCwweGM5LDB4NjYsMHhmZiwweGYxLDB4MjEsMHgzMiwweGZhLDB4NjIsMHg0MywweGNkLDB4OTcsMHhkMywweDNkLDB4YWYsXG4gICAgICAgICAgICAgICAgICAgIDB4YjQsMHgyOSwweDI5LDB4MjYsMHg0ZSwweDFjLDB4YTAsMHhhZCwweDFjLDB4MDcsMHgyOCwweDNmLDB4ZTUsMHg0MywweDEwLFxuICAgICAgICAgICAgICAgICAgICAweGJhLDB4YjQsMHgwOCwweGUwLDB4ZGMsMHhhMiwweGMzLDB4NWIsMHgxZiwweGJkLDB4OTQsMHhjNywweDQzLDB4ZTUsMHhmMixcbiAgICAgICAgICAgICAgICAgICAgMHgxNywweDMwLDB4NTQsMHg3ZiwweDE0LDB4YmUsMHhmNCwweGJkLDB4OTEsMHgzYiwweGU0LDB4MzYsMHhhNCwweDUwLDB4NWIsXG4gICAgICAgICAgICAgICAgICAgIDB4MzcsMHg4OSwweDVlLDB4Y2MsMHhjNywweDc0LDB4NTQsMHgzMiwweDIwLDB4MDksMHg2MywweDk4LDB4YjcsMHhkOSwweGFmLFxuICAgICAgICAgICAgICAgICAgICAweDdmLDB4YjAsMHg2YywweDI3LDB4NDMsMHhmZSwweDUyLDB4ZTYsMHgxYSwweDg4LDB4NTksMHgyNSwweGZjLDB4ZWIsMHg0MyxcbiAgICAgICAgICAgICAgICAgICAgMHg1MCwweGM3LDB4NjUsMHg0MywweGMxLDB4ODYsMHg3MywweDU4LDB4NTMsMHgzYSwweGNmLDB4N2EsMHhhMywweDFkLDB4NTYsXG4gICAgICAgICAgICAgICAgICAgIDB4YzgsMHg0YSwweDgwLDB4NzAsMHhiNywweGJmLDB4ZjIsMHhhMywweGVjLDB4ZTgsMHg3NywweDA1LDB4MzMsMHgwOSwweDlkLFxuICAgICAgICAgICAgICAgICAgICAweGFhLDB4Y2EsMHhhMCwweGUxLDB4NjQsMHg2NCwweDZmLDB4NzYsMHg5OSwweDQxLDB4NzUsMHg3OCwweDkwLDB4ZjYsMHhlNyxcbiAgICAgICAgICAgICAgICAgICAgMHgyMywweGU2LDB4ZWMsMHg1MCwweGU1LDB4OTksMHhhOCwweDNlLDB4MWEsMHg0YiwweGM5LDB4ODgsMHg1OCwweDY2LDB4YWUsXG4gICAgICAgICAgICAgICAgICAgIDB4MWEsMHg1MywweDVlLDB4ZTQsMHhiNywweDg2LDB4Y2YsMHhhNiwweGU1LDB4YWQsMHhiNCwweDgwLDB4YTAsMHhmMSwweDBkLFxuICAgICAgICAgICAgICAgICAgICAweDk2LDB4YjgsMHg0MSwweGQwLDB4MDcsMHg5YSwweDIxLDB4OGQsMHg1MCwweDdmLDB4NGYsMHg3MywweDEzLDB4YTIsMHhlMixcbiAgICAgICAgICAgICAgICAgICAgMHgwMiwweDA3LDB4YzMsMHhhMywweDBmLDB4MDksMHgxOCwweDdmLDB4ZjcsMHg2YiwweDkwLDB4NzAsMHhjMCwweGY5LDB4MGMsXG4gICAgICAgICAgICAgICAgICAgIDB4NjcsMHg4ZCwweDlkLDB4MTQsMHhiNiwweDlkLDB4MzIsMHg4MiwweGQwLDB4YjUsMHhjNiwweDU3LDB4ZjAsMHg5MSwweGQ5LFxuICAgICAgICAgICAgICAgICAgICAweGMzLDB4MjYsMHhhZSwweDlmLDB4YTksMHg2NywweDQ5LDB4OTYsMHg1YywweDA3LDB4M2UsMHg0NywweDVjLDB4ZWQsMHg2MCxcbiAgICAgICAgICAgICAgICAgICAgMHgwNywweGFjLDB4NmFdKV07XG4gIHZhciBEU0FzZWNNUElzdHJzID0gW3V0aWwuYmluMnN0cihbMHgwMSwweDAwLDB4OWIsMHg1OCwweGE4LDB4ZjQsMHgwNCwweGIxLDB4ZDUsMHgxNCwweDA5LDB4ZTEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAweGUxLDB4YTEsMHg4YSwweDBiLDB4YTMsMHhjMywweGEzLDB4NjYsMHhhYSwweDI3LDB4OTksMHg1MCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MWMsMHg0ZCwweGJhLDB4MjQsMHhlZSwweGRmLDB4ZGYsMHhiOCwweDhlLDB4OGVdKV07XG4gICAgICAgICAgICBcbiAgdmFyIEVsZ2FtYWxwdWJNUElzdHJzID0gXG4gICAgICAgICAgW3V0aWwuYmluMnN0cihbMHgwOCwweDAwLDB4ZWEsMHhjYywweGJlLDB4ZTIsMHhlNCwweDVhLDB4NTEsMHgxOCwweDkzLDB4YTEsMHgxMiwweDJmLFxuICAgICAgICAgICAgICAgICAgICAgMHgwMCwweDk5LDB4NDIsMHhkOCwweDVjLDB4MWMsMHgyZiwweGI2LDB4M2MsMHhkOSwweDk0LDB4NjEsMHhiNCwweDU1LFxuICAgICAgICAgICAgICAgICAgICAgMHg4ZCwweDRlLDB4NzMsMHhlNiwweDY5LDB4YmMsMHgxZCwweDMzLDB4ZTMsMHgyZCwweDkxLDB4MjMsMHg2OSwweDk1LFxuICAgICAgICAgICAgICAgICAgICAgMHg5OCwweGQ3LDB4MTgsMHg1YSwweGFmLDB4YTcsMHg5MywweGM2LDB4MDUsMHg5MywweDNhLDB4YzcsMHhlYSwweGQwLFxuICAgICAgICAgICAgICAgICAgICAgMHhiMSwweGE5LDB4YzcsMHhhYiwweDQxLDB4ODksMHhjOCwweDM4LDB4OTksMHhkYywweDFhLDB4NTcsMHgzNSwweDFhLFxuICAgICAgICAgICAgICAgICAgICAgMHgyNywweDYyLDB4NDAsMHg3MSwweDlmLDB4MzYsMHgxYywweDZkLDB4MTgsMHgxYywweDkzLDB4ZjcsMHhiYSwweDM1LFxuICAgICAgICAgICAgICAgICAgICAgMHgwNiwweGVkLDB4MzAsMHhiOCwweGQ5LDB4OGEsMHg3YywweDAzLDB4YWYsMHhiYSwweDQwLDB4MWYsMHg2MiwweGYxLFxuICAgICAgICAgICAgICAgICAgICAgMHg2ZCwweDg3LDB4MmMsMHhhNiwweDJlLDB4NDYsMHhiMCwweGFhLDB4YmMsMHhiYywweDkzLDB4ZmEsMHg5YiwweDQ3LFxuICAgICAgICAgICAgICAgICAgICAgMHgzZiwweDcwLDB4MWYsMHgyYSwweGMyLDB4NjYsMHg5YywweDdjLDB4NjksMHhlMCwweDJiLDB4MDUsMHhlZSwweGI3LFxuICAgICAgICAgICAgICAgICAgICAgMHhhNywweDdmLDB4ZjMsMHgyMSwweDQ4LDB4ODUsMHhjMiwweDk1LDB4NWYsMHg2ZiwweDFlLDB4YjMsMHg5YiwweDk3LFxuICAgICAgICAgICAgICAgICAgICAgMHhmOCwweDE0LDB4YzMsMHhmZiwweDRkLDB4OTcsMHgyNSwweDI5LDB4OTQsMHg0MSwweDRiLDB4OTAsMHhkOCwweGJhLFxuICAgICAgICAgICAgICAgICAgICAgMHg3MSwweDQ1LDB4NGIsMHgxZSwweDJmLDB4Y2EsMHg4MiwweDVmLDB4NTYsMHg3NywweGU5LDB4ZDMsMHg4OCwweDVkLFxuICAgICAgICAgICAgICAgICAgICAgMHg4YiwweGVjLDB4OTIsMHg4YiwweDhhLDB4MjMsMHg4OCwweDA1LDB4ZjgsMHgyYywweGE4LDB4ZjEsMHg3MCwweDc2LFxuICAgICAgICAgICAgICAgICAgICAgMHhlNywweGJmLDB4NzUsMHhhOCwweDMxLDB4MTQsMHg4ZSwweDc2LDB4YzgsMHgwMSwweGE2LDB4MjUsMHgyNywweDQ5LFxuICAgICAgICAgICAgICAgICAgICAgMHhhZiwweGRjLDB4ZjQsMHhmNiwweGY0LDB4Y2UsMHg5MCwweDg0LDB4MTUsMHgyYiwweDRkLDB4YjMsMHhjYywweDc3LFxuICAgICAgICAgICAgICAgICAgICAgMHhkYiwweDY1LDB4NzEsMHg3NSwweGQzLDB4MDAsMHgxZCwweDIyLDB4YzUsMHg0MiwweDJmLDB4NTEsMHhmYSwweDdiLFxuICAgICAgICAgICAgICAgICAgICAgMHhlYiwweDZlLDB4MDMsMHhkOSwweDQxLDB4ZGQsMHgyZCwweDFhLDB4ZGQsMHgwNywweDc0LDB4OGIsMHhiNywweGEyLFxuICAgICAgICAgICAgICAgICAgICAgMHhmYSwweGIyLDB4NTksMHgwZSwweDBlLDB4OTQsMHg3YywweDAwLDB4YWQsMHg5NSwweDIzLDB4NDIsMHg5MSwweDE4LFxuICAgICAgICAgICAgICAgICAgICAgMHg0YywweDk3LDB4ZjEsMHgyNywweDYyLDB4NzddKSxcbiAgICAgICB1dGlsLmJpbjJzdHIoWzB4MDAsMHgwMywweDA1XSksXG4gICAgICAgdXRpbC5iaW4yc3RyKFsweDA3LDB4ZmYsMHg1NywweDE5LDB4NzYsMHhmYywweDA5LDB4NmEsMHg3YSwweGY3LDB4YmEsMHhiMiwweDQyLDB4YmYsXG4gICAgICAgICAgICAgICAgICAgICAweGNkLDB4MmIsMHhjMSwweDFhLDB4NzksMHgyNSwweDhjLDB4YWQsMHhmNCwweDNhLDB4MGEsMHg3YSwweDliLDB4NGMsXG4gICAgICAgICAgICAgICAgICAgICAweDQ2LDB4M2MsMHhlMCwweDRmLDB4Y2MsMHg2ZSwweGU1LDB4N2EsMHgzMywweDNhLDB4NGUsMHg4MCwweGNiLDB4ZDMsXG4gICAgICAgICAgICAgICAgICAgICAweDYyLDB4ZDcsMHg4ZiwweGUyLDB4YzgsMHhiMCwweGQwLDB4Y2IsMHg0OSwweGM5LDB4OWUsMHgyZCwweDk3LDB4MTYsXG4gICAgICAgICAgICAgICAgICAgICAweDNhLDB4N2QsMHhiMSwweGUxLDB4ZDMsMHhkOSwweGQ3LDB4M2YsMHgyMCwweDYwLDB4ZTMsMHgzZSwweDc3LDB4ZWEsXG4gICAgICAgICAgICAgICAgICAgICAweDBjLDB4ZTQsMHg3YiwweGYwLDB4MzksMHgxYSwweDBkLDB4ZDksMHg4ZiwweDczLDB4ZDIsMHg1MSwweGI4LDB4MGMsXG4gICAgICAgICAgICAgICAgICAgICAweDBlLDB4MTUsMHgxZSwweGFkLDB4N2MsMHhkOCwweDlkLDB4NzQsMHg2ZSwweGEyLDB4MTcsMHg2YiwweDU4LDB4MTQsXG4gICAgICAgICAgICAgICAgICAgICAweDJiLDB4YjcsMHhhZCwweDhhLDB4ZDcsMHg2NiwweGMwLDB4ZGYsMHhlYSwweDJkLDB4ZmMsMHhjNCwweDZlLDB4NjgsXG4gICAgICAgICAgICAgICAgICAgICAweGI2LDB4NGMsMHg5YSwweDE2LDB4YTQsMHgzZCwweGMyLDB4MjYsMHgwYywweGI3LDB4ZDQsMHgxMywweDdiLDB4MjIsXG4gICAgICAgICAgICAgICAgICAgICAweGZkLDB4ODQsMHhkNywweDBmLDB4ZGMsMHg0MiwweDc1LDB4MDUsMHg4NSwweDI5LDB4MDAsMHgzMSwweDFkLDB4ZWMsXG4gICAgICAgICAgICAgICAgICAgICAweDRlLDB4MjIsMHg4YiwweGY2LDB4MzcsMHg4MywweDQ1LDB4ZTUsMHhiMywweDMxLDB4NjEsMHgyYywweDAyLDB4YTEsXG4gICAgICAgICAgICAgICAgICAgICAweGM2LDB4OWQsMHhlYSwweGJhLDB4M2QsMHg4YSwweGFiLDB4MGYsMHg2MSwweDVlLDB4MTQsMHg2NCwweDY5LDB4MWUsXG4gICAgICAgICAgICAgICAgICAgICAweGEwLDB4MTUsMHg0OCwweDg2LDB4ZTUsMHgxMSwweDA2LDB4ZTgsMHhkZSwweDM0LDB4YzcsMHhhNywweDNkLDB4MzUsXG4gICAgICAgICAgICAgICAgICAgICAweGQxLDB4NzYsMHhjMiwweGJlLDB4MDEsMHg4MiwweDYxLDB4OGQsMHhlNywweDdlLDB4MjgsMHgxZCwweDRlLDB4OGMsXG4gICAgICAgICAgICAgICAgICAgICAweGI5LDB4ZTgsMHg3ZSwweGE0LDB4NWYsMHhhNiwweDNhLDB4OWUsMHg1ZCwweGFjLDB4ZjMsMHg2MCwweDIyLDB4MTQsXG4gICAgICAgICAgICAgICAgICAgICAweGQ1LDB4ZDUsMHhiZSwweDFmLDB4ZjAsMHgxOSwweGU2LDB4ODEsMHhmZCwweDVkLDB4ZTEsMHhmOCwweDc2LDB4NWYsXG4gICAgICAgICAgICAgICAgICAgICAweGUzLDB4ZGEsMHhiYSwweDE5LDB4ZjMsMHhjYiwweDEwLDB4YTAsMHg2YiwweGQwLDB4MmQsMHhiZSwweDQwLDB4NDIsXG4gICAgICAgICAgICAgICAgICAgICAweDdiLDB4OWIsMHgxNSwweGE0LDB4MmQsMHhlYywweGNmLDB4MDksMHhkNiwweGUzLDB4OTIsMHhjMywweDhkLDB4NjUsXG4gICAgICAgICAgICAgICAgICAgICAweDZiLDB4NjAsMHg5NywweGRhLDB4NmIsMHhjYV0pXTtcblxuICB2YXIgRWxnYW1hbHNlY01QSXN0cnMgPSBbXG4gICAgICAgICAgICAgdXRpbC5iaW4yc3RyKFsweDAxLDB4NTIsMHgwMiwweDgwLDB4ODcsMHhmNiwweGU0LDB4NDksMHhkNywweDJlLDB4M2UsMHhmZSwweDYwLDB4YjksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAweGEzLDB4MmEsMHhmMCwweDY3LDB4NTgsMHhlOSwweGY2LDB4NDcsMHg4MywweGRlLDB4N2UsMHhmYiwweGJiLDB4YmQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAweGRmLDB4NDgsMHgxMiwweDFiLDB4MDYsMHg3ZCwweDEzLDB4YmMsMHgzYiwweDQ5LDB4ZjksMHg4NiwweGQ0LDB4NTMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAweGVkLDB4MmQsMHg2OF0pXTtcblxuICB2YXIgUlNBcHViTVBJcyA9IFtdO1xuICB2YXIgaTtcbiAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykge1xuICAgIFJTQXB1Yk1QSXNbaV0gPSBuZXcgb3BlbnBncC5tcGkoKTtcbiAgICBSU0FwdWJNUElzW2ldLnJlYWQoUlNBcHViTVBJc3Ryc1tpXSk7XG4gIH1cblxuICB2YXIgUlNBc2VjTVBJcyA9IFtdO1xuICBmb3IgKGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgUlNBc2VjTVBJc1tpXSA9IG5ldyBvcGVucGdwLm1waSgpO1xuICAgIFJTQXNlY01QSXNbaV0ucmVhZChSU0FzZWNNUElzdHJzW2ldKTtcbiAgfVxuICAgIFxuICB2YXIgRFNBc2VjTVBJcyA9IFtdO1xuICBmb3IgKGkgPSAwOyBpIDwgMTsgaSsrKSB7XG4gICAgRFNBc2VjTVBJc1tpXSA9IG5ldyBvcGVucGdwLm1waSgpO1xuICAgIERTQXNlY01QSXNbaV0ucmVhZChEU0FzZWNNUElzdHJzW2ldKTtcbiAgfVxuICAgIFxuICB2YXIgRFNBcHViTVBJcyA9IFtdO1xuICBmb3IgKGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgRFNBcHViTVBJc1tpXSA9IG5ldyBvcGVucGdwLm1waSgpO1xuICAgIERTQXB1Yk1QSXNbaV0ucmVhZChEU0FwdWJNUElzdHJzW2ldKTtcbiAgfVxuICB2YXIgRWxnYW1hbHNlY01QSXMgPSBbXTtcbiAgZm9yIChpID0gMDsgaSA8IDE7IGkrKykge1xuICAgIEVsZ2FtYWxzZWNNUElzW2ldID0gbmV3IG9wZW5wZ3AubXBpKCk7XG4gICAgRWxnYW1hbHNlY01QSXNbaV0ucmVhZChFbGdhbWFsc2VjTVBJc3Ryc1tpXSk7XG4gIH1cbiAgICBcbiAgdmFyIEVsZ2FtYWxwdWJNUElzID0gW107XG4gIGZvciAoaSA9IDA7IGkgPCAzOyBpKyspIHtcbiAgICBFbGdhbWFscHViTVBJc1tpXSA9IG5ldyBvcGVucGdwLm1waSgpO1xuICAgIEVsZ2FtYWxwdWJNUElzW2ldLnJlYWQoRWxnYW1hbHB1Yk1QSXN0cnNbaV0pO1xuICB9XG5cbiAgLy9PcmlnaW5hbGx5IHdlIHBhc3NlZCBwdWJsaWMgYW5kIHNlY3JldCBNUEkgc2VwYXJhdGVseSwgbm93IHRoZXkgYXJlIGpvaW5lZC4gSXMgdGhpcyB3aGF0IHdlIHdhbnQgdG8gZG8gbG9uZyB0ZXJtP1xuICAvLyBSU0FcbiAgdmFyIFJTQXNpZ25lZERhdGEgPSBvcGVucGdwLmNyeXB0by5zaWduYXR1cmUuc2lnbigyLCAxLCBSU0FwdWJNUElzLmNvbmNhdChSU0FzZWNNUElzKSwgXCJmb29iYXJcIik7XG4gIHZhciBSU0FzaWduZWREYXRhTVBJID0gbmV3IG9wZW5wZ3AubXBpKCk7XG4gIFJTQXNpZ25lZERhdGFNUEkucmVhZChSU0FzaWduZWREYXRhKTtcbiAgcmVzdWx0WzBdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBSU0EgU2lnbiBhbmQgVmVyaWZ5XCIsXG4gICAgICBvcGVucGdwLmNyeXB0by5zaWduYXR1cmUudmVyaWZ5KDEsIDIsIFtSU0FzaWduZWREYXRhTVBJXSwgUlNBcHViTVBJcywgXCJmb29iYXJcIikpO1xuXG4gIC8vIERTQSBcbiAgdmFyIERTQXNpZ25lZERhdGEgPSBvcGVucGdwLmNyeXB0by5zaWduYXR1cmUuc2lnbigyLCAxNywgRFNBcHViTVBJcy5jb25jYXQoRFNBc2VjTVBJcyksIFwiZm9vYmFyXCIpO1xuICBcbiAgdmFyIERTQW1zZ01QSXMgPSBbXTtcbiAgICBEU0Ftc2dNUElzWzBdID0gbmV3IG9wZW5wZ3AubXBpKCk7XG4gICAgRFNBbXNnTVBJc1sxXSA9IG5ldyBvcGVucGdwLm1waSgpO1xuICAgIERTQW1zZ01QSXNbMF0ucmVhZChEU0FzaWduZWREYXRhLnN1YnN0cmluZygwLDM0KSk7XG4gICAgRFNBbXNnTVBJc1sxXS5yZWFkKERTQXNpZ25lZERhdGEuc3Vic3RyaW5nKDM0LDY4KSk7XG4gIHJlc3VsdFsxXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3RpbmcgRFNBIFNpZ24gYW5kIFZlcmlmeVwiLFxuICAgICAgb3BlbnBncC5jcnlwdG8uc2lnbmF0dXJlLnZlcmlmeSgxNywgMiwgRFNBbXNnTVBJcywgRFNBcHViTVBJcywgXCJmb29iYXJcIikpO1xuICBcbiAgdmFyIHN5bW1BbGdvID0gXCJhZXMyNTZcIjsgLy8gQUVTMjU2XG4gIHZhciBzeW1tS2V5ID0gb3BlbnBncC5jcnlwdG8uZ2VuZXJhdGVTZXNzaW9uS2V5KHN5bW1BbGdvKTtcbiAgdmFyIHN5bW1lbmNEYXRhT0NGQiA9IG9wZW5wZ3AuY3J5cHRvLmNmYi5lbmNyeXB0KG9wZW5wZ3AuY3J5cHRvLmdldFByZWZpeFJhbmRvbShzeW1tQWxnbyksIHN5bW1BbGdvLCBcImZvb2JhcmZvb2JhcjEyMzQ1Njc4OTBcIiwgc3ltbUtleSwgdHJ1ZSk7XG4gIHZhciBzeW1tZW5jRGF0YUNGQiAgPSBvcGVucGdwLmNyeXB0by5jZmIuZW5jcnlwdChvcGVucGdwLmNyeXB0by5nZXRQcmVmaXhSYW5kb20oc3ltbUFsZ28pLCBzeW1tQWxnbywgXCJmb29iYXJmb29iYXIxMjM0NTY3ODkwXCIsIHN5bW1LZXksIGZhbHNlKTtcbiAgXG4gIHJlc3VsdFsyXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3Rpbmcgc3ltbWV0cmljIGVuY3J5cHQgYW5kIGRlY3J5cHQgd2l0aCBPcGVuUEdQIENGQiByZXN5bmNcIixcbiAgICAgIG9wZW5wZ3AuY3J5cHRvLmNmYi5kZWNyeXB0KHN5bW1BbGdvLHN5bW1LZXksc3ltbWVuY0RhdGFPQ0ZCLHRydWUpID09IFwiZm9vYmFyZm9vYmFyMTIzNDU2Nzg5MFwiKTtcbiAgcmVzdWx0WzNdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBzeW1tZXRyaWMgZW5jcnlwdCBhbmQgZGVjcnlwdCB3aXRob3V0IE9wZW5QR1AgQ0ZCIHJlc3luYyAodXNlZCBpbiBtb2RpZmljYXRpb24gZGV0ZWN0aW9uIGNvZGUgXFxcIk1EQ1xcXCIgcGFja2V0cylcIixcbiAgICAgIG9wZW5wZ3AuY3J5cHRvLmNmYi5kZWNyeXB0KHN5bW1BbGdvLHN5bW1LZXksc3ltbWVuY0RhdGFDRkIsZmFsc2UpID09IFwiZm9vYmFyZm9vYmFyMTIzNDU2Nzg5MFwiKTtcbiAgXG4gIHZhciBSU0FVbmVuY3J5cHRlZERhdGEgPSBuZXcgb3BlbnBncC5tcGkoKTtcbiAgUlNBVW5lbmNyeXB0ZWREYXRhLmZyb21CeXRlcyhvcGVucGdwLmNyeXB0by5wa2NzMS5lbWUuZW5jb2RlKHN5bW1LZXksIFJTQXB1Yk1QSXNbMF0uYnl0ZUxlbmd0aCgpKSk7XG4gIHZhciBSU0FFbmNyeXB0ZWREYXRhID0gb3BlbnBncC5jcnlwdG8ucHVibGljS2V5RW5jcnlwdChcInJzYV9lbmNyeXB0X3NpZ25cIiwgUlNBcHViTVBJcywgUlNBVW5lbmNyeXB0ZWREYXRhKTtcblxuICByZXN1bHRbNF0gPSBuZXcgdW5pdC5yZXN1bHQoXCJUZXN0aW5nIGFzeW1tZXRyaWMgZW5jcnlwdCBhbmQgZGVjcnlwdCB1c2luZyBSU0Egd2l0aCBlbWVfcGtjczEgcGFkZGluZ1wiLFxuICAgICAgb3BlbnBncC5jcnlwdG8ucGtjczEuZW1lLmRlY29kZShvcGVucGdwLmNyeXB0by5wdWJsaWNLZXlEZWNyeXB0KFwicnNhX2VuY3J5cHRfc2lnblwiLCBSU0FwdWJNUElzLmNvbmNhdChSU0FzZWNNUElzKSwgUlNBRW5jcnlwdGVkRGF0YSkud3JpdGUoKS5zdWJzdHJpbmcoMiksIFJTQXB1Yk1QSXNbMF0uYnl0ZUxlbmd0aCgpKSA9PSBzeW1tS2V5KTtcblxuICB2YXIgRWxnYW1hbFVuZW5jcnlwdGVkRGF0YSA9IG5ldyBvcGVucGdwLm1waSgpO1xuICBFbGdhbWFsVW5lbmNyeXB0ZWREYXRhLmZyb21CeXRlcyhvcGVucGdwLmNyeXB0by5wa2NzMS5lbWUuZW5jb2RlKHN5bW1LZXksIEVsZ2FtYWxwdWJNUElzWzBdLmJ5dGVMZW5ndGgoKSkpO1xuICB2YXIgRWxnYW1hbEVuY3J5cHRlZERhdGEgPSBvcGVucGdwLmNyeXB0by5wdWJsaWNLZXlFbmNyeXB0KFwiZWxnYW1hbFwiLCBFbGdhbWFscHViTVBJcywgRWxnYW1hbFVuZW5jcnlwdGVkRGF0YSk7XG5cbiAgcmVzdWx0WzVdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBhc3ltbWV0cmljIGVuY3J5cHQgYW5kIGRlY3J5cHQgdXNpbmcgRWxnYW1hbCB3aXRoIGVtZV9wa2NzMSBwYWRkaW5nXCIsXG4gICAgICBvcGVucGdwLmNyeXB0by5wa2NzMS5lbWUuZGVjb2RlKG9wZW5wZ3AuY3J5cHRvLnB1YmxpY0tleURlY3J5cHQoXCJlbGdhbWFsXCIsIEVsZ2FtYWxwdWJNUElzLmNvbmNhdChFbGdhbWFsc2VjTVBJcyksIEVsZ2FtYWxFbmNyeXB0ZWREYXRhKS53cml0ZSgpLnN1YnN0cmluZygyKSwgRWxnYW1hbHB1Yk1QSXNbMF0uYnl0ZUxlbmd0aCgpKSA9PSBzeW1tS2V5KTtcblxuICByZXR1cm4gcmVzdWx0O1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uLy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIk1ENSB0ZXN0IHdpdGggdGVzdCB2ZWN0b3JzIGZyb20gUkZDIDEzMjFcIiwgZnVuY3Rpb24oKSB7XG5cdHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vLi4vJyksXG5cdFx0dXRpbCA9IG9wZW5wZ3AudXRpbCxcblx0XHRNRDUgPSBvcGVucGdwLmNyeXB0by5oYXNoLm1kNTtcblxuXHR2YXIgcmVzdWx0ID0gbmV3IEFycmF5KCk7XG5cdHJlc3VsdFswXSA9IG5ldyB1bml0LnJlc3VsdChcIk1ENSAoXFxcIlxcXCIpID0gZDQxZDhjZDk4ZjAwYjIwNGU5ODAwOTk4ZWNmODQyN2VcIixcblx0XHRcdHV0aWwuaGV4c3RyZHVtcChNRDUoXCJcIikpID09IFwiZDQxZDhjZDk4ZjAwYjIwNGU5ODAwOTk4ZWNmODQyN2VcIik7XG5cdHJlc3VsdFsxXSA9IG5ldyB1bml0LnJlc3VsdChcIk1ENSAoXFxcImFcXFwiKSA9IDBjYzE3NWI5YzBmMWI2YTgzMWMzOTllMjY5NzcyNjYxXCIsXG5cdFx0XHR1dGlsLmhleHN0cmR1bXAoTUQ1IChcImFiY1wiKSkgPT0gXCI5MDAxNTA5ODNjZDI0ZmIwZDY5NjNmN2QyOGUxN2Y3MlwiKTtcblx0cmVzdWx0WzJdID0gbmV3IHVuaXQucmVzdWx0KFwiTUQ1IChcXFwibWVzc2FnZSBkaWdlc3RcXFwiKSA9IGY5NmI2OTdkN2NiNzkzOGQ1MjVhMmYzMWFhZjE2MWQwXCIsXG5cdFx0XHR1dGlsLmhleHN0cmR1bXAoTUQ1IChcIm1lc3NhZ2UgZGlnZXN0XCIpKSA9PSBcImY5NmI2OTdkN2NiNzkzOGQ1MjVhMmYzMWFhZjE2MWQwXCIpO1xuXHRyZXN1bHRbM10gPSBuZXcgdW5pdC5yZXN1bHQoXCJNRDUgKFxcXCJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elxcXCIpID0gYzNmY2QzZDc2MTkyZTQwMDdkZmI0OTZjY2E2N2UxM2JcIixcblx0XHRcdHV0aWwuaGV4c3RyZHVtcChNRDUgKFwiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIikpID09IFwiYzNmY2QzZDc2MTkyZTQwMDdkZmI0OTZjY2E2N2UxM2JcIik7XG5cdHJlc3VsdFs0XSA9IG5ldyB1bml0LnJlc3VsdChcIk1ENSAoXFxcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5XFxcIikgPSBkMTc0YWI5OGQyNzdkOWY1YTU2MTFjMmM5ZjQxOWQ5ZlwiLFxuXHRcdFx0dXRpbC5oZXhzdHJkdW1wKE1ENSAoXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OVwiKSkgPT0gXCJkMTc0YWI5OGQyNzdkOWY1YTU2MTFjMmM5ZjQxOWQ5ZlwiKTtcblx0cmVzdWx0WzVdID0gbmV3IHVuaXQucmVzdWx0KFwiTUQ1IChcXFwiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTBcXFwiKSA9IDU3ZWRmNGEyMmJlM2M5NTVhYzQ5ZGEyZTIxMDdiNjdhXCIsXG5cdFx0XHR1dGlsLmhleHN0cmR1bXAoTUQ1IChcIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwXCIpKSA9PSBcIjU3ZWRmNGEyMmJlM2M5NTVhYzQ5ZGEyZTIxMDdiNjdhXCIpO1xuXHRyZXR1cm4gcmVzdWx0O1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uLy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIlJJUEUtTUQgMTYwIGJpdHMgdGVzdCB3aXRoIHRlc3QgdmVjdG9ycyBmcm9tIGh0dHA6Ly9ob21lcy5lc2F0Lmt1bGV1dmVuLmJlL35ib3NzZWxhZS9yaXBlbWQxNjAuaHRtbFwiLCBmdW5jdGlvbigpIHtcblxuXHR2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLy4uLycpLFxuXHRcdHV0aWwgPSBvcGVucGdwLnV0aWwsXG5cdFx0Uk1Ec3RyaW5nID0gb3BlbnBncC5jcnlwdG8uaGFzaC5yaXBlbWQ7XG5cblx0dmFyIHJlc3VsdCA9IG5ldyBBcnJheSgpO1xuXHRyZXN1bHRbMF0gPSBuZXcgdW5pdC5yZXN1bHQoXCJSTURzdHJpbmcgKFxcXCJcXFwiKSA9IDljMTE4NWE1YzVlOWZjNTQ2MTI4MDg5NzdlZThmNTQ4YjIyNThkMzFcIixcblx0XHRcdHV0aWwuaGV4c3RyZHVtcChSTURzdHJpbmcoXCJcIikpID09IFwiOWMxMTg1YTVjNWU5ZmM1NDYxMjgwODk3N2VlOGY1NDhiMjI1OGQzMVwiKTtcblx0cmVzdWx0WzFdID0gbmV3IHVuaXQucmVzdWx0KFwiUk1Ec3RyaW5nIChcXFwiYVxcXCIpID0gMGJkYzlkMmQyNTZiM2VlOWRhYWUzNDdiZTZmNGRjODM1YTQ2N2ZmZVwiLFxuXHRcdFx0dXRpbC5oZXhzdHJkdW1wKFJNRHN0cmluZyhcImFcIikpID09IFwiMGJkYzlkMmQyNTZiM2VlOWRhYWUzNDdiZTZmNGRjODM1YTQ2N2ZmZVwiKTtcblx0cmVzdWx0WzJdID0gbmV3IHVuaXQucmVzdWx0KFwiUk1Ec3RyaW5nIChcXFwiYWJjXFxcIikgPSA4ZWIyMDhmN2UwNWQ5ODdhOWIwNDRhOGU5OGM2YjA4N2YxNWEwYmZjXCIsXG5cdFx0XHR1dGlsLmhleHN0cmR1bXAoUk1Ec3RyaW5nKFwiYWJjXCIpKSA9PSBcIjhlYjIwOGY3ZTA1ZDk4N2E5YjA0NGE4ZTk4YzZiMDg3ZjE1YTBiZmNcIik7XG5cdHJlc3VsdFszXSA9IG5ldyB1bml0LnJlc3VsdChcIlJNRHN0cmluZyAoXFxcIm1lc3NhZ2UgZGlnZXN0XFxcIikgPSA1ZDA2ODllZjQ5ZDJmYWU1NzJiODgxYjEyM2E4NWZmYTIxNTk1ZjM2XCIsXG5cdFx0XHR1dGlsLmhleHN0cmR1bXAoUk1Ec3RyaW5nKFwibWVzc2FnZSBkaWdlc3RcIikpID09IFwiNWQwNjg5ZWY0OWQyZmFlNTcyYjg4MWIxMjNhODVmZmEyMTU5NWYzNlwiKTtcblx0cmV0dXJuIHJlc3VsdDtcbn0pO1xuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi8uLi91bml0LmpzJyk7XG5cblxudW5pdC5yZWdpc3RlcihcIlNIQSogdGVzdCB3aXRoIHRlc3QgdmVjdG9ycyBmcm9tIE5JU1QgRklQUyAxODAtMlwiLCBmdW5jdGlvbigpIHtcblx0dmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8uLi8nKSxcblx0XHR1dGlsID0gb3BlbnBncC51dGlsLFxuXHRcdGhhc2ggPSBvcGVucGdwLmNyeXB0by5oYXNoO1xuXG5cdHZhciByZXN1bHQgPSBuZXcgQXJyYXkoKTtcblx0XG5cdHJlc3VsdFswXSA9IG5ldyB1bml0LnJlc3VsdChcIlNIQTEgLSBhOTk5M2UzNjQ3MDY4MTZhYmEzZTI1NzE3ODUwYzI2YzljZDBkODlkID0gaGFzaC5zaGExKFxcXCJhYmNcXFwiKSBcIixcblx0XHRcdFwiYTk5OTNlMzY0NzA2ODE2YWJhM2UyNTcxNzg1MGMyNmM5Y2QwZDg5ZFwiID09IHV0aWwuaGV4c3RyZHVtcChoYXNoLnNoYTEoXCJhYmNcIikpKTtcblx0cmVzdWx0WzFdID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBMSAtIDg0OTgzZTQ0MWMzYmQyNmViYWFlNGFhMWY5NTEyOWU1ZTU0NjcwZjEgPSBoYXNoLnNoYTEoXFxcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXFxcIikgXCIsXG5cdFx0XHRcIjg0OTgzZTQ0MWMzYmQyNmViYWFlNGFhMWY5NTEyOWU1ZTU0NjcwZjFcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGExKFwiYWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHFcIikpKTtcblx0cmVzdWx0WzJdID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBMjI0IC0gMjMwOTdkMjIzNDA1ZDgyMjg2NDJhNDc3YmRhMjU1YjMyYWFkYmNlNGJkYTBiM2Y3ZTM2YzlkYTcgPSBoYXNoLnNoYTIyNChcXFwiYWJjXFxcIikgXCIsXG5cdFx0XHRcIjIzMDk3ZDIyMzQwNWQ4MjI4NjQyYTQ3N2JkYTI1NWIzMmFhZGJjZTRiZGEwYjNmN2UzNmM5ZGE3XCIgPT0gdXRpbC5oZXhzdHJkdW1wKGhhc2guc2hhMjI0KFwiYWJjXCIpKSk7XG5cdHJlc3VsdFszXSA9IG5ldyB1bml0LnJlc3VsdChcIlNIQTIyNCAtIDc1Mzg4YjE2NTEyNzc2Y2M1ZGJhNWRhMWZkODkwMTUwYjBjNjQ1NWNiNGY1OGIxOTUyNTIyNTI1ID0gaGFzaC5zaGEyMjQoXFxcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXFxcIikgXCIsXG5cdFx0XHRcIjc1Mzg4YjE2NTEyNzc2Y2M1ZGJhNWRhMWZkODkwMTUwYjBjNjQ1NWNiNGY1OGIxOTUyNTIyNTI1XCIgPT0gdXRpbC5oZXhzdHJkdW1wKGhhc2guc2hhMjI0KFwiYWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHFcIikpKTtcblx0cmVzdWx0WzRdID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBMjU2IC0gYmE3ODE2YmY4ZjAxY2ZlYTQxNDE0MGRlNWRhZTIyMjNiMDAzNjFhMzk2MTc3YTljYjQxMGZmNjFmMjAwMTVhZCA9IGhhc2guc2hhMjU2KFxcXCJhYmNcXFwiKSBcIixcblx0XHRcdFwiYmE3ODE2YmY4ZjAxY2ZlYTQxNDE0MGRlNWRhZTIyMjNiMDAzNjFhMzk2MTc3YTljYjQxMGZmNjFmMjAwMTVhZFwiID09IHV0aWwuaGV4c3RyZHVtcChoYXNoLnNoYTI1NihcImFiY1wiKSkpO1xuXHRyZXN1bHRbNV0gPSBuZXcgdW5pdC5yZXN1bHQoXCJTSEEyNTYgLSAyNDhkNmE2MWQyMDYzOGI4ZTVjMDI2OTMwYzNlNjAzOWEzM2NlNDU5NjRmZjIxNjdmNmVjZWRkNDE5ZGIwNmMxID0gaGFzaC5zaGEyNTYoXFxcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXFxcIikgXCIsXG5cdFx0XHRcIjI0OGQ2YTYxZDIwNjM4YjhlNWMwMjY5MzBjM2U2MDM5YTMzY2U0NTk2NGZmMjE2N2Y2ZWNlZGQ0MTlkYjA2YzFcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGEyNTYoXCJhYmNkYmNkZWNkZWZkZWZnZWZnaGZnaGlnaGlqaGlqa2lqa2xqa2xta2xtbmxtbm9tbm9wbm9wcVwiKSkpO1xuXHRyZXN1bHRbNl0gPSBuZXcgdW5pdC5yZXN1bHQoXCJTSEEzODQgLSBjYjAwNzUzZjQ1YTM1ZThiYjVhMDNkNjk5YWM2NTAwNzI3MmMzMmFiMGVkZWQxNjMxYThiNjA1YTQzZmY1YmVkODA4NjA3MmJhMWU3Y2MyMzU4YmFlY2ExMzRjODI1YTcgPSBoYXNoLnNoYTM4NChcXFwiYWJjXFxcIikgXCIsXG5cdFx0XHRcImNiMDA3NTNmNDVhMzVlOGJiNWEwM2Q2OTlhYzY1MDA3MjcyYzMyYWIwZWRlZDE2MzFhOGI2MDVhNDNmZjViZWQ4MDg2MDcyYmExZTdjYzIzNThiYWVjYTEzNGM4MjVhN1wiID09IHV0aWwuaGV4c3RyZHVtcChoYXNoLnNoYTM4NChcImFiY1wiKSkpO1xuXHRyZXN1bHRbN10gPSBuZXcgdW5pdC5yZXN1bHQoXCJTSEEzODQgLSAzMzkxZmRkZGZjOGRjNzM5MzcwN2E2NWIxYjQ3MDkzOTdjZjhiMWQxNjJhZjA1YWJmZThmNDUwZGU1ZjM2YmM2YjA0NTVhODUyMGJjNGU2ZjVmZTk1YjFmZTNjODQ1MmIgPSBzdHIzODQoXFxcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXFxcIikgXCIsXG5cdFx0XHRcIjMzOTFmZGRkZmM4ZGM3MzkzNzA3YTY1YjFiNDcwOTM5N2NmOGIxZDE2MmFmMDVhYmZlOGY0NTBkZTVmMzZiYzZiMDQ1NWE4NTIwYmM0ZTZmNWZlOTViMWZlM2M4NDUyYlwiID09IHV0aWwuaGV4c3RyZHVtcChoYXNoLnNoYTM4NChcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXCIpKSk7XHRcdFx0XHRcdFxuXHRyZXN1bHRbOF0gPSBuZXcgdW5pdC5yZXN1bHQoXCJTSEE1MTIgLSBkZGFmMzVhMTkzNjE3YWJhY2M0MTczNDlhZTIwNDEzMTEyZTZmYTRlODlhOTdlYTIwYTllZWVlNjRiNTVkMzlhMjE5Mjk5MmEyNzRmYzFhODM2YmEzYzIzYTNmZWViYmQ0NTRkNDQyMzY0M2NlODBlMmE5YWM5NGZhNTRjYTQ5ZiA9IGhhc2guc2hhNTEyKFxcXCJhYmNcXFwiKSBcIixcblx0XHRcdFwiZGRhZjM1YTE5MzYxN2FiYWNjNDE3MzQ5YWUyMDQxMzExMmU2ZmE0ZTg5YTk3ZWEyMGE5ZWVlZTY0YjU1ZDM5YTIxOTI5OTJhMjc0ZmMxYTgzNmJhM2MyM2EzZmVlYmJkNDU0ZDQ0MjM2NDNjZTgwZTJhOWFjOTRmYTU0Y2E0OWZcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGE1MTIoXCJhYmNcIikpKTtcblx0cmVzdWx0WzldID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBNTEyIC0gMjA0YThmYzZkZGE4MmYwYTBjZWQ3YmViOGUwOGE0MTY1N2MxNmVmNDY4YjIyOGE4Mjc5YmUzMzFhNzAzYzMzNTk2ZmQxNWMxM2IxYjA3ZjlhYTFkM2JlYTU3Nzg5Y2EwMzFhZDg1YzdhNzFkZDcwMzU0ZWM2MzEyMzhjYTM0NDUgPSBoYXNoLnNoYTUxMihcXFwiYWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHFcXFwiKSBcIixcblx0XHRcdFwiMjA0YThmYzZkZGE4MmYwYTBjZWQ3YmViOGUwOGE0MTY1N2MxNmVmNDY4YjIyOGE4Mjc5YmUzMzFhNzAzYzMzNTk2ZmQxNWMxM2IxYjA3ZjlhYTFkM2JlYTU3Nzg5Y2EwMzFhZDg1YzdhNzFkZDcwMzU0ZWM2MzEyMzhjYTM0NDVcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGE1MTIoXCJhYmNkYmNkZWNkZWZkZWZnZWZnaGZnaGlnaGlqaGlqa2lqa2xqa2xta2xtbmxtbm9tbm9wbm9wcVwiKSkpO1x0XHRcdFx0XHRcblx0cmV0dXJuIHJlc3VsdDtcbn0pO1xuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJLZXkgZ2VuZXJhdGlvbi9lbmNyeXB0aW9uL2RlY3J5cHRpb25cIiwgZnVuY3Rpb24oKSB7XG4gIHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vJyk7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIHRlc3RIZWxwZXIgPSBmdW5jdGlvbihwYXNzcGhyYXNlLCB1c2VyaWQsIG1lc3NhZ2UpIHtcbiAgICB2YXIga2V5ID0gb3BlbnBncC5nZW5lcmF0ZUtleVBhaXIob3BlbnBncC5lbnVtcy5wdWJsaWNLZXkucnNhX2VuY3J5cHRfc2lnbiwgNTEyLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlcmlkLCBwYXNzcGhyYXNlKTtcblxuICAgIHZhciBpbmZvID0gJ1xcbnBhc3NwaHJhc2U6ICcgKyBwYXNzcGhyYXNlICsgJ1xcbidcbiAgICAgICAgKyAndXNlcmlkOiAnICsgdXNlcmlkICsgJ1xcbidcbiAgICAgICAgKyAnbWVzc2FnZTogJyArIG1lc3NhZ2U7XG5cbiAgICB2YXIgcHJpdktleSA9IG9wZW5wZ3Aua2V5LnJlYWRBcm1vcmVkKGtleS5wcml2YXRlS2V5QXJtb3JlZCk7XG5cbiAgICB2YXIgZW5jcnlwdGVkID0gb3BlbnBncC5lbmNyeXB0TWVzc2FnZShbcHJpdktleV0sIG1lc3NhZ2UpO1xuXG4gICAgdmFyIG1zZyA9IG9wZW5wZ3AubWVzc2FnZS5yZWFkQXJtb3JlZChlbmNyeXB0ZWQpO1xuXG4gICAgdmFyIGtleWlkcyA9IG1zZy5nZXRFbmNyeXB0aW9uS2V5SWRzKCk7XG5cbiAgICBwcml2S2V5LmRlY3J5cHRLZXlQYWNrZXQoa2V5aWRzLCBwYXNzcGhyYXNlKTtcblxuICAgIHRyeSB7XG4gICAgICB2YXIgZGVjcnlwdGVkID0gb3BlbnBncC5kZWNyeXB0TWVzc2FnZShwcml2S2V5LCBtc2cpO1xuICAgICAgcmV0dXJuIG5ldyB1bml0LnJlc3VsdChtZXNzYWdlICsgJyA9PSAnICsgZGVjcnlwdGVkICsgaW5mbywgbWVzc2FnZSA9PSBkZWNyeXB0ZWQpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBuZXcgdW5pdC5yZXN1bHQoXCJFeGNlcHRpb24gb24gZGVjcnlwdCBvZiBwcml2YXRlIGtleSBwYWNrZXQhXCIgKyBpbmZvLCBmYWxzZSk7XG4gICAgfVxuXG4gIH07XG5cbiAgcmVzdWx0LnB1c2godGVzdEhlbHBlcigncGFzc3dvcmQnLCAnVGVzdCBNY1Rlc3Rpbmd0b24gPHRlc3RAZXhhbXBsZS5jb20+JywgJ2hlbGxvIHdvcmxkJykpO1xuICByZXN1bHQucHVzaCh0ZXN0SGVscGVyKCfil4/il4/il4/il48nLCAn4pmU4pmU4pmU4pmUIDx0ZXN0QGV4YW1wbGUuY29tPicsICfFgsOkw7PEhycpKTtcblxuICByZXR1cm4gcmVzdWx0O1xufSk7XG5cbnVuaXQucmVnaXN0ZXIoXCJNZXNzYWdlIGVuY3J5cHRpb24vZGVjcnlwdGlvblwiLCBmdW5jdGlvbigpIHtcbiAgdmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8nKTtcblxuICB2YXIgcmVzdWx0ID0gW107XG5cbiAgdmFyIHB1Yl9rZXkgPSBcbiAgICAgWyctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0nLFxuICAgICAgJ1ZlcnNpb246IEdudVBHIHYyLjAuMTkgKEdOVS9MaW51eCknLFxuICAgICAgJ1R5cGU6IFJTQS9SU0EnLFxuICAgICAgJycsXG4gICAgICAnbUkwRVVtRXZUZ0VFQU55V3RRUU1PeWJROUpsdERxbWFYMFduTlBKZUxJTElNMzZzdzZ6TDBuZlRRNXpYU1MzKycsXG4gICAgICAnZklGNlAyOWxKRnhwYmxXazAyUFNJRDV6WC9EWVU5L3pqTTJ4UE84T2E0eG8wY1ZUT1RMaisrUmk1bXRyLy9mNScsXG4gICAgICAnR0xzSVh4RnJCSmhEL2doRnNMM09wMEdYT2VMSjlBNWJzT244dGg3eDZKdWNOS3VhUkI2YlFiU1BBQkVCQUFHMCcsXG4gICAgICAnSkZSbGMzUWdUV05VWlhOMGFXNW5kRzl1SUR4MFpYTjBRR1Y0WVcxd2JHVXVZMjl0UG9pNUJCTUJBZ0FqQlFKUycsXG4gICAgICAnWVM5T0Foc3ZCd3NKQ0FjREFnRUdGUWdDQ1FvTEJCWUNBd0VDSGdFQ0Y0QUFDZ2tRU21OaE9rMXVRSlF3REFQNicsXG4gICAgICAnQWdyVHlxa1JsSlZxejJwYjQ2VGZiRE0yVERGN285Q0JuQnpJR294QmhsUndwcUFMejd6Mmt4QkRtd3BRYStraScsXG4gICAgICAnQnEzalpOL1Vvc1k5eThiaHdNQWxuckRZOWpQMWdkQ28rSDBzRDQ4Q2RYeWJibE53YVlwd3FDOFZTcERkVG5kZicsXG4gICAgICAnOWoyd0Uvd2VpaEdwL0RBZHkvMmt5QkNhaU9ZMXNqaFVmSjFHb2dGNDlyQzRqUVJTWVM5T0FRUUE2Ui9QdEJGYScsXG4gICAgICAnSmFUNGpxMTB5cUFTazRzcXdWTXNjNkhjaWZNNWxTZHh6RXhGUDc0bmFVTU15RXNLSFA1M1F4VEYwR3JxdXNhZycsXG4gICAgICAnUWcvWnRnVDBDTjFIVU0xNTJ5N0FDT2RwMWdpS2pwTXpPVFFDbHFDb2NseXZXT0ZCK0wvU3dHRUlKZjdMU0NFcicsXG4gICAgICAnd29CdUppZkpjOHhBVnIwWFgwSnRob1crdVA5MWVUUTNYcHNBRVFFQUFZa0JQUVFZQVFJQUNRVUNVbUV2VGdJYicsXG4gICAgICAnTGdDb0NSQktZMkU2VFc1QWxKMGdCQmtCQWdBR0JRSlNZUzlPQUFvSkVPQ0U5MFJzSUN5WHVxSUVBTm1taVJDQScsXG4gICAgICAnU0Y3WUs3UHZGa2llSk53emVLMFYzRjJsR1grdXU2WTNRL1p4ZHR3YzR4UittZS9DU0Jtc1VSeVhUTzI5T1doUCcsXG4gICAgICAnR0xzelBIOXpTSlU5QmREaTZ2MHlOcHJtRlBYLzFOZzBBYm4vc0Nrd2V0dmp4QzFZSXZUTEZ3dFVMLzd2Nk5TMicsXG4gICAgICAnYlpwc1V4UlRnOStjU3JNV1dTTmppWTlxVUtham0xdHV6UERaWEFVRUFNTm1BTjN4WE4vS2p5dmoyT0syY2swWCcsXG4gICAgICAnVzc0OHNsL3RjM3FpS1BNSiswQWtNRjdQamhtaDlueHFFOStRQ0VsN3FpbkZxcUJManV6Z1VoQlU0UWx3WDFHRCcsXG4gICAgICAnQXROVHE2aWhMTUQ1djFkODJaQzd0TmF0ZGxETUdXbklkdkVNQ3YyR1pjdUlxRFE5clhXczQ5ZTd0cTFObmNMWScsXG4gICAgICAnaHozdFlqS2hvRlRLRUlxM3kzUHAnLFxuICAgICAgJz1oL2FYJyxcbiAgICAgICctLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tJ10uam9pbignXFxuJyk7XG5cbiAgdmFyIHByaXZfa2V5ID1cbiAgICAgIFsnLS0tLS1CRUdJTiBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLScsXG4gICAgICAnVmVyc2lvbjogR251UEcgdjIuMC4xOSAoR05VL0xpbnV4KScsXG4gICAgICAnVHlwZTogUlNBL1JTQScsXG4gICAgICAnUHdkOiBoZWxsbyB3b3JsZCcsXG4gICAgICAnJyxcbiAgICAgICdsUUgrQkZKaEwwNEJCQURjbHJVRUREc20wUFNaYlE2cG1sOUZwelR5WGl5Q3lETityTU9zeTlKMzAwT2MxMGt0JyxcbiAgICAgICcvbnlCZWo5dlpTUmNhVzVWcE5OajBpQStjMS93MkZQZjg0ek5zVHp2RG11TWFOSEZVemt5NC92a1l1WnJhLy8zJyxcbiAgICAgICcrUmk3Q0Y4UmF3U1lRLzRJUmJDOXpxZEJsem5peWZRT1c3RHAvTFllOGVpYm5EU3Jta1FlbTBHMGp3QVJBUUFCJyxcbiAgICAgICcvZ01EQXU3TC8vY3pCcEU0MHAxWnFPOEszazdVZWplbWpzUXFjN2tPcW5sRFlkMVo2LzNORUEvVU0zMFNpaXByJyxcbiAgICAgICdLamRJRlk1K2hwMGhjczZFaWlOcTBQRGZtL1cyais3SGZyWjVrcGVRVnhEZWs0aXJlellacmw3SlMyeGV6YUx2JyxcbiAgICAgICdrMEZ2LzZmeGFzbkZ0ak9NNlFic3R1NjdzNUdwbDl5MDZaeGJQM1ZwVDYyK1hlaWJuL3N3V3JmaUpqdUdFRWhNJyxcbiAgICAgICdiZ25zTXBIdHpBei9MOHk2S1N6VmlHLzA1aEJhcXJ2azMvR2VFQTZuRStvMCswYTZyMExZTFRlbW1xNkZiYUExJyxcbiAgICAgICdQSG8reDdrN29GY0JGVVVlU3pneDc4R2NrdVB3cXIybU5mZUYrSXVTUm5ybHBabDNrY2JIQVNQQU9mRWt5TVhTJyxcbiAgICAgICdzV0dFN2dyQ0FqYnlReU0zT0VYVFN5cW5laHZHUy8xUmRCNmtERHhHd2dFL1FGYndOeUVoNks0ZWFhQVRoVzJqJyxcbiAgICAgICdJRUVJMFdFblJrUGk5Zlh5eGhGc0NMU0kxWGhxVGFxN2lETnFKVHhFK0FYMmI5WnVaWEF4STNUYy83Kyt2RXlMJyxcbiAgICAgICczcDE4Ti9NQjJrdDFXYjFhem1YV0wyRUtsVDFCWjV5RGFKdUJROEJocGhNM3RDUlVaWE4wSUUxalZHVnpkR2x1JyxcbiAgICAgICdaM1J2YmlBOGRHVnpkRUJsZUdGdGNHeGxMbU52YlQ2SXVRUVRBUUlBSXdVQ1VtRXZUZ0liTHdjTENRZ0hBd0lCJyxcbiAgICAgICdCaFVJQWdrS0N3UVdBZ01CQWg0QkFoZUFBQW9KRUVwallUcE5ia0NVTUF3RCtnSUswOHFwRVpTVmFzOXFXK09rJyxcbiAgICAgICczMnd6Tmt3eGU2UFFnWndjeUJxTVFZWlVjS2FnQzgrODlwTVFRNXNLVUd2cElnYXQ0MlRmMUtMR1Bjdkc0Y0RBJyxcbiAgICAgICdKWjZ3MlBZejlZSFFxUGg5TEErUEFuVjhtMjVUY0dtS2NLZ3ZGVXFRM1U1M1gvWTlzQlA4SG9vUnFmd3dIY3Y5JyxcbiAgICAgICdwTWdRbW9qbU5iSTRWSHlkUnFJQmVQYXduUUgrQkZKaEwwNEJCQURwSDgrMEVWb2xwUGlPclhUS29CS1RpeXJCJyxcbiAgICAgICdVeXh6b2R5Sjh6bVZKM0hNVEVVL3ZpZHBRd3pJU3dvYy9uZERGTVhRYXVxNnhxQkNEOW0yQlBRSTNVZFF6WG5iJyxcbiAgICAgICdMc0FJNTJuV0NJcU9rek01TkFLV29LaHlYSzlZNFVINHY5TEFZUWdsL3N0SUlTdkNnRzRtSjhsenpFQld2UmRmJyxcbiAgICAgICdRbTJHaGI2NC8zVjVORGRlbXdBUkFRQUIvZ01EQXU3TC8vY3pCcEU0MGlQY3BMekw3R3dCYldGaFNXZ1NMeTUzJyxcbiAgICAgICdNZDk5S3h3M2NBcFdDb2syRThSOS80VlMwNDkweEtaSWE1eTJJL0s4dGhWaHFrOTZaOEtidDdNUk1DMVdMSGdDJyxcbiAgICAgICdxSnZrZVFDSTZQckZNMFBVSVBMSEFRdERKWUt0YUxYeFl1ZXhjQWRLelpqM0ZIZHRMTldDb29LNm4zdkpsTDFjJyxcbiAgICAgICdXalpjSEoxUEg3VVNsajFqdXA0WGZ4c2J6aXV5c1JVU3lYa2puOTJHWkxtKzY0dkNJaXdocUFZb2l6RjJOSEhHJyxcbiAgICAgICdoUlRONGdRenhyeGdrZVZjaGwrYWc3RGtRVURBTklJVkkrQTYzSmVMSmdXSmlIMWZiWWx3RVNCeUhXK3pCRk50JyxcbiAgICAgICdxU3RqZklPaGpyZk5JYzNSdnNnZ2JEZFdRTGNieG1MWmo0c0IweWRQU2dSS29hVWRSSEpZMFM0dnA5b3VLT3RsJyxcbiAgICAgICcyYXUvUDFCUDNiaEQwZkRYbDkxb2VoZVl0aCtNU21zSkZEZy92Wkp6Q0poRmFROWRwKzJFbmpONWF1TkNOYmFJJyxcbiAgICAgICdiZUZKUkhGZjljaGE4cDNoaCtBSzU0TlJDVCsrQjJNWFlmK1RQd3FYODhqWU1Cdjhrazh2WVVnbzgxMjhyMXpRJyxcbiAgICAgICdFemp2aVFFOUJCZ0JBZ0FKQlFKU1lTOU9BaHN1QUtnSkVFcGpZVHBOYmtDVW5TQUVHUUVDQUFZRkFsSmhMMDRBJyxcbiAgICAgICdDZ2tRNElUM1JHd2dMSmU2b2dRQTJhYUpFSUJJWHRncnMrOFdTSjRrM0RONHJSWGNYYVVaZjY2N3BqZEQ5bkYyJyxcbiAgICAgICczQnpqRkg2Wjc4SklHYXhSSEpkTTdiMDVhRThZdXpNOGYzTklsVDBGME9McS9USTJtdVlVOWYvVTJEUUJ1Zit3JyxcbiAgICAgICdLVEI2MitQRUxWZ2k5TXNYQzFRdi91L28xTFp0bW14VEZGT0QzNXhLc3haWkkyT0pqMnBRcHFPYlcyN004TmxjJyxcbiAgICAgICdCUVFBdzJZQTNmRmMzOHFQSytQWTRyWnlUUmRidmp5eVgrMXplcUlvOHduN1FDUXdYcytPR2FIMmZHb1QzNUFJJyxcbiAgICAgICdTWHVxS2NXcW9FdU83T0JTRUZUaENYQmZVWU1DMDFPcnFLRXN3UG0vVjN6WmtMdTAxcTEyVU13WmFjaDI4UXdLJyxcbiAgICAgICcvWVpseTRpb05EMnRkYXpqMTd1MnJVMmR3dGlIUGUxaU1xR2dWTW9RaXJmTGMraz0nLFxuICAgICAgJz1sdzVlJyxcbiAgICAgICctLS0tLUVORCBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLSddLmpvaW4oJ1xcbicpO1xuXG4gIHZhciBwbGFpbnRleHQgPSAnc2hvcnQgbWVzc2FnZVxcbm5leHQgbGluZVxcbu2VnOq1reyWtC/sobDshKDrp5AnO1xuXG4gIHZhciBrZXkgPSBvcGVucGdwLmtleS5yZWFkQXJtb3JlZChwdWJfa2V5KTtcblxuICB2YXIgZW5jcnlwdGVkID0gb3BlbnBncC5lbmNyeXB0TWVzc2FnZShba2V5XSwgcGxhaW50ZXh0KTtcblxuICB2YXIgbWVzc2FnZSA9IG9wZW5wZ3AubWVzc2FnZS5yZWFkQXJtb3JlZChlbmNyeXB0ZWQpO1xuXG4gIHZhciBwcml2S2V5ID0gb3BlbnBncC5rZXkucmVhZEFybW9yZWQocHJpdl9rZXkpO1xuXG4gIC8vIGdldCBrZXkgSURzIHRoZSBtZXNzYWdlIGlzIGVuY3J5cHRlZCBmb3JcbiAgdmFyIGtleWlkcyA9IG1lc3NhZ2UuZ2V0RW5jcnlwdGlvbktleUlkcygpO1xuXG4gIC8vIGRlY3J5cHQgb25seSByZXF1aXJlZCBrZXkgcGFja2V0c1xuICB2YXIgc3VjY2VzcyA9IHByaXZLZXkuZGVjcnlwdEtleVBhY2tldChrZXlpZHMsICdoZWxsbyB3aGF0PycpXG5cbiAgcmVzdWx0LnB1c2gobmV3IHVuaXQucmVzdWx0KCdEZWNyeXB0aW5nIGtleSBwYWNrZXQgd2l0aCB3cm9uZyBwYXNzd29yZCByZXR1cm5zIGZhbHNlJywgIXN1Y2Nlc3MpKTtcblxuICB2YXIgZGVjcnlwdGVkLCBlcnJvcjtcbiAgdHJ5IHtcbiAgICBkZWNyeXB0ZWQgPSBvcGVucGdwLmRlY3J5cHRNZXNzYWdlKHByaXZLZXksIG1lc3NhZ2UpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyb3IgPSBlO1xuICB9XG4gIHJlc3VsdC5wdXNoKG5ldyB1bml0LnJlc3VsdCgnQ2FsbGluZyBkZWNyeXB0TWVzc2FnZSB3aXRoIG5vdCBkZWNyeXB0ZWQga2V5IHBhY2tldCBsZWFkcyB0byBleGNlcHRpb246IFxcJycgKyAoZXJyb3IgfHwgJycpICsgJ1xcJycsIGVycm9yKSk7XG5cbiAgc3VjY2VzcyA9IHByaXZLZXkuZGVjcnlwdEtleVBhY2tldChrZXlpZHMsICdoZWxsbyB3b3JsZCcpO1xuXG4gIHJlc3VsdC5wdXNoKG5ldyB1bml0LnJlc3VsdCgnRGVjcnlwdGluZyBrZXkgcGFja2V0IHdpdGggY29ycmVjdCBwYXNzd29yZCByZXR1cm5zIHRydWUnLCBzdWNjZXNzKSk7XG5cbiAgZGVjcnlwdGVkID0gb3BlbnBncC5kZWNyeXB0TWVzc2FnZShwcml2S2V5LCBtZXNzYWdlKTtcblxuICByZXN1bHQucHVzaChuZXcgdW5pdC5yZXN1bHQoJ0VuY3J5cHQgcGxhaW4gdGV4dCBhbmQgYWZ0ZXJ3YXJkcyBkZWNyeXB0IGxlYWRzIHRvIHNhbWUgcmVzdWx0JywgcGxhaW50ZXh0ID09IGRlY3J5cHRlZCkpO1xuXG4gIHJldHVybiByZXN1bHQ7XG5cbn0pO1xuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJLZXlyaW5nIHRlc3RpbmdcIiwgZnVuY3Rpb24oKSB7XG4gIHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vJyk7XG4gIHZhciBrZXlyaW5nID0gcmVxdWlyZSgnLi4vLi4vc3JjL2tleXJpbmcuanMnKTtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gIC8vIEV4ZXJjaXNlcyB0aGUgYWJpbGl0eSBvZiBvcGVucGdwX2tleXJpbmcuZ2V0UHVibGljS2V5c0ZvcktleUlkIHRvIHJldHVybiBzdWJrZXlzXG4gIGtleXJpbmcuaW5pdCgpO1xuICBrZXlyaW5nLmltcG9ydFBhY2tldGxpc3QoW1xuICAgICAgICAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tJyxcbiAgICAgICAgJ1ZlcnNpb246IEdudVBHIHYxLjQuMTEgKEdOVS9MaW51eCknLFxuICAgICAgICAnJyxcbiAgICAgICAgJ21RR2lCRkVSdkk0UkJBRDBNL0hHZ2xDdFZOWFBGNzJlaFQ4cmlBWHJsMHJTZWM0UkpDNjFCaCtVQU9oeG41K1UnLFxuICAgICAgICAnZkRnb3M1cDFTcEl6WW1uK004N0pvU1NWTEFqZmFrRmswZ0hnUjlJM2J1N1NJd3EzQmlrazFWdzNnTyt5RFNPNicsXG4gICAgICAgICdUS3BMVUZHWURpQlNTRTFNR2R4QmFkV0xFMWhsUmY1QjJ4NjJnbkdtalNwU1ZibHkzM1BGa29EbXJ3Q2c5ckFwJyxcbiAgICAgICAgJ1JtbmNuRjlHaFdqT0xGa0VvUXc5WXg4RUFPc3h2cThJZzVaMWdrK1pLZkRaZWZ0cEhSZTNGZHJSdGJuaHh2WVknLFxuICAgICAgICAnN3ordzl1ejFFcG9aVXdEUjVHNFgzaFR3SlE3bFhtSU9za2cvK2VSTUxFQXFFWTdiLzd0VzZSYVVKMmQ2RWhzaScsXG4gICAgICAgICdkT1M4OWZJeEVsd2pBT25WT001UzI0ZjBGRFFUVHRvN1FCT294Y05UZmtFSkNIWFNscG9PVW1HQVA4NWZYaDNsJyxcbiAgICAgICAgJ3lQVEdCQUNKZktjNzZVbjNVV0Mxc1dJUkR4WWl5aDNacFp5TkVza29WNkVTVzhqRUkxUm5NbnY1VHJmR0pINUsnLFxuICAgICAgICAnRThqV1g3VFRub0Z5UEp0QlRqbHVjQXRrUWFTNEJiN2RnMUxMamExN3pBcUtOR09KSzJiOWZiMlorbG5UalBpWScsXG4gICAgICAgICdpN0RQSDFYSG5mYUVleGpsaC9VN21ZYTVScndJcGhSeE5pOGdDdXh2ODc0Wk1taEVuN1FXVkdWemRETWdQSFJsJyxcbiAgICAgICAgJ2MzUXpRSFJsYzNRdVkyOXRQb2hpQkJNUkFnQWlCUUpSRWJ5T0Foc0RCZ3NKQ0FjREFnWVZDQUlKQ2dzRUZnSUQnLFxuICAgICAgICAnQVFJZUFRSVhnQUFLQ1JDMHU4TzBNb2EySll4eUFKOU9pMlVsY1VUMFZKTmd3anlsL1ZGOVhjamY5Z0NlSlB2eScsXG4gICAgICAgICdnL2ZwNEVBVThNSklhTjJ5TUk4cExGUzVBYUlFVVJHOG5oRUVBS1ZnZU5EdVlEUHVmTHVKMEdySlYvQ2JYRWpqJyxcbiAgICAgICAgJ2FFUEEwaVRVcVYwblRDUGRBZlEvbm1FM2doNVVsTk1yL3pTSEorYzRGUWhZZExyelJHRE9TelYrbWZQSEgzdCsnLFxuICAgICAgICAnWVZ4K3dhdDBCWXdBQnBIQXRzSXVMSVZvMlJRcVlaWUg4NXRhdHdCa203MUhIVDNqbWxFQXZyNk5GSDM4K3YzcycsXG4gICAgICAgICczdzRXbDAvc2RIeWFlaVNYQUtDeEo0WDFlT2RON0wxcnJiSm96US9nRENGdVZRUC9kY1Y2S3NzczhBdzQ0M2pHJyxcbiAgICAgICAgJ0FZQkxIV2g2bzRHaEFZNi9oMWtpakYweEQrdWMrdE5tVFFuUWkxdEVPb1RlSVpNWG5TUnd0azhYRXVKa2tiQVAnLFxuICAgICAgICAnK3V5dk1neVYzd3JrOXprYVRBaW43bnJqQUVSeGV6Rk9kQkVPdG5CMUNvdkp4dE1uK1JSeGFNRUdwQzRHbkVUeScsXG4gICAgICAgICdONSs2RmtMdUxjTlhpQ1FQNzVhanpPQU4xYUlEL2p1TmpVTnBCYk5wZnFCVjdqMUsrS24wbjlIWVR5UWw5Z2h5JyxcbiAgICAgICAgJzAyNisvNGM4YWcySFYrYmczQkQ3YzJWVFZ1OXhCT0RIc2Z1MHE4UWwvUUI5Vzh0bVl1Z1U2RGVYTUhhZVdQVUgnLFxuICAgICAgICAncGg5OGd1TTlrRjJ5SElpUkJ2QWQ1aTd3T2p3bitJL0lyNm5CUjJ5eEozcDMxQ0RVblVsYmpUUFlnN210UXZIVycsXG4gICAgICAgICdFWTJDcDRTV2lKRUVHQkVDQUFrRkFsRVJ2SjRDR3dJQVVna1F0THZEdERLR3RpVkhJQVFaRVFJQUJnVUNVUkc4JyxcbiAgICAgICAgJ25nQUtDUkFNaU1lUjI5NlkyU2p5QUo5VjN3UkpKMlN6YXpxYWw0a2hXR2ZMdTVSNi93Q2ZRUUlSRDI0eVZkejgnLFxuICAgICAgICAnMmErMmVDcnd5QUxUMkdBaWhBQ2ZTMG5XTTNhMGd0SVRxbmdwSnNSd3MrRXArZUlBbjE1cUQyaXR1dHhOYjhOSScsXG4gICAgICAgICdiUjJnQkI1UW1WSjMnLFxuICAgICAgICAnPXBHQTYnLFxuICAgICAgICAnLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLSdcbiAgICAgICAgXS5qb2luKFwiXFxuXCIpKTtcblxuICB2YXIgbXNnMiA9IG9wZW5wZ3AubWVzc2FnZS5yZWFkQXJtb3JlZChbXG4gICAgICAgICctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS0nLFxuICAgICAgICAnVmVyc2lvbjogR251UEcgdjEuNC4xMSAoR05VL0xpbnV4KScsXG4gICAgICAgICcnLFxuICAgICAgICAna0EwREFBSVJESWpIa2R2ZW1Oa0JyQjFpQjJadmJ5NTBlSFJSRWJ6M1ZFVlRWQ0JFUVZSQklERXlNelExTm9oRycsXG4gICAgICAgICdCQUFSQWdBR0JRSlJFYnozQUFvSkVBeUl4NUhiM3BqWjJUY0FuMzJMcERFdUhlOVFyU1JseXZTdVJFS05PRnd6JyxcbiAgICAgICAgJ0FKOXpoNHpzSzRHSVB1RXU4MVlQTm1Ic2p1N0RZZz09JyxcbiAgICAgICAgJz1XYVN4JyxcbiAgICAgICAgJy0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0nXG4gICAgICAgIF0uam9pbihcIlxcblwiKSkucGFja2V0cztcbiAgdmFyIHBhY2tldGxpc3RzID0ga2V5cmluZy5nZXRQYWNrZXRsaXN0c0ZvcktleUlkKG1zZzJbMF0uc2lnbmluZ0tleUlkLndyaXRlKCkpO1xuICB2YXIgcHViS2V5ID0gcGFja2V0bGlzdHNbMF07XG4gIG1zZzJbMl0udmVyaWZ5KHB1YktleVszXSwgbXNnMlsxXSk7XG4gIHJlc3VsdFsyXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3Rpbmcga2V5cmluZyBwdWJsaWMgc3Via2V5IHN1cHBvcnRcIixcbiAgICAgICAgICBwYWNrZXRsaXN0cyAhPT0gbnVsbCAmJiBcbiAgICAgICAgICBwYWNrZXRsaXN0cy5sZW5ndGggPT0gMSAmJiBcbiAgICAgICAgICBtc2cyWzJdLnZlcmlmaWVkKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn0pO1xuXG4gXG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIlBhY2tldCB0ZXN0aW5nXCIsIGZ1bmN0aW9uKCkge1xuXG5cdHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vJyk7XG5cblx0dmFyIGFybW9yZWRfa2V5ID1cblx0XHQnLS0tLS1CRUdJTiBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLVxcbicgK1xuXHRcdCdWZXJzaW9uOiBHbnVQRyB2Mi4wLjE5IChHTlUvTGludXgpXFxuJyArXG5cdFx0J1xcbicgK1xuXHRcdCdsUUgrQkZGNzlKOEJCQUREaFJVT01VU0dkWU0xS3E5Si92VlMzcUxmYVpId2V5Y0FLbTlTbnBMR0xKRStRYmtpXFxuJyArXG5cdFx0J0pSWExBaHhaK0hnVlRoUjlWWHM4d2JQUjJVWG5EaE1KR2UrVmNNQTBqaXdJT0VBRjB5OU0zWlFzUEZXZ3VlajJcXG4nICtcblx0XHQnMVp5Y2dPd3hZSGVoYktkUHFSSytuRmdGYmh2ZzZmNngyR3QrYTBaYnZpdkdMMUJxU1NHc0wrZGNoUUFSQVFBQlxcbicgK1xuXHRcdCcvZ01EQWlqYXRVTmVVRlpTeWZnMTZ4MzQzLzFKbzZ1MDdMVlRkSDZCY2J4NHlCUWpFSHZsZ2I2bTFlcUVJYloxXFxuJyArXG5cdFx0J2hvbFZ6dDBmU0tUem1seGx0RGFPd0ZMZjdpNDJscU5vV3lmYXFGck9ibEo1QXlzN1ErNnhpSlRCUk9HOXBvK2pcXG4nICtcblx0XHQnWjJBRStoa0JJd0tnaEI2NDVPaWtjaFI0c245RWozaXBlYTV2OSthN1lpbUhsVm1JaXFnTER5Z1F2WGt6WFZhZlxcbicgK1xuXHRcdCdaaTFQMndCN2VVNklmMnhlZVg1R1NSOHJXbytJN3VqbnMwVzhTOVB4QkhsSDNuMW9YVW1GV3NXTFpDWS9xcGtEXFxuJyArXG5cdFx0J0kvRnJvQmhYeEJWUnBRaFFtZHNXUFVkY2dtUVRFajhqblArK2x3U1FleGZnazJRYm9BVzdPRFVBOENsOW95ODdcXG4nICtcblx0XHQnVW9yNXNjaHd3ZEQzb1JvTEdjSlpmUjZEeXU5ZENZZFFTRFdqK0lRczk1aEpRZkhOY2ZqN1hGdFR5T2k3S3h4MFxcbicgK1xuXHRcdCdKeGlvOURlODRRbnhOQW9OWXVMdHdrYVJna1VWS1ZwaDJuWVdKZkFKdW51TU1vc00yV2RjaWRISjVkNlJJZHhCXFxuJyArXG5cdFx0J1U2bzNUK2Q4QlBYdVJRRVpIOStGa0RrYjRpaGFrS08zK1pjb244NWUxWlVVdEIxUVlYUnlhV05ySUR4d1lYUnlcXG4nICtcblx0XHQnYVdOclFHVjRZVzF3YkdVdVkyOXRQb2k1QkJNQkFnQWpCUUpSZS9TZkFoc0RCd3NKQ0FjREFnRUdGUWdDQ1FvTFxcbicgK1xuXHRcdCdCQllDQXdFQ0hnRUNGNEFBQ2drUU9ibGlTZE0vR0VKYmpnUC9mZmVpNGxVNmZYcDhRdTB1Yk5IaDRBNnN3a1RPXFxuJyArXG5cdFx0J2Izc3V1QkVMRTRBMi9wSzVZblc1eUJ5RkZTaTRrcThiSnA1TzZwOXlkWHBPQTM4dDNhUTh3cmJvMHlEdkdla3JcXG4nICtcblx0XHQnMVMxSFdPTGdDYVk3ckVEUXVidUNPSGQyUjgxL1ZRT0p5RzN6Z1g0S0ZJZ2tWeVY5QlpYVXB6NFBYdWhNT1JtdlxcbicgK1xuXHRcdCc4MXV6ZWo5cjdCWWtKNkdkQWY0RVVYdjBud0VFQUtiTzAyanRHRUhldDJmUWZrQVl5Tys3ODlzVHh5ZnJVeTV5XFxuJyArXG5cdFx0J1NBZjVuM0dna3VpSHo4ZEZldmhncVl5TUswT1lFT0NacWRkMWxSQmpMNlVzN1B4VGxqSGMyanRHaG9BZ0U0YVpcXG4nICtcblx0XHQnTEthckkzais1T29mY2FxMCtTMGJocWlRNWhsNkM0U2tkWU9FZUowSGxxMjAwOG4wcEpJbFU0RTV5SXUwb052YlxcbicgK1xuXHRcdCc0KzRvd1RwUkFCRUJBQUgrQXdNQ0tOcTFRMTVRVmxMSnlldUdCRUErN25YUzNhU3k2bUU0bFI1ZjNNbDVOUnF0XFxuJyArXG5cdFx0J2ptNlErVVVJNjlEemhMR1g0akhSeG5hNk5NUDc0UzNDZ2hPejllQ2hNbmRrZldMQy9jMTFoMW5wekxjaStBd0pcXG4nICtcblx0XHQnNDV4TWJ3L09XNVBMbGF4ZHRrZy9TbnNIcEZHQ0F1VFVXWTg3a3VXb0cwSFNWTW45Q2xtKzY3cmRpY09XNkw1YVxcbicgK1xuXHRcdCdDaGZ5V2NWWitIdndqeDhZTTAvajExSWY3b1VrQ1pFc3RTVWVKWU9JMTBKUUxoTkxwRGRrQjg5dlhoQU1hQ3VVXFxuJyArXG5cdFx0J0lqaGRxMHZ2Smk2SnJ1S1FHUEsramFqSjRNTWFubnBRdEtBdnQ4YWlmcXBkb3ZZeTh3NHloMnBHa2FkRnZyc1pcXG4nICtcblx0XHQnbXhwanFtbWF3YWI2emxPVzVXckx4UVZMMWNRUmRySVE3all0dUxBcEdXa1BmeXRTQ0JaMjBwU3lXbm1reGQ0WFxcbicgK1xuXHRcdCdPSW1zNkJqcXJQOUx4QkVYc1BCd2RVQTVJcmFucitVQklQRHhRclRwNWswREpoWEJDcEoxazNaVCsyZHhpUlMyXFxuJyArXG5cdFx0J3NrODN3MlZVQm5YZFlXWngwWWxNcXIzYkRUNko1Zk8rOFY4cGJnWTVCa0hSQ0ZNYWNGeDQ1a20vZnZtSW53UVlcXG4nICtcblx0XHQnQVFJQUNRVUNVWHYwbndJYkRBQUtDUkE1dVdKSjB6OFlRcWIzQS85N25qTGwzM09RWVhWcDlPVGsvVmdFNk8rd1xcbicgK1xuXHRcdCdvU1lhKzZ4TU96c2s3dGx1TElSUXRuSXByZ2EvZTh2RVpYR1RvbVYyYTc3SEJrc2crWWpsVGgvbDhvTXVhb3hHXFxuJyArXG5cdFx0J1FOa01wb1JKS1BpcDI5UlRXNGdMZG5vSlZla1ovYXdrQk4yUzNOTUFyT1pHY2E4VStNMUl1VjdPeVZjaFNWU2xcXG4nICtcblx0XHQnWVJsY2k3MkdIaGx5b3M4WUhBPT1cXG4nICtcblx0XHQnPUtYa2pcXG4nICtcblx0XHQnLS0tLS1FTkQgUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS0nO1xuXG5cblx0dmFyIHRlc3RzID0gW2Z1bmN0aW9uKCkge1xuXHRcdHZhciBtZXNzYWdlID0gbmV3IG9wZW5wZ3AucGFja2V0Lmxpc3QoKTtcblxuXHRcdHZhciBsaXRlcmFsID0gbmV3IG9wZW5wZ3AucGFja2V0LmxpdGVyYWwoKTtcblx0XHRsaXRlcmFsLnNldFRleHQoJ0hlbGxvIHdvcmxkJyk7XG5cdFx0XG5cdFx0dmFyIGVuYyA9IG5ldyBvcGVucGdwLnBhY2tldC5zeW1tZXRyaWNhbGx5X2VuY3J5cHRlZCgpO1xuXHRcdG1lc3NhZ2UucHVzaChlbmMpO1xuXHRcdGVuYy5wYWNrZXRzLnB1c2gobGl0ZXJhbCk7XG5cblx0XHR2YXIga2V5ID0gJzEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyJyxcblx0XHRcdGFsZ28gPSAnYWVzMjU2JztcblxuXHRcdGVuYy5lbmNyeXB0KGFsZ28sIGtleSk7XG5cblxuXG5cdFx0dmFyIG1zZzIgPSBuZXcgb3BlbnBncC5wYWNrZXQubGlzdCgpO1xuXHRcdG1zZzIucmVhZChtZXNzYWdlLndyaXRlKCkpO1xuXG5cdFx0bXNnMlswXS5kZWNyeXB0KGFsZ28sIGtleSk7XG5cblx0XHRyZXR1cm4gbmV3IHVuaXQucmVzdWx0KCdTeW1tZXRyaWNhbGx5IGVuY3J5cHRlZCBwYWNrZXQnLCBcblx0XHRcdG1zZzJbMF0ucGFja2V0c1swXS5kYXRhID09IGxpdGVyYWwuZGF0YSk7XG5cblx0fSwgZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGtleSA9ICcxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMicsXG5cdFx0XHRhbGdvID0gJ2FlczI1Nic7XG5cblx0XHR2YXIgbGl0ZXJhbCA9IG5ldyBvcGVucGdwLnBhY2tldC5saXRlcmFsKCksXG5cdFx0XHRlbmMgPSBuZXcgb3BlbnBncC5wYWNrZXQuc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkKCksXG5cdFx0XHRtc2cgPSBuZXcgb3BlbnBncC5wYWNrZXQubGlzdCgpO1xuXG5cdFx0bXNnLnB1c2goZW5jKTtcblx0XHRsaXRlcmFsLnNldFRleHQoJ0hlbGxvIHdvcmxkIScpO1xuXHRcdGVuYy5wYWNrZXRzLnB1c2gobGl0ZXJhbCk7XG5cdFx0ZW5jLmVuY3J5cHQoYWxnbywga2V5KTtcblx0XHRcblxuXG5cdFx0dmFyIG1zZzIgPSBuZXcgb3BlbnBncC5wYWNrZXQubGlzdCgpO1xuXHRcdG1zZzIucmVhZChtc2cud3JpdGUoKSk7XG5cblx0XHRtc2cyWzBdLmRlY3J5cHQoYWxnbywga2V5KTtcblxuXHRcdHJldHVybiBuZXcgdW5pdC5yZXN1bHQoJ1N5bS4gZW5jcnlwdGVkIGludGVncml0eSBwcm90ZWN0ZWQgcGFja2V0JywgXG5cdFx0XHRtc2cyWzBdLnBhY2tldHNbMF0uZGF0YSA9PSBsaXRlcmFsLmRhdGEpO1xuXHRcblx0fSwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcblx0XHR2YXIgbXNnID0gXG5cdFx0XHQnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tXFxuJyArXG5cdFx0XHQnVmVyc2lvbjogR251UEcgdjIuMC4xOSAoR05VL0xpbnV4KVxcbicgK1xuXHRcdFx0J1xcbicgK1xuXHRcdFx0J2pBMEVDUU1DcG83SThXcXNlYlRKMGtvQm1tNi9vcWRIWEpVOWFQZStQbytuay9rNC9QWnJMbWxYd3oybGhxQmdcXG4nICtcblx0XHRcdCdHQWxZOXJ4VlN0TEJyZzBIbis1Z2toeUhJOUI4NXJNMUJFWVhROHBQNUNTRnVUd2JKM08yczY3ZHpRPT1cXG4nICtcblx0XHRcdCc9VlowL1xcbicgK1xuXHRcdFx0Jy0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0nO1xuXG5cblxuXHRcdHZhciBtc2dieXRlcyA9IG9wZW5wZ3AuYXJtb3IuZGVjb2RlKG1zZykuZGF0YTtcblxuXHRcdHZhciBwYXJzZWQgPSBuZXcgb3BlbnBncC5wYWNrZXQubGlzdCgpO1xuXHRcdHBhcnNlZC5yZWFkKG1zZ2J5dGVzKTtcblxuXHRcdHBhcnNlZFswXS5kZWNyeXB0KCd0ZXN0Jyk7XG5cblx0XHR2YXIga2V5ID0gcGFyc2VkWzBdLnNlc3Npb25LZXk7XG5cdFx0cGFyc2VkWzFdLmRlY3J5cHQocGFyc2VkWzBdLnNlc3Npb25LZXlBbGdvcml0aG0sIGtleSk7XG5cdFx0dmFyIGNvbXByZXNzZWQgPSBwYXJzZWRbMV0ucGFja2V0c1swXTtcblxuXHRcdHZhciByZXN1bHQgPSBjb21wcmVzc2VkLnBhY2tldHNbMF0uZGF0YTtcblxuXHRcdHJldHVybiBuZXcgdW5pdC5yZXN1bHQoJ1N5bSBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXkgd2l0aCBhIGNvbXByZXNzZWQgcGFja2V0Jyxcblx0XHRcdHJlc3VsdCA9PSAnSGVsbG8gd29ybGQhXFxuJyk7XG5cblx0fSwgZnVuY3Rpb24oKSB7XG5cdFxuXHRcdHZhciByc2EgPSBuZXcgb3BlbnBncC5jcnlwdG8ucHVibGljS2V5LnJzYSgpLFxuXHRcdFx0bXBpID0gcnNhLmdlbmVyYXRlKDUxMiwgXCIxMDAwMVwiKVxuXG5cdFx0dmFyIG1waSA9IFttcGkubiwgbXBpLmVlLCBtcGkuZCwgbXBpLnAsIG1waS5xLCBtcGkudV07XG5cblx0XHRtcGkgPSBtcGkubWFwKGZ1bmN0aW9uKGspIHtcblx0XHRcdFx0dmFyIG1waSA9IG5ldyBvcGVucGdwLm1waSgpO1xuXHRcdFx0XHRtcGkuZnJvbUJpZ0ludGVnZXIoayk7XG5cdFx0XHRcdHJldHVybiBtcGk7XG5cdFx0fSk7XG5cblx0XHR2YXIgZW5jID0gbmV3IG9wZW5wZ3AucGFja2V0LnB1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5KCksXG5cdFx0XHRtc2cgPSBuZXcgb3BlbnBncC5wYWNrZXQubGlzdCgpLFxuXHRcdFx0bXNnMiA9IG5ldyBvcGVucGdwLnBhY2tldC5saXN0KCk7XG5cblx0XHRlbmMuc2Vzc2lvbktleSA9ICcxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMic7XG5cdFx0ZW5jLnB1YmxpY0tleUFsZ29yaXRobSA9ICdyc2FfZW5jcnlwdCc7XG5cdFx0ZW5jLnNlc3Npb25LZXlBbGdvcml0aG0gPSAnYWVzMjU2Jztcblx0XHRlbmMucHVibGljS2V5SWQuYnl0ZXMgPSAnMTIzNDU2NzgnO1xuXHRcdGVuYy5lbmNyeXB0KHsgbXBpOiBtcGkgfSk7XG5cblx0XHRtc2cucHVzaChlbmMpO1xuXG5cdFx0bXNnMi5yZWFkKG1zZy53cml0ZSgpKTtcblxuXHRcdG1zZzJbMF0uZGVjcnlwdCh7IG1waTogbXBpIH0pO1xuXG5cdFx0cmV0dXJuIG5ldyB1bml0LnJlc3VsdCgnUHVibGljIGtleSBlbmNyeXB0ZWQgc3ltbWV0cmljIGtleSBwYWNrZXQnLCBcblx0XHRcdG1zZzJbMF0uc2Vzc2lvbktleSA9PSBlbmMuc2Vzc2lvbktleSAmJlxuXHRcdFx0bXNnMlswXS5zZXNzaW9uS2V5QWxnb3JpdGhtID09IGVuYy5zZXNzaW9uS2V5QWxnb3JpdGhtKTtcblx0fSwgZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGFybW9yZWRfa2V5ID0gXG5cdFx0XHQnLS0tLS1CRUdJTiBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLVxcbicgK1xuXHRcdFx0J1ZlcnNpb246IEdudVBHIHYyLjAuMTkgKEdOVS9MaW51eClcXG4nICtcblx0XHRcdCdcXG4nICtcblx0XHRcdCdsUUhZQkZGMzNpTUJCQUM5WWZPWWFoSmxXclZqMkoxVGpRaVpMdW5XbGpJNEc5ZTZBUlR5RDk5bmZPa1Yzc3doXFxuJyArXG5cdFx0XHQnMFdhT3NlNFV0ajdCZlRxZFljb2V6aENhUXB1RXhVdXBLV1pxbWR1QmN3U21FQmZOdTFYeUtjeGxEUXV1azBWa1xcbicgK1xuXHRcdFx0J3ZpR0Mza0ZSY2UvY0phS1ZGU1JVOFY1elBndDZLUU52L3dOejd5ZEVpc2FTb05iazUxdlF0NW9HZndBUkFRQUJcXG4nICtcblx0XHRcdCdBQVA1QVZMOHhXTXVLZ0xqOWc3L3dmdE1IK2pPN3ZoQXhqZTJXM1krOHI4VG5PU24wNTM2bFF2emwvZVF5ZUxDXFxuJyArXG5cdFx0XHQnVksyazMrNyt0cmdPN0k0S3VYQ1hacWdBYkVpM25pRFlYRGFDSis4Z2RSOXF2UE0yZ2k5Tk03MVRHWFp2R0Uwd1xcbicgK1xuXHRcdFx0J1g4Z0laZnFMVFFXS205VElTLzN0ZHJ0aDRud2hpeWUwQVN5Y2hPYm9JaU42VklFQ0FNYkNRNC9ub3hHVjZ5VEtcXG4nICtcblx0XHRcdCdWZXpzR1N6K2lDTXh6MmxWMjcwL0FjMkM1V1BrK09seFhsb3hVWGVFa0dJcjZYa21oaHBjZWVkMktMNDFVQzhZXFxuJyArXG5cdFx0XHQndzV0dEdJRUNBUFBzYWhuaUtHeXFwOUNIeTZXMEI4M3loaGNJYm1MbGFWRzJmdEt5VUVEeElnZ3pPbFh1VnJ1ZVxcbicgK1xuXHRcdFx0J3o5WFJkNndGcXdEZDFRTUZXMHVVeUhQRENJRlBudjhDQUphREZTWnV0dVdkV010MTVOWlhqZmdSZ2ZKdURydHZcXG4nICtcblx0XHRcdCdFN3lGWS9wMGVsOGxDaWhPVDhXb0hiVG4xUGJDWU16TkJjMEloSGFaS0F0QTJwamtFK3d6ejlDbFA3UWJSMlZ2XFxuJyArXG5cdFx0XHQnY21kbElEeG5aVzl5WjJWQVpYaGhiWEJzWlM1amIyMCtpTGtFRXdFQ0FDTUZBbEYzM2lNQ0d3TUhDd2tJQndNQ1xcbicgK1xuXHRcdFx0J0FRWVZDQUlKQ2dzRUZnSURBUUllQVFJWGdBQUtDUkJjcXMzNmZ3SkNYUmJ2QS85TFBpSzZXRktjRm9OQm5MRUpcXG4nICtcblx0XHRcdCdtUy9DTmtMOHlUcGtzbHBDUDYrVHdKTWM4dVhxd1lsOS9QVzIrQ3dtelpqczZKc3ZUek1jUi9aYmZaSnVTVzZZXFxuJyArXG5cdFx0XHQnRXNMTmVqc1NwZ2NZOWFpZXdHdEUrNTNlNW9LWW5sbVZNVFdPUHl3Y2lJZ012WGx6ZEdoeGN3cUo4dTBoVCt1Z1xcbicgK1xuXHRcdFx0JzlDamNBZnVYOXl3ODVMd1h0ZEd3Tmg3SjhRPT1cXG4nICtcblx0XHRcdCc9bEtpU1xcbicgK1xuXHRcdFx0Jy0tLS0tRU5EIFBHUCBQUklWQVRFIEtFWSBCTE9DSy0tLS0tJztcblxuXHRcdGtleSA9IG5ldyBvcGVucGdwLnBhY2tldC5saXN0KCk7XG5cdFx0a2V5LnJlYWQob3BlbnBncC5hcm1vci5kZWNvZGUoYXJtb3JlZF9rZXkpLmRhdGEpO1xuXHRcdGtleSA9IGtleVswXTtcblxuXHRcdHZhciBlbmMgPSBuZXcgb3BlbnBncC5wYWNrZXQucHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkoKSxcblx0XHRcdHNlY3JldCA9ICcxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMic7XG5cblx0XHRlbmMuc2Vzc2lvbktleSA9IHNlY3JldDtcblx0XHRlbmMucHVibGljS2V5QWxnb3JpdGhtID0gJ3JzYV9lbmNyeXB0Jztcblx0XHRlbmMuc2Vzc2lvbktleUFsZ29yaXRobSA9ICdhZXMyNTYnO1xuXHRcdGVuYy5wdWJsaWNLZXlJZC5ieXRlcyA9ICcxMjM0NTY3OCc7XG5cblx0XHRlbmMuZW5jcnlwdChrZXkpO1xuXG5cdFx0ZW5jLmRlY3J5cHQoa2V5KTtcblxuXHRcdHJldHVybiBuZXcgdW5pdC5yZXN1bHQoJ1NlY3JldCBrZXkgcGFja2V0IChyZWFkaW5nLCB1bmVuY3JwdGVkKScsXG5cdFx0XHRlbmMuc2Vzc2lvbktleSA9PSBzZWNyZXQpO1xuXHR9LCBmdW5jdGlvbigpIHtcblxuXHRcdHZhciBhcm1vcmVkX2tleSA9XG5cdFx0XHQnLS0tLS1CRUdJTiBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLVxcbicgK1xuXHRcdFx0J1ZlcnNpb246IEdudVBHIHYyLjAuMTkgKEdOVS9MaW51eClcXG4nICtcblx0XHRcdCdcXG4nICtcblx0XHRcdCdsUUhZQkZGNmd0a0JCQURLVU9XWks2L1Y3NU1Od0JTK2hMWWljb1MwU29qYm8zcVdYWHBTN2VNK3VoaURtNGJQXFxuJyArXG5cdFx0XHQnRE5qZE5WQTBSK1RDanZoV2JjM1c2Y3ZkSFlUbUhSTWhUSU9lZm5jWlJ0M093RjdBdlZrNTNmS0tQaU5OdjVDOVxcbicgK1xuXHRcdFx0J0lLOGJjRGhBa25TT2cxVFhSU3BYTEh0WXkzNkE2aURnZmZOU2pvQ09WYWVLcHVSRE1BMzdQdkpXRlFBUkFRQUJcXG4nICtcblx0XHRcdCdBQVArS3hIYk93Y3JuUFB1WHBwQ1lFZXczWGI3TE1XRVNwdk1GRmdzbXh4MUNPekZuTGplazFQMUUreU9XVDduXFxuJyArXG5cdFx0XHQnNG9wY3NFdWFhekxrK1RyWVNNT3VSNk82RGdHZzVjK2N0VlBVK05HTk5DaWlUa096dUQrOG93OE5nc29JTk94aVxcbicgK1xuXHRcdFx0JzQ4MXFMSzBOWXBjNXNFZzM5NEozZlJ1enBmRWk2RFRTL1J6Q043WURpR0ZjY05FQ0FNNzFOdWFBekg1THJaK0JcXG4nICtcblx0XHRcdCc0T2t3eTlDUVFiZ29ZcmRhaWEyNENqRWFVT0RhUk9ueU5zdk9iMHlkRWViVkFiR3pyc0JyNkxyaXNUaWR5WnNHXFxuJyArXG5cdFx0XHQndDJUK0w3RUNBUHBDRnpaSXd3azZnaVoxMEhtWEVoWFpMWFltZGhRRC8xZndlZ3BUckVjaU1BNk1DY2RrY0N5T1xcbicgK1xuXHRcdFx0JzIvSitTK05YTTYyeWtNR0RoZzJjamhVMXJqL3VhYVVDQUpmQ2prd3B4TXNES0hZREZEWHlqSkZ5MnZFbUEzczhcXG4nICtcblx0XHRcdCdjbm1BVURGMWNhUHlFY1BFWm1ZSlJFK0tkcm9PRDZJR2h6cDdvQTM0RWYzRDZIT0Nvdkg5WWFDZ2JiUWJTbTlvXFxuJyArXG5cdFx0XHQnYm01NUlEeHFiMmh1Ym5sQVpYaGhiWEJzWlM1amIyMCtpTGtFRXdFQ0FDTUZBbEY2Z3RrQ0d3TUhDd2tJQndNQ1xcbicgK1xuXHRcdFx0J0FRWVZDQUlKQ2dzRUZnSURBUUllQVFJWGdBQUtDUkE2SFRNOHlQMDhrZVpnQS80dkwyNzN6cnFubU9ycW1vL0tcXG4nICtcblx0XHRcdCdVeFFnRDB2TWhNNThkMjVVakdZSTZMQVprQWxzL2s0RnZGdDVHVUhWV0pSM0hCUnV1TmxCN1VuZEgvdVlsVTdqXFxuJyArXG5cdFx0XHQnbS9iUUxpUDR1dkZRdVJHdUc3NmYwTzV0L0t5ZVVkenJwTmlKcGU4dFlEQW5vUHhVekVOWXNJdjBmbTJaSVNvMVxcbicgK1xuXHRcdFx0J1FublhYMld1VlpHTVpIMVloUW9ha1p4Ym5wMEIyQVJSZW9MWkFRUUF2UXZQcDJNTHU5dm5SdlozUHk1NTlrUWZcXG4nICtcblx0XHRcdCcwWjVBbkVYVm9rQUxUbjVBMm01MWRMZWtROVQzUmh6OHA5STZDL1hqVlF3QmtwMVVTT2FEVXorTDdsc2JOZFk0XFxuJyArXG5cdFx0XHQnWWJVaTNlSUE1UkltVlhlVElyRDFoRTRDbGxETkttcVQ1d0ZOMDdlRXU3UWhERXVZaW9PKzRndGpqaFVEWWVJQVxcbicgK1xuXHRcdFx0J2RDVnRWTy8vcThyUDh1a1pFYzhBRVFFQUFRQUQvUkhsdHR5TmUzUm5Eci9Bb0t4NkhYRExwVW1HbG01VkRETW1cXG4nICtcblx0XHRcdCdwZ3RoMTRqMmNTZENKWXFJZEhxT1R2c2lZMzF6WTNqUFFLemRPVGdIbnNJNFgycUs5SW5id1hlcFNCa2FPSnpZXFxuJyArXG5cdFx0XHQnaU5oaWZQU1VzOXFvTmF3RHFiRko4UE1YZDRRUUdnTTkzdyt0dWRLQzY1MFp1cTdNN2VXU2RRZzB1OWFvTFk5N1xcbicgK1xuXHRcdFx0J01wS3gzRFVGQWdEQS9SZ29POHhZTWdrS04xdHVLV2E2MXFlc0xkSlJBWkkvM2NudnRzbW1FQnQ5dGRiY0RvQnpcXG4nICtcblx0XHRcdCdnT0lBQXZVRmdpcHVQNmRCV0x5ZjJOUk5SVlZRZE5UbEFnRDZ4UzdTODdnM2tUYTNHTGNFSTJjdmVhUDFXV05LXFxuJyArXG5cdFx0XHQncktGblZXc2pCS0FyS0Z6TVE1TjZGTW5GRDRUOTZpM3NZbEFDRTVVakg5MFNwT2dCS09wZEt6U2pBZjluZ2hyd1xcbicgK1xuXHRcdFx0J2tiRmJGNzA4WklwVkV3eHZwL0pvU3V0WVVRNHYwMU1JbW5DR3F6RFZ1U2VmM2V1dExMdTRaRzdrTGVreE5hdVZcXG4nICtcblx0XHRcdCc4dEdGd3hzZHR2MzBSTC8zblcrSW53UVlBUUlBQ1FVQ1VYcUMyUUliREFBS0NSQTZIVE04eVAwOGtSWGpCQUN1XFxuJyArXG5cdFx0XHQnUnRFd2pVK3A2cXFtM3BtaDd4ejFDemhRTjFGN1ZPajlkRlVlRUNKSjFpdjhKNzF3NVVJTkgwb3RJY2VlQmVXeVxcbicgK1xuXHRcdFx0J05MQS9Rdks4KzQvYjlRVytTOGFEWnllWnBZZzM3Z0J3ZFROR05UN1RzRUF4ejlTVWJ4OXVSamEwd05tdGI1eFdcXG4nICtcblx0XHRcdCdtRytWRThDQlhOa3A4SlRXeDA1QUh3dEszYmFXbEhXd3B3blJsYlU5NFE9PVxcbicgK1xuXHRcdFx0Jz1GU3dBXFxuJyArXG5cdFx0XHQnLS0tLS1FTkQgUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS0nO1xuXG5cdFx0dmFyIGFybW9yZWRfbXNnID0gXG5cdFx0XHQnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tXFxuJyArXG5cdFx0XHQnVmVyc2lvbjogR251UEcgdjIuMC4xOSAoR05VL0xpbnV4KVxcbicgK1xuXHRcdFx0J1xcbicgK1xuXHRcdFx0J2hJd0RGWUVUKzdiZngvQUJBLzk1VWM5OTQyVGc4b3FwTzB2RXUyZVNLd1BBTE0zYTBEclZkQWlGT0lLL2RKbVpcXG4nICtcblx0XHRcdCdZcnRQUnczRUV3SFpqbDZDTzlSRCs5NWlFMjd0UGJzSUN3MUs0M2dvZlNWL3dXc1BPNnZ2czNlZnRRWUhTeHhhXFxuJyArXG5cdFx0XHQnSVFiVFBJbWlSYUo3M01mN2lNM0NOdFFNNGlVQnN4MUhuVUdsK3J0RDBuejNmTG02aTNDandpTlFXVzQySTlKSFxcbicgK1xuXHRcdFx0J0FXdjhFdnZweFo4WDJDbEZmU1czVVZCb1JPSGU5Q0FXSE0vNDBuR3V0QVpLOE1JZ21VSTR4cWtMRkJicXFUeXhcXG4nICtcblx0XHRcdCcvY0RTQzRRK3N2NjVVWDR1cmJmYzd1SnVrMUNwajU0PVxcbicgK1xuXHRcdFx0Jz1pU2FLXFxuJyArXG5cdFx0XHQnLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLSc7XG5cblxuXHRcdHZhciBrZXkgPSBuZXcgb3BlbnBncC5wYWNrZXQubGlzdCgpO1xuXHRcdGtleS5yZWFkKG9wZW5wZ3AuYXJtb3IuZGVjb2RlKGFybW9yZWRfa2V5KS5kYXRhKTtcblx0XHRrZXkgPSBrZXlbM107XG5cblx0XHR2YXIgbXNnID0gbmV3IG9wZW5wZ3AucGFja2V0Lmxpc3QoKTtcblx0XHRtc2cucmVhZChvcGVucGdwLmFybW9yLmRlY29kZShhcm1vcmVkX21zZykuZGF0YSk7XG5cblx0XHRtc2dbMF0uZGVjcnlwdChrZXkpO1xuXHRcdG1zZ1sxXS5kZWNyeXB0KG1zZ1swXS5zZXNzaW9uS2V5QWxnb3JpdGhtLCBtc2dbMF0uc2Vzc2lvbktleSk7XG5cblx0XHR2YXIgdGV4dCA9IG1zZ1sxXS5wYWNrZXRzWzBdLnBhY2tldHNbMF0uZGF0YTtcblxuXG5cdFx0cmV0dXJuIG5ldyB1bml0LnJlc3VsdCgnUHVibGljIGtleSBlbmNyeXB0ZWQgcGFja2V0IChyZWFkaW5nLCBHUEcpJyxcblx0XHRcdHRleHQgPT0gJ0hlbGxvIHdvcmxkIScpO1xuXHR9LCBmdW5jdGlvbigpIHtcblxuXHRcdHZhciBwYXNzcGhyYXNlID0gJ2hlbGxvJyxcblx0XHRcdGFsZ28gPSAnYWVzMjU2JztcblxuXHRcdHZhciBsaXRlcmFsID0gbmV3IG9wZW5wZ3AucGFja2V0LmxpdGVyYWwoKSxcblx0XHRcdGtleV9lbmMgPSBuZXcgb3BlbnBncC5wYWNrZXQuc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleSgpLFxuXHRcdFx0ZW5jID0gbmV3IG9wZW5wZ3AucGFja2V0LnN5bV9lbmNyeXB0ZWRfaW50ZWdyaXR5X3Byb3RlY3RlZCgpLFxuXHRcdFx0bXNnID0gbmV3IG9wZW5wZ3AucGFja2V0Lmxpc3QoKTtcblxuXHRcdG1zZy5wdXNoKGtleV9lbmMpO1xuXHRcdG1zZy5wdXNoKGVuYyk7XG5cblx0XHRrZXlfZW5jLnNlc3Npb25LZXlBbGdvcml0aG0gPSBhbGdvO1xuXHRcdGtleV9lbmMuZGVjcnlwdChwYXNzcGhyYXNlKTtcblxuXHRcdHZhciBrZXkgPSBrZXlfZW5jLnNlc3Npb25LZXk7XG5cblx0XHRsaXRlcmFsLnNldFRleHQoJ0hlbGxvIHdvcmxkIScpO1xuXHRcdGVuYy5wYWNrZXRzLnB1c2gobGl0ZXJhbCk7XG5cdFx0ZW5jLmVuY3J5cHQoYWxnbywga2V5KTtcblxuXG5cdFx0dmFyIG1zZzIgPSBuZXcgb3BlbnBncC5wYWNrZXQubGlzdCgpO1xuXHRcdG1zZzIucmVhZChtc2cud3JpdGUoKSk7XG5cblx0XHRtc2cyWzBdLmRlY3J5cHQocGFzc3BocmFzZSk7XG5cdFx0dmFyIGtleTIgPSBtc2cyWzBdLnNlc3Npb25LZXk7XG5cdFx0bXNnMlsxXS5kZWNyeXB0KG1zZzJbMF0uc2Vzc2lvbktleUFsZ29yaXRobSwga2V5Mik7XG5cblxuXHRcdHJldHVybiBuZXcgdW5pdC5yZXN1bHQoJ1N5bSBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXkgcmVhZGluZy93cml0aW5nJywgXG5cdFx0XHRtc2cyWzFdLnBhY2tldHNbMF0uZGF0YSA9PSBsaXRlcmFsLmRhdGEpO1xuXHRcblx0fSwgZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGFybW9yZWRfbXNnID0gXG5cdFx0XHQnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tXFxuJyArXG5cdFx0XHQnVmVyc2lvbjogR251UEcgdjIuMC4xOSAoR05VL0xpbnV4KVxcbicgK1xuXHRcdFx0J1xcbicgK1xuXHRcdFx0J2hJd0Q5NUQ5YUhTNWZ4RUJBLzk4Q3dINTRYWm13b2JPbUhVY3ZXY0REUXlzQkVDNHVmN3dBU2lHY1JiZWpEYU9cXG4nICtcblx0XHRcdCdhSnFjcksvM2s4c0JRTU83eU9odnJDUnFxcEdEcW5teDdJYWFLTG5aUzduWUFab0hFc0s5VXlHMGhEYThDZmJvXFxuJyArXG5cdFx0XHQnQ1A0eFpWY2dJdklmQVcvaW4xTGVUMnRkMFFjUU5iZWV3Qm1QZWErdlFFRXZSZ0lQMTB0bEU3TUs4QXk0OGRKSFxcbicgK1xuXHRcdFx0J0FhZ01nTllnN01CVWpwdU9DVnJqTTFwV2phOHV6YlVMZlloVHEzSUo4SDNRaGJkVCtrOWtoWTlmMGFKUEVlWWlcXG4nICtcblx0XHRcdCdkVnY2REs5dXZpTUdjL0RzVkN3NUs4bFFSTGxrY0hjPVxcbicgK1xuXHRcdFx0Jz1wUitDXFxuJyArXG5cdFx0XHQnLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLSc7XG5cblx0XHR2YXIga2V5ID0gbmV3IG9wZW5wZ3AucGFja2V0Lmxpc3QoKTtcblx0XHRrZXkucmVhZChvcGVucGdwLmFybW9yLmRlY29kZShhcm1vcmVkX2tleSkuZGF0YSk7XG5cdFx0a2V5ID0ga2V5WzNdO1xuXHRcdGtleS5kZWNyeXB0KCd0ZXN0Jyk7XG5cblx0XHR2YXIgbXNnID0gbmV3IG9wZW5wZ3AucGFja2V0Lmxpc3QoKTtcblx0XHRtc2cucmVhZChvcGVucGdwLmFybW9yLmRlY29kZShhcm1vcmVkX21zZykuZGF0YSk7XG5cblx0XHRtc2dbMF0uZGVjcnlwdChrZXkpO1xuXHRcdG1zZ1sxXS5kZWNyeXB0KG1zZ1swXS5zZXNzaW9uS2V5QWxnb3JpdGhtLCBtc2dbMF0uc2Vzc2lvbktleSk7XG5cblx0XHR2YXIgdGV4dCA9IG1zZ1sxXS5wYWNrZXRzWzBdLnBhY2tldHNbMF0uZGF0YTtcblxuXG5cblx0XHRyZXR1cm4gbmV3IHVuaXQucmVzdWx0KCdTZWNyZXQga2V5IGVuY3J5cHRpb24vZGVjcnlwdGlvbiB0ZXN0Jyxcblx0XHRcdHRleHQgPT0gJ0hlbGxvIHdvcmxkIScpO1xuXHR9LCBmdW5jdGlvbigpIHtcblx0XG5cblx0XHR2YXIga2V5ID0gbmV3IG9wZW5wZ3AucGFja2V0Lmxpc3QoKTtcblx0XHRrZXkucmVhZChvcGVucGdwLmFybW9yLmRlY29kZShhcm1vcmVkX2tleSkuZGF0YSk7XG5cblxuXHRcdHZhciB2ZXJpZmllZCA9IGtleVsyXS52ZXJpZnkoa2V5WzBdLFxuXHRcdFx0e1xuXHRcdFx0XHR1c2VyaWQ6IGtleVsxXSxcblx0XHRcdFx0a2V5OiBrZXlbMF1cblx0XHRcdH0pO1xuXG5cdFx0dmVyaWZpZWQgPSB2ZXJpZmllZCAmJiBrZXlbNF0udmVyaWZ5KGtleVswXSxcblx0XHRcdHtcblx0XHRcdFx0a2V5OiBrZXlbMF0sXG5cdFx0XHRcdGJpbmQ6IGtleVszXSxcblx0XHRcdH0pXG5cblxuXHRcdHJldHVybiBuZXcgdW5pdC5yZXN1bHQoJ1NlY3JldCBrZXkgcmVhZGluZyB3aXRoIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24uJyxcblx0XHRcdHZlcmlmaWVkID09IHRydWUpO1xuXHR9LCBmdW5jdGlvbigpIHtcblxuXHRcdHZhciBhcm1vcmVkX21zZyA9IFxuXHRcdFx0Jy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcbicgK1xuXHRcdFx0J1ZlcnNpb246IEdudVBHIHYyLjAuMTkgKEdOVS9MaW51eClcXG4nICtcblx0XHRcdCdcXG4nICtcblx0XHRcdCdoSXdEOTVEOWFIUzVmeEVCQS80L1g0bXl2SCtqQjFIWU5lWnZkSytXc0JORE1mTHNCR09mMjA1UnhyM3ZTb2IvXFxuJyArXG5cdFx0XHQnQTA5Ym9qOC85bEZhaXBxdStBRWRRS0VqQ0I4c1orT1kwV2lRUEVQcHVoRyttVnFEcUVpUEZrZHBjcU50UzBWVlxcbicgK1xuXHRcdFx0J3B3cXBsSG82UW5IMk1IZnhwclpIWXV3Y0VDOXluSkN4SjZrU0NEOFhzOTloK1BqeE5OdzdOaE1qa0YrTjY5TEFcXG4nICtcblx0XHRcdCdOd0dQdGJMeDIvcjJuUjRnTzhnVjkyQTJSUUNPd1BQN1pWKzZmWGdXSXMrbWh5Q0hGUDN4VVA1RGFGQ05NOG1vXFxuJyArXG5cdFx0XHQnUE45N2k2NTl1Y3hGNkliT29LNTZGRWFVYk9QVEQ2eGR5aFdhbXhLZk1zSWIwVUpnVlVOaEdhcStWbHZPSnhhQlxcbicgK1xuXHRcdFx0J2lSY25ZNVV4c3lwS2d0cWZjS0lzZWIyMU1JbzR2Y05kb2d5eEJJRGxBTzQ3MlpmeG4wdWR6cjZXMmFRNzcrTktcXG4nICtcblx0XHRcdCdGRTFPMGtDWFMrRFRGT1lZVkQ3WDhyWEdTZ2xRc2RYSm1IZDg5c2RZRlFrTzdEN2JPTGRSSnVYZ2RnSDJjekNzXFxuJyArXG5cdFx0XHQnVUJHdUhaenNHYlRkeUt2cFZCdVMzcm55SEhCazZvQ25zbTFObDdlTHM2NFZrWlV4akVVYnE1cGI0ZGxyMXB3MlxcbicgK1xuXHRcdFx0J3p0cG1wQW5SY21NPVxcbicgK1xuXHRcdFx0Jz1odHJCXFxuJyArXG5cdFx0XHQnLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLSdcblxuXHRcdHZhciBrZXkgPSBuZXcgb3BlbnBncC5wYWNrZXQubGlzdCgpO1xuXHRcdGtleS5yZWFkKG9wZW5wZ3AuYXJtb3IuZGVjb2RlKGFybW9yZWRfa2V5KS5kYXRhKTtcblx0XHRrZXlbM10uZGVjcnlwdCgndGVzdCcpXG5cblx0XHR2YXIgbXNnID0gbmV3IG9wZW5wZ3AucGFja2V0Lmxpc3QoKTtcblx0XHRtc2cucmVhZChvcGVucGdwLmFybW9yLmRlY29kZShhcm1vcmVkX21zZykuZGF0YSk7XG5cblxuXHRcdG1zZ1swXS5kZWNyeXB0KGtleVszXSk7XG5cdFx0bXNnWzFdLmRlY3J5cHQobXNnWzBdLnNlc3Npb25LZXlBbGdvcml0aG0sIG1zZ1swXS5zZXNzaW9uS2V5KTtcblxuXHRcdHZhciBwYXlsb2FkID0gbXNnWzFdLnBhY2tldHNbMF0ucGFja2V0c1xuXG5cblxuXHRcdHZhciB2ZXJpZmllZCA9IHBheWxvYWRbMl0udmVyaWZ5KGtleVswXSwgcGF5bG9hZFsxXSk7XG5cblxuXG5cdFx0cmV0dXJuIG5ldyB1bml0LnJlc3VsdCgnUmVhZGluZyBhIHNpZ25lZCwgZW5jcnlwdGVkIG1lc3NhZ2UuJyxcblx0XHRcdHZlcmlmaWVkID09IHRydWUpO1xuXHR9LCBmdW5jdGlvbigpIHtcblx0XHR2YXIga2V5ID0gbmV3IG9wZW5wZ3AucGFja2V0Lmxpc3QoKTtcblx0XHRrZXkucHVzaChuZXcgb3BlbnBncC5wYWNrZXQuc2VjcmV0X2tleSk7XG5cblx0XHR2YXIgcnNhID0gbmV3IG9wZW5wZ3AuY3J5cHRvLnB1YmxpY0tleS5yc2EoKSxcblx0XHRcdG1waSA9IHJzYS5nZW5lcmF0ZSg1MTIsIFwiMTAwMDFcIilcblxuXG5cdFx0dmFyIG1waSA9IFttcGkubiwgbXBpLmVlLCBtcGkuZCwgbXBpLnAsIG1waS5xLCBtcGkudV07XG5cblx0XHRtcGkgPSBtcGkubWFwKGZ1bmN0aW9uKGspIHtcblx0XHRcdFx0dmFyIG1waSA9IG5ldyBvcGVucGdwLm1waSgpO1xuXHRcdFx0XHRtcGkuZnJvbUJpZ0ludGVnZXIoayk7XG5cdFx0XHRcdHJldHVybiBtcGk7XG5cdFx0fSk7XG5cblx0XHRrZXlbMF0ubXBpID0gbXBpO1xuXG5cdFx0a2V5WzBdLmVuY3J5cHQoJ2hlbGxvJyk7XG5cblx0XHR2YXIgcmF3ID0ga2V5LndyaXRlKCk7XG5cblx0XHR2YXIga2V5MiA9IG5ldyBvcGVucGdwLnBhY2tldC5saXN0KCk7XG5cdFx0a2V5Mi5yZWFkKHJhdyk7XG5cdFx0a2V5MlswXS5kZWNyeXB0KCdoZWxsbycpO1xuXHRcblx0XG5cdFx0cmV0dXJuIG5ldyB1bml0LnJlc3VsdCgnV3JpdGluZyBhbmQgZW5jcnlwdGlvIG9mIGEgc2VjcmV0IGtleSBwYWNrZXQuJyxcblx0XHRcdGtleVswXS5tcGkudG9TdHJpbmcoKSA9PSBrZXkyWzBdLm1waS50b1N0cmluZygpKTtcblx0fSwgZnVuY3Rpb24oKSB7XG5cblx0XHR2YXIga2V5ID0gbmV3IG9wZW5wZ3AucGFja2V0LnNlY3JldF9rZXkoKTtcblxuXHRcdHZhciByc2EgPSBuZXcgb3BlbnBncC5jcnlwdG8ucHVibGljS2V5LnJzYSxcblx0XHRcdG1waSA9IHJzYS5nZW5lcmF0ZSg1MTIsIFwiMTAwMDFcIilcblxuXHRcdHZhciBtcGkgPSBbbXBpLm4sIG1waS5lZSwgbXBpLmQsIG1waS5wLCBtcGkucSwgbXBpLnVdO1xuXG5cdFx0bXBpID0gbXBpLm1hcChmdW5jdGlvbihrKSB7XG5cdFx0XHRcdHZhciBtcGkgPSBuZXcgb3BlbnBncC5tcGkoKTtcblx0XHRcdFx0bXBpLmZyb21CaWdJbnRlZ2VyKGspO1xuXHRcdFx0XHRyZXR1cm4gbXBpO1xuXHRcdH0pO1xuXG5cdFx0a2V5Lm1waSA9IG1waTtcblxuXHRcdHZhciBzaWduZWQgPSBuZXcgb3BlbnBncC5wYWNrZXQubGlzdCgpLFxuXHRcdFx0bGl0ZXJhbCA9IG5ldyBvcGVucGdwLnBhY2tldC5saXRlcmFsKCksXG5cdFx0XHRzaWduYXR1cmUgPSBuZXcgb3BlbnBncC5wYWNrZXQuc2lnbmF0dXJlKCk7XG5cblx0XHRsaXRlcmFsLnNldFRleHQoJ0hlbGxvIHdvcmxkJyk7XG5cblx0XHRzaWduYXR1cmUuaGFzaEFsZ29yaXRobSA9ICdzaGEyNTYnO1xuXHRcdHNpZ25hdHVyZS5wdWJsaWNLZXlBbGdvcml0aG0gPSAncnNhX3NpZ24nO1xuXHRcdHNpZ25hdHVyZS5zaWduYXR1cmVUeXBlID0gJ2JpbmFyeSc7XG5cblx0XHRzaWduYXR1cmUuc2lnbihrZXksIGxpdGVyYWwpO1xuXG5cdFx0c2lnbmVkLnB1c2gobGl0ZXJhbCk7XG5cdFx0c2lnbmVkLnB1c2goc2lnbmF0dXJlKTtcblxuXHRcdHZhciByYXcgPSBzaWduZWQud3JpdGUoKTtcblxuXHRcdHZhciBzaWduZWQyID0gbmV3IG9wZW5wZ3AucGFja2V0Lmxpc3QoKTtcblx0XHRzaWduZWQyLnJlYWQocmF3KTtcblxuXHRcdHZhciB2ZXJpZmllZCA9IHNpZ25lZDJbMV0udmVyaWZ5KGtleSwgc2lnbmVkMlswXSk7XG5cdFxuXHRcblx0XHRyZXR1cm4gbmV3IHVuaXQucmVzdWx0KCdXcml0aW5nIGFuZCB2ZXJpZmljYXRpb24gb2YgYSBzaWduYXR1cmUgcGFja2V0LicsXG5cdFx0XHR2ZXJpZmllZCA9PSB0cnVlKTtcblx0fV07XG5cblxuXG5cdHRlc3RzLnJldmVyc2UoKTtcblxuXHR2YXIgcmVzdWx0cyA9IFtdO1xuXG5cdGZvcih2YXIgaSBpbiB0ZXN0cykge1xuXHRcdHJlc3VsdHMucHVzaCh0ZXN0c1tpXSgpKTtcblx0fVxuXHRcblx0XG5cdHJldHVybiByZXN1bHRzO1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIlNpZ25hdHVyZSB0ZXN0aW5nXCIsIGZ1bmN0aW9uKCkge1xuICB2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLycpO1xuXG4gICAgICB2YXIgcHJpdl9rZXlfYXJtMSA9XG4gICAgICAgIFsgJy0tLS0tQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS0nLFxuICAgICAgICAgICdWZXJzaW9uOiBHbnVQRyB2MS40LjExIChHTlUvTGludXgpJyxcbiAgICAgICAgICAnJyxcbiAgICAgICAgICAnbFFIaEJGRVJuck1SQkFEbU0waElma0kzeW9zamdiV285djBMbnIzQ0NFKzhLc01zemdWUytoQnUwWGZHcmFLbScsXG4gICAgICAgICAgJ2l2Y0EyYWFKaW1IcVZZT1A3Z0Vud0ZBeEhCQnBlVEpjdTV3ekNGeUp3RVlxVmVTM25uYUloQlBwbFNGMTREdWYnLFxuICAgICAgICAgICdpNmJCOVJWN0t4VkFnNmF1bm1NMnRBdXRxQythMHkyckRhZjdqa0pvWjlnV0plMnpJK3ZyYUQ2Zml3Q2d4dkhvJyxcbiAgICAgICAgICAnM0lnVUxCOVJxSXFwTG9NZ1hmY2pDK2NELzFqZUpsS1JtK243MXJ5WXdUL0VDS3NzcEZ6N1MzNno2cTNYeVM4UScsXG4gICAgICAgICAgJ1FmcnNVejJwMWZiRmljdkp3SU9KOEIyMEovTjIvbml0NFAwZ0JVVFV4djNRRWE3WENNLzU2L3hyR2t5QnpzY1cnLFxuICAgICAgICAgICdBekJveS9BSzlLN0dONnoxM1JvenVBUzYwRjF4TzdNUWM2WWkyVlUzZUFTRFFFS2l5TC9VYmYvcy9ya1orc0dqJyxcbiAgICAgICAgICAneUppekJBQ3R3Q2JRekErejlYQlpOVWF0NU5QZ2NaejVRZWgxbndGOU54bnI2cHlCdjd0a3JMaC8zZ3hSR0hxRycsXG4gICAgICAgICAgJzA2M2RNYlVrOHBtVWNKekJVeVJzTmlJUERvRVVzTGpZNXptWlptcC93YUFocFJFc25LMjlXTENicUxkcFVvcnMnLFxuICAgICAgICAgICdjMUpKQnNPYmtBMUlNOFRaWThZVW12c01FdkJMQ0NhbnVLcGNsWlpYcWVSQWVPSEowdjREQXdLOFdmdVRlNUIrJyxcbiAgICAgICAgICAnTTJCT09lWmJOOEJwZmlBMWwvL2ZNTUhMUlMzVXZiTEJ2NFAxKzRTeXZoeVlUUjdNNzZRMHhQYzAzTUZPV0hMKycsXG4gICAgICAgICAgJ1M5VnVtYlFXVkdWemRESWdQSFJsYzNReVFIUmxjM1F1WTI5dFBvaGlCQk1SQWdBaUJRSlJFWjZ6QWhzREJnc0onLFxuICAgICAgICAgICdDQWNEQWdZVkNBSUpDZ3NFRmdJREFRSWVBUUlYZ0FBS0NSQVJKNVFEeXhhZStNWE5BS0N6V1NEUjN0TXJUckRiJyxcbiAgICAgICAgICAnVEFyaTczTjFYYjNqMUFDZlNsOXkrU0FhaDJxN0d2bWlSMSs2Ky9la3FKR2RBVmdFVVJHZXN4QUVBTmxwTVpqVycsXG4gICAgICAgICAgJzMzak14bEtIRGR5UkZYdEtPcThScmVYaHEwMHBsb3JIYmd6OXpGRVdtNFZGNTMrRS9LR25tSEd5WTVDeThUS3knLFxuICAgICAgICAgICdaamF1ZVpaOVh1RzBodVpnNUlmNjhpckZmTlp0eGRBMjZqdjgvL1BkWjBVaitYNkozUlZhMnBlTUxERHN3VFlMJyxcbiAgICAgICAgICAnT0wxWk8xZnhkdERENDBmZEFpSVoxUXlqd0VHMEFQdHo0MUVmQUFNRkJBQzUvZHRnQkJQdEhlOFVqREJhVWU0bicsXG4gICAgICAgICAgJ056SHVVQkJwNlhFK0g3ZXFITkZDdVpBSjd5cUpMR1ZITklhUVI0MTljTnkwOC9PTy8rWVVRN3JnNzhMeGpGaXYnLFxuICAgICAgICAgICdDSDdJemhmVSs2eXZFTFNiZ1JNaWNZNkVuQVAyR1QrYjErTXRGTmEzbEJHdEJIY0psYTUyYzJyVEFIdGhZWldrJyxcbiAgICAgICAgICAnZlQ1UjVEbkp1UTJjSkhCTVM5SFd5UDREQXdLOFdmdVRlNUIrTTJDN2EvWUpTVXY2U2V4ZEdDYWlhVGNBbTZnLycsXG4gICAgICAgICAgJ1B2QTZody9GTHpJRVA2N1FjUVNTVG1oZnRRSXduZGR0NFM0TXlKSkgzVTRmSmFGZllRMXpDbmlZSm9oSkJCZ1InLFxuICAgICAgICAgICdBZ0FKQlFKUkVaNnpBaHNNQUFvSkVCRW5sQVBMRnA3NFFiTUFuM1Y0ODU3eHduTzkvK3Z6SVZuTDkzVzNrMC84JyxcbiAgICAgICAgICAnQUtDOG9tWVBQb21OMUUvVUpGZlhkTERJTWk1TG9BPT0nLFxuICAgICAgICAgICc9TFNyVycsXG4gICAgICAgICAgJy0tLS0tRU5EIFBHUCBQUklWQVRFIEtFWSBCTE9DSy0tLS0tJ1xuICAgICAgICBdLmpvaW4oXCJcXG5cIik7XG4gICAgdmFyIHB1Yl9rZXlfYXJtMSA9IFxuICAgICAgICBbICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0nLFxuICAgICAgICAgICdWZXJzaW9uOiBHbnVQRyB2MS40LjExIChHTlUvTGludXgpJyxcbiAgICAgICAgICAnJyxcbiAgICAgICAgICAnbVFHaUJGRVJsdzRSQkFENkJtY2YydzFkdFVtdENMa2R4ZXFaTEFyazN2WW9RQWpkaWJ4QTNnWFZ5dXI3ZnNXYicsXG4gICAgICAgICAgJ3JvMGpWYkJIcU9DdEM2akR4RTJsNTJOUDkrdFRsV2VWTWFxcU52VUU0N0xTYVBxMkRHSThXeDFSajZiRjNtVHMnLFxuICAgICAgICAgICdvYllFd2hHYkdoL01oSm5NRTlBSE9EYXJ2azhBWmJ6bzArazFFd3JCV0Y2ZFRVQlBmcU83ckdVMmV3Q2c4MFdWJyxcbiAgICAgICAgICAneDVwdDNldmo4clJLM2pROFNNS1ROUnNELzFQaFRkeGRaVGRYQVJBRnpjVzFWYWFydVdXMFJyMStYSEtLd0RDeicsXG4gICAgICAgICAgJ2k3SEU3NlNPOXFqblFmWkNaRzc1Q2RReEkwaDhHRmVOM3pzRHFtaG9iMmlTejJhSjFrcnRqTStpWjFGQkZkNTcnLFxuICAgICAgICAgICdPcUNWNndtazVJVDBSQk4xMlp6TVMxOVl2ek4vT05YSHJtVFpsS0V4ZDlNaDlSS0xlVk53K2JmNkpzS1FFemNZJyxcbiAgICAgICAgICAnSnpGa0JBQ1g5WCtoRFljaE8vMmhpVHd4NGlPTzlGaHN1aDdlSVd1bUIzZ3QrYVVwbTFqclNiYXMvUUxUeW1taycsXG4gICAgICAgICAgJ3VadVFWWEk0TnRubHZ6bE5nV3Y0TDVzNVJVNVdxTkdHN1dTYUtOZGNydkpaUkMyZGdiVUp0MDRKNUNLcldwNlInLFxuICAgICAgICAgICdhSVlhbC84MVV0MTc3OGxVMDFQRXQ1NjNUY1FuVUJsbmpVNU9SMjVLaGZTZU41Q1pZN1FVVkdWemRDQThkR1Z6JyxcbiAgICAgICAgICAnZEVCMFpYTjBMbU52YlQ2SVlnUVRFUUlBSWdVQ1VSR1hEZ0liQXdZTENRZ0hBd0lHRlFnQ0NRb0xCQllDQXdFQycsXG4gICAgICAgICAgJ0hnRUNGNEFBQ2drUWlrRGxaSy9VdkxTc3BnQ2ZjTmFPcFRnMVcydWNSMUp3QmJCR3ZhRVJmdU1BblJndDMvcnMnLFxuICAgICAgICAgICdFcGxxRWFrTWNrQ3Rpa0VucHhZZScsXG4gICAgICAgICAgJz1iMkxuJyxcbiAgICAgICAgICAnLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLSdcbiAgICAgICAgXS5qb2luKFwiXFxuXCIpO1xuICAgIHZhciBtc2dfYXJtMSA9XG4gICAgICAgIFsgJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLScsXG4gICAgICAgICAgJ1ZlcnNpb246IEdudVBHIHYxLjQuMTEgKEdOVS9MaW51eCknLFxuICAgICAgICAgICcnLFxuICAgICAgICAgICdoUUVPQTFONE9DU1NqRUNCRUFQL2RpREpDUW40ZTg4MTkzUGdxaGJmQWtvaGs5UlEwdjBNUG5YcEpiQ1JUSEtPJyxcbiAgICAgICAgICAnOHI5bnhpQXIvVFF2NFpPaW5nWGRBcDJKWkVvRTlwWHhaM3IxVVdldzA0Y3p4bWdKOEZQMXp0WllXVkZBV0ZWaScsXG4gICAgICAgICAgJ1RqOTMwVEJEN0wxZlkvTUQ0Zks2eGpFRzd6NUdUOGs0dG40bUxtL1BwV01iYXJJZ2xmTW9wVHkxTS9weTJjSUQnLFxuICAgICAgICAgICcvMlNqN0lraDNVRmlHK3ptNHNWaVljNXJvTmJNeThpeGVvS2l4eGk5OU14OElOYTJjeE5mcWJhYmpibEZ5YzBaJyxcbiAgICAgICAgICAnQndtYkljK1ppWTJtZVJOSTV5L3RrMGdSRDdoVDg0SVhHR2w2L21IMDBic1gva2tXZEtHZVR2ejhzNUc4UkRIYScsXG4gICAgICAgICAgJ1phNEhnTGJYSXRrWC9RYXJ2UlM5a3ZrRDAxdWpIZmorMVp2Z21PQnR0TmZQMHA4QlFMSUlDcXZnMWVZRDlhUEInLFxuICAgICAgICAgICcrR3RPWjJGMytrNVZ5Qkw1eUluL3M2NVNCak5POEZxczNhTDB4K3A3czFjZlV6eDhKOGE4bldwcXEvcUlRSXFnJyxcbiAgICAgICAgICAnWkpINk1aUkt1UXdzY3dINk5XZ3NTVndjblZDQVhuWU9wYkh4RlErajdSYkYvK3VpdXFVK0RGSC9SZDVwaWs4YicsXG4gICAgICAgICAgJzBEcW5wMHlmZWZya2pRMG51dnViZ0I2UnY4OW1IcG52dUpmRkpSSW5wZzRsckh3THZSd2RwTjJIRG96RkhjS0snLFxuICAgICAgICAgICdhT1U9JyxcbiAgICAgICAgICAnPTRpR3QnLFxuICAgICAgICAgICctLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tJ1xuICAgICAgICBdLmpvaW4oXCJcXG5cIik7XG5cbiAgICB2YXIgcHJpdl9rZXlfYXJtMiA9XG4gICAgICBbJy0tLS0tQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS0nLFxuICAgICAgJ1ZlcnNpb246IEdudVBHIHYyLjAuMTkgKEdOVS9MaW51eCknLFxuICAgICAgJ1R5cGU6IFJTQS9SU0EnLFxuICAgICAgJ1B3ZDogaGVsbG8gd29ybGQnLFxuICAgICAgJycsXG4gICAgICAnbFFIK0JGSmhMMDRCQkFEY2xyVUVERHNtMFBTWmJRNnBtbDlGcHpUeVhpeUN5RE4rck1Pc3k5SjMwME9jMTBrdCcsXG4gICAgICAnL255QmVqOXZaU1JjYVc1VnBOTmowaUErYzEvdzJGUGY4NHpOc1R6dkRtdU1hTkhGVXpreTQvdmtZdVpyYS8vMycsXG4gICAgICAnK1JpN0NGOFJhd1NZUS80SVJiQzl6cWRCbHpuaXlmUU9XN0RwL0xZZThlaWJuRFNybWtRZW0wRzBqd0FSQVFBQicsXG4gICAgICAnL2dNREF1N0wvL2N6QnBFNDBwMVpxTzhLM2s3VWVqZW1qc1FxYzdrT3FubERZZDFaNi8zTkVBL1VNMzBTaWlwcicsXG4gICAgICAnS2pkSUZZNStocDBoY3M2RWlpTnEwUERmbS9XMmorN0hmclo1a3BlUVZ4RGVrNGlyZXpZWnJsN0pTMnhlemFMdicsXG4gICAgICAnazBGdi82Znhhc25GdGpPTTZRYnN0dTY3czVHcGw5eTA2WnhiUDNWcFQ2MitYZWlibi9zd1dyZmlKanVHRUVoTScsXG4gICAgICAnYmduc01wSHR6QXovTDh5NktTelZpRy8wNWhCYXFydmszL0dlRUE2bkUrbzArMGE2cjBMWUxUZW1tcTZGYmFBMScsXG4gICAgICAnUEhvK3g3azdvRmNCRlVVZVN6Z3g3OEdja3VQd3FyMm1OZmVGK0l1U1JucmxwWmwza2NiSEFTUEFPZkVreU1YUycsXG4gICAgICAnc1dHRTdnckNBamJ5UXlNM09FWFRTeXFuZWh2R1MvMVJkQjZrRER4R3dnRS9RRmJ3TnlFaDZLNGVhYUFUaFcyaicsXG4gICAgICAnSUVFSTBXRW5Sa1BpOWZYeXhoRnNDTFNJMVhocVRhcTdpRE5xSlR4RStBWDJiOVp1WlhBeEkzVGMvNysrdkV5TCcsXG4gICAgICAnM3AxOE4vTUIya3QxV2IxYXptWFdMMkVLbFQxQlo1eURhSnVCUThCaHBoTTN0Q1JVWlhOMElFMWpWR1Z6ZEdsdScsXG4gICAgICAnWjNSdmJpQThkR1Z6ZEVCbGVHRnRjR3hsTG1OdmJUNkl1UVFUQVFJQUl3VUNVbUV2VGdJYkx3Y0xDUWdIQXdJQicsXG4gICAgICAnQmhVSUFna0tDd1FXQWdNQkFoNEJBaGVBQUFvSkVFcGpZVHBOYmtDVU1Bd0QrZ0lLMDhxcEVaU1ZhczlxVytPaycsXG4gICAgICAnMzJ3ek5rd3hlNlBRZ1p3Y3lCcU1RWVpVY0thZ0M4Kzg5cE1RUTVzS1VHdnBJZ2F0NDJUZjFLTEdQY3ZHNGNEQScsXG4gICAgICAnSlo2dzJQWXo5WUhRcVBoOUxBK1BBblY4bTI1VGNHbUtjS2d2RlVxUTNVNTNYL1k5c0JQOEhvb1JxZnd3SGN2OScsXG4gICAgICAncE1nUW1vam1OYkk0Vkh5ZFJxSUJlUGF3blFIK0JGSmhMMDRCQkFEcEg4KzBFVm9scFBpT3JYVEtvQktUaXlyQicsXG4gICAgICAnVXl4em9keUo4em1WSjNITVRFVS92aWRwUXd6SVN3b2MvbmRERk1YUWF1cTZ4cUJDRDltMkJQUUkzVWRRelhuYicsXG4gICAgICAnTHNBSTUybldDSXFPa3pNNU5BS1dvS2h5WEs5WTRVSDR2OUxBWVFnbC9zdElJU3ZDZ0c0bUo4bHp6RUJXdlJkZicsXG4gICAgICAnUW0yR2hiNjQvM1Y1TkRkZW13QVJBUUFCL2dNREF1N0wvL2N6QnBFNDBpUGNwTHpMN0d3QmJXRmhTV2dTTHk1MycsXG4gICAgICAnTWQ5OUt4dzNjQXBXQ29rMkU4UjkvNFZTMDQ5MHhLWklhNXkySS9LOHRoVmhxazk2WjhLYnQ3TVJNQzFXTEhnQycsXG4gICAgICAncUp2a2VRQ0k2UHJGTTBQVUlQTEhBUXRESllLdGFMWHhZdWV4Y0FkS3paajNGSGR0TE5XQ29vSzZuM3ZKbEwxYycsXG4gICAgICAnV2paY0hKMVBIN1VTbGoxanVwNFhmeHNieml1eXNSVVN5WGtqbjkyR1pMbSs2NHZDSWl3aHFBWW9pekYyTkhIRycsXG4gICAgICAnaFJUTjRnUXp4cnhna2VWY2hsK2FnN0RrUVVEQU5JSVZJK0E2M0plTEpnV0ppSDFmYllsd0VTQnlIVyt6QkZOdCcsXG4gICAgICAncVN0amZJT2hqcmZOSWMzUnZzZ2diRGRXUUxjYnhtTFpqNHNCMHlkUFNnUktvYVVkUkhKWTBTNHZwOW91S090bCcsXG4gICAgICAnMmF1L1AxQlAzYmhEMGZEWGw5MW9laGVZdGgrTVNtc0pGRGcvdlpKekNKaEZhUTlkcCsyRW5qTjVhdU5DTmJhSScsXG4gICAgICAnYmVGSlJIRmY5Y2hhOHAzaGgrQUs1NE5SQ1QrK0IyTVhZZitUUHdxWDg4allNQnY4a2s4dllVZ284MTI4cjF6UScsXG4gICAgICAnRXpqdmlRRTlCQmdCQWdBSkJRSlNZUzlPQWhzdUFLZ0pFRXBqWVRwTmJrQ1VuU0FFR1FFQ0FBWUZBbEpoTDA0QScsXG4gICAgICAnQ2drUTRJVDNSR3dnTEplNm9nUUEyYWFKRUlCSVh0Z3JzKzhXU0o0azNETjRyUlhjWGFVWmY2NjdwamREOW5GMicsXG4gICAgICAnM0J6akZINlo3OEpJR2F4UkhKZE03YjA1YUU4WXV6TThmM05JbFQwRjBPTHEvVEkybXVZVTlmL1UyRFFCdWYrdycsXG4gICAgICAnS1RCNjIrUEVMVmdpOU1zWEMxUXYvdS9vMUxadG1teFRGRk9EMzV4S3N4WlpJMk9KajJwUXBxT2JXMjdNOE5sYycsXG4gICAgICAnQlFRQXcyWUEzZkZjMzhxUEsrUFk0clp5VFJkYnZqeXlYKzF6ZXFJbzh3bjdRQ1F3WHMrT0dhSDJmR29UMzVBSScsXG4gICAgICAnU1h1cUtjV3FvRXVPN09CU0VGVGhDWEJmVVlNQzAxT3JxS0Vzd1BtL1YzelprTHUwMXExMlVNd1phY2gyOFF3SycsXG4gICAgICAnL1labHk0aW9ORDJ0ZGF6ajE3dTJyVTJkd3RpSFBlMWlNcUdnVk1vUWlyZkxjK2s9JyxcbiAgICAgICc9bHc1ZScsXG4gICAgICAnLS0tLS1FTkQgUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS0nXS5qb2luKCdcXG4nKTtcblxuICAgIHZhciBwdWJfa2V5X2FybTIgPSBcbiAgICAgWyctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0nLFxuICAgICAgJ1ZlcnNpb246IEdudVBHIHYyLjAuMTkgKEdOVS9MaW51eCknLFxuICAgICAgJ1R5cGU6IFJTQS9SU0EnLFxuICAgICAgJycsXG4gICAgICAnbUkwRVVtRXZUZ0VFQU55V3RRUU1PeWJROUpsdERxbWFYMFduTlBKZUxJTElNMzZzdzZ6TDBuZlRRNXpYU1MzKycsXG4gICAgICAnZklGNlAyOWxKRnhwYmxXazAyUFNJRDV6WC9EWVU5L3pqTTJ4UE84T2E0eG8wY1ZUT1RMaisrUmk1bXRyLy9mNScsXG4gICAgICAnR0xzSVh4RnJCSmhEL2doRnNMM09wMEdYT2VMSjlBNWJzT244dGg3eDZKdWNOS3VhUkI2YlFiU1BBQkVCQUFHMCcsXG4gICAgICAnSkZSbGMzUWdUV05VWlhOMGFXNW5kRzl1SUR4MFpYTjBRR1Y0WVcxd2JHVXVZMjl0UG9pNUJCTUJBZ0FqQlFKUycsXG4gICAgICAnWVM5T0Foc3ZCd3NKQ0FjREFnRUdGUWdDQ1FvTEJCWUNBd0VDSGdFQ0Y0QUFDZ2tRU21OaE9rMXVRSlF3REFQNicsXG4gICAgICAnQWdyVHlxa1JsSlZxejJwYjQ2VGZiRE0yVERGN285Q0JuQnpJR294QmhsUndwcUFMejd6Mmt4QkRtd3BRYStraScsXG4gICAgICAnQnEzalpOL1Vvc1k5eThiaHdNQWxuckRZOWpQMWdkQ28rSDBzRDQ4Q2RYeWJibE53YVlwd3FDOFZTcERkVG5kZicsXG4gICAgICAnOWoyd0Uvd2VpaEdwL0RBZHkvMmt5QkNhaU9ZMXNqaFVmSjFHb2dGNDlyQzRqUVJTWVM5T0FRUUE2Ui9QdEJGYScsXG4gICAgICAnSmFUNGpxMTB5cUFTazRzcXdWTXNjNkhjaWZNNWxTZHh6RXhGUDc0bmFVTU15RXNLSFA1M1F4VEYwR3JxdXNhZycsXG4gICAgICAnUWcvWnRnVDBDTjFIVU0xNTJ5N0FDT2RwMWdpS2pwTXpPVFFDbHFDb2NseXZXT0ZCK0wvU3dHRUlKZjdMU0NFcicsXG4gICAgICAnd29CdUppZkpjOHhBVnIwWFgwSnRob1crdVA5MWVUUTNYcHNBRVFFQUFZa0JQUVFZQVFJQUNRVUNVbUV2VGdJYicsXG4gICAgICAnTGdDb0NSQktZMkU2VFc1QWxKMGdCQmtCQWdBR0JRSlNZUzlPQUFvSkVPQ0U5MFJzSUN5WHVxSUVBTm1taVJDQScsXG4gICAgICAnU0Y3WUs3UHZGa2llSk53emVLMFYzRjJsR1grdXU2WTNRL1p4ZHR3YzR4UittZS9DU0Jtc1VSeVhUTzI5T1doUCcsXG4gICAgICAnR0xzelBIOXpTSlU5QmREaTZ2MHlOcHJtRlBYLzFOZzBBYm4vc0Nrd2V0dmp4QzFZSXZUTEZ3dFVMLzd2Nk5TMicsXG4gICAgICAnYlpwc1V4UlRnOStjU3JNV1dTTmppWTlxVUtham0xdHV6UERaWEFVRUFNTm1BTjN4WE4vS2p5dmoyT0syY2swWCcsXG4gICAgICAnVzc0OHNsL3RjM3FpS1BNSiswQWtNRjdQamhtaDlueHFFOStRQ0VsN3FpbkZxcUJManV6Z1VoQlU0UWx3WDFHRCcsXG4gICAgICAnQXROVHE2aWhMTUQ1djFkODJaQzd0TmF0ZGxETUdXbklkdkVNQ3YyR1pjdUlxRFE5clhXczQ5ZTd0cTFObmNMWScsXG4gICAgICAnaHozdFlqS2hvRlRLRUlxM3kzUHAnLFxuICAgICAgJz1oL2FYJyxcbiAgICAgICctLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tJ10uam9pbignXFxuJyk7XG5cbnZhciBwdWJfa2V5X2FybTMgPVxuICAgICAgWyctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0nLFxuICAgICAgJ1ZlcnNpb246IEdudVBHIHYyLjAuMTkgKEdOVS9MaW51eCknLFxuICAgICAgJycsXG4gICAgICAnbVFFTkJGS1YwRlVCQ0FDdFpsaUFweTAxS0JHYkdOQjM2WUdINGxwcis1S29xRjFJOEE1SVQwWWVOanlHaXNPaycsXG4gICAgICAnV3NEc1V6T3FhTnZnelE4MkkzTVkvalFWNXJMQmhILzZMaVJtQ0ExNldrS2NxQnJIZk5HSXhKK1Erb2ZWQkhVYicsXG4gICAgICAnYVM5Q2xYWUk4OGo3NDdRZ1d6aXJuTHVFQTBHZmlsUlpjZXdJSTFwREEvRzcrbTFId1Y0cUhzUGF0YVlMZWJvcScsXG4gICAgICAnaFBBM2gxRVZWUUZNQWN3bHFqT3VTOCt3ZUhRUmZOVlJHUWRSTW02SDcxNjZQc2VEVlJVSGRrSnBWYUtGaHB0ZycsXG4gICAgICAnckRvTkkwbE8rVXVqZHFlRjFvNXRWWjBqL3M3UmJ5QnZkTFRYTnVCYmNwcTkzY2VTV3VKUFptaTFYenRRWEtZZScsXG4gICAgICAneTBmK2x0Z1Z0WkRFYzdUR1Y1V0RYOWVyUkVDQ2NBMytzN0ozQUJFQkFBRzBHMHBUSUVOeWVYQjBieUE4WkdsbScsXG4gICAgICAnWm1sbFFHaHZiV1V1YjNKblBva0JQd1FUQVFJQUtRVUNVcFhRVlFJYkF3VUpDV1lCZ0FjTENRZ0hBd0lCQmhVSScsXG4gICAgICAnQWdrS0N3UVdBZ01CQWg0QkFoZUFBQW9KRU52eUkraHdVMDMweVJBSUFLWC9tR0VnaS9taXFhc2JiUW95Sy9DUycsXG4gICAgICAnYTdzUnhnWndPV1FMZGkyeHhwRTVWNFc0SEpJRE5MSnM1dkdwUk40bW1jTksyZm1KQWg3NHcwUHNrbVZnSkVoUCcsXG4gICAgICAnZEZKMTRVQzNmRlBxNW5icWtCbDdoVTB0RFA1alp4bzlydVFaZkRPV3BIS3hPQ3o1Z3VZSjBDVzk3Yno0ZkNoWicsXG4gICAgICAnTkZEeWZVN1ZzSlF3UklvVmlWY01DaXBQMGZWWlFrSWhod3B6UXBtVm1OOEUwYTZqV2V6VFp2MVlwTWRsemJFZicsXG4gICAgICAnSDc5bDNTdGFPaDkvVW45Q2tJeXFFV2RZaUt2SVltczluRU55ZWhON3IvT0tZTjNTVytxbHQ1R2FMK3dzK04xdycsXG4gICAgICAnNmtFWmpQRnduc3IrWTRBM29IY0F3WHE3bmZPejcxVVNvalNtbW84cGdkTjhqZTE2Q1A5OHZ3My9rNlRuY0xTNScsXG4gICAgICAnQVEwRVVwWFFWUUVJQU1FakhNZXFnN0IwNEZsaVVGV3IvOEM2c0pEYjQ5Mk1sR0FXZ2doSWJudUpmWEFuVUdkTicsXG4gICAgICAnb0F6bjBTK245M1kvcUhiVzZZY2pIRDQvRytrSzNNdXh0aEFGcWNWamRIWlFYSzBya2hYTy91MWNvN3YxY2R0aycsXG4gICAgICAnT1RFY3lPcHlMWG9sTS8xUzJVWUltaHJtbDdZdWxUSE1uV1ZqYTd4dTZRSVJzbys3SEJGVC91OUQ0N0wveFhyWCcsXG4gICAgICAnTXpYRlZaZkJ0VlkreW9lVHJPWTNPWDljQk1PQXUwa3VOOWVUMThZdjJ5aTZYTXpQM2lPTlZIdGw2SGZGckFBNycsXG4gICAgICAna0F0eDRuZTBqZ0FQV1orYThoTXk1OW9uMlpGcy9BdlNwSnRTYzFrdy92TVRXa3lWUDFLeTIwdkFQSFE2RWo1cScsXG4gICAgICAnMU5HSi9KYmNGZ29sdkVlSS8zdUR1ZUxqajRTZFNJYkxPWE1BRVFFQUFZa0JKUVFZQVFJQUR3VUNVcFhRVlFJYicsXG4gICAgICAnREFVSkNXWUJnQUFLQ1JEYjhpUG9jRk5OOU5Ma0Ivd080aVJ4aWEwemY0S3cyUkxWWkc4cWN1bzNCdzlVVFhZWScsXG4gICAgICAnbEkwQXV0b0xOblNVUk1MTENxNnJjSjBCQ1hHai8yaVowTkJ4WnEzdDV2YlJoNnVVditocGlTeEsxbkY3QWhlTicsXG4gICAgICAnNGFBQXpoYld4MFVEVEYwNGViRy9uZUU0dURrbFJJSkxoaWY2K0J3dStFVWVUbEdiRGo3ZnFHU3NOZThnOTJ3NycsXG4gICAgICAnMWU0MXJGLzlDTW9Pc3dyS2dJalhBb3UzYWV4b2dXY0h2S1kyRCsxcTlleE9SZTFySWExK3NVR2w1UEcyd3NFcycsXG4gICAgICAnem5ONnF0TjVnTWxHWTFvZldEWStJMDJnTzRxemFaL0Z4UlpmaXR0Q3c3djVkbVFZS290OXFSaTJLeDNGdncraCcsXG4gICAgICAnaXZGQnBDNFRXZ3BwRkJuSkpuQXNGWFpKUWNlak1XNG5FbU9WaVJRWFk4TjhQZXBRbWdzdScsXG4gICAgICAnPXVtbXknLFxuICAgICAgJy0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0nXS5qb2luKCdcXG4nKTtcblxuXG4gIHZhciB0ZXN0cyA9IFtmdW5jdGlvbigpIHtcbiAgICB2YXIgcHJpdl9rZXkgPSBvcGVucGdwLmtleS5yZWFkQXJtb3JlZChwcml2X2tleV9hcm0xKS5wYWNrZXRzO1xuICAgIHZhciBwdWJfa2V5ID0gb3BlbnBncC5rZXkucmVhZEFybW9yZWQocHViX2tleV9hcm0xKS5wYWNrZXRzO1xuICAgIHZhciBtc2cgPSBvcGVucGdwLm1lc3NhZ2UucmVhZEFybW9yZWQobXNnX2FybTEpLnBhY2tldHM7XG4gICAgLy9UT0RPIG5lZWQgYm90aD9cbiAgICBwcml2X2tleVswXS5kZWNyeXB0KFwiYWJjZFwiKTtcbiAgICBwcml2X2tleVszXS5kZWNyeXB0KFwiYWJjZFwiKTtcbiAgICBtc2dbMF0uZGVjcnlwdChwcml2X2tleVszXSk7XG4gICAgbXNnWzFdLmRlY3J5cHQobXNnWzBdLnNlc3Npb25LZXlBbGdvcml0aG0sIG1zZ1swXS5zZXNzaW9uS2V5KTtcbiAgICBtc2dbMV0ucGFja2V0c1syXS52ZXJpZnkocHViX2tleVswXSwgbXNnWzFdLnBhY2tldHNbMV0pO1xuICAgIHJldHVybiBuZXcgdW5pdC5yZXN1bHQoXCJUZXN0aW5nIHNpZ25hdHVyZSBjaGVja2luZyBvbiBDQVNUNS1lbmNpcGhlcmVkIG1lc3NhZ2VcIixcbiAgICAgICAgICAgIG1zZ1sxXS5wYWNrZXRzWzJdLnZlcmlmaWVkID09PSB0cnVlKTtcblxuICB9LCBmdW5jdGlvbigpIHtcblxuICAgIC8vIGV4ZXJjaXNlcyB0aGUgR251UEcgczJrIHR5cGUgMTAwMSBleHRlbnNpb246XG4gICAgLy8gdGhlIHNlY3JldHMgb24gdGhlIHByaW1hcnkga2V5IGhhdmUgYmVlbiBzdHJpcHBlZC5cbiAgICB2YXIgcHJpdl9rZXlfZ251cGdfZXh0ID0gb3BlbnBncC5rZXkucmVhZEFybW9yZWQoW1xuICAgICAgICAgICctLS0tLUJFR0lOIFBHUCBQUklWQVRFIEtFWSBCTE9DSy0tLS0tJyxcbiAgICAgICAgICAnVmVyc2lvbjogR251UEcgdjEuNC4xMSAoR05VL0xpbnV4KScsXG4gICAgICAgICAgJycsXG4gICAgICAgICAgJ2xRR3FCRkVSbnJNUkJBRG1NMGhJZmtJM3lvc2pnYldvOXYwTG5yM0NDRSs4S3NNc3pnVlMraEJ1MFhmR3JhS20nLFxuICAgICAgICAgICdpdmNBMmFhSmltSHFWWU9QN2dFbndGQXhIQkJwZVRKY3U1d3pDRnlKd0VZcVZlUzNubmFJaEJQcGxTRjE0RHVmJyxcbiAgICAgICAgICAnaTZiQjlSVjdLeFZBZzZhdW5tTTJ0QXV0cUMrYTB5MnJEYWY3amtKb1o5Z1dKZTJ6SSt2cmFENmZpd0NneHZIbycsXG4gICAgICAgICAgJzNJZ1VMQjlScUlxcExvTWdYZmNqQytjRC8xamVKbEtSbStuNzFyeVl3VC9FQ0tzc3BGejdTMzZ6NnEzWHlTOFEnLFxuICAgICAgICAgICdRZnJzVXoycDFmYkZpY3ZKd0lPSjhCMjBKL04yL25pdDRQMGdCVVRVeHYzUUVhN1hDTS81Ni94ckdreUJ6c2NXJyxcbiAgICAgICAgICAnQXpCb3kvQUs5SzdHTjZ6MTNSb3p1QVM2MEYxeE83TVFjNllpMlZVM2VBU0RRRUtpeUwvVWJmL3MvcmtaK3NHaicsXG4gICAgICAgICAgJ3lKaXpCQUN0d0NiUXpBK3o5WEJaTlVhdDVOUGdjWno1UWVoMW53RjlOeG5yNnB5QnY3dGtyTGgvM2d4UkdIcUcnLFxuICAgICAgICAgICcwNjNkTWJVazhwbVVjSnpCVXlSc05pSVBEb0VVc0xqWTV6bVpabXAvd2FBaHBSRXNuSzI5V0xDYnFMZHBVb3JzJyxcbiAgICAgICAgICAnYzFKSkJzT2JrQTFJTThUWlk4WVVtdnNNRXZCTENDYW51S3BjbFpaWHFlUkFlT0hKMHY0RFpRSkhUbFVCdEJaVScsXG4gICAgICAgICAgJ1pYTjBNaUE4ZEdWemRESkFkR1Z6ZEM1amIyMCtpR0lFRXhFQ0FDSUZBbEVSbnJNQ0d3TUdDd2tJQndNQ0JoVUknLFxuICAgICAgICAgICdBZ2tLQ3dRV0FnTUJBaDRCQWhlQUFBb0pFQkVubEFQTEZwNzR4YzBBb0xOWklOSGUweXRPc050TUN1THZjM1ZkJyxcbiAgICAgICAgICAndmVQVUFKOUtYM0w1SUJxSGFyc2ErYUpIWDdyNzk2U29rWjBCV0FSUkVaNnpFQVFBMldreG1OYmZlTXpHVW9jTicsXG4gICAgICAgICAgJzNKRVZlMG82cnhHdDVlR3JUU21XaXNkdURQM01VUmFiaFVYbmY0VDhvYWVZY2JKamtMTHhNckptTnE1NWxuMWUnLFxuICAgICAgICAgICc0YlNHNW1Ea2gvcnlLc1Y4MW0zRjBEYnFPL3ovODkxblJTUDVmb25kRlZyYWw0d3NNT3pCTmdzNHZWazdWL0YyJyxcbiAgICAgICAgICAnME1QalI5MENJaG5WREtQQVFiUUErM1BqVVI4QUF3VUVBTG45MjJBRUUrMGQ3eFNNTUZwUjdpYzNNZTVRRUducCcsXG4gICAgICAgICAgJ2NUNGZ0Nm9jMFVLNWtBbnZLb2tzWlVjMGhwQkhqWDF3M0xUejg0Ny81aFJEdXVEdnd2R01XSzhJZnNqT0Y5VDcnLFxuICAgICAgICAgICdySzhRdEp1QkV5Snhqb1NjQS9ZWlA1dlg0eTBVMXJlVUVhMEVkd21Wcm5aemF0TUFlMkZobGFSOVBsSGtPY201JyxcbiAgICAgICAgICAnRFp3a2NFeEwwZGJJL2dNREFyeForNU43a0g0ellMdHI5Z2xKUy9wSjdGMFlKcUpwTndDYnFEOCs4RHFIRDhVdicsXG4gICAgICAgICAgJ01nUS9ydEJ4QkpKT2FGKzFBakNkMTIzaExneklra2ZkVGg4bG9WOWhEWE1LZUpnbWlFa0VHQkVDQUFrRkFsRVInLFxuICAgICAgICAgICduck1DR3d3QUNna1FFU2VVQThzV252aEJzd0NmZFhqem52SENjNzMvNi9NaFdjdjNkYmVUVC93QW9MeWlaZzgrJyxcbiAgICAgICAgICAnaVkzVVQ5UWtWOWQwc01neUxrdWcnLFxuICAgICAgICAgICc9R1FzWScsXG4gICAgICAgICAgJy0tLS0tRU5EIFBHUCBQUklWQVRFIEtFWSBCTE9DSy0tLS0tJyxcbiAgICAgICAgXS5qb2luKFwiXFxuXCIpKS5wYWNrZXRzO1xuICAgIHZhciBwdWJfa2V5ID0gb3BlbnBncC5rZXkucmVhZEFybW9yZWQocHViX2tleV9hcm0xKS5wYWNrZXRzO1xuICAgIHZhciBtc2cgPSBvcGVucGdwLm1lc3NhZ2UucmVhZEFybW9yZWQobXNnX2FybTEpLnBhY2tldHM7XG5cbiAgICBwcml2X2tleV9nbnVwZ19leHRbM10uZGVjcnlwdChcImFiY2RcIik7XG4gICAgbXNnWzBdLmRlY3J5cHQocHJpdl9rZXlfZ251cGdfZXh0WzNdKTtcbiAgICBtc2dbMV0uZGVjcnlwdChtc2dbMF0uc2Vzc2lvbktleUFsZ29yaXRobSwgbXNnWzBdLnNlc3Npb25LZXkpO1xuICAgIG1zZ1sxXS5wYWNrZXRzWzJdLnZlcmlmeShwdWJfa2V5WzBdLCBtc2dbMV0ucGFja2V0c1sxXSk7XG4gICAgcmV0dXJuIG5ldyB1bml0LnJlc3VsdChcIlRlc3RpbmcgR251UEcgc3RyaXBwZWQta2V5IGV4dGVuc2lvbnNcIixcbiAgICAgICAgICAgIG1zZ1sxXS5wYWNrZXRzWzJdLnZlcmlmaWVkID09PSB0cnVlKTtcblxuICB9LCBmdW5jdGlvbigpIHtcblxuICAgIHZhciBzaWduZWRBcm1vciA9IFxuICAgICAgIFsnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tJyxcbiAgICAgICAgJ1ZlcnNpb246IEdudVBHIHYyLjAuMTkgKEdOVS9MaW51eCknLFxuICAgICAgICAnJyxcbiAgICAgICAgJ293R2J3TXZNd01UNG9PVzdTNDZDem5UR05lWkpMQ1dwRlNWQlUzWkdGMmZrRjVVbzVLWVdGeWVtcDNMbEFVVVYnLFxuICAgICAgICAnY2pMelVybmVUcDN6YXV2YU45TzI2TDladU9GTnk0TFh5eWR3Y1hYTVlXRmdaR0pnWTJVQ2FXWGc0aFNBbWJsSycsXG4gICAgICAgICduUG1mc1hZeGQ1OEthOWVWckVuU3B6aWxyNTIwZlhCckpzZjJQL29UcXpUajNoenlMRzBvM1RUenhGZnJ0T1hmJyxcbiAgICAgICAgJ2N3NlU1N24zL1o0WDBwRVo2OEM1L28vNk5wUElDRDdmdUVPejM5MzZyYVo2d1hHenVlWThwZlBuVmpZMGFqQWMnLFxuICAgICAgICAnUHRKenZ2cWordWJZYVQxc0s5d1doZDlsTDMvVis5WnV1YTlRak9XQzIyYnVjaHNDcm9oOGZMb1pBQT09JyxcbiAgICAgICAgJz1WSDhGJyxcbiAgICAgICAgJy0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0nXS5qb2luKCdcXG4nKTtcblxuICAgIHZhciBzTXNnID0gb3BlbnBncC5tZXNzYWdlLnJlYWRBcm1vcmVkKHNpZ25lZEFybW9yKS5wYWNrZXRzO1xuICAgIHZhciBwdWJfa2V5ID0gb3BlbnBncC5rZXkucmVhZEFybW9yZWQocHViX2tleV9hcm0yKS5wYWNrZXRzO1xuICAgIHNNc2dbMF0ucGFja2V0c1syXS52ZXJpZnkocHViX2tleVszXSwgc01zZ1swXS5wYWNrZXRzWzFdKTtcbiAgICByZXR1cm4gbmV3IHVuaXQucmVzdWx0KFwiVmVyaWZ5IFY0IHNpZ25hdHVyZS4gSGFzaDogU0hBMS4gUEs6IFJTQS4gU2lnbmF0dXJlIFR5cGU6IDB4MDAgKGJpbmFyeSBkb2N1bWVudClcIiwgc01zZ1swXS5wYWNrZXRzWzJdLnZlcmlmaWVkKTtcbiAgfSwgZnVuY3Rpb24oKSB7XG5cbiAgICB2YXIgc2lnbmVkQXJtb3IgPSBcbiAgICAgICBbJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLScsXG4gICAgICAgICdWZXJzaW9uOiBHbnVQRyB2Mi4wLjE5IChHTlUvTGludXgpJyxcbiAgICAgICAgJycsXG4gICAgICAgICdvd0did012TXlNajRvT1c3UzQ2Q3puVEcwOVlsTENXcEZTVkJVNDd4Rkdma0Y1VW81S1lXRnllbXAvSnk1UUdGJyxcbiAgICAgICAgJ0ZYSXk4NERNdDFQbnZOcTY5czIwTGZwdkZtNTQwN0xnOWZJSnZGeThYSjBNVTVsWkdVRmE0ZVl4eGlRei82Ky8nLFxuICAgICAgICAnYUZ0NC82K2U3Nk82czFhZkxpNjVlbW1LOXhzZGg3TXI2MFVuVDJVTjBMd29jV25UN3Qvbk9NSnVibnlwdnpUdScsXG4gICAgICAgICdhUEp5dm05VFRwb2JXL08rUDFuMlRITFM0VUN2V3QxMk9hMmxKMDRHTHdrL2JERjF1KzhacGZQQ3BzeExWemNzJyxcbiAgICAgICAgJ1pHdGJxL2YyM1h4Vi9qa0w0N2hyM3MzSWM0eW9aVFc0b1pPMjdHWWYzN1RQcDlMM1Zib0NBQT09JyxcbiAgICAgICAgJz1wYTZCJyxcbiAgICAgICAgJy0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0nXS5qb2luKCdcXG4nKTtcblxuICAgIHZhciBzTXNnID0gb3BlbnBncC5tZXNzYWdlLnJlYWRBcm1vcmVkKHNpZ25lZEFybW9yKS5wYWNrZXRzO1xuICAgIHZhciBwdWJfa2V5ID0gb3BlbnBncC5rZXkucmVhZEFybW9yZWQocHViX2tleV9hcm0yKS5wYWNrZXRzO1xuICAgIHNNc2dbMF0ucGFja2V0c1syXS52ZXJpZnkocHViX2tleVszXSwgc01zZ1swXS5wYWNrZXRzWzFdKTtcbiAgICByZXR1cm4gbmV3IHVuaXQucmVzdWx0KFwiVmVyaWZ5IFYzIHNpZ25hdHVyZS4gSGFzaDogTUQ1LiBQSzogUlNBLiBTaWduYXR1cmUgVHlwZTogMHgwMSAodGV4dCBkb2N1bWVudClcIiwgc01zZ1swXS5wYWNrZXRzWzJdLnZlcmlmaWVkKTtcbiAgfSwgZnVuY3Rpb24oKSB7XG5cbiAgICB2YXIgbXNnX2FybW9yID0gXG4gICAgICAgWyctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS0nLFxuICAgICAgICAnVmVyc2lvbjogR251UEcgdjIuMC4xOSAoR05VL0xpbnV4KScsXG4gICAgICAgICcnLFxuICAgICAgICAnaEl3RDRJVDNSR3dnTEpjQkJBREVCZG0rR0VXN0lWMUsvQnlrZzBuQjBXWU8wOGFpNy84LytZL085eHU2UmlVMCcsXG4gICAgICAgICdxNy9qV3VLbXM3a1NqdzlneE1DamYyZEduQXVUNENnNTA1S2o1V2ZlQnVIaDYxOG92TzhxbzRoMHFIeXAxL3kzJyxcbiAgICAgICAgJ28xUDBJWFBBYitMR0pPZU83RHlNOVhwMkFPQmlJS09WV3pGVGcrTUJaT2MrWFpFVngzRmlvSGZtOVNTRHVkTEEnLFxuICAgICAgICAnV0FFa0Rha0NHNk1SRmovN1NtT2lWOG1RS0grWVBNS1Q2OWVEWlc3aGpJTmFicnBNMnBkUlU3YzlsQzdDTVVCeCcsXG4gICAgICAgICdWajd3WnNRQk1BU1NDOGYycmhwR0EyaUt2WU1zbVczZzlSMXhrdmoxTVhXZnRTUFVTNGplTlRBZ0V3dnZGNkFmJyxcbiAgICAgICAgJ2NQK09ZU1hLbFRid2ZFcjczRVMyTzMvSUZFOXNIUmpQcVdheFd1djRERFE1WWZJeEU1NEMxYUU4QXE1L1FhSUgnLFxuICAgICAgICAndjM4VFVTaWEweUVNQ2MvdEpkNThEaWtrVDA3QUYxNjJ0Y3g5Um8wWmpodWR5dXZVeVhJZlBmeEErWFdSMnBkeicsXG4gICAgICAgICdpZnh5VjR6aWE5UnZhQ1VZOHZYR00rZ1FKM05OWHgyTGtaQTNrV1VFeXhGVkwxVmwvWFVRWTBNNlUrdWNjU2s0JyxcbiAgICAgICAgJ2VNWG02ZXlFV0RjajBsQlJja3FLb0tvMXcvdWFuMTFqUHVIc25SejZqTzlEc3VLRXo3OVVEZ0k9JyxcbiAgICAgICAgJz1jRmk3JyxcbiAgICAgICAgJy0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0nXS5qb2luKCdcXG4nKTtcblxuICAgIHZhciBwbGFpbnRleHQgPSAnc2hvcnQgbWVzc2FnZVxcbm5leHQgbGluZVxcbu2VnOq1reyWtC/sobDshKDrp5AnO1xuICAgIHZhciBlc01zZyA9IG9wZW5wZ3AubWVzc2FnZS5yZWFkQXJtb3JlZChtc2dfYXJtb3IpO1xuICAgIHZhciBwdWJLZXkgPSBvcGVucGdwLmtleS5yZWFkQXJtb3JlZChwdWJfa2V5X2FybTIpO1xuICAgIHZhciBwcml2S2V5ID0gb3BlbnBncC5rZXkucmVhZEFybW9yZWQocHJpdl9rZXlfYXJtMik7XG5cbiAgICB2YXIga2V5aWRzID0gZXNNc2cuZ2V0RW5jcnlwdGlvbktleUlkcygpO1xuICAgIHByaXZLZXkuZGVjcnlwdEtleVBhY2tldChrZXlpZHMsICdoZWxsbyB3b3JsZCcpO1xuXG4gICAgdmFyIGRlY3J5cHRlZCA9IG9wZW5wZ3AuZGVjcnlwdEFuZFZlcmlmeU1lc3NhZ2UocHJpdktleSwgW3B1YktleV0sIGVzTXNnKTtcbiAgICB2YXIgdmVyaWZpZWQgPSBkZWNyeXB0ZWQudGV4dCA9PSBwbGFpbnRleHQgJiYgZGVjcnlwdGVkLnNpZ25hdHVyZXNbMF0uc3RhdHVzO1xuXG4gICAgcmV0dXJuIG5ldyB1bml0LnJlc3VsdChcIlZlcmlmeSBzaWduYXR1cmUgb2Ygc2lnbmVkIGFuZCBlbmNyeXB0ZWQgbWVzc2FnZSBmcm9tIEdQRzIgd2l0aCBvcGVucGdwLmRlY3J5cHRBbmRWZXJpZnlNZXNzYWdlXCIsIHZlcmlmaWVkKTtcbiAgfSwgZnVuY3Rpb24oKSB7XG5cbiAgICB2YXIgbXNnX2FybW9yID0gXG4gICAgICBbJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLScsXG4gICAgICAnVmVyc2lvbjogRW5jcnlwdGlvbiBEZXNrdG9wIDEwLjMuMCAoQnVpbGQgOTMwNyknLFxuICAgICAgJ0NoYXJzZXQ6IHV0Zi04JyxcbiAgICAgICcnLFxuICAgICAgJ3FBTlFSMURCakFQZ2hQZEViQ0FzbHdFRC8yUzRvTnZDak81VGRMVU1NVXVWT1FjOGZpNmM1WElCdTdZMDlmRVgnLFxuICAgICAgJ0ptL1Vya0RIVmdtUG9qTEdCREYwQ1lFTk5aT1ZyTmZwYWhZN0EzcjRIUHpHdWNCekNPMXV4dVVJS2podE5BQU0nLFxuICAgICAgJ21qRDkzOWVybmpvb09ack02eER1UmFYOGFkRzBMU3hwTmFWSkd4WGQvRWRsbUtESmJZREk2YUo1SU5yVXh6QVInLFxuICAgICAgJ0RBcXcwc0JTQVhnUldnaUg2SUlpQW81eTVXRkVERU45c0dTdGFFUVQyd2QzMmtYNzNNNGladU10L0dNMmFnaUInLFxuICAgICAgJ3NXYjd5TGNOSGlKLzNPblRmRGc5K1Q1NDNrRnE5Rmx3RmJ3cXlnTy93bTllL2tnTUJxMFpzRk9mVitHUnRYZXAnLFxuICAgICAgJzNxTmJKc216R3ZkcWlVSGIvK2hrZEUxOTFqYVNWY08vemFNVzROMFZjMUl3SUVoWjhJOSs5Ykt3dXNkVmhIVDUnLFxuICAgICAgJ015U25oSW9ndiswSWxhZy9hWStVaUN0K1pjaWU2OVQ3RWl4NDhmQy9WVlc1dzNJTmYxVDJDTW1EbTVaTFpGUk4nLFxuICAgICAgJ295cXpiOVZzZ3UxZ1M3U0NiNnFUYm5iVjlQbFN5VTR3SkI2c2lYOGh6L1UwdXJva1Q1c2UzdVlSamlWMEtia0EnLFxuICAgICAgJ3psMS9yL3dDcm13WDRHbDlWTjkrMzNjUWdZWkFsSkxzUnc4TjgyR2hiVndlWlM4cXd2MjRHUT09JyxcbiAgICAgICc9bng5MCcsXG4gICAgICAnLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLSddLmpvaW4oJ1xcbicpO1xuXG4gICAgdmFyIHBsYWludGV4dCA9ICdzaG9ydCBtZXNzYWdlXFxubmV4dCBsaW5lXFxu7ZWc6rWt7Ja0L+yhsOyEoOunkFxcblxcbic7XG4gICAgdmFyIGVzTXNnID0gb3BlbnBncC5tZXNzYWdlLnJlYWRBcm1vcmVkKG1zZ19hcm1vcik7XG4gICAgdmFyIHB1YktleSA9IG9wZW5wZ3Aua2V5LnJlYWRBcm1vcmVkKHB1Yl9rZXlfYXJtMik7XG4gICAgdmFyIHByaXZLZXkgPSBvcGVucGdwLmtleS5yZWFkQXJtb3JlZChwcml2X2tleV9hcm0yKTtcblxuICAgIHZhciBrZXlpZHMgPSBlc01zZy5nZXRFbmNyeXB0aW9uS2V5SWRzKCk7XG4gICAgcHJpdktleS5kZWNyeXB0S2V5UGFja2V0KGtleWlkcywgJ2hlbGxvIHdvcmxkJyk7XG5cbiAgICB2YXIgZGVjcnlwdGVkID0gb3BlbnBncC5kZWNyeXB0QW5kVmVyaWZ5TWVzc2FnZShwcml2S2V5LCBbcHViS2V5XSwgZXNNc2cpO1xuICAgIHZhciB2ZXJpZmllZCA9IGRlY3J5cHRlZC50ZXh0ID09IHBsYWludGV4dCAmJiBkZWNyeXB0ZWQuc2lnbmF0dXJlc1swXS5zdGF0dXM7XG5cbiAgICByZXR1cm4gbmV3IHVuaXQucmVzdWx0KFwiVmVyaWZ5IHNpZ25hdHVyZSBvZiBzaWduZWQgYW5kIGVuY3J5cHRlZCBtZXNzYWdlIGZyb20gUEdQIDEwLjMuMCB3aXRoIG9wZW5wZ3AuZGVjcnlwdEFuZFZlcmlmeU1lc3NhZ2VcIiwgdmVyaWZpZWQpO1xuICB9LCBmdW5jdGlvbigpIHtcblxuICAgIHZhciBtc2dfYXJtb3IgPSBcbiAgICAgWyctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS0nLFxuICAgICAgJ1ZlcnNpb246IEdudVBHIHYyLjAuMTkgKEdOVS9MaW51eCknLFxuICAgICAgJycsXG4gICAgICAnb3dHYndNdk13TUY0KzVQeWk0SmczeThNRThEY0J5M2ZYWElVZEtZenJqRk5ZaWxKclNnSm1zWERYSnlSWDFTaScsXG4gICAgICAna0p0YVhKeVluc3FWQnhSVnlNbk1TK1Y2TzNYT3E2MXIzMHpib3Y5bTRZWTNMUXRlTDUvUU1ZZUZnWkdEZ1kyVicsXG4gICAgICAnQ2FTUmdZdFRBR1ppWXhZTHd5U2JRazA3cHRaZWw2Z21qckt5QldzeVdka09HM29zY0xCZElwWFhmRGRiNmZOdicsXG4gICAgICAnOFVMTjVMMWVkK3hObzc5UDJkQm90V3VkNnZuN2U5ZHRMSjdvMTJQdW5udkV6OGd5eXZQNC9Bcy9sb3MweHNuWicsXG4gICAgICAnSCs4dWJscmh2R3RMeEpVWnVVS1pPNlFkSHEyTmVwdXc4T3JmaU1YUEJEUVhYcFYycTExWmUrckQzbG5kZ3YvQycsXG4gICAgICAnYkpRTk9obGwwSjBIODM5akZ2dC8xNm0yMGgvWm1Eb1dxSnl3YXBueXBqZElqY1hyKzdySkZlc3M0MHllblY3UScsXG4gICAgICAnMkxTdS9FWDZBcTI5eCtkditHUFVNZnVoVE5FM3ZpV1dVUjRQRDZUN1hmbWRWaVV3bVNmOGZrUk5Vbi90M2EybicsXG4gICAgICAnY3E0NlhyMzZzZUNvci9PTHAwYXRTWndIcmp4MlNVNXpQTGhlWm4rencvMGQxL1labkQ3QUVlUDlzL0N1eWN5dicsXG4gICAgICAnQ1o1SFpOS3VmdkI4ZnNoK2RmZFNYVzBHZnFrUGZ4azM2Vnc4dWZwamFvWkR5dDJueHhnLzZENEtTM1V2Wnp2MycsXG4gICAgICAnYXhkTFo5eWQwT0pOWnY0UDUwMUlmMjRXNHZUR3o2bkk3U2VyOFlkMlBpT3ZFNU1XTVQwd0xaUSt6UFgxc3YwLycsXG4gICAgICAnczhQdmt5V21WTTBPMGZCL1pTSG92SE5OUGZmRGcvcldoek9tWFE5Lzd2VG40NzdGK2FXbTVzWXpKNzUvQlFBPScsXG4gICAgICAnPStMMFMnLFxuICAgICAgJy0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0nXS5qb2luKCdcXG4nKTtcblxuICAgIHZhciBwbGFpbnRleHQgPSAnc2hvcnQgbWVzc2FnZVxcbm5leHQgbGluZVxcbu2VnOq1reyWtC/sobDshKDrp5AnO1xuICAgIHZhciBzTXNnID0gb3BlbnBncC5tZXNzYWdlLnJlYWRBcm1vcmVkKG1zZ19hcm1vcik7XG4gICAgdmFyIHB1YktleTIgPSBvcGVucGdwLmtleS5yZWFkQXJtb3JlZChwdWJfa2V5X2FybTIpO1xuICAgIHZhciBwdWJLZXkzID0gb3BlbnBncC5rZXkucmVhZEFybW9yZWQocHViX2tleV9hcm0zKTtcblxuICAgIHZhciBrZXlpZHMgPSBzTXNnLmdldFNpZ25pbmdLZXlJZHMoKTtcblxuICAgIHZhciB2ZXJpZmllZCA9IHB1YktleTIuZ2V0UHVibGljS2V5UGFja2V0KGtleWlkcykgIT09IG51bGwgJiYgcHViS2V5My5nZXRQdWJsaWNLZXlQYWNrZXQoa2V5aWRzKSAhPT0gbnVsbDtcblxuICAgIHZlcmlmaWVkID0gdmVyaWZpZWQgJiYgc01zZy5nZXRUZXh0KCkgPT0gcGxhaW50ZXh0O1xuXG4gICAgdmFyIHZlcmlmaWVkU2lnID0gc01zZy52ZXJpZnkoW3B1YktleTIsIHB1YktleTNdKTtcbiAgICBcbiAgICB2ZXJpZmllZCA9IHZlcmlmaWVkICYmIHZlcmlmaWVkU2lnWzBdLnN0YXR1cyAmJiB2ZXJpZmllZFNpZ1sxXS5zdGF0dXM7XG5cbiAgICByZXR1cm4gbmV3IHVuaXQucmVzdWx0KFwiVmVyaWZ5IHNpZ25lZCBtZXNzYWdlIHdpdGggdHdvIG9uZSBwYXNzIHNpZ25hdHVyZXNcIiwgdmVyaWZpZWQpO1xuICB9LCBmdW5jdGlvbigpIHtcblxuICAgIHZhciBtc2dfYXJtb3IgPSBcbiAgICAgWyctLS0tLUJFR0lOIFBHUCBTSUdORUQgTUVTU0FHRS0tLS0tJyxcbiAgICAgICdIYXNoOiBTSEEyNTYnLFxuICAgICAgJycsXG4gICAgICAnc2hvcnQgbWVzc2FnZScsXG4gICAgICAnbmV4dCBsaW5lJyxcbiAgICAgICftlZzqta3slrQv7KGw7ISg66eQJyxcbiAgICAgICctLS0tLUJFR0lOIFBHUCBTSUdOQVRVUkUtLS0tLScsXG4gICAgICAnVmVyc2lvbjogR251UEcgdjIuMC4xOSAoR05VL0xpbnV4KScsXG4gICAgICAnJyxcbiAgICAgICdpSndFQVFFSUFBWUZBbEtjanU4QUNna1E0SVQzUkd3Z0xKY2k2Z1AvZENtSXJhVWE2QUdwSnh6R2ZLK2pZcGpsJyxcbiAgICAgICdHMEt1bkZ5R215UHhlSlZuUGkyYkJwM0VQSWJpYXlRNzFDY0RlOURLcEYwNDZ0b3JhMDdBQTllbysvWWJ2SjlQJyxcbiAgICAgICdQV2VTY3czb2ovZWpzbUtRb0RCR3p5RE1GVXBoZXZuaGdjNWxFTmpvdkpxbWl1NkZLak5tQURUeGNaL3FGVE9xJyxcbiAgICAgICc0NEVXVGdkVzNJcVhGa05wS2plSkFSd0VBUUVJQUFZRkFsS2NqdThBQ2drUTIvSWo2SEJUVGZRaTZnZjlIeGhFJyxcbiAgICAgICd5Y0xEaFE4aXlDMDkwVGFZd3NEeXRTY1Uydk9NaUk1ckpDeTJ0ZkRWMHBmbitVZWtZR01uS3haVHB3dG1ubzFqJyxcbiAgICAgICdtVk9saWVFTnN6ejVJY2VoUzVUWXdrNGxtUkZqb2JhK1o4cXdQRVloWXhQMjlHTWJtUklzSDgxMXNRSEZUaWdvJyxcbiAgICAgICdMSTJ0NHBTU1NVcEFpWGQ5eTZLdHZrV2NHR244SWZrTkhDRUhQaDFvdjI4UXZIMCtCeUlpS1lLNU42WkI4aEVvJyxcbiAgICAgICcwdU1ZaEtRUFZKZFBDdk1rQXhRQ1JQdzg0RXZteHVKMEhNQ2VTQjl0SFFYcHo1dW4ybThEOXlpR3BCUVBucWxXJyxcbiAgICAgICd2Q0NxN2ZnYVV6OGtzeHZROWJTd3YwaUlJYmJCZFRQN1o4eTJjMU9vZjZORGw3aXJIK1FDZU5UN0lJR3M4U21uJyxcbiAgICAgICdCRXp2L0Zxa1FBaGp5M0tyeGc9PScsXG4gICAgICAnPTNQa2wnLFxuICAgICAgJy0tLS0tRU5EIFBHUCBTSUdOQVRVUkUtLS0tLSddLmpvaW4oJ1xcbicpO1xuXG4gICAgdmFyIHBsYWludGV4dCA9ICdzaG9ydCBtZXNzYWdlXFxubmV4dCBsaW5lXFxu7ZWc6rWt7Ja0L+yhsOyEoOunkCc7XG4gICAgdmFyIGNzTXNnID0gb3BlbnBncC5jbGVhcnRleHQucmVhZEFybW9yZWQobXNnX2FybW9yKTtcbiAgICB2YXIgcHViS2V5MiA9IG9wZW5wZ3Aua2V5LnJlYWRBcm1vcmVkKHB1Yl9rZXlfYXJtMik7XG4gICAgdmFyIHB1YktleTMgPSBvcGVucGdwLmtleS5yZWFkQXJtb3JlZChwdWJfa2V5X2FybTMpO1xuXG4gICAgdmFyIGtleWlkcyA9IGNzTXNnLmdldFNpZ25pbmdLZXlJZHMoKTtcblxuICAgIHZhciB2ZXJpZmllZCA9IHB1YktleTIuZ2V0UHVibGljS2V5UGFja2V0KGtleWlkcykgIT09IG51bGwgJiYgcHViS2V5My5nZXRQdWJsaWNLZXlQYWNrZXQoa2V5aWRzKSAhPT0gbnVsbDtcblxuICAgIHZhciBjbGVhcnRleHRTaWcgPSBvcGVucGdwLnZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZShbcHViS2V5MiwgcHViS2V5M10sIGNzTXNnKTtcblxuICAgIHZlcmlmaWVkID0gdmVyaWZpZWQgJiYgY2xlYXJ0ZXh0U2lnLnRleHQgPT0gcGxhaW50ZXh0O1xuXG4gICAgdmVyaWZpZWQgPSB2ZXJpZmllZCAmJiBjbGVhcnRleHRTaWcuc2lnbmF0dXJlc1swXS5zdGF0dXMgJiYgY2xlYXJ0ZXh0U2lnLnNpZ25hdHVyZXNbMV0uc3RhdHVzO1xuXG4gICAgcmV0dXJuIG5ldyB1bml0LnJlc3VsdChcIlZlcmlmeSBjbGVhcnRleHQgc2lnbmVkIG1lc3NhZ2Ugd2l0aCB0d28gc2lnbmF0dXJlcyB3aXRoIG9wZW5wZ3AudmVyaWZ5Q2xlYXJTaWduZWRNZXNzYWdlXCIsIHZlcmlmaWVkKTtcbiAgfSwgZnVuY3Rpb24oKSB7XG5cbiAgICB2YXIgcGxhaW50ZXh0ID0gJ3Nob3J0IG1lc3NhZ2VcXG5uZXh0IGxpbmVcXG7tlZzqta3slrQv7KGw7ISg66eQJztcbiAgICB2YXIgcHViS2V5ID0gb3BlbnBncC5rZXkucmVhZEFybW9yZWQocHViX2tleV9hcm0yKTtcbiAgICB2YXIgcHJpdktleSA9IG9wZW5wZ3Aua2V5LnJlYWRBcm1vcmVkKHByaXZfa2V5X2FybTIpO1xuICAgIHByaXZLZXkuZ2V0U2lnbmluZ0tleVBhY2tldCgpLmRlY3J5cHQoJ2hlbGxvIHdvcmxkJyk7XG5cbiAgICB2YXIgY2xlYXJTaWduZWRBcm1vciA9IG9wZW5wZ3Auc2lnbkNsZWFyTWVzc2FnZShbcHJpdktleV0sIHBsYWludGV4dCk7XG5cbiAgICB2YXIgY3NNc2cgPSBvcGVucGdwLmNsZWFydGV4dC5yZWFkQXJtb3JlZChjbGVhclNpZ25lZEFybW9yKTtcbiAgICBcbiAgICB2YXIgY2xlYXJ0ZXh0U2lnID0gb3BlbnBncC52ZXJpZnlDbGVhclNpZ25lZE1lc3NhZ2UoW3B1YktleV0sIGNzTXNnKTtcblxuICAgIHZhciB2ZXJpZmllZCA9IGNsZWFydGV4dFNpZy50ZXh0ID09IHBsYWludGV4dC5yZXBsYWNlKC9cXHIvZywnJyk7XG5cbiAgICB2ZXJpZmllZCA9IHZlcmlmaWVkICYmIGNsZWFydGV4dFNpZy5zaWduYXR1cmVzWzBdLnN0YXR1cztcblxuICAgIHJldHVybiBuZXcgdW5pdC5yZXN1bHQoXCJTaWduIHRleHQgd2l0aCBvcGVucGdwLnNpZ25DbGVhck1lc3NhZ2UgYW5kIHZlcmlmeSB3aXRoIG9wZW5wZ3AudmVyaWZ5Q2xlYXJTaWduZWRNZXNzYWdlIGxlYWRzIHRvIHNhbWUgY2xlYXJ0ZXh0IGFuZCB2YWxpZCBzaWduYXR1cmVzXCIsIHZlcmlmaWVkKTtcbiAgfSwgZnVuY3Rpb24oKSB7XG5cbiAgICB2YXIgbXNnX2FybW9yID0gXG4gICAgIFsnLS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLScsXG4gICAgICAnSGFzaDogU0hBMjU2JyxcbiAgICAgICcnLFxuICAgICAgJ8Okw7bDvCcsXG4gICAgICAnc29tZScsXG4gICAgICAnbW9yZScsXG4gICAgICAnLS0tLS1CRUdJTiBQR1AgU0lHTkFUVVJFLS0tLS0nLFxuICAgICAgJ1ZlcnNpb246IEdudVBHIHYyLjAuMTkgKEdOVS9MaW51eCknLFxuICAgICAgJycsXG4gICAgICAnaUp3RUFRRUlBQVlGQWxLa2JTOEFDZ2tRNElUM1JHd2dMSmYvNHdRQWlHOHM0Q3dMK1ljdlZhWS9VVkV1VkNOKycsXG4gICAgICAnN1oveTlrTklVM011UFF5LzdraUFWL2YzbUU0ODgzNjNMZWxyTHVwcFpScEFtYllGbUZDa2xLL3hnWEYxTWZSUScsXG4gICAgICAnSjdaR1cwUHJ4UVBpOEtSOGtTUHphVWprelVrODZzQVJCMExlSXhjRys1VC9xaDdmRFhDUlJ5WFBvbTVFYnFzZicsXG4gICAgICAnWENFZnZ2ZEo2MHppdG5sRmlJWT0nLFxuICAgICAgJz1kbS9OJyxcbiAgICAgICctLS0tLUVORCBQR1AgU0lHTkFUVVJFLS0tLS0nXS5qb2luKCdcXG4nKTtcblxuICAgIHZhciBwbGFpbnRleHQgPSAnw6TDtsO8XFxuc29tZVxcbm1vcmUnO1xuICAgIHZhciBjc01zZyA9IG9wZW5wZ3AuY2xlYXJ0ZXh0LnJlYWRBcm1vcmVkKG1zZ19hcm1vcik7XG4gICAgdmFyIHB1YktleTIgPSBvcGVucGdwLmtleS5yZWFkQXJtb3JlZChwdWJfa2V5X2FybTIpO1xuXG4gICAgdmFyIGtleWlkcyA9IGNzTXNnLmdldFNpZ25pbmdLZXlJZHMoKTtcblxuICAgIHZhciBjbGVhcnRleHRTaWcgPSBvcGVucGdwLnZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZShbcHViS2V5Ml0sIGNzTXNnKTtcblxuICAgIHZhciB2ZXJpZmllZCA9IGNsZWFydGV4dFNpZy50ZXh0ID09IHBsYWludGV4dDtcblxuICAgIHZlcmlmaWVkID0gdmVyaWZpZWQgJiYgY2xlYXJ0ZXh0U2lnLnNpZ25hdHVyZXNbMF0uc3RhdHVzO1xuXG4gICAgcmV0dXJuIG5ldyB1bml0LnJlc3VsdChcIlZlcmlmeSBjbGVhcnRleHQgc2lnbmVkIG1lc3NhZ2Ugd2l0aCBDUC0xMjUyIGNoYXJhY3RlciBlbmNvZGluZ1wiLCB2ZXJpZmllZCk7XG4gIH1dO1xuXG4gIHZhciByZXN1bHRzID0gW107XG5cbiAgZm9yKHZhciBpIGluIHRlc3RzKSB7XG4gICAgcmVzdWx0cy5wdXNoKHRlc3RzW2ldKCkpO1xuICB9ICBcbiAgXG4gIHJldHVybiByZXN1bHRzO1xuXG59KTsiLCJtb2R1bGUuZXhwb3J0cz1yZXF1aXJlKCdRalBaMXEnKTsiLCJ2YXIgcHJvY2Vzcz1yZXF1aXJlKFwiX19icm93c2VyaWZ5X3Byb2Nlc3NcIik7XG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0dGVzdHM6IFtdLFxuXHRyZWdpc3RlcjogZnVuY3Rpb24oc3RyX3RpdGxlLCBmdW5jX3J1bnRlc3QpIHtcblx0XHR0aGlzLnRlc3RzLnB1c2goeyB0aXRsZTogc3RyX3RpdGxlLCBydW46IGZ1bmNfcnVudGVzdCB9KTtcblx0fSxcblx0XG5cdHJ1bjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIHRlc3QgPSB0aGlzLnRlc3RzLnNoaWZ0KCk7XG5cblx0XHR2YXIgcmVzdWx0ID0ge1xuXHRcdFx0dGl0bGU6IHRlc3QudGl0bGVcblx0XHR9O1xuXG5cblx0XHRyZXN1bHQudGVzdHMgPSB0ZXN0LnJ1bigpO1xuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fSxcblxuXHRydW5fYWxsOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgcGFzc2VkID0gdHJ1ZTtcblxuXHRcdHdoaWxlKHRoaXMudGVzdHMubGVuZ3RoID4gMCkge1xuXHRcdFx0dmFyIHJlc3VsdCA9IHRoaXMucnVuKCk7XG5cblx0XHRcdGNvbnNvbGUubG9nKCdUZXN0OiAnICsgcmVzdWx0LnRpdGxlKTtcblxuXHRcdFx0Zm9yKHZhciBpIGluIHJlc3VsdC50ZXN0cykge1xuXG5cdFx0XHRcdHZhciByZXMgPSByZXN1bHQudGVzdHNbaV0ucmVzdWx0ID9cblx0XHRcdFx0XHQnU1VDQ0VTUycgOiAnRkFJTEVEJztcblxuXHRcdFx0XHRjb25zb2xlLmxvZyhyZXN1bHQudGVzdHNbaV0uZGVzY3JpcHRpb24gKyAnICcgKyByZXMpO1xuXG5cdFx0XHRcdHBhc3NlZCA9IHBhc3NlZCAmJiByZXN1bHQudGVzdHNbaV0ucmVzdWx0O1xuXHRcdFx0fVx0XHRcdFx0XG5cdFx0fVxuXG5cdFx0aWYoIXBhc3NlZCkgcHJvY2Vzcy5leGl0KDEpO1xuXHR9LFxuXHRcdFxuXHRyZXN1bHQ6IGZ1bmN0aW9uKHN0cl9kZXNjcmlwdGlvbiwgYm9vbGVhbl9yZXN1bHQpIHtcblx0XHR0aGlzLmRlc2NyaXB0aW9uID0gc3RyX2Rlc2NyaXB0aW9uO1xuXHRcdHRoaXMucmVzdWx0ID0gYm9vbGVhbl9yZXN1bHQ7XG5cdH1cbn1cblxuIl19 -; \ No newline at end of file