30857 lines
2.6 MiB
30857 lines
2.6 MiB
(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){
|
||
var createIwcConnector;
|
||
|
||
createIwcConnector = function(callback, options) {
|
||
var IwcConnector, duiClient, init, iwcHandler, received_HB, userIwcHandler;
|
||
userIwcHandler = null;
|
||
if (options != null) {
|
||
userIwcHandler = options.iwcHandler;
|
||
}
|
||
iwcHandler = {};
|
||
duiClient = new DUIClient();
|
||
duiClient.connect(function(intent) {
|
||
var _ref;
|
||
if ((_ref = iwcHandler[intent.action]) != null) {
|
||
_ref.map(function(f) {
|
||
return setTimeout(function() {
|
||
return f(intent);
|
||
}, 0);
|
||
});
|
||
}
|
||
if (userIwcHandler != null) {
|
||
return userIwcHandler(intent);
|
||
}
|
||
});
|
||
duiClient.initOK();
|
||
received_HB = null;
|
||
IwcConnector = (function() {
|
||
function IwcConnector(engine, HB, execution_listener, yatta) {
|
||
var receiveHB, receive_, sendHistoryBuffer, send_;
|
||
this.engine = engine;
|
||
this.HB = HB;
|
||
this.execution_listener = execution_listener;
|
||
this.yatta = yatta;
|
||
this.duiClient = duiClient;
|
||
this.iwcHandler = iwcHandler;
|
||
send_ = (function(_this) {
|
||
return function(o) {
|
||
if (Object.getOwnPropertyNames(_this.initialized).length !== 0) {
|
||
return _this.send(o);
|
||
}
|
||
};
|
||
})(this);
|
||
this.execution_listener.push(send_);
|
||
this.initialized = {};
|
||
receiveHB = (function(_this) {
|
||
return function(json) {
|
||
var him;
|
||
HB = json.extras.HB;
|
||
him = json.extras.user;
|
||
_this.engine.applyOpsCheckDouble(HB);
|
||
return _this.initialized[him] = true;
|
||
};
|
||
})(this);
|
||
iwcHandler["Yatta_push_HB_element"] = [receiveHB];
|
||
this.sendIwcIntent("Yatta_get_HB_element", this.HB.getOperationCounter());
|
||
receive_ = (function(_this) {
|
||
return function(intent) {
|
||
var o;
|
||
o = intent.extras;
|
||
if (_this.initialized[o.uid.creator] != null) {
|
||
return _this.receive(o);
|
||
}
|
||
};
|
||
})(this);
|
||
this.iwcHandler["Yatta_new_operation"] = [receive_];
|
||
if (received_HB != null) {
|
||
this.engine.applyOpsCheckDouble(received_HB);
|
||
}
|
||
sendHistoryBuffer = (function(_this) {
|
||
return function(intent) {
|
||
var json, state_vector;
|
||
state_vector = intent.extras;
|
||
console.log(state_vector);
|
||
json = {
|
||
HB: _this.yatta.getHistoryBuffer()._encode(state_vector),
|
||
user: _this.yatta.getUserId()
|
||
};
|
||
return _this.sendIwcIntent("Yatta_push_HB_element", json);
|
||
};
|
||
})(this);
|
||
this.iwcHandler["Yatta_get_HB_element"] = [sendHistoryBuffer];
|
||
}
|
||
|
||
IwcConnector.prototype.setIwcHandler = function(f) {
|
||
return userIwcHandler = f;
|
||
};
|
||
|
||
IwcConnector.prototype.sendIwcIntent = function(action_name, content) {
|
||
var intent;
|
||
intent = null;
|
||
if (arguments.length >= 2) {
|
||
action_name = arguments[0], content = arguments[1];
|
||
intent = {
|
||
action: action_name,
|
||
component: "",
|
||
data: "",
|
||
dataType: "",
|
||
flags: ["PUBLISH_GLOBAL"],
|
||
extras: content
|
||
};
|
||
} else {
|
||
intent = arguments[0];
|
||
}
|
||
return this.duiClient.sendIntent(intent);
|
||
};
|
||
|
||
IwcConnector.prototype.send = function(o) {
|
||
if (o.uid.creator === this.HB.getUserId() && (typeof o.uid.op_number !== "string")) {
|
||
return this.sendIwcIntent("Yatta_new_operation", o);
|
||
}
|
||
};
|
||
|
||
IwcConnector.prototype.receive = function(o) {
|
||
if (o.uid.creator !== this.HB.getUserId()) {
|
||
return this.engine.applyOp(o);
|
||
}
|
||
};
|
||
|
||
return IwcConnector;
|
||
|
||
})();
|
||
init = function() {
|
||
var proposed_user_id;
|
||
proposed_user_id = Math.floor(Math.random() * 1000000);
|
||
return callback(IwcConnector, proposed_user_id);
|
||
};
|
||
setTimeout(init, 5000);
|
||
return void 0;
|
||
};
|
||
|
||
module.exports = createIwcConnector;
|
||
|
||
if (typeof window !== "undefined" && window !== null) {
|
||
if (window.Y == null) {
|
||
window.Y = {};
|
||
}
|
||
window.Y.createIwcConnector = createIwcConnector;
|
||
}
|
||
|
||
|
||
},{}],2:[function(require,module,exports){
|
||
var _;
|
||
|
||
_ = require("underscore");
|
||
|
||
module.exports = function(user_list) {
|
||
var TestConnector;
|
||
return TestConnector = (function() {
|
||
function TestConnector(engine, HB, execution_listener) {
|
||
var appliedOperationsListener, send_;
|
||
this.engine = engine;
|
||
this.HB = HB;
|
||
this.execution_listener = execution_listener;
|
||
send_ = (function(_this) {
|
||
return function(o) {
|
||
return _this.send(o);
|
||
};
|
||
})(this);
|
||
this.execution_listener.push(send_);
|
||
this.applied_operations = [];
|
||
appliedOperationsListener = (function(_this) {
|
||
return function(o) {
|
||
return _this.applied_operations.push(o);
|
||
};
|
||
})(this);
|
||
this.execution_listener.push(appliedOperationsListener);
|
||
if (!((user_list != null ? user_list.length : void 0) === 0)) {
|
||
this.engine.applyOps(user_list[0].getHistoryBuffer()._encode());
|
||
}
|
||
this.HB.setManualGarbageCollect();
|
||
this.unexecuted = {};
|
||
}
|
||
|
||
TestConnector.prototype.getOpsInExecutionOrder = function() {
|
||
return this.applied_operations;
|
||
};
|
||
|
||
TestConnector.prototype.send = function(o) {
|
||
var user, _i, _len, _results;
|
||
if ((o.uid.creator === this.HB.getUserId()) && (typeof o.uid.op_number !== "string")) {
|
||
_results = [];
|
||
for (_i = 0, _len = user_list.length; _i < _len; _i++) {
|
||
user = user_list[_i];
|
||
if (user.getUserId() !== this.HB.getUserId()) {
|
||
_results.push(user.getConnector().receive(o));
|
||
} else {
|
||
_results.push(void 0);
|
||
}
|
||
}
|
||
return _results;
|
||
}
|
||
};
|
||
|
||
TestConnector.prototype.receive = function(o) {
|
||
var _base, _name;
|
||
if ((_base = this.unexecuted)[_name = o.uid.creator] == null) {
|
||
_base[_name] = [];
|
||
}
|
||
return this.unexecuted[o.uid.creator].push(o);
|
||
};
|
||
|
||
TestConnector.prototype.flushOne = function(user) {
|
||
var _ref;
|
||
if (((_ref = this.unexecuted[user]) != null ? _ref.length : void 0) > 0) {
|
||
return this.engine.applyOp(this.unexecuted[user].shift());
|
||
}
|
||
};
|
||
|
||
TestConnector.prototype.flushOneRandom = function() {
|
||
return this.flushOne(_.random(0, user_list.length - 1));
|
||
};
|
||
|
||
TestConnector.prototype.flushAll = function() {
|
||
var n, ops, _ref;
|
||
_ref = this.unexecuted;
|
||
for (n in _ref) {
|
||
ops = _ref[n];
|
||
this.engine.applyOps(ops);
|
||
}
|
||
return this.unexecuted = {};
|
||
};
|
||
|
||
return TestConnector;
|
||
|
||
})();
|
||
};
|
||
|
||
|
||
},{"underscore":84}],3:[function(require,module,exports){
|
||
var Engine;
|
||
|
||
Engine = (function() {
|
||
function Engine(HB, parser) {
|
||
this.HB = HB;
|
||
this.parser = parser;
|
||
this.unprocessed_ops = [];
|
||
}
|
||
|
||
Engine.prototype.parseOperation = function(json) {
|
||
var typeParser;
|
||
typeParser = this.parser[json.type];
|
||
if (typeParser != null) {
|
||
return typeParser(json);
|
||
} else {
|
||
throw new Error("You forgot to specify a parser for type " + json.type + ". The message is " + (JSON.stringify(json)) + ".");
|
||
}
|
||
};
|
||
|
||
Engine.prototype.applyOpsBundle = function(ops_json) {
|
||
var o, ops, _i, _j, _k, _len, _len1, _len2;
|
||
ops = [];
|
||
for (_i = 0, _len = ops_json.length; _i < _len; _i++) {
|
||
o = ops_json[_i];
|
||
ops.push(this.parseOperation(o));
|
||
}
|
||
for (_j = 0, _len1 = ops.length; _j < _len1; _j++) {
|
||
o = ops[_j];
|
||
this.HB.addOperation(o);
|
||
}
|
||
for (_k = 0, _len2 = ops.length; _k < _len2; _k++) {
|
||
o = ops[_k];
|
||
if (!o.execute()) {
|
||
this.unprocessed_ops.push(o);
|
||
}
|
||
}
|
||
return this.tryUnprocessed();
|
||
};
|
||
|
||
Engine.prototype.applyOpsCheckDouble = function(ops_json) {
|
||
var o, _i, _len, _results;
|
||
_results = [];
|
||
for (_i = 0, _len = ops_json.length; _i < _len; _i++) {
|
||
o = ops_json[_i];
|
||
if (this.HB.getOperation(o.uid) == null) {
|
||
_results.push(this.applyOp(o));
|
||
} else {
|
||
_results.push(void 0);
|
||
}
|
||
}
|
||
return _results;
|
||
};
|
||
|
||
Engine.prototype.applyOps = function(ops_json) {
|
||
var o, _i, _len, _results;
|
||
_results = [];
|
||
for (_i = 0, _len = ops_json.length; _i < _len; _i++) {
|
||
o = ops_json[_i];
|
||
_results.push(this.applyOp(o));
|
||
}
|
||
return _results;
|
||
};
|
||
|
||
Engine.prototype.applyOp = function(op_json) {
|
||
var o;
|
||
o = this.parseOperation(op_json);
|
||
this.HB.addToCounter(o);
|
||
if (this.HB.getOperation(o) != null) {
|
||
|
||
} else if (!o.execute()) {
|
||
this.unprocessed_ops.push(o);
|
||
} else {
|
||
this.HB.addOperation(o);
|
||
}
|
||
return this.tryUnprocessed();
|
||
};
|
||
|
||
Engine.prototype.tryUnprocessed = function() {
|
||
var old_length, op, unprocessed, _i, _len, _ref, _results;
|
||
_results = [];
|
||
while (true) {
|
||
old_length = this.unprocessed_ops.length;
|
||
unprocessed = [];
|
||
_ref = this.unprocessed_ops;
|
||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||
op = _ref[_i];
|
||
if (this.HB.getOperation(op) != null) {
|
||
|
||
} else if (!op.execute()) {
|
||
unprocessed.push(op);
|
||
} else {
|
||
this.HB.addOperation(op);
|
||
}
|
||
}
|
||
this.unprocessed_ops = unprocessed;
|
||
if (this.unprocessed_ops.length === old_length) {
|
||
break;
|
||
} else {
|
||
_results.push(void 0);
|
||
}
|
||
}
|
||
return _results;
|
||
};
|
||
|
||
return Engine;
|
||
|
||
})();
|
||
|
||
module.exports = Engine;
|
||
|
||
|
||
},{}],4:[function(require,module,exports){
|
||
var Engine, HistoryBuffer, JsonFramework, json_types_uninitialized;
|
||
|
||
json_types_uninitialized = require("../Types/JsonTypes");
|
||
|
||
HistoryBuffer = require("../HistoryBuffer");
|
||
|
||
Engine = require("../Engine");
|
||
|
||
JsonFramework = (function() {
|
||
function JsonFramework(user_id, Connector) {
|
||
var beg, end, first_word, type_manager, uid_beg, uid_end;
|
||
this.HB = new HistoryBuffer(user_id);
|
||
type_manager = json_types_uninitialized(this.HB);
|
||
this.types = type_manager.types;
|
||
this.engine = new Engine(this.HB, type_manager.parser);
|
||
this.HB.engine = this.engine;
|
||
this.connector = new Connector(this.engine, this.HB, type_manager.execution_listener, this);
|
||
first_word = new this.types.JsonType(this.HB.getReservedUniqueIdentifier());
|
||
this.HB.addOperation(first_word).execute();
|
||
uid_beg = this.HB.getReservedUniqueIdentifier();
|
||
uid_end = this.HB.getReservedUniqueIdentifier();
|
||
beg = this.HB.addOperation(new this.types.Delimiter(uid_beg, void 0, uid_end)).execute();
|
||
end = this.HB.addOperation(new this.types.Delimiter(uid_end, beg, void 0)).execute();
|
||
this.root_element = new this.types.ReplaceManager(void 0, this.HB.getReservedUniqueIdentifier(), beg, end);
|
||
this.HB.addOperation(this.root_element).execute();
|
||
this.root_element.replace(first_word, this.HB.getReservedUniqueIdentifier());
|
||
}
|
||
|
||
JsonFramework.prototype.getSharedObject = function() {
|
||
return this.root_element.val();
|
||
};
|
||
|
||
JsonFramework.prototype.getConnector = function() {
|
||
return this.connector;
|
||
};
|
||
|
||
JsonFramework.prototype.getHistoryBuffer = function() {
|
||
return this.HB;
|
||
};
|
||
|
||
JsonFramework.prototype.setMutableDefault = function(mutable) {
|
||
return this.getSharedObject().setMutableDefault(mutable);
|
||
};
|
||
|
||
JsonFramework.prototype.getUserId = function() {
|
||
return this.HB.getUserId();
|
||
};
|
||
|
||
JsonFramework.prototype.toJson = function() {
|
||
return this.getSharedObject().toJson();
|
||
};
|
||
|
||
JsonFramework.prototype.val = function(name, content, mutable) {
|
||
return this.getSharedObject().val(name, content, mutable);
|
||
};
|
||
|
||
JsonFramework.prototype.on = function() {
|
||
var _ref;
|
||
return (_ref = this.getSharedObject()).on.apply(_ref, arguments);
|
||
};
|
||
|
||
JsonFramework.prototype.deleteListener = function() {
|
||
var _ref;
|
||
return (_ref = this.getSharedObject()).deleteListener.apply(_ref, arguments);
|
||
};
|
||
|
||
Object.defineProperty(JsonFramework.prototype, 'value', {
|
||
get: function() {
|
||
return this.getSharedObject().value;
|
||
},
|
||
set: function(o) {
|
||
var o_name, o_obj, _results;
|
||
if (o.constructor === {}.constructor) {
|
||
_results = [];
|
||
for (o_name in o) {
|
||
o_obj = o[o_name];
|
||
_results.push(this.val(o_name, o_obj, 'immutable'));
|
||
}
|
||
return _results;
|
||
} else {
|
||
throw new Error("You must only set Object values!");
|
||
}
|
||
}
|
||
});
|
||
|
||
return JsonFramework;
|
||
|
||
})();
|
||
|
||
module.exports = JsonFramework;
|
||
|
||
if (typeof window !== "undefined" && window !== null) {
|
||
if (window.Y == null) {
|
||
window.Y = {};
|
||
}
|
||
window.Y.JsonFramework = JsonFramework;
|
||
}
|
||
|
||
|
||
},{"../Engine":3,"../HistoryBuffer":7,"../Types/JsonTypes":9}],5:[function(require,module,exports){
|
||
var Engine, HistoryBuffer, TextFramework, text_types_uninitialized;
|
||
|
||
text_types_uninitialized = require("../Types/TextTypes");
|
||
|
||
HistoryBuffer = require("../HistoryBuffer");
|
||
|
||
Engine = require("../Engine");
|
||
|
||
TextFramework = (function() {
|
||
function TextFramework(user_id, Connector) {
|
||
var beg, beginning, end, first_word, text_types, uid_beg, uid_end, uid_r;
|
||
this.HB = new HistoryBuffer(user_id);
|
||
text_types = text_types_uninitialized(this.HB);
|
||
this.types = text_types.types;
|
||
this.engine = new Engine(this.HB, text_types.parser);
|
||
this.connector = new Connector(this.engine, this.HB, text_types.execution_listener, this);
|
||
beginning = this.HB.addOperation(new this.types.Delimiter({
|
||
creator: '_',
|
||
op_number: '_beginning'
|
||
}, void 0, void 0));
|
||
end = this.HB.addOperation(new this.types.Delimiter({
|
||
creator: '_',
|
||
op_number: '_end'
|
||
}, beginning, void 0));
|
||
beginning.next_cl = end;
|
||
beginning.execute();
|
||
end.execute();
|
||
first_word = new this.types.WordType({
|
||
creator: '_',
|
||
op_number: '_'
|
||
}, beginning, end);
|
||
this.HB.addOperation(first_word).execute();
|
||
uid_r = {
|
||
creator: '_',
|
||
op_number: "RM"
|
||
};
|
||
uid_beg = {
|
||
creator: '_',
|
||
op_number: "_RM_beginning"
|
||
};
|
||
uid_end = {
|
||
creator: '_',
|
||
op_number: "_RM_end"
|
||
};
|
||
beg = this.HB.addOperation(new this.types.Delimiter(uid_beg, void 0, uid_end)).execute();
|
||
end = this.HB.addOperation(new this.types.Delimiter(uid_end, beg, void 0)).execute();
|
||
this.root_element = this.HB.addOperation(new this.types.ReplaceManager(void 0, uid_r, beg, end)).execute();
|
||
this.root_element.replace(first_word, {
|
||
creator: '_',
|
||
op_number: 'Replaceable'
|
||
});
|
||
}
|
||
|
||
TextFramework.prototype.getSharedObject = function() {
|
||
return this.root_element.val();
|
||
};
|
||
|
||
TextFramework.prototype.getConnector = function() {
|
||
return this.connector;
|
||
};
|
||
|
||
TextFramework.prototype.getHistoryBuffer = function() {
|
||
return this.HB;
|
||
};
|
||
|
||
TextFramework.prototype.getUserId = function() {
|
||
return this.HB.getUserId();
|
||
};
|
||
|
||
TextFramework.prototype.val = function() {
|
||
return this.getSharedObject().val();
|
||
};
|
||
|
||
TextFramework.prototype.insertText = function(pos, content) {
|
||
return this.getSharedObject().insertText(pos, content);
|
||
};
|
||
|
||
TextFramework.prototype.deleteText = function(pos, length) {
|
||
return this.getSharedObject().deleteText(pos, length);
|
||
};
|
||
|
||
TextFramework.prototype.bind = function(textarea) {
|
||
return this.getSharedObject().bind(textarea);
|
||
};
|
||
|
||
TextFramework.prototype.replaceText = function(text) {
|
||
return this.getSharedObject().replaceText(text);
|
||
};
|
||
|
||
TextFramework.prototype.on = function() {
|
||
var _ref;
|
||
return (_ref = this.root_element).on.apply(_ref, arguments);
|
||
};
|
||
|
||
return TextFramework;
|
||
|
||
})();
|
||
|
||
module.exports = TextFramework;
|
||
|
||
if (typeof window !== "undefined" && window !== null) {
|
||
if (window.Y == null) {
|
||
window.Y = {};
|
||
}
|
||
window.Y.TextFramework = TextFramework;
|
||
}
|
||
|
||
|
||
},{"../Engine":3,"../HistoryBuffer":7,"../Types/TextTypes":11}],6:[function(require,module,exports){
|
||
var Engine, HistoryBuffer, XmlFramework, json_types_uninitialized;
|
||
|
||
json_types_uninitialized = require("../Types/XmlTypes");
|
||
|
||
HistoryBuffer = require("../HistoryBuffer");
|
||
|
||
Engine = require("../Engine");
|
||
|
||
XmlFramework = (function() {
|
||
function XmlFramework(user_id, Connector) {
|
||
var beg, end, type_manager, uid_beg, uid_end;
|
||
this.HB = new HistoryBuffer(user_id);
|
||
type_manager = json_types_uninitialized(this.HB);
|
||
this.types = type_manager.types;
|
||
this.engine = new Engine(this.HB, type_manager.parser);
|
||
this.HB.engine = this.engine;
|
||
this.connector = new Connector(this.engine, this.HB, type_manager.execution_listener, this);
|
||
uid_beg = this.HB.getReservedUniqueIdentifier();
|
||
uid_end = this.HB.getReservedUniqueIdentifier();
|
||
beg = this.HB.addOperation(new this.types.Delimiter(uid_beg, void 0, uid_end)).execute();
|
||
end = this.HB.addOperation(new this.types.Delimiter(uid_end, beg, void 0)).execute();
|
||
this.root_element = new this.types.ReplaceManager(void 0, this.HB.getReservedUniqueIdentifier(), beg, end);
|
||
this.HB.addOperation(this.root_element).execute();
|
||
}
|
||
|
||
XmlFramework.prototype.getSharedObject = function() {
|
||
return this.root_element.val();
|
||
};
|
||
|
||
XmlFramework.prototype.getConnector = function() {
|
||
return this.connector;
|
||
};
|
||
|
||
XmlFramework.prototype.getHistoryBuffer = function() {
|
||
return this.HB;
|
||
};
|
||
|
||
XmlFramework.prototype.setMutableDefault = function(mutable) {
|
||
return this.getSharedObject().setMutableDefault(mutable);
|
||
};
|
||
|
||
XmlFramework.prototype.getUserId = function() {
|
||
return this.HB.getUserId();
|
||
};
|
||
|
||
XmlFramework.prototype.toJson = function() {
|
||
return this.getSharedObject().toJson();
|
||
};
|
||
|
||
XmlFramework.prototype.val = function() {
|
||
var newXml;
|
||
if ((arguments.length === 0) || (typeof arguments[0] === "boolean")) {
|
||
return this.getSharedObject().val(arguments[0]);
|
||
} else if (arguments.length === 1) {
|
||
newXml = new this.types.XmlType(void 0, void 0, void 0, void 0, arguments[0]);
|
||
this.HB.addOperation(newXml).execute();
|
||
this.root_element.replace(newXml);
|
||
return newXml;
|
||
} else {
|
||
throw new Error("can only parse 0, or 1 parameter!");
|
||
}
|
||
};
|
||
|
||
XmlFramework.prototype.on = function() {
|
||
var _ref;
|
||
return (_ref = this.getSharedObject()).on.apply(_ref, arguments);
|
||
};
|
||
|
||
return XmlFramework;
|
||
|
||
})();
|
||
|
||
module.exports = XmlFramework;
|
||
|
||
if (typeof window !== "undefined" && window !== null) {
|
||
if (window.Y == null) {
|
||
window.Y = {};
|
||
}
|
||
window.Y.XmlFramework = XmlFramework;
|
||
}
|
||
|
||
|
||
},{"../Engine":3,"../HistoryBuffer":7,"../Types/XmlTypes":12}],7:[function(require,module,exports){
|
||
var HistoryBuffer,
|
||
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
||
|
||
HistoryBuffer = (function() {
|
||
function HistoryBuffer(user_id) {
|
||
this.user_id = user_id;
|
||
this.emptyGarbage = __bind(this.emptyGarbage, this);
|
||
this.operation_counter = {};
|
||
this.buffer = {};
|
||
this.change_listeners = [];
|
||
this.garbage = [];
|
||
this.trash = [];
|
||
this.performGarbageCollection = true;
|
||
this.garbageCollectTimeout = 1000;
|
||
this.reserved_identifier_counter = 0;
|
||
setTimeout(this.emptyGarbage, this.garbageCollectTimeout);
|
||
}
|
||
|
||
HistoryBuffer.prototype.emptyGarbage = function() {
|
||
var o, _i, _len, _ref;
|
||
_ref = this.garbage;
|
||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||
o = _ref[_i];
|
||
if (typeof o.cleanup === "function") {
|
||
o.cleanup();
|
||
}
|
||
}
|
||
this.garbage = this.trash;
|
||
this.trash = [];
|
||
if (this.garbageCollectTimeout !== -1) {
|
||
this.garbageCollectTimeoutId = setTimeout(this.emptyGarbage, this.garbageCollectTimeout);
|
||
}
|
||
return void 0;
|
||
};
|
||
|
||
HistoryBuffer.prototype.getUserId = function() {
|
||
return this.user_id;
|
||
};
|
||
|
||
HistoryBuffer.prototype.addToGarbageCollector = function() {
|
||
var o, _i, _len, _results;
|
||
if (this.performGarbageCollection) {
|
||
_results = [];
|
||
for (_i = 0, _len = arguments.length; _i < _len; _i++) {
|
||
o = arguments[_i];
|
||
if (o != null) {
|
||
_results.push(this.garbage.push(o));
|
||
} else {
|
||
_results.push(void 0);
|
||
}
|
||
}
|
||
return _results;
|
||
}
|
||
};
|
||
|
||
HistoryBuffer.prototype.stopGarbageCollection = function() {
|
||
this.performGarbageCollection = false;
|
||
this.setManualGarbageCollect();
|
||
this.garbage = [];
|
||
return this.trash = [];
|
||
};
|
||
|
||
HistoryBuffer.prototype.setManualGarbageCollect = function() {
|
||
this.garbageCollectTimeout = -1;
|
||
clearTimeout(this.garbageCollectTimeoutId);
|
||
return this.garbageCollectTimeoutId = void 0;
|
||
};
|
||
|
||
HistoryBuffer.prototype.setGarbageCollectTimeout = function(garbageCollectTimeout) {
|
||
this.garbageCollectTimeout = garbageCollectTimeout;
|
||
};
|
||
|
||
HistoryBuffer.prototype.getReservedUniqueIdentifier = function() {
|
||
return {
|
||
creator: '_',
|
||
op_number: "_" + (this.reserved_identifier_counter++),
|
||
doSync: false
|
||
};
|
||
};
|
||
|
||
HistoryBuffer.prototype.getOperationCounter = function(user_id) {
|
||
var ctn, res, user, _ref;
|
||
if (user_id == null) {
|
||
res = {};
|
||
_ref = this.operation_counter;
|
||
for (user in _ref) {
|
||
ctn = _ref[user];
|
||
res[user] = ctn;
|
||
}
|
||
return res;
|
||
} else {
|
||
return this.operation_counter[user_id];
|
||
}
|
||
};
|
||
|
||
HistoryBuffer.prototype._encode = function(state_vector) {
|
||
var json, o, o_json, o_next, o_number, o_prev, u_name, unknown, user, _ref;
|
||
if (state_vector == null) {
|
||
state_vector = {};
|
||
}
|
||
json = [];
|
||
unknown = function(user, o_number) {
|
||
if ((user == null) || (o_number == null)) {
|
||
throw new Error("dah!");
|
||
}
|
||
return (state_vector[user] == null) || state_vector[user] <= o_number;
|
||
};
|
||
_ref = this.buffer;
|
||
for (u_name in _ref) {
|
||
user = _ref[u_name];
|
||
for (o_number in user) {
|
||
o = user[o_number];
|
||
if (o.doSync && unknown(u_name, o_number)) {
|
||
o_json = o._encode();
|
||
if (o.next_cl != null) {
|
||
o_next = o.next_cl;
|
||
while ((o_next.next_cl != null) && unknown(o_next.creator, o_next.op_number)) {
|
||
o_next = o_next.next_cl;
|
||
}
|
||
o_json.next = o_next.getUid();
|
||
} else if (o.prev_cl != null) {
|
||
o_prev = o.prev_cl;
|
||
while ((o_prev.prev_cl != null) && unknown(o_prev.creator, o_prev.op_number)) {
|
||
o_prev = o_prev.prev_cl;
|
||
}
|
||
o_json.prev = o_prev.getUid();
|
||
}
|
||
json.push(o_json);
|
||
}
|
||
}
|
||
}
|
||
return json;
|
||
};
|
||
|
||
HistoryBuffer.prototype.getNextOperationIdentifier = function(user_id) {
|
||
var uid;
|
||
if (user_id == null) {
|
||
user_id = this.user_id;
|
||
}
|
||
if (this.operation_counter[user_id] == null) {
|
||
this.operation_counter[user_id] = 0;
|
||
}
|
||
uid = {
|
||
'creator': user_id,
|
||
'op_number': this.operation_counter[user_id]
|
||
};
|
||
this.operation_counter[user_id]++;
|
||
return uid;
|
||
};
|
||
|
||
HistoryBuffer.prototype.getOperation = function(uid) {
|
||
var _ref;
|
||
if (uid instanceof Object) {
|
||
return (_ref = this.buffer[uid.creator]) != null ? _ref[uid.op_number] : void 0;
|
||
} else if (uid == null) {
|
||
|
||
} else {
|
||
throw new Error("This type of uid is not defined!");
|
||
}
|
||
};
|
||
|
||
HistoryBuffer.prototype.addOperation = function(o) {
|
||
if (this.buffer[o.creator] == null) {
|
||
this.buffer[o.creator] = {};
|
||
}
|
||
if (this.buffer[o.creator][o.op_number] != null) {
|
||
throw new Error("You must not overwrite operations!");
|
||
}
|
||
this.buffer[o.creator][o.op_number] = o;
|
||
return o;
|
||
};
|
||
|
||
HistoryBuffer.prototype.removeOperation = function(o) {
|
||
var _ref;
|
||
return (_ref = this.buffer[o.creator]) != null ? delete _ref[o.op_number] : void 0;
|
||
};
|
||
|
||
HistoryBuffer.prototype.addToCounter = function(o) {
|
||
var _results;
|
||
if (this.operation_counter[o.creator] == null) {
|
||
this.operation_counter[o.creator] = 0;
|
||
}
|
||
if (typeof o.op_number === 'number' && o.creator !== this.getUserId()) {
|
||
if (o.op_number === this.operation_counter[o.creator]) {
|
||
this.operation_counter[o.creator]++;
|
||
_results = [];
|
||
while (this.getOperation({
|
||
creator: o.creator,
|
||
op_number: this.operation_counter[o.creator]
|
||
}) != null) {
|
||
_results.push(this.operation_counter[o.creator]++);
|
||
}
|
||
return _results;
|
||
}
|
||
}
|
||
};
|
||
|
||
return HistoryBuffer;
|
||
|
||
})();
|
||
|
||
module.exports = HistoryBuffer;
|
||
|
||
|
||
},{}],8:[function(require,module,exports){
|
||
var __slice = [].slice,
|
||
__hasProp = {}.hasOwnProperty,
|
||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
||
|
||
module.exports = function(HB) {
|
||
var Delete, Delimiter, ImmutableObject, Insert, Operation, execution_listener, parser;
|
||
parser = {};
|
||
execution_listener = [];
|
||
Operation = (function() {
|
||
function Operation(uid) {
|
||
this.is_deleted = false;
|
||
this.doSync = true;
|
||
this.garbage_collected = false;
|
||
if (uid == null) {
|
||
uid = HB.getNextOperationIdentifier();
|
||
}
|
||
if (uid.doSync == null) {
|
||
uid.doSync = !isNaN(parseInt(uid.op_number));
|
||
}
|
||
this.creator = uid['creator'], this.op_number = uid['op_number'], this.doSync = uid['doSync'];
|
||
}
|
||
|
||
Operation.prototype.type = "Insert";
|
||
|
||
Operation.prototype.on = function(events, f) {
|
||
var e, _base, _i, _len, _results;
|
||
if (this.event_listeners == null) {
|
||
this.event_listeners = {};
|
||
}
|
||
if (events.constructor !== [].constructor) {
|
||
events = [events];
|
||
}
|
||
_results = [];
|
||
for (_i = 0, _len = events.length; _i < _len; _i++) {
|
||
e = events[_i];
|
||
if ((_base = this.event_listeners)[e] == null) {
|
||
_base[e] = [];
|
||
}
|
||
_results.push(this.event_listeners[e].push(f));
|
||
}
|
||
return _results;
|
||
};
|
||
|
||
Operation.prototype.deleteListener = function(events, f) {
|
||
var e, _i, _len, _ref, _results;
|
||
if (events.constructor !== [].constructor) {
|
||
events = [events];
|
||
}
|
||
_results = [];
|
||
for (_i = 0, _len = events.length; _i < _len; _i++) {
|
||
e = events[_i];
|
||
if (((_ref = this.event_listeners) != null ? _ref[e] : void 0) != null) {
|
||
_results.push(this.event_listeners[e] = this.event_listeners[e].filter(function(g) {
|
||
return f !== g;
|
||
}));
|
||
} else {
|
||
_results.push(void 0);
|
||
}
|
||
}
|
||
return _results;
|
||
};
|
||
|
||
Operation.prototype.callEvent = function() {
|
||
return this.forwardEvent.apply(this, [this].concat(__slice.call(arguments)));
|
||
};
|
||
|
||
Operation.prototype.forwardEvent = function() {
|
||
var args, event, f, op, _i, _len, _ref, _ref1, _results;
|
||
op = arguments[0], event = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
|
||
if (((_ref = this.event_listeners) != null ? _ref[event] : void 0) != null) {
|
||
_ref1 = this.event_listeners[event];
|
||
_results = [];
|
||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||
f = _ref1[_i];
|
||
_results.push(f.call.apply(f, [op, event].concat(__slice.call(args))));
|
||
}
|
||
return _results;
|
||
}
|
||
};
|
||
|
||
Operation.prototype.isDeleted = function() {
|
||
return this.is_deleted;
|
||
};
|
||
|
||
Operation.prototype.applyDelete = function(garbagecollect) {
|
||
if (garbagecollect == null) {
|
||
garbagecollect = true;
|
||
}
|
||
if (!this.garbage_collected) {
|
||
this.is_deleted = true;
|
||
if (garbagecollect) {
|
||
this.garbage_collected = true;
|
||
return HB.addToGarbageCollector(this);
|
||
}
|
||
}
|
||
};
|
||
|
||
Operation.prototype.cleanup = function() {
|
||
return HB.removeOperation(this);
|
||
};
|
||
|
||
Operation.prototype.setParent = function(parent) {
|
||
this.parent = parent;
|
||
};
|
||
|
||
Operation.prototype.getParent = function() {
|
||
return this.parent;
|
||
};
|
||
|
||
Operation.prototype.getUid = function() {
|
||
return {
|
||
'creator': this.creator,
|
||
'op_number': this.op_number,
|
||
'sync': this.doSync
|
||
};
|
||
};
|
||
|
||
Operation.prototype.dontSync = function() {
|
||
return this.doSync = false;
|
||
};
|
||
|
||
Operation.prototype.execute = function() {
|
||
var l, _i, _len;
|
||
this.is_executed = true;
|
||
for (_i = 0, _len = execution_listener.length; _i < _len; _i++) {
|
||
l = execution_listener[_i];
|
||
l(this._encode());
|
||
}
|
||
return this;
|
||
};
|
||
|
||
Operation.prototype.saveOperation = function(name, op) {
|
||
if ((op != null ? op.execute : void 0) != null) {
|
||
return this[name] = op;
|
||
} else if (op != null) {
|
||
if (this.unchecked == null) {
|
||
this.unchecked = {};
|
||
}
|
||
return this.unchecked[name] = op;
|
||
}
|
||
};
|
||
|
||
Operation.prototype.validateSavedOperations = function() {
|
||
var name, op, op_uid, success, uninstantiated, _ref;
|
||
uninstantiated = {};
|
||
success = this;
|
||
_ref = this.unchecked;
|
||
for (name in _ref) {
|
||
op_uid = _ref[name];
|
||
op = HB.getOperation(op_uid);
|
||
if (op) {
|
||
this[name] = op;
|
||
} else {
|
||
uninstantiated[name] = op_uid;
|
||
success = false;
|
||
}
|
||
}
|
||
delete this.unchecked;
|
||
if (!success) {
|
||
this.unchecked = uninstantiated;
|
||
}
|
||
return success;
|
||
};
|
||
|
||
return Operation;
|
||
|
||
})();
|
||
Delete = (function(_super) {
|
||
__extends(Delete, _super);
|
||
|
||
function Delete(uid, deletes) {
|
||
this.saveOperation('deletes', deletes);
|
||
Delete.__super__.constructor.call(this, uid);
|
||
}
|
||
|
||
Delete.prototype.type = "Delete";
|
||
|
||
Delete.prototype._encode = function() {
|
||
return {
|
||
'type': "Delete",
|
||
'uid': this.getUid(),
|
||
'deletes': this.deletes.getUid()
|
||
};
|
||
};
|
||
|
||
Delete.prototype.execute = function() {
|
||
if (this.validateSavedOperations()) {
|
||
this.deletes.applyDelete(this);
|
||
return Delete.__super__.execute.apply(this, arguments);
|
||
} else {
|
||
return false;
|
||
}
|
||
};
|
||
|
||
return Delete;
|
||
|
||
})(Operation);
|
||
parser['Delete'] = function(o) {
|
||
var deletes_uid, uid;
|
||
uid = o['uid'], deletes_uid = o['deletes'];
|
||
return new Delete(uid, deletes_uid);
|
||
};
|
||
Insert = (function(_super) {
|
||
__extends(Insert, _super);
|
||
|
||
function Insert(uid, prev_cl, next_cl, origin) {
|
||
this.saveOperation('prev_cl', prev_cl);
|
||
this.saveOperation('next_cl', next_cl);
|
||
if (origin != null) {
|
||
this.saveOperation('origin', origin);
|
||
} else {
|
||
this.saveOperation('origin', prev_cl);
|
||
}
|
||
Insert.__super__.constructor.call(this, uid);
|
||
}
|
||
|
||
Insert.prototype.type = "Insert";
|
||
|
||
Insert.prototype.applyDelete = function(o) {
|
||
var garbagecollect, _ref;
|
||
if (this.deleted_by == null) {
|
||
this.deleted_by = [];
|
||
}
|
||
if ((this.parent != null) && !this.isDeleted()) {
|
||
this.parent.callEvent("delete", this, o);
|
||
}
|
||
if (o != null) {
|
||
this.deleted_by.push(o);
|
||
}
|
||
garbagecollect = false;
|
||
if (!((this.prev_cl != null) && (this.next_cl != null)) || this.prev_cl.isDeleted()) {
|
||
garbagecollect = true;
|
||
}
|
||
Insert.__super__.applyDelete.call(this, garbagecollect);
|
||
if ((_ref = this.next_cl) != null ? _ref.isDeleted() : void 0) {
|
||
return this.next_cl.applyDelete();
|
||
}
|
||
};
|
||
|
||
Insert.prototype.cleanup = function() {
|
||
var d, o, _i, _len, _ref, _ref1;
|
||
if ((_ref = this.prev_cl) != null ? _ref.isDeleted() : void 0) {
|
||
_ref1 = this.deleted_by;
|
||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||
d = _ref1[_i];
|
||
d.cleanup();
|
||
}
|
||
o = this.next_cl;
|
||
while (o.type !== "Delimiter") {
|
||
if (o.origin === this) {
|
||
o.origin = this.prev_cl;
|
||
}
|
||
o = o.next_cl;
|
||
}
|
||
this.prev_cl.next_cl = this.next_cl;
|
||
this.next_cl.prev_cl = this.prev_cl;
|
||
return Insert.__super__.cleanup.apply(this, arguments);
|
||
}
|
||
};
|
||
|
||
Insert.prototype.getDistanceToOrigin = function() {
|
||
var d, o;
|
||
d = 0;
|
||
o = this.prev_cl;
|
||
while (true) {
|
||
if (this.origin === o) {
|
||
break;
|
||
}
|
||
d++;
|
||
o = o.prev_cl;
|
||
}
|
||
return d;
|
||
};
|
||
|
||
Insert.prototype.execute = function(fire_event) {
|
||
var distance_to_origin, i, o, parent, _ref;
|
||
if (fire_event == null) {
|
||
fire_event = true;
|
||
}
|
||
if (!this.validateSavedOperations()) {
|
||
return false;
|
||
} else {
|
||
if (this.prev_cl != null) {
|
||
distance_to_origin = this.getDistanceToOrigin();
|
||
o = this.prev_cl.next_cl;
|
||
i = distance_to_origin;
|
||
while (true) {
|
||
if (o !== this.next_cl) {
|
||
if (o.getDistanceToOrigin() === i) {
|
||
if (o.creator < this.creator) {
|
||
this.prev_cl = o;
|
||
distance_to_origin = i + 1;
|
||
} else {
|
||
|
||
}
|
||
} else if (o.getDistanceToOrigin() < i) {
|
||
if (i - distance_to_origin <= o.getDistanceToOrigin()) {
|
||
this.prev_cl = o;
|
||
distance_to_origin = i + 1;
|
||
} else {
|
||
|
||
}
|
||
} else {
|
||
break;
|
||
}
|
||
i++;
|
||
o = o.next_cl;
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
this.next_cl = this.prev_cl.next_cl;
|
||
this.prev_cl.next_cl = this;
|
||
this.next_cl.prev_cl = this;
|
||
}
|
||
parent = (_ref = this.prev_cl) != null ? _ref.getParent() : void 0;
|
||
if ((parent != null) && fire_event) {
|
||
this.setParent(parent);
|
||
this.parent.callEvent("insert", this);
|
||
}
|
||
return Insert.__super__.execute.apply(this, arguments);
|
||
}
|
||
};
|
||
|
||
Insert.prototype.getPosition = function() {
|
||
var position, prev;
|
||
position = 0;
|
||
prev = this.prev_cl;
|
||
while (true) {
|
||
if (prev instanceof Delimiter) {
|
||
break;
|
||
}
|
||
if (!prev.isDeleted()) {
|
||
position++;
|
||
}
|
||
prev = prev.prev_cl;
|
||
}
|
||
return position;
|
||
};
|
||
|
||
return Insert;
|
||
|
||
})(Operation);
|
||
ImmutableObject = (function(_super) {
|
||
__extends(ImmutableObject, _super);
|
||
|
||
function ImmutableObject(uid, content, prev, next, origin) {
|
||
this.content = content;
|
||
ImmutableObject.__super__.constructor.call(this, uid, prev, next, origin);
|
||
}
|
||
|
||
ImmutableObject.prototype.type = "ImmutableObject";
|
||
|
||
ImmutableObject.prototype.val = function() {
|
||
return this.content;
|
||
};
|
||
|
||
ImmutableObject.prototype._encode = function() {
|
||
var json;
|
||
json = {
|
||
'type': "ImmutableObject",
|
||
'uid': this.getUid(),
|
||
'content': this.content
|
||
};
|
||
if (this.prev_cl != null) {
|
||
json['prev'] = this.prev_cl.getUid();
|
||
}
|
||
if (this.next_cl != null) {
|
||
json['next'] = this.next_cl.getUid();
|
||
}
|
||
if (this.origin != null) {
|
||
json["origin"] = this.origin().getUid();
|
||
}
|
||
return json;
|
||
};
|
||
|
||
return ImmutableObject;
|
||
|
||
})(Operation);
|
||
parser['ImmutableObject'] = function(json) {
|
||
var content, next, origin, prev, uid;
|
||
uid = json['uid'], content = json['content'], prev = json['prev'], next = json['next'], origin = json['origin'];
|
||
return new ImmutableObject(uid, content, prev, next, origin);
|
||
};
|
||
Delimiter = (function(_super) {
|
||
__extends(Delimiter, _super);
|
||
|
||
function Delimiter(uid, prev_cl, next_cl, origin) {
|
||
this.saveOperation('prev_cl', prev_cl);
|
||
this.saveOperation('next_cl', next_cl);
|
||
this.saveOperation('origin', prev_cl);
|
||
Delimiter.__super__.constructor.call(this, uid);
|
||
}
|
||
|
||
Delimiter.prototype.type = "Delimiter";
|
||
|
||
Delimiter.prototype.applyDelete = function() {
|
||
var o;
|
||
Delimiter.__super__.applyDelete.call(this);
|
||
o = this.next_cl;
|
||
while (o != null) {
|
||
o.applyDelete();
|
||
o = o.next_cl;
|
||
}
|
||
return void 0;
|
||
};
|
||
|
||
Delimiter.prototype.cleanup = function() {
|
||
return Delimiter.__super__.cleanup.call(this);
|
||
};
|
||
|
||
Delimiter.prototype.execute = function() {
|
||
var _ref, _ref1;
|
||
if (((_ref = this.unchecked) != null ? _ref['next_cl'] : void 0) != null) {
|
||
return Delimiter.__super__.execute.apply(this, arguments);
|
||
} else if ((_ref1 = this.unchecked) != null ? _ref1['prev_cl'] : void 0) {
|
||
if (this.validateSavedOperations()) {
|
||
if (this.prev_cl.next_cl != null) {
|
||
throw new Error("Probably duplicated operations");
|
||
}
|
||
this.prev_cl.next_cl = this;
|
||
delete this.prev_cl.unchecked.next_cl;
|
||
return Delimiter.__super__.execute.apply(this, arguments);
|
||
} else {
|
||
return false;
|
||
}
|
||
} else if ((this.prev_cl != null) && (this.prev_cl.next_cl == null)) {
|
||
delete this.prev_cl.unchecked.next_cl;
|
||
return this.prev_cl.next_cl = this;
|
||
} else if ((this.prev_cl != null) || (this.next_cl != null)) {
|
||
return Delimiter.__super__.execute.apply(this, arguments);
|
||
} else {
|
||
throw new Error("Delimiter is unsufficient defined!");
|
||
}
|
||
};
|
||
|
||
Delimiter.prototype._encode = function() {
|
||
var _ref, _ref1;
|
||
return {
|
||
'type': "Delimiter",
|
||
'uid': this.getUid(),
|
||
'prev': (_ref = this.prev_cl) != null ? _ref.getUid() : void 0,
|
||
'next': (_ref1 = this.next_cl) != null ? _ref1.getUid() : void 0
|
||
};
|
||
};
|
||
|
||
return Delimiter;
|
||
|
||
})(Operation);
|
||
parser['Delimiter'] = function(json) {
|
||
var next, prev, uid;
|
||
uid = json['uid'], prev = json['prev'], next = json['next'];
|
||
return new Delimiter(uid, prev, next);
|
||
};
|
||
return {
|
||
'types': {
|
||
'Delete': Delete,
|
||
'Insert': Insert,
|
||
'Delimiter': Delimiter,
|
||
'Operation': Operation,
|
||
'ImmutableObject': ImmutableObject
|
||
},
|
||
'parser': parser,
|
||
'execution_listener': execution_listener
|
||
};
|
||
};
|
||
|
||
|
||
},{}],9:[function(require,module,exports){
|
||
var text_types_uninitialized,
|
||
__hasProp = {}.hasOwnProperty,
|
||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||
__slice = [].slice;
|
||
|
||
text_types_uninitialized = require("./TextTypes");
|
||
|
||
module.exports = function(HB) {
|
||
var JsonType, createJsonTypeWrapper, parser, text_types, types;
|
||
text_types = text_types_uninitialized(HB);
|
||
types = text_types.types;
|
||
parser = text_types.parser;
|
||
createJsonTypeWrapper = function(_jsonType) {
|
||
var JsonTypeWrapper;
|
||
JsonTypeWrapper = (function() {
|
||
function JsonTypeWrapper(jsonType) {
|
||
var name, obj, _fn, _ref;
|
||
_ref = jsonType.map;
|
||
_fn = function(name, obj) {
|
||
return Object.defineProperty(JsonTypeWrapper.prototype, name, {
|
||
get: function() {
|
||
var x;
|
||
x = obj.val();
|
||
if (x instanceof JsonType) {
|
||
return createJsonTypeWrapper(x);
|
||
} else if (x instanceof types.ImmutableObject) {
|
||
return x.val();
|
||
} else {
|
||
return x;
|
||
}
|
||
},
|
||
set: function(o) {
|
||
var o_name, o_obj, overwrite, _results;
|
||
overwrite = jsonType.val(name);
|
||
if (o.constructor === {}.constructor && overwrite instanceof types.Operation) {
|
||
_results = [];
|
||
for (o_name in o) {
|
||
o_obj = o[o_name];
|
||
_results.push(overwrite.val(o_name, o_obj, 'immutable'));
|
||
}
|
||
return _results;
|
||
} else {
|
||
return jsonType.val(name, o, 'immutable');
|
||
}
|
||
},
|
||
enumerable: true,
|
||
configurable: false
|
||
});
|
||
};
|
||
for (name in _ref) {
|
||
obj = _ref[name];
|
||
_fn(name, obj);
|
||
}
|
||
}
|
||
|
||
return JsonTypeWrapper;
|
||
|
||
})();
|
||
return new JsonTypeWrapper(_jsonType);
|
||
};
|
||
JsonType = (function(_super) {
|
||
__extends(JsonType, _super);
|
||
|
||
function JsonType(uid, initial_value, mutable) {
|
||
var name, o;
|
||
JsonType.__super__.constructor.call(this, uid);
|
||
if (initial_value != null) {
|
||
if (typeof initial_value !== "object") {
|
||
throw new Error("The initial value of JsonTypes must be of type Object! (current type: " + (typeof initial_value) + ")");
|
||
}
|
||
for (name in initial_value) {
|
||
o = initial_value[name];
|
||
this.val(name, o, mutable);
|
||
}
|
||
}
|
||
}
|
||
|
||
JsonType.prototype.type = "JsonType";
|
||
|
||
JsonType.prototype.applyDelete = function() {
|
||
return JsonType.__super__.applyDelete.call(this);
|
||
};
|
||
|
||
JsonType.prototype.cleanup = function() {
|
||
return JsonType.__super__.cleanup.call(this);
|
||
};
|
||
|
||
JsonType.prototype.toJson = function() {
|
||
var json, name, o, val;
|
||
val = this.val();
|
||
json = {};
|
||
for (name in val) {
|
||
o = val[name];
|
||
if (o === null) {
|
||
json[name] = o;
|
||
} else if (o.constructor === {}.constructor) {
|
||
json[name] = this.val(name).toJson();
|
||
} else if (o instanceof types.Operation) {
|
||
while (o instanceof types.Operation) {
|
||
o = o.val();
|
||
}
|
||
json[name] = o;
|
||
} else {
|
||
json[name] = o;
|
||
}
|
||
}
|
||
return json;
|
||
};
|
||
|
||
JsonType.prototype.setReplaceManager = function(replace_manager) {
|
||
this.replace_manager = replace_manager;
|
||
return this.on(['change', 'addProperty'], function() {
|
||
var _ref;
|
||
if (replace_manager.parent != null) {
|
||
return (_ref = replace_manager.parent).forwardEvent.apply(_ref, [this].concat(__slice.call(arguments)));
|
||
}
|
||
});
|
||
};
|
||
|
||
JsonType.prototype.getParent = function() {
|
||
return this.replace_manager.parent;
|
||
};
|
||
|
||
JsonType.prototype.mutable_default = true;
|
||
|
||
JsonType.prototype.setMutableDefault = function(mutable) {
|
||
if (mutable === true || mutable === 'mutable') {
|
||
JsonType.prototype.mutable_default = true;
|
||
} else if (mutable === false || mutable === 'immutable') {
|
||
JsonType.prototype.mutable_default = false;
|
||
} else {
|
||
throw new Error('Set mutable either "mutable" or "immutable"!');
|
||
}
|
||
return 'OK';
|
||
};
|
||
|
||
JsonType.prototype.val = function(name, content, mutable) {
|
||
var json, obj, word;
|
||
if (typeof name === 'object') {
|
||
json = new JsonType(void 0, name, content);
|
||
HB.addOperation(json).execute();
|
||
this.replace_manager.replace(json);
|
||
return this;
|
||
} else if ((name != null) && ((content != null) || content === null)) {
|
||
if (mutable != null) {
|
||
if (mutable === true || mutable === 'mutable') {
|
||
mutable = true;
|
||
} else {
|
||
mutable = false;
|
||
}
|
||
} else {
|
||
mutable = this.mutable_default;
|
||
}
|
||
if (typeof content === 'function') {
|
||
return this;
|
||
} else if (content === null || (((!mutable) || typeof content === 'number') && content.constructor !== Object)) {
|
||
obj = HB.addOperation(new types.ImmutableObject(void 0, content)).execute();
|
||
return JsonType.__super__.val.call(this, name, obj);
|
||
} else {
|
||
if (typeof content === 'string') {
|
||
word = HB.addOperation(new types.WordType(void 0)).execute();
|
||
word.insertText(0, content);
|
||
return JsonType.__super__.val.call(this, name, word);
|
||
} else if (content.constructor === Object) {
|
||
json = HB.addOperation(new JsonType(void 0, content, mutable)).execute();
|
||
return JsonType.__super__.val.call(this, name, json);
|
||
} else {
|
||
throw new Error("You must not set " + (typeof content) + "-types in collaborative Json-objects!");
|
||
}
|
||
}
|
||
} else {
|
||
return JsonType.__super__.val.call(this, name, content);
|
||
}
|
||
};
|
||
|
||
Object.defineProperty(JsonType.prototype, 'value', {
|
||
get: function() {
|
||
return createJsonTypeWrapper(this);
|
||
},
|
||
set: function(o) {
|
||
var o_name, o_obj, _results;
|
||
if (o.constructor === {}.constructor) {
|
||
_results = [];
|
||
for (o_name in o) {
|
||
o_obj = o[o_name];
|
||
_results.push(this.val(o_name, o_obj, 'immutable'));
|
||
}
|
||
return _results;
|
||
} else {
|
||
throw new Error("You must only set Object values!");
|
||
}
|
||
}
|
||
});
|
||
|
||
JsonType.prototype._encode = function() {
|
||
return {
|
||
'type': "JsonType",
|
||
'uid': this.getUid()
|
||
};
|
||
};
|
||
|
||
return JsonType;
|
||
|
||
})(types.MapManager);
|
||
parser['JsonType'] = function(json) {
|
||
var uid;
|
||
uid = json['uid'];
|
||
return new JsonType(uid);
|
||
};
|
||
types['JsonType'] = JsonType;
|
||
return text_types;
|
||
};
|
||
|
||
|
||
},{"./TextTypes":11}],10:[function(require,module,exports){
|
||
var basic_types_uninitialized,
|
||
__hasProp = {}.hasOwnProperty,
|
||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
||
|
||
basic_types_uninitialized = require("./BasicTypes");
|
||
|
||
module.exports = function(HB) {
|
||
var AddName, ListManager, MapManager, ReplaceManager, Replaceable, basic_types, parser, types;
|
||
basic_types = basic_types_uninitialized(HB);
|
||
types = basic_types.types;
|
||
parser = basic_types.parser;
|
||
MapManager = (function(_super) {
|
||
__extends(MapManager, _super);
|
||
|
||
function MapManager(uid) {
|
||
this.map = {};
|
||
MapManager.__super__.constructor.call(this, uid);
|
||
}
|
||
|
||
MapManager.prototype.type = "MapManager";
|
||
|
||
MapManager.prototype.applyDelete = function() {
|
||
var name, p, _ref;
|
||
_ref = this.map;
|
||
for (name in _ref) {
|
||
p = _ref[name];
|
||
p.applyDelete();
|
||
}
|
||
return MapManager.__super__.applyDelete.call(this);
|
||
};
|
||
|
||
MapManager.prototype.cleanup = function() {
|
||
return MapManager.__super__.cleanup.call(this);
|
||
};
|
||
|
||
MapManager.prototype.val = function(name, content) {
|
||
var o, obj, result, _ref, _ref1;
|
||
if (content != null) {
|
||
if (this.map[name] == null) {
|
||
HB.addOperation(new AddName(void 0, this, name)).execute();
|
||
}
|
||
this.map[name].replace(content);
|
||
return this;
|
||
} else if (name != null) {
|
||
obj = (_ref = this.map[name]) != null ? _ref.val() : void 0;
|
||
if (obj instanceof types.ImmutableObject) {
|
||
return obj.val();
|
||
} else {
|
||
return obj;
|
||
}
|
||
} else {
|
||
result = {};
|
||
_ref1 = this.map;
|
||
for (name in _ref1) {
|
||
o = _ref1[name];
|
||
obj = o.val();
|
||
if (obj instanceof types.ImmutableObject || obj instanceof MapManager) {
|
||
obj = obj.val();
|
||
}
|
||
result[name] = obj;
|
||
}
|
||
return result;
|
||
}
|
||
};
|
||
|
||
return MapManager;
|
||
|
||
})(types.Operation);
|
||
AddName = (function(_super) {
|
||
__extends(AddName, _super);
|
||
|
||
function AddName(uid, map_manager, name) {
|
||
this.name = name;
|
||
this.saveOperation('map_manager', map_manager);
|
||
AddName.__super__.constructor.call(this, uid);
|
||
}
|
||
|
||
AddName.prototype.type = "AddName";
|
||
|
||
AddName.prototype.applyDelete = function() {
|
||
return AddName.__super__.applyDelete.call(this);
|
||
};
|
||
|
||
AddName.prototype.cleanup = function() {
|
||
return AddName.__super__.cleanup.call(this);
|
||
};
|
||
|
||
AddName.prototype.execute = function() {
|
||
var beg, end, uid_beg, uid_end, uid_r, _base;
|
||
if (!this.validateSavedOperations()) {
|
||
return false;
|
||
} else {
|
||
uid_r = this.map_manager.getUid();
|
||
uid_r.op_number = "_" + uid_r.op_number + "_RM_" + this.name;
|
||
if (HB.getOperation(uid_r) == null) {
|
||
uid_beg = this.map_manager.getUid();
|
||
uid_beg.op_number = "_" + uid_beg.op_number + "_RM_" + this.name + "_beginning";
|
||
uid_end = this.map_manager.getUid();
|
||
uid_end.op_number = "_" + uid_end.op_number + "_RM_" + this.name + "_end";
|
||
beg = HB.addOperation(new types.Delimiter(uid_beg, void 0, uid_end)).execute();
|
||
end = HB.addOperation(new types.Delimiter(uid_end, beg, void 0)).execute();
|
||
this.map_manager.map[this.name] = HB.addOperation(new ReplaceManager(void 0, uid_r, beg, end));
|
||
this.map_manager.map[this.name].setParent(this.map_manager, this.name);
|
||
((_base = this.map_manager.map[this.name]).add_name_ops != null ? _base.add_name_ops : _base.add_name_ops = []).push(this);
|
||
this.map_manager.map[this.name].execute();
|
||
}
|
||
return AddName.__super__.execute.apply(this, arguments);
|
||
}
|
||
};
|
||
|
||
AddName.prototype._encode = function() {
|
||
return {
|
||
'type': "AddName",
|
||
'uid': this.getUid(),
|
||
'map_manager': this.map_manager.getUid(),
|
||
'name': this.name
|
||
};
|
||
};
|
||
|
||
return AddName;
|
||
|
||
})(types.Operation);
|
||
parser['AddName'] = function(json) {
|
||
var map_manager, name, uid;
|
||
map_manager = json['map_manager'], uid = json['uid'], name = json['name'];
|
||
return new AddName(uid, map_manager, name);
|
||
};
|
||
ListManager = (function(_super) {
|
||
__extends(ListManager, _super);
|
||
|
||
function ListManager(uid, beginning, end, prev, next, origin) {
|
||
if ((beginning != null) && (end != null)) {
|
||
this.saveOperation('beginning', beginning);
|
||
this.saveOperation('end', end);
|
||
} else {
|
||
this.beginning = HB.addOperation(new types.Delimiter(void 0, void 0, void 0));
|
||
this.end = HB.addOperation(new types.Delimiter(void 0, this.beginning, void 0));
|
||
this.beginning.next_cl = this.end;
|
||
this.beginning.execute();
|
||
this.end.execute();
|
||
}
|
||
ListManager.__super__.constructor.call(this, uid, prev, next, origin);
|
||
}
|
||
|
||
ListManager.prototype.type = "ListManager";
|
||
|
||
ListManager.prototype.execute = function() {
|
||
if (this.validateSavedOperations()) {
|
||
this.beginning.setParent(this);
|
||
this.end.setParent(this);
|
||
return ListManager.__super__.execute.apply(this, arguments);
|
||
} else {
|
||
return false;
|
||
}
|
||
};
|
||
|
||
ListManager.prototype.getLastOperation = function() {
|
||
return this.end.prev_cl;
|
||
};
|
||
|
||
ListManager.prototype.getFirstOperation = function() {
|
||
return this.beginning.next_cl;
|
||
};
|
||
|
||
ListManager.prototype.toArray = function() {
|
||
var o, result;
|
||
o = this.beginning.next_cl;
|
||
result = [];
|
||
while (o !== this.end) {
|
||
result.push(o);
|
||
o = o.next_cl;
|
||
}
|
||
return result;
|
||
};
|
||
|
||
ListManager.prototype.getOperationByPosition = function(position) {
|
||
var o;
|
||
o = this.beginning.next_cl;
|
||
if ((position > 0 || o.isDeleted()) && !(o instanceof types.Delimiter)) {
|
||
while (o.isDeleted() && !(o instanceof types.Delimiter)) {
|
||
o = o.next_cl;
|
||
}
|
||
while (true) {
|
||
if (o instanceof types.Delimiter) {
|
||
break;
|
||
}
|
||
if (position <= 0 && !o.isDeleted()) {
|
||
break;
|
||
}
|
||
o = o.next_cl;
|
||
if (!o.isDeleted()) {
|
||
position -= 1;
|
||
}
|
||
}
|
||
}
|
||
return o;
|
||
};
|
||
|
||
return ListManager;
|
||
|
||
})(types.Operation);
|
||
ReplaceManager = (function(_super) {
|
||
__extends(ReplaceManager, _super);
|
||
|
||
function ReplaceManager(initial_content, uid, beginning, end, prev, next, origin) {
|
||
ReplaceManager.__super__.constructor.call(this, uid, beginning, end, prev, next, origin);
|
||
if (initial_content != null) {
|
||
this.replace(initial_content);
|
||
}
|
||
}
|
||
|
||
ReplaceManager.prototype.type = "ReplaceManager";
|
||
|
||
ReplaceManager.prototype.applyDelete = function() {
|
||
var o, _i, _len, _ref;
|
||
o = this.beginning;
|
||
while (o != null) {
|
||
o.applyDelete();
|
||
o = o.next_cl;
|
||
}
|
||
if (this.add_name_ops != null) {
|
||
_ref = this.add_name_ops;
|
||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||
o = _ref[_i];
|
||
o.applyDelete();
|
||
}
|
||
}
|
||
return ReplaceManager.__super__.applyDelete.call(this);
|
||
};
|
||
|
||
ReplaceManager.prototype.cleanup = function() {
|
||
return ReplaceManager.__super__.cleanup.call(this);
|
||
};
|
||
|
||
ReplaceManager.prototype.replace = function(content, replaceable_uid) {
|
||
var o, op;
|
||
o = this.getLastOperation();
|
||
op = new Replaceable(content, this, replaceable_uid, o, o.next_cl);
|
||
HB.addOperation(op).execute();
|
||
return void 0;
|
||
};
|
||
|
||
ReplaceManager.prototype.setParent = function(parent, property_name) {
|
||
var addPropertyListener, repl_manager;
|
||
repl_manager = this;
|
||
this.on('insert', function(event, op) {
|
||
if (op.next_cl instanceof types.Delimiter) {
|
||
return repl_manager.parent.callEvent('change', property_name, op);
|
||
}
|
||
});
|
||
this.on('change', function(event, op) {
|
||
if (repl_manager !== this) {
|
||
return repl_manager.parent.callEvent('change', property_name, op);
|
||
}
|
||
});
|
||
addPropertyListener = function(event, op) {
|
||
repl_manager.deleteListener('addProperty', addPropertyListener);
|
||
return repl_manager.parent.callEvent('addProperty', property_name, op);
|
||
};
|
||
this.on('insert', addPropertyListener);
|
||
return ReplaceManager.__super__.setParent.call(this, parent);
|
||
};
|
||
|
||
ReplaceManager.prototype.val = function() {
|
||
var o;
|
||
o = this.getLastOperation();
|
||
return typeof o.val === "function" ? o.val() : void 0;
|
||
};
|
||
|
||
ReplaceManager.prototype._encode = function() {
|
||
var json;
|
||
json = {
|
||
'type': "ReplaceManager",
|
||
'uid': this.getUid(),
|
||
'beginning': this.beginning.getUid(),
|
||
'end': this.end.getUid()
|
||
};
|
||
if ((this.prev_cl != null) && (this.next_cl != null)) {
|
||
json['prev'] = this.prev_cl.getUid();
|
||
json['next'] = this.next_cl.getUid();
|
||
}
|
||
if (this.origin != null) {
|
||
json["origin"] = this.origin().getUid();
|
||
}
|
||
return json;
|
||
};
|
||
|
||
return ReplaceManager;
|
||
|
||
})(ListManager);
|
||
parser["ReplaceManager"] = function(json) {
|
||
var beginning, content, end, next, origin, prev, uid;
|
||
content = json['content'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'], beginning = json['beginning'], end = json['end'];
|
||
return new ReplaceManager(content, uid, beginning, end, prev, next, origin);
|
||
};
|
||
Replaceable = (function(_super) {
|
||
__extends(Replaceable, _super);
|
||
|
||
function Replaceable(content, parent, uid, prev, next, origin) {
|
||
this.saveOperation('content', content);
|
||
this.saveOperation('parent', parent);
|
||
if (!((prev != null) && (next != null))) {
|
||
throw new Error("You must define prev, and next for Replaceable-types!");
|
||
}
|
||
Replaceable.__super__.constructor.call(this, uid, prev, next, origin);
|
||
}
|
||
|
||
Replaceable.prototype.type = "Replaceable";
|
||
|
||
Replaceable.prototype.val = function() {
|
||
return this.content;
|
||
};
|
||
|
||
Replaceable.prototype.replace = function(content) {
|
||
return this.parent.replace(content);
|
||
};
|
||
|
||
Replaceable.prototype.applyDelete = function() {
|
||
if (this.content != null) {
|
||
this.content.applyDelete();
|
||
this.content.dontSync();
|
||
}
|
||
this.content = null;
|
||
return Replaceable.__super__.applyDelete.apply(this, arguments);
|
||
};
|
||
|
||
Replaceable.prototype.cleanup = function() {
|
||
return Replaceable.__super__.cleanup.apply(this, arguments);
|
||
};
|
||
|
||
Replaceable.prototype.execute = function() {
|
||
var ins_result, _ref;
|
||
if (!this.validateSavedOperations()) {
|
||
return false;
|
||
} else {
|
||
if ((_ref = this.content) != null) {
|
||
if (typeof _ref.setReplaceManager === "function") {
|
||
_ref.setReplaceManager(this.parent);
|
||
}
|
||
}
|
||
ins_result = Replaceable.__super__.execute.call(this, this.content != null);
|
||
if (ins_result) {
|
||
if (this.next_cl.type === "Delimiter" && this.prev_cl.type !== "Delimiter") {
|
||
this.prev_cl.applyDelete();
|
||
} else if (this.next_cl.type !== "Delimiter") {
|
||
this.applyDelete();
|
||
}
|
||
}
|
||
return ins_result;
|
||
}
|
||
};
|
||
|
||
Replaceable.prototype._encode = function() {
|
||
var json, _ref;
|
||
json = {
|
||
'type': "Replaceable",
|
||
'content': (_ref = this.content) != null ? _ref.getUid() : void 0,
|
||
'ReplaceManager': this.parent.getUid(),
|
||
'prev': this.prev_cl.getUid(),
|
||
'next': this.next_cl.getUid(),
|
||
'uid': this.getUid()
|
||
};
|
||
if ((this.origin != null) && this.origin !== this.prev_cl) {
|
||
json["origin"] = this.origin.getUid();
|
||
}
|
||
return json;
|
||
};
|
||
|
||
return Replaceable;
|
||
|
||
})(types.Insert);
|
||
parser["Replaceable"] = function(json) {
|
||
var content, next, origin, parent, prev, uid;
|
||
content = json['content'], parent = json['ReplaceManager'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'];
|
||
return new Replaceable(content, parent, uid, prev, next, origin);
|
||
};
|
||
types['ListManager'] = ListManager;
|
||
types['MapManager'] = MapManager;
|
||
types['ReplaceManager'] = ReplaceManager;
|
||
types['Replaceable'] = Replaceable;
|
||
return basic_types;
|
||
};
|
||
|
||
|
||
},{"./BasicTypes":8}],11:[function(require,module,exports){
|
||
var structured_types_uninitialized,
|
||
__hasProp = {}.hasOwnProperty,
|
||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
||
|
||
structured_types_uninitialized = require("./StructuredTypes");
|
||
|
||
module.exports = function(HB) {
|
||
var TextDelete, TextInsert, WordType, parser, structured_types, types;
|
||
structured_types = structured_types_uninitialized(HB);
|
||
types = structured_types.types;
|
||
parser = structured_types.parser;
|
||
TextDelete = (function(_super) {
|
||
__extends(TextDelete, _super);
|
||
|
||
function TextDelete() {
|
||
return TextDelete.__super__.constructor.apply(this, arguments);
|
||
}
|
||
|
||
return TextDelete;
|
||
|
||
})(types.Delete);
|
||
parser["TextDelete"] = parser["Delete"];
|
||
TextInsert = (function(_super) {
|
||
__extends(TextInsert, _super);
|
||
|
||
function TextInsert(content, uid, prev, next, origin) {
|
||
this.content = content;
|
||
if (!((prev != null) && (next != null))) {
|
||
throw new Error("You must define prev, and next for TextInsert-types!");
|
||
}
|
||
TextInsert.__super__.constructor.call(this, uid, prev, next, origin);
|
||
}
|
||
|
||
TextInsert.prototype.type = "TextInsert";
|
||
|
||
TextInsert.prototype.getLength = function() {
|
||
if (this.isDeleted()) {
|
||
return 0;
|
||
} else {
|
||
return this.content.length;
|
||
}
|
||
};
|
||
|
||
TextInsert.prototype.applyDelete = function() {
|
||
this.content = null;
|
||
return TextInsert.__super__.applyDelete.apply(this, arguments);
|
||
};
|
||
|
||
TextInsert.prototype.val = function(current_position) {
|
||
if (this.isDeleted() || (this.content == null)) {
|
||
return "";
|
||
} else {
|
||
return this.content;
|
||
}
|
||
};
|
||
|
||
TextInsert.prototype._encode = function() {
|
||
var json;
|
||
json = {
|
||
'type': "TextInsert",
|
||
'content': this.content,
|
||
'uid': this.getUid(),
|
||
'prev': this.prev_cl.getUid(),
|
||
'next': this.next_cl.getUid()
|
||
};
|
||
if (this.origin !== this.prev_cl) {
|
||
json["origin"] = this.origin.getUid();
|
||
}
|
||
return json;
|
||
};
|
||
|
||
return TextInsert;
|
||
|
||
})(types.Insert);
|
||
parser["TextInsert"] = function(json) {
|
||
var content, next, origin, prev, uid;
|
||
content = json['content'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'];
|
||
return new TextInsert(content, uid, prev, next, origin);
|
||
};
|
||
WordType = (function(_super) {
|
||
__extends(WordType, _super);
|
||
|
||
function WordType(uid, beginning, end, prev, next, origin) {
|
||
WordType.__super__.constructor.call(this, uid, beginning, end, prev, next, origin);
|
||
}
|
||
|
||
WordType.prototype.type = "WordType";
|
||
|
||
WordType.prototype.applyDelete = function() {
|
||
var o;
|
||
o = this.beginning;
|
||
while (o != null) {
|
||
o.applyDelete();
|
||
o = o.next_cl;
|
||
}
|
||
return WordType.__super__.applyDelete.call(this);
|
||
};
|
||
|
||
WordType.prototype.cleanup = function() {
|
||
return WordType.__super__.cleanup.call(this);
|
||
};
|
||
|
||
WordType.prototype.push = function(content) {
|
||
return this.insertAfter(this.end.prev_cl, content);
|
||
};
|
||
|
||
WordType.prototype.insertAfter = function(left, content) {
|
||
var c, op, right, _i, _len;
|
||
while (left.isDeleted()) {
|
||
left = left.prev_cl;
|
||
}
|
||
right = left.next_cl;
|
||
if (content.type != null) {
|
||
op = new TextInsert(content, void 0, left, right);
|
||
HB.addOperation(op).execute();
|
||
} else {
|
||
for (_i = 0, _len = content.length; _i < _len; _i++) {
|
||
c = content[_i];
|
||
op = new TextInsert(c, void 0, left, right);
|
||
HB.addOperation(op).execute();
|
||
left = op;
|
||
}
|
||
}
|
||
return this;
|
||
};
|
||
|
||
WordType.prototype.insertText = function(position, content) {
|
||
var ith, left;
|
||
ith = this.getOperationByPosition(position);
|
||
left = ith.prev_cl;
|
||
return this.insertAfter(left, content);
|
||
};
|
||
|
||
WordType.prototype.deleteText = function(position, length) {
|
||
var d, delete_ops, i, o, _i;
|
||
o = this.getOperationByPosition(position);
|
||
delete_ops = [];
|
||
for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) {
|
||
if (o instanceof types.Delimiter) {
|
||
break;
|
||
}
|
||
d = HB.addOperation(new TextDelete(void 0, o)).execute();
|
||
o = o.next_cl;
|
||
while (!(o instanceof types.Delimiter) && o.isDeleted()) {
|
||
o = o.next_cl;
|
||
}
|
||
delete_ops.push(d._encode());
|
||
}
|
||
return this;
|
||
};
|
||
|
||
WordType.prototype.replaceText = function(text) {
|
||
var word;
|
||
if (this.replace_manager != null) {
|
||
word = HB.addOperation(new WordType(void 0)).execute();
|
||
word.insertText(0, text);
|
||
this.replace_manager.replace(word);
|
||
return word;
|
||
} else {
|
||
throw new Error("This type is currently not maintained by a ReplaceManager!");
|
||
}
|
||
};
|
||
|
||
WordType.prototype.val = function() {
|
||
var c, o;
|
||
c = (function() {
|
||
var _i, _len, _ref, _results;
|
||
_ref = this.toArray();
|
||
_results = [];
|
||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||
o = _ref[_i];
|
||
if (o.val != null) {
|
||
_results.push(o.val());
|
||
} else {
|
||
_results.push("");
|
||
}
|
||
}
|
||
return _results;
|
||
}).call(this);
|
||
return c.join('');
|
||
};
|
||
|
||
WordType.prototype.toString = function() {
|
||
return this.val();
|
||
};
|
||
|
||
WordType.prototype.setReplaceManager = function(op) {
|
||
this.saveOperation('replace_manager', op);
|
||
this.validateSavedOperations();
|
||
this.on('insert', (function(_this) {
|
||
return function(event, ins) {
|
||
var _ref;
|
||
return (_ref = _this.replace_manager) != null ? _ref.forwardEvent(_this, 'change', ins) : void 0;
|
||
};
|
||
})(this));
|
||
return this.on('delete', (function(_this) {
|
||
return function(event, ins, del) {
|
||
var _ref;
|
||
return (_ref = _this.replace_manager) != null ? _ref.forwardEvent(_this, 'change', del) : void 0;
|
||
};
|
||
})(this));
|
||
};
|
||
|
||
WordType.prototype.bind = function(textfield) {
|
||
var word;
|
||
word = this;
|
||
textfield.value = this.val();
|
||
this.on("insert", function(event, op) {
|
||
var fix, left, o_pos, right;
|
||
o_pos = op.getPosition();
|
||
fix = function(cursor) {
|
||
if (cursor <= o_pos) {
|
||
return cursor;
|
||
} else {
|
||
cursor += 1;
|
||
return cursor;
|
||
}
|
||
};
|
||
left = fix(textfield.selectionStart);
|
||
right = fix(textfield.selectionEnd);
|
||
textfield.value = word.val();
|
||
return textfield.setSelectionRange(left, right);
|
||
});
|
||
this.on("delete", function(event, op) {
|
||
var fix, left, o_pos, right;
|
||
o_pos = op.getPosition();
|
||
fix = function(cursor) {
|
||
if (cursor < o_pos) {
|
||
return cursor;
|
||
} else {
|
||
cursor -= 1;
|
||
return cursor;
|
||
}
|
||
};
|
||
left = fix(textfield.selectionStart);
|
||
right = fix(textfield.selectionEnd);
|
||
textfield.value = word.val();
|
||
return textfield.setSelectionRange(left, right);
|
||
});
|
||
textfield.onkeypress = function(event) {
|
||
var char, diff, new_pos, pos;
|
||
char = null;
|
||
if (event.key != null) {
|
||
if (event.charCode === 32) {
|
||
char = " ";
|
||
} else if (event.keyCode === 13) {
|
||
char = '\n';
|
||
} else {
|
||
char = event.key;
|
||
}
|
||
} else {
|
||
char = String.fromCharCode(event.keyCode);
|
||
}
|
||
if (char.length > 0) {
|
||
pos = Math.min(textfield.selectionStart, textfield.selectionEnd);
|
||
diff = Math.abs(textfield.selectionEnd - textfield.selectionStart);
|
||
word.deleteText(pos, diff);
|
||
word.insertText(pos, char);
|
||
new_pos = pos + char.length;
|
||
textfield.setSelectionRange(new_pos, new_pos);
|
||
return event.preventDefault();
|
||
} else {
|
||
return event.preventDefault();
|
||
}
|
||
};
|
||
textfield.onpaste = function(event) {
|
||
return event.preventDefault();
|
||
};
|
||
textfield.oncut = function(event) {
|
||
return event.preventDefault();
|
||
};
|
||
return textfield.onkeydown = function(event) {
|
||
var del_length, diff, new_pos, pos, val;
|
||
pos = Math.min(textfield.selectionStart, textfield.selectionEnd);
|
||
diff = Math.abs(textfield.selectionEnd - textfield.selectionStart);
|
||
if ((event.keyCode != null) && event.keyCode === 8) {
|
||
if (diff > 0) {
|
||
word.deleteText(pos, diff);
|
||
textfield.setSelectionRange(pos, pos);
|
||
} else {
|
||
if ((event.ctrlKey != null) && event.ctrlKey) {
|
||
val = textfield.value;
|
||
new_pos = pos;
|
||
del_length = 0;
|
||
if (pos > 0) {
|
||
new_pos--;
|
||
del_length++;
|
||
}
|
||
while (new_pos > 0 && val[new_pos] !== " " && val[new_pos] !== '\n') {
|
||
new_pos--;
|
||
del_length++;
|
||
}
|
||
word.deleteText(new_pos, pos - new_pos);
|
||
textfield.setSelectionRange(new_pos, new_pos);
|
||
} else {
|
||
word.deleteText(pos - 1, 1);
|
||
}
|
||
}
|
||
return event.preventDefault();
|
||
} else if ((event.keyCode != null) && event.keyCode === 46) {
|
||
if (diff > 0) {
|
||
word.deleteText(pos, diff);
|
||
textfield.setSelectionRange(pos, pos);
|
||
} else {
|
||
word.deleteText(pos, 1);
|
||
textfield.setSelectionRange(pos, pos);
|
||
}
|
||
return event.preventDefault();
|
||
}
|
||
};
|
||
};
|
||
|
||
WordType.prototype._encode = function() {
|
||
var json;
|
||
json = {
|
||
'type': "WordType",
|
||
'uid': this.getUid(),
|
||
'beginning': this.beginning.getUid(),
|
||
'end': this.end.getUid()
|
||
};
|
||
if (this.prev_cl != null) {
|
||
json['prev'] = this.prev_cl.getUid();
|
||
}
|
||
if (this.next_cl != null) {
|
||
json['next'] = this.next_cl.getUid();
|
||
}
|
||
if (this.origin != null) {
|
||
json["origin"] = this.origin().getUid();
|
||
}
|
||
return json;
|
||
};
|
||
|
||
return WordType;
|
||
|
||
})(types.ListManager);
|
||
parser['WordType'] = function(json) {
|
||
var beginning, end, next, origin, prev, uid;
|
||
uid = json['uid'], beginning = json['beginning'], end = json['end'], prev = json['prev'], next = json['next'], origin = json['origin'];
|
||
return new WordType(uid, beginning, end, prev, next, origin);
|
||
};
|
||
types['TextInsert'] = TextInsert;
|
||
types['TextDelete'] = TextDelete;
|
||
types['WordType'] = WordType;
|
||
return structured_types;
|
||
};
|
||
|
||
|
||
},{"./StructuredTypes":10}],12:[function(require,module,exports){
|
||
var json_types_uninitialized,
|
||
__hasProp = {}.hasOwnProperty,
|
||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
||
|
||
json_types_uninitialized = require("./JsonTypes");
|
||
|
||
if (typeof Element !== "undefined" && Element !== null) {
|
||
Element.prototype._proxy = function(f_name, f) {
|
||
var old_f;
|
||
old_f = this[f_name];
|
||
if (old_f != null) {
|
||
return this[f_name] = function() {
|
||
f.apply(this, arguments);
|
||
return old_f.apply(this, arguments);
|
||
};
|
||
} else {
|
||
return this[f_name] = f;
|
||
}
|
||
};
|
||
}
|
||
|
||
module.exports = function(HB) {
|
||
var XmlType, json_types, parser, types;
|
||
json_types = json_types_uninitialized(HB);
|
||
types = json_types.types;
|
||
parser = json_types.parser;
|
||
XmlType = (function(_super) {
|
||
__extends(XmlType, _super);
|
||
|
||
function XmlType(uid, tagname, attributes, elements, xml) {
|
||
var attr, element, i, n, word, _i, _j, _len, _ref, _ref1;
|
||
this.tagname = tagname;
|
||
this.xml = xml;
|
||
|
||
/* In case you make this instanceof Insert again
|
||
if prev? and (not next?) and prev.type?
|
||
* adjust what you actually mean. you want to insert after prev, then
|
||
* next is not defined. but we only insert after non-deleted elements.
|
||
* This is also handled in TextInsert.
|
||
while prev.isDeleted()
|
||
prev = prev.prev_cl
|
||
next = prev.next_cl
|
||
*/
|
||
XmlType.__super__.constructor.call(this);
|
||
if ((attributes != null) && (elements != null)) {
|
||
this.saveOperation('attributes', attributes);
|
||
this.saveOperation('elements', elements);
|
||
} else if ((attributes == null) && (elements == null)) {
|
||
this.attributes = new types.JsonType();
|
||
HB.addOperation(this.attributes).execute();
|
||
this.elements = new types.WordType();
|
||
this.elements.parent = this;
|
||
HB.addOperation(this.elements).execute();
|
||
} else {
|
||
throw new Error("Either define attribute and elements both, or none of them");
|
||
}
|
||
if (this.xml != null) {
|
||
this.tagname = this.xml.tagName;
|
||
for (i = _i = 0, _ref = this.xml.attributes.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
||
attr = xml.attributes[i];
|
||
this.attributes.val(attr.name, attr.value);
|
||
}
|
||
_ref1 = this.xml.childNodes;
|
||
for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
|
||
n = _ref1[_j];
|
||
if (n.nodeType === n.TEXT_NODE) {
|
||
word = new types.WordType();
|
||
HB.addOperation(word).execute();
|
||
word.push(n.textContent);
|
||
this.elements.push(word);
|
||
} else if (n.nodeType === n.ELEMENT_NODE) {
|
||
element = new XmlType(void 0, void 0, void 0, void 0, n);
|
||
HB.addOperation(element).execute();
|
||
this.elements.push(element);
|
||
} else {
|
||
throw new Error("I don't know Node-type " + n.nodeType + "!!");
|
||
}
|
||
}
|
||
this.setXmlProxy();
|
||
}
|
||
void 0;
|
||
}
|
||
|
||
XmlType.prototype.type = "XmlType";
|
||
|
||
XmlType.prototype.applyDelete = function() {
|
||
this.attributes.applyDelete();
|
||
this.elements.applyDelete();
|
||
return XmlType.__super__.applyDelete.call(this);
|
||
};
|
||
|
||
XmlType.prototype.cleanup = function() {
|
||
return XmlType.__super__.cleanup.call(this);
|
||
};
|
||
|
||
XmlType.prototype.setXmlProxy = function() {
|
||
this.xml._yatta = this;
|
||
return this.xml._proxy('insertBefore', function(insertedNode, adjacentNode) {
|
||
var element, next, prev;
|
||
next = adjacentNode != null ? adjacentNode._yatta : void 0;
|
||
prev = null;
|
||
if (next != null) {
|
||
prev = next.prev_cl;
|
||
} else {
|
||
prev = this._yatta.elements.end.prev_cl;
|
||
}
|
||
element = new XmlType(void 0, void 0, void 0, void 0);
|
||
HB.addOperation(element).execute();
|
||
return this.elements.insertAfter(prev, element);
|
||
});
|
||
};
|
||
|
||
XmlType.prototype.val = function(enforce) {
|
||
var a, attr, attr_name, e, n, text_node, value;
|
||
if (enforce == null) {
|
||
enforce = false;
|
||
}
|
||
if (typeof document !== "undefined" && document !== null) {
|
||
if ((this.xml == null) || enforce) {
|
||
this.xml = document.createElement(this.tagname);
|
||
attr = this.attributes.val();
|
||
for (attr_name in attr) {
|
||
value = attr[attr_name];
|
||
a = document.createAttribute(attr_name);
|
||
a.value = value;
|
||
this.xml.setAttributeNode(a);
|
||
}
|
||
e = this.elements.beginning.next_cl;
|
||
while (e.type !== "Delimiter") {
|
||
n = e.content;
|
||
if (!n.isDeleted()) {
|
||
if (n.type === "XmlType") {
|
||
this.xml.appendChild(n.val(enforce));
|
||
} else if (n.type === "WordType") {
|
||
text_node = document.createTextNode(n.val());
|
||
this.xml.appendChild(text_node);
|
||
} else {
|
||
throw new Error("Internal structure cannot be transformed to dom");
|
||
}
|
||
}
|
||
e = e.next_cl;
|
||
}
|
||
}
|
||
this.setXmlProxy();
|
||
return this.xml;
|
||
}
|
||
};
|
||
|
||
XmlType.prototype.execute = function() {
|
||
return XmlType.__super__.execute.apply(this, arguments);
|
||
};
|
||
|
||
|
||
/*
|
||
if not @validateSavedOperations()
|
||
return false
|
||
else
|
||
|
||
return true
|
||
*/
|
||
|
||
XmlType.prototype.getParent = function() {
|
||
return this.parent;
|
||
};
|
||
|
||
XmlType.prototype._encode = function() {
|
||
var json;
|
||
json = {
|
||
'type': this.type,
|
||
'attributes': this.attributes.getUid(),
|
||
'elements': this.elements.getUid(),
|
||
'tagname': this.tagname,
|
||
'uid': this.getUid()
|
||
};
|
||
return json;
|
||
};
|
||
|
||
return XmlType;
|
||
|
||
})(types.Insert);
|
||
parser['XmlType'] = function(json) {
|
||
var attributes, elements, tagname, uid;
|
||
uid = json['uid'], attributes = json['attributes'], elements = json['elements'], tagname = json['tagname'];
|
||
return new XmlType(uid, tagname, attributes, elements, void 0);
|
||
};
|
||
types['XmlType'] = XmlType;
|
||
return json_types;
|
||
};
|
||
|
||
|
||
},{"./JsonTypes":9}],13:[function(require,module,exports){
|
||
exports['IwcConnector'] = require('./Connectors/IwcConnector');
|
||
|
||
exports['TestConnector'] = require('./Connectors/TestConnector');
|
||
|
||
exports['JsonFramework'] = require('./Frameworks/JsonFramework');
|
||
|
||
exports['TextFramework'] = require('./Frameworks/TextFramework');
|
||
|
||
exports['XmlFramework'] = require('./Frameworks/XmlFramework');
|
||
|
||
|
||
},{"./Connectors/IwcConnector":1,"./Connectors/TestConnector":2,"./Frameworks/JsonFramework":4,"./Frameworks/TextFramework":5,"./Frameworks/XmlFramework":6}],14:[function(require,module,exports){
|
||
module.exports = require('./lib/chai');
|
||
|
||
},{"./lib/chai":15}],15:[function(require,module,exports){
|
||
/*!
|
||
* chai
|
||
* Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
var used = []
|
||
, exports = module.exports = {};
|
||
|
||
/*!
|
||
* Chai version
|
||
*/
|
||
|
||
exports.version = '1.9.1';
|
||
|
||
/*!
|
||
* Assertion Error
|
||
*/
|
||
|
||
exports.AssertionError = require('assertion-error');
|
||
|
||
/*!
|
||
* Utils for plugins (not exported)
|
||
*/
|
||
|
||
var util = require('./chai/utils');
|
||
|
||
/**
|
||
* # .use(function)
|
||
*
|
||
* Provides a way to extend the internals of Chai
|
||
*
|
||
* @param {Function}
|
||
* @returns {this} for chaining
|
||
* @api public
|
||
*/
|
||
|
||
exports.use = function (fn) {
|
||
if (!~used.indexOf(fn)) {
|
||
fn(this, util);
|
||
used.push(fn);
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
/*!
|
||
* Configuration
|
||
*/
|
||
|
||
var config = require('./chai/config');
|
||
exports.config = config;
|
||
|
||
/*!
|
||
* Primary `Assertion` prototype
|
||
*/
|
||
|
||
var assertion = require('./chai/assertion');
|
||
exports.use(assertion);
|
||
|
||
/*!
|
||
* Core Assertions
|
||
*/
|
||
|
||
var core = require('./chai/core/assertions');
|
||
exports.use(core);
|
||
|
||
/*!
|
||
* Expect interface
|
||
*/
|
||
|
||
var expect = require('./chai/interface/expect');
|
||
exports.use(expect);
|
||
|
||
/*!
|
||
* Should interface
|
||
*/
|
||
|
||
var should = require('./chai/interface/should');
|
||
exports.use(should);
|
||
|
||
/*!
|
||
* Assert interface
|
||
*/
|
||
|
||
var assert = require('./chai/interface/assert');
|
||
exports.use(assert);
|
||
|
||
},{"./chai/assertion":16,"./chai/config":17,"./chai/core/assertions":18,"./chai/interface/assert":19,"./chai/interface/expect":20,"./chai/interface/should":21,"./chai/utils":32,"assertion-error":41}],16:[function(require,module,exports){
|
||
/*!
|
||
* chai
|
||
* http://chaijs.com
|
||
* Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
var config = require('./config');
|
||
|
||
module.exports = function (_chai, util) {
|
||
/*!
|
||
* Module dependencies.
|
||
*/
|
||
|
||
var AssertionError = _chai.AssertionError
|
||
, flag = util.flag;
|
||
|
||
/*!
|
||
* Module export.
|
||
*/
|
||
|
||
_chai.Assertion = Assertion;
|
||
|
||
/*!
|
||
* Assertion Constructor
|
||
*
|
||
* Creates object for chaining.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
function Assertion (obj, msg, stack) {
|
||
flag(this, 'ssfi', stack || arguments.callee);
|
||
flag(this, 'object', obj);
|
||
flag(this, 'message', msg);
|
||
}
|
||
|
||
Object.defineProperty(Assertion, 'includeStack', {
|
||
get: function() {
|
||
console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
|
||
return config.includeStack;
|
||
},
|
||
set: function(value) {
|
||
console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
|
||
config.includeStack = value;
|
||
}
|
||
});
|
||
|
||
Object.defineProperty(Assertion, 'showDiff', {
|
||
get: function() {
|
||
console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
|
||
return config.showDiff;
|
||
},
|
||
set: function(value) {
|
||
console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
|
||
config.showDiff = value;
|
||
}
|
||
});
|
||
|
||
Assertion.addProperty = function (name, fn) {
|
||
util.addProperty(this.prototype, name, fn);
|
||
};
|
||
|
||
Assertion.addMethod = function (name, fn) {
|
||
util.addMethod(this.prototype, name, fn);
|
||
};
|
||
|
||
Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
|
||
util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
|
||
};
|
||
|
||
Assertion.overwriteProperty = function (name, fn) {
|
||
util.overwriteProperty(this.prototype, name, fn);
|
||
};
|
||
|
||
Assertion.overwriteMethod = function (name, fn) {
|
||
util.overwriteMethod(this.prototype, name, fn);
|
||
};
|
||
|
||
Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {
|
||
util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);
|
||
};
|
||
|
||
/*!
|
||
* ### .assert(expression, message, negateMessage, expected, actual)
|
||
*
|
||
* Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
|
||
*
|
||
* @name assert
|
||
* @param {Philosophical} expression to be tested
|
||
* @param {String} message to display if fails
|
||
* @param {String} negatedMessage to display if negated expression fails
|
||
* @param {Mixed} expected value (remember to check for negation)
|
||
* @param {Mixed} actual (optional) will default to `this.obj`
|
||
* @api private
|
||
*/
|
||
|
||
Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {
|
||
var ok = util.test(this, arguments);
|
||
if (true !== showDiff) showDiff = false;
|
||
if (true !== config.showDiff) showDiff = false;
|
||
|
||
if (!ok) {
|
||
var msg = util.getMessage(this, arguments)
|
||
, actual = util.getActual(this, arguments);
|
||
throw new AssertionError(msg, {
|
||
actual: actual
|
||
, expected: expected
|
||
, showDiff: showDiff
|
||
}, (config.includeStack) ? this.assert : flag(this, 'ssfi'));
|
||
}
|
||
};
|
||
|
||
/*!
|
||
* ### ._obj
|
||
*
|
||
* Quick reference to stored `actual` value for plugin developers.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Object.defineProperty(Assertion.prototype, '_obj',
|
||
{ get: function () {
|
||
return flag(this, 'object');
|
||
}
|
||
, set: function (val) {
|
||
flag(this, 'object', val);
|
||
}
|
||
});
|
||
};
|
||
|
||
},{"./config":17}],17:[function(require,module,exports){
|
||
module.exports = {
|
||
|
||
/**
|
||
* ### config.includeStack
|
||
*
|
||
* User configurable property, influences whether stack trace
|
||
* is included in Assertion error message. Default of false
|
||
* suppresses stack trace in the error message.
|
||
*
|
||
* chai.config.includeStack = true; // enable stack on error
|
||
*
|
||
* @param {Boolean}
|
||
* @api public
|
||
*/
|
||
|
||
includeStack: false,
|
||
|
||
/**
|
||
* ### config.showDiff
|
||
*
|
||
* User configurable property, influences whether or not
|
||
* the `showDiff` flag should be included in the thrown
|
||
* AssertionErrors. `false` will always be `false`; `true`
|
||
* will be true when the assertion has requested a diff
|
||
* be shown.
|
||
*
|
||
* @param {Boolean}
|
||
* @api public
|
||
*/
|
||
|
||
showDiff: true,
|
||
|
||
/**
|
||
* ### config.truncateThreshold
|
||
*
|
||
* User configurable property, sets length threshold for actual and
|
||
* expected values in assertion errors. If this threshold is exceeded,
|
||
* the value is truncated.
|
||
*
|
||
* Set it to zero if you want to disable truncating altogether.
|
||
*
|
||
* chai.config.truncateThreshold = 0; // disable truncating
|
||
*
|
||
* @param {Number}
|
||
* @api public
|
||
*/
|
||
|
||
truncateThreshold: 40
|
||
|
||
};
|
||
|
||
},{}],18:[function(require,module,exports){
|
||
/*!
|
||
* chai
|
||
* http://chaijs.com
|
||
* Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
module.exports = function (chai, _) {
|
||
var Assertion = chai.Assertion
|
||
, toString = Object.prototype.toString
|
||
, flag = _.flag;
|
||
|
||
/**
|
||
* ### Language Chains
|
||
*
|
||
* The following are provided as chainable getters to
|
||
* improve the readability of your assertions. They
|
||
* do not provide testing capabilities unless they
|
||
* have been overwritten by a plugin.
|
||
*
|
||
* **Chains**
|
||
*
|
||
* - to
|
||
* - be
|
||
* - been
|
||
* - is
|
||
* - that
|
||
* - and
|
||
* - has
|
||
* - have
|
||
* - with
|
||
* - at
|
||
* - of
|
||
* - same
|
||
*
|
||
* @name language chains
|
||
* @api public
|
||
*/
|
||
|
||
[ 'to', 'be', 'been'
|
||
, 'is', 'and', 'has', 'have'
|
||
, 'with', 'that', 'at'
|
||
, 'of', 'same' ].forEach(function (chain) {
|
||
Assertion.addProperty(chain, function () {
|
||
return this;
|
||
});
|
||
});
|
||
|
||
/**
|
||
* ### .not
|
||
*
|
||
* Negates any of assertions following in the chain.
|
||
*
|
||
* expect(foo).to.not.equal('bar');
|
||
* expect(goodFn).to.not.throw(Error);
|
||
* expect({ foo: 'baz' }).to.have.property('foo')
|
||
* .and.not.equal('bar');
|
||
*
|
||
* @name not
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addProperty('not', function () {
|
||
flag(this, 'negate', true);
|
||
});
|
||
|
||
/**
|
||
* ### .deep
|
||
*
|
||
* Sets the `deep` flag, later used by the `equal` and
|
||
* `property` assertions.
|
||
*
|
||
* expect(foo).to.deep.equal({ bar: 'baz' });
|
||
* expect({ foo: { bar: { baz: 'quux' } } })
|
||
* .to.have.deep.property('foo.bar.baz', 'quux');
|
||
*
|
||
* @name deep
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addProperty('deep', function () {
|
||
flag(this, 'deep', true);
|
||
});
|
||
|
||
/**
|
||
* ### .a(type)
|
||
*
|
||
* The `a` and `an` assertions are aliases that can be
|
||
* used either as language chains or to assert a value's
|
||
* type.
|
||
*
|
||
* // typeof
|
||
* expect('test').to.be.a('string');
|
||
* expect({ foo: 'bar' }).to.be.an('object');
|
||
* expect(null).to.be.a('null');
|
||
* expect(undefined).to.be.an('undefined');
|
||
*
|
||
* // language chain
|
||
* expect(foo).to.be.an.instanceof(Foo);
|
||
*
|
||
* @name a
|
||
* @alias an
|
||
* @param {String} type
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
function an (type, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
type = type.toLowerCase();
|
||
var obj = flag(this, 'object')
|
||
, article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';
|
||
|
||
this.assert(
|
||
type === _.type(obj)
|
||
, 'expected #{this} to be ' + article + type
|
||
, 'expected #{this} not to be ' + article + type
|
||
);
|
||
}
|
||
|
||
Assertion.addChainableMethod('an', an);
|
||
Assertion.addChainableMethod('a', an);
|
||
|
||
/**
|
||
* ### .include(value)
|
||
*
|
||
* The `include` and `contain` assertions can be used as either property
|
||
* based language chains or as methods to assert the inclusion of an object
|
||
* in an array or a substring in a string. When used as language chains,
|
||
* they toggle the `contain` flag for the `keys` assertion.
|
||
*
|
||
* expect([1,2,3]).to.include(2);
|
||
* expect('foobar').to.contain('foo');
|
||
* expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');
|
||
*
|
||
* @name include
|
||
* @alias contain
|
||
* @param {Object|String|Number} obj
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
function includeChainingBehavior () {
|
||
flag(this, 'contains', true);
|
||
}
|
||
|
||
function include (val, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
var expected = false;
|
||
if (_.type(obj) === 'array' && _.type(val) === 'object') {
|
||
for (var i in obj) {
|
||
if (_.eql(obj[i], val)) {
|
||
expected = true;
|
||
break;
|
||
}
|
||
}
|
||
} else if (_.type(val) === 'object') {
|
||
if (!flag(this, 'negate')) {
|
||
for (var k in val) new Assertion(obj).property(k, val[k]);
|
||
return;
|
||
}
|
||
var subset = {}
|
||
for (var k in val) subset[k] = obj[k]
|
||
expected = _.eql(subset, val);
|
||
} else {
|
||
expected = obj && ~obj.indexOf(val)
|
||
}
|
||
this.assert(
|
||
expected
|
||
, 'expected #{this} to include ' + _.inspect(val)
|
||
, 'expected #{this} to not include ' + _.inspect(val));
|
||
}
|
||
|
||
Assertion.addChainableMethod('include', include, includeChainingBehavior);
|
||
Assertion.addChainableMethod('contain', include, includeChainingBehavior);
|
||
|
||
/**
|
||
* ### .ok
|
||
*
|
||
* Asserts that the target is truthy.
|
||
*
|
||
* expect('everthing').to.be.ok;
|
||
* expect(1).to.be.ok;
|
||
* expect(false).to.not.be.ok;
|
||
* expect(undefined).to.not.be.ok;
|
||
* expect(null).to.not.be.ok;
|
||
*
|
||
* @name ok
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addProperty('ok', function () {
|
||
this.assert(
|
||
flag(this, 'object')
|
||
, 'expected #{this} to be truthy'
|
||
, 'expected #{this} to be falsy');
|
||
});
|
||
|
||
/**
|
||
* ### .true
|
||
*
|
||
* Asserts that the target is `true`.
|
||
*
|
||
* expect(true).to.be.true;
|
||
* expect(1).to.not.be.true;
|
||
*
|
||
* @name true
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addProperty('true', function () {
|
||
this.assert(
|
||
true === flag(this, 'object')
|
||
, 'expected #{this} to be true'
|
||
, 'expected #{this} to be false'
|
||
, this.negate ? false : true
|
||
);
|
||
});
|
||
|
||
/**
|
||
* ### .false
|
||
*
|
||
* Asserts that the target is `false`.
|
||
*
|
||
* expect(false).to.be.false;
|
||
* expect(0).to.not.be.false;
|
||
*
|
||
* @name false
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addProperty('false', function () {
|
||
this.assert(
|
||
false === flag(this, 'object')
|
||
, 'expected #{this} to be false'
|
||
, 'expected #{this} to be true'
|
||
, this.negate ? true : false
|
||
);
|
||
});
|
||
|
||
/**
|
||
* ### .null
|
||
*
|
||
* Asserts that the target is `null`.
|
||
*
|
||
* expect(null).to.be.null;
|
||
* expect(undefined).not.to.be.null;
|
||
*
|
||
* @name null
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addProperty('null', function () {
|
||
this.assert(
|
||
null === flag(this, 'object')
|
||
, 'expected #{this} to be null'
|
||
, 'expected #{this} not to be null'
|
||
);
|
||
});
|
||
|
||
/**
|
||
* ### .undefined
|
||
*
|
||
* Asserts that the target is `undefined`.
|
||
*
|
||
* expect(undefined).to.be.undefined;
|
||
* expect(null).to.not.be.undefined;
|
||
*
|
||
* @name undefined
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addProperty('undefined', function () {
|
||
this.assert(
|
||
undefined === flag(this, 'object')
|
||
, 'expected #{this} to be undefined'
|
||
, 'expected #{this} not to be undefined'
|
||
);
|
||
});
|
||
|
||
/**
|
||
* ### .exist
|
||
*
|
||
* Asserts that the target is neither `null` nor `undefined`.
|
||
*
|
||
* var foo = 'hi'
|
||
* , bar = null
|
||
* , baz;
|
||
*
|
||
* expect(foo).to.exist;
|
||
* expect(bar).to.not.exist;
|
||
* expect(baz).to.not.exist;
|
||
*
|
||
* @name exist
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addProperty('exist', function () {
|
||
this.assert(
|
||
null != flag(this, 'object')
|
||
, 'expected #{this} to exist'
|
||
, 'expected #{this} to not exist'
|
||
);
|
||
});
|
||
|
||
|
||
/**
|
||
* ### .empty
|
||
*
|
||
* Asserts that the target's length is `0`. For arrays, it checks
|
||
* the `length` property. For objects, it gets the count of
|
||
* enumerable keys.
|
||
*
|
||
* expect([]).to.be.empty;
|
||
* expect('').to.be.empty;
|
||
* expect({}).to.be.empty;
|
||
*
|
||
* @name empty
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addProperty('empty', function () {
|
||
var obj = flag(this, 'object')
|
||
, expected = obj;
|
||
|
||
if (Array.isArray(obj) || 'string' === typeof object) {
|
||
expected = obj.length;
|
||
} else if (typeof obj === 'object') {
|
||
expected = Object.keys(obj).length;
|
||
}
|
||
|
||
this.assert(
|
||
!expected
|
||
, 'expected #{this} to be empty'
|
||
, 'expected #{this} not to be empty'
|
||
);
|
||
});
|
||
|
||
/**
|
||
* ### .arguments
|
||
*
|
||
* Asserts that the target is an arguments object.
|
||
*
|
||
* function test () {
|
||
* expect(arguments).to.be.arguments;
|
||
* }
|
||
*
|
||
* @name arguments
|
||
* @alias Arguments
|
||
* @api public
|
||
*/
|
||
|
||
function checkArguments () {
|
||
var obj = flag(this, 'object')
|
||
, type = Object.prototype.toString.call(obj);
|
||
this.assert(
|
||
'[object Arguments]' === type
|
||
, 'expected #{this} to be arguments but got ' + type
|
||
, 'expected #{this} to not be arguments'
|
||
);
|
||
}
|
||
|
||
Assertion.addProperty('arguments', checkArguments);
|
||
Assertion.addProperty('Arguments', checkArguments);
|
||
|
||
/**
|
||
* ### .equal(value)
|
||
*
|
||
* Asserts that the target is strictly equal (`===`) to `value`.
|
||
* Alternately, if the `deep` flag is set, asserts that
|
||
* the target is deeply equal to `value`.
|
||
*
|
||
* expect('hello').to.equal('hello');
|
||
* expect(42).to.equal(42);
|
||
* expect(1).to.not.equal(true);
|
||
* expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });
|
||
* expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });
|
||
*
|
||
* @name equal
|
||
* @alias equals
|
||
* @alias eq
|
||
* @alias deep.equal
|
||
* @param {Mixed} value
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
function assertEqual (val, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
if (flag(this, 'deep')) {
|
||
return this.eql(val);
|
||
} else {
|
||
this.assert(
|
||
val === obj
|
||
, 'expected #{this} to equal #{exp}'
|
||
, 'expected #{this} to not equal #{exp}'
|
||
, val
|
||
, this._obj
|
||
, true
|
||
);
|
||
}
|
||
}
|
||
|
||
Assertion.addMethod('equal', assertEqual);
|
||
Assertion.addMethod('equals', assertEqual);
|
||
Assertion.addMethod('eq', assertEqual);
|
||
|
||
/**
|
||
* ### .eql(value)
|
||
*
|
||
* Asserts that the target is deeply equal to `value`.
|
||
*
|
||
* expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
|
||
* expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);
|
||
*
|
||
* @name eql
|
||
* @alias eqls
|
||
* @param {Mixed} value
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
function assertEql(obj, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
this.assert(
|
||
_.eql(obj, flag(this, 'object'))
|
||
, 'expected #{this} to deeply equal #{exp}'
|
||
, 'expected #{this} to not deeply equal #{exp}'
|
||
, obj
|
||
, this._obj
|
||
, true
|
||
);
|
||
}
|
||
|
||
Assertion.addMethod('eql', assertEql);
|
||
Assertion.addMethod('eqls', assertEql);
|
||
|
||
/**
|
||
* ### .above(value)
|
||
*
|
||
* Asserts that the target is greater than `value`.
|
||
*
|
||
* expect(10).to.be.above(5);
|
||
*
|
||
* Can also be used in conjunction with `length` to
|
||
* assert a minimum length. The benefit being a
|
||
* more informative error message than if the length
|
||
* was supplied directly.
|
||
*
|
||
* expect('foo').to.have.length.above(2);
|
||
* expect([ 1, 2, 3 ]).to.have.length.above(2);
|
||
*
|
||
* @name above
|
||
* @alias gt
|
||
* @alias greaterThan
|
||
* @param {Number} value
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
function assertAbove (n, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
if (flag(this, 'doLength')) {
|
||
new Assertion(obj, msg).to.have.property('length');
|
||
var len = obj.length;
|
||
this.assert(
|
||
len > n
|
||
, 'expected #{this} to have a length above #{exp} but got #{act}'
|
||
, 'expected #{this} to not have a length above #{exp}'
|
||
, n
|
||
, len
|
||
);
|
||
} else {
|
||
this.assert(
|
||
obj > n
|
||
, 'expected #{this} to be above ' + n
|
||
, 'expected #{this} to be at most ' + n
|
||
);
|
||
}
|
||
}
|
||
|
||
Assertion.addMethod('above', assertAbove);
|
||
Assertion.addMethod('gt', assertAbove);
|
||
Assertion.addMethod('greaterThan', assertAbove);
|
||
|
||
/**
|
||
* ### .least(value)
|
||
*
|
||
* Asserts that the target is greater than or equal to `value`.
|
||
*
|
||
* expect(10).to.be.at.least(10);
|
||
*
|
||
* Can also be used in conjunction with `length` to
|
||
* assert a minimum length. The benefit being a
|
||
* more informative error message than if the length
|
||
* was supplied directly.
|
||
*
|
||
* expect('foo').to.have.length.of.at.least(2);
|
||
* expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);
|
||
*
|
||
* @name least
|
||
* @alias gte
|
||
* @param {Number} value
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
function assertLeast (n, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
if (flag(this, 'doLength')) {
|
||
new Assertion(obj, msg).to.have.property('length');
|
||
var len = obj.length;
|
||
this.assert(
|
||
len >= n
|
||
, 'expected #{this} to have a length at least #{exp} but got #{act}'
|
||
, 'expected #{this} to have a length below #{exp}'
|
||
, n
|
||
, len
|
||
);
|
||
} else {
|
||
this.assert(
|
||
obj >= n
|
||
, 'expected #{this} to be at least ' + n
|
||
, 'expected #{this} to be below ' + n
|
||
);
|
||
}
|
||
}
|
||
|
||
Assertion.addMethod('least', assertLeast);
|
||
Assertion.addMethod('gte', assertLeast);
|
||
|
||
/**
|
||
* ### .below(value)
|
||
*
|
||
* Asserts that the target is less than `value`.
|
||
*
|
||
* expect(5).to.be.below(10);
|
||
*
|
||
* Can also be used in conjunction with `length` to
|
||
* assert a maximum length. The benefit being a
|
||
* more informative error message than if the length
|
||
* was supplied directly.
|
||
*
|
||
* expect('foo').to.have.length.below(4);
|
||
* expect([ 1, 2, 3 ]).to.have.length.below(4);
|
||
*
|
||
* @name below
|
||
* @alias lt
|
||
* @alias lessThan
|
||
* @param {Number} value
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
function assertBelow (n, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
if (flag(this, 'doLength')) {
|
||
new Assertion(obj, msg).to.have.property('length');
|
||
var len = obj.length;
|
||
this.assert(
|
||
len < n
|
||
, 'expected #{this} to have a length below #{exp} but got #{act}'
|
||
, 'expected #{this} to not have a length below #{exp}'
|
||
, n
|
||
, len
|
||
);
|
||
} else {
|
||
this.assert(
|
||
obj < n
|
||
, 'expected #{this} to be below ' + n
|
||
, 'expected #{this} to be at least ' + n
|
||
);
|
||
}
|
||
}
|
||
|
||
Assertion.addMethod('below', assertBelow);
|
||
Assertion.addMethod('lt', assertBelow);
|
||
Assertion.addMethod('lessThan', assertBelow);
|
||
|
||
/**
|
||
* ### .most(value)
|
||
*
|
||
* Asserts that the target is less than or equal to `value`.
|
||
*
|
||
* expect(5).to.be.at.most(5);
|
||
*
|
||
* Can also be used in conjunction with `length` to
|
||
* assert a maximum length. The benefit being a
|
||
* more informative error message than if the length
|
||
* was supplied directly.
|
||
*
|
||
* expect('foo').to.have.length.of.at.most(4);
|
||
* expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);
|
||
*
|
||
* @name most
|
||
* @alias lte
|
||
* @param {Number} value
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
function assertMost (n, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
if (flag(this, 'doLength')) {
|
||
new Assertion(obj, msg).to.have.property('length');
|
||
var len = obj.length;
|
||
this.assert(
|
||
len <= n
|
||
, 'expected #{this} to have a length at most #{exp} but got #{act}'
|
||
, 'expected #{this} to have a length above #{exp}'
|
||
, n
|
||
, len
|
||
);
|
||
} else {
|
||
this.assert(
|
||
obj <= n
|
||
, 'expected #{this} to be at most ' + n
|
||
, 'expected #{this} to be above ' + n
|
||
);
|
||
}
|
||
}
|
||
|
||
Assertion.addMethod('most', assertMost);
|
||
Assertion.addMethod('lte', assertMost);
|
||
|
||
/**
|
||
* ### .within(start, finish)
|
||
*
|
||
* Asserts that the target is within a range.
|
||
*
|
||
* expect(7).to.be.within(5,10);
|
||
*
|
||
* Can also be used in conjunction with `length` to
|
||
* assert a length range. The benefit being a
|
||
* more informative error message than if the length
|
||
* was supplied directly.
|
||
*
|
||
* expect('foo').to.have.length.within(2,4);
|
||
* expect([ 1, 2, 3 ]).to.have.length.within(2,4);
|
||
*
|
||
* @name within
|
||
* @param {Number} start lowerbound inclusive
|
||
* @param {Number} finish upperbound inclusive
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addMethod('within', function (start, finish, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object')
|
||
, range = start + '..' + finish;
|
||
if (flag(this, 'doLength')) {
|
||
new Assertion(obj, msg).to.have.property('length');
|
||
var len = obj.length;
|
||
this.assert(
|
||
len >= start && len <= finish
|
||
, 'expected #{this} to have a length within ' + range
|
||
, 'expected #{this} to not have a length within ' + range
|
||
);
|
||
} else {
|
||
this.assert(
|
||
obj >= start && obj <= finish
|
||
, 'expected #{this} to be within ' + range
|
||
, 'expected #{this} to not be within ' + range
|
||
);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* ### .instanceof(constructor)
|
||
*
|
||
* Asserts that the target is an instance of `constructor`.
|
||
*
|
||
* var Tea = function (name) { this.name = name; }
|
||
* , Chai = new Tea('chai');
|
||
*
|
||
* expect(Chai).to.be.an.instanceof(Tea);
|
||
* expect([ 1, 2, 3 ]).to.be.instanceof(Array);
|
||
*
|
||
* @name instanceof
|
||
* @param {Constructor} constructor
|
||
* @param {String} message _optional_
|
||
* @alias instanceOf
|
||
* @api public
|
||
*/
|
||
|
||
function assertInstanceOf (constructor, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var name = _.getName(constructor);
|
||
this.assert(
|
||
flag(this, 'object') instanceof constructor
|
||
, 'expected #{this} to be an instance of ' + name
|
||
, 'expected #{this} to not be an instance of ' + name
|
||
);
|
||
};
|
||
|
||
Assertion.addMethod('instanceof', assertInstanceOf);
|
||
Assertion.addMethod('instanceOf', assertInstanceOf);
|
||
|
||
/**
|
||
* ### .property(name, [value])
|
||
*
|
||
* Asserts that the target has a property `name`, optionally asserting that
|
||
* the value of that property is strictly equal to `value`.
|
||
* If the `deep` flag is set, you can use dot- and bracket-notation for deep
|
||
* references into objects and arrays.
|
||
*
|
||
* // simple referencing
|
||
* var obj = { foo: 'bar' };
|
||
* expect(obj).to.have.property('foo');
|
||
* expect(obj).to.have.property('foo', 'bar');
|
||
*
|
||
* // deep referencing
|
||
* var deepObj = {
|
||
* green: { tea: 'matcha' }
|
||
* , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]
|
||
* };
|
||
|
||
* expect(deepObj).to.have.deep.property('green.tea', 'matcha');
|
||
* expect(deepObj).to.have.deep.property('teas[1]', 'matcha');
|
||
* expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');
|
||
*
|
||
* You can also use an array as the starting point of a `deep.property`
|
||
* assertion, or traverse nested arrays.
|
||
*
|
||
* var arr = [
|
||
* [ 'chai', 'matcha', 'konacha' ]
|
||
* , [ { tea: 'chai' }
|
||
* , { tea: 'matcha' }
|
||
* , { tea: 'konacha' } ]
|
||
* ];
|
||
*
|
||
* expect(arr).to.have.deep.property('[0][1]', 'matcha');
|
||
* expect(arr).to.have.deep.property('[1][2].tea', 'konacha');
|
||
*
|
||
* Furthermore, `property` changes the subject of the assertion
|
||
* to be the value of that property from the original object. This
|
||
* permits for further chainable assertions on that property.
|
||
*
|
||
* expect(obj).to.have.property('foo')
|
||
* .that.is.a('string');
|
||
* expect(deepObj).to.have.property('green')
|
||
* .that.is.an('object')
|
||
* .that.deep.equals({ tea: 'matcha' });
|
||
* expect(deepObj).to.have.property('teas')
|
||
* .that.is.an('array')
|
||
* .with.deep.property('[2]')
|
||
* .that.deep.equals({ tea: 'konacha' });
|
||
*
|
||
* @name property
|
||
* @alias deep.property
|
||
* @param {String} name
|
||
* @param {Mixed} value (optional)
|
||
* @param {String} message _optional_
|
||
* @returns value of property for chaining
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addMethod('property', function (name, val, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
|
||
var descriptor = flag(this, 'deep') ? 'deep property ' : 'property '
|
||
, negate = flag(this, 'negate')
|
||
, obj = flag(this, 'object')
|
||
, value = flag(this, 'deep')
|
||
? _.getPathValue(name, obj)
|
||
: obj[name];
|
||
|
||
if (negate && undefined !== val) {
|
||
if (undefined === value) {
|
||
msg = (msg != null) ? msg + ': ' : '';
|
||
throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));
|
||
}
|
||
} else {
|
||
this.assert(
|
||
undefined !== value
|
||
, 'expected #{this} to have a ' + descriptor + _.inspect(name)
|
||
, 'expected #{this} to not have ' + descriptor + _.inspect(name));
|
||
}
|
||
|
||
if (undefined !== val) {
|
||
this.assert(
|
||
val === value
|
||
, 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
|
||
, 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'
|
||
, val
|
||
, value
|
||
);
|
||
}
|
||
|
||
flag(this, 'object', value);
|
||
});
|
||
|
||
|
||
/**
|
||
* ### .ownProperty(name)
|
||
*
|
||
* Asserts that the target has an own property `name`.
|
||
*
|
||
* expect('test').to.have.ownProperty('length');
|
||
*
|
||
* @name ownProperty
|
||
* @alias haveOwnProperty
|
||
* @param {String} name
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
function assertOwnProperty (name, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
this.assert(
|
||
obj.hasOwnProperty(name)
|
||
, 'expected #{this} to have own property ' + _.inspect(name)
|
||
, 'expected #{this} to not have own property ' + _.inspect(name)
|
||
);
|
||
}
|
||
|
||
Assertion.addMethod('ownProperty', assertOwnProperty);
|
||
Assertion.addMethod('haveOwnProperty', assertOwnProperty);
|
||
|
||
/**
|
||
* ### .length(value)
|
||
*
|
||
* Asserts that the target's `length` property has
|
||
* the expected value.
|
||
*
|
||
* expect([ 1, 2, 3]).to.have.length(3);
|
||
* expect('foobar').to.have.length(6);
|
||
*
|
||
* Can also be used as a chain precursor to a value
|
||
* comparison for the length property.
|
||
*
|
||
* expect('foo').to.have.length.above(2);
|
||
* expect([ 1, 2, 3 ]).to.have.length.above(2);
|
||
* expect('foo').to.have.length.below(4);
|
||
* expect([ 1, 2, 3 ]).to.have.length.below(4);
|
||
* expect('foo').to.have.length.within(2,4);
|
||
* expect([ 1, 2, 3 ]).to.have.length.within(2,4);
|
||
*
|
||
* @name length
|
||
* @alias lengthOf
|
||
* @param {Number} length
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
function assertLengthChain () {
|
||
flag(this, 'doLength', true);
|
||
}
|
||
|
||
function assertLength (n, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
new Assertion(obj, msg).to.have.property('length');
|
||
var len = obj.length;
|
||
|
||
this.assert(
|
||
len == n
|
||
, 'expected #{this} to have a length of #{exp} but got #{act}'
|
||
, 'expected #{this} to not have a length of #{act}'
|
||
, n
|
||
, len
|
||
);
|
||
}
|
||
|
||
Assertion.addChainableMethod('length', assertLength, assertLengthChain);
|
||
Assertion.addMethod('lengthOf', assertLength, assertLengthChain);
|
||
|
||
/**
|
||
* ### .match(regexp)
|
||
*
|
||
* Asserts that the target matches a regular expression.
|
||
*
|
||
* expect('foobar').to.match(/^foo/);
|
||
*
|
||
* @name match
|
||
* @param {RegExp} RegularExpression
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addMethod('match', function (re, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
this.assert(
|
||
re.exec(obj)
|
||
, 'expected #{this} to match ' + re
|
||
, 'expected #{this} not to match ' + re
|
||
);
|
||
});
|
||
|
||
/**
|
||
* ### .string(string)
|
||
*
|
||
* Asserts that the string target contains another string.
|
||
*
|
||
* expect('foobar').to.have.string('bar');
|
||
*
|
||
* @name string
|
||
* @param {String} string
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addMethod('string', function (str, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
new Assertion(obj, msg).is.a('string');
|
||
|
||
this.assert(
|
||
~obj.indexOf(str)
|
||
, 'expected #{this} to contain ' + _.inspect(str)
|
||
, 'expected #{this} to not contain ' + _.inspect(str)
|
||
);
|
||
});
|
||
|
||
|
||
/**
|
||
* ### .keys(key1, [key2], [...])
|
||
*
|
||
* Asserts that the target has exactly the given keys, or
|
||
* asserts the inclusion of some keys when using the
|
||
* `include` or `contain` modifiers.
|
||
*
|
||
* expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
|
||
* expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
|
||
*
|
||
* @name keys
|
||
* @alias key
|
||
* @param {String...|Array} keys
|
||
* @api public
|
||
*/
|
||
|
||
function assertKeys (keys) {
|
||
var obj = flag(this, 'object')
|
||
, str
|
||
, ok = true;
|
||
|
||
keys = keys instanceof Array
|
||
? keys
|
||
: Array.prototype.slice.call(arguments);
|
||
|
||
if (!keys.length) throw new Error('keys required');
|
||
|
||
var actual = Object.keys(obj)
|
||
, len = keys.length;
|
||
|
||
// Inclusion
|
||
ok = keys.every(function(key){
|
||
return ~actual.indexOf(key);
|
||
});
|
||
|
||
// Strict
|
||
if (!flag(this, 'negate') && !flag(this, 'contains')) {
|
||
ok = ok && keys.length == actual.length;
|
||
}
|
||
|
||
// Key string
|
||
if (len > 1) {
|
||
keys = keys.map(function(key){
|
||
return _.inspect(key);
|
||
});
|
||
var last = keys.pop();
|
||
str = keys.join(', ') + ', and ' + last;
|
||
} else {
|
||
str = _.inspect(keys[0]);
|
||
}
|
||
|
||
// Form
|
||
str = (len > 1 ? 'keys ' : 'key ') + str;
|
||
|
||
// Have / include
|
||
str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
|
||
|
||
// Assertion
|
||
this.assert(
|
||
ok
|
||
, 'expected #{this} to ' + str
|
||
, 'expected #{this} to not ' + str
|
||
);
|
||
}
|
||
|
||
Assertion.addMethod('keys', assertKeys);
|
||
Assertion.addMethod('key', assertKeys);
|
||
|
||
/**
|
||
* ### .throw(constructor)
|
||
*
|
||
* Asserts that the function target will throw a specific error, or specific type of error
|
||
* (as determined using `instanceof`), optionally with a RegExp or string inclusion test
|
||
* for the error's message.
|
||
*
|
||
* var err = new ReferenceError('This is a bad function.');
|
||
* var fn = function () { throw err; }
|
||
* expect(fn).to.throw(ReferenceError);
|
||
* expect(fn).to.throw(Error);
|
||
* expect(fn).to.throw(/bad function/);
|
||
* expect(fn).to.not.throw('good function');
|
||
* expect(fn).to.throw(ReferenceError, /bad function/);
|
||
* expect(fn).to.throw(err);
|
||
* expect(fn).to.not.throw(new RangeError('Out of range.'));
|
||
*
|
||
* Please note that when a throw expectation is negated, it will check each
|
||
* parameter independently, starting with error constructor type. The appropriate way
|
||
* to check for the existence of a type of error but for a message that does not match
|
||
* is to use `and`.
|
||
*
|
||
* expect(fn).to.throw(ReferenceError)
|
||
* .and.not.throw(/good function/);
|
||
*
|
||
* @name throw
|
||
* @alias throws
|
||
* @alias Throw
|
||
* @param {ErrorConstructor} constructor
|
||
* @param {String|RegExp} expected error message
|
||
* @param {String} message _optional_
|
||
* @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
|
||
* @returns error for chaining (null if no error)
|
||
* @api public
|
||
*/
|
||
|
||
function assertThrows (constructor, errMsg, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
new Assertion(obj, msg).is.a('function');
|
||
|
||
var thrown = false
|
||
, desiredError = null
|
||
, name = null
|
||
, thrownError = null;
|
||
|
||
if (arguments.length === 0) {
|
||
errMsg = null;
|
||
constructor = null;
|
||
} else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
|
||
errMsg = constructor;
|
||
constructor = null;
|
||
} else if (constructor && constructor instanceof Error) {
|
||
desiredError = constructor;
|
||
constructor = null;
|
||
errMsg = null;
|
||
} else if (typeof constructor === 'function') {
|
||
name = constructor.prototype.name || constructor.name;
|
||
if (name === 'Error' && constructor !== Error) {
|
||
name = (new constructor()).name;
|
||
}
|
||
} else {
|
||
constructor = null;
|
||
}
|
||
|
||
try {
|
||
obj();
|
||
} catch (err) {
|
||
// first, check desired error
|
||
if (desiredError) {
|
||
this.assert(
|
||
err === desiredError
|
||
, 'expected #{this} to throw #{exp} but #{act} was thrown'
|
||
, 'expected #{this} to not throw #{exp}'
|
||
, (desiredError instanceof Error ? desiredError.toString() : desiredError)
|
||
, (err instanceof Error ? err.toString() : err)
|
||
);
|
||
|
||
flag(this, 'object', err);
|
||
return this;
|
||
}
|
||
|
||
// next, check constructor
|
||
if (constructor) {
|
||
this.assert(
|
||
err instanceof constructor
|
||
, 'expected #{this} to throw #{exp} but #{act} was thrown'
|
||
, 'expected #{this} to not throw #{exp} but #{act} was thrown'
|
||
, name
|
||
, (err instanceof Error ? err.toString() : err)
|
||
);
|
||
|
||
if (!errMsg) {
|
||
flag(this, 'object', err);
|
||
return this;
|
||
}
|
||
}
|
||
|
||
// next, check message
|
||
var message = 'object' === _.type(err) && "message" in err
|
||
? err.message
|
||
: '' + err;
|
||
|
||
if ((message != null) && errMsg && errMsg instanceof RegExp) {
|
||
this.assert(
|
||
errMsg.exec(message)
|
||
, 'expected #{this} to throw error matching #{exp} but got #{act}'
|
||
, 'expected #{this} to throw error not matching #{exp}'
|
||
, errMsg
|
||
, message
|
||
);
|
||
|
||
flag(this, 'object', err);
|
||
return this;
|
||
} else if ((message != null) && errMsg && 'string' === typeof errMsg) {
|
||
this.assert(
|
||
~message.indexOf(errMsg)
|
||
, 'expected #{this} to throw error including #{exp} but got #{act}'
|
||
, 'expected #{this} to throw error not including #{act}'
|
||
, errMsg
|
||
, message
|
||
);
|
||
|
||
flag(this, 'object', err);
|
||
return this;
|
||
} else {
|
||
thrown = true;
|
||
thrownError = err;
|
||
}
|
||
}
|
||
|
||
var actuallyGot = ''
|
||
, expectedThrown = name !== null
|
||
? name
|
||
: desiredError
|
||
? '#{exp}' //_.inspect(desiredError)
|
||
: 'an error';
|
||
|
||
if (thrown) {
|
||
actuallyGot = ' but #{act} was thrown'
|
||
}
|
||
|
||
this.assert(
|
||
thrown === true
|
||
, 'expected #{this} to throw ' + expectedThrown + actuallyGot
|
||
, 'expected #{this} to not throw ' + expectedThrown + actuallyGot
|
||
, (desiredError instanceof Error ? desiredError.toString() : desiredError)
|
||
, (thrownError instanceof Error ? thrownError.toString() : thrownError)
|
||
);
|
||
|
||
flag(this, 'object', thrownError);
|
||
};
|
||
|
||
Assertion.addMethod('throw', assertThrows);
|
||
Assertion.addMethod('throws', assertThrows);
|
||
Assertion.addMethod('Throw', assertThrows);
|
||
|
||
/**
|
||
* ### .respondTo(method)
|
||
*
|
||
* Asserts that the object or class target will respond to a method.
|
||
*
|
||
* Klass.prototype.bar = function(){};
|
||
* expect(Klass).to.respondTo('bar');
|
||
* expect(obj).to.respondTo('bar');
|
||
*
|
||
* To check if a constructor will respond to a static function,
|
||
* set the `itself` flag.
|
||
*
|
||
* Klass.baz = function(){};
|
||
* expect(Klass).itself.to.respondTo('baz');
|
||
*
|
||
* @name respondTo
|
||
* @param {String} method
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addMethod('respondTo', function (method, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object')
|
||
, itself = flag(this, 'itself')
|
||
, context = ('function' === _.type(obj) && !itself)
|
||
? obj.prototype[method]
|
||
: obj[method];
|
||
|
||
this.assert(
|
||
'function' === typeof context
|
||
, 'expected #{this} to respond to ' + _.inspect(method)
|
||
, 'expected #{this} to not respond to ' + _.inspect(method)
|
||
);
|
||
});
|
||
|
||
/**
|
||
* ### .itself
|
||
*
|
||
* Sets the `itself` flag, later used by the `respondTo` assertion.
|
||
*
|
||
* function Foo() {}
|
||
* Foo.bar = function() {}
|
||
* Foo.prototype.baz = function() {}
|
||
*
|
||
* expect(Foo).itself.to.respondTo('bar');
|
||
* expect(Foo).itself.not.to.respondTo('baz');
|
||
*
|
||
* @name itself
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addProperty('itself', function () {
|
||
flag(this, 'itself', true);
|
||
});
|
||
|
||
/**
|
||
* ### .satisfy(method)
|
||
*
|
||
* Asserts that the target passes a given truth test.
|
||
*
|
||
* expect(1).to.satisfy(function(num) { return num > 0; });
|
||
*
|
||
* @name satisfy
|
||
* @param {Function} matcher
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addMethod('satisfy', function (matcher, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
this.assert(
|
||
matcher(obj)
|
||
, 'expected #{this} to satisfy ' + _.objDisplay(matcher)
|
||
, 'expected #{this} to not satisfy' + _.objDisplay(matcher)
|
||
, this.negate ? false : true
|
||
, matcher(obj)
|
||
);
|
||
});
|
||
|
||
/**
|
||
* ### .closeTo(expected, delta)
|
||
*
|
||
* Asserts that the target is equal `expected`, to within a +/- `delta` range.
|
||
*
|
||
* expect(1.5).to.be.closeTo(1, 0.5);
|
||
*
|
||
* @name closeTo
|
||
* @param {Number} expected
|
||
* @param {Number} delta
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addMethod('closeTo', function (expected, delta, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
this.assert(
|
||
Math.abs(obj - expected) <= delta
|
||
, 'expected #{this} to be close to ' + expected + ' +/- ' + delta
|
||
, 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
|
||
);
|
||
});
|
||
|
||
function isSubsetOf(subset, superset, cmp) {
|
||
return subset.every(function(elem) {
|
||
if (!cmp) return superset.indexOf(elem) !== -1;
|
||
|
||
return superset.some(function(elem2) {
|
||
return cmp(elem, elem2);
|
||
});
|
||
})
|
||
}
|
||
|
||
/**
|
||
* ### .members(set)
|
||
*
|
||
* Asserts that the target is a superset of `set`,
|
||
* or that the target and `set` have the same strictly-equal (===) members.
|
||
* Alternately, if the `deep` flag is set, set members are compared for deep
|
||
* equality.
|
||
*
|
||
* expect([1, 2, 3]).to.include.members([3, 2]);
|
||
* expect([1, 2, 3]).to.not.include.members([3, 2, 8]);
|
||
*
|
||
* expect([4, 2]).to.have.members([2, 4]);
|
||
* expect([5, 2]).to.not.have.members([5, 2, 1]);
|
||
*
|
||
* expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);
|
||
*
|
||
* @name members
|
||
* @param {Array} set
|
||
* @param {String} message _optional_
|
||
* @api public
|
||
*/
|
||
|
||
Assertion.addMethod('members', function (subset, msg) {
|
||
if (msg) flag(this, 'message', msg);
|
||
var obj = flag(this, 'object');
|
||
|
||
new Assertion(obj).to.be.an('array');
|
||
new Assertion(subset).to.be.an('array');
|
||
|
||
var cmp = flag(this, 'deep') ? _.eql : undefined;
|
||
|
||
if (flag(this, 'contains')) {
|
||
return this.assert(
|
||
isSubsetOf(subset, obj, cmp)
|
||
, 'expected #{this} to be a superset of #{act}'
|
||
, 'expected #{this} to not be a superset of #{act}'
|
||
, obj
|
||
, subset
|
||
);
|
||
}
|
||
|
||
this.assert(
|
||
isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)
|
||
, 'expected #{this} to have the same members as #{act}'
|
||
, 'expected #{this} to not have the same members as #{act}'
|
||
, obj
|
||
, subset
|
||
);
|
||
});
|
||
};
|
||
|
||
},{}],19:[function(require,module,exports){
|
||
/*!
|
||
* chai
|
||
* Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
|
||
module.exports = function (chai, util) {
|
||
|
||
/*!
|
||
* Chai dependencies.
|
||
*/
|
||
|
||
var Assertion = chai.Assertion
|
||
, flag = util.flag;
|
||
|
||
/*!
|
||
* Module export.
|
||
*/
|
||
|
||
/**
|
||
* ### assert(expression, message)
|
||
*
|
||
* Write your own test expressions.
|
||
*
|
||
* assert('foo' !== 'bar', 'foo is not bar');
|
||
* assert(Array.isArray([]), 'empty arrays are arrays');
|
||
*
|
||
* @param {Mixed} expression to test for truthiness
|
||
* @param {String} message to display on error
|
||
* @name assert
|
||
* @api public
|
||
*/
|
||
|
||
var assert = chai.assert = function (express, errmsg) {
|
||
var test = new Assertion(null, null, chai.assert);
|
||
test.assert(
|
||
express
|
||
, errmsg
|
||
, '[ negation message unavailable ]'
|
||
);
|
||
};
|
||
|
||
/**
|
||
* ### .fail(actual, expected, [message], [operator])
|
||
*
|
||
* Throw a failure. Node.js `assert` module-compatible.
|
||
*
|
||
* @name fail
|
||
* @param {Mixed} actual
|
||
* @param {Mixed} expected
|
||
* @param {String} message
|
||
* @param {String} operator
|
||
* @api public
|
||
*/
|
||
|
||
assert.fail = function (actual, expected, message, operator) {
|
||
message = message || 'assert.fail()';
|
||
throw new chai.AssertionError(message, {
|
||
actual: actual
|
||
, expected: expected
|
||
, operator: operator
|
||
}, assert.fail);
|
||
};
|
||
|
||
/**
|
||
* ### .ok(object, [message])
|
||
*
|
||
* Asserts that `object` is truthy.
|
||
*
|
||
* assert.ok('everything', 'everything is ok');
|
||
* assert.ok(false, 'this will fail');
|
||
*
|
||
* @name ok
|
||
* @param {Mixed} object to test
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.ok = function (val, msg) {
|
||
new Assertion(val, msg).is.ok;
|
||
};
|
||
|
||
/**
|
||
* ### .notOk(object, [message])
|
||
*
|
||
* Asserts that `object` is falsy.
|
||
*
|
||
* assert.notOk('everything', 'this will fail');
|
||
* assert.notOk(false, 'this will pass');
|
||
*
|
||
* @name notOk
|
||
* @param {Mixed} object to test
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.notOk = function (val, msg) {
|
||
new Assertion(val, msg).is.not.ok;
|
||
};
|
||
|
||
/**
|
||
* ### .equal(actual, expected, [message])
|
||
*
|
||
* Asserts non-strict equality (`==`) of `actual` and `expected`.
|
||
*
|
||
* assert.equal(3, '3', '== coerces values to strings');
|
||
*
|
||
* @name equal
|
||
* @param {Mixed} actual
|
||
* @param {Mixed} expected
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.equal = function (act, exp, msg) {
|
||
var test = new Assertion(act, msg, assert.equal);
|
||
|
||
test.assert(
|
||
exp == flag(test, 'object')
|
||
, 'expected #{this} to equal #{exp}'
|
||
, 'expected #{this} to not equal #{act}'
|
||
, exp
|
||
, act
|
||
);
|
||
};
|
||
|
||
/**
|
||
* ### .notEqual(actual, expected, [message])
|
||
*
|
||
* Asserts non-strict inequality (`!=`) of `actual` and `expected`.
|
||
*
|
||
* assert.notEqual(3, 4, 'these numbers are not equal');
|
||
*
|
||
* @name notEqual
|
||
* @param {Mixed} actual
|
||
* @param {Mixed} expected
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.notEqual = function (act, exp, msg) {
|
||
var test = new Assertion(act, msg, assert.notEqual);
|
||
|
||
test.assert(
|
||
exp != flag(test, 'object')
|
||
, 'expected #{this} to not equal #{exp}'
|
||
, 'expected #{this} to equal #{act}'
|
||
, exp
|
||
, act
|
||
);
|
||
};
|
||
|
||
/**
|
||
* ### .strictEqual(actual, expected, [message])
|
||
*
|
||
* Asserts strict equality (`===`) of `actual` and `expected`.
|
||
*
|
||
* assert.strictEqual(true, true, 'these booleans are strictly equal');
|
||
*
|
||
* @name strictEqual
|
||
* @param {Mixed} actual
|
||
* @param {Mixed} expected
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.strictEqual = function (act, exp, msg) {
|
||
new Assertion(act, msg).to.equal(exp);
|
||
};
|
||
|
||
/**
|
||
* ### .notStrictEqual(actual, expected, [message])
|
||
*
|
||
* Asserts strict inequality (`!==`) of `actual` and `expected`.
|
||
*
|
||
* assert.notStrictEqual(3, '3', 'no coercion for strict equality');
|
||
*
|
||
* @name notStrictEqual
|
||
* @param {Mixed} actual
|
||
* @param {Mixed} expected
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.notStrictEqual = function (act, exp, msg) {
|
||
new Assertion(act, msg).to.not.equal(exp);
|
||
};
|
||
|
||
/**
|
||
* ### .deepEqual(actual, expected, [message])
|
||
*
|
||
* Asserts that `actual` is deeply equal to `expected`.
|
||
*
|
||
* assert.deepEqual({ tea: 'green' }, { tea: 'green' });
|
||
*
|
||
* @name deepEqual
|
||
* @param {Mixed} actual
|
||
* @param {Mixed} expected
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.deepEqual = function (act, exp, msg) {
|
||
new Assertion(act, msg).to.eql(exp);
|
||
};
|
||
|
||
/**
|
||
* ### .notDeepEqual(actual, expected, [message])
|
||
*
|
||
* Assert that `actual` is not deeply equal to `expected`.
|
||
*
|
||
* assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
|
||
*
|
||
* @name notDeepEqual
|
||
* @param {Mixed} actual
|
||
* @param {Mixed} expected
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.notDeepEqual = function (act, exp, msg) {
|
||
new Assertion(act, msg).to.not.eql(exp);
|
||
};
|
||
|
||
/**
|
||
* ### .isTrue(value, [message])
|
||
*
|
||
* Asserts that `value` is true.
|
||
*
|
||
* var teaServed = true;
|
||
* assert.isTrue(teaServed, 'the tea has been served');
|
||
*
|
||
* @name isTrue
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isTrue = function (val, msg) {
|
||
new Assertion(val, msg).is['true'];
|
||
};
|
||
|
||
/**
|
||
* ### .isFalse(value, [message])
|
||
*
|
||
* Asserts that `value` is false.
|
||
*
|
||
* var teaServed = false;
|
||
* assert.isFalse(teaServed, 'no tea yet? hmm...');
|
||
*
|
||
* @name isFalse
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isFalse = function (val, msg) {
|
||
new Assertion(val, msg).is['false'];
|
||
};
|
||
|
||
/**
|
||
* ### .isNull(value, [message])
|
||
*
|
||
* Asserts that `value` is null.
|
||
*
|
||
* assert.isNull(err, 'there was no error');
|
||
*
|
||
* @name isNull
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isNull = function (val, msg) {
|
||
new Assertion(val, msg).to.equal(null);
|
||
};
|
||
|
||
/**
|
||
* ### .isNotNull(value, [message])
|
||
*
|
||
* Asserts that `value` is not null.
|
||
*
|
||
* var tea = 'tasty chai';
|
||
* assert.isNotNull(tea, 'great, time for tea!');
|
||
*
|
||
* @name isNotNull
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isNotNull = function (val, msg) {
|
||
new Assertion(val, msg).to.not.equal(null);
|
||
};
|
||
|
||
/**
|
||
* ### .isUndefined(value, [message])
|
||
*
|
||
* Asserts that `value` is `undefined`.
|
||
*
|
||
* var tea;
|
||
* assert.isUndefined(tea, 'no tea defined');
|
||
*
|
||
* @name isUndefined
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isUndefined = function (val, msg) {
|
||
new Assertion(val, msg).to.equal(undefined);
|
||
};
|
||
|
||
/**
|
||
* ### .isDefined(value, [message])
|
||
*
|
||
* Asserts that `value` is not `undefined`.
|
||
*
|
||
* var tea = 'cup of chai';
|
||
* assert.isDefined(tea, 'tea has been defined');
|
||
*
|
||
* @name isDefined
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isDefined = function (val, msg) {
|
||
new Assertion(val, msg).to.not.equal(undefined);
|
||
};
|
||
|
||
/**
|
||
* ### .isFunction(value, [message])
|
||
*
|
||
* Asserts that `value` is a function.
|
||
*
|
||
* function serveTea() { return 'cup of tea'; };
|
||
* assert.isFunction(serveTea, 'great, we can have tea now');
|
||
*
|
||
* @name isFunction
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isFunction = function (val, msg) {
|
||
new Assertion(val, msg).to.be.a('function');
|
||
};
|
||
|
||
/**
|
||
* ### .isNotFunction(value, [message])
|
||
*
|
||
* Asserts that `value` is _not_ a function.
|
||
*
|
||
* var serveTea = [ 'heat', 'pour', 'sip' ];
|
||
* assert.isNotFunction(serveTea, 'great, we have listed the steps');
|
||
*
|
||
* @name isNotFunction
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isNotFunction = function (val, msg) {
|
||
new Assertion(val, msg).to.not.be.a('function');
|
||
};
|
||
|
||
/**
|
||
* ### .isObject(value, [message])
|
||
*
|
||
* Asserts that `value` is an object (as revealed by
|
||
* `Object.prototype.toString`).
|
||
*
|
||
* var selection = { name: 'Chai', serve: 'with spices' };
|
||
* assert.isObject(selection, 'tea selection is an object');
|
||
*
|
||
* @name isObject
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isObject = function (val, msg) {
|
||
new Assertion(val, msg).to.be.a('object');
|
||
};
|
||
|
||
/**
|
||
* ### .isNotObject(value, [message])
|
||
*
|
||
* Asserts that `value` is _not_ an object.
|
||
*
|
||
* var selection = 'chai'
|
||
* assert.isNotObject(selection, 'tea selection is not an object');
|
||
* assert.isNotObject(null, 'null is not an object');
|
||
*
|
||
* @name isNotObject
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isNotObject = function (val, msg) {
|
||
new Assertion(val, msg).to.not.be.a('object');
|
||
};
|
||
|
||
/**
|
||
* ### .isArray(value, [message])
|
||
*
|
||
* Asserts that `value` is an array.
|
||
*
|
||
* var menu = [ 'green', 'chai', 'oolong' ];
|
||
* assert.isArray(menu, 'what kind of tea do we want?');
|
||
*
|
||
* @name isArray
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isArray = function (val, msg) {
|
||
new Assertion(val, msg).to.be.an('array');
|
||
};
|
||
|
||
/**
|
||
* ### .isNotArray(value, [message])
|
||
*
|
||
* Asserts that `value` is _not_ an array.
|
||
*
|
||
* var menu = 'green|chai|oolong';
|
||
* assert.isNotArray(menu, 'what kind of tea do we want?');
|
||
*
|
||
* @name isNotArray
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isNotArray = function (val, msg) {
|
||
new Assertion(val, msg).to.not.be.an('array');
|
||
};
|
||
|
||
/**
|
||
* ### .isString(value, [message])
|
||
*
|
||
* Asserts that `value` is a string.
|
||
*
|
||
* var teaOrder = 'chai';
|
||
* assert.isString(teaOrder, 'order placed');
|
||
*
|
||
* @name isString
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isString = function (val, msg) {
|
||
new Assertion(val, msg).to.be.a('string');
|
||
};
|
||
|
||
/**
|
||
* ### .isNotString(value, [message])
|
||
*
|
||
* Asserts that `value` is _not_ a string.
|
||
*
|
||
* var teaOrder = 4;
|
||
* assert.isNotString(teaOrder, 'order placed');
|
||
*
|
||
* @name isNotString
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isNotString = function (val, msg) {
|
||
new Assertion(val, msg).to.not.be.a('string');
|
||
};
|
||
|
||
/**
|
||
* ### .isNumber(value, [message])
|
||
*
|
||
* Asserts that `value` is a number.
|
||
*
|
||
* var cups = 2;
|
||
* assert.isNumber(cups, 'how many cups');
|
||
*
|
||
* @name isNumber
|
||
* @param {Number} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isNumber = function (val, msg) {
|
||
new Assertion(val, msg).to.be.a('number');
|
||
};
|
||
|
||
/**
|
||
* ### .isNotNumber(value, [message])
|
||
*
|
||
* Asserts that `value` is _not_ a number.
|
||
*
|
||
* var cups = '2 cups please';
|
||
* assert.isNotNumber(cups, 'how many cups');
|
||
*
|
||
* @name isNotNumber
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isNotNumber = function (val, msg) {
|
||
new Assertion(val, msg).to.not.be.a('number');
|
||
};
|
||
|
||
/**
|
||
* ### .isBoolean(value, [message])
|
||
*
|
||
* Asserts that `value` is a boolean.
|
||
*
|
||
* var teaReady = true
|
||
* , teaServed = false;
|
||
*
|
||
* assert.isBoolean(teaReady, 'is the tea ready');
|
||
* assert.isBoolean(teaServed, 'has tea been served');
|
||
*
|
||
* @name isBoolean
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isBoolean = function (val, msg) {
|
||
new Assertion(val, msg).to.be.a('boolean');
|
||
};
|
||
|
||
/**
|
||
* ### .isNotBoolean(value, [message])
|
||
*
|
||
* Asserts that `value` is _not_ a boolean.
|
||
*
|
||
* var teaReady = 'yep'
|
||
* , teaServed = 'nope';
|
||
*
|
||
* assert.isNotBoolean(teaReady, 'is the tea ready');
|
||
* assert.isNotBoolean(teaServed, 'has tea been served');
|
||
*
|
||
* @name isNotBoolean
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.isNotBoolean = function (val, msg) {
|
||
new Assertion(val, msg).to.not.be.a('boolean');
|
||
};
|
||
|
||
/**
|
||
* ### .typeOf(value, name, [message])
|
||
*
|
||
* Asserts that `value`'s type is `name`, as determined by
|
||
* `Object.prototype.toString`.
|
||
*
|
||
* assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');
|
||
* assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');
|
||
* assert.typeOf('tea', 'string', 'we have a string');
|
||
* assert.typeOf(/tea/, 'regexp', 'we have a regular expression');
|
||
* assert.typeOf(null, 'null', 'we have a null');
|
||
* assert.typeOf(undefined, 'undefined', 'we have an undefined');
|
||
*
|
||
* @name typeOf
|
||
* @param {Mixed} value
|
||
* @param {String} name
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.typeOf = function (val, type, msg) {
|
||
new Assertion(val, msg).to.be.a(type);
|
||
};
|
||
|
||
/**
|
||
* ### .notTypeOf(value, name, [message])
|
||
*
|
||
* Asserts that `value`'s type is _not_ `name`, as determined by
|
||
* `Object.prototype.toString`.
|
||
*
|
||
* assert.notTypeOf('tea', 'number', 'strings are not numbers');
|
||
*
|
||
* @name notTypeOf
|
||
* @param {Mixed} value
|
||
* @param {String} typeof name
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.notTypeOf = function (val, type, msg) {
|
||
new Assertion(val, msg).to.not.be.a(type);
|
||
};
|
||
|
||
/**
|
||
* ### .instanceOf(object, constructor, [message])
|
||
*
|
||
* Asserts that `value` is an instance of `constructor`.
|
||
*
|
||
* var Tea = function (name) { this.name = name; }
|
||
* , chai = new Tea('chai');
|
||
*
|
||
* assert.instanceOf(chai, Tea, 'chai is an instance of tea');
|
||
*
|
||
* @name instanceOf
|
||
* @param {Object} object
|
||
* @param {Constructor} constructor
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.instanceOf = function (val, type, msg) {
|
||
new Assertion(val, msg).to.be.instanceOf(type);
|
||
};
|
||
|
||
/**
|
||
* ### .notInstanceOf(object, constructor, [message])
|
||
*
|
||
* Asserts `value` is not an instance of `constructor`.
|
||
*
|
||
* var Tea = function (name) { this.name = name; }
|
||
* , chai = new String('chai');
|
||
*
|
||
* assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');
|
||
*
|
||
* @name notInstanceOf
|
||
* @param {Object} object
|
||
* @param {Constructor} constructor
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.notInstanceOf = function (val, type, msg) {
|
||
new Assertion(val, msg).to.not.be.instanceOf(type);
|
||
};
|
||
|
||
/**
|
||
* ### .include(haystack, needle, [message])
|
||
*
|
||
* Asserts that `haystack` includes `needle`. Works
|
||
* for strings and arrays.
|
||
*
|
||
* assert.include('foobar', 'bar', 'foobar contains string "bar"');
|
||
* assert.include([ 1, 2, 3 ], 3, 'array contains value');
|
||
*
|
||
* @name include
|
||
* @param {Array|String} haystack
|
||
* @param {Mixed} needle
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.include = function (exp, inc, msg) {
|
||
new Assertion(exp, msg, assert.include).include(inc);
|
||
};
|
||
|
||
/**
|
||
* ### .notInclude(haystack, needle, [message])
|
||
*
|
||
* Asserts that `haystack` does not include `needle`. Works
|
||
* for strings and arrays.
|
||
*i
|
||
* assert.notInclude('foobar', 'baz', 'string not include substring');
|
||
* assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');
|
||
*
|
||
* @name notInclude
|
||
* @param {Array|String} haystack
|
||
* @param {Mixed} needle
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.notInclude = function (exp, inc, msg) {
|
||
new Assertion(exp, msg, assert.notInclude).not.include(inc);
|
||
};
|
||
|
||
/**
|
||
* ### .match(value, regexp, [message])
|
||
*
|
||
* Asserts that `value` matches the regular expression `regexp`.
|
||
*
|
||
* assert.match('foobar', /^foo/, 'regexp matches');
|
||
*
|
||
* @name match
|
||
* @param {Mixed} value
|
||
* @param {RegExp} regexp
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.match = function (exp, re, msg) {
|
||
new Assertion(exp, msg).to.match(re);
|
||
};
|
||
|
||
/**
|
||
* ### .notMatch(value, regexp, [message])
|
||
*
|
||
* Asserts that `value` does not match the regular expression `regexp`.
|
||
*
|
||
* assert.notMatch('foobar', /^foo/, 'regexp does not match');
|
||
*
|
||
* @name notMatch
|
||
* @param {Mixed} value
|
||
* @param {RegExp} regexp
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.notMatch = function (exp, re, msg) {
|
||
new Assertion(exp, msg).to.not.match(re);
|
||
};
|
||
|
||
/**
|
||
* ### .property(object, property, [message])
|
||
*
|
||
* Asserts that `object` has a property named by `property`.
|
||
*
|
||
* assert.property({ tea: { green: 'matcha' }}, 'tea');
|
||
*
|
||
* @name property
|
||
* @param {Object} object
|
||
* @param {String} property
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.property = function (obj, prop, msg) {
|
||
new Assertion(obj, msg).to.have.property(prop);
|
||
};
|
||
|
||
/**
|
||
* ### .notProperty(object, property, [message])
|
||
*
|
||
* Asserts that `object` does _not_ have a property named by `property`.
|
||
*
|
||
* assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');
|
||
*
|
||
* @name notProperty
|
||
* @param {Object} object
|
||
* @param {String} property
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.notProperty = function (obj, prop, msg) {
|
||
new Assertion(obj, msg).to.not.have.property(prop);
|
||
};
|
||
|
||
/**
|
||
* ### .deepProperty(object, property, [message])
|
||
*
|
||
* Asserts that `object` has a property named by `property`, which can be a
|
||
* string using dot- and bracket-notation for deep reference.
|
||
*
|
||
* assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');
|
||
*
|
||
* @name deepProperty
|
||
* @param {Object} object
|
||
* @param {String} property
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.deepProperty = function (obj, prop, msg) {
|
||
new Assertion(obj, msg).to.have.deep.property(prop);
|
||
};
|
||
|
||
/**
|
||
* ### .notDeepProperty(object, property, [message])
|
||
*
|
||
* Asserts that `object` does _not_ have a property named by `property`, which
|
||
* can be a string using dot- and bracket-notation for deep reference.
|
||
*
|
||
* assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');
|
||
*
|
||
* @name notDeepProperty
|
||
* @param {Object} object
|
||
* @param {String} property
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.notDeepProperty = function (obj, prop, msg) {
|
||
new Assertion(obj, msg).to.not.have.deep.property(prop);
|
||
};
|
||
|
||
/**
|
||
* ### .propertyVal(object, property, value, [message])
|
||
*
|
||
* Asserts that `object` has a property named by `property` with value given
|
||
* by `value`.
|
||
*
|
||
* assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');
|
||
*
|
||
* @name propertyVal
|
||
* @param {Object} object
|
||
* @param {String} property
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.propertyVal = function (obj, prop, val, msg) {
|
||
new Assertion(obj, msg).to.have.property(prop, val);
|
||
};
|
||
|
||
/**
|
||
* ### .propertyNotVal(object, property, value, [message])
|
||
*
|
||
* Asserts that `object` has a property named by `property`, but with a value
|
||
* different from that given by `value`.
|
||
*
|
||
* assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');
|
||
*
|
||
* @name propertyNotVal
|
||
* @param {Object} object
|
||
* @param {String} property
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.propertyNotVal = function (obj, prop, val, msg) {
|
||
new Assertion(obj, msg).to.not.have.property(prop, val);
|
||
};
|
||
|
||
/**
|
||
* ### .deepPropertyVal(object, property, value, [message])
|
||
*
|
||
* Asserts that `object` has a property named by `property` with value given
|
||
* by `value`. `property` can use dot- and bracket-notation for deep
|
||
* reference.
|
||
*
|
||
* assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');
|
||
*
|
||
* @name deepPropertyVal
|
||
* @param {Object} object
|
||
* @param {String} property
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.deepPropertyVal = function (obj, prop, val, msg) {
|
||
new Assertion(obj, msg).to.have.deep.property(prop, val);
|
||
};
|
||
|
||
/**
|
||
* ### .deepPropertyNotVal(object, property, value, [message])
|
||
*
|
||
* Asserts that `object` has a property named by `property`, but with a value
|
||
* different from that given by `value`. `property` can use dot- and
|
||
* bracket-notation for deep reference.
|
||
*
|
||
* assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');
|
||
*
|
||
* @name deepPropertyNotVal
|
||
* @param {Object} object
|
||
* @param {String} property
|
||
* @param {Mixed} value
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.deepPropertyNotVal = function (obj, prop, val, msg) {
|
||
new Assertion(obj, msg).to.not.have.deep.property(prop, val);
|
||
};
|
||
|
||
/**
|
||
* ### .lengthOf(object, length, [message])
|
||
*
|
||
* Asserts that `object` has a `length` property with the expected value.
|
||
*
|
||
* assert.lengthOf([1,2,3], 3, 'array has length of 3');
|
||
* assert.lengthOf('foobar', 5, 'string has length of 6');
|
||
*
|
||
* @name lengthOf
|
||
* @param {Mixed} object
|
||
* @param {Number} length
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.lengthOf = function (exp, len, msg) {
|
||
new Assertion(exp, msg).to.have.length(len);
|
||
};
|
||
|
||
/**
|
||
* ### .throws(function, [constructor/string/regexp], [string/regexp], [message])
|
||
*
|
||
* Asserts that `function` will throw an error that is an instance of
|
||
* `constructor`, or alternately that it will throw an error with message
|
||
* matching `regexp`.
|
||
*
|
||
* assert.throw(fn, 'function throws a reference error');
|
||
* assert.throw(fn, /function throws a reference error/);
|
||
* assert.throw(fn, ReferenceError);
|
||
* assert.throw(fn, ReferenceError, 'function throws a reference error');
|
||
* assert.throw(fn, ReferenceError, /function throws a reference error/);
|
||
*
|
||
* @name throws
|
||
* @alias throw
|
||
* @alias Throw
|
||
* @param {Function} function
|
||
* @param {ErrorConstructor} constructor
|
||
* @param {RegExp} regexp
|
||
* @param {String} message
|
||
* @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
|
||
* @api public
|
||
*/
|
||
|
||
assert.Throw = function (fn, errt, errs, msg) {
|
||
if ('string' === typeof errt || errt instanceof RegExp) {
|
||
errs = errt;
|
||
errt = null;
|
||
}
|
||
|
||
var assertErr = new Assertion(fn, msg).to.Throw(errt, errs);
|
||
return flag(assertErr, 'object');
|
||
};
|
||
|
||
/**
|
||
* ### .doesNotThrow(function, [constructor/regexp], [message])
|
||
*
|
||
* Asserts that `function` will _not_ throw an error that is an instance of
|
||
* `constructor`, or alternately that it will not throw an error with message
|
||
* matching `regexp`.
|
||
*
|
||
* assert.doesNotThrow(fn, Error, 'function does not throw');
|
||
*
|
||
* @name doesNotThrow
|
||
* @param {Function} function
|
||
* @param {ErrorConstructor} constructor
|
||
* @param {RegExp} regexp
|
||
* @param {String} message
|
||
* @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
|
||
* @api public
|
||
*/
|
||
|
||
assert.doesNotThrow = function (fn, type, msg) {
|
||
if ('string' === typeof type) {
|
||
msg = type;
|
||
type = null;
|
||
}
|
||
|
||
new Assertion(fn, msg).to.not.Throw(type);
|
||
};
|
||
|
||
/**
|
||
* ### .operator(val1, operator, val2, [message])
|
||
*
|
||
* Compares two values using `operator`.
|
||
*
|
||
* assert.operator(1, '<', 2, 'everything is ok');
|
||
* assert.operator(1, '>', 2, 'this will fail');
|
||
*
|
||
* @name operator
|
||
* @param {Mixed} val1
|
||
* @param {String} operator
|
||
* @param {Mixed} val2
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.operator = function (val, operator, val2, msg) {
|
||
if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) {
|
||
throw new Error('Invalid operator "' + operator + '"');
|
||
}
|
||
var test = new Assertion(eval(val + operator + val2), msg);
|
||
test.assert(
|
||
true === flag(test, 'object')
|
||
, 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)
|
||
, 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );
|
||
};
|
||
|
||
/**
|
||
* ### .closeTo(actual, expected, delta, [message])
|
||
*
|
||
* Asserts that the target is equal `expected`, to within a +/- `delta` range.
|
||
*
|
||
* assert.closeTo(1.5, 1, 0.5, 'numbers are close');
|
||
*
|
||
* @name closeTo
|
||
* @param {Number} actual
|
||
* @param {Number} expected
|
||
* @param {Number} delta
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.closeTo = function (act, exp, delta, msg) {
|
||
new Assertion(act, msg).to.be.closeTo(exp, delta);
|
||
};
|
||
|
||
/**
|
||
* ### .sameMembers(set1, set2, [message])
|
||
*
|
||
* Asserts that `set1` and `set2` have the same members.
|
||
* Order is not taken into account.
|
||
*
|
||
* assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');
|
||
*
|
||
* @name sameMembers
|
||
* @param {Array} superset
|
||
* @param {Array} subset
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.sameMembers = function (set1, set2, msg) {
|
||
new Assertion(set1, msg).to.have.same.members(set2);
|
||
}
|
||
|
||
/**
|
||
* ### .includeMembers(superset, subset, [message])
|
||
*
|
||
* Asserts that `subset` is included in `superset`.
|
||
* Order is not taken into account.
|
||
*
|
||
* assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');
|
||
*
|
||
* @name includeMembers
|
||
* @param {Array} superset
|
||
* @param {Array} subset
|
||
* @param {String} message
|
||
* @api public
|
||
*/
|
||
|
||
assert.includeMembers = function (superset, subset, msg) {
|
||
new Assertion(superset, msg).to.include.members(subset);
|
||
}
|
||
|
||
/*!
|
||
* Undocumented / untested
|
||
*/
|
||
|
||
assert.ifError = function (val, msg) {
|
||
new Assertion(val, msg).to.not.be.ok;
|
||
};
|
||
|
||
/*!
|
||
* Aliases.
|
||
*/
|
||
|
||
(function alias(name, as){
|
||
assert[as] = assert[name];
|
||
return alias;
|
||
})
|
||
('Throw', 'throw')
|
||
('Throw', 'throws');
|
||
};
|
||
|
||
},{}],20:[function(require,module,exports){
|
||
/*!
|
||
* chai
|
||
* Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
module.exports = function (chai, util) {
|
||
chai.expect = function (val, message) {
|
||
return new chai.Assertion(val, message);
|
||
};
|
||
};
|
||
|
||
|
||
},{}],21:[function(require,module,exports){
|
||
/*!
|
||
* chai
|
||
* Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
module.exports = function (chai, util) {
|
||
var Assertion = chai.Assertion;
|
||
|
||
function loadShould () {
|
||
// explicitly define this method as function as to have it's name to include as `ssfi`
|
||
function shouldGetter() {
|
||
if (this instanceof String || this instanceof Number) {
|
||
return new Assertion(this.constructor(this), null, shouldGetter);
|
||
} else if (this instanceof Boolean) {
|
||
return new Assertion(this == true, null, shouldGetter);
|
||
}
|
||
return new Assertion(this, null, shouldGetter);
|
||
}
|
||
function shouldSetter(value) {
|
||
// See https://github.com/chaijs/chai/issues/86: this makes
|
||
// `whatever.should = someValue` actually set `someValue`, which is
|
||
// especially useful for `global.should = require('chai').should()`.
|
||
//
|
||
// Note that we have to use [[DefineProperty]] instead of [[Put]]
|
||
// since otherwise we would trigger this very setter!
|
||
Object.defineProperty(this, 'should', {
|
||
value: value,
|
||
enumerable: true,
|
||
configurable: true,
|
||
writable: true
|
||
});
|
||
}
|
||
// modify Object.prototype to have `should`
|
||
Object.defineProperty(Object.prototype, 'should', {
|
||
set: shouldSetter
|
||
, get: shouldGetter
|
||
, configurable: true
|
||
});
|
||
|
||
var should = {};
|
||
|
||
should.equal = function (val1, val2, msg) {
|
||
new Assertion(val1, msg).to.equal(val2);
|
||
};
|
||
|
||
should.Throw = function (fn, errt, errs, msg) {
|
||
new Assertion(fn, msg).to.Throw(errt, errs);
|
||
};
|
||
|
||
should.exist = function (val, msg) {
|
||
new Assertion(val, msg).to.exist;
|
||
}
|
||
|
||
// negation
|
||
should.not = {}
|
||
|
||
should.not.equal = function (val1, val2, msg) {
|
||
new Assertion(val1, msg).to.not.equal(val2);
|
||
};
|
||
|
||
should.not.Throw = function (fn, errt, errs, msg) {
|
||
new Assertion(fn, msg).to.not.Throw(errt, errs);
|
||
};
|
||
|
||
should.not.exist = function (val, msg) {
|
||
new Assertion(val, msg).to.not.exist;
|
||
}
|
||
|
||
should['throw'] = should['Throw'];
|
||
should.not['throw'] = should.not['Throw'];
|
||
|
||
return should;
|
||
};
|
||
|
||
chai.should = loadShould;
|
||
chai.Should = loadShould;
|
||
};
|
||
|
||
},{}],22:[function(require,module,exports){
|
||
/*!
|
||
* Chai - addChainingMethod utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/*!
|
||
* Module dependencies
|
||
*/
|
||
|
||
var transferFlags = require('./transferFlags');
|
||
var flag = require('./flag');
|
||
var config = require('../config');
|
||
|
||
/*!
|
||
* Module variables
|
||
*/
|
||
|
||
// Check whether `__proto__` is supported
|
||
var hasProtoSupport = '__proto__' in Object;
|
||
|
||
// Without `__proto__` support, this module will need to add properties to a function.
|
||
// However, some Function.prototype methods cannot be overwritten,
|
||
// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).
|
||
var excludeNames = /^(?:length|name|arguments|caller)$/;
|
||
|
||
// Cache `Function` properties
|
||
var call = Function.prototype.call,
|
||
apply = Function.prototype.apply;
|
||
|
||
/**
|
||
* ### addChainableMethod (ctx, name, method, chainingBehavior)
|
||
*
|
||
* Adds a method to an object, such that the method can also be chained.
|
||
*
|
||
* utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {
|
||
* var obj = utils.flag(this, 'object');
|
||
* new chai.Assertion(obj).to.be.equal(str);
|
||
* });
|
||
*
|
||
* Can also be accessed directly from `chai.Assertion`.
|
||
*
|
||
* chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);
|
||
*
|
||
* The result can then be used as both a method assertion, executing both `method` and
|
||
* `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.
|
||
*
|
||
* expect(fooStr).to.be.foo('bar');
|
||
* expect(fooStr).to.be.foo.equal('foo');
|
||
*
|
||
* @param {Object} ctx object to which the method is added
|
||
* @param {String} name of method to add
|
||
* @param {Function} method function to be used for `name`, when called
|
||
* @param {Function} chainingBehavior function to be called every time the property is accessed
|
||
* @name addChainableMethod
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function (ctx, name, method, chainingBehavior) {
|
||
if (typeof chainingBehavior !== 'function') {
|
||
chainingBehavior = function () { };
|
||
}
|
||
|
||
var chainableBehavior = {
|
||
method: method
|
||
, chainingBehavior: chainingBehavior
|
||
};
|
||
|
||
// save the methods so we can overwrite them later, if we need to.
|
||
if (!ctx.__methods) {
|
||
ctx.__methods = {};
|
||
}
|
||
ctx.__methods[name] = chainableBehavior;
|
||
|
||
Object.defineProperty(ctx, name,
|
||
{ get: function () {
|
||
chainableBehavior.chainingBehavior.call(this);
|
||
|
||
var assert = function assert() {
|
||
var old_ssfi = flag(this, 'ssfi');
|
||
if (old_ssfi && config.includeStack === false)
|
||
flag(this, 'ssfi', assert);
|
||
var result = chainableBehavior.method.apply(this, arguments);
|
||
return result === undefined ? this : result;
|
||
};
|
||
|
||
// Use `__proto__` if available
|
||
if (hasProtoSupport) {
|
||
// Inherit all properties from the object by replacing the `Function` prototype
|
||
var prototype = assert.__proto__ = Object.create(this);
|
||
// Restore the `call` and `apply` methods from `Function`
|
||
prototype.call = call;
|
||
prototype.apply = apply;
|
||
}
|
||
// Otherwise, redefine all properties (slow!)
|
||
else {
|
||
var asserterNames = Object.getOwnPropertyNames(ctx);
|
||
asserterNames.forEach(function (asserterName) {
|
||
if (!excludeNames.test(asserterName)) {
|
||
var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);
|
||
Object.defineProperty(assert, asserterName, pd);
|
||
}
|
||
});
|
||
}
|
||
|
||
transferFlags(this, assert);
|
||
return assert;
|
||
}
|
||
, configurable: true
|
||
});
|
||
};
|
||
|
||
},{"../config":17,"./flag":25,"./transferFlags":39}],23:[function(require,module,exports){
|
||
/*!
|
||
* Chai - addMethod utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
var config = require('../config');
|
||
|
||
/**
|
||
* ### .addMethod (ctx, name, method)
|
||
*
|
||
* Adds a method to the prototype of an object.
|
||
*
|
||
* utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {
|
||
* var obj = utils.flag(this, 'object');
|
||
* new chai.Assertion(obj).to.be.equal(str);
|
||
* });
|
||
*
|
||
* Can also be accessed directly from `chai.Assertion`.
|
||
*
|
||
* chai.Assertion.addMethod('foo', fn);
|
||
*
|
||
* Then can be used as any other assertion.
|
||
*
|
||
* expect(fooStr).to.be.foo('bar');
|
||
*
|
||
* @param {Object} ctx object to which the method is added
|
||
* @param {String} name of method to add
|
||
* @param {Function} method function to be used for name
|
||
* @name addMethod
|
||
* @api public
|
||
*/
|
||
var flag = require('./flag');
|
||
|
||
module.exports = function (ctx, name, method) {
|
||
ctx[name] = function () {
|
||
var old_ssfi = flag(this, 'ssfi');
|
||
if (old_ssfi && config.includeStack === false)
|
||
flag(this, 'ssfi', ctx[name]);
|
||
var result = method.apply(this, arguments);
|
||
return result === undefined ? this : result;
|
||
};
|
||
};
|
||
|
||
},{"../config":17,"./flag":25}],24:[function(require,module,exports){
|
||
/*!
|
||
* Chai - addProperty utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/**
|
||
* ### addProperty (ctx, name, getter)
|
||
*
|
||
* Adds a property to the prototype of an object.
|
||
*
|
||
* utils.addProperty(chai.Assertion.prototype, 'foo', function () {
|
||
* var obj = utils.flag(this, 'object');
|
||
* new chai.Assertion(obj).to.be.instanceof(Foo);
|
||
* });
|
||
*
|
||
* Can also be accessed directly from `chai.Assertion`.
|
||
*
|
||
* chai.Assertion.addProperty('foo', fn);
|
||
*
|
||
* Then can be used as any other assertion.
|
||
*
|
||
* expect(myFoo).to.be.foo;
|
||
*
|
||
* @param {Object} ctx object to which the property is added
|
||
* @param {String} name of property to add
|
||
* @param {Function} getter function to be used for name
|
||
* @name addProperty
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function (ctx, name, getter) {
|
||
Object.defineProperty(ctx, name,
|
||
{ get: function () {
|
||
var result = getter.call(this);
|
||
return result === undefined ? this : result;
|
||
}
|
||
, configurable: true
|
||
});
|
||
};
|
||
|
||
},{}],25:[function(require,module,exports){
|
||
/*!
|
||
* Chai - flag utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/**
|
||
* ### flag(object ,key, [value])
|
||
*
|
||
* Get or set a flag value on an object. If a
|
||
* value is provided it will be set, else it will
|
||
* return the currently set value or `undefined` if
|
||
* the value is not set.
|
||
*
|
||
* utils.flag(this, 'foo', 'bar'); // setter
|
||
* utils.flag(this, 'foo'); // getter, returns `bar`
|
||
*
|
||
* @param {Object} object (constructed Assertion
|
||
* @param {String} key
|
||
* @param {Mixed} value (optional)
|
||
* @name flag
|
||
* @api private
|
||
*/
|
||
|
||
module.exports = function (obj, key, value) {
|
||
var flags = obj.__flags || (obj.__flags = Object.create(null));
|
||
if (arguments.length === 3) {
|
||
flags[key] = value;
|
||
} else {
|
||
return flags[key];
|
||
}
|
||
};
|
||
|
||
},{}],26:[function(require,module,exports){
|
||
/*!
|
||
* Chai - getActual utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/**
|
||
* # getActual(object, [actual])
|
||
*
|
||
* Returns the `actual` value for an Assertion
|
||
*
|
||
* @param {Object} object (constructed Assertion)
|
||
* @param {Arguments} chai.Assertion.prototype.assert arguments
|
||
*/
|
||
|
||
module.exports = function (obj, args) {
|
||
return args.length > 4 ? args[4] : obj._obj;
|
||
};
|
||
|
||
},{}],27:[function(require,module,exports){
|
||
/*!
|
||
* Chai - getEnumerableProperties utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/**
|
||
* ### .getEnumerableProperties(object)
|
||
*
|
||
* This allows the retrieval of enumerable property names of an object,
|
||
* inherited or not.
|
||
*
|
||
* @param {Object} object
|
||
* @returns {Array}
|
||
* @name getEnumerableProperties
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function getEnumerableProperties(object) {
|
||
var result = [];
|
||
for (var name in object) {
|
||
result.push(name);
|
||
}
|
||
return result;
|
||
};
|
||
|
||
},{}],28:[function(require,module,exports){
|
||
/*!
|
||
* Chai - message composition utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/*!
|
||
* Module dependancies
|
||
*/
|
||
|
||
var flag = require('./flag')
|
||
, getActual = require('./getActual')
|
||
, inspect = require('./inspect')
|
||
, objDisplay = require('./objDisplay');
|
||
|
||
/**
|
||
* ### .getMessage(object, message, negateMessage)
|
||
*
|
||
* Construct the error message based on flags
|
||
* and template tags. Template tags will return
|
||
* a stringified inspection of the object referenced.
|
||
*
|
||
* Message template tags:
|
||
* - `#{this}` current asserted object
|
||
* - `#{act}` actual value
|
||
* - `#{exp}` expected value
|
||
*
|
||
* @param {Object} object (constructed Assertion)
|
||
* @param {Arguments} chai.Assertion.prototype.assert arguments
|
||
* @name getMessage
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function (obj, args) {
|
||
var negate = flag(obj, 'negate')
|
||
, val = flag(obj, 'object')
|
||
, expected = args[3]
|
||
, actual = getActual(obj, args)
|
||
, msg = negate ? args[2] : args[1]
|
||
, flagMsg = flag(obj, 'message');
|
||
|
||
msg = msg || '';
|
||
msg = msg
|
||
.replace(/#{this}/g, objDisplay(val))
|
||
.replace(/#{act}/g, objDisplay(actual))
|
||
.replace(/#{exp}/g, objDisplay(expected));
|
||
|
||
return flagMsg ? flagMsg + ': ' + msg : msg;
|
||
};
|
||
|
||
},{"./flag":25,"./getActual":26,"./inspect":33,"./objDisplay":34}],29:[function(require,module,exports){
|
||
/*!
|
||
* Chai - getName utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/**
|
||
* # getName(func)
|
||
*
|
||
* Gets the name of a function, in a cross-browser way.
|
||
*
|
||
* @param {Function} a function (usually a constructor)
|
||
*/
|
||
|
||
module.exports = function (func) {
|
||
if (func.name) return func.name;
|
||
|
||
var match = /^\s?function ([^(]*)\(/.exec(func);
|
||
return match && match[1] ? match[1] : "";
|
||
};
|
||
|
||
},{}],30:[function(require,module,exports){
|
||
/*!
|
||
* Chai - getPathValue utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* @see https://github.com/logicalparadox/filtr
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/**
|
||
* ### .getPathValue(path, object)
|
||
*
|
||
* This allows the retrieval of values in an
|
||
* object given a string path.
|
||
*
|
||
* var obj = {
|
||
* prop1: {
|
||
* arr: ['a', 'b', 'c']
|
||
* , str: 'Hello'
|
||
* }
|
||
* , prop2: {
|
||
* arr: [ { nested: 'Universe' } ]
|
||
* , str: 'Hello again!'
|
||
* }
|
||
* }
|
||
*
|
||
* The following would be the results.
|
||
*
|
||
* getPathValue('prop1.str', obj); // Hello
|
||
* getPathValue('prop1.att[2]', obj); // b
|
||
* getPathValue('prop2.arr[0].nested', obj); // Universe
|
||
*
|
||
* @param {String} path
|
||
* @param {Object} object
|
||
* @returns {Object} value or `undefined`
|
||
* @name getPathValue
|
||
* @api public
|
||
*/
|
||
|
||
var getPathValue = module.exports = function (path, obj) {
|
||
var parsed = parsePath(path);
|
||
return _getPathValue(parsed, obj);
|
||
};
|
||
|
||
/*!
|
||
* ## parsePath(path)
|
||
*
|
||
* Helper function used to parse string object
|
||
* paths. Use in conjunction with `_getPathValue`.
|
||
*
|
||
* var parsed = parsePath('myobject.property.subprop');
|
||
*
|
||
* ### Paths:
|
||
*
|
||
* * Can be as near infinitely deep and nested
|
||
* * Arrays are also valid using the formal `myobject.document[3].property`.
|
||
*
|
||
* @param {String} path
|
||
* @returns {Object} parsed
|
||
* @api private
|
||
*/
|
||
|
||
function parsePath (path) {
|
||
var str = path.replace(/\[/g, '.[')
|
||
, parts = str.match(/(\\\.|[^.]+?)+/g);
|
||
return parts.map(function (value) {
|
||
var re = /\[(\d+)\]$/
|
||
, mArr = re.exec(value)
|
||
if (mArr) return { i: parseFloat(mArr[1]) };
|
||
else return { p: value };
|
||
});
|
||
};
|
||
|
||
/*!
|
||
* ## _getPathValue(parsed, obj)
|
||
*
|
||
* Helper companion function for `.parsePath` that returns
|
||
* the value located at the parsed address.
|
||
*
|
||
* var value = getPathValue(parsed, obj);
|
||
*
|
||
* @param {Object} parsed definition from `parsePath`.
|
||
* @param {Object} object to search against
|
||
* @returns {Object|Undefined} value
|
||
* @api private
|
||
*/
|
||
|
||
function _getPathValue (parsed, obj) {
|
||
var tmp = obj
|
||
, res;
|
||
for (var i = 0, l = parsed.length; i < l; i++) {
|
||
var part = parsed[i];
|
||
if (tmp) {
|
||
if ('undefined' !== typeof part.p)
|
||
tmp = tmp[part.p];
|
||
else if ('undefined' !== typeof part.i)
|
||
tmp = tmp[part.i];
|
||
if (i == (l - 1)) res = tmp;
|
||
} else {
|
||
res = undefined;
|
||
}
|
||
}
|
||
return res;
|
||
};
|
||
|
||
},{}],31:[function(require,module,exports){
|
||
/*!
|
||
* Chai - getProperties utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/**
|
||
* ### .getProperties(object)
|
||
*
|
||
* This allows the retrieval of property names of an object, enumerable or not,
|
||
* inherited or not.
|
||
*
|
||
* @param {Object} object
|
||
* @returns {Array}
|
||
* @name getProperties
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function getProperties(object) {
|
||
var result = Object.getOwnPropertyNames(subject);
|
||
|
||
function addProperty(property) {
|
||
if (result.indexOf(property) === -1) {
|
||
result.push(property);
|
||
}
|
||
}
|
||
|
||
var proto = Object.getPrototypeOf(subject);
|
||
while (proto !== null) {
|
||
Object.getOwnPropertyNames(proto).forEach(addProperty);
|
||
proto = Object.getPrototypeOf(proto);
|
||
}
|
||
|
||
return result;
|
||
};
|
||
|
||
},{}],32:[function(require,module,exports){
|
||
/*!
|
||
* chai
|
||
* Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/*!
|
||
* Main exports
|
||
*/
|
||
|
||
var exports = module.exports = {};
|
||
|
||
/*!
|
||
* test utility
|
||
*/
|
||
|
||
exports.test = require('./test');
|
||
|
||
/*!
|
||
* type utility
|
||
*/
|
||
|
||
exports.type = require('./type');
|
||
|
||
/*!
|
||
* message utility
|
||
*/
|
||
|
||
exports.getMessage = require('./getMessage');
|
||
|
||
/*!
|
||
* actual utility
|
||
*/
|
||
|
||
exports.getActual = require('./getActual');
|
||
|
||
/*!
|
||
* Inspect util
|
||
*/
|
||
|
||
exports.inspect = require('./inspect');
|
||
|
||
/*!
|
||
* Object Display util
|
||
*/
|
||
|
||
exports.objDisplay = require('./objDisplay');
|
||
|
||
/*!
|
||
* Flag utility
|
||
*/
|
||
|
||
exports.flag = require('./flag');
|
||
|
||
/*!
|
||
* Flag transferring utility
|
||
*/
|
||
|
||
exports.transferFlags = require('./transferFlags');
|
||
|
||
/*!
|
||
* Deep equal utility
|
||
*/
|
||
|
||
exports.eql = require('deep-eql');
|
||
|
||
/*!
|
||
* Deep path value
|
||
*/
|
||
|
||
exports.getPathValue = require('./getPathValue');
|
||
|
||
/*!
|
||
* Function name
|
||
*/
|
||
|
||
exports.getName = require('./getName');
|
||
|
||
/*!
|
||
* add Property
|
||
*/
|
||
|
||
exports.addProperty = require('./addProperty');
|
||
|
||
/*!
|
||
* add Method
|
||
*/
|
||
|
||
exports.addMethod = require('./addMethod');
|
||
|
||
/*!
|
||
* overwrite Property
|
||
*/
|
||
|
||
exports.overwriteProperty = require('./overwriteProperty');
|
||
|
||
/*!
|
||
* overwrite Method
|
||
*/
|
||
|
||
exports.overwriteMethod = require('./overwriteMethod');
|
||
|
||
/*!
|
||
* Add a chainable method
|
||
*/
|
||
|
||
exports.addChainableMethod = require('./addChainableMethod');
|
||
|
||
/*!
|
||
* Overwrite chainable method
|
||
*/
|
||
|
||
exports.overwriteChainableMethod = require('./overwriteChainableMethod');
|
||
|
||
|
||
},{"./addChainableMethod":22,"./addMethod":23,"./addProperty":24,"./flag":25,"./getActual":26,"./getMessage":28,"./getName":29,"./getPathValue":30,"./inspect":33,"./objDisplay":34,"./overwriteChainableMethod":35,"./overwriteMethod":36,"./overwriteProperty":37,"./test":38,"./transferFlags":39,"./type":40,"deep-eql":42}],33:[function(require,module,exports){
|
||
// This is (almost) directly from Node.js utils
|
||
// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
|
||
|
||
var getName = require('./getName');
|
||
var getProperties = require('./getProperties');
|
||
var getEnumerableProperties = require('./getEnumerableProperties');
|
||
|
||
module.exports = inspect;
|
||
|
||
/**
|
||
* Echos the value of a value. Trys to print the value out
|
||
* in the best way possible given the different types.
|
||
*
|
||
* @param {Object} obj The object to print out.
|
||
* @param {Boolean} showHidden Flag that shows hidden (not enumerable)
|
||
* properties of objects.
|
||
* @param {Number} depth Depth in which to descend in object. Default is 2.
|
||
* @param {Boolean} colors Flag to turn on ANSI escape codes to color the
|
||
* output. Default is false (no coloring).
|
||
*/
|
||
function inspect(obj, showHidden, depth, colors) {
|
||
var ctx = {
|
||
showHidden: showHidden,
|
||
seen: [],
|
||
stylize: function (str) { return str; }
|
||
};
|
||
return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
|
||
}
|
||
|
||
// https://gist.github.com/1044128/
|
||
var getOuterHTML = function(element) {
|
||
if ('outerHTML' in element) return element.outerHTML;
|
||
var ns = "http://www.w3.org/1999/xhtml";
|
||
var container = document.createElementNS(ns, '_');
|
||
var elemProto = (window.HTMLElement || window.Element).prototype;
|
||
var xmlSerializer = new XMLSerializer();
|
||
var html;
|
||
if (document.xmlVersion) {
|
||
return xmlSerializer.serializeToString(element);
|
||
} else {
|
||
container.appendChild(element.cloneNode(false));
|
||
html = container.innerHTML.replace('><', '>' + element.innerHTML + '<');
|
||
container.innerHTML = '';
|
||
return html;
|
||
}
|
||
};
|
||
|
||
// Returns true if object is a DOM element.
|
||
var isDOMElement = function (object) {
|
||
if (typeof HTMLElement === 'object') {
|
||
return object instanceof HTMLElement;
|
||
} else {
|
||
return object &&
|
||
typeof object === 'object' &&
|
||
object.nodeType === 1 &&
|
||
typeof object.nodeName === 'string';
|
||
}
|
||
};
|
||
|
||
function formatValue(ctx, value, recurseTimes) {
|
||
// Provide a hook for user-specified inspect functions.
|
||
// Check that value is an object with an inspect function on it
|
||
if (value && typeof value.inspect === 'function' &&
|
||
// Filter out the util module, it's inspect function is special
|
||
value.inspect !== exports.inspect &&
|
||
// Also filter out any prototype objects using the circular check.
|
||
!(value.constructor && value.constructor.prototype === value)) {
|
||
var ret = value.inspect(recurseTimes);
|
||
if (typeof ret !== 'string') {
|
||
ret = formatValue(ctx, ret, recurseTimes);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
// Primitive types cannot have properties
|
||
var primitive = formatPrimitive(ctx, value);
|
||
if (primitive) {
|
||
return primitive;
|
||
}
|
||
|
||
// If it's DOM elem, get outer HTML.
|
||
if (isDOMElement(value)) {
|
||
return getOuterHTML(value);
|
||
}
|
||
|
||
// Look up the keys of the object.
|
||
var visibleKeys = getEnumerableProperties(value);
|
||
var keys = ctx.showHidden ? getProperties(value) : visibleKeys;
|
||
|
||
// Some type of object without properties can be shortcutted.
|
||
// In IE, errors have a single `stack` property, or if they are vanilla `Error`,
|
||
// a `stack` plus `description` property; ignore those for consistency.
|
||
if (keys.length === 0 || (isError(value) && (
|
||
(keys.length === 1 && keys[0] === 'stack') ||
|
||
(keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')
|
||
))) {
|
||
if (typeof value === 'function') {
|
||
var name = getName(value);
|
||
var nameSuffix = name ? ': ' + name : '';
|
||
return ctx.stylize('[Function' + nameSuffix + ']', 'special');
|
||
}
|
||
if (isRegExp(value)) {
|
||
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
||
}
|
||
if (isDate(value)) {
|
||
return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
|
||
}
|
||
if (isError(value)) {
|
||
return formatError(value);
|
||
}
|
||
}
|
||
|
||
var base = '', array = false, braces = ['{', '}'];
|
||
|
||
// Make Array say that they are Array
|
||
if (isArray(value)) {
|
||
array = true;
|
||
braces = ['[', ']'];
|
||
}
|
||
|
||
// Make functions say that they are functions
|
||
if (typeof value === 'function') {
|
||
var name = getName(value);
|
||
var nameSuffix = name ? ': ' + name : '';
|
||
base = ' [Function' + nameSuffix + ']';
|
||
}
|
||
|
||
// Make RegExps say that they are RegExps
|
||
if (isRegExp(value)) {
|
||
base = ' ' + RegExp.prototype.toString.call(value);
|
||
}
|
||
|
||
// Make dates with properties first say the date
|
||
if (isDate(value)) {
|
||
base = ' ' + Date.prototype.toUTCString.call(value);
|
||
}
|
||
|
||
// Make error with message first say the error
|
||
if (isError(value)) {
|
||
return formatError(value);
|
||
}
|
||
|
||
if (keys.length === 0 && (!array || value.length == 0)) {
|
||
return braces[0] + base + braces[1];
|
||
}
|
||
|
||
if (recurseTimes < 0) {
|
||
if (isRegExp(value)) {
|
||
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
||
} else {
|
||
return ctx.stylize('[Object]', 'special');
|
||
}
|
||
}
|
||
|
||
ctx.seen.push(value);
|
||
|
||
var output;
|
||
if (array) {
|
||
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
|
||
} else {
|
||
output = keys.map(function(key) {
|
||
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
|
||
});
|
||
}
|
||
|
||
ctx.seen.pop();
|
||
|
||
return reduceToSingleString(output, base, braces);
|
||
}
|
||
|
||
|
||
function formatPrimitive(ctx, value) {
|
||
switch (typeof value) {
|
||
case 'undefined':
|
||
return ctx.stylize('undefined', 'undefined');
|
||
|
||
case 'string':
|
||
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
|
||
.replace(/'/g, "\\'")
|
||
.replace(/\\"/g, '"') + '\'';
|
||
return ctx.stylize(simple, 'string');
|
||
|
||
case 'number':
|
||
return ctx.stylize('' + value, 'number');
|
||
|
||
case 'boolean':
|
||
return ctx.stylize('' + value, 'boolean');
|
||
}
|
||
// For some reason typeof null is "object", so special case here.
|
||
if (value === null) {
|
||
return ctx.stylize('null', 'null');
|
||
}
|
||
}
|
||
|
||
|
||
function formatError(value) {
|
||
return '[' + Error.prototype.toString.call(value) + ']';
|
||
}
|
||
|
||
|
||
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
|
||
var output = [];
|
||
for (var i = 0, l = value.length; i < l; ++i) {
|
||
if (Object.prototype.hasOwnProperty.call(value, String(i))) {
|
||
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
||
String(i), true));
|
||
} else {
|
||
output.push('');
|
||
}
|
||
}
|
||
keys.forEach(function(key) {
|
||
if (!key.match(/^\d+$/)) {
|
||
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
||
key, true));
|
||
}
|
||
});
|
||
return output;
|
||
}
|
||
|
||
|
||
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
|
||
var name, str;
|
||
if (value.__lookupGetter__) {
|
||
if (value.__lookupGetter__(key)) {
|
||
if (value.__lookupSetter__(key)) {
|
||
str = ctx.stylize('[Getter/Setter]', 'special');
|
||
} else {
|
||
str = ctx.stylize('[Getter]', 'special');
|
||
}
|
||
} else {
|
||
if (value.__lookupSetter__(key)) {
|
||
str = ctx.stylize('[Setter]', 'special');
|
||
}
|
||
}
|
||
}
|
||
if (visibleKeys.indexOf(key) < 0) {
|
||
name = '[' + key + ']';
|
||
}
|
||
if (!str) {
|
||
if (ctx.seen.indexOf(value[key]) < 0) {
|
||
if (recurseTimes === null) {
|
||
str = formatValue(ctx, value[key], null);
|
||
} else {
|
||
str = formatValue(ctx, value[key], recurseTimes - 1);
|
||
}
|
||
if (str.indexOf('\n') > -1) {
|
||
if (array) {
|
||
str = str.split('\n').map(function(line) {
|
||
return ' ' + line;
|
||
}).join('\n').substr(2);
|
||
} else {
|
||
str = '\n' + str.split('\n').map(function(line) {
|
||
return ' ' + line;
|
||
}).join('\n');
|
||
}
|
||
}
|
||
} else {
|
||
str = ctx.stylize('[Circular]', 'special');
|
||
}
|
||
}
|
||
if (typeof name === 'undefined') {
|
||
if (array && key.match(/^\d+$/)) {
|
||
return str;
|
||
}
|
||
name = JSON.stringify('' + key);
|
||
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
||
name = name.substr(1, name.length - 2);
|
||
name = ctx.stylize(name, 'name');
|
||
} else {
|
||
name = name.replace(/'/g, "\\'")
|
||
.replace(/\\"/g, '"')
|
||
.replace(/(^"|"$)/g, "'");
|
||
name = ctx.stylize(name, 'string');
|
||
}
|
||
}
|
||
|
||
return name + ': ' + str;
|
||
}
|
||
|
||
|
||
function reduceToSingleString(output, base, braces) {
|
||
var numLinesEst = 0;
|
||
var length = output.reduce(function(prev, cur) {
|
||
numLinesEst++;
|
||
if (cur.indexOf('\n') >= 0) numLinesEst++;
|
||
return prev + cur.length + 1;
|
||
}, 0);
|
||
|
||
if (length > 60) {
|
||
return braces[0] +
|
||
(base === '' ? '' : base + '\n ') +
|
||
' ' +
|
||
output.join(',\n ') +
|
||
' ' +
|
||
braces[1];
|
||
}
|
||
|
||
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
|
||
}
|
||
|
||
function isArray(ar) {
|
||
return Array.isArray(ar) ||
|
||
(typeof ar === 'object' && objectToString(ar) === '[object Array]');
|
||
}
|
||
|
||
function isRegExp(re) {
|
||
return typeof re === 'object' && objectToString(re) === '[object RegExp]';
|
||
}
|
||
|
||
function isDate(d) {
|
||
return typeof d === 'object' && objectToString(d) === '[object Date]';
|
||
}
|
||
|
||
function isError(e) {
|
||
return typeof e === 'object' && objectToString(e) === '[object Error]';
|
||
}
|
||
|
||
function objectToString(o) {
|
||
return Object.prototype.toString.call(o);
|
||
}
|
||
|
||
},{"./getEnumerableProperties":27,"./getName":29,"./getProperties":31}],34:[function(require,module,exports){
|
||
/*!
|
||
* Chai - flag utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/*!
|
||
* Module dependancies
|
||
*/
|
||
|
||
var inspect = require('./inspect');
|
||
var config = require('../config');
|
||
|
||
/**
|
||
* ### .objDisplay (object)
|
||
*
|
||
* Determines if an object or an array matches
|
||
* criteria to be inspected in-line for error
|
||
* messages or should be truncated.
|
||
*
|
||
* @param {Mixed} javascript object to inspect
|
||
* @name objDisplay
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function (obj) {
|
||
var str = inspect(obj)
|
||
, type = Object.prototype.toString.call(obj);
|
||
|
||
if (config.truncateThreshold && str.length >= config.truncateThreshold) {
|
||
if (type === '[object Function]') {
|
||
return !obj.name || obj.name === ''
|
||
? '[Function]'
|
||
: '[Function: ' + obj.name + ']';
|
||
} else if (type === '[object Array]') {
|
||
return '[ Array(' + obj.length + ') ]';
|
||
} else if (type === '[object Object]') {
|
||
var keys = Object.keys(obj)
|
||
, kstr = keys.length > 2
|
||
? keys.splice(0, 2).join(', ') + ', ...'
|
||
: keys.join(', ');
|
||
return '{ Object (' + kstr + ') }';
|
||
} else {
|
||
return str;
|
||
}
|
||
} else {
|
||
return str;
|
||
}
|
||
};
|
||
|
||
},{"../config":17,"./inspect":33}],35:[function(require,module,exports){
|
||
/*!
|
||
* Chai - overwriteChainableMethod utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/**
|
||
* ### overwriteChainableMethod (ctx, name, fn)
|
||
*
|
||
* Overwites an already existing chainable method
|
||
* and provides access to the previous function or
|
||
* property. Must return functions to be used for
|
||
* name.
|
||
*
|
||
* utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',
|
||
* function (_super) {
|
||
* }
|
||
* , function (_super) {
|
||
* }
|
||
* );
|
||
*
|
||
* Can also be accessed directly from `chai.Assertion`.
|
||
*
|
||
* chai.Assertion.overwriteChainableMethod('foo', fn, fn);
|
||
*
|
||
* Then can be used as any other assertion.
|
||
*
|
||
* expect(myFoo).to.have.length(3);
|
||
* expect(myFoo).to.have.length.above(3);
|
||
*
|
||
* @param {Object} ctx object whose method / property is to be overwritten
|
||
* @param {String} name of method / property to overwrite
|
||
* @param {Function} method function that returns a function to be used for name
|
||
* @param {Function} chainingBehavior function that returns a function to be used for property
|
||
* @name overwriteChainableMethod
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function (ctx, name, method, chainingBehavior) {
|
||
var chainableBehavior = ctx.__methods[name];
|
||
|
||
var _chainingBehavior = chainableBehavior.chainingBehavior;
|
||
chainableBehavior.chainingBehavior = function () {
|
||
var result = chainingBehavior(_chainingBehavior).call(this);
|
||
return result === undefined ? this : result;
|
||
};
|
||
|
||
var _method = chainableBehavior.method;
|
||
chainableBehavior.method = function () {
|
||
var result = method(_method).apply(this, arguments);
|
||
return result === undefined ? this : result;
|
||
};
|
||
};
|
||
|
||
},{}],36:[function(require,module,exports){
|
||
/*!
|
||
* Chai - overwriteMethod utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/**
|
||
* ### overwriteMethod (ctx, name, fn)
|
||
*
|
||
* Overwites an already existing method and provides
|
||
* access to previous function. Must return function
|
||
* to be used for name.
|
||
*
|
||
* utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {
|
||
* return function (str) {
|
||
* var obj = utils.flag(this, 'object');
|
||
* if (obj instanceof Foo) {
|
||
* new chai.Assertion(obj.value).to.equal(str);
|
||
* } else {
|
||
* _super.apply(this, arguments);
|
||
* }
|
||
* }
|
||
* });
|
||
*
|
||
* Can also be accessed directly from `chai.Assertion`.
|
||
*
|
||
* chai.Assertion.overwriteMethod('foo', fn);
|
||
*
|
||
* Then can be used as any other assertion.
|
||
*
|
||
* expect(myFoo).to.equal('bar');
|
||
*
|
||
* @param {Object} ctx object whose method is to be overwritten
|
||
* @param {String} name of method to overwrite
|
||
* @param {Function} method function that returns a function to be used for name
|
||
* @name overwriteMethod
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function (ctx, name, method) {
|
||
var _method = ctx[name]
|
||
, _super = function () { return this; };
|
||
|
||
if (_method && 'function' === typeof _method)
|
||
_super = _method;
|
||
|
||
ctx[name] = function () {
|
||
var result = method(_super).apply(this, arguments);
|
||
return result === undefined ? this : result;
|
||
}
|
||
};
|
||
|
||
},{}],37:[function(require,module,exports){
|
||
/*!
|
||
* Chai - overwriteProperty utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/**
|
||
* ### overwriteProperty (ctx, name, fn)
|
||
*
|
||
* Overwites an already existing property getter and provides
|
||
* access to previous value. Must return function to use as getter.
|
||
*
|
||
* utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {
|
||
* return function () {
|
||
* var obj = utils.flag(this, 'object');
|
||
* if (obj instanceof Foo) {
|
||
* new chai.Assertion(obj.name).to.equal('bar');
|
||
* } else {
|
||
* _super.call(this);
|
||
* }
|
||
* }
|
||
* });
|
||
*
|
||
*
|
||
* Can also be accessed directly from `chai.Assertion`.
|
||
*
|
||
* chai.Assertion.overwriteProperty('foo', fn);
|
||
*
|
||
* Then can be used as any other assertion.
|
||
*
|
||
* expect(myFoo).to.be.ok;
|
||
*
|
||
* @param {Object} ctx object whose property is to be overwritten
|
||
* @param {String} name of property to overwrite
|
||
* @param {Function} getter function that returns a getter function to be used for name
|
||
* @name overwriteProperty
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function (ctx, name, getter) {
|
||
var _get = Object.getOwnPropertyDescriptor(ctx, name)
|
||
, _super = function () {};
|
||
|
||
if (_get && 'function' === typeof _get.get)
|
||
_super = _get.get
|
||
|
||
Object.defineProperty(ctx, name,
|
||
{ get: function () {
|
||
var result = getter(_super).call(this);
|
||
return result === undefined ? this : result;
|
||
}
|
||
, configurable: true
|
||
});
|
||
};
|
||
|
||
},{}],38:[function(require,module,exports){
|
||
/*!
|
||
* Chai - test utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/*!
|
||
* Module dependancies
|
||
*/
|
||
|
||
var flag = require('./flag');
|
||
|
||
/**
|
||
* # test(object, expression)
|
||
*
|
||
* Test and object for expression.
|
||
*
|
||
* @param {Object} object (constructed Assertion)
|
||
* @param {Arguments} chai.Assertion.prototype.assert arguments
|
||
*/
|
||
|
||
module.exports = function (obj, args) {
|
||
var negate = flag(obj, 'negate')
|
||
, expr = args[0];
|
||
return negate ? !expr : expr;
|
||
};
|
||
|
||
},{"./flag":25}],39:[function(require,module,exports){
|
||
/*!
|
||
* Chai - transferFlags utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/**
|
||
* ### transferFlags(assertion, object, includeAll = true)
|
||
*
|
||
* Transfer all the flags for `assertion` to `object`. If
|
||
* `includeAll` is set to `false`, then the base Chai
|
||
* assertion flags (namely `object`, `ssfi`, and `message`)
|
||
* will not be transferred.
|
||
*
|
||
*
|
||
* var newAssertion = new Assertion();
|
||
* utils.transferFlags(assertion, newAssertion);
|
||
*
|
||
* var anotherAsseriton = new Assertion(myObj);
|
||
* utils.transferFlags(assertion, anotherAssertion, false);
|
||
*
|
||
* @param {Assertion} assertion the assertion to transfer the flags from
|
||
* @param {Object} object the object to transfer the flags too; usually a new assertion
|
||
* @param {Boolean} includeAll
|
||
* @name getAllFlags
|
||
* @api private
|
||
*/
|
||
|
||
module.exports = function (assertion, object, includeAll) {
|
||
var flags = assertion.__flags || (assertion.__flags = Object.create(null));
|
||
|
||
if (!object.__flags) {
|
||
object.__flags = Object.create(null);
|
||
}
|
||
|
||
includeAll = arguments.length === 3 ? includeAll : true;
|
||
|
||
for (var flag in flags) {
|
||
if (includeAll ||
|
||
(flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {
|
||
object.__flags[flag] = flags[flag];
|
||
}
|
||
}
|
||
};
|
||
|
||
},{}],40:[function(require,module,exports){
|
||
/*!
|
||
* Chai - type utility
|
||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/*!
|
||
* Detectable javascript natives
|
||
*/
|
||
|
||
var natives = {
|
||
'[object Arguments]': 'arguments'
|
||
, '[object Array]': 'array'
|
||
, '[object Date]': 'date'
|
||
, '[object Function]': 'function'
|
||
, '[object Number]': 'number'
|
||
, '[object RegExp]': 'regexp'
|
||
, '[object String]': 'string'
|
||
};
|
||
|
||
/**
|
||
* ### type(object)
|
||
*
|
||
* Better implementation of `typeof` detection that can
|
||
* be used cross-browser. Handles the inconsistencies of
|
||
* Array, `null`, and `undefined` detection.
|
||
*
|
||
* utils.type({}) // 'object'
|
||
* utils.type(null) // `null'
|
||
* utils.type(undefined) // `undefined`
|
||
* utils.type([]) // `array`
|
||
*
|
||
* @param {Mixed} object to detect type of
|
||
* @name type
|
||
* @api private
|
||
*/
|
||
|
||
module.exports = function (obj) {
|
||
var str = Object.prototype.toString.call(obj);
|
||
if (natives[str]) return natives[str];
|
||
if (obj === null) return 'null';
|
||
if (obj === undefined) return 'undefined';
|
||
if (obj === Object(obj)) return 'object';
|
||
return typeof obj;
|
||
};
|
||
|
||
},{}],41:[function(require,module,exports){
|
||
/*!
|
||
* assertion-error
|
||
* Copyright(c) 2013 Jake Luer <jake@qualiancy.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/*!
|
||
* Return a function that will copy properties from
|
||
* one object to another excluding any originally
|
||
* listed. Returned function will create a new `{}`.
|
||
*
|
||
* @param {String} excluded properties ...
|
||
* @return {Function}
|
||
*/
|
||
|
||
function exclude () {
|
||
var excludes = [].slice.call(arguments);
|
||
|
||
function excludeProps (res, obj) {
|
||
Object.keys(obj).forEach(function (key) {
|
||
if (!~excludes.indexOf(key)) res[key] = obj[key];
|
||
});
|
||
}
|
||
|
||
return function extendExclude () {
|
||
var args = [].slice.call(arguments)
|
||
, i = 0
|
||
, res = {};
|
||
|
||
for (; i < args.length; i++) {
|
||
excludeProps(res, args[i]);
|
||
}
|
||
|
||
return res;
|
||
};
|
||
};
|
||
|
||
/*!
|
||
* Primary Exports
|
||
*/
|
||
|
||
module.exports = AssertionError;
|
||
|
||
/**
|
||
* ### AssertionError
|
||
*
|
||
* An extension of the JavaScript `Error` constructor for
|
||
* assertion and validation scenarios.
|
||
*
|
||
* @param {String} message
|
||
* @param {Object} properties to include (optional)
|
||
* @param {callee} start stack function (optional)
|
||
*/
|
||
|
||
function AssertionError (message, _props, ssf) {
|
||
var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')
|
||
, props = extend(_props || {});
|
||
|
||
// default values
|
||
this.message = message || 'Unspecified AssertionError';
|
||
this.showDiff = false;
|
||
|
||
// copy from properties
|
||
for (var key in props) {
|
||
this[key] = props[key];
|
||
}
|
||
|
||
// capture stack trace
|
||
ssf = ssf || arguments.callee;
|
||
if (ssf && Error.captureStackTrace) {
|
||
Error.captureStackTrace(this, ssf);
|
||
}
|
||
}
|
||
|
||
/*!
|
||
* Inherit from Error.prototype
|
||
*/
|
||
|
||
AssertionError.prototype = Object.create(Error.prototype);
|
||
|
||
/*!
|
||
* Statically set name
|
||
*/
|
||
|
||
AssertionError.prototype.name = 'AssertionError';
|
||
|
||
/*!
|
||
* Ensure correct constructor
|
||
*/
|
||
|
||
AssertionError.prototype.constructor = AssertionError;
|
||
|
||
/**
|
||
* Allow errors to be converted to JSON for static transfer.
|
||
*
|
||
* @param {Boolean} include stack (default: `true`)
|
||
* @return {Object} object that can be `JSON.stringify`
|
||
*/
|
||
|
||
AssertionError.prototype.toJSON = function (stack) {
|
||
var extend = exclude('constructor', 'toJSON', 'stack')
|
||
, props = extend({ name: this.name }, this);
|
||
|
||
// include stack if exists and not turned off
|
||
if (false !== stack && this.stack) {
|
||
props.stack = this.stack;
|
||
}
|
||
|
||
return props;
|
||
};
|
||
|
||
},{}],42:[function(require,module,exports){
|
||
module.exports = require('./lib/eql');
|
||
|
||
},{"./lib/eql":43}],43:[function(require,module,exports){
|
||
/*!
|
||
* deep-eql
|
||
* Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/*!
|
||
* Module dependencies
|
||
*/
|
||
|
||
var type = require('type-detect');
|
||
|
||
/*!
|
||
* Buffer.isBuffer browser shim
|
||
*/
|
||
|
||
var Buffer;
|
||
try { Buffer = require('buffer').Buffer; }
|
||
catch(ex) {
|
||
Buffer = {};
|
||
Buffer.isBuffer = function() { return false; }
|
||
}
|
||
|
||
/*!
|
||
* Primary Export
|
||
*/
|
||
|
||
module.exports = deepEqual;
|
||
|
||
/**
|
||
* Assert super-strict (egal) equality between
|
||
* two objects of any type.
|
||
*
|
||
* @param {Mixed} a
|
||
* @param {Mixed} b
|
||
* @param {Array} memoised (optional)
|
||
* @return {Boolean} equal match
|
||
*/
|
||
|
||
function deepEqual(a, b, m) {
|
||
if (sameValue(a, b)) {
|
||
return true;
|
||
} else if ('date' === type(a)) {
|
||
return dateEqual(a, b);
|
||
} else if ('regexp' === type(a)) {
|
||
return regexpEqual(a, b);
|
||
} else if (Buffer.isBuffer(a)) {
|
||
return bufferEqual(a, b);
|
||
} else if ('arguments' === type(a)) {
|
||
return argumentsEqual(a, b, m);
|
||
} else if (!typeEqual(a, b)) {
|
||
return false;
|
||
} else if (('object' !== type(a) && 'object' !== type(b))
|
||
&& ('array' !== type(a) && 'array' !== type(b))) {
|
||
return sameValue(a, b);
|
||
} else {
|
||
return objectEqual(a, b, m);
|
||
}
|
||
}
|
||
|
||
/*!
|
||
* Strict (egal) equality test. Ensures that NaN always
|
||
* equals NaN and `-0` does not equal `+0`.
|
||
*
|
||
* @param {Mixed} a
|
||
* @param {Mixed} b
|
||
* @return {Boolean} equal match
|
||
*/
|
||
|
||
function sameValue(a, b) {
|
||
if (a === b) return a !== 0 || 1 / a === 1 / b;
|
||
return a !== a && b !== b;
|
||
}
|
||
|
||
/*!
|
||
* Compare the types of two given objects and
|
||
* return if they are equal. Note that an Array
|
||
* has a type of `array` (not `object`) and arguments
|
||
* have a type of `arguments` (not `array`/`object`).
|
||
*
|
||
* @param {Mixed} a
|
||
* @param {Mixed} b
|
||
* @return {Boolean} result
|
||
*/
|
||
|
||
function typeEqual(a, b) {
|
||
return type(a) === type(b);
|
||
}
|
||
|
||
/*!
|
||
* Compare two Date objects by asserting that
|
||
* the time values are equal using `saveValue`.
|
||
*
|
||
* @param {Date} a
|
||
* @param {Date} b
|
||
* @return {Boolean} result
|
||
*/
|
||
|
||
function dateEqual(a, b) {
|
||
if ('date' !== type(b)) return false;
|
||
return sameValue(a.getTime(), b.getTime());
|
||
}
|
||
|
||
/*!
|
||
* Compare two regular expressions by converting them
|
||
* to string and checking for `sameValue`.
|
||
*
|
||
* @param {RegExp} a
|
||
* @param {RegExp} b
|
||
* @return {Boolean} result
|
||
*/
|
||
|
||
function regexpEqual(a, b) {
|
||
if ('regexp' !== type(b)) return false;
|
||
return sameValue(a.toString(), b.toString());
|
||
}
|
||
|
||
/*!
|
||
* Assert deep equality of two `arguments` objects.
|
||
* Unfortunately, these must be sliced to arrays
|
||
* prior to test to ensure no bad behavior.
|
||
*
|
||
* @param {Arguments} a
|
||
* @param {Arguments} b
|
||
* @param {Array} memoize (optional)
|
||
* @return {Boolean} result
|
||
*/
|
||
|
||
function argumentsEqual(a, b, m) {
|
||
if ('arguments' !== type(b)) return false;
|
||
a = [].slice.call(a);
|
||
b = [].slice.call(b);
|
||
return deepEqual(a, b, m);
|
||
}
|
||
|
||
/*!
|
||
* Get enumerable properties of a given object.
|
||
*
|
||
* @param {Object} a
|
||
* @return {Array} property names
|
||
*/
|
||
|
||
function enumerable(a) {
|
||
var res = [];
|
||
for (var key in a) res.push(key);
|
||
return res;
|
||
}
|
||
|
||
/*!
|
||
* Simple equality for flat iterable objects
|
||
* such as Arrays or Node.js buffers.
|
||
*
|
||
* @param {Iterable} a
|
||
* @param {Iterable} b
|
||
* @return {Boolean} result
|
||
*/
|
||
|
||
function iterableEqual(a, b) {
|
||
if (a.length !== b.length) return false;
|
||
|
||
var i = 0;
|
||
var match = true;
|
||
|
||
for (; i < a.length; i++) {
|
||
if (a[i] !== b[i]) {
|
||
match = false;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return match;
|
||
}
|
||
|
||
/*!
|
||
* Extension to `iterableEqual` specifically
|
||
* for Node.js Buffers.
|
||
*
|
||
* @param {Buffer} a
|
||
* @param {Mixed} b
|
||
* @return {Boolean} result
|
||
*/
|
||
|
||
function bufferEqual(a, b) {
|
||
if (!Buffer.isBuffer(b)) return false;
|
||
return iterableEqual(a, b);
|
||
}
|
||
|
||
/*!
|
||
* Block for `objectEqual` ensuring non-existing
|
||
* values don't get in.
|
||
*
|
||
* @param {Mixed} object
|
||
* @return {Boolean} result
|
||
*/
|
||
|
||
function isValue(a) {
|
||
return a !== null && a !== undefined;
|
||
}
|
||
|
||
/*!
|
||
* Recursively check the equality of two objects.
|
||
* Once basic sameness has been established it will
|
||
* defer to `deepEqual` for each enumerable key
|
||
* in the object.
|
||
*
|
||
* @param {Mixed} a
|
||
* @param {Mixed} b
|
||
* @return {Boolean} result
|
||
*/
|
||
|
||
function objectEqual(a, b, m) {
|
||
if (!isValue(a) || !isValue(b)) {
|
||
return false;
|
||
}
|
||
|
||
if (a.prototype !== b.prototype) {
|
||
return false;
|
||
}
|
||
|
||
var i;
|
||
if (m) {
|
||
for (i = 0; i < m.length; i++) {
|
||
if ((m[i][0] === a && m[i][1] === b)
|
||
|| (m[i][0] === b && m[i][1] === a)) {
|
||
return true;
|
||
}
|
||
}
|
||
} else {
|
||
m = [];
|
||
}
|
||
|
||
try {
|
||
var ka = enumerable(a);
|
||
var kb = enumerable(b);
|
||
} catch (ex) {
|
||
return false;
|
||
}
|
||
|
||
ka.sort();
|
||
kb.sort();
|
||
|
||
if (!iterableEqual(ka, kb)) {
|
||
return false;
|
||
}
|
||
|
||
m.push([ a, b ]);
|
||
|
||
var key;
|
||
for (i = ka.length - 1; i >= 0; i--) {
|
||
key = ka[i];
|
||
if (!deepEqual(a[key], b[key], m)) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
},{"buffer":57,"type-detect":44}],44:[function(require,module,exports){
|
||
module.exports = require('./lib/type');
|
||
|
||
},{"./lib/type":45}],45:[function(require,module,exports){
|
||
/*!
|
||
* type-detect
|
||
* Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
|
||
* MIT Licensed
|
||
*/
|
||
|
||
/*!
|
||
* Primary Exports
|
||
*/
|
||
|
||
var exports = module.exports = getType;
|
||
|
||
/*!
|
||
* Detectable javascript natives
|
||
*/
|
||
|
||
var natives = {
|
||
'[object Array]': 'array'
|
||
, '[object RegExp]': 'regexp'
|
||
, '[object Function]': 'function'
|
||
, '[object Arguments]': 'arguments'
|
||
, '[object Date]': 'date'
|
||
};
|
||
|
||
/**
|
||
* ### typeOf (obj)
|
||
*
|
||
* Use several different techniques to determine
|
||
* the type of object being tested.
|
||
*
|
||
*
|
||
* @param {Mixed} object
|
||
* @return {String} object type
|
||
* @api public
|
||
*/
|
||
|
||
function getType (obj) {
|
||
var str = Object.prototype.toString.call(obj);
|
||
if (natives[str]) return natives[str];
|
||
if (obj === null) return 'null';
|
||
if (obj === undefined) return 'undefined';
|
||
if (obj === Object(obj)) return 'object';
|
||
return typeof obj;
|
||
}
|
||
|
||
exports.Library = Library;
|
||
|
||
/**
|
||
* ### Library
|
||
*
|
||
* Create a repository for custom type detection.
|
||
*
|
||
* ```js
|
||
* var lib = new type.Library;
|
||
* ```
|
||
*
|
||
*/
|
||
|
||
function Library () {
|
||
this.tests = {};
|
||
}
|
||
|
||
/**
|
||
* #### .of (obj)
|
||
*
|
||
* Expose replacement `typeof` detection to the library.
|
||
*
|
||
* ```js
|
||
* if ('string' === lib.of('hello world')) {
|
||
* // ...
|
||
* }
|
||
* ```
|
||
*
|
||
* @param {Mixed} object to test
|
||
* @return {String} type
|
||
*/
|
||
|
||
Library.prototype.of = getType;
|
||
|
||
/**
|
||
* #### .define (type, test)
|
||
*
|
||
* Add a test to for the `.test()` assertion.
|
||
*
|
||
* Can be defined as a regular expression:
|
||
*
|
||
* ```js
|
||
* lib.define('int', /^[0-9]+$/);
|
||
* ```
|
||
*
|
||
* ... or as a function:
|
||
*
|
||
* ```js
|
||
* lib.define('bln', function (obj) {
|
||
* if ('boolean' === lib.of(obj)) return true;
|
||
* var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];
|
||
* if ('string' === lib.of(obj)) obj = obj.toLowerCase();
|
||
* return !! ~blns.indexOf(obj);
|
||
* });
|
||
* ```
|
||
*
|
||
* @param {String} type
|
||
* @param {RegExp|Function} test
|
||
* @api public
|
||
*/
|
||
|
||
Library.prototype.define = function (type, test) {
|
||
if (arguments.length === 1) return this.tests[type];
|
||
this.tests[type] = test;
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* #### .test (obj, test)
|
||
*
|
||
* Assert that an object is of type. Will first
|
||
* check natives, and if that does not pass it will
|
||
* use the user defined custom tests.
|
||
*
|
||
* ```js
|
||
* assert(lib.test('1', 'int'));
|
||
* assert(lib.test('yes', 'bln'));
|
||
* ```
|
||
*
|
||
* @param {Mixed} object
|
||
* @param {String} type
|
||
* @return {Boolean} result
|
||
* @api public
|
||
*/
|
||
|
||
Library.prototype.test = function (obj, type) {
|
||
if (type === getType(obj)) return true;
|
||
var test = this.tests[type];
|
||
|
||
if (test && 'regexp' === getType(test)) {
|
||
return test.test(obj);
|
||
} else if (test && 'function' === getType(test)) {
|
||
return test(obj);
|
||
} else {
|
||
throw new ReferenceError('Type test "' + type + '" not defined or invalid.');
|
||
}
|
||
};
|
||
|
||
},{}],46:[function(require,module,exports){
|
||
// Generated by CoffeeScript 1.6.3
|
||
var coffee, compile, compileFile, ext, extensions, formatSourcePosition, fs, getSourceMap, helpers, loadFile, patchStackTrace, patched, path, sourceMaps, _i, _len,
|
||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||
|
||
fs = require('fs');
|
||
|
||
path = require('path');
|
||
|
||
helpers = require('coffee-script/lib/coffee-script/helpers');
|
||
|
||
coffee = require('coffee-script');
|
||
|
||
if (parseInt(coffee.VERSION.replace(/\D+/g, '')) < 162) {
|
||
throw new Error('`coffee-errors` expects `coffee-script@~1.6.2`');
|
||
}
|
||
|
||
compile = coffee.compile;
|
||
|
||
patched = false;
|
||
|
||
extensions = ['.coffee', '.litcoffee', '.coffee.md'];
|
||
|
||
sourceMaps = {};
|
||
|
||
patchStackTrace = function() {
|
||
var oldPrepareStackTrack;
|
||
if (patched) {
|
||
return;
|
||
}
|
||
patched = true;
|
||
oldPrepareStackTrack = Error.prepareStackTrace;
|
||
return Error.prepareStackTrace = function(err, stack) {
|
||
var e, frame, frames, getSourceMapping, sourceFiles, _ref;
|
||
try {
|
||
sourceFiles = {};
|
||
getSourceMapping = function(filename, line, column) {
|
||
var answer, sourceMap;
|
||
sourceMap = getSourceMap(filename);
|
||
if (sourceMap) {
|
||
answer = sourceMap.sourceLocation([line - 1, column - 1]);
|
||
}
|
||
if (answer) {
|
||
return [answer[0] + 1, answer[1] + 1];
|
||
} else {
|
||
return null;
|
||
}
|
||
};
|
||
frames = (function() {
|
||
var _i, _len, _results;
|
||
_results = [];
|
||
for (_i = 0, _len = stack.length; _i < _len; _i++) {
|
||
frame = stack[_i];
|
||
if (frame.getFunction() === coffee.run) {
|
||
break;
|
||
}
|
||
_results.push(" at " + (formatSourcePosition(frame, getSourceMapping)));
|
||
}
|
||
return _results;
|
||
})();
|
||
return "" + err.name + ": " + ((_ref = err.message) != null ? _ref : '') + "\n" + (frames.join('\n')) + "\n";
|
||
} catch (_error) {
|
||
e = _error;
|
||
Error.prepareStackTrace = oldPrepareStackTrack;
|
||
"`coffee-errors` failed during stack parsing, falling back onto the previous parser. " + err.stack;
|
||
return err.stack;
|
||
}
|
||
};
|
||
};
|
||
|
||
formatSourcePosition = function(frame, getSourceMapping) {
|
||
var as, column, fileLocation, fileName, functionName, isConstructor, isMethodCall, line, methodName, source, tp, typeName;
|
||
fileName = void 0;
|
||
fileLocation = '';
|
||
if (frame.isNative()) {
|
||
fileLocation = "native";
|
||
} else {
|
||
if (frame.isEval()) {
|
||
fileName = frame.getScriptNameOrSourceURL();
|
||
if (!fileName) {
|
||
fileLocation = "" + (frame.getEvalOrigin()) + ", ";
|
||
}
|
||
} else {
|
||
fileName = frame.getFileName();
|
||
}
|
||
fileName || (fileName = "<anonymous>");
|
||
line = frame.getLineNumber();
|
||
column = frame.getColumnNumber();
|
||
source = getSourceMapping(fileName, line, column);
|
||
fileLocation = source ? "" + fileName + ":" + source[0] + ":" + source[1] : "" + fileName + ":" + line + ":" + column;
|
||
}
|
||
functionName = frame.getFunctionName();
|
||
isConstructor = frame.isConstructor();
|
||
isMethodCall = !(frame.isToplevel() || isConstructor);
|
||
if (isMethodCall) {
|
||
methodName = frame.getMethodName();
|
||
typeName = frame.getTypeName();
|
||
if (functionName) {
|
||
tp = as = '';
|
||
if (typeName && functionName.indexOf(typeName)) {
|
||
tp = "" + typeName + ".";
|
||
}
|
||
if (methodName && functionName.indexOf("." + methodName) !== functionName.length - methodName.length - 1) {
|
||
as = " [as " + methodName + "]";
|
||
}
|
||
return "" + tp + functionName + as + " (" + fileLocation + ")";
|
||
} else {
|
||
return "" + typeName + "." + (methodName || '<anonymous>') + " (" + fileLocation + ")";
|
||
}
|
||
} else if (isConstructor) {
|
||
return "new " + (functionName || '<anonymous>') + " (" + fileLocation + ")";
|
||
} else if (functionName) {
|
||
return "" + functionName + " (" + fileLocation + ")";
|
||
} else {
|
||
return fileLocation;
|
||
}
|
||
};
|
||
|
||
compileFile = function(filename, sourceMap) {
|
||
var answer, err, raw, stripped;
|
||
raw = fs.readFileSync(filename, 'utf8');
|
||
stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw;
|
||
try {
|
||
answer = compile(stripped, {
|
||
filename: filename,
|
||
sourceMap: sourceMap,
|
||
literate: helpers.isLiterate(filename)
|
||
});
|
||
} catch (_error) {
|
||
err = _error;
|
||
err.filename = filename;
|
||
err.code = stripped;
|
||
throw err;
|
||
}
|
||
return answer;
|
||
};
|
||
|
||
getSourceMap = function(filename) {
|
||
var answer, _ref;
|
||
if (sourceMaps[filename]) {
|
||
return sourceMaps[filename];
|
||
}
|
||
if (_ref = path.extname(filename), __indexOf.call(extensions, _ref) < 0) {
|
||
return;
|
||
}
|
||
answer = compileFile(filename, true);
|
||
return sourceMaps[filename] = answer.sourceMap;
|
||
};
|
||
|
||
loadFile = function(module, filename) {
|
||
var answer;
|
||
answer = compileFile(filename, false);
|
||
return module._compile(answer, filename);
|
||
};
|
||
|
||
if (require.extensions) {
|
||
for (_i = 0, _len = extensions.length; _i < _len; _i++) {
|
||
ext = extensions[_i];
|
||
require.extensions[ext] = loadFile;
|
||
}
|
||
}
|
||
|
||
patchStackTrace();
|
||
|
||
},{"coffee-script":47,"coffee-script/lib/coffee-script/helpers":48,"fs":56,"path":61}],47:[function(require,module,exports){
|
||
(function (process,global){
|
||
// Generated by CoffeeScript 1.8.0
|
||
(function() {
|
||
var Lexer, SourceMap, compile, ext, formatSourcePosition, fs, getSourceMap, helpers, lexer, parser, path, sourceMaps, vm, withPrettyErrors, _base, _i, _len, _ref,
|
||
__hasProp = {}.hasOwnProperty,
|
||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||
|
||
fs = require('fs');
|
||
|
||
vm = require('vm');
|
||
|
||
path = require('path');
|
||
|
||
Lexer = require('./lexer').Lexer;
|
||
|
||
parser = require('./parser').parser;
|
||
|
||
helpers = require('./helpers');
|
||
|
||
SourceMap = require('./sourcemap');
|
||
|
||
exports.VERSION = '1.8.0';
|
||
|
||
exports.FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md'];
|
||
|
||
exports.helpers = helpers;
|
||
|
||
withPrettyErrors = function(fn) {
|
||
return function(code, options) {
|
||
var err;
|
||
if (options == null) {
|
||
options = {};
|
||
}
|
||
try {
|
||
return fn.call(this, code, options);
|
||
} catch (_error) {
|
||
err = _error;
|
||
throw helpers.updateSyntaxError(err, code, options.filename);
|
||
}
|
||
};
|
||
};
|
||
|
||
exports.compile = compile = withPrettyErrors(function(code, options) {
|
||
var answer, currentColumn, currentLine, extend, fragment, fragments, header, js, map, merge, newLines, _i, _len;
|
||
merge = helpers.merge, extend = helpers.extend;
|
||
options = extend({}, options);
|
||
if (options.sourceMap) {
|
||
map = new SourceMap;
|
||
}
|
||
fragments = parser.parse(lexer.tokenize(code, options)).compileToFragments(options);
|
||
currentLine = 0;
|
||
if (options.header) {
|
||
currentLine += 1;
|
||
}
|
||
if (options.shiftLine) {
|
||
currentLine += 1;
|
||
}
|
||
currentColumn = 0;
|
||
js = "";
|
||
for (_i = 0, _len = fragments.length; _i < _len; _i++) {
|
||
fragment = fragments[_i];
|
||
if (options.sourceMap) {
|
||
if (fragment.locationData) {
|
||
map.add([fragment.locationData.first_line, fragment.locationData.first_column], [currentLine, currentColumn], {
|
||
noReplace: true
|
||
});
|
||
}
|
||
newLines = helpers.count(fragment.code, "\n");
|
||
currentLine += newLines;
|
||
if (newLines) {
|
||
currentColumn = fragment.code.length - (fragment.code.lastIndexOf("\n") + 1);
|
||
} else {
|
||
currentColumn += fragment.code.length;
|
||
}
|
||
}
|
||
js += fragment.code;
|
||
}
|
||
if (options.header) {
|
||
header = "Generated by CoffeeScript " + this.VERSION;
|
||
js = "// " + header + "\n" + js;
|
||
}
|
||
if (options.sourceMap) {
|
||
answer = {
|
||
js: js
|
||
};
|
||
answer.sourceMap = map;
|
||
answer.v3SourceMap = map.generate(options, code);
|
||
return answer;
|
||
} else {
|
||
return js;
|
||
}
|
||
});
|
||
|
||
exports.tokens = withPrettyErrors(function(code, options) {
|
||
return lexer.tokenize(code, options);
|
||
});
|
||
|
||
exports.nodes = withPrettyErrors(function(source, options) {
|
||
if (typeof source === 'string') {
|
||
return parser.parse(lexer.tokenize(source, options));
|
||
} else {
|
||
return parser.parse(source);
|
||
}
|
||
});
|
||
|
||
exports.run = function(code, options) {
|
||
var answer, dir, mainModule, _ref;
|
||
if (options == null) {
|
||
options = {};
|
||
}
|
||
mainModule = require.main;
|
||
mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.';
|
||
mainModule.moduleCache && (mainModule.moduleCache = {});
|
||
dir = options.filename ? path.dirname(fs.realpathSync(options.filename)) : fs.realpathSync('.');
|
||
mainModule.paths = require('module')._nodeModulePaths(dir);
|
||
if (!helpers.isCoffee(mainModule.filename) || require.extensions) {
|
||
answer = compile(code, options);
|
||
code = (_ref = answer.js) != null ? _ref : answer;
|
||
}
|
||
return mainModule._compile(code, mainModule.filename);
|
||
};
|
||
|
||
exports["eval"] = function(code, options) {
|
||
var Module, Script, js, k, o, r, sandbox, v, _i, _len, _module, _ref, _ref1, _require;
|
||
if (options == null) {
|
||
options = {};
|
||
}
|
||
if (!(code = code.trim())) {
|
||
return;
|
||
}
|
||
Script = vm.Script;
|
||
if (Script) {
|
||
if (options.sandbox != null) {
|
||
if (options.sandbox instanceof Script.createContext().constructor) {
|
||
sandbox = options.sandbox;
|
||
} else {
|
||
sandbox = Script.createContext();
|
||
_ref = options.sandbox;
|
||
for (k in _ref) {
|
||
if (!__hasProp.call(_ref, k)) continue;
|
||
v = _ref[k];
|
||
sandbox[k] = v;
|
||
}
|
||
}
|
||
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox;
|
||
} else {
|
||
sandbox = global;
|
||
}
|
||
sandbox.__filename = options.filename || 'eval';
|
||
sandbox.__dirname = path.dirname(sandbox.__filename);
|
||
if (!(sandbox !== global || sandbox.module || sandbox.require)) {
|
||
Module = require('module');
|
||
sandbox.module = _module = new Module(options.modulename || 'eval');
|
||
sandbox.require = _require = function(path) {
|
||
return Module._load(path, _module, true);
|
||
};
|
||
_module.filename = sandbox.__filename;
|
||
_ref1 = Object.getOwnPropertyNames(require);
|
||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||
r = _ref1[_i];
|
||
if (r !== 'paths') {
|
||
_require[r] = require[r];
|
||
}
|
||
}
|
||
_require.paths = _module.paths = Module._nodeModulePaths(process.cwd());
|
||
_require.resolve = function(request) {
|
||
return Module._resolveFilename(request, _module);
|
||
};
|
||
}
|
||
}
|
||
o = {};
|
||
for (k in options) {
|
||
if (!__hasProp.call(options, k)) continue;
|
||
v = options[k];
|
||
o[k] = v;
|
||
}
|
||
o.bare = true;
|
||
js = compile(code, o);
|
||
if (sandbox === global) {
|
||
return vm.runInThisContext(js);
|
||
} else {
|
||
return vm.runInContext(js, sandbox);
|
||
}
|
||
};
|
||
|
||
exports.register = function() {
|
||
return require('./register');
|
||
};
|
||
|
||
if (require.extensions) {
|
||
_ref = this.FILE_EXTENSIONS;
|
||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||
ext = _ref[_i];
|
||
if ((_base = require.extensions)[ext] == null) {
|
||
_base[ext] = function() {
|
||
throw new Error("Use CoffeeScript.register() or require the coffee-script/register module to require " + ext + " files.");
|
||
};
|
||
}
|
||
}
|
||
}
|
||
|
||
exports._compileFile = function(filename, sourceMap) {
|
||
var answer, err, raw, stripped;
|
||
if (sourceMap == null) {
|
||
sourceMap = false;
|
||
}
|
||
raw = fs.readFileSync(filename, 'utf8');
|
||
stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw;
|
||
try {
|
||
answer = compile(stripped, {
|
||
filename: filename,
|
||
sourceMap: sourceMap,
|
||
literate: helpers.isLiterate(filename)
|
||
});
|
||
} catch (_error) {
|
||
err = _error;
|
||
throw helpers.updateSyntaxError(err, stripped, filename);
|
||
}
|
||
return answer;
|
||
};
|
||
|
||
lexer = new Lexer;
|
||
|
||
parser.lexer = {
|
||
lex: function() {
|
||
var tag, token;
|
||
token = this.tokens[this.pos++];
|
||
if (token) {
|
||
tag = token[0], this.yytext = token[1], this.yylloc = token[2];
|
||
this.errorToken = token.origin || token;
|
||
this.yylineno = this.yylloc.first_line;
|
||
} else {
|
||
tag = '';
|
||
}
|
||
return tag;
|
||
},
|
||
setInput: function(tokens) {
|
||
this.tokens = tokens;
|
||
return this.pos = 0;
|
||
},
|
||
upcomingInput: function() {
|
||
return "";
|
||
}
|
||
};
|
||
|
||
parser.yy = require('./nodes');
|
||
|
||
parser.yy.parseError = function(message, _arg) {
|
||
var errorLoc, errorTag, errorText, errorToken, token, tokens, _ref1;
|
||
token = _arg.token;
|
||
_ref1 = parser.lexer, errorToken = _ref1.errorToken, tokens = _ref1.tokens;
|
||
errorTag = errorToken[0], errorText = errorToken[1], errorLoc = errorToken[2];
|
||
errorText = errorToken === tokens[tokens.length - 1] ? 'end of input' : errorTag === 'INDENT' || errorTag === 'OUTDENT' ? 'indentation' : helpers.nameWhitespaceCharacter(errorText);
|
||
return helpers.throwSyntaxError("unexpected " + errorText, errorLoc);
|
||
};
|
||
|
||
formatSourcePosition = function(frame, getSourceMapping) {
|
||
var as, column, fileLocation, fileName, functionName, isConstructor, isMethodCall, line, methodName, source, tp, typeName;
|
||
fileName = void 0;
|
||
fileLocation = '';
|
||
if (frame.isNative()) {
|
||
fileLocation = "native";
|
||
} else {
|
||
if (frame.isEval()) {
|
||
fileName = frame.getScriptNameOrSourceURL();
|
||
if (!fileName) {
|
||
fileLocation = "" + (frame.getEvalOrigin()) + ", ";
|
||
}
|
||
} else {
|
||
fileName = frame.getFileName();
|
||
}
|
||
fileName || (fileName = "<anonymous>");
|
||
line = frame.getLineNumber();
|
||
column = frame.getColumnNumber();
|
||
source = getSourceMapping(fileName, line, column);
|
||
fileLocation = source ? "" + fileName + ":" + source[0] + ":" + source[1] : "" + fileName + ":" + line + ":" + column;
|
||
}
|
||
functionName = frame.getFunctionName();
|
||
isConstructor = frame.isConstructor();
|
||
isMethodCall = !(frame.isToplevel() || isConstructor);
|
||
if (isMethodCall) {
|
||
methodName = frame.getMethodName();
|
||
typeName = frame.getTypeName();
|
||
if (functionName) {
|
||
tp = as = '';
|
||
if (typeName && functionName.indexOf(typeName)) {
|
||
tp = "" + typeName + ".";
|
||
}
|
||
if (methodName && functionName.indexOf("." + methodName) !== functionName.length - methodName.length - 1) {
|
||
as = " [as " + methodName + "]";
|
||
}
|
||
return "" + tp + functionName + as + " (" + fileLocation + ")";
|
||
} else {
|
||
return "" + typeName + "." + (methodName || '<anonymous>') + " (" + fileLocation + ")";
|
||
}
|
||
} else if (isConstructor) {
|
||
return "new " + (functionName || '<anonymous>') + " (" + fileLocation + ")";
|
||
} else if (functionName) {
|
||
return "" + functionName + " (" + fileLocation + ")";
|
||
} else {
|
||
return fileLocation;
|
||
}
|
||
};
|
||
|
||
sourceMaps = {};
|
||
|
||
getSourceMap = function(filename) {
|
||
var answer, _ref1;
|
||
if (sourceMaps[filename]) {
|
||
return sourceMaps[filename];
|
||
}
|
||
if (_ref1 = path != null ? path.extname(filename) : void 0, __indexOf.call(exports.FILE_EXTENSIONS, _ref1) < 0) {
|
||
return;
|
||
}
|
||
answer = exports._compileFile(filename, true);
|
||
return sourceMaps[filename] = answer.sourceMap;
|
||
};
|
||
|
||
Error.prepareStackTrace = function(err, stack) {
|
||
var frame, frames, getSourceMapping;
|
||
getSourceMapping = function(filename, line, column) {
|
||
var answer, sourceMap;
|
||
sourceMap = getSourceMap(filename);
|
||
if (sourceMap) {
|
||
answer = sourceMap.sourceLocation([line - 1, column - 1]);
|
||
}
|
||
if (answer) {
|
||
return [answer[0] + 1, answer[1] + 1];
|
||
} else {
|
||
return null;
|
||
}
|
||
};
|
||
frames = (function() {
|
||
var _j, _len1, _results;
|
||
_results = [];
|
||
for (_j = 0, _len1 = stack.length; _j < _len1; _j++) {
|
||
frame = stack[_j];
|
||
if (frame.getFunction() === exports.run) {
|
||
break;
|
||
}
|
||
_results.push(" at " + (formatSourcePosition(frame, getSourceMapping)));
|
||
}
|
||
return _results;
|
||
})();
|
||
return "" + (err.toString()) + "\n" + (frames.join('\n')) + "\n";
|
||
};
|
||
|
||
}).call(this);
|
||
|
||
}).call(this,require("1YiZ5S"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
},{"./helpers":48,"./lexer":49,"./nodes":50,"./parser":51,"./register":52,"./sourcemap":55,"1YiZ5S":62,"fs":56,"module":56,"path":61,"vm":65}],48:[function(require,module,exports){
|
||
(function (process){
|
||
// Generated by CoffeeScript 1.8.0
|
||
(function() {
|
||
var buildLocationData, extend, flatten, last, repeat, syntaxErrorToString, _ref;
|
||
|
||
exports.starts = function(string, literal, start) {
|
||
return literal === string.substr(start, literal.length);
|
||
};
|
||
|
||
exports.ends = function(string, literal, back) {
|
||
var len;
|
||
len = literal.length;
|
||
return literal === string.substr(string.length - len - (back || 0), len);
|
||
};
|
||
|
||
exports.repeat = repeat = function(str, n) {
|
||
var res;
|
||
res = '';
|
||
while (n > 0) {
|
||
if (n & 1) {
|
||
res += str;
|
||
}
|
||
n >>>= 1;
|
||
str += str;
|
||
}
|
||
return res;
|
||
};
|
||
|
||
exports.compact = function(array) {
|
||
var item, _i, _len, _results;
|
||
_results = [];
|
||
for (_i = 0, _len = array.length; _i < _len; _i++) {
|
||
item = array[_i];
|
||
if (item) {
|
||
_results.push(item);
|
||
}
|
||
}
|
||
return _results;
|
||
};
|
||
|
||
exports.count = function(string, substr) {
|
||
var num, pos;
|
||
num = pos = 0;
|
||
if (!substr.length) {
|
||
return 1 / 0;
|
||
}
|
||
while (pos = 1 + string.indexOf(substr, pos)) {
|
||
num++;
|
||
}
|
||
return num;
|
||
};
|
||
|
||
exports.merge = function(options, overrides) {
|
||
return extend(extend({}, options), overrides);
|
||
};
|
||
|
||
extend = exports.extend = function(object, properties) {
|
||
var key, val;
|
||
for (key in properties) {
|
||
val = properties[key];
|
||
object[key] = val;
|
||
}
|
||
return object;
|
||
};
|
||
|
||
exports.flatten = flatten = function(array) {
|
||
var element, flattened, _i, _len;
|
||
flattened = [];
|
||
for (_i = 0, _len = array.length; _i < _len; _i++) {
|
||
element = array[_i];
|
||
if (element instanceof Array) {
|
||
flattened = flattened.concat(flatten(element));
|
||
} else {
|
||
flattened.push(element);
|
||
}
|
||
}
|
||
return flattened;
|
||
};
|
||
|
||
exports.del = function(obj, key) {
|
||
var val;
|
||
val = obj[key];
|
||
delete obj[key];
|
||
return val;
|
||
};
|
||
|
||
exports.last = last = function(array, back) {
|
||
return array[array.length - (back || 0) - 1];
|
||
};
|
||
|
||
exports.some = (_ref = Array.prototype.some) != null ? _ref : function(fn) {
|
||
var e, _i, _len;
|
||
for (_i = 0, _len = this.length; _i < _len; _i++) {
|
||
e = this[_i];
|
||
if (fn(e)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
exports.invertLiterate = function(code) {
|
||
var line, lines, maybe_code;
|
||
maybe_code = true;
|
||
lines = (function() {
|
||
var _i, _len, _ref1, _results;
|
||
_ref1 = code.split('\n');
|
||
_results = [];
|
||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||
line = _ref1[_i];
|
||
if (maybe_code && /^([ ]{4}|[ ]{0,3}\t)/.test(line)) {
|
||
_results.push(line);
|
||
} else if (maybe_code = /^\s*$/.test(line)) {
|
||
_results.push(line);
|
||
} else {
|
||
_results.push('# ' + line);
|
||
}
|
||
}
|
||
return _results;
|
||
})();
|
||
return lines.join('\n');
|
||
};
|
||
|
||
buildLocationData = function(first, last) {
|
||
if (!last) {
|
||
return first;
|
||
} else {
|
||
return {
|
||
first_line: first.first_line,
|
||
first_column: first.first_column,
|
||
last_line: last.last_line,
|
||
last_column: last.last_column
|
||
};
|
||
}
|
||
};
|
||
|
||
exports.addLocationDataFn = function(first, last) {
|
||
return function(obj) {
|
||
if (((typeof obj) === 'object') && (!!obj['updateLocationDataIfMissing'])) {
|
||
obj.updateLocationDataIfMissing(buildLocationData(first, last));
|
||
}
|
||
return obj;
|
||
};
|
||
};
|
||
|
||
exports.locationDataToString = function(obj) {
|
||
var locationData;
|
||
if (("2" in obj) && ("first_line" in obj[2])) {
|
||
locationData = obj[2];
|
||
} else if ("first_line" in obj) {
|
||
locationData = obj;
|
||
}
|
||
if (locationData) {
|
||
return ("" + (locationData.first_line + 1) + ":" + (locationData.first_column + 1) + "-") + ("" + (locationData.last_line + 1) + ":" + (locationData.last_column + 1));
|
||
} else {
|
||
return "No location data";
|
||
}
|
||
};
|
||
|
||
exports.baseFileName = function(file, stripExt, useWinPathSep) {
|
||
var parts, pathSep;
|
||
if (stripExt == null) {
|
||
stripExt = false;
|
||
}
|
||
if (useWinPathSep == null) {
|
||
useWinPathSep = false;
|
||
}
|
||
pathSep = useWinPathSep ? /\\|\// : /\//;
|
||
parts = file.split(pathSep);
|
||
file = parts[parts.length - 1];
|
||
if (!(stripExt && file.indexOf('.') >= 0)) {
|
||
return file;
|
||
}
|
||
parts = file.split('.');
|
||
parts.pop();
|
||
if (parts[parts.length - 1] === 'coffee' && parts.length > 1) {
|
||
parts.pop();
|
||
}
|
||
return parts.join('.');
|
||
};
|
||
|
||
exports.isCoffee = function(file) {
|
||
return /\.((lit)?coffee|coffee\.md)$/.test(file);
|
||
};
|
||
|
||
exports.isLiterate = function(file) {
|
||
return /\.(litcoffee|coffee\.md)$/.test(file);
|
||
};
|
||
|
||
exports.throwSyntaxError = function(message, location) {
|
||
var error;
|
||
error = new SyntaxError(message);
|
||
error.location = location;
|
||
error.toString = syntaxErrorToString;
|
||
error.stack = error.toString();
|
||
throw error;
|
||
};
|
||
|
||
exports.updateSyntaxError = function(error, code, filename) {
|
||
if (error.toString === syntaxErrorToString) {
|
||
error.code || (error.code = code);
|
||
error.filename || (error.filename = filename);
|
||
error.stack = error.toString();
|
||
}
|
||
return error;
|
||
};
|
||
|
||
syntaxErrorToString = function() {
|
||
var codeLine, colorize, colorsEnabled, end, filename, first_column, first_line, last_column, last_line, marker, start, _ref1, _ref2;
|
||
if (!(this.code && this.location)) {
|
||
return Error.prototype.toString.call(this);
|
||
}
|
||
_ref1 = this.location, first_line = _ref1.first_line, first_column = _ref1.first_column, last_line = _ref1.last_line, last_column = _ref1.last_column;
|
||
if (last_line == null) {
|
||
last_line = first_line;
|
||
}
|
||
if (last_column == null) {
|
||
last_column = first_column;
|
||
}
|
||
filename = this.filename || '[stdin]';
|
||
codeLine = this.code.split('\n')[first_line];
|
||
start = first_column;
|
||
end = first_line === last_line ? last_column + 1 : codeLine.length;
|
||
marker = codeLine.slice(0, start).replace(/[^\s]/g, ' ') + repeat('^', end - start);
|
||
if (typeof process !== "undefined" && process !== null) {
|
||
colorsEnabled = process.stdout.isTTY && !process.env.NODE_DISABLE_COLORS;
|
||
}
|
||
if ((_ref2 = this.colorful) != null ? _ref2 : colorsEnabled) {
|
||
colorize = function(str) {
|
||
return "\x1B[1;31m" + str + "\x1B[0m";
|
||
};
|
||
codeLine = codeLine.slice(0, start) + colorize(codeLine.slice(start, end)) + codeLine.slice(end);
|
||
marker = colorize(marker);
|
||
}
|
||
return "" + filename + ":" + (first_line + 1) + ":" + (first_column + 1) + ": error: " + this.message + "\n" + codeLine + "\n" + marker;
|
||
};
|
||
|
||
exports.nameWhitespaceCharacter = function(string) {
|
||
switch (string) {
|
||
case ' ':
|
||
return 'space';
|
||
case '\n':
|
||
return 'newline';
|
||
case '\r':
|
||
return 'carriage return';
|
||
case '\t':
|
||
return 'tab';
|
||
default:
|
||
return string;
|
||
}
|
||
};
|
||
|
||
}).call(this);
|
||
|
||
}).call(this,require("1YiZ5S"))
|
||
},{"1YiZ5S":62}],49:[function(require,module,exports){
|
||
// Generated by CoffeeScript 1.8.0
|
||
(function() {
|
||
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, UNARY_MATH, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, repeat, starts, throwSyntaxError, _ref, _ref1,
|
||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||
|
||
_ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
|
||
|
||
_ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last, repeat = _ref1.repeat, invertLiterate = _ref1.invertLiterate, locationDataToString = _ref1.locationDataToString, throwSyntaxError = _ref1.throwSyntaxError;
|
||
|
||
exports.Lexer = Lexer = (function() {
|
||
function Lexer() {}
|
||
|
||
Lexer.prototype.tokenize = function(code, opts) {
|
||
var consumed, i, tag, _ref2;
|
||
if (opts == null) {
|
||
opts = {};
|
||
}
|
||
this.literate = opts.literate;
|
||
this.indent = 0;
|
||
this.baseIndent = 0;
|
||
this.indebt = 0;
|
||
this.outdebt = 0;
|
||
this.indents = [];
|
||
this.ends = [];
|
||
this.tokens = [];
|
||
this.chunkLine = opts.line || 0;
|
||
this.chunkColumn = opts.column || 0;
|
||
code = this.clean(code);
|
||
i = 0;
|
||
while (this.chunk = code.slice(i)) {
|
||
consumed = this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
|
||
_ref2 = this.getLineAndColumnFromChunk(consumed), this.chunkLine = _ref2[0], this.chunkColumn = _ref2[1];
|
||
i += consumed;
|
||
}
|
||
this.closeIndentation();
|
||
if (tag = this.ends.pop()) {
|
||
this.error("missing " + tag);
|
||
}
|
||
if (opts.rewrite === false) {
|
||
return this.tokens;
|
||
}
|
||
return (new Rewriter).rewrite(this.tokens);
|
||
};
|
||
|
||
Lexer.prototype.clean = function(code) {
|
||
if (code.charCodeAt(0) === BOM) {
|
||
code = code.slice(1);
|
||
}
|
||
code = code.replace(/\r/g, '').replace(TRAILING_SPACES, '');
|
||
if (WHITESPACE.test(code)) {
|
||
code = "\n" + code;
|
||
this.chunkLine--;
|
||
}
|
||
if (this.literate) {
|
||
code = invertLiterate(code);
|
||
}
|
||
return code;
|
||
};
|
||
|
||
Lexer.prototype.identifierToken = function() {
|
||
var colon, colonOffset, forcedIdentifier, id, idLength, input, match, poppedToken, prev, tag, tagToken, _ref2, _ref3, _ref4;
|
||
if (!(match = IDENTIFIER.exec(this.chunk))) {
|
||
return 0;
|
||
}
|
||
input = match[0], id = match[1], colon = match[2];
|
||
idLength = id.length;
|
||
poppedToken = void 0;
|
||
if (id === 'own' && this.tag() === 'FOR') {
|
||
this.token('OWN', id);
|
||
return id.length;
|
||
}
|
||
forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref2 = prev[0]) === '.' || _ref2 === '?.' || _ref2 === '::' || _ref2 === '?::') || !prev.spaced && prev[0] === '@');
|
||
tag = 'IDENTIFIER';
|
||
if (!forcedIdentifier && (__indexOf.call(JS_KEYWORDS, id) >= 0 || __indexOf.call(COFFEE_KEYWORDS, id) >= 0)) {
|
||
tag = id.toUpperCase();
|
||
if (tag === 'WHEN' && (_ref3 = this.tag(), __indexOf.call(LINE_BREAK, _ref3) >= 0)) {
|
||
tag = 'LEADING_WHEN';
|
||
} else if (tag === 'FOR') {
|
||
this.seenFor = true;
|
||
} else if (tag === 'UNLESS') {
|
||
tag = 'IF';
|
||
} else if (__indexOf.call(UNARY, tag) >= 0) {
|
||
tag = 'UNARY';
|
||
} else if (__indexOf.call(RELATION, tag) >= 0) {
|
||
if (tag !== 'INSTANCEOF' && this.seenFor) {
|
||
tag = 'FOR' + tag;
|
||
this.seenFor = false;
|
||
} else {
|
||
tag = 'RELATION';
|
||
if (this.value() === '!') {
|
||
poppedToken = this.tokens.pop();
|
||
id = '!' + id;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (__indexOf.call(JS_FORBIDDEN, id) >= 0) {
|
||
if (forcedIdentifier) {
|
||
tag = 'IDENTIFIER';
|
||
id = new String(id);
|
||
id.reserved = true;
|
||
} else if (__indexOf.call(RESERVED, id) >= 0) {
|
||
this.error("reserved word \"" + id + "\"");
|
||
}
|
||
}
|
||
if (!forcedIdentifier) {
|
||
if (__indexOf.call(COFFEE_ALIASES, id) >= 0) {
|
||
id = COFFEE_ALIAS_MAP[id];
|
||
}
|
||
tag = (function() {
|
||
switch (id) {
|
||
case '!':
|
||
return 'UNARY';
|
||
case '==':
|
||
case '!=':
|
||
return 'COMPARE';
|
||
case '&&':
|
||
case '||':
|
||
return 'LOGIC';
|
||
case 'true':
|
||
case 'false':
|
||
return 'BOOL';
|
||
case 'break':
|
||
case 'continue':
|
||
return 'STATEMENT';
|
||
default:
|
||
return tag;
|
||
}
|
||
})();
|
||
}
|
||
tagToken = this.token(tag, id, 0, idLength);
|
||
if (poppedToken) {
|
||
_ref4 = [poppedToken[2].first_line, poppedToken[2].first_column], tagToken[2].first_line = _ref4[0], tagToken[2].first_column = _ref4[1];
|
||
}
|
||
if (colon) {
|
||
colonOffset = input.lastIndexOf(':');
|
||
this.token(':', ':', colonOffset, colon.length);
|
||
}
|
||
return input.length;
|
||
};
|
||
|
||
Lexer.prototype.numberToken = function() {
|
||
var binaryLiteral, lexedLength, match, number, octalLiteral;
|
||
if (!(match = NUMBER.exec(this.chunk))) {
|
||
return 0;
|
||
}
|
||
number = match[0];
|
||
if (/^0[BOX]/.test(number)) {
|
||
this.error("radix prefix '" + number + "' must be lowercase");
|
||
} else if (/E/.test(number) && !/^0x/.test(number)) {
|
||
this.error("exponential notation '" + number + "' must be indicated with a lowercase 'e'");
|
||
} else if (/^0\d*[89]/.test(number)) {
|
||
this.error("decimal literal '" + number + "' must not be prefixed with '0'");
|
||
} else if (/^0\d+/.test(number)) {
|
||
this.error("octal literal '" + number + "' must be prefixed with '0o'");
|
||
}
|
||
lexedLength = number.length;
|
||
if (octalLiteral = /^0o([0-7]+)/.exec(number)) {
|
||
number = '0x' + parseInt(octalLiteral[1], 8).toString(16);
|
||
}
|
||
if (binaryLiteral = /^0b([01]+)/.exec(number)) {
|
||
number = '0x' + parseInt(binaryLiteral[1], 2).toString(16);
|
||
}
|
||
this.token('NUMBER', number, 0, lexedLength);
|
||
return lexedLength;
|
||
};
|
||
|
||
Lexer.prototype.stringToken = function() {
|
||
var inner, innerLen, numBreak, octalEsc, pos, quote, string, trimmed;
|
||
switch (quote = this.chunk.charAt(0)) {
|
||
case "'":
|
||
string = (SIMPLESTR.exec(this.chunk) || [])[0];
|
||
break;
|
||
case '"':
|
||
string = this.balancedString(this.chunk, '"');
|
||
}
|
||
if (!string) {
|
||
return 0;
|
||
}
|
||
inner = string.slice(1, -1);
|
||
trimmed = this.removeNewlines(inner);
|
||
if (quote === '"' && 0 < string.indexOf('#{', 1)) {
|
||
numBreak = pos = 0;
|
||
innerLen = inner.length;
|
||
while (inner.charAt(pos++) === '\n' && pos < innerLen) {
|
||
numBreak++;
|
||
}
|
||
this.interpolateString(trimmed, {
|
||
strOffset: 1 + numBreak,
|
||
lexedLength: string.length
|
||
});
|
||
} else {
|
||
this.token('STRING', quote + this.escapeLines(trimmed) + quote, 0, string.length);
|
||
}
|
||
if (octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(string)) {
|
||
this.error("octal escape sequences " + string + " are not allowed");
|
||
}
|
||
return string.length;
|
||
};
|
||
|
||
Lexer.prototype.heredocToken = function() {
|
||
var doc, heredoc, match, quote, strOffset;
|
||
if (!(match = HEREDOC.exec(this.chunk))) {
|
||
return 0;
|
||
}
|
||
heredoc = match[0];
|
||
quote = heredoc.charAt(0);
|
||
doc = this.sanitizeHeredoc(match[2], {
|
||
quote: quote,
|
||
indent: null
|
||
});
|
||
if (quote === '"' && 0 <= doc.indexOf('#{')) {
|
||
strOffset = match[2].charAt(0) === '\n' ? 4 : 3;
|
||
this.interpolateString(doc, {
|
||
heredoc: true,
|
||
strOffset: strOffset,
|
||
lexedLength: heredoc.length
|
||
});
|
||
} else {
|
||
this.token('STRING', this.makeString(doc, quote, true), 0, heredoc.length);
|
||
}
|
||
return heredoc.length;
|
||
};
|
||
|
||
Lexer.prototype.commentToken = function() {
|
||
var comment, here, match;
|
||
if (!(match = this.chunk.match(COMMENT))) {
|
||
return 0;
|
||
}
|
||
comment = match[0], here = match[1];
|
||
if (here) {
|
||
this.token('HERECOMMENT', this.sanitizeHeredoc(here, {
|
||
herecomment: true,
|
||
indent: repeat(' ', this.indent)
|
||
}), 0, comment.length);
|
||
}
|
||
return comment.length;
|
||
};
|
||
|
||
Lexer.prototype.jsToken = function() {
|
||
var match, script;
|
||
if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) {
|
||
return 0;
|
||
}
|
||
this.token('JS', (script = match[0]).slice(1, -1), 0, script.length);
|
||
return script.length;
|
||
};
|
||
|
||
Lexer.prototype.regexToken = function() {
|
||
var flags, length, match, prev, regex, _ref2, _ref3;
|
||
if (this.chunk.charAt(0) !== '/') {
|
||
return 0;
|
||
}
|
||
if (length = this.heregexToken()) {
|
||
return length;
|
||
}
|
||
prev = last(this.tokens);
|
||
if (prev && (_ref2 = prev[0], __indexOf.call((prev.spaced ? NOT_REGEX : NOT_SPACED_REGEX), _ref2) >= 0)) {
|
||
return 0;
|
||
}
|
||
if (!(match = REGEX.exec(this.chunk))) {
|
||
return 0;
|
||
}
|
||
_ref3 = match, match = _ref3[0], regex = _ref3[1], flags = _ref3[2];
|
||
if (regex === '//') {
|
||
return 0;
|
||
}
|
||
if (regex.slice(0, 2) === '/*') {
|
||
this.error('regular expressions cannot begin with `*`');
|
||
}
|
||
this.token('REGEX', "" + regex + flags, 0, match.length);
|
||
return match.length;
|
||
};
|
||
|
||
Lexer.prototype.heregexToken = function() {
|
||
var body, flags, flagsOffset, heregex, match, plusToken, prev, re, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
|
||
if (!(match = HEREGEX.exec(this.chunk))) {
|
||
return 0;
|
||
}
|
||
heregex = match[0], body = match[1], flags = match[2];
|
||
if (0 > body.indexOf('#{')) {
|
||
re = this.escapeLines(body.replace(HEREGEX_OMIT, '$1$2').replace(/\//g, '\\/'), true);
|
||
if (re.match(/^\*/)) {
|
||
this.error('regular expressions cannot begin with `*`');
|
||
}
|
||
this.token('REGEX', "/" + (re || '(?:)') + "/" + flags, 0, heregex.length);
|
||
return heregex.length;
|
||
}
|
||
this.token('IDENTIFIER', 'RegExp', 0, 0);
|
||
this.token('CALL_START', '(', 0, 0);
|
||
tokens = [];
|
||
_ref2 = this.interpolateString(body, {
|
||
regex: true,
|
||
strOffset: 3
|
||
});
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
token = _ref2[_i];
|
||
tag = token[0], value = token[1];
|
||
if (tag === 'TOKENS') {
|
||
tokens.push.apply(tokens, value);
|
||
} else if (tag === 'NEOSTRING') {
|
||
if (!(value = value.replace(HEREGEX_OMIT, '$1$2'))) {
|
||
continue;
|
||
}
|
||
value = value.replace(/\\/g, '\\\\');
|
||
token[0] = 'STRING';
|
||
token[1] = this.makeString(value, '"', true);
|
||
tokens.push(token);
|
||
} else {
|
||
this.error("Unexpected " + tag);
|
||
}
|
||
prev = last(this.tokens);
|
||
plusToken = ['+', '+'];
|
||
plusToken[2] = prev[2];
|
||
tokens.push(plusToken);
|
||
}
|
||
tokens.pop();
|
||
if (((_ref3 = tokens[0]) != null ? _ref3[0] : void 0) !== 'STRING') {
|
||
this.token('STRING', '""', 0, 0);
|
||
this.token('+', '+', 0, 0);
|
||
}
|
||
(_ref4 = this.tokens).push.apply(_ref4, tokens);
|
||
if (flags) {
|
||
flagsOffset = heregex.lastIndexOf(flags);
|
||
this.token(',', ',', flagsOffset, 0);
|
||
this.token('STRING', '"' + flags + '"', flagsOffset, flags.length);
|
||
}
|
||
this.token(')', ')', heregex.length - 1, 0);
|
||
return heregex.length;
|
||
};
|
||
|
||
Lexer.prototype.lineToken = function() {
|
||
var diff, indent, match, noNewlines, size;
|
||
if (!(match = MULTI_DENT.exec(this.chunk))) {
|
||
return 0;
|
||
}
|
||
indent = match[0];
|
||
this.seenFor = false;
|
||
size = indent.length - 1 - indent.lastIndexOf('\n');
|
||
noNewlines = this.unfinished();
|
||
if (size - this.indebt === this.indent) {
|
||
if (noNewlines) {
|
||
this.suppressNewlines();
|
||
} else {
|
||
this.newlineToken(0);
|
||
}
|
||
return indent.length;
|
||
}
|
||
if (size > this.indent) {
|
||
if (noNewlines) {
|
||
this.indebt = size - this.indent;
|
||
this.suppressNewlines();
|
||
return indent.length;
|
||
}
|
||
if (!this.tokens.length) {
|
||
this.baseIndent = this.indent = size;
|
||
return indent.length;
|
||
}
|
||
diff = size - this.indent + this.outdebt;
|
||
this.token('INDENT', diff, indent.length - size, size);
|
||
this.indents.push(diff);
|
||
this.ends.push('OUTDENT');
|
||
this.outdebt = this.indebt = 0;
|
||
this.indent = size;
|
||
} else if (size < this.baseIndent) {
|
||
this.error('missing indentation', indent.length);
|
||
} else {
|
||
this.indebt = 0;
|
||
this.outdentToken(this.indent - size, noNewlines, indent.length);
|
||
}
|
||
return indent.length;
|
||
};
|
||
|
||
Lexer.prototype.outdentToken = function(moveOut, noNewlines, outdentLength) {
|
||
var decreasedIndent, dent, lastIndent, _ref2;
|
||
decreasedIndent = this.indent - moveOut;
|
||
while (moveOut > 0) {
|
||
lastIndent = this.indents[this.indents.length - 1];
|
||
if (!lastIndent) {
|
||
moveOut = 0;
|
||
} else if (lastIndent === this.outdebt) {
|
||
moveOut -= this.outdebt;
|
||
this.outdebt = 0;
|
||
} else if (lastIndent < this.outdebt) {
|
||
this.outdebt -= lastIndent;
|
||
moveOut -= lastIndent;
|
||
} else {
|
||
dent = this.indents.pop() + this.outdebt;
|
||
if (outdentLength && (_ref2 = this.chunk[outdentLength], __indexOf.call(INDENTABLE_CLOSERS, _ref2) >= 0)) {
|
||
decreasedIndent -= dent - moveOut;
|
||
moveOut = dent;
|
||
}
|
||
this.outdebt = 0;
|
||
this.pair('OUTDENT');
|
||
this.token('OUTDENT', moveOut, 0, outdentLength);
|
||
moveOut -= dent;
|
||
}
|
||
}
|
||
if (dent) {
|
||
this.outdebt -= moveOut;
|
||
}
|
||
while (this.value() === ';') {
|
||
this.tokens.pop();
|
||
}
|
||
if (!(this.tag() === 'TERMINATOR' || noNewlines)) {
|
||
this.token('TERMINATOR', '\n', outdentLength, 0);
|
||
}
|
||
this.indent = decreasedIndent;
|
||
return this;
|
||
};
|
||
|
||
Lexer.prototype.whitespaceToken = function() {
|
||
var match, nline, prev;
|
||
if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) {
|
||
return 0;
|
||
}
|
||
prev = last(this.tokens);
|
||
if (prev) {
|
||
prev[match ? 'spaced' : 'newLine'] = true;
|
||
}
|
||
if (match) {
|
||
return match[0].length;
|
||
} else {
|
||
return 0;
|
||
}
|
||
};
|
||
|
||
Lexer.prototype.newlineToken = function(offset) {
|
||
while (this.value() === ';') {
|
||
this.tokens.pop();
|
||
}
|
||
if (this.tag() !== 'TERMINATOR') {
|
||
this.token('TERMINATOR', '\n', offset, 0);
|
||
}
|
||
return this;
|
||
};
|
||
|
||
Lexer.prototype.suppressNewlines = function() {
|
||
if (this.value() === '\\') {
|
||
this.tokens.pop();
|
||
}
|
||
return this;
|
||
};
|
||
|
||
Lexer.prototype.literalToken = function() {
|
||
var match, prev, tag, value, _ref2, _ref3, _ref4, _ref5;
|
||
if (match = OPERATOR.exec(this.chunk)) {
|
||
value = match[0];
|
||
if (CODE.test(value)) {
|
||
this.tagParameters();
|
||
}
|
||
} else {
|
||
value = this.chunk.charAt(0);
|
||
}
|
||
tag = value;
|
||
prev = last(this.tokens);
|
||
if (value === '=' && prev) {
|
||
if (!prev[1].reserved && (_ref2 = prev[1], __indexOf.call(JS_FORBIDDEN, _ref2) >= 0)) {
|
||
this.error("reserved word \"" + (this.value()) + "\" can't be assigned");
|
||
}
|
||
if ((_ref3 = prev[1]) === '||' || _ref3 === '&&') {
|
||
prev[0] = 'COMPOUND_ASSIGN';
|
||
prev[1] += '=';
|
||
return value.length;
|
||
}
|
||
}
|
||
if (value === ';') {
|
||
this.seenFor = false;
|
||
tag = 'TERMINATOR';
|
||
} else if (__indexOf.call(MATH, value) >= 0) {
|
||
tag = 'MATH';
|
||
} else if (__indexOf.call(COMPARE, value) >= 0) {
|
||
tag = 'COMPARE';
|
||
} else if (__indexOf.call(COMPOUND_ASSIGN, value) >= 0) {
|
||
tag = 'COMPOUND_ASSIGN';
|
||
} else if (__indexOf.call(UNARY, value) >= 0) {
|
||
tag = 'UNARY';
|
||
} else if (__indexOf.call(UNARY_MATH, value) >= 0) {
|
||
tag = 'UNARY_MATH';
|
||
} else if (__indexOf.call(SHIFT, value) >= 0) {
|
||
tag = 'SHIFT';
|
||
} else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) {
|
||
tag = 'LOGIC';
|
||
} else if (prev && !prev.spaced) {
|
||
if (value === '(' && (_ref4 = prev[0], __indexOf.call(CALLABLE, _ref4) >= 0)) {
|
||
if (prev[0] === '?') {
|
||
prev[0] = 'FUNC_EXIST';
|
||
}
|
||
tag = 'CALL_START';
|
||
} else if (value === '[' && (_ref5 = prev[0], __indexOf.call(INDEXABLE, _ref5) >= 0)) {
|
||
tag = 'INDEX_START';
|
||
switch (prev[0]) {
|
||
case '?':
|
||
prev[0] = 'INDEX_SOAK';
|
||
}
|
||
}
|
||
}
|
||
switch (value) {
|
||
case '(':
|
||
case '{':
|
||
case '[':
|
||
this.ends.push(INVERSES[value]);
|
||
break;
|
||
case ')':
|
||
case '}':
|
||
case ']':
|
||
this.pair(value);
|
||
}
|
||
this.token(tag, value);
|
||
return value.length;
|
||
};
|
||
|
||
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
|
||
var attempt, herecomment, indent, match, _ref2;
|
||
indent = options.indent, herecomment = options.herecomment;
|
||
if (herecomment) {
|
||
if (HEREDOC_ILLEGAL.test(doc)) {
|
||
this.error("block comment cannot contain \"*/\", starting");
|
||
}
|
||
if (doc.indexOf('\n') < 0) {
|
||
return doc;
|
||
}
|
||
} else {
|
||
while (match = HEREDOC_INDENT.exec(doc)) {
|
||
attempt = match[1];
|
||
if (indent === null || (0 < (_ref2 = attempt.length) && _ref2 < indent.length)) {
|
||
indent = attempt;
|
||
}
|
||
}
|
||
}
|
||
if (indent) {
|
||
doc = doc.replace(RegExp("\\n" + indent, "g"), '\n');
|
||
}
|
||
if (!herecomment) {
|
||
doc = doc.replace(/^\n/, '');
|
||
}
|
||
return doc;
|
||
};
|
||
|
||
Lexer.prototype.tagParameters = function() {
|
||
var i, stack, tok, tokens;
|
||
if (this.tag() !== ')') {
|
||
return this;
|
||
}
|
||
stack = [];
|
||
tokens = this.tokens;
|
||
i = tokens.length;
|
||
tokens[--i][0] = 'PARAM_END';
|
||
while (tok = tokens[--i]) {
|
||
switch (tok[0]) {
|
||
case ')':
|
||
stack.push(tok);
|
||
break;
|
||
case '(':
|
||
case 'CALL_START':
|
||
if (stack.length) {
|
||
stack.pop();
|
||
} else if (tok[0] === '(') {
|
||
tok[0] = 'PARAM_START';
|
||
return this;
|
||
} else {
|
||
return this;
|
||
}
|
||
}
|
||
}
|
||
return this;
|
||
};
|
||
|
||
Lexer.prototype.closeIndentation = function() {
|
||
return this.outdentToken(this.indent);
|
||
};
|
||
|
||
Lexer.prototype.balancedString = function(str, end) {
|
||
var continueCount, i, letter, match, prev, stack, _i, _ref2;
|
||
continueCount = 0;
|
||
stack = [end];
|
||
for (i = _i = 1, _ref2 = str.length; 1 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 1 <= _ref2 ? ++_i : --_i) {
|
||
if (continueCount) {
|
||
--continueCount;
|
||
continue;
|
||
}
|
||
switch (letter = str.charAt(i)) {
|
||
case '\\':
|
||
++continueCount;
|
||
continue;
|
||
case end:
|
||
stack.pop();
|
||
if (!stack.length) {
|
||
return str.slice(0, +i + 1 || 9e9);
|
||
}
|
||
end = stack[stack.length - 1];
|
||
continue;
|
||
}
|
||
if (end === '}' && (letter === '"' || letter === "'")) {
|
||
stack.push(end = letter);
|
||
} else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) {
|
||
continueCount += match[0].length - 1;
|
||
} else if (end === '}' && letter === '{') {
|
||
stack.push(end = '}');
|
||
} else if (end === '"' && prev === '#' && letter === '{') {
|
||
stack.push(end = '}');
|
||
}
|
||
prev = letter;
|
||
}
|
||
return this.error("missing " + (stack.pop()) + ", starting");
|
||
};
|
||
|
||
Lexer.prototype.interpolateString = function(str, options) {
|
||
var column, errorToken, expr, heredoc, i, inner, interpolated, len, letter, lexedLength, line, locationToken, nested, offsetInChunk, pi, plusToken, popped, regex, rparen, strOffset, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
|
||
if (options == null) {
|
||
options = {};
|
||
}
|
||
heredoc = options.heredoc, regex = options.regex, offsetInChunk = options.offsetInChunk, strOffset = options.strOffset, lexedLength = options.lexedLength;
|
||
offsetInChunk || (offsetInChunk = 0);
|
||
strOffset || (strOffset = 0);
|
||
lexedLength || (lexedLength = str.length);
|
||
tokens = [];
|
||
pi = 0;
|
||
i = -1;
|
||
while (letter = str.charAt(i += 1)) {
|
||
if (letter === '\\') {
|
||
i += 1;
|
||
continue;
|
||
}
|
||
if (!(letter === '#' && str.charAt(i + 1) === '{' && (expr = this.balancedString(str.slice(i + 1), '}')))) {
|
||
continue;
|
||
}
|
||
if (pi < i) {
|
||
tokens.push(this.makeToken('NEOSTRING', str.slice(pi, i), strOffset + pi));
|
||
}
|
||
if (!errorToken) {
|
||
errorToken = this.makeToken('', 'string interpolation', offsetInChunk + i + 1, 2);
|
||
}
|
||
inner = expr.slice(1, -1);
|
||
if (inner.length) {
|
||
_ref2 = this.getLineAndColumnFromChunk(strOffset + i + 2), line = _ref2[0], column = _ref2[1];
|
||
nested = new Lexer().tokenize(inner, {
|
||
line: line,
|
||
column: column,
|
||
rewrite: false
|
||
});
|
||
popped = nested.pop();
|
||
if (((_ref3 = nested[0]) != null ? _ref3[0] : void 0) === 'TERMINATOR') {
|
||
popped = nested.shift();
|
||
}
|
||
if (len = nested.length) {
|
||
if (len > 1) {
|
||
nested.unshift(this.makeToken('(', '(', strOffset + i + 1, 0));
|
||
nested.push(this.makeToken(')', ')', strOffset + i + 1 + inner.length, 0));
|
||
}
|
||
tokens.push(['TOKENS', nested]);
|
||
}
|
||
}
|
||
i += expr.length;
|
||
pi = i + 1;
|
||
}
|
||
if ((i > pi && pi < str.length)) {
|
||
tokens.push(this.makeToken('NEOSTRING', str.slice(pi), strOffset + pi));
|
||
}
|
||
if (regex) {
|
||
return tokens;
|
||
}
|
||
if (!tokens.length) {
|
||
return this.token('STRING', '""', offsetInChunk, lexedLength);
|
||
}
|
||
if (tokens[0][0] !== 'NEOSTRING') {
|
||
tokens.unshift(this.makeToken('NEOSTRING', '', offsetInChunk));
|
||
}
|
||
if (interpolated = tokens.length > 1) {
|
||
this.token('(', '(', offsetInChunk, 0, errorToken);
|
||
}
|
||
for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) {
|
||
token = tokens[i];
|
||
tag = token[0], value = token[1];
|
||
if (i) {
|
||
if (i) {
|
||
plusToken = this.token('+', '+');
|
||
}
|
||
locationToken = tag === 'TOKENS' ? value[0] : token;
|
||
plusToken[2] = {
|
||
first_line: locationToken[2].first_line,
|
||
first_column: locationToken[2].first_column,
|
||
last_line: locationToken[2].first_line,
|
||
last_column: locationToken[2].first_column
|
||
};
|
||
}
|
||
if (tag === 'TOKENS') {
|
||
(_ref4 = this.tokens).push.apply(_ref4, value);
|
||
} else if (tag === 'NEOSTRING') {
|
||
token[0] = 'STRING';
|
||
token[1] = this.makeString(value, '"', heredoc);
|
||
this.tokens.push(token);
|
||
} else {
|
||
this.error("Unexpected " + tag);
|
||
}
|
||
}
|
||
if (interpolated) {
|
||
rparen = this.makeToken(')', ')', offsetInChunk + lexedLength, 0);
|
||
rparen.stringEnd = true;
|
||
this.tokens.push(rparen);
|
||
}
|
||
return tokens;
|
||
};
|
||
|
||
Lexer.prototype.pair = function(tag) {
|
||
var wanted;
|
||
if (tag !== (wanted = last(this.ends))) {
|
||
if ('OUTDENT' !== wanted) {
|
||
this.error("unmatched " + tag);
|
||
}
|
||
this.outdentToken(last(this.indents), true);
|
||
return this.pair(tag);
|
||
}
|
||
return this.ends.pop();
|
||
};
|
||
|
||
Lexer.prototype.getLineAndColumnFromChunk = function(offset) {
|
||
var column, lineCount, lines, string;
|
||
if (offset === 0) {
|
||
return [this.chunkLine, this.chunkColumn];
|
||
}
|
||
if (offset >= this.chunk.length) {
|
||
string = this.chunk;
|
||
} else {
|
||
string = this.chunk.slice(0, +(offset - 1) + 1 || 9e9);
|
||
}
|
||
lineCount = count(string, '\n');
|
||
column = this.chunkColumn;
|
||
if (lineCount > 0) {
|
||
lines = string.split('\n');
|
||
column = last(lines).length;
|
||
} else {
|
||
column += string.length;
|
||
}
|
||
return [this.chunkLine + lineCount, column];
|
||
};
|
||
|
||
Lexer.prototype.makeToken = function(tag, value, offsetInChunk, length) {
|
||
var lastCharacter, locationData, token, _ref2, _ref3;
|
||
if (offsetInChunk == null) {
|
||
offsetInChunk = 0;
|
||
}
|
||
if (length == null) {
|
||
length = value.length;
|
||
}
|
||
locationData = {};
|
||
_ref2 = this.getLineAndColumnFromChunk(offsetInChunk), locationData.first_line = _ref2[0], locationData.first_column = _ref2[1];
|
||
lastCharacter = Math.max(0, length - 1);
|
||
_ref3 = this.getLineAndColumnFromChunk(offsetInChunk + lastCharacter), locationData.last_line = _ref3[0], locationData.last_column = _ref3[1];
|
||
token = [tag, value, locationData];
|
||
return token;
|
||
};
|
||
|
||
Lexer.prototype.token = function(tag, value, offsetInChunk, length, origin) {
|
||
var token;
|
||
token = this.makeToken(tag, value, offsetInChunk, length);
|
||
if (origin) {
|
||
token.origin = origin;
|
||
}
|
||
this.tokens.push(token);
|
||
return token;
|
||
};
|
||
|
||
Lexer.prototype.tag = function(index, tag) {
|
||
var tok;
|
||
return (tok = last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]);
|
||
};
|
||
|
||
Lexer.prototype.value = function(index, val) {
|
||
var tok;
|
||
return (tok = last(this.tokens, index)) && (val ? tok[1] = val : tok[1]);
|
||
};
|
||
|
||
Lexer.prototype.unfinished = function() {
|
||
var _ref2;
|
||
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === 'UNARY_MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === '**' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
|
||
};
|
||
|
||
Lexer.prototype.removeNewlines = function(str) {
|
||
return str.replace(/^\s*\n\s*/, '').replace(/([^\\]|\\\\)\s*\n\s*$/, '$1');
|
||
};
|
||
|
||
Lexer.prototype.escapeLines = function(str, heredoc) {
|
||
str = str.replace(/\\[^\S\n]*(\n|\\)\s*/g, function(escaped, character) {
|
||
if (character === '\n') {
|
||
return '';
|
||
} else {
|
||
return escaped;
|
||
}
|
||
});
|
||
if (heredoc) {
|
||
return str.replace(MULTILINER, '\\n');
|
||
} else {
|
||
return str.replace(/\s*\n\s*/g, ' ');
|
||
}
|
||
};
|
||
|
||
Lexer.prototype.makeString = function(body, quote, heredoc) {
|
||
if (!body) {
|
||
return quote + quote;
|
||
}
|
||
body = body.replace(RegExp("\\\\(" + quote + "|\\\\)", "g"), function(match, contents) {
|
||
if (contents === quote) {
|
||
return contents;
|
||
} else {
|
||
return match;
|
||
}
|
||
});
|
||
body = body.replace(RegExp("" + quote, "g"), '\\$&');
|
||
return quote + this.escapeLines(body, heredoc) + quote;
|
||
};
|
||
|
||
Lexer.prototype.error = function(message, offset) {
|
||
var first_column, first_line, _ref2;
|
||
if (offset == null) {
|
||
offset = 0;
|
||
}
|
||
_ref2 = this.getLineAndColumnFromChunk(offset), first_line = _ref2[0], first_column = _ref2[1];
|
||
return throwSyntaxError(message, {
|
||
first_line: first_line,
|
||
first_column: first_column
|
||
});
|
||
};
|
||
|
||
return Lexer;
|
||
|
||
})();
|
||
|
||
JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super'];
|
||
|
||
COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when'];
|
||
|
||
COFFEE_ALIAS_MAP = {
|
||
and: '&&',
|
||
or: '||',
|
||
is: '==',
|
||
isnt: '!=',
|
||
not: '!',
|
||
yes: 'true',
|
||
no: 'false',
|
||
on: 'true',
|
||
off: 'false'
|
||
};
|
||
|
||
COFFEE_ALIASES = (function() {
|
||
var _results;
|
||
_results = [];
|
||
for (key in COFFEE_ALIAS_MAP) {
|
||
_results.push(key);
|
||
}
|
||
return _results;
|
||
})();
|
||
|
||
COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES);
|
||
|
||
RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf', 'implements', 'interface', 'package', 'private', 'protected', 'public', 'static', 'yield'];
|
||
|
||
STRICT_PROSCRIBED = ['arguments', 'eval'];
|
||
|
||
JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED);
|
||
|
||
exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS).concat(STRICT_PROSCRIBED);
|
||
|
||
exports.STRICT_PROSCRIBED = STRICT_PROSCRIBED;
|
||
|
||
BOM = 65279;
|
||
|
||
IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/;
|
||
|
||
NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
|
||
|
||
HEREDOC = /^("""|''')((?:\\[\s\S]|[^\\])*?)(?:\n[^\n\S]*)?\1/;
|
||
|
||
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>*\/%])\2=?|\?(\.|::)|\.{2,3})/;
|
||
|
||
WHITESPACE = /^[^\n\S]+/;
|
||
|
||
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/;
|
||
|
||
CODE = /^[-=]>/;
|
||
|
||
MULTI_DENT = /^(?:\n[^\n\S]*)+/;
|
||
|
||
SIMPLESTR = /^'[^\\']*(?:\\[\s\S][^\\']*)*'/;
|
||
|
||
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
|
||
|
||
REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;
|
||
|
||
HEREGEX = /^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/;
|
||
|
||
HEREGEX_OMIT = /((?:\\\\)+)|\\(\s|\/)|\s+(?:#.*)?/g;
|
||
|
||
MULTILINER = /\n/g;
|
||
|
||
HEREDOC_INDENT = /\n+([^\n\S]*)/g;
|
||
|
||
HEREDOC_ILLEGAL = /\*\//;
|
||
|
||
LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/;
|
||
|
||
TRAILING_SPACES = /\s+$/;
|
||
|
||
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=', '**=', '//=', '%%='];
|
||
|
||
UNARY = ['NEW', 'TYPEOF', 'DELETE', 'DO'];
|
||
|
||
UNARY_MATH = ['!', '~'];
|
||
|
||
LOGIC = ['&&', '||', '&', '|', '^'];
|
||
|
||
SHIFT = ['<<', '>>', '>>>'];
|
||
|
||
COMPARE = ['==', '!=', '<', '>', '<=', '>='];
|
||
|
||
MATH = ['*', '/', '%', '//', '%%'];
|
||
|
||
RELATION = ['IN', 'OF', 'INSTANCEOF'];
|
||
|
||
BOOL = ['TRUE', 'FALSE'];
|
||
|
||
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--'];
|
||
|
||
NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING', ']');
|
||
|
||
CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER'];
|
||
|
||
INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL', 'NULL', 'UNDEFINED');
|
||
|
||
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
||
|
||
INDENTABLE_CLOSERS = [')', '}', ']'];
|
||
|
||
}).call(this);
|
||
|
||
},{"./helpers":48,"./rewriter":53}],50:[function(require,module,exports){
|
||
// Generated by CoffeeScript 1.8.0
|
||
(function() {
|
||
var Access, Arr, Assign, Base, Block, Call, Class, Code, CodeFragment, Comment, Existence, Expansion, Extends, For, HEXNUM, IDENTIFIER, IDENTIFIER_STR, IS_REGEX, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, NUMBER, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, isLiteralArguments, isLiteralThis, last, locationDataToString, merge, multident, parseNum, some, starts, throwSyntaxError, unfoldSoak, utility, _ref, _ref1,
|
||
__hasProp = {}.hasOwnProperty,
|
||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
||
__slice = [].slice;
|
||
|
||
Error.stackTraceLimit = Infinity;
|
||
|
||
Scope = require('./scope').Scope;
|
||
|
||
_ref = require('./lexer'), RESERVED = _ref.RESERVED, STRICT_PROSCRIBED = _ref.STRICT_PROSCRIBED;
|
||
|
||
_ref1 = require('./helpers'), compact = _ref1.compact, flatten = _ref1.flatten, extend = _ref1.extend, merge = _ref1.merge, del = _ref1.del, starts = _ref1.starts, ends = _ref1.ends, last = _ref1.last, some = _ref1.some, addLocationDataFn = _ref1.addLocationDataFn, locationDataToString = _ref1.locationDataToString, throwSyntaxError = _ref1.throwSyntaxError;
|
||
|
||
exports.extend = extend;
|
||
|
||
exports.addLocationDataFn = addLocationDataFn;
|
||
|
||
YES = function() {
|
||
return true;
|
||
};
|
||
|
||
NO = function() {
|
||
return false;
|
||
};
|
||
|
||
THIS = function() {
|
||
return this;
|
||
};
|
||
|
||
NEGATE = function() {
|
||
this.negated = !this.negated;
|
||
return this;
|
||
};
|
||
|
||
exports.CodeFragment = CodeFragment = (function() {
|
||
function CodeFragment(parent, code) {
|
||
var _ref2;
|
||
this.code = "" + code;
|
||
this.locationData = parent != null ? parent.locationData : void 0;
|
||
this.type = (parent != null ? (_ref2 = parent.constructor) != null ? _ref2.name : void 0 : void 0) || 'unknown';
|
||
}
|
||
|
||
CodeFragment.prototype.toString = function() {
|
||
return "" + this.code + (this.locationData ? ": " + locationDataToString(this.locationData) : '');
|
||
};
|
||
|
||
return CodeFragment;
|
||
|
||
})();
|
||
|
||
fragmentsToText = function(fragments) {
|
||
var fragment;
|
||
return ((function() {
|
||
var _i, _len, _results;
|
||
_results = [];
|
||
for (_i = 0, _len = fragments.length; _i < _len; _i++) {
|
||
fragment = fragments[_i];
|
||
_results.push(fragment.code);
|
||
}
|
||
return _results;
|
||
})()).join('');
|
||
};
|
||
|
||
exports.Base = Base = (function() {
|
||
function Base() {}
|
||
|
||
Base.prototype.compile = function(o, lvl) {
|
||
return fragmentsToText(this.compileToFragments(o, lvl));
|
||
};
|
||
|
||
Base.prototype.compileToFragments = function(o, lvl) {
|
||
var node;
|
||
o = extend({}, o);
|
||
if (lvl) {
|
||
o.level = lvl;
|
||
}
|
||
node = this.unfoldSoak(o) || this;
|
||
node.tab = o.indent;
|
||
if (o.level === LEVEL_TOP || !node.isStatement(o)) {
|
||
return node.compileNode(o);
|
||
} else {
|
||
return node.compileClosure(o);
|
||
}
|
||
};
|
||
|
||
Base.prototype.compileClosure = function(o) {
|
||
var args, argumentsNode, func, jumpNode, meth;
|
||
if (jumpNode = this.jumps()) {
|
||
jumpNode.error('cannot use a pure statement in an expression');
|
||
}
|
||
o.sharedScope = true;
|
||
func = new Code([], Block.wrap([this]));
|
||
args = [];
|
||
if ((argumentsNode = this.contains(isLiteralArguments)) || this.contains(isLiteralThis)) {
|
||
args = [new Literal('this')];
|
||
if (argumentsNode) {
|
||
meth = 'apply';
|
||
args.push(new Literal('arguments'));
|
||
} else {
|
||
meth = 'call';
|
||
}
|
||
func = new Value(func, [new Access(new Literal(meth))]);
|
||
}
|
||
return (new Call(func, args)).compileNode(o);
|
||
};
|
||
|
||
Base.prototype.cache = function(o, level, reused) {
|
||
var ref, sub;
|
||
if (!this.isComplex()) {
|
||
ref = level ? this.compileToFragments(o, level) : this;
|
||
return [ref, ref];
|
||
} else {
|
||
ref = new Literal(reused || o.scope.freeVariable('ref'));
|
||
sub = new Assign(ref, this);
|
||
if (level) {
|
||
return [sub.compileToFragments(o, level), [this.makeCode(ref.value)]];
|
||
} else {
|
||
return [sub, ref];
|
||
}
|
||
}
|
||
};
|
||
|
||
Base.prototype.cacheToCodeFragments = function(cacheValues) {
|
||
return [fragmentsToText(cacheValues[0]), fragmentsToText(cacheValues[1])];
|
||
};
|
||
|
||
Base.prototype.makeReturn = function(res) {
|
||
var me;
|
||
me = this.unwrapAll();
|
||
if (res) {
|
||
return new Call(new Literal("" + res + ".push"), [me]);
|
||
} else {
|
||
return new Return(me);
|
||
}
|
||
};
|
||
|
||
Base.prototype.contains = function(pred) {
|
||
var node;
|
||
node = void 0;
|
||
this.traverseChildren(false, function(n) {
|
||
if (pred(n)) {
|
||
node = n;
|
||
return false;
|
||
}
|
||
});
|
||
return node;
|
||
};
|
||
|
||
Base.prototype.lastNonComment = function(list) {
|
||
var i;
|
||
i = list.length;
|
||
while (i--) {
|
||
if (!(list[i] instanceof Comment)) {
|
||
return list[i];
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
|
||
Base.prototype.toString = function(idt, name) {
|
||
var tree;
|
||
if (idt == null) {
|
||
idt = '';
|
||
}
|
||
if (name == null) {
|
||
name = this.constructor.name;
|
||
}
|
||
tree = '\n' + idt + name;
|
||
if (this.soak) {
|
||
tree += '?';
|
||
}
|
||
this.eachChild(function(node) {
|
||
return tree += node.toString(idt + TAB);
|
||
});
|
||
return tree;
|
||
};
|
||
|
||
Base.prototype.eachChild = function(func) {
|
||
var attr, child, _i, _j, _len, _len1, _ref2, _ref3;
|
||
if (!this.children) {
|
||
return this;
|
||
}
|
||
_ref2 = this.children;
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
attr = _ref2[_i];
|
||
if (this[attr]) {
|
||
_ref3 = flatten([this[attr]]);
|
||
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
|
||
child = _ref3[_j];
|
||
if (func(child) === false) {
|
||
return this;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return this;
|
||
};
|
||
|
||
Base.prototype.traverseChildren = function(crossScope, func) {
|
||
return this.eachChild(function(child) {
|
||
var recur;
|
||
recur = func(child);
|
||
if (recur !== false) {
|
||
return child.traverseChildren(crossScope, func);
|
||
}
|
||
});
|
||
};
|
||
|
||
Base.prototype.invert = function() {
|
||
return new Op('!', this);
|
||
};
|
||
|
||
Base.prototype.unwrapAll = function() {
|
||
var node;
|
||
node = this;
|
||
while (node !== (node = node.unwrap())) {
|
||
continue;
|
||
}
|
||
return node;
|
||
};
|
||
|
||
Base.prototype.children = [];
|
||
|
||
Base.prototype.isStatement = NO;
|
||
|
||
Base.prototype.jumps = NO;
|
||
|
||
Base.prototype.isComplex = YES;
|
||
|
||
Base.prototype.isChainable = NO;
|
||
|
||
Base.prototype.isAssignable = NO;
|
||
|
||
Base.prototype.unwrap = THIS;
|
||
|
||
Base.prototype.unfoldSoak = NO;
|
||
|
||
Base.prototype.assigns = NO;
|
||
|
||
Base.prototype.updateLocationDataIfMissing = function(locationData) {
|
||
if (this.locationData) {
|
||
return this;
|
||
}
|
||
this.locationData = locationData;
|
||
return this.eachChild(function(child) {
|
||
return child.updateLocationDataIfMissing(locationData);
|
||
});
|
||
};
|
||
|
||
Base.prototype.error = function(message) {
|
||
return throwSyntaxError(message, this.locationData);
|
||
};
|
||
|
||
Base.prototype.makeCode = function(code) {
|
||
return new CodeFragment(this, code);
|
||
};
|
||
|
||
Base.prototype.wrapInBraces = function(fragments) {
|
||
return [].concat(this.makeCode('('), fragments, this.makeCode(')'));
|
||
};
|
||
|
||
Base.prototype.joinFragmentArrays = function(fragmentsList, joinStr) {
|
||
var answer, fragments, i, _i, _len;
|
||
answer = [];
|
||
for (i = _i = 0, _len = fragmentsList.length; _i < _len; i = ++_i) {
|
||
fragments = fragmentsList[i];
|
||
if (i) {
|
||
answer.push(this.makeCode(joinStr));
|
||
}
|
||
answer = answer.concat(fragments);
|
||
}
|
||
return answer;
|
||
};
|
||
|
||
return Base;
|
||
|
||
})();
|
||
|
||
exports.Block = Block = (function(_super) {
|
||
__extends(Block, _super);
|
||
|
||
function Block(nodes) {
|
||
this.expressions = compact(flatten(nodes || []));
|
||
}
|
||
|
||
Block.prototype.children = ['expressions'];
|
||
|
||
Block.prototype.push = function(node) {
|
||
this.expressions.push(node);
|
||
return this;
|
||
};
|
||
|
||
Block.prototype.pop = function() {
|
||
return this.expressions.pop();
|
||
};
|
||
|
||
Block.prototype.unshift = function(node) {
|
||
this.expressions.unshift(node);
|
||
return this;
|
||
};
|
||
|
||
Block.prototype.unwrap = function() {
|
||
if (this.expressions.length === 1) {
|
||
return this.expressions[0];
|
||
} else {
|
||
return this;
|
||
}
|
||
};
|
||
|
||
Block.prototype.isEmpty = function() {
|
||
return !this.expressions.length;
|
||
};
|
||
|
||
Block.prototype.isStatement = function(o) {
|
||
var exp, _i, _len, _ref2;
|
||
_ref2 = this.expressions;
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
exp = _ref2[_i];
|
||
if (exp.isStatement(o)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
Block.prototype.jumps = function(o) {
|
||
var exp, jumpNode, _i, _len, _ref2;
|
||
_ref2 = this.expressions;
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
exp = _ref2[_i];
|
||
if (jumpNode = exp.jumps(o)) {
|
||
return jumpNode;
|
||
}
|
||
}
|
||
};
|
||
|
||
Block.prototype.makeReturn = function(res) {
|
||
var expr, len;
|
||
len = this.expressions.length;
|
||
while (len--) {
|
||
expr = this.expressions[len];
|
||
if (!(expr instanceof Comment)) {
|
||
this.expressions[len] = expr.makeReturn(res);
|
||
if (expr instanceof Return && !expr.expression) {
|
||
this.expressions.splice(len, 1);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return this;
|
||
};
|
||
|
||
Block.prototype.compileToFragments = function(o, level) {
|
||
if (o == null) {
|
||
o = {};
|
||
}
|
||
if (o.scope) {
|
||
return Block.__super__.compileToFragments.call(this, o, level);
|
||
} else {
|
||
return this.compileRoot(o);
|
||
}
|
||
};
|
||
|
||
Block.prototype.compileNode = function(o) {
|
||
var answer, compiledNodes, fragments, index, node, top, _i, _len, _ref2;
|
||
this.tab = o.indent;
|
||
top = o.level === LEVEL_TOP;
|
||
compiledNodes = [];
|
||
_ref2 = this.expressions;
|
||
for (index = _i = 0, _len = _ref2.length; _i < _len; index = ++_i) {
|
||
node = _ref2[index];
|
||
node = node.unwrapAll();
|
||
node = node.unfoldSoak(o) || node;
|
||
if (node instanceof Block) {
|
||
compiledNodes.push(node.compileNode(o));
|
||
} else if (top) {
|
||
node.front = true;
|
||
fragments = node.compileToFragments(o);
|
||
if (!node.isStatement(o)) {
|
||
fragments.unshift(this.makeCode("" + this.tab));
|
||
fragments.push(this.makeCode(";"));
|
||
}
|
||
compiledNodes.push(fragments);
|
||
} else {
|
||
compiledNodes.push(node.compileToFragments(o, LEVEL_LIST));
|
||
}
|
||
}
|
||
if (top) {
|
||
if (this.spaced) {
|
||
return [].concat(this.joinFragmentArrays(compiledNodes, '\n\n'), this.makeCode("\n"));
|
||
} else {
|
||
return this.joinFragmentArrays(compiledNodes, '\n');
|
||
}
|
||
}
|
||
if (compiledNodes.length) {
|
||
answer = this.joinFragmentArrays(compiledNodes, ', ');
|
||
} else {
|
||
answer = [this.makeCode("void 0")];
|
||
}
|
||
if (compiledNodes.length > 1 && o.level >= LEVEL_LIST) {
|
||
return this.wrapInBraces(answer);
|
||
} else {
|
||
return answer;
|
||
}
|
||
};
|
||
|
||
Block.prototype.compileRoot = function(o) {
|
||
var exp, fragments, i, name, prelude, preludeExps, rest, _i, _len, _ref2;
|
||
o.indent = o.bare ? '' : TAB;
|
||
o.level = LEVEL_TOP;
|
||
this.spaced = true;
|
||
o.scope = new Scope(null, this, null);
|
||
_ref2 = o.locals || [];
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
name = _ref2[_i];
|
||
o.scope.parameter(name);
|
||
}
|
||
prelude = [];
|
||
if (!o.bare) {
|
||
preludeExps = (function() {
|
||
var _j, _len1, _ref3, _results;
|
||
_ref3 = this.expressions;
|
||
_results = [];
|
||
for (i = _j = 0, _len1 = _ref3.length; _j < _len1; i = ++_j) {
|
||
exp = _ref3[i];
|
||
if (!(exp.unwrap() instanceof Comment)) {
|
||
break;
|
||
}
|
||
_results.push(exp);
|
||
}
|
||
return _results;
|
||
}).call(this);
|
||
rest = this.expressions.slice(preludeExps.length);
|
||
this.expressions = preludeExps;
|
||
if (preludeExps.length) {
|
||
prelude = this.compileNode(merge(o, {
|
||
indent: ''
|
||
}));
|
||
prelude.push(this.makeCode("\n"));
|
||
}
|
||
this.expressions = rest;
|
||
}
|
||
fragments = this.compileWithDeclarations(o);
|
||
if (o.bare) {
|
||
return fragments;
|
||
}
|
||
return [].concat(prelude, this.makeCode("(function() {\n"), fragments, this.makeCode("\n}).call(this);\n"));
|
||
};
|
||
|
||
Block.prototype.compileWithDeclarations = function(o) {
|
||
var assigns, declars, exp, fragments, i, post, rest, scope, spaced, _i, _len, _ref2, _ref3, _ref4;
|
||
fragments = [];
|
||
post = [];
|
||
_ref2 = this.expressions;
|
||
for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
|
||
exp = _ref2[i];
|
||
exp = exp.unwrap();
|
||
if (!(exp instanceof Comment || exp instanceof Literal)) {
|
||
break;
|
||
}
|
||
}
|
||
o = merge(o, {
|
||
level: LEVEL_TOP
|
||
});
|
||
if (i) {
|
||
rest = this.expressions.splice(i, 9e9);
|
||
_ref3 = [this.spaced, false], spaced = _ref3[0], this.spaced = _ref3[1];
|
||
_ref4 = [this.compileNode(o), spaced], fragments = _ref4[0], this.spaced = _ref4[1];
|
||
this.expressions = rest;
|
||
}
|
||
post = this.compileNode(o);
|
||
scope = o.scope;
|
||
if (scope.expressions === this) {
|
||
declars = o.scope.hasDeclarations();
|
||
assigns = scope.hasAssignments;
|
||
if (declars || assigns) {
|
||
if (i) {
|
||
fragments.push(this.makeCode('\n'));
|
||
}
|
||
fragments.push(this.makeCode("" + this.tab + "var "));
|
||
if (declars) {
|
||
fragments.push(this.makeCode(scope.declaredVariables().join(', ')));
|
||
}
|
||
if (assigns) {
|
||
if (declars) {
|
||
fragments.push(this.makeCode(",\n" + (this.tab + TAB)));
|
||
}
|
||
fragments.push(this.makeCode(scope.assignedVariables().join(",\n" + (this.tab + TAB))));
|
||
}
|
||
fragments.push(this.makeCode(";\n" + (this.spaced ? '\n' : '')));
|
||
} else if (fragments.length && post.length) {
|
||
fragments.push(this.makeCode("\n"));
|
||
}
|
||
}
|
||
return fragments.concat(post);
|
||
};
|
||
|
||
Block.wrap = function(nodes) {
|
||
if (nodes.length === 1 && nodes[0] instanceof Block) {
|
||
return nodes[0];
|
||
}
|
||
return new Block(nodes);
|
||
};
|
||
|
||
return Block;
|
||
|
||
})(Base);
|
||
|
||
exports.Literal = Literal = (function(_super) {
|
||
__extends(Literal, _super);
|
||
|
||
function Literal(value) {
|
||
this.value = value;
|
||
}
|
||
|
||
Literal.prototype.makeReturn = function() {
|
||
if (this.isStatement()) {
|
||
return this;
|
||
} else {
|
||
return Literal.__super__.makeReturn.apply(this, arguments);
|
||
}
|
||
};
|
||
|
||
Literal.prototype.isAssignable = function() {
|
||
return IDENTIFIER.test(this.value);
|
||
};
|
||
|
||
Literal.prototype.isStatement = function() {
|
||
var _ref2;
|
||
return (_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger';
|
||
};
|
||
|
||
Literal.prototype.isComplex = NO;
|
||
|
||
Literal.prototype.assigns = function(name) {
|
||
return name === this.value;
|
||
};
|
||
|
||
Literal.prototype.jumps = function(o) {
|
||
if (this.value === 'break' && !((o != null ? o.loop : void 0) || (o != null ? o.block : void 0))) {
|
||
return this;
|
||
}
|
||
if (this.value === 'continue' && !(o != null ? o.loop : void 0)) {
|
||
return this;
|
||
}
|
||
};
|
||
|
||
Literal.prototype.compileNode = function(o) {
|
||
var answer, code, _ref2;
|
||
code = this.value === 'this' ? ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0) ? o.scope.method.context : this.value : this.value.reserved ? "\"" + this.value + "\"" : this.value;
|
||
answer = this.isStatement() ? "" + this.tab + code + ";" : code;
|
||
return [this.makeCode(answer)];
|
||
};
|
||
|
||
Literal.prototype.toString = function() {
|
||
return ' "' + this.value + '"';
|
||
};
|
||
|
||
return Literal;
|
||
|
||
})(Base);
|
||
|
||
exports.Undefined = (function(_super) {
|
||
__extends(Undefined, _super);
|
||
|
||
function Undefined() {
|
||
return Undefined.__super__.constructor.apply(this, arguments);
|
||
}
|
||
|
||
Undefined.prototype.isAssignable = NO;
|
||
|
||
Undefined.prototype.isComplex = NO;
|
||
|
||
Undefined.prototype.compileNode = function(o) {
|
||
return [this.makeCode(o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0')];
|
||
};
|
||
|
||
return Undefined;
|
||
|
||
})(Base);
|
||
|
||
exports.Null = (function(_super) {
|
||
__extends(Null, _super);
|
||
|
||
function Null() {
|
||
return Null.__super__.constructor.apply(this, arguments);
|
||
}
|
||
|
||
Null.prototype.isAssignable = NO;
|
||
|
||
Null.prototype.isComplex = NO;
|
||
|
||
Null.prototype.compileNode = function() {
|
||
return [this.makeCode("null")];
|
||
};
|
||
|
||
return Null;
|
||
|
||
})(Base);
|
||
|
||
exports.Bool = (function(_super) {
|
||
__extends(Bool, _super);
|
||
|
||
Bool.prototype.isAssignable = NO;
|
||
|
||
Bool.prototype.isComplex = NO;
|
||
|
||
Bool.prototype.compileNode = function() {
|
||
return [this.makeCode(this.val)];
|
||
};
|
||
|
||
function Bool(val) {
|
||
this.val = val;
|
||
}
|
||
|
||
return Bool;
|
||
|
||
})(Base);
|
||
|
||
exports.Return = Return = (function(_super) {
|
||
__extends(Return, _super);
|
||
|
||
function Return(expression) {
|
||
this.expression = expression;
|
||
}
|
||
|
||
Return.prototype.children = ['expression'];
|
||
|
||
Return.prototype.isStatement = YES;
|
||
|
||
Return.prototype.makeReturn = THIS;
|
||
|
||
Return.prototype.jumps = THIS;
|
||
|
||
Return.prototype.compileToFragments = function(o, level) {
|
||
var expr, _ref2;
|
||
expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0;
|
||
if (expr && !(expr instanceof Return)) {
|
||
return expr.compileToFragments(o, level);
|
||
} else {
|
||
return Return.__super__.compileToFragments.call(this, o, level);
|
||
}
|
||
};
|
||
|
||
Return.prototype.compileNode = function(o) {
|
||
var answer;
|
||
answer = [];
|
||
answer.push(this.makeCode(this.tab + ("return" + (this.expression ? " " : ""))));
|
||
if (this.expression) {
|
||
answer = answer.concat(this.expression.compileToFragments(o, LEVEL_PAREN));
|
||
}
|
||
answer.push(this.makeCode(";"));
|
||
return answer;
|
||
};
|
||
|
||
return Return;
|
||
|
||
})(Base);
|
||
|
||
exports.Value = Value = (function(_super) {
|
||
__extends(Value, _super);
|
||
|
||
function Value(base, props, tag) {
|
||
if (!props && base instanceof Value) {
|
||
return base;
|
||
}
|
||
this.base = base;
|
||
this.properties = props || [];
|
||
if (tag) {
|
||
this[tag] = true;
|
||
}
|
||
return this;
|
||
}
|
||
|
||
Value.prototype.children = ['base', 'properties'];
|
||
|
||
Value.prototype.add = function(props) {
|
||
this.properties = this.properties.concat(props);
|
||
return this;
|
||
};
|
||
|
||
Value.prototype.hasProperties = function() {
|
||
return !!this.properties.length;
|
||
};
|
||
|
||
Value.prototype.bareLiteral = function(type) {
|
||
return !this.properties.length && this.base instanceof type;
|
||
};
|
||
|
||
Value.prototype.isArray = function() {
|
||
return this.bareLiteral(Arr);
|
||
};
|
||
|
||
Value.prototype.isRange = function() {
|
||
return this.bareLiteral(Range);
|
||
};
|
||
|
||
Value.prototype.isComplex = function() {
|
||
return this.hasProperties() || this.base.isComplex();
|
||
};
|
||
|
||
Value.prototype.isAssignable = function() {
|
||
return this.hasProperties() || this.base.isAssignable();
|
||
};
|
||
|
||
Value.prototype.isSimpleNumber = function() {
|
||
return this.bareLiteral(Literal) && SIMPLENUM.test(this.base.value);
|
||
};
|
||
|
||
Value.prototype.isString = function() {
|
||
return this.bareLiteral(Literal) && IS_STRING.test(this.base.value);
|
||
};
|
||
|
||
Value.prototype.isRegex = function() {
|
||
return this.bareLiteral(Literal) && IS_REGEX.test(this.base.value);
|
||
};
|
||
|
||
Value.prototype.isAtomic = function() {
|
||
var node, _i, _len, _ref2;
|
||
_ref2 = this.properties.concat(this.base);
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
node = _ref2[_i];
|
||
if (node.soak || node instanceof Call) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
};
|
||
|
||
Value.prototype.isNotCallable = function() {
|
||
return this.isSimpleNumber() || this.isString() || this.isRegex() || this.isArray() || this.isRange() || this.isSplice() || this.isObject();
|
||
};
|
||
|
||
Value.prototype.isStatement = function(o) {
|
||
return !this.properties.length && this.base.isStatement(o);
|
||
};
|
||
|
||
Value.prototype.assigns = function(name) {
|
||
return !this.properties.length && this.base.assigns(name);
|
||
};
|
||
|
||
Value.prototype.jumps = function(o) {
|
||
return !this.properties.length && this.base.jumps(o);
|
||
};
|
||
|
||
Value.prototype.isObject = function(onlyGenerated) {
|
||
if (this.properties.length) {
|
||
return false;
|
||
}
|
||
return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated);
|
||
};
|
||
|
||
Value.prototype.isSplice = function() {
|
||
return last(this.properties) instanceof Slice;
|
||
};
|
||
|
||
Value.prototype.looksStatic = function(className) {
|
||
var _ref2;
|
||
return this.base.value === className && this.properties.length && ((_ref2 = this.properties[0].name) != null ? _ref2.value : void 0) !== 'prototype';
|
||
};
|
||
|
||
Value.prototype.unwrap = function() {
|
||
if (this.properties.length) {
|
||
return this;
|
||
} else {
|
||
return this.base;
|
||
}
|
||
};
|
||
|
||
Value.prototype.cacheReference = function(o) {
|
||
var base, bref, name, nref;
|
||
name = last(this.properties);
|
||
if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) {
|
||
return [this, this];
|
||
}
|
||
base = new Value(this.base, this.properties.slice(0, -1));
|
||
if (base.isComplex()) {
|
||
bref = new Literal(o.scope.freeVariable('base'));
|
||
base = new Value(new Parens(new Assign(bref, base)));
|
||
}
|
||
if (!name) {
|
||
return [base, bref];
|
||
}
|
||
if (name.isComplex()) {
|
||
nref = new Literal(o.scope.freeVariable('name'));
|
||
name = new Index(new Assign(nref, name.index));
|
||
nref = new Index(nref);
|
||
}
|
||
return [base.add(name), new Value(bref || base.base, [nref || name])];
|
||
};
|
||
|
||
Value.prototype.compileNode = function(o) {
|
||
var fragments, prop, props, _i, _len;
|
||
this.base.front = this.front;
|
||
props = this.properties;
|
||
fragments = this.base.compileToFragments(o, (props.length ? LEVEL_ACCESS : null));
|
||
if ((this.base instanceof Parens || props.length) && SIMPLENUM.test(fragmentsToText(fragments))) {
|
||
fragments.push(this.makeCode('.'));
|
||
}
|
||
for (_i = 0, _len = props.length; _i < _len; _i++) {
|
||
prop = props[_i];
|
||
fragments.push.apply(fragments, prop.compileToFragments(o));
|
||
}
|
||
return fragments;
|
||
};
|
||
|
||
Value.prototype.unfoldSoak = function(o) {
|
||
return this.unfoldedSoak != null ? this.unfoldedSoak : this.unfoldedSoak = (function(_this) {
|
||
return function() {
|
||
var fst, i, ifn, prop, ref, snd, _i, _len, _ref2, _ref3;
|
||
if (ifn = _this.base.unfoldSoak(o)) {
|
||
(_ref2 = ifn.body.properties).push.apply(_ref2, _this.properties);
|
||
return ifn;
|
||
}
|
||
_ref3 = _this.properties;
|
||
for (i = _i = 0, _len = _ref3.length; _i < _len; i = ++_i) {
|
||
prop = _ref3[i];
|
||
if (!prop.soak) {
|
||
continue;
|
||
}
|
||
prop.soak = false;
|
||
fst = new Value(_this.base, _this.properties.slice(0, i));
|
||
snd = new Value(_this.base, _this.properties.slice(i));
|
||
if (fst.isComplex()) {
|
||
ref = new Literal(o.scope.freeVariable('ref'));
|
||
fst = new Parens(new Assign(ref, fst));
|
||
snd.base = ref;
|
||
}
|
||
return new If(new Existence(fst), snd, {
|
||
soak: true
|
||
});
|
||
}
|
||
return false;
|
||
};
|
||
})(this)();
|
||
};
|
||
|
||
return Value;
|
||
|
||
})(Base);
|
||
|
||
exports.Comment = Comment = (function(_super) {
|
||
__extends(Comment, _super);
|
||
|
||
function Comment(comment) {
|
||
this.comment = comment;
|
||
}
|
||
|
||
Comment.prototype.isStatement = YES;
|
||
|
||
Comment.prototype.makeReturn = THIS;
|
||
|
||
Comment.prototype.compileNode = function(o, level) {
|
||
var code, comment;
|
||
comment = this.comment.replace(/^(\s*)#/gm, "$1 *");
|
||
code = "/*" + (multident(comment, this.tab)) + (__indexOf.call(comment, '\n') >= 0 ? "\n" + this.tab : '') + " */";
|
||
if ((level || o.level) === LEVEL_TOP) {
|
||
code = o.indent + code;
|
||
}
|
||
return [this.makeCode("\n"), this.makeCode(code)];
|
||
};
|
||
|
||
return Comment;
|
||
|
||
})(Base);
|
||
|
||
exports.Call = Call = (function(_super) {
|
||
__extends(Call, _super);
|
||
|
||
function Call(variable, args, soak) {
|
||
this.args = args != null ? args : [];
|
||
this.soak = soak;
|
||
this.isNew = false;
|
||
this.isSuper = variable === 'super';
|
||
this.variable = this.isSuper ? null : variable;
|
||
if (variable instanceof Value && variable.isNotCallable()) {
|
||
variable.error("literal is not a function");
|
||
}
|
||
}
|
||
|
||
Call.prototype.children = ['variable', 'args'];
|
||
|
||
Call.prototype.newInstance = function() {
|
||
var base, _ref2;
|
||
base = ((_ref2 = this.variable) != null ? _ref2.base : void 0) || this.variable;
|
||
if (base instanceof Call && !base.isNew) {
|
||
base.newInstance();
|
||
} else {
|
||
this.isNew = true;
|
||
}
|
||
return this;
|
||
};
|
||
|
||
Call.prototype.superReference = function(o) {
|
||
var accesses, method;
|
||
method = o.scope.namedMethod();
|
||
if (method != null ? method.klass : void 0) {
|
||
accesses = [new Access(new Literal('__super__'))];
|
||
if (method["static"]) {
|
||
accesses.push(new Access(new Literal('constructor')));
|
||
}
|
||
accesses.push(new Access(new Literal(method.name)));
|
||
return (new Value(new Literal(method.klass), accesses)).compile(o);
|
||
} else if (method != null ? method.ctor : void 0) {
|
||
return "" + method.name + ".__super__.constructor";
|
||
} else {
|
||
return this.error('cannot call super outside of an instance method.');
|
||
}
|
||
};
|
||
|
||
Call.prototype.superThis = function(o) {
|
||
var method;
|
||
method = o.scope.method;
|
||
return (method && !method.klass && method.context) || "this";
|
||
};
|
||
|
||
Call.prototype.unfoldSoak = function(o) {
|
||
var call, ifn, left, list, rite, _i, _len, _ref2, _ref3;
|
||
if (this.soak) {
|
||
if (this.variable) {
|
||
if (ifn = unfoldSoak(o, this, 'variable')) {
|
||
return ifn;
|
||
}
|
||
_ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
|
||
} else {
|
||
left = new Literal(this.superReference(o));
|
||
rite = new Value(left);
|
||
}
|
||
rite = new Call(rite, this.args);
|
||
rite.isNew = this.isNew;
|
||
left = new Literal("typeof " + (left.compile(o)) + " === \"function\"");
|
||
return new If(left, new Value(rite), {
|
||
soak: true
|
||
});
|
||
}
|
||
call = this;
|
||
list = [];
|
||
while (true) {
|
||
if (call.variable instanceof Call) {
|
||
list.push(call);
|
||
call = call.variable;
|
||
continue;
|
||
}
|
||
if (!(call.variable instanceof Value)) {
|
||
break;
|
||
}
|
||
list.push(call);
|
||
if (!((call = call.variable.base) instanceof Call)) {
|
||
break;
|
||
}
|
||
}
|
||
_ref3 = list.reverse();
|
||
for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
|
||
call = _ref3[_i];
|
||
if (ifn) {
|
||
if (call.variable instanceof Call) {
|
||
call.variable = ifn;
|
||
} else {
|
||
call.variable.base = ifn;
|
||
}
|
||
}
|
||
ifn = unfoldSoak(o, call, 'variable');
|
||
}
|
||
return ifn;
|
||
};
|
||
|
||
Call.prototype.compileNode = function(o) {
|
||
var arg, argIndex, compiledArgs, compiledArray, fragments, preface, _i, _len, _ref2, _ref3;
|
||
if ((_ref2 = this.variable) != null) {
|
||
_ref2.front = this.front;
|
||
}
|
||
compiledArray = Splat.compileSplattedArray(o, this.args, true);
|
||
if (compiledArray.length) {
|
||
return this.compileSplat(o, compiledArray);
|
||
}
|
||
compiledArgs = [];
|
||
_ref3 = this.args;
|
||
for (argIndex = _i = 0, _len = _ref3.length; _i < _len; argIndex = ++_i) {
|
||
arg = _ref3[argIndex];
|
||
if (argIndex) {
|
||
compiledArgs.push(this.makeCode(", "));
|
||
}
|
||
compiledArgs.push.apply(compiledArgs, arg.compileToFragments(o, LEVEL_LIST));
|
||
}
|
||
fragments = [];
|
||
if (this.isSuper) {
|
||
preface = this.superReference(o) + (".call(" + (this.superThis(o)));
|
||
if (compiledArgs.length) {
|
||
preface += ", ";
|
||
}
|
||
fragments.push(this.makeCode(preface));
|
||
} else {
|
||
if (this.isNew) {
|
||
fragments.push(this.makeCode('new '));
|
||
}
|
||
fragments.push.apply(fragments, this.variable.compileToFragments(o, LEVEL_ACCESS));
|
||
fragments.push(this.makeCode("("));
|
||
}
|
||
fragments.push.apply(fragments, compiledArgs);
|
||
fragments.push(this.makeCode(")"));
|
||
return fragments;
|
||
};
|
||
|
||
Call.prototype.compileSplat = function(o, splatArgs) {
|
||
var answer, base, fun, idt, name, ref;
|
||
if (this.isSuper) {
|
||
return [].concat(this.makeCode("" + (this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", "), splatArgs, this.makeCode(")"));
|
||
}
|
||
if (this.isNew) {
|
||
idt = this.tab + TAB;
|
||
return [].concat(this.makeCode("(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args);\n" + idt + "return Object(result) === result ? result : child;\n" + this.tab + "})("), this.variable.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), splatArgs, this.makeCode(", function(){})"));
|
||
}
|
||
answer = [];
|
||
base = new Value(this.variable);
|
||
if ((name = base.properties.pop()) && base.isComplex()) {
|
||
ref = o.scope.freeVariable('ref');
|
||
answer = answer.concat(this.makeCode("(" + ref + " = "), base.compileToFragments(o, LEVEL_LIST), this.makeCode(")"), name.compileToFragments(o));
|
||
} else {
|
||
fun = base.compileToFragments(o, LEVEL_ACCESS);
|
||
if (SIMPLENUM.test(fragmentsToText(fun))) {
|
||
fun = this.wrapInBraces(fun);
|
||
}
|
||
if (name) {
|
||
ref = fragmentsToText(fun);
|
||
fun.push.apply(fun, name.compileToFragments(o));
|
||
} else {
|
||
ref = 'null';
|
||
}
|
||
answer = answer.concat(fun);
|
||
}
|
||
return answer = answer.concat(this.makeCode(".apply(" + ref + ", "), splatArgs, this.makeCode(")"));
|
||
};
|
||
|
||
return Call;
|
||
|
||
})(Base);
|
||
|
||
exports.Extends = Extends = (function(_super) {
|
||
__extends(Extends, _super);
|
||
|
||
function Extends(child, parent) {
|
||
this.child = child;
|
||
this.parent = parent;
|
||
}
|
||
|
||
Extends.prototype.children = ['child', 'parent'];
|
||
|
||
Extends.prototype.compileToFragments = function(o) {
|
||
return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compileToFragments(o);
|
||
};
|
||
|
||
return Extends;
|
||
|
||
})(Base);
|
||
|
||
exports.Access = Access = (function(_super) {
|
||
__extends(Access, _super);
|
||
|
||
function Access(name, tag) {
|
||
this.name = name;
|
||
this.name.asKey = true;
|
||
this.soak = tag === 'soak';
|
||
}
|
||
|
||
Access.prototype.children = ['name'];
|
||
|
||
Access.prototype.compileToFragments = function(o) {
|
||
var name;
|
||
name = this.name.compileToFragments(o);
|
||
if (IDENTIFIER.test(fragmentsToText(name))) {
|
||
name.unshift(this.makeCode("."));
|
||
} else {
|
||
name.unshift(this.makeCode("["));
|
||
name.push(this.makeCode("]"));
|
||
}
|
||
return name;
|
||
};
|
||
|
||
Access.prototype.isComplex = NO;
|
||
|
||
return Access;
|
||
|
||
})(Base);
|
||
|
||
exports.Index = Index = (function(_super) {
|
||
__extends(Index, _super);
|
||
|
||
function Index(index) {
|
||
this.index = index;
|
||
}
|
||
|
||
Index.prototype.children = ['index'];
|
||
|
||
Index.prototype.compileToFragments = function(o) {
|
||
return [].concat(this.makeCode("["), this.index.compileToFragments(o, LEVEL_PAREN), this.makeCode("]"));
|
||
};
|
||
|
||
Index.prototype.isComplex = function() {
|
||
return this.index.isComplex();
|
||
};
|
||
|
||
return Index;
|
||
|
||
})(Base);
|
||
|
||
exports.Range = Range = (function(_super) {
|
||
__extends(Range, _super);
|
||
|
||
Range.prototype.children = ['from', 'to'];
|
||
|
||
function Range(from, to, tag) {
|
||
this.from = from;
|
||
this.to = to;
|
||
this.exclusive = tag === 'exclusive';
|
||
this.equals = this.exclusive ? '' : '=';
|
||
}
|
||
|
||
Range.prototype.compileVariables = function(o) {
|
||
var step, _ref2, _ref3, _ref4, _ref5;
|
||
o = merge(o, {
|
||
top: true
|
||
});
|
||
_ref2 = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST)), this.fromC = _ref2[0], this.fromVar = _ref2[1];
|
||
_ref3 = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST)), this.toC = _ref3[0], this.toVar = _ref3[1];
|
||
if (step = del(o, 'step')) {
|
||
_ref4 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST)), this.step = _ref4[0], this.stepVar = _ref4[1];
|
||
}
|
||
_ref5 = [this.fromVar.match(NUMBER), this.toVar.match(NUMBER)], this.fromNum = _ref5[0], this.toNum = _ref5[1];
|
||
if (this.stepVar) {
|
||
return this.stepNum = this.stepVar.match(NUMBER);
|
||
}
|
||
};
|
||
|
||
Range.prototype.compileNode = function(o) {
|
||
var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart, _ref2, _ref3;
|
||
if (!this.fromVar) {
|
||
this.compileVariables(o);
|
||
}
|
||
if (!o.index) {
|
||
return this.compileArray(o);
|
||
}
|
||
known = this.fromNum && this.toNum;
|
||
idx = del(o, 'index');
|
||
idxName = del(o, 'name');
|
||
namedIndex = idxName && idxName !== idx;
|
||
varPart = "" + idx + " = " + this.fromC;
|
||
if (this.toC !== this.toVar) {
|
||
varPart += ", " + this.toC;
|
||
}
|
||
if (this.step !== this.stepVar) {
|
||
varPart += ", " + this.step;
|
||
}
|
||
_ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1];
|
||
condPart = this.stepNum ? parseNum(this.stepNum[0]) > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [parseNum(this.fromNum[0]), parseNum(this.toNum[0])], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = this.stepVar ? "" + this.stepVar + " > 0" : "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar);
|
||
stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? "" + idx + "++" : "" + idx + "--" : namedIndex ? "" + cond + " ? ++" + idx + " : --" + idx : "" + cond + " ? " + idx + "++ : " + idx + "--";
|
||
if (namedIndex) {
|
||
varPart = "" + idxName + " = " + varPart;
|
||
}
|
||
if (namedIndex) {
|
||
stepPart = "" + idxName + " = " + stepPart;
|
||
}
|
||
return [this.makeCode("" + varPart + "; " + condPart + "; " + stepPart)];
|
||
};
|
||
|
||
Range.prototype.compileArray = function(o) {
|
||
var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results;
|
||
if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) {
|
||
range = (function() {
|
||
_results = [];
|
||
for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); }
|
||
return _results;
|
||
}).apply(this);
|
||
if (this.exclusive) {
|
||
range.pop();
|
||
}
|
||
return [this.makeCode("[" + (range.join(', ')) + "]")];
|
||
}
|
||
idt = this.tab + TAB;
|
||
i = o.scope.freeVariable('i');
|
||
result = o.scope.freeVariable('results');
|
||
pre = "\n" + idt + result + " = [];";
|
||
if (this.fromNum && this.toNum) {
|
||
o.index = i;
|
||
body = fragmentsToText(this.compileNode(o));
|
||
} else {
|
||
vars = ("" + i + " = " + this.fromC) + (this.toC !== this.toVar ? ", " + this.toC : '');
|
||
cond = "" + this.fromVar + " <= " + this.toVar;
|
||
body = "var " + vars + "; " + cond + " ? " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + cond + " ? " + i + "++ : " + i + "--";
|
||
}
|
||
post = "{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + o.indent;
|
||
hasArgs = function(node) {
|
||
return node != null ? node.contains(isLiteralArguments) : void 0;
|
||
};
|
||
if (hasArgs(this.from) || hasArgs(this.to)) {
|
||
args = ', arguments';
|
||
}
|
||
return [this.makeCode("(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this" + (args != null ? args : '') + ")")];
|
||
};
|
||
|
||
return Range;
|
||
|
||
})(Base);
|
||
|
||
exports.Slice = Slice = (function(_super) {
|
||
__extends(Slice, _super);
|
||
|
||
Slice.prototype.children = ['range'];
|
||
|
||
function Slice(range) {
|
||
this.range = range;
|
||
Slice.__super__.constructor.call(this);
|
||
}
|
||
|
||
Slice.prototype.compileNode = function(o) {
|
||
var compiled, compiledText, from, fromCompiled, to, toStr, _ref2;
|
||
_ref2 = this.range, to = _ref2.to, from = _ref2.from;
|
||
fromCompiled = from && from.compileToFragments(o, LEVEL_PAREN) || [this.makeCode('0')];
|
||
if (to) {
|
||
compiled = to.compileToFragments(o, LEVEL_PAREN);
|
||
compiledText = fragmentsToText(compiled);
|
||
if (!(!this.range.exclusive && +compiledText === -1)) {
|
||
toStr = ', ' + (this.range.exclusive ? compiledText : SIMPLENUM.test(compiledText) ? "" + (+compiledText + 1) : (compiled = to.compileToFragments(o, LEVEL_ACCESS), "+" + (fragmentsToText(compiled)) + " + 1 || 9e9"));
|
||
}
|
||
}
|
||
return [this.makeCode(".slice(" + (fragmentsToText(fromCompiled)) + (toStr || '') + ")")];
|
||
};
|
||
|
||
return Slice;
|
||
|
||
})(Base);
|
||
|
||
exports.Obj = Obj = (function(_super) {
|
||
__extends(Obj, _super);
|
||
|
||
function Obj(props, generated) {
|
||
this.generated = generated != null ? generated : false;
|
||
this.objects = this.properties = props || [];
|
||
}
|
||
|
||
Obj.prototype.children = ['properties'];
|
||
|
||
Obj.prototype.compileNode = function(o) {
|
||
var answer, i, idt, indent, join, lastNoncom, node, prop, props, _i, _j, _len, _len1;
|
||
props = this.properties;
|
||
if (!props.length) {
|
||
return [this.makeCode(this.front ? '({})' : '{}')];
|
||
}
|
||
if (this.generated) {
|
||
for (_i = 0, _len = props.length; _i < _len; _i++) {
|
||
node = props[_i];
|
||
if (node instanceof Value) {
|
||
node.error('cannot have an implicit value in an implicit object');
|
||
}
|
||
}
|
||
}
|
||
idt = o.indent += TAB;
|
||
lastNoncom = this.lastNonComment(this.properties);
|
||
answer = [];
|
||
for (i = _j = 0, _len1 = props.length; _j < _len1; i = ++_j) {
|
||
prop = props[i];
|
||
join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n';
|
||
indent = prop instanceof Comment ? '' : idt;
|
||
if (prop instanceof Assign && prop.variable instanceof Value && prop.variable.hasProperties()) {
|
||
prop.variable.error('Invalid object key');
|
||
}
|
||
if (prop instanceof Value && prop["this"]) {
|
||
prop = new Assign(prop.properties[0].name, prop, 'object');
|
||
}
|
||
if (!(prop instanceof Comment)) {
|
||
if (!(prop instanceof Assign)) {
|
||
prop = new Assign(prop, prop, 'object');
|
||
}
|
||
(prop.variable.base || prop.variable).asKey = true;
|
||
}
|
||
if (indent) {
|
||
answer.push(this.makeCode(indent));
|
||
}
|
||
answer.push.apply(answer, prop.compileToFragments(o, LEVEL_TOP));
|
||
if (join) {
|
||
answer.push(this.makeCode(join));
|
||
}
|
||
}
|
||
answer.unshift(this.makeCode("{" + (props.length && '\n')));
|
||
answer.push(this.makeCode("" + (props.length && '\n' + this.tab) + "}"));
|
||
if (this.front) {
|
||
return this.wrapInBraces(answer);
|
||
} else {
|
||
return answer;
|
||
}
|
||
};
|
||
|
||
Obj.prototype.assigns = function(name) {
|
||
var prop, _i, _len, _ref2;
|
||
_ref2 = this.properties;
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
prop = _ref2[_i];
|
||
if (prop.assigns(name)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
return Obj;
|
||
|
||
})(Base);
|
||
|
||
exports.Arr = Arr = (function(_super) {
|
||
__extends(Arr, _super);
|
||
|
||
function Arr(objs) {
|
||
this.objects = objs || [];
|
||
}
|
||
|
||
Arr.prototype.children = ['objects'];
|
||
|
||
Arr.prototype.compileNode = function(o) {
|
||
var answer, compiledObjs, fragments, index, obj, _i, _len;
|
||
if (!this.objects.length) {
|
||
return [this.makeCode('[]')];
|
||
}
|
||
o.indent += TAB;
|
||
answer = Splat.compileSplattedArray(o, this.objects);
|
||
if (answer.length) {
|
||
return answer;
|
||
}
|
||
answer = [];
|
||
compiledObjs = (function() {
|
||
var _i, _len, _ref2, _results;
|
||
_ref2 = this.objects;
|
||
_results = [];
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
obj = _ref2[_i];
|
||
_results.push(obj.compileToFragments(o, LEVEL_LIST));
|
||
}
|
||
return _results;
|
||
}).call(this);
|
||
for (index = _i = 0, _len = compiledObjs.length; _i < _len; index = ++_i) {
|
||
fragments = compiledObjs[index];
|
||
if (index) {
|
||
answer.push(this.makeCode(", "));
|
||
}
|
||
answer.push.apply(answer, fragments);
|
||
}
|
||
if (fragmentsToText(answer).indexOf('\n') >= 0) {
|
||
answer.unshift(this.makeCode("[\n" + o.indent));
|
||
answer.push(this.makeCode("\n" + this.tab + "]"));
|
||
} else {
|
||
answer.unshift(this.makeCode("["));
|
||
answer.push(this.makeCode("]"));
|
||
}
|
||
return answer;
|
||
};
|
||
|
||
Arr.prototype.assigns = function(name) {
|
||
var obj, _i, _len, _ref2;
|
||
_ref2 = this.objects;
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
obj = _ref2[_i];
|
||
if (obj.assigns(name)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
return Arr;
|
||
|
||
})(Base);
|
||
|
||
exports.Class = Class = (function(_super) {
|
||
__extends(Class, _super);
|
||
|
||
function Class(variable, parent, body) {
|
||
this.variable = variable;
|
||
this.parent = parent;
|
||
this.body = body != null ? body : new Block;
|
||
this.boundFuncs = [];
|
||
this.body.classBody = true;
|
||
}
|
||
|
||
Class.prototype.children = ['variable', 'parent', 'body'];
|
||
|
||
Class.prototype.determineName = function() {
|
||
var decl, tail;
|
||
if (!this.variable) {
|
||
return null;
|
||
}
|
||
decl = (tail = last(this.variable.properties)) ? tail instanceof Access && tail.name.value : this.variable.base.value;
|
||
if (__indexOf.call(STRICT_PROSCRIBED, decl) >= 0) {
|
||
this.variable.error("class variable name may not be " + decl);
|
||
}
|
||
return decl && (decl = IDENTIFIER.test(decl) && decl);
|
||
};
|
||
|
||
Class.prototype.setContext = function(name) {
|
||
return this.body.traverseChildren(false, function(node) {
|
||
if (node.classBody) {
|
||
return false;
|
||
}
|
||
if (node instanceof Literal && node.value === 'this') {
|
||
return node.value = name;
|
||
} else if (node instanceof Code) {
|
||
node.klass = name;
|
||
if (node.bound) {
|
||
return node.context = name;
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
Class.prototype.addBoundFunctions = function(o) {
|
||
var bvar, lhs, _i, _len, _ref2;
|
||
_ref2 = this.boundFuncs;
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
bvar = _ref2[_i];
|
||
lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o);
|
||
this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)"));
|
||
}
|
||
};
|
||
|
||
Class.prototype.addProperties = function(node, name, o) {
|
||
var assign, base, exprs, func, props;
|
||
props = node.base.properties.slice(0);
|
||
exprs = (function() {
|
||
var _results;
|
||
_results = [];
|
||
while (assign = props.shift()) {
|
||
if (assign instanceof Assign) {
|
||
base = assign.variable.base;
|
||
delete assign.context;
|
||
func = assign.value;
|
||
if (base.value === 'constructor') {
|
||
if (this.ctor) {
|
||
assign.error('cannot define more than one constructor in a class');
|
||
}
|
||
if (func.bound) {
|
||
assign.error('cannot define a constructor as a bound function');
|
||
}
|
||
if (func instanceof Code) {
|
||
assign = this.ctor = func;
|
||
} else {
|
||
this.externalCtor = o.classScope.freeVariable('class');
|
||
assign = new Assign(new Literal(this.externalCtor), func);
|
||
}
|
||
} else {
|
||
if (assign.variable["this"]) {
|
||
func["static"] = true;
|
||
} else {
|
||
assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]);
|
||
if (func instanceof Code && func.bound) {
|
||
this.boundFuncs.push(base);
|
||
func.bound = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
_results.push(assign);
|
||
}
|
||
return _results;
|
||
}).call(this);
|
||
return compact(exprs);
|
||
};
|
||
|
||
Class.prototype.walkBody = function(name, o) {
|
||
return this.traverseChildren(false, (function(_this) {
|
||
return function(child) {
|
||
var cont, exps, i, node, _i, _len, _ref2;
|
||
cont = true;
|
||
if (child instanceof Class) {
|
||
return false;
|
||
}
|
||
if (child instanceof Block) {
|
||
_ref2 = exps = child.expressions;
|
||
for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
|
||
node = _ref2[i];
|
||
if (node instanceof Assign && node.variable.looksStatic(name)) {
|
||
node.value["static"] = true;
|
||
} else if (node instanceof Value && node.isObject(true)) {
|
||
cont = false;
|
||
exps[i] = _this.addProperties(node, name, o);
|
||
}
|
||
}
|
||
child.expressions = exps = flatten(exps);
|
||
}
|
||
return cont && !(child instanceof Class);
|
||
};
|
||
})(this));
|
||
};
|
||
|
||
Class.prototype.hoistDirectivePrologue = function() {
|
||
var expressions, index, node;
|
||
index = 0;
|
||
expressions = this.body.expressions;
|
||
while ((node = expressions[index]) && node instanceof Comment || node instanceof Value && node.isString()) {
|
||
++index;
|
||
}
|
||
return this.directives = expressions.splice(0, index);
|
||
};
|
||
|
||
Class.prototype.ensureConstructor = function(name) {
|
||
if (!this.ctor) {
|
||
this.ctor = new Code;
|
||
if (this.externalCtor) {
|
||
this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)"));
|
||
} else if (this.parent) {
|
||
this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)"));
|
||
}
|
||
this.ctor.body.makeReturn();
|
||
this.body.expressions.unshift(this.ctor);
|
||
}
|
||
this.ctor.ctor = this.ctor.name = name;
|
||
this.ctor.klass = null;
|
||
return this.ctor.noReturn = true;
|
||
};
|
||
|
||
Class.prototype.compileNode = function(o) {
|
||
var args, argumentsNode, func, jumpNode, klass, lname, name, superClass, _ref2;
|
||
if (jumpNode = this.body.jumps()) {
|
||
jumpNode.error('Class bodies cannot contain pure statements');
|
||
}
|
||
if (argumentsNode = this.body.contains(isLiteralArguments)) {
|
||
argumentsNode.error("Class bodies shouldn't reference arguments");
|
||
}
|
||
name = this.determineName() || '_Class';
|
||
if (name.reserved) {
|
||
name = "_" + name;
|
||
}
|
||
lname = new Literal(name);
|
||
func = new Code([], Block.wrap([this.body]));
|
||
args = [];
|
||
o.classScope = func.makeScope(o.scope);
|
||
this.hoistDirectivePrologue();
|
||
this.setContext(name);
|
||
this.walkBody(name, o);
|
||
this.ensureConstructor(name);
|
||
this.addBoundFunctions(o);
|
||
this.body.spaced = true;
|
||
this.body.expressions.push(lname);
|
||
if (this.parent) {
|
||
superClass = new Literal(o.classScope.freeVariable('super', false));
|
||
this.body.expressions.unshift(new Extends(lname, superClass));
|
||
func.params.push(new Param(superClass));
|
||
args.push(this.parent);
|
||
}
|
||
(_ref2 = this.body.expressions).unshift.apply(_ref2, this.directives);
|
||
klass = new Parens(new Call(func, args));
|
||
if (this.variable) {
|
||
klass = new Assign(this.variable, klass);
|
||
}
|
||
return klass.compileToFragments(o);
|
||
};
|
||
|
||
return Class;
|
||
|
||
})(Base);
|
||
|
||
exports.Assign = Assign = (function(_super) {
|
||
__extends(Assign, _super);
|
||
|
||
function Assign(variable, value, context, options) {
|
||
var forbidden, name, _ref2;
|
||
this.variable = variable;
|
||
this.value = value;
|
||
this.context = context;
|
||
this.param = options && options.param;
|
||
this.subpattern = options && options.subpattern;
|
||
forbidden = (_ref2 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0);
|
||
if (forbidden && this.context !== 'object') {
|
||
this.variable.error("variable name may not be \"" + name + "\"");
|
||
}
|
||
}
|
||
|
||
Assign.prototype.children = ['variable', 'value'];
|
||
|
||
Assign.prototype.isStatement = function(o) {
|
||
return (o != null ? o.level : void 0) === LEVEL_TOP && (this.context != null) && __indexOf.call(this.context, "?") >= 0;
|
||
};
|
||
|
||
Assign.prototype.assigns = function(name) {
|
||
return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
|
||
};
|
||
|
||
Assign.prototype.unfoldSoak = function(o) {
|
||
return unfoldSoak(o, this, 'variable');
|
||
};
|
||
|
||
Assign.prototype.compileNode = function(o) {
|
||
var answer, compiledName, isValue, match, name, val, varBase, _ref2, _ref3, _ref4, _ref5;
|
||
if (isValue = this.variable instanceof Value) {
|
||
if (this.variable.isArray() || this.variable.isObject()) {
|
||
return this.compilePatternMatch(o);
|
||
}
|
||
if (this.variable.isSplice()) {
|
||
return this.compileSplice(o);
|
||
}
|
||
if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') {
|
||
return this.compileConditional(o);
|
||
}
|
||
if ((_ref3 = this.context) === '**=' || _ref3 === '//=' || _ref3 === '%%=') {
|
||
return this.compileSpecialMath(o);
|
||
}
|
||
}
|
||
compiledName = this.variable.compileToFragments(o, LEVEL_LIST);
|
||
name = fragmentsToText(compiledName);
|
||
if (!this.context) {
|
||
varBase = this.variable.unwrapAll();
|
||
if (!varBase.isAssignable()) {
|
||
this.variable.error("\"" + (this.variable.compile(o)) + "\" cannot be assigned");
|
||
}
|
||
if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) {
|
||
if (this.param) {
|
||
o.scope.add(name, 'var');
|
||
} else {
|
||
o.scope.find(name);
|
||
}
|
||
}
|
||
}
|
||
if (this.value instanceof Code && (match = METHOD_DEF.exec(name))) {
|
||
if (match[2]) {
|
||
this.value.klass = match[1];
|
||
}
|
||
this.value.name = (_ref4 = (_ref5 = match[3]) != null ? _ref5 : match[4]) != null ? _ref4 : match[5];
|
||
}
|
||
val = this.value.compileToFragments(o, LEVEL_LIST);
|
||
if (this.context === 'object') {
|
||
return compiledName.concat(this.makeCode(": "), val);
|
||
}
|
||
answer = compiledName.concat(this.makeCode(" " + (this.context || '=') + " "), val);
|
||
if (o.level <= LEVEL_LIST) {
|
||
return answer;
|
||
} else {
|
||
return this.wrapInBraces(answer);
|
||
}
|
||
};
|
||
|
||
Assign.prototype.compilePatternMatch = function(o) {
|
||
var acc, assigns, code, expandedIdx, fragments, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, top, val, value, vvar, vvarText, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
|
||
top = o.level === LEVEL_TOP;
|
||
value = this.value;
|
||
objects = this.variable.base.objects;
|
||
if (!(olen = objects.length)) {
|
||
code = value.compileToFragments(o);
|
||
if (o.level >= LEVEL_OP) {
|
||
return this.wrapInBraces(code);
|
||
} else {
|
||
return code;
|
||
}
|
||
}
|
||
isObject = this.variable.isObject();
|
||
if (top && olen === 1 && !((obj = objects[0]) instanceof Splat)) {
|
||
if (obj instanceof Assign) {
|
||
_ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value;
|
||
} else {
|
||
idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
|
||
}
|
||
acc = IDENTIFIER.test(idx.unwrap().value || 0);
|
||
value = new Value(value);
|
||
value.properties.push(new (acc ? Access : Index)(idx));
|
||
if (_ref4 = obj.unwrap().value, __indexOf.call(RESERVED, _ref4) >= 0) {
|
||
obj.error("assignment to a reserved word: " + (obj.compile(o)));
|
||
}
|
||
return new Assign(obj, value, null, {
|
||
param: this.param
|
||
}).compileToFragments(o, LEVEL_TOP);
|
||
}
|
||
vvar = value.compileToFragments(o, LEVEL_LIST);
|
||
vvarText = fragmentsToText(vvar);
|
||
assigns = [];
|
||
expandedIdx = false;
|
||
if (!IDENTIFIER.test(vvarText) || this.variable.assigns(vvarText)) {
|
||
assigns.push([this.makeCode("" + (ref = o.scope.freeVariable('ref')) + " = ")].concat(__slice.call(vvar)));
|
||
vvar = [this.makeCode(ref)];
|
||
vvarText = ref;
|
||
}
|
||
for (i = _i = 0, _len = objects.length; _i < _len; i = ++_i) {
|
||
obj = objects[i];
|
||
idx = i;
|
||
if (isObject) {
|
||
if (obj instanceof Assign) {
|
||
_ref5 = obj, (_ref6 = _ref5.variable, idx = _ref6.base), obj = _ref5.value;
|
||
} else {
|
||
if (obj.base instanceof Parens) {
|
||
_ref7 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref7[0], idx = _ref7[1];
|
||
} else {
|
||
idx = obj["this"] ? obj.properties[0].name : obj;
|
||
}
|
||
}
|
||
}
|
||
if (!expandedIdx && obj instanceof Splat) {
|
||
name = obj.name.unwrap().value;
|
||
obj = obj.unwrap();
|
||
val = "" + olen + " <= " + vvarText + ".length ? " + (utility('slice')) + ".call(" + vvarText + ", " + i;
|
||
if (rest = olen - i - 1) {
|
||
ivar = o.scope.freeVariable('i');
|
||
val += ", " + ivar + " = " + vvarText + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])";
|
||
} else {
|
||
val += ") : []";
|
||
}
|
||
val = new Literal(val);
|
||
expandedIdx = "" + ivar + "++";
|
||
} else if (!expandedIdx && obj instanceof Expansion) {
|
||
if (rest = olen - i - 1) {
|
||
if (rest === 1) {
|
||
expandedIdx = "" + vvarText + ".length - 1";
|
||
} else {
|
||
ivar = o.scope.freeVariable('i');
|
||
val = new Literal("" + ivar + " = " + vvarText + ".length - " + rest);
|
||
expandedIdx = "" + ivar + "++";
|
||
assigns.push(val.compileToFragments(o, LEVEL_LIST));
|
||
}
|
||
}
|
||
continue;
|
||
} else {
|
||
name = obj.unwrap().value;
|
||
if (obj instanceof Splat || obj instanceof Expansion) {
|
||
obj.error("multiple splats/expansions are disallowed in an assignment");
|
||
}
|
||
if (typeof idx === 'number') {
|
||
idx = new Literal(expandedIdx || idx);
|
||
acc = false;
|
||
} else {
|
||
acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0);
|
||
}
|
||
val = new Value(new Literal(vvarText), [new (acc ? Access : Index)(idx)]);
|
||
}
|
||
if ((name != null) && __indexOf.call(RESERVED, name) >= 0) {
|
||
obj.error("assignment to a reserved word: " + (obj.compile(o)));
|
||
}
|
||
assigns.push(new Assign(obj, val, null, {
|
||
param: this.param,
|
||
subpattern: true
|
||
}).compileToFragments(o, LEVEL_LIST));
|
||
}
|
||
if (!(top || this.subpattern)) {
|
||
assigns.push(vvar);
|
||
}
|
||
fragments = this.joinFragmentArrays(assigns, ', ');
|
||
if (o.level < LEVEL_LIST) {
|
||
return fragments;
|
||
} else {
|
||
return this.wrapInBraces(fragments);
|
||
}
|
||
};
|
||
|
||
Assign.prototype.compileConditional = function(o) {
|
||
var fragments, left, right, _ref2;
|
||
_ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1];
|
||
if (!left.properties.length && left.base instanceof Literal && left.base.value !== "this" && !o.scope.check(left.base.value)) {
|
||
this.variable.error("the variable \"" + left.base.value + "\" can't be assigned with " + this.context + " because it has not been declared before");
|
||
}
|
||
if (__indexOf.call(this.context, "?") >= 0) {
|
||
o.isExistentialEquals = true;
|
||
return new If(new Existence(left), right, {
|
||
type: 'if'
|
||
}).addElse(new Assign(right, this.value, '=')).compileToFragments(o);
|
||
} else {
|
||
fragments = new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compileToFragments(o);
|
||
if (o.level <= LEVEL_LIST) {
|
||
return fragments;
|
||
} else {
|
||
return this.wrapInBraces(fragments);
|
||
}
|
||
}
|
||
};
|
||
|
||
Assign.prototype.compileSpecialMath = function(o) {
|
||
var left, right, _ref2;
|
||
_ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1];
|
||
return new Assign(left, new Op(this.context.slice(0, -1), right, this.value)).compileToFragments(o);
|
||
};
|
||
|
||
Assign.prototype.compileSplice = function(o) {
|
||
var answer, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4;
|
||
_ref2 = this.variable.properties.pop().range, from = _ref2.from, to = _ref2.to, exclusive = _ref2.exclusive;
|
||
name = this.variable.compile(o);
|
||
if (from) {
|
||
_ref3 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = _ref3[0], fromRef = _ref3[1];
|
||
} else {
|
||
fromDecl = fromRef = '0';
|
||
}
|
||
if (to) {
|
||
if (from instanceof Value && from.isSimpleNumber() && to instanceof Value && to.isSimpleNumber()) {
|
||
to = to.compile(o) - fromRef;
|
||
if (!exclusive) {
|
||
to += 1;
|
||
}
|
||
} else {
|
||
to = to.compile(o, LEVEL_ACCESS) + ' - ' + fromRef;
|
||
if (!exclusive) {
|
||
to += ' + 1';
|
||
}
|
||
}
|
||
} else {
|
||
to = "9e9";
|
||
}
|
||
_ref4 = this.value.cache(o, LEVEL_LIST), valDef = _ref4[0], valRef = _ref4[1];
|
||
answer = [].concat(this.makeCode("[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat("), valDef, this.makeCode(")), "), valRef);
|
||
if (o.level > LEVEL_TOP) {
|
||
return this.wrapInBraces(answer);
|
||
} else {
|
||
return answer;
|
||
}
|
||
};
|
||
|
||
return Assign;
|
||
|
||
})(Base);
|
||
|
||
exports.Code = Code = (function(_super) {
|
||
__extends(Code, _super);
|
||
|
||
function Code(params, body, tag) {
|
||
this.params = params || [];
|
||
this.body = body || new Block;
|
||
this.bound = tag === 'boundfunc';
|
||
}
|
||
|
||
Code.prototype.children = ['params', 'body'];
|
||
|
||
Code.prototype.isStatement = function() {
|
||
return !!this.ctor;
|
||
};
|
||
|
||
Code.prototype.jumps = NO;
|
||
|
||
Code.prototype.makeScope = function(parentScope) {
|
||
return new Scope(parentScope, this.body, this);
|
||
};
|
||
|
||
Code.prototype.compileNode = function(o) {
|
||
var answer, boundfunc, code, exprs, i, lit, p, param, params, ref, splats, uniqs, val, wasEmpty, wrapper, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _m, _n, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
|
||
if (this.bound && ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0)) {
|
||
this.context = o.scope.method.context;
|
||
}
|
||
if (this.bound && !this.context) {
|
||
this.context = '_this';
|
||
wrapper = new Code([new Param(new Literal(this.context))], new Block([this]));
|
||
boundfunc = new Call(wrapper, [new Literal('this')]);
|
||
boundfunc.updateLocationDataIfMissing(this.locationData);
|
||
return boundfunc.compileNode(o);
|
||
}
|
||
o.scope = del(o, 'classScope') || this.makeScope(o.scope);
|
||
o.scope.shared = del(o, 'sharedScope');
|
||
o.indent += TAB;
|
||
delete o.bare;
|
||
delete o.isExistentialEquals;
|
||
params = [];
|
||
exprs = [];
|
||
_ref3 = this.params;
|
||
for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
|
||
param = _ref3[_i];
|
||
if (!(param instanceof Expansion)) {
|
||
o.scope.parameter(param.asReference(o));
|
||
}
|
||
}
|
||
_ref4 = this.params;
|
||
for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
|
||
param = _ref4[_j];
|
||
if (!(param.splat || param instanceof Expansion)) {
|
||
continue;
|
||
}
|
||
_ref5 = this.params;
|
||
for (_k = 0, _len2 = _ref5.length; _k < _len2; _k++) {
|
||
p = _ref5[_k].name;
|
||
if (!(!(param instanceof Expansion))) {
|
||
continue;
|
||
}
|
||
if (p["this"]) {
|
||
p = p.properties[0].name;
|
||
}
|
||
if (p.value) {
|
||
o.scope.add(p.value, 'var', true);
|
||
}
|
||
}
|
||
splats = new Assign(new Value(new Arr((function() {
|
||
var _l, _len3, _ref6, _results;
|
||
_ref6 = this.params;
|
||
_results = [];
|
||
for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) {
|
||
p = _ref6[_l];
|
||
_results.push(p.asReference(o));
|
||
}
|
||
return _results;
|
||
}).call(this))), new Value(new Literal('arguments')));
|
||
break;
|
||
}
|
||
_ref6 = this.params;
|
||
for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) {
|
||
param = _ref6[_l];
|
||
if (param.isComplex()) {
|
||
val = ref = param.asReference(o);
|
||
if (param.value) {
|
||
val = new Op('?', ref, param.value);
|
||
}
|
||
exprs.push(new Assign(new Value(param.name), val, '=', {
|
||
param: true
|
||
}));
|
||
} else {
|
||
ref = param;
|
||
if (param.value) {
|
||
lit = new Literal(ref.name.value + ' == null');
|
||
val = new Assign(new Value(param.name), param.value, '=');
|
||
exprs.push(new If(lit, val));
|
||
}
|
||
}
|
||
if (!splats) {
|
||
params.push(ref);
|
||
}
|
||
}
|
||
wasEmpty = this.body.isEmpty();
|
||
if (splats) {
|
||
exprs.unshift(splats);
|
||
}
|
||
if (exprs.length) {
|
||
(_ref7 = this.body.expressions).unshift.apply(_ref7, exprs);
|
||
}
|
||
for (i = _m = 0, _len4 = params.length; _m < _len4; i = ++_m) {
|
||
p = params[i];
|
||
params[i] = p.compileToFragments(o);
|
||
o.scope.parameter(fragmentsToText(params[i]));
|
||
}
|
||
uniqs = [];
|
||
this.eachParamName(function(name, node) {
|
||
if (__indexOf.call(uniqs, name) >= 0) {
|
||
node.error("multiple parameters named '" + name + "'");
|
||
}
|
||
return uniqs.push(name);
|
||
});
|
||
if (!(wasEmpty || this.noReturn)) {
|
||
this.body.makeReturn();
|
||
}
|
||
code = 'function';
|
||
if (this.ctor) {
|
||
code += ' ' + this.name;
|
||
}
|
||
code += '(';
|
||
answer = [this.makeCode(code)];
|
||
for (i = _n = 0, _len5 = params.length; _n < _len5; i = ++_n) {
|
||
p = params[i];
|
||
if (i) {
|
||
answer.push(this.makeCode(", "));
|
||
}
|
||
answer.push.apply(answer, p);
|
||
}
|
||
answer.push(this.makeCode(') {'));
|
||
if (!this.body.isEmpty()) {
|
||
answer = answer.concat(this.makeCode("\n"), this.body.compileWithDeclarations(o), this.makeCode("\n" + this.tab));
|
||
}
|
||
answer.push(this.makeCode('}'));
|
||
if (this.ctor) {
|
||
return [this.makeCode(this.tab)].concat(__slice.call(answer));
|
||
}
|
||
if (this.front || (o.level >= LEVEL_ACCESS)) {
|
||
return this.wrapInBraces(answer);
|
||
} else {
|
||
return answer;
|
||
}
|
||
};
|
||
|
||
Code.prototype.eachParamName = function(iterator) {
|
||
var param, _i, _len, _ref2, _results;
|
||
_ref2 = this.params;
|
||
_results = [];
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
param = _ref2[_i];
|
||
_results.push(param.eachName(iterator));
|
||
}
|
||
return _results;
|
||
};
|
||
|
||
Code.prototype.traverseChildren = function(crossScope, func) {
|
||
if (crossScope) {
|
||
return Code.__super__.traverseChildren.call(this, crossScope, func);
|
||
}
|
||
};
|
||
|
||
return Code;
|
||
|
||
})(Base);
|
||
|
||
exports.Param = Param = (function(_super) {
|
||
__extends(Param, _super);
|
||
|
||
function Param(name, value, splat) {
|
||
var _ref2;
|
||
this.name = name;
|
||
this.value = value;
|
||
this.splat = splat;
|
||
if (_ref2 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) {
|
||
this.name.error("parameter name \"" + name + "\" is not allowed");
|
||
}
|
||
}
|
||
|
||
Param.prototype.children = ['name', 'value'];
|
||
|
||
Param.prototype.compileToFragments = function(o) {
|
||
return this.name.compileToFragments(o, LEVEL_LIST);
|
||
};
|
||
|
||
Param.prototype.asReference = function(o) {
|
||
var node;
|
||
if (this.reference) {
|
||
return this.reference;
|
||
}
|
||
node = this.name;
|
||
if (node["this"]) {
|
||
node = node.properties[0].name;
|
||
if (node.value.reserved) {
|
||
node = new Literal(o.scope.freeVariable(node.value));
|
||
}
|
||
} else if (node.isComplex()) {
|
||
node = new Literal(o.scope.freeVariable('arg'));
|
||
}
|
||
node = new Value(node);
|
||
if (this.splat) {
|
||
node = new Splat(node);
|
||
}
|
||
node.updateLocationDataIfMissing(this.locationData);
|
||
return this.reference = node;
|
||
};
|
||
|
||
Param.prototype.isComplex = function() {
|
||
return this.name.isComplex();
|
||
};
|
||
|
||
Param.prototype.eachName = function(iterator, name) {
|
||
var atParam, node, obj, _i, _len, _ref2;
|
||
if (name == null) {
|
||
name = this.name;
|
||
}
|
||
atParam = function(obj) {
|
||
var node;
|
||
node = obj.properties[0].name;
|
||
if (!node.value.reserved) {
|
||
return iterator(node.value, node);
|
||
}
|
||
};
|
||
if (name instanceof Literal) {
|
||
return iterator(name.value, name);
|
||
}
|
||
if (name instanceof Value) {
|
||
return atParam(name);
|
||
}
|
||
_ref2 = name.objects;
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
obj = _ref2[_i];
|
||
if (obj instanceof Assign) {
|
||
this.eachName(iterator, obj.value.unwrap());
|
||
} else if (obj instanceof Splat) {
|
||
node = obj.name.unwrap();
|
||
iterator(node.value, node);
|
||
} else if (obj instanceof Value) {
|
||
if (obj.isArray() || obj.isObject()) {
|
||
this.eachName(iterator, obj.base);
|
||
} else if (obj["this"]) {
|
||
atParam(obj);
|
||
} else {
|
||
iterator(obj.base.value, obj.base);
|
||
}
|
||
} else if (!(obj instanceof Expansion)) {
|
||
obj.error("illegal parameter " + (obj.compile()));
|
||
}
|
||
}
|
||
};
|
||
|
||
return Param;
|
||
|
||
})(Base);
|
||
|
||
exports.Splat = Splat = (function(_super) {
|
||
__extends(Splat, _super);
|
||
|
||
Splat.prototype.children = ['name'];
|
||
|
||
Splat.prototype.isAssignable = YES;
|
||
|
||
function Splat(name) {
|
||
this.name = name.compile ? name : new Literal(name);
|
||
}
|
||
|
||
Splat.prototype.assigns = function(name) {
|
||
return this.name.assigns(name);
|
||
};
|
||
|
||
Splat.prototype.compileToFragments = function(o) {
|
||
return this.name.compileToFragments(o);
|
||
};
|
||
|
||
Splat.prototype.unwrap = function() {
|
||
return this.name;
|
||
};
|
||
|
||
Splat.compileSplattedArray = function(o, list, apply) {
|
||
var args, base, compiledNode, concatPart, fragments, i, index, node, _i, _len;
|
||
index = -1;
|
||
while ((node = list[++index]) && !(node instanceof Splat)) {
|
||
continue;
|
||
}
|
||
if (index >= list.length) {
|
||
return [];
|
||
}
|
||
if (list.length === 1) {
|
||
node = list[0];
|
||
fragments = node.compileToFragments(o, LEVEL_LIST);
|
||
if (apply) {
|
||
return fragments;
|
||
}
|
||
return [].concat(node.makeCode("" + (utility('slice')) + ".call("), fragments, node.makeCode(")"));
|
||
}
|
||
args = list.slice(index);
|
||
for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) {
|
||
node = args[i];
|
||
compiledNode = node.compileToFragments(o, LEVEL_LIST);
|
||
args[i] = node instanceof Splat ? [].concat(node.makeCode("" + (utility('slice')) + ".call("), compiledNode, node.makeCode(")")) : [].concat(node.makeCode("["), compiledNode, node.makeCode("]"));
|
||
}
|
||
if (index === 0) {
|
||
node = list[0];
|
||
concatPart = node.joinFragmentArrays(args.slice(1), ', ');
|
||
return args[0].concat(node.makeCode(".concat("), concatPart, node.makeCode(")"));
|
||
}
|
||
base = (function() {
|
||
var _j, _len1, _ref2, _results;
|
||
_ref2 = list.slice(0, index);
|
||
_results = [];
|
||
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
|
||
node = _ref2[_j];
|
||
_results.push(node.compileToFragments(o, LEVEL_LIST));
|
||
}
|
||
return _results;
|
||
})();
|
||
base = list[0].joinFragmentArrays(base, ', ');
|
||
concatPart = list[index].joinFragmentArrays(args, ', ');
|
||
return [].concat(list[0].makeCode("["), base, list[index].makeCode("].concat("), concatPart, (last(list)).makeCode(")"));
|
||
};
|
||
|
||
return Splat;
|
||
|
||
})(Base);
|
||
|
||
exports.Expansion = Expansion = (function(_super) {
|
||
__extends(Expansion, _super);
|
||
|
||
function Expansion() {
|
||
return Expansion.__super__.constructor.apply(this, arguments);
|
||
}
|
||
|
||
Expansion.prototype.isComplex = NO;
|
||
|
||
Expansion.prototype.compileNode = function(o) {
|
||
return this.error('Expansion must be used inside a destructuring assignment or parameter list');
|
||
};
|
||
|
||
Expansion.prototype.asReference = function(o) {
|
||
return this;
|
||
};
|
||
|
||
Expansion.prototype.eachName = function(iterator) {};
|
||
|
||
return Expansion;
|
||
|
||
})(Base);
|
||
|
||
exports.While = While = (function(_super) {
|
||
__extends(While, _super);
|
||
|
||
function While(condition, options) {
|
||
this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition;
|
||
this.guard = options != null ? options.guard : void 0;
|
||
}
|
||
|
||
While.prototype.children = ['condition', 'guard', 'body'];
|
||
|
||
While.prototype.isStatement = YES;
|
||
|
||
While.prototype.makeReturn = function(res) {
|
||
if (res) {
|
||
return While.__super__.makeReturn.apply(this, arguments);
|
||
} else {
|
||
this.returns = !this.jumps({
|
||
loop: true
|
||
});
|
||
return this;
|
||
}
|
||
};
|
||
|
||
While.prototype.addBody = function(body) {
|
||
this.body = body;
|
||
return this;
|
||
};
|
||
|
||
While.prototype.jumps = function() {
|
||
var expressions, jumpNode, node, _i, _len;
|
||
expressions = this.body.expressions;
|
||
if (!expressions.length) {
|
||
return false;
|
||
}
|
||
for (_i = 0, _len = expressions.length; _i < _len; _i++) {
|
||
node = expressions[_i];
|
||
if (jumpNode = node.jumps({
|
||
loop: true
|
||
})) {
|
||
return jumpNode;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
While.prototype.compileNode = function(o) {
|
||
var answer, body, rvar, set;
|
||
o.indent += TAB;
|
||
set = '';
|
||
body = this.body;
|
||
if (body.isEmpty()) {
|
||
body = this.makeCode('');
|
||
} else {
|
||
if (this.returns) {
|
||
body.makeReturn(rvar = o.scope.freeVariable('results'));
|
||
set = "" + this.tab + rvar + " = [];\n";
|
||
}
|
||
if (this.guard) {
|
||
if (body.expressions.length > 1) {
|
||
body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
|
||
} else {
|
||
if (this.guard) {
|
||
body = Block.wrap([new If(this.guard, body)]);
|
||
}
|
||
}
|
||
}
|
||
body = [].concat(this.makeCode("\n"), body.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab));
|
||
}
|
||
answer = [].concat(this.makeCode(set + this.tab + "while ("), this.condition.compileToFragments(o, LEVEL_PAREN), this.makeCode(") {"), body, this.makeCode("}"));
|
||
if (this.returns) {
|
||
answer.push(this.makeCode("\n" + this.tab + "return " + rvar + ";"));
|
||
}
|
||
return answer;
|
||
};
|
||
|
||
return While;
|
||
|
||
})(Base);
|
||
|
||
exports.Op = Op = (function(_super) {
|
||
var CONVERSIONS, INVERSIONS;
|
||
|
||
__extends(Op, _super);
|
||
|
||
function Op(op, first, second, flip) {
|
||
if (op === 'in') {
|
||
return new In(first, second);
|
||
}
|
||
if (op === 'do') {
|
||
return this.generateDo(first);
|
||
}
|
||
if (op === 'new') {
|
||
if (first instanceof Call && !first["do"] && !first.isNew) {
|
||
return first.newInstance();
|
||
}
|
||
if (first instanceof Code && first.bound || first["do"]) {
|
||
first = new Parens(first);
|
||
}
|
||
}
|
||
this.operator = CONVERSIONS[op] || op;
|
||
this.first = first;
|
||
this.second = second;
|
||
this.flip = !!flip;
|
||
return this;
|
||
}
|
||
|
||
CONVERSIONS = {
|
||
'==': '===',
|
||
'!=': '!==',
|
||
'of': 'in'
|
||
};
|
||
|
||
INVERSIONS = {
|
||
'!==': '===',
|
||
'===': '!=='
|
||
};
|
||
|
||
Op.prototype.children = ['first', 'second'];
|
||
|
||
Op.prototype.isSimpleNumber = NO;
|
||
|
||
Op.prototype.isUnary = function() {
|
||
return !this.second;
|
||
};
|
||
|
||
Op.prototype.isComplex = function() {
|
||
var _ref2;
|
||
return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex();
|
||
};
|
||
|
||
Op.prototype.isChainable = function() {
|
||
var _ref2;
|
||
return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!==';
|
||
};
|
||
|
||
Op.prototype.invert = function() {
|
||
var allInvertable, curr, fst, op, _ref2;
|
||
if (this.isChainable() && this.first.isChainable()) {
|
||
allInvertable = true;
|
||
curr = this;
|
||
while (curr && curr.operator) {
|
||
allInvertable && (allInvertable = curr.operator in INVERSIONS);
|
||
curr = curr.first;
|
||
}
|
||
if (!allInvertable) {
|
||
return new Parens(this).invert();
|
||
}
|
||
curr = this;
|
||
while (curr && curr.operator) {
|
||
curr.invert = !curr.invert;
|
||
curr.operator = INVERSIONS[curr.operator];
|
||
curr = curr.first;
|
||
}
|
||
return this;
|
||
} else if (op = INVERSIONS[this.operator]) {
|
||
this.operator = op;
|
||
if (this.first.unwrap() instanceof Op) {
|
||
this.first.invert();
|
||
}
|
||
return this;
|
||
} else if (this.second) {
|
||
return new Parens(this).invert();
|
||
} else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) {
|
||
return fst;
|
||
} else {
|
||
return new Op('!', this);
|
||
}
|
||
};
|
||
|
||
Op.prototype.unfoldSoak = function(o) {
|
||
var _ref2;
|
||
return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first');
|
||
};
|
||
|
||
Op.prototype.generateDo = function(exp) {
|
||
var call, func, param, passedParams, ref, _i, _len, _ref2;
|
||
passedParams = [];
|
||
func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp;
|
||
_ref2 = func.params || [];
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
param = _ref2[_i];
|
||
if (param.value) {
|
||
passedParams.push(param.value);
|
||
delete param.value;
|
||
} else {
|
||
passedParams.push(param);
|
||
}
|
||
}
|
||
call = new Call(exp, passedParams);
|
||
call["do"] = true;
|
||
return call;
|
||
};
|
||
|
||
Op.prototype.compileNode = function(o) {
|
||
var answer, isChain, lhs, rhs, _ref2, _ref3;
|
||
isChain = this.isChainable() && this.first.isChainable();
|
||
if (!isChain) {
|
||
this.first.front = this.front;
|
||
}
|
||
if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) {
|
||
this.error('delete operand may not be argument or var');
|
||
}
|
||
if (((_ref2 = this.operator) === '--' || _ref2 === '++') && (_ref3 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref3) >= 0)) {
|
||
this.error("cannot increment/decrement \"" + (this.first.unwrapAll().value) + "\"");
|
||
}
|
||
if (this.isUnary()) {
|
||
return this.compileUnary(o);
|
||
}
|
||
if (isChain) {
|
||
return this.compileChain(o);
|
||
}
|
||
switch (this.operator) {
|
||
case '?':
|
||
return this.compileExistence(o);
|
||
case '**':
|
||
return this.compilePower(o);
|
||
case '//':
|
||
return this.compileFloorDivision(o);
|
||
case '%%':
|
||
return this.compileModulo(o);
|
||
default:
|
||
lhs = this.first.compileToFragments(o, LEVEL_OP);
|
||
rhs = this.second.compileToFragments(o, LEVEL_OP);
|
||
answer = [].concat(lhs, this.makeCode(" " + this.operator + " "), rhs);
|
||
if (o.level <= LEVEL_OP) {
|
||
return answer;
|
||
} else {
|
||
return this.wrapInBraces(answer);
|
||
}
|
||
}
|
||
};
|
||
|
||
Op.prototype.compileChain = function(o) {
|
||
var fragments, fst, shared, _ref2;
|
||
_ref2 = this.first.second.cache(o), this.first.second = _ref2[0], shared = _ref2[1];
|
||
fst = this.first.compileToFragments(o, LEVEL_OP);
|
||
fragments = fst.concat(this.makeCode(" " + (this.invert ? '&&' : '||') + " "), shared.compileToFragments(o), this.makeCode(" " + this.operator + " "), this.second.compileToFragments(o, LEVEL_OP));
|
||
return this.wrapInBraces(fragments);
|
||
};
|
||
|
||
Op.prototype.compileExistence = function(o) {
|
||
var fst, ref;
|
||
if (this.first.isComplex()) {
|
||
ref = new Literal(o.scope.freeVariable('ref'));
|
||
fst = new Parens(new Assign(ref, this.first));
|
||
} else {
|
||
fst = this.first;
|
||
ref = fst;
|
||
}
|
||
return new If(new Existence(fst), ref, {
|
||
type: 'if'
|
||
}).addElse(this.second).compileToFragments(o);
|
||
};
|
||
|
||
Op.prototype.compileUnary = function(o) {
|
||
var op, parts, plusMinus;
|
||
parts = [];
|
||
op = this.operator;
|
||
parts.push([this.makeCode(op)]);
|
||
if (op === '!' && this.first instanceof Existence) {
|
||
this.first.negated = !this.first.negated;
|
||
return this.first.compileToFragments(o);
|
||
}
|
||
if (o.level >= LEVEL_ACCESS) {
|
||
return (new Parens(this)).compileToFragments(o);
|
||
}
|
||
plusMinus = op === '+' || op === '-';
|
||
if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) {
|
||
parts.push([this.makeCode(' ')]);
|
||
}
|
||
if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) {
|
||
this.first = new Parens(this.first);
|
||
}
|
||
parts.push(this.first.compileToFragments(o, LEVEL_OP));
|
||
if (this.flip) {
|
||
parts.reverse();
|
||
}
|
||
return this.joinFragmentArrays(parts, '');
|
||
};
|
||
|
||
Op.prototype.compilePower = function(o) {
|
||
var pow;
|
||
pow = new Value(new Literal('Math'), [new Access(new Literal('pow'))]);
|
||
return new Call(pow, [this.first, this.second]).compileToFragments(o);
|
||
};
|
||
|
||
Op.prototype.compileFloorDivision = function(o) {
|
||
var div, floor;
|
||
floor = new Value(new Literal('Math'), [new Access(new Literal('floor'))]);
|
||
div = new Op('/', this.first, this.second);
|
||
return new Call(floor, [div]).compileToFragments(o);
|
||
};
|
||
|
||
Op.prototype.compileModulo = function(o) {
|
||
var mod;
|
||
mod = new Value(new Literal(utility('modulo')));
|
||
return new Call(mod, [this.first, this.second]).compileToFragments(o);
|
||
};
|
||
|
||
Op.prototype.toString = function(idt) {
|
||
return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator);
|
||
};
|
||
|
||
return Op;
|
||
|
||
})(Base);
|
||
|
||
exports.In = In = (function(_super) {
|
||
__extends(In, _super);
|
||
|
||
function In(object, array) {
|
||
this.object = object;
|
||
this.array = array;
|
||
}
|
||
|
||
In.prototype.children = ['object', 'array'];
|
||
|
||
In.prototype.invert = NEGATE;
|
||
|
||
In.prototype.compileNode = function(o) {
|
||
var hasSplat, obj, _i, _len, _ref2;
|
||
if (this.array instanceof Value && this.array.isArray() && this.array.base.objects.length) {
|
||
_ref2 = this.array.base.objects;
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
obj = _ref2[_i];
|
||
if (!(obj instanceof Splat)) {
|
||
continue;
|
||
}
|
||
hasSplat = true;
|
||
break;
|
||
}
|
||
if (!hasSplat) {
|
||
return this.compileOrTest(o);
|
||
}
|
||
}
|
||
return this.compileLoopTest(o);
|
||
};
|
||
|
||
In.prototype.compileOrTest = function(o) {
|
||
var cmp, cnj, i, item, ref, sub, tests, _i, _len, _ref2, _ref3, _ref4;
|
||
_ref2 = this.object.cache(o, LEVEL_OP), sub = _ref2[0], ref = _ref2[1];
|
||
_ref3 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref3[0], cnj = _ref3[1];
|
||
tests = [];
|
||
_ref4 = this.array.base.objects;
|
||
for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) {
|
||
item = _ref4[i];
|
||
if (i) {
|
||
tests.push(this.makeCode(cnj));
|
||
}
|
||
tests = tests.concat((i ? ref : sub), this.makeCode(cmp), item.compileToFragments(o, LEVEL_ACCESS));
|
||
}
|
||
if (o.level < LEVEL_OP) {
|
||
return tests;
|
||
} else {
|
||
return this.wrapInBraces(tests);
|
||
}
|
||
};
|
||
|
||
In.prototype.compileLoopTest = function(o) {
|
||
var fragments, ref, sub, _ref2;
|
||
_ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1];
|
||
fragments = [].concat(this.makeCode(utility('indexOf') + ".call("), this.array.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), ref, this.makeCode(") " + (this.negated ? '< 0' : '>= 0')));
|
||
if (fragmentsToText(sub) === fragmentsToText(ref)) {
|
||
return fragments;
|
||
}
|
||
fragments = sub.concat(this.makeCode(', '), fragments);
|
||
if (o.level < LEVEL_LIST) {
|
||
return fragments;
|
||
} else {
|
||
return this.wrapInBraces(fragments);
|
||
}
|
||
};
|
||
|
||
In.prototype.toString = function(idt) {
|
||
return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : ''));
|
||
};
|
||
|
||
return In;
|
||
|
||
})(Base);
|
||
|
||
exports.Try = Try = (function(_super) {
|
||
__extends(Try, _super);
|
||
|
||
function Try(attempt, errorVariable, recovery, ensure) {
|
||
this.attempt = attempt;
|
||
this.errorVariable = errorVariable;
|
||
this.recovery = recovery;
|
||
this.ensure = ensure;
|
||
}
|
||
|
||
Try.prototype.children = ['attempt', 'recovery', 'ensure'];
|
||
|
||
Try.prototype.isStatement = YES;
|
||
|
||
Try.prototype.jumps = function(o) {
|
||
var _ref2;
|
||
return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0);
|
||
};
|
||
|
||
Try.prototype.makeReturn = function(res) {
|
||
if (this.attempt) {
|
||
this.attempt = this.attempt.makeReturn(res);
|
||
}
|
||
if (this.recovery) {
|
||
this.recovery = this.recovery.makeReturn(res);
|
||
}
|
||
return this;
|
||
};
|
||
|
||
Try.prototype.compileNode = function(o) {
|
||
var catchPart, ensurePart, placeholder, tryPart;
|
||
o.indent += TAB;
|
||
tryPart = this.attempt.compileToFragments(o, LEVEL_TOP);
|
||
catchPart = this.recovery ? (placeholder = new Literal('_error'), this.errorVariable ? this.recovery.unshift(new Assign(this.errorVariable, placeholder)) : void 0, [].concat(this.makeCode(" catch ("), placeholder.compileToFragments(o), this.makeCode(") {\n"), this.recovery.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}"))) : !(this.ensure || this.recovery) ? [this.makeCode(' catch (_error) {}')] : [];
|
||
ensurePart = this.ensure ? [].concat(this.makeCode(" finally {\n"), this.ensure.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}")) : [];
|
||
return [].concat(this.makeCode("" + this.tab + "try {\n"), tryPart, this.makeCode("\n" + this.tab + "}"), catchPart, ensurePart);
|
||
};
|
||
|
||
return Try;
|
||
|
||
})(Base);
|
||
|
||
exports.Throw = Throw = (function(_super) {
|
||
__extends(Throw, _super);
|
||
|
||
function Throw(expression) {
|
||
this.expression = expression;
|
||
}
|
||
|
||
Throw.prototype.children = ['expression'];
|
||
|
||
Throw.prototype.isStatement = YES;
|
||
|
||
Throw.prototype.jumps = NO;
|
||
|
||
Throw.prototype.makeReturn = THIS;
|
||
|
||
Throw.prototype.compileNode = function(o) {
|
||
return [].concat(this.makeCode(this.tab + "throw "), this.expression.compileToFragments(o), this.makeCode(";"));
|
||
};
|
||
|
||
return Throw;
|
||
|
||
})(Base);
|
||
|
||
exports.Existence = Existence = (function(_super) {
|
||
__extends(Existence, _super);
|
||
|
||
function Existence(expression) {
|
||
this.expression = expression;
|
||
}
|
||
|
||
Existence.prototype.children = ['expression'];
|
||
|
||
Existence.prototype.invert = NEGATE;
|
||
|
||
Existence.prototype.compileNode = function(o) {
|
||
var cmp, cnj, code, _ref2;
|
||
this.expression.front = this.front;
|
||
code = this.expression.compile(o, LEVEL_OP);
|
||
if (IDENTIFIER.test(code) && !o.scope.check(code)) {
|
||
_ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1];
|
||
code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null";
|
||
} else {
|
||
code = "" + code + " " + (this.negated ? '==' : '!=') + " null";
|
||
}
|
||
return [this.makeCode(o.level <= LEVEL_COND ? code : "(" + code + ")")];
|
||
};
|
||
|
||
return Existence;
|
||
|
||
})(Base);
|
||
|
||
exports.Parens = Parens = (function(_super) {
|
||
__extends(Parens, _super);
|
||
|
||
function Parens(body) {
|
||
this.body = body;
|
||
}
|
||
|
||
Parens.prototype.children = ['body'];
|
||
|
||
Parens.prototype.unwrap = function() {
|
||
return this.body;
|
||
};
|
||
|
||
Parens.prototype.isComplex = function() {
|
||
return this.body.isComplex();
|
||
};
|
||
|
||
Parens.prototype.compileNode = function(o) {
|
||
var bare, expr, fragments;
|
||
expr = this.body.unwrap();
|
||
if (expr instanceof Value && expr.isAtomic()) {
|
||
expr.front = this.front;
|
||
return expr.compileToFragments(o);
|
||
}
|
||
fragments = expr.compileToFragments(o, LEVEL_PAREN);
|
||
bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns));
|
||
if (bare) {
|
||
return fragments;
|
||
} else {
|
||
return this.wrapInBraces(fragments);
|
||
}
|
||
};
|
||
|
||
return Parens;
|
||
|
||
})(Base);
|
||
|
||
exports.For = For = (function(_super) {
|
||
__extends(For, _super);
|
||
|
||
function For(body, source) {
|
||
var _ref2;
|
||
this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index;
|
||
this.body = Block.wrap([body]);
|
||
this.own = !!source.own;
|
||
this.object = !!source.object;
|
||
if (this.object) {
|
||
_ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1];
|
||
}
|
||
if (this.index instanceof Value) {
|
||
this.index.error('index cannot be a pattern matching expression');
|
||
}
|
||
this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length;
|
||
this.pattern = this.name instanceof Value;
|
||
if (this.range && this.index) {
|
||
this.index.error('indexes do not apply to range loops');
|
||
}
|
||
if (this.range && this.pattern) {
|
||
this.name.error('cannot pattern match over range loops');
|
||
}
|
||
if (this.own && !this.object) {
|
||
this.name.error('cannot use own with for-in');
|
||
}
|
||
this.returns = false;
|
||
}
|
||
|
||
For.prototype.children = ['body', 'source', 'guard', 'step'];
|
||
|
||
For.prototype.compileNode = function(o) {
|
||
var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart, _ref2, _ref3;
|
||
body = Block.wrap([this.body]);
|
||
lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0;
|
||
if (lastJumps && lastJumps instanceof Return) {
|
||
this.returns = false;
|
||
}
|
||
source = this.range ? this.source.base : this.source;
|
||
scope = o.scope;
|
||
if (!this.pattern) {
|
||
name = this.name && (this.name.compile(o, LEVEL_LIST));
|
||
}
|
||
index = this.index && (this.index.compile(o, LEVEL_LIST));
|
||
if (name && !this.pattern) {
|
||
scope.find(name);
|
||
}
|
||
if (index) {
|
||
scope.find(index);
|
||
}
|
||
if (this.returns) {
|
||
rvar = scope.freeVariable('results');
|
||
}
|
||
ivar = (this.object && index) || scope.freeVariable('i');
|
||
kvar = (this.range && name) || index || ivar;
|
||
kvarAssign = kvar !== ivar ? "" + kvar + " = " : "";
|
||
if (this.step && !this.range) {
|
||
_ref3 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST)), step = _ref3[0], stepVar = _ref3[1];
|
||
stepNum = stepVar.match(NUMBER);
|
||
}
|
||
if (this.pattern) {
|
||
name = ivar;
|
||
}
|
||
varPart = '';
|
||
guardPart = '';
|
||
defPart = '';
|
||
idt1 = this.tab + TAB;
|
||
if (this.range) {
|
||
forPartFragments = source.compileToFragments(merge(o, {
|
||
index: ivar,
|
||
name: name,
|
||
step: this.step
|
||
}));
|
||
} else {
|
||
svar = this.source.compile(o, LEVEL_LIST);
|
||
if ((name || this.own) && !IDENTIFIER.test(svar)) {
|
||
defPart += "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n";
|
||
svar = ref;
|
||
}
|
||
if (name && !this.pattern) {
|
||
namePart = "" + name + " = " + svar + "[" + kvar + "]";
|
||
}
|
||
if (!this.object) {
|
||
if (step !== stepVar) {
|
||
defPart += "" + this.tab + step + ";\n";
|
||
}
|
||
if (!(this.step && stepNum && (down = parseNum(stepNum[0]) < 0))) {
|
||
lvar = scope.freeVariable('len');
|
||
}
|
||
declare = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length";
|
||
declareDown = "" + kvarAssign + ivar + " = " + svar + ".length - 1";
|
||
compare = "" + ivar + " < " + lvar;
|
||
compareDown = "" + ivar + " >= 0";
|
||
if (this.step) {
|
||
if (stepNum) {
|
||
if (down) {
|
||
compare = compareDown;
|
||
declare = declareDown;
|
||
}
|
||
} else {
|
||
compare = "" + stepVar + " > 0 ? " + compare + " : " + compareDown;
|
||
declare = "(" + stepVar + " > 0 ? (" + declare + ") : " + declareDown + ")";
|
||
}
|
||
increment = "" + ivar + " += " + stepVar;
|
||
} else {
|
||
increment = "" + (kvar !== ivar ? "++" + ivar : "" + ivar + "++");
|
||
}
|
||
forPartFragments = [this.makeCode("" + declare + "; " + compare + "; " + kvarAssign + increment)];
|
||
}
|
||
}
|
||
if (this.returns) {
|
||
resultPart = "" + this.tab + rvar + " = [];\n";
|
||
returnResult = "\n" + this.tab + "return " + rvar + ";";
|
||
body.makeReturn(rvar);
|
||
}
|
||
if (this.guard) {
|
||
if (body.expressions.length > 1) {
|
||
body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
|
||
} else {
|
||
if (this.guard) {
|
||
body = Block.wrap([new If(this.guard, body)]);
|
||
}
|
||
}
|
||
}
|
||
if (this.pattern) {
|
||
body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + kvar + "]")));
|
||
}
|
||
defPartFragments = [].concat(this.makeCode(defPart), this.pluckDirectCall(o, body));
|
||
if (namePart) {
|
||
varPart = "\n" + idt1 + namePart + ";";
|
||
}
|
||
if (this.object) {
|
||
forPartFragments = [this.makeCode("" + kvar + " in " + svar)];
|
||
if (this.own) {
|
||
guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + kvar + ")) continue;";
|
||
}
|
||
}
|
||
bodyFragments = body.compileToFragments(merge(o, {
|
||
indent: idt1
|
||
}), LEVEL_TOP);
|
||
if (bodyFragments && (bodyFragments.length > 0)) {
|
||
bodyFragments = [].concat(this.makeCode("\n"), bodyFragments, this.makeCode("\n"));
|
||
}
|
||
return [].concat(defPartFragments, this.makeCode("" + (resultPart || '') + this.tab + "for ("), forPartFragments, this.makeCode(") {" + guardPart + varPart), bodyFragments, this.makeCode("" + this.tab + "}" + (returnResult || '')));
|
||
};
|
||
|
||
For.prototype.pluckDirectCall = function(o, body) {
|
||
var base, defs, expr, fn, idx, ref, val, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8;
|
||
defs = [];
|
||
_ref2 = body.expressions;
|
||
for (idx = _i = 0, _len = _ref2.length; _i < _len; idx = ++_i) {
|
||
expr = _ref2[idx];
|
||
expr = expr.unwrapAll();
|
||
if (!(expr instanceof Call)) {
|
||
continue;
|
||
}
|
||
val = (_ref3 = expr.variable) != null ? _ref3.unwrapAll() : void 0;
|
||
if (!((val instanceof Code) || (val instanceof Value && ((_ref4 = val.base) != null ? _ref4.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref5 = (_ref6 = val.properties[0].name) != null ? _ref6.value : void 0) === 'call' || _ref5 === 'apply')))) {
|
||
continue;
|
||
}
|
||
fn = ((_ref7 = val.base) != null ? _ref7.unwrapAll() : void 0) || val;
|
||
ref = new Literal(o.scope.freeVariable('fn'));
|
||
base = new Value(ref);
|
||
if (val.base) {
|
||
_ref8 = [base, val], val.base = _ref8[0], base = _ref8[1];
|
||
}
|
||
body.expressions[idx] = new Call(base, expr.args);
|
||
defs = defs.concat(this.makeCode(this.tab), new Assign(ref, fn).compileToFragments(o, LEVEL_TOP), this.makeCode(';\n'));
|
||
}
|
||
return defs;
|
||
};
|
||
|
||
return For;
|
||
|
||
})(While);
|
||
|
||
exports.Switch = Switch = (function(_super) {
|
||
__extends(Switch, _super);
|
||
|
||
function Switch(subject, cases, otherwise) {
|
||
this.subject = subject;
|
||
this.cases = cases;
|
||
this.otherwise = otherwise;
|
||
}
|
||
|
||
Switch.prototype.children = ['subject', 'cases', 'otherwise'];
|
||
|
||
Switch.prototype.isStatement = YES;
|
||
|
||
Switch.prototype.jumps = function(o) {
|
||
var block, conds, jumpNode, _i, _len, _ref2, _ref3, _ref4;
|
||
if (o == null) {
|
||
o = {
|
||
block: true
|
||
};
|
||
}
|
||
_ref2 = this.cases;
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
_ref3 = _ref2[_i], conds = _ref3[0], block = _ref3[1];
|
||
if (jumpNode = block.jumps(o)) {
|
||
return jumpNode;
|
||
}
|
||
}
|
||
return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0;
|
||
};
|
||
|
||
Switch.prototype.makeReturn = function(res) {
|
||
var pair, _i, _len, _ref2, _ref3;
|
||
_ref2 = this.cases;
|
||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||
pair = _ref2[_i];
|
||
pair[1].makeReturn(res);
|
||
}
|
||
if (res) {
|
||
this.otherwise || (this.otherwise = new Block([new Literal('void 0')]));
|
||
}
|
||
if ((_ref3 = this.otherwise) != null) {
|
||
_ref3.makeReturn(res);
|
||
}
|
||
return this;
|
||
};
|
||
|
||
Switch.prototype.compileNode = function(o) {
|
||
var block, body, cond, conditions, expr, fragments, i, idt1, idt2, _i, _j, _len, _len1, _ref2, _ref3, _ref4;
|
||
idt1 = o.indent + TAB;
|
||
idt2 = o.indent = idt1 + TAB;
|
||
fragments = [].concat(this.makeCode(this.tab + "switch ("), (this.subject ? this.subject.compileToFragments(o, LEVEL_PAREN) : this.makeCode("false")), this.makeCode(") {\n"));
|
||
_ref2 = this.cases;
|
||
for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
|
||
_ref3 = _ref2[i], conditions = _ref3[0], block = _ref3[1];
|
||
_ref4 = flatten([conditions]);
|
||
for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
|
||
cond = _ref4[_j];
|
||
if (!this.subject) {
|
||
cond = cond.invert();
|
||
}
|
||
fragments = fragments.concat(this.makeCode(idt1 + "case "), cond.compileToFragments(o, LEVEL_PAREN), this.makeCode(":\n"));
|
||
}
|
||
if ((body = block.compileToFragments(o, LEVEL_TOP)).length > 0) {
|
||
fragments = fragments.concat(body, this.makeCode('\n'));
|
||
}
|
||
if (i === this.cases.length - 1 && !this.otherwise) {
|
||
break;
|
||
}
|
||
expr = this.lastNonComment(block.expressions);
|
||
if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) {
|
||
continue;
|
||
}
|
||
fragments.push(cond.makeCode(idt2 + 'break;\n'));
|
||
}
|
||
if (this.otherwise && this.otherwise.expressions.length) {
|
||
fragments.push.apply(fragments, [this.makeCode(idt1 + "default:\n")].concat(__slice.call(this.otherwise.compileToFragments(o, LEVEL_TOP)), [this.makeCode("\n")]));
|
||
}
|
||
fragments.push(this.makeCode(this.tab + '}'));
|
||
return fragments;
|
||
};
|
||
|
||
return Switch;
|
||
|
||
})(Base);
|
||
|
||
exports.If = If = (function(_super) {
|
||
__extends(If, _super);
|
||
|
||
function If(condition, body, options) {
|
||
this.body = body;
|
||
if (options == null) {
|
||
options = {};
|
||
}
|
||
this.condition = options.type === 'unless' ? condition.invert() : condition;
|
||
this.elseBody = null;
|
||
this.isChain = false;
|
||
this.soak = options.soak;
|
||
}
|
||
|
||
If.prototype.children = ['condition', 'body', 'elseBody'];
|
||
|
||
If.prototype.bodyNode = function() {
|
||
var _ref2;
|
||
return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0;
|
||
};
|
||
|
||
If.prototype.elseBodyNode = function() {
|
||
var _ref2;
|
||
return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0;
|
||
};
|
||
|
||
If.prototype.addElse = function(elseBody) {
|
||
if (this.isChain) {
|
||
this.elseBodyNode().addElse(elseBody);
|
||
} else {
|
||
this.isChain = elseBody instanceof If;
|
||
this.elseBody = this.ensureBlock(elseBody);
|
||
this.elseBody.updateLocationDataIfMissing(elseBody.locationData);
|
||
}
|
||
return this;
|
||
};
|
||
|
||
If.prototype.isStatement = function(o) {
|
||
var _ref2;
|
||
return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0);
|
||
};
|
||
|
||
If.prototype.jumps = function(o) {
|
||
var _ref2;
|
||
return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0);
|
||
};
|
||
|
||
If.prototype.compileNode = function(o) {
|
||
if (this.isStatement(o)) {
|
||
return this.compileStatement(o);
|
||
} else {
|
||
return this.compileExpression(o);
|
||
}
|
||
};
|
||
|
||
If.prototype.makeReturn = function(res) {
|
||
if (res) {
|
||
this.elseBody || (this.elseBody = new Block([new Literal('void 0')]));
|
||
}
|
||
this.body && (this.body = new Block([this.body.makeReturn(res)]));
|
||
this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)]));
|
||
return this;
|
||
};
|
||
|
||
If.prototype.ensureBlock = function(node) {
|
||
if (node instanceof Block) {
|
||
return node;
|
||
} else {
|
||
return new Block([node]);
|
||
}
|
||
};
|
||
|
||
If.prototype.compileStatement = function(o) {
|
||
var answer, body, child, cond, exeq, ifPart, indent;
|
||
child = del(o, 'chainChild');
|
||
exeq = del(o, 'isExistentialEquals');
|
||
if (exeq) {
|
||
return new If(this.condition.invert(), this.elseBodyNode(), {
|
||
type: 'if'
|
||
}).compileToFragments(o);
|
||
}
|
||
indent = o.indent + TAB;
|
||
cond = this.condition.compileToFragments(o, LEVEL_PAREN);
|
||
body = this.ensureBlock(this.body).compileToFragments(merge(o, {
|
||
indent: indent
|
||
}));
|
||
ifPart = [].concat(this.makeCode("if ("), cond, this.makeCode(") {\n"), body, this.makeCode("\n" + this.tab + "}"));
|
||
if (!child) {
|
||
ifPart.unshift(this.makeCode(this.tab));
|
||
}
|
||
if (!this.elseBody) {
|
||
return ifPart;
|
||
}
|
||
answer = ifPart.concat(this.makeCode(' else '));
|
||
if (this.isChain) {
|
||
o.chainChild = true;
|
||
answer = answer.concat(this.elseBody.unwrap().compileToFragments(o, LEVEL_TOP));
|
||
} else {
|
||
answer = answer.concat(this.makeCode("{\n"), this.elseBody.compileToFragments(merge(o, {
|
||
indent: indent
|
||
}), LEVEL_TOP), this.makeCode("\n" + this.tab + "}"));
|
||
}
|
||
return answer;
|
||
};
|
||
|
||
If.prototype.compileExpression = function(o) {
|
||
var alt, body, cond, fragments;
|
||
cond = this.condition.compileToFragments(o, LEVEL_COND);
|
||
body = this.bodyNode().compileToFragments(o, LEVEL_LIST);
|
||
alt = this.elseBodyNode() ? this.elseBodyNode().compileToFragments(o, LEVEL_LIST) : [this.makeCode('void 0')];
|
||
fragments = cond.concat(this.makeCode(" ? "), body, this.makeCode(" : "), alt);
|
||
if (o.level >= LEVEL_COND) {
|
||
return this.wrapInBraces(fragments);
|
||
} else {
|
||
return fragments;
|
||
}
|
||
};
|
||
|
||
If.prototype.unfoldSoak = function() {
|
||
return this.soak && this;
|
||
};
|
||
|
||
return If;
|
||
|
||
})(Base);
|
||
|
||
UTILITIES = {
|
||
"extends": function() {
|
||
return "function(child, parent) { for (var key in parent) { if (" + (utility('hasProp')) + ".call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }";
|
||
},
|
||
bind: function() {
|
||
return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }';
|
||
},
|
||
indexOf: function() {
|
||
return "[].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }";
|
||
},
|
||
modulo: function() {
|
||
return "function(a, b) { return (+a % (b = +b) + b) % b; }";
|
||
},
|
||
hasProp: function() {
|
||
return '{}.hasOwnProperty';
|
||
},
|
||
slice: function() {
|
||
return '[].slice';
|
||
}
|
||
};
|
||
|
||
LEVEL_TOP = 1;
|
||
|
||
LEVEL_PAREN = 2;
|
||
|
||
LEVEL_LIST = 3;
|
||
|
||
LEVEL_COND = 4;
|
||
|
||
LEVEL_OP = 5;
|
||
|
||
LEVEL_ACCESS = 6;
|
||
|
||
TAB = ' ';
|
||
|
||
IDENTIFIER_STR = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*";
|
||
|
||
IDENTIFIER = RegExp("^" + IDENTIFIER_STR + "$");
|
||
|
||
SIMPLENUM = /^[+-]?\d+$/;
|
||
|
||
HEXNUM = /^[+-]?0x[\da-f]+/i;
|
||
|
||
NUMBER = /^[+-]?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)$/i;
|
||
|
||
METHOD_DEF = RegExp("^(" + IDENTIFIER_STR + ")(\\.prototype)?(?:\\.(" + IDENTIFIER_STR + ")|\\[(\"(?:[^\\\\\"\\r\\n]|\\\\.)*\"|'(?:[^\\\\'\\r\\n]|\\\\.)*')\\]|\\[(0x[\\da-fA-F]+|\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\])$");
|
||
|
||
IS_STRING = /^['"]/;
|
||
|
||
IS_REGEX = /^\//;
|
||
|
||
utility = function(name) {
|
||
var ref;
|
||
ref = "__" + name;
|
||
Scope.root.assign(ref, UTILITIES[name]());
|
||
return ref;
|
||
};
|
||
|
||
multident = function(code, tab) {
|
||
code = code.replace(/\n/g, '$&' + tab);
|
||
return code.replace(/\s+$/, '');
|
||
};
|
||
|
||
parseNum = function(x) {
|
||
if (x == null) {
|
||
return 0;
|
||
} else if (x.match(HEXNUM)) {
|
||
return parseInt(x, 16);
|
||
} else {
|
||
return parseFloat(x);
|
||
}
|
||
};
|
||
|
||
isLiteralArguments = function(node) {
|
||
return node instanceof Literal && node.value === 'arguments' && !node.asKey;
|
||
};
|
||
|
||
isLiteralThis = function(node) {
|
||
return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound) || (node instanceof Call && node.isSuper);
|
||
};
|
||
|
||
unfoldSoak = function(o, parent, name) {
|
||
var ifn;
|
||
if (!(ifn = parent[name].unfoldSoak(o))) {
|
||
return;
|
||
}
|
||
parent[name] = ifn.body;
|
||
ifn.body = new Value(parent);
|
||
return ifn;
|
||
};
|
||
|
||
}).call(this);
|
||
|
||
},{"./helpers":48,"./lexer":49,"./scope":54}],51:[function(require,module,exports){
|
||
(function (process){
|
||
/* parser generated by jison 0.4.13 */
|
||
/*
|
||
Returns a Parser object of the following structure:
|
||
|
||
Parser: {
|
||
yy: {}
|
||
}
|
||
|
||
Parser.prototype: {
|
||
yy: {},
|
||
trace: function(),
|
||
symbols_: {associative list: name ==> number},
|
||
terminals_: {associative list: number ==> name},
|
||
productions_: [...],
|
||
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
|
||
table: [...],
|
||
defaultActions: {...},
|
||
parseError: function(str, hash),
|
||
parse: function(input),
|
||
|
||
lexer: {
|
||
EOF: 1,
|
||
parseError: function(str, hash),
|
||
setInput: function(input),
|
||
input: function(),
|
||
unput: function(str),
|
||
more: function(),
|
||
less: function(n),
|
||
pastInput: function(),
|
||
upcomingInput: function(),
|
||
showPosition: function(),
|
||
test_match: function(regex_match_array, rule_index),
|
||
next: function(),
|
||
lex: function(),
|
||
begin: function(condition),
|
||
popState: function(),
|
||
_currentRules: function(),
|
||
topState: function(),
|
||
pushState: function(condition),
|
||
|
||
options: {
|
||
ranges: boolean (optional: true ==> token location info will include a .range[] member)
|
||
flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
|
||
backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
|
||
},
|
||
|
||
performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
|
||
rules: [...],
|
||
conditions: {associative list: name ==> set},
|
||
}
|
||
}
|
||
|
||
|
||
token location info (@$, _$, etc.): {
|
||
first_line: n,
|
||
last_line: n,
|
||
first_column: n,
|
||
last_column: n,
|
||
range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)
|
||
}
|
||
|
||
|
||
the parseError function receives a 'hash' object with these members for lexer and parser errors: {
|
||
text: (matched text)
|
||
token: (the produced terminal token, if any)
|
||
line: (yylineno)
|
||
}
|
||
while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
|
||
loc: (yylloc)
|
||
expected: (string describing the set of expected tokens)
|
||
recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
|
||
}
|
||
*/
|
||
var parser = (function(){
|
||
var parser = {trace: function trace() { },
|
||
yy: {},
|
||
symbols_: {"error":2,"Root":3,"Body":4,"Line":5,"TERMINATOR":6,"Expression":7,"Statement":8,"Return":9,"Comment":10,"STATEMENT":11,"Value":12,"Invocation":13,"Code":14,"Operation":15,"Assign":16,"If":17,"Try":18,"While":19,"For":20,"Switch":21,"Class":22,"Throw":23,"Block":24,"INDENT":25,"OUTDENT":26,"Identifier":27,"IDENTIFIER":28,"AlphaNumeric":29,"NUMBER":30,"STRING":31,"Literal":32,"JS":33,"REGEX":34,"DEBUGGER":35,"UNDEFINED":36,"NULL":37,"BOOL":38,"Assignable":39,"=":40,"AssignObj":41,"ObjAssignable":42,":":43,"ThisProperty":44,"RETURN":45,"HERECOMMENT":46,"PARAM_START":47,"ParamList":48,"PARAM_END":49,"FuncGlyph":50,"->":51,"=>":52,"OptComma":53,",":54,"Param":55,"ParamVar":56,"...":57,"Array":58,"Object":59,"Splat":60,"SimpleAssignable":61,"Accessor":62,"Parenthetical":63,"Range":64,"This":65,".":66,"?.":67,"::":68,"?::":69,"Index":70,"INDEX_START":71,"IndexValue":72,"INDEX_END":73,"INDEX_SOAK":74,"Slice":75,"{":76,"AssignList":77,"}":78,"CLASS":79,"EXTENDS":80,"OptFuncExist":81,"Arguments":82,"SUPER":83,"FUNC_EXIST":84,"CALL_START":85,"CALL_END":86,"ArgList":87,"THIS":88,"@":89,"[":90,"]":91,"RangeDots":92,"..":93,"Arg":94,"SimpleArgs":95,"TRY":96,"Catch":97,"FINALLY":98,"CATCH":99,"THROW":100,"(":101,")":102,"WhileSource":103,"WHILE":104,"WHEN":105,"UNTIL":106,"Loop":107,"LOOP":108,"ForBody":109,"FOR":110,"ForStart":111,"ForSource":112,"ForVariables":113,"OWN":114,"ForValue":115,"FORIN":116,"FOROF":117,"BY":118,"SWITCH":119,"Whens":120,"ELSE":121,"When":122,"LEADING_WHEN":123,"IfBlock":124,"IF":125,"POST_IF":126,"UNARY":127,"UNARY_MATH":128,"-":129,"+":130,"--":131,"++":132,"?":133,"MATH":134,"**":135,"SHIFT":136,"COMPARE":137,"LOGIC":138,"RELATION":139,"COMPOUND_ASSIGN":140,"$accept":0,"$end":1},
|
||
terminals_: {2:"error",6:"TERMINATOR",11:"STATEMENT",25:"INDENT",26:"OUTDENT",28:"IDENTIFIER",30:"NUMBER",31:"STRING",33:"JS",34:"REGEX",35:"DEBUGGER",36:"UNDEFINED",37:"NULL",38:"BOOL",40:"=",43:":",45:"RETURN",46:"HERECOMMENT",47:"PARAM_START",49:"PARAM_END",51:"->",52:"=>",54:",",57:"...",66:".",67:"?.",68:"::",69:"?::",71:"INDEX_START",73:"INDEX_END",74:"INDEX_SOAK",76:"{",78:"}",79:"CLASS",80:"EXTENDS",83:"SUPER",84:"FUNC_EXIST",85:"CALL_START",86:"CALL_END",88:"THIS",89:"@",90:"[",91:"]",93:"..",96:"TRY",98:"FINALLY",99:"CATCH",100:"THROW",101:"(",102:")",104:"WHILE",105:"WHEN",106:"UNTIL",108:"LOOP",110:"FOR",114:"OWN",116:"FORIN",117:"FOROF",118:"BY",119:"SWITCH",121:"ELSE",123:"LEADING_WHEN",125:"IF",126:"POST_IF",127:"UNARY",128:"UNARY_MATH",129:"-",130:"+",131:"--",132:"++",133:"?",134:"MATH",135:"**",136:"SHIFT",137:"COMPARE",138:"LOGIC",139:"RELATION",140:"COMPOUND_ASSIGN"},
|
||
productions_: [0,[3,0],[3,1],[4,1],[4,3],[4,2],[5,1],[5,1],[8,1],[8,1],[8,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[24,2],[24,3],[27,1],[29,1],[29,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[16,3],[16,4],[16,5],[41,1],[41,3],[41,5],[41,1],[42,1],[42,1],[42,1],[9,2],[9,1],[10,1],[14,5],[14,2],[50,1],[50,1],[53,0],[53,1],[48,0],[48,1],[48,3],[48,4],[48,6],[55,1],[55,2],[55,3],[55,1],[56,1],[56,1],[56,1],[56,1],[60,2],[61,1],[61,2],[61,2],[61,1],[39,1],[39,1],[39,1],[12,1],[12,1],[12,1],[12,1],[12,1],[62,2],[62,2],[62,2],[62,2],[62,1],[62,1],[70,3],[70,2],[72,1],[72,1],[59,4],[77,0],[77,1],[77,3],[77,4],[77,6],[22,1],[22,2],[22,3],[22,4],[22,2],[22,3],[22,4],[22,5],[13,3],[13,3],[13,1],[13,2],[81,0],[81,1],[82,2],[82,4],[65,1],[65,1],[44,2],[58,2],[58,4],[92,1],[92,1],[64,5],[75,3],[75,2],[75,2],[75,1],[87,1],[87,3],[87,4],[87,4],[87,6],[94,1],[94,1],[94,1],[95,1],[95,3],[18,2],[18,3],[18,4],[18,5],[97,3],[97,3],[97,2],[23,2],[63,3],[63,5],[103,2],[103,4],[103,2],[103,4],[19,2],[19,2],[19,2],[19,1],[107,2],[107,2],[20,2],[20,2],[20,2],[109,2],[109,2],[111,2],[111,3],[115,1],[115,1],[115,1],[115,1],[113,1],[113,3],[112,2],[112,2],[112,4],[112,4],[112,4],[112,6],[112,6],[21,5],[21,7],[21,4],[21,6],[120,1],[120,2],[122,3],[122,4],[124,3],[124,5],[17,1],[17,3],[17,3],[17,3],[15,2],[15,2],[15,2],[15,2],[15,2],[15,2],[15,2],[15,2],[15,2],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,5],[15,4],[15,3]],
|
||
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
|
||
/* this == yyval */
|
||
|
||
var $0 = $$.length - 1;
|
||
switch (yystate) {
|
||
case 1:return this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Block);
|
||
break;
|
||
case 2:return this.$ = $$[$0];
|
||
break;
|
||
case 3:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Block.wrap([$$[$0]]));
|
||
break;
|
||
case 4:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].push($$[$0]));
|
||
break;
|
||
case 5:this.$ = $$[$0-1];
|
||
break;
|
||
case 6:this.$ = $$[$0];
|
||
break;
|
||
case 7:this.$ = $$[$0];
|
||
break;
|
||
case 8:this.$ = $$[$0];
|
||
break;
|
||
case 9:this.$ = $$[$0];
|
||
break;
|
||
case 10:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
|
||
break;
|
||
case 11:this.$ = $$[$0];
|
||
break;
|
||
case 12:this.$ = $$[$0];
|
||
break;
|
||
case 13:this.$ = $$[$0];
|
||
break;
|
||
case 14:this.$ = $$[$0];
|
||
break;
|
||
case 15:this.$ = $$[$0];
|
||
break;
|
||
case 16:this.$ = $$[$0];
|
||
break;
|
||
case 17:this.$ = $$[$0];
|
||
break;
|
||
case 18:this.$ = $$[$0];
|
||
break;
|
||
case 19:this.$ = $$[$0];
|
||
break;
|
||
case 20:this.$ = $$[$0];
|
||
break;
|
||
case 21:this.$ = $$[$0];
|
||
break;
|
||
case 22:this.$ = $$[$0];
|
||
break;
|
||
case 23:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Block);
|
||
break;
|
||
case 24:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-1]);
|
||
break;
|
||
case 25:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
|
||
break;
|
||
case 26:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
|
||
break;
|
||
case 27:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
|
||
break;
|
||
case 28:this.$ = $$[$0];
|
||
break;
|
||
case 29:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
|
||
break;
|
||
case 30:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
|
||
break;
|
||
case 31:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
|
||
break;
|
||
case 32:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Undefined);
|
||
break;
|
||
case 33:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Null);
|
||
break;
|
||
case 34:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Bool($$[$0]));
|
||
break;
|
||
case 35:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0]));
|
||
break;
|
||
case 36:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0]));
|
||
break;
|
||
case 37:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1]));
|
||
break;
|
||
case 38:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
|
||
break;
|
||
case 39:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-2])(new yy.Value($$[$0-2])), $$[$0], 'object'));
|
||
break;
|
||
case 40:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-4])(new yy.Value($$[$0-4])), $$[$0-1], 'object'));
|
||
break;
|
||
case 41:this.$ = $$[$0];
|
||
break;
|
||
case 42:this.$ = $$[$0];
|
||
break;
|
||
case 43:this.$ = $$[$0];
|
||
break;
|
||
case 44:this.$ = $$[$0];
|
||
break;
|
||
case 45:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Return($$[$0]));
|
||
break;
|
||
case 46:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Return);
|
||
break;
|
||
case 47:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Comment($$[$0]));
|
||
break;
|
||
case 48:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Code($$[$0-3], $$[$0], $$[$0-1]));
|
||
break;
|
||
case 49:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Code([], $$[$0], $$[$0-1]));
|
||
break;
|
||
case 50:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('func');
|
||
break;
|
||
case 51:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('boundfunc');
|
||
break;
|
||
case 52:this.$ = $$[$0];
|
||
break;
|
||
case 53:this.$ = $$[$0];
|
||
break;
|
||
case 54:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([]);
|
||
break;
|
||
case 55:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
|
||
break;
|
||
case 56:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0]));
|
||
break;
|
||
case 57:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0]));
|
||
break;
|
||
case 58:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2]));
|
||
break;
|
||
case 59:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Param($$[$0]));
|
||
break;
|
||
case 60:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Param($$[$0-1], null, true));
|
||
break;
|
||
case 61:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Param($$[$0-2], $$[$0]));
|
||
break;
|
||
case 62:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Expansion);
|
||
break;
|
||
case 63:this.$ = $$[$0];
|
||
break;
|
||
case 64:this.$ = $$[$0];
|
||
break;
|
||
case 65:this.$ = $$[$0];
|
||
break;
|
||
case 66:this.$ = $$[$0];
|
||
break;
|
||
case 67:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Splat($$[$0-1]));
|
||
break;
|
||
case 68:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
|
||
break;
|
||
case 69:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].add($$[$0]));
|
||
break;
|
||
case 70:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Value($$[$0-1], [].concat($$[$0])));
|
||
break;
|
||
case 71:this.$ = $$[$0];
|
||
break;
|
||
case 72:this.$ = $$[$0];
|
||
break;
|
||
case 73:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
|
||
break;
|
||
case 74:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
|
||
break;
|
||
case 75:this.$ = $$[$0];
|
||
break;
|
||
case 76:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
|
||
break;
|
||
case 77:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
|
||
break;
|
||
case 78:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
|
||
break;
|
||
case 79:this.$ = $$[$0];
|
||
break;
|
||
case 80:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Access($$[$0]));
|
||
break;
|
||
case 81:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Access($$[$0], 'soak'));
|
||
break;
|
||
case 82:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Access(new yy.Literal('prototype'))), yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))]);
|
||
break;
|
||
case 83:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Access(new yy.Literal('prototype'), 'soak')), yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))]);
|
||
break;
|
||
case 84:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Access(new yy.Literal('prototype')));
|
||
break;
|
||
case 85:this.$ = $$[$0];
|
||
break;
|
||
case 86:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-1]);
|
||
break;
|
||
case 87:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.extend($$[$0], {
|
||
soak: true
|
||
}));
|
||
break;
|
||
case 88:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Index($$[$0]));
|
||
break;
|
||
case 89:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Slice($$[$0]));
|
||
break;
|
||
case 90:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Obj($$[$0-2], $$[$0-3].generated));
|
||
break;
|
||
case 91:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([]);
|
||
break;
|
||
case 92:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
|
||
break;
|
||
case 93:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0]));
|
||
break;
|
||
case 94:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0]));
|
||
break;
|
||
case 95:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2]));
|
||
break;
|
||
case 96:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Class);
|
||
break;
|
||
case 97:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Class(null, null, $$[$0]));
|
||
break;
|
||
case 98:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Class(null, $$[$0]));
|
||
break;
|
||
case 99:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Class(null, $$[$0-1], $$[$0]));
|
||
break;
|
||
case 100:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Class($$[$0]));
|
||
break;
|
||
case 101:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Class($$[$0-1], null, $$[$0]));
|
||
break;
|
||
case 102:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Class($$[$0-2], $$[$0]));
|
||
break;
|
||
case 103:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Class($$[$0-3], $$[$0-1], $$[$0]));
|
||
break;
|
||
case 104:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Call($$[$0-2], $$[$0], $$[$0-1]));
|
||
break;
|
||
case 105:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Call($$[$0-2], $$[$0], $$[$0-1]));
|
||
break;
|
||
case 106:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))]));
|
||
break;
|
||
case 107:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Call('super', $$[$0]));
|
||
break;
|
||
case 108:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(false);
|
||
break;
|
||
case 109:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(true);
|
||
break;
|
||
case 110:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([]);
|
||
break;
|
||
case 111:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-2]);
|
||
break;
|
||
case 112:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value(new yy.Literal('this')));
|
||
break;
|
||
case 113:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value(new yy.Literal('this')));
|
||
break;
|
||
case 114:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Value(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('this')), [yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))], 'this'));
|
||
break;
|
||
case 115:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Arr([]));
|
||
break;
|
||
case 116:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Arr($$[$0-2]));
|
||
break;
|
||
case 117:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('inclusive');
|
||
break;
|
||
case 118:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('exclusive');
|
||
break;
|
||
case 119:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Range($$[$0-3], $$[$0-1], $$[$0-2]));
|
||
break;
|
||
case 120:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Range($$[$0-2], $$[$0], $$[$0-1]));
|
||
break;
|
||
case 121:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Range($$[$0-1], null, $$[$0]));
|
||
break;
|
||
case 122:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Range(null, $$[$0], $$[$0-1]));
|
||
break;
|
||
case 123:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Range(null, null, $$[$0]));
|
||
break;
|
||
case 124:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
|
||
break;
|
||
case 125:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0]));
|
||
break;
|
||
case 126:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0]));
|
||
break;
|
||
case 127:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-2]);
|
||
break;
|
||
case 128:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2]));
|
||
break;
|
||
case 129:this.$ = $$[$0];
|
||
break;
|
||
case 130:this.$ = $$[$0];
|
||
break;
|
||
case 131:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Expansion);
|
||
break;
|
||
case 132:this.$ = $$[$0];
|
||
break;
|
||
case 133:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([].concat($$[$0-2], $$[$0]));
|
||
break;
|
||
case 134:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Try($$[$0]));
|
||
break;
|
||
case 135:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Try($$[$0-1], $$[$0][0], $$[$0][1]));
|
||
break;
|
||
case 136:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Try($$[$0-2], null, null, $$[$0]));
|
||
break;
|
||
case 137:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0]));
|
||
break;
|
||
case 138:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([$$[$0-1], $$[$0]]);
|
||
break;
|
||
case 139:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Value($$[$0-1])), $$[$0]]);
|
||
break;
|
||
case 140:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([null, $$[$0]]);
|
||
break;
|
||
case 141:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Throw($$[$0]));
|
||
break;
|
||
case 142:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Parens($$[$0-1]));
|
||
break;
|
||
case 143:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Parens($$[$0-2]));
|
||
break;
|
||
case 144:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While($$[$0]));
|
||
break;
|
||
case 145:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.While($$[$0-2], {
|
||
guard: $$[$0]
|
||
}));
|
||
break;
|
||
case 146:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While($$[$0], {
|
||
invert: true
|
||
}));
|
||
break;
|
||
case 147:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.While($$[$0-2], {
|
||
invert: true,
|
||
guard: $$[$0]
|
||
}));
|
||
break;
|
||
case 148:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].addBody($$[$0]));
|
||
break;
|
||
case 149:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0].addBody(yy.addLocationDataFn(_$[$0-1])(yy.Block.wrap([$$[$0-1]]))));
|
||
break;
|
||
case 150:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0].addBody(yy.addLocationDataFn(_$[$0-1])(yy.Block.wrap([$$[$0-1]]))));
|
||
break;
|
||
case 151:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])($$[$0]);
|
||
break;
|
||
case 152:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('true'))).addBody($$[$0]));
|
||
break;
|
||
case 153:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('true'))).addBody(yy.addLocationDataFn(_$[$0])(yy.Block.wrap([$$[$0]]))));
|
||
break;
|
||
case 154:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0-1], $$[$0]));
|
||
break;
|
||
case 155:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0-1], $$[$0]));
|
||
break;
|
||
case 156:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0], $$[$0-1]));
|
||
break;
|
||
case 157:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({
|
||
source: yy.addLocationDataFn(_$[$0])(new yy.Value($$[$0]))
|
||
});
|
||
break;
|
||
case 158:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])((function () {
|
||
$$[$0].own = $$[$0-1].own;
|
||
$$[$0].name = $$[$0-1][0];
|
||
$$[$0].index = $$[$0-1][1];
|
||
return $$[$0];
|
||
}()));
|
||
break;
|
||
case 159:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0]);
|
||
break;
|
||
case 160:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])((function () {
|
||
$$[$0].own = true;
|
||
return $$[$0];
|
||
}()));
|
||
break;
|
||
case 161:this.$ = $$[$0];
|
||
break;
|
||
case 162:this.$ = $$[$0];
|
||
break;
|
||
case 163:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
|
||
break;
|
||
case 164:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
|
||
break;
|
||
case 165:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
|
||
break;
|
||
case 166:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([$$[$0-2], $$[$0]]);
|
||
break;
|
||
case 167:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({
|
||
source: $$[$0]
|
||
});
|
||
break;
|
||
case 168:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({
|
||
source: $$[$0],
|
||
object: true
|
||
});
|
||
break;
|
||
case 169:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({
|
||
source: $$[$0-2],
|
||
guard: $$[$0]
|
||
});
|
||
break;
|
||
case 170:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({
|
||
source: $$[$0-2],
|
||
guard: $$[$0],
|
||
object: true
|
||
});
|
||
break;
|
||
case 171:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({
|
||
source: $$[$0-2],
|
||
step: $$[$0]
|
||
});
|
||
break;
|
||
case 172:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])({
|
||
source: $$[$0-4],
|
||
guard: $$[$0-2],
|
||
step: $$[$0]
|
||
});
|
||
break;
|
||
case 173:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])({
|
||
source: $$[$0-4],
|
||
step: $$[$0-2],
|
||
guard: $$[$0]
|
||
});
|
||
break;
|
||
case 174:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Switch($$[$0-3], $$[$0-1]));
|
||
break;
|
||
case 175:this.$ = yy.addLocationDataFn(_$[$0-6], _$[$0])(new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1]));
|
||
break;
|
||
case 176:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Switch(null, $$[$0-1]));
|
||
break;
|
||
case 177:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])(new yy.Switch(null, $$[$0-3], $$[$0-1]));
|
||
break;
|
||
case 178:this.$ = $$[$0];
|
||
break;
|
||
case 179:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].concat($$[$0]));
|
||
break;
|
||
case 180:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([[$$[$0-1], $$[$0]]]);
|
||
break;
|
||
case 181:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])([[$$[$0-2], $$[$0-1]]]);
|
||
break;
|
||
case 182:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], {
|
||
type: $$[$0-2]
|
||
}));
|
||
break;
|
||
case 183:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])($$[$0-4].addElse(yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], {
|
||
type: $$[$0-2]
|
||
}))));
|
||
break;
|
||
case 184:this.$ = $$[$0];
|
||
break;
|
||
case 185:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].addElse($$[$0]));
|
||
break;
|
||
case 186:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0], yy.addLocationDataFn(_$[$0-2])(yy.Block.wrap([$$[$0-2]])), {
|
||
type: $$[$0-1],
|
||
statement: true
|
||
}));
|
||
break;
|
||
case 187:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0], yy.addLocationDataFn(_$[$0-2])(yy.Block.wrap([$$[$0-2]])), {
|
||
type: $$[$0-1],
|
||
statement: true
|
||
}));
|
||
break;
|
||
case 188:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op($$[$0-1], $$[$0]));
|
||
break;
|
||
case 189:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op($$[$0-1], $$[$0]));
|
||
break;
|
||
case 190:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('-', $$[$0]));
|
||
break;
|
||
case 191:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('+', $$[$0]));
|
||
break;
|
||
case 192:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('--', $$[$0]));
|
||
break;
|
||
case 193:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('++', $$[$0]));
|
||
break;
|
||
case 194:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('--', $$[$0-1], null, true));
|
||
break;
|
||
case 195:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('++', $$[$0-1], null, true));
|
||
break;
|
||
case 196:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Existence($$[$0-1]));
|
||
break;
|
||
case 197:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op('+', $$[$0-2], $$[$0]));
|
||
break;
|
||
case 198:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op('-', $$[$0-2], $$[$0]));
|
||
break;
|
||
case 199:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
|
||
break;
|
||
case 200:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
|
||
break;
|
||
case 201:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
|
||
break;
|
||
case 202:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
|
||
break;
|
||
case 203:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
|
||
break;
|
||
case 204:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])((function () {
|
||
if ($$[$0-1].charAt(0) === '!') {
|
||
return new yy.Op($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert();
|
||
} else {
|
||
return new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
|
||
}
|
||
}()));
|
||
break;
|
||
case 205:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0], $$[$0-1]));
|
||
break;
|
||
case 206:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3]));
|
||
break;
|
||
case 207:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0], $$[$0-2]));
|
||
break;
|
||
case 208:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Extends($$[$0-2], $$[$0]));
|
||
break;
|
||
}
|
||
},
|
||
table: [{1:[2,1],3:1,4:2,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[3]},{1:[2,2],6:[1,73]},{1:[2,3],6:[2,3],26:[2,3],102:[2,3]},{1:[2,6],6:[2,6],26:[2,6],102:[2,6],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,7],6:[2,7],26:[2,7],102:[2,7],103:87,104:[1,64],106:[1,65],109:88,110:[1,67],111:68,126:[1,86]},{1:[2,11],6:[2,11],25:[2,11],26:[2,11],49:[2,11],54:[2,11],57:[2,11],62:90,66:[1,92],67:[1,93],68:[1,94],69:[1,95],70:96,71:[1,97],73:[2,11],74:[1,98],78:[2,11],81:89,84:[1,91],85:[2,108],86:[2,11],91:[2,11],93:[2,11],102:[2,11],104:[2,11],105:[2,11],106:[2,11],110:[2,11],118:[2,11],126:[2,11],129:[2,11],130:[2,11],133:[2,11],134:[2,11],135:[2,11],136:[2,11],137:[2,11],138:[2,11],139:[2,11]},{1:[2,12],6:[2,12],25:[2,12],26:[2,12],49:[2,12],54:[2,12],57:[2,12],62:100,66:[1,92],67:[1,93],68:[1,94],69:[1,95],70:96,71:[1,97],73:[2,12],74:[1,98],78:[2,12],81:99,84:[1,91],85:[2,108],86:[2,12],91:[2,12],93:[2,12],102:[2,12],104:[2,12],105:[2,12],106:[2,12],110:[2,12],118:[2,12],126:[2,12],129:[2,12],130:[2,12],133:[2,12],134:[2,12],135:[2,12],136:[2,12],137:[2,12],138:[2,12],139:[2,12]},{1:[2,13],6:[2,13],25:[2,13],26:[2,13],49:[2,13],54:[2,13],57:[2,13],73:[2,13],78:[2,13],86:[2,13],91:[2,13],93:[2,13],102:[2,13],104:[2,13],105:[2,13],106:[2,13],110:[2,13],118:[2,13],126:[2,13],129:[2,13],130:[2,13],133:[2,13],134:[2,13],135:[2,13],136:[2,13],137:[2,13],138:[2,13],139:[2,13]},{1:[2,14],6:[2,14],25:[2,14],26:[2,14],49:[2,14],54:[2,14],57:[2,14],73:[2,14],78:[2,14],86:[2,14],91:[2,14],93:[2,14],102:[2,14],104:[2,14],105:[2,14],106:[2,14],110:[2,14],118:[2,14],126:[2,14],129:[2,14],130:[2,14],133:[2,14],134:[2,14],135:[2,14],136:[2,14],137:[2,14],138:[2,14],139:[2,14]},{1:[2,15],6:[2,15],25:[2,15],26:[2,15],49:[2,15],54:[2,15],57:[2,15],73:[2,15],78:[2,15],86:[2,15],91:[2,15],93:[2,15],102:[2,15],104:[2,15],105:[2,15],106:[2,15],110:[2,15],118:[2,15],126:[2,15],129:[2,15],130:[2,15],133:[2,15],134:[2,15],135:[2,15],136:[2,15],137:[2,15],138:[2,15],139:[2,15]},{1:[2,16],6:[2,16],25:[2,16],26:[2,16],49:[2,16],54:[2,16],57:[2,16],73:[2,16],78:[2,16],86:[2,16],91:[2,16],93:[2,16],102:[2,16],104:[2,16],105:[2,16],106:[2,16],110:[2,16],118:[2,16],126:[2,16],129:[2,16],130:[2,16],133:[2,16],134:[2,16],135:[2,16],136:[2,16],137:[2,16],138:[2,16],139:[2,16]},{1:[2,17],6:[2,17],25:[2,17],26:[2,17],49:[2,17],54:[2,17],57:[2,17],73:[2,17],78:[2,17],86:[2,17],91:[2,17],93:[2,17],102:[2,17],104:[2,17],105:[2,17],106:[2,17],110:[2,17],118:[2,17],126:[2,17],129:[2,17],130:[2,17],133:[2,17],134:[2,17],135:[2,17],136:[2,17],137:[2,17],138:[2,17],139:[2,17]},{1:[2,18],6:[2,18],25:[2,18],26:[2,18],49:[2,18],54:[2,18],57:[2,18],73:[2,18],78:[2,18],86:[2,18],91:[2,18],93:[2,18],102:[2,18],104:[2,18],105:[2,18],106:[2,18],110:[2,18],118:[2,18],126:[2,18],129:[2,18],130:[2,18],133:[2,18],134:[2,18],135:[2,18],136:[2,18],137:[2,18],138:[2,18],139:[2,18]},{1:[2,19],6:[2,19],25:[2,19],26:[2,19],49:[2,19],54:[2,19],57:[2,19],73:[2,19],78:[2,19],86:[2,19],91:[2,19],93:[2,19],102:[2,19],104:[2,19],105:[2,19],106:[2,19],110:[2,19],118:[2,19],126:[2,19],129:[2,19],130:[2,19],133:[2,19],134:[2,19],135:[2,19],136:[2,19],137:[2,19],138:[2,19],139:[2,19]},{1:[2,20],6:[2,20],25:[2,20],26:[2,20],49:[2,20],54:[2,20],57:[2,20],73:[2,20],78:[2,20],86:[2,20],91:[2,20],93:[2,20],102:[2,20],104:[2,20],105:[2,20],106:[2,20],110:[2,20],118:[2,20],126:[2,20],129:[2,20],130:[2,20],133:[2,20],134:[2,20],135:[2,20],136:[2,20],137:[2,20],138:[2,20],139:[2,20]},{1:[2,21],6:[2,21],25:[2,21],26:[2,21],49:[2,21],54:[2,21],57:[2,21],73:[2,21],78:[2,21],86:[2,21],91:[2,21],93:[2,21],102:[2,21],104:[2,21],105:[2,21],106:[2,21],110:[2,21],118:[2,21],126:[2,21],129:[2,21],130:[2,21],133:[2,21],134:[2,21],135:[2,21],136:[2,21],137:[2,21],138:[2,21],139:[2,21]},{1:[2,22],6:[2,22],25:[2,22],26:[2,22],49:[2,22],54:[2,22],57:[2,22],73:[2,22],78:[2,22],86:[2,22],91:[2,22],93:[2,22],102:[2,22],104:[2,22],105:[2,22],106:[2,22],110:[2,22],118:[2,22],126:[2,22],129:[2,22],130:[2,22],133:[2,22],134:[2,22],135:[2,22],136:[2,22],137:[2,22],138:[2,22],139:[2,22]},{1:[2,8],6:[2,8],26:[2,8],102:[2,8],104:[2,8],106:[2,8],110:[2,8],126:[2,8]},{1:[2,9],6:[2,9],26:[2,9],102:[2,9],104:[2,9],106:[2,9],110:[2,9],126:[2,9]},{1:[2,10],6:[2,10],26:[2,10],102:[2,10],104:[2,10],106:[2,10],110:[2,10],126:[2,10]},{1:[2,75],6:[2,75],25:[2,75],26:[2,75],40:[1,101],49:[2,75],54:[2,75],57:[2,75],66:[2,75],67:[2,75],68:[2,75],69:[2,75],71:[2,75],73:[2,75],74:[2,75],78:[2,75],84:[2,75],85:[2,75],86:[2,75],91:[2,75],93:[2,75],102:[2,75],104:[2,75],105:[2,75],106:[2,75],110:[2,75],118:[2,75],126:[2,75],129:[2,75],130:[2,75],133:[2,75],134:[2,75],135:[2,75],136:[2,75],137:[2,75],138:[2,75],139:[2,75]},{1:[2,76],6:[2,76],25:[2,76],26:[2,76],49:[2,76],54:[2,76],57:[2,76],66:[2,76],67:[2,76],68:[2,76],69:[2,76],71:[2,76],73:[2,76],74:[2,76],78:[2,76],84:[2,76],85:[2,76],86:[2,76],91:[2,76],93:[2,76],102:[2,76],104:[2,76],105:[2,76],106:[2,76],110:[2,76],118:[2,76],126:[2,76],129:[2,76],130:[2,76],133:[2,76],134:[2,76],135:[2,76],136:[2,76],137:[2,76],138:[2,76],139:[2,76]},{1:[2,77],6:[2,77],25:[2,77],26:[2,77],49:[2,77],54:[2,77],57:[2,77],66:[2,77],67:[2,77],68:[2,77],69:[2,77],71:[2,77],73:[2,77],74:[2,77],78:[2,77],84:[2,77],85:[2,77],86:[2,77],91:[2,77],93:[2,77],102:[2,77],104:[2,77],105:[2,77],106:[2,77],110:[2,77],118:[2,77],126:[2,77],129:[2,77],130:[2,77],133:[2,77],134:[2,77],135:[2,77],136:[2,77],137:[2,77],138:[2,77],139:[2,77]},{1:[2,78],6:[2,78],25:[2,78],26:[2,78],49:[2,78],54:[2,78],57:[2,78],66:[2,78],67:[2,78],68:[2,78],69:[2,78],71:[2,78],73:[2,78],74:[2,78],78:[2,78],84:[2,78],85:[2,78],86:[2,78],91:[2,78],93:[2,78],102:[2,78],104:[2,78],105:[2,78],106:[2,78],110:[2,78],118:[2,78],126:[2,78],129:[2,78],130:[2,78],133:[2,78],134:[2,78],135:[2,78],136:[2,78],137:[2,78],138:[2,78],139:[2,78]},{1:[2,79],6:[2,79],25:[2,79],26:[2,79],49:[2,79],54:[2,79],57:[2,79],66:[2,79],67:[2,79],68:[2,79],69:[2,79],71:[2,79],73:[2,79],74:[2,79],78:[2,79],84:[2,79],85:[2,79],86:[2,79],91:[2,79],93:[2,79],102:[2,79],104:[2,79],105:[2,79],106:[2,79],110:[2,79],118:[2,79],126:[2,79],129:[2,79],130:[2,79],133:[2,79],134:[2,79],135:[2,79],136:[2,79],137:[2,79],138:[2,79],139:[2,79]},{1:[2,106],6:[2,106],25:[2,106],26:[2,106],49:[2,106],54:[2,106],57:[2,106],66:[2,106],67:[2,106],68:[2,106],69:[2,106],71:[2,106],73:[2,106],74:[2,106],78:[2,106],82:102,84:[2,106],85:[1,103],86:[2,106],91:[2,106],93:[2,106],102:[2,106],104:[2,106],105:[2,106],106:[2,106],110:[2,106],118:[2,106],126:[2,106],129:[2,106],130:[2,106],133:[2,106],134:[2,106],135:[2,106],136:[2,106],137:[2,106],138:[2,106],139:[2,106]},{6:[2,54],25:[2,54],27:108,28:[1,72],44:109,48:104,49:[2,54],54:[2,54],55:105,56:106,57:[1,107],58:110,59:111,76:[1,69],89:[1,112],90:[1,113]},{24:114,25:[1,115]},{7:116,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:118,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:119,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:120,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{12:122,13:123,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:124,44:62,58:46,59:47,61:121,63:23,64:24,65:25,76:[1,69],83:[1,26],88:[1,57],89:[1,58],90:[1,56],101:[1,55]},{12:122,13:123,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:124,44:62,58:46,59:47,61:125,63:23,64:24,65:25,76:[1,69],83:[1,26],88:[1,57],89:[1,58],90:[1,56],101:[1,55]},{1:[2,72],6:[2,72],25:[2,72],26:[2,72],40:[2,72],49:[2,72],54:[2,72],57:[2,72],66:[2,72],67:[2,72],68:[2,72],69:[2,72],71:[2,72],73:[2,72],74:[2,72],78:[2,72],80:[1,129],84:[2,72],85:[2,72],86:[2,72],91:[2,72],93:[2,72],102:[2,72],104:[2,72],105:[2,72],106:[2,72],110:[2,72],118:[2,72],126:[2,72],129:[2,72],130:[2,72],131:[1,126],132:[1,127],133:[2,72],134:[2,72],135:[2,72],136:[2,72],137:[2,72],138:[2,72],139:[2,72],140:[1,128]},{1:[2,184],6:[2,184],25:[2,184],26:[2,184],49:[2,184],54:[2,184],57:[2,184],73:[2,184],78:[2,184],86:[2,184],91:[2,184],93:[2,184],102:[2,184],104:[2,184],105:[2,184],106:[2,184],110:[2,184],118:[2,184],121:[1,130],126:[2,184],129:[2,184],130:[2,184],133:[2,184],134:[2,184],135:[2,184],136:[2,184],137:[2,184],138:[2,184],139:[2,184]},{24:131,25:[1,115]},{24:132,25:[1,115]},{1:[2,151],6:[2,151],25:[2,151],26:[2,151],49:[2,151],54:[2,151],57:[2,151],73:[2,151],78:[2,151],86:[2,151],91:[2,151],93:[2,151],102:[2,151],104:[2,151],105:[2,151],106:[2,151],110:[2,151],118:[2,151],126:[2,151],129:[2,151],130:[2,151],133:[2,151],134:[2,151],135:[2,151],136:[2,151],137:[2,151],138:[2,151],139:[2,151]},{24:133,25:[1,115]},{7:134,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,135],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,96],6:[2,96],12:122,13:123,24:136,25:[1,115],26:[2,96],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:124,44:62,49:[2,96],54:[2,96],57:[2,96],58:46,59:47,61:138,63:23,64:24,65:25,73:[2,96],76:[1,69],78:[2,96],80:[1,137],83:[1,26],86:[2,96],88:[1,57],89:[1,58],90:[1,56],91:[2,96],93:[2,96],101:[1,55],102:[2,96],104:[2,96],105:[2,96],106:[2,96],110:[2,96],118:[2,96],126:[2,96],129:[2,96],130:[2,96],133:[2,96],134:[2,96],135:[2,96],136:[2,96],137:[2,96],138:[2,96],139:[2,96]},{7:139,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,46],6:[2,46],7:140,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,26:[2,46],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],102:[2,46],103:38,104:[2,46],106:[2,46],107:39,108:[1,66],109:40,110:[2,46],111:68,119:[1,41],124:36,125:[1,63],126:[2,46],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,47],6:[2,47],25:[2,47],26:[2,47],54:[2,47],78:[2,47],102:[2,47],104:[2,47],106:[2,47],110:[2,47],126:[2,47]},{1:[2,73],6:[2,73],25:[2,73],26:[2,73],40:[2,73],49:[2,73],54:[2,73],57:[2,73],66:[2,73],67:[2,73],68:[2,73],69:[2,73],71:[2,73],73:[2,73],74:[2,73],78:[2,73],84:[2,73],85:[2,73],86:[2,73],91:[2,73],93:[2,73],102:[2,73],104:[2,73],105:[2,73],106:[2,73],110:[2,73],118:[2,73],126:[2,73],129:[2,73],130:[2,73],133:[2,73],134:[2,73],135:[2,73],136:[2,73],137:[2,73],138:[2,73],139:[2,73]},{1:[2,74],6:[2,74],25:[2,74],26:[2,74],40:[2,74],49:[2,74],54:[2,74],57:[2,74],66:[2,74],67:[2,74],68:[2,74],69:[2,74],71:[2,74],73:[2,74],74:[2,74],78:[2,74],84:[2,74],85:[2,74],86:[2,74],91:[2,74],93:[2,74],102:[2,74],104:[2,74],105:[2,74],106:[2,74],110:[2,74],118:[2,74],126:[2,74],129:[2,74],130:[2,74],133:[2,74],134:[2,74],135:[2,74],136:[2,74],137:[2,74],138:[2,74],139:[2,74]},{1:[2,28],6:[2,28],25:[2,28],26:[2,28],49:[2,28],54:[2,28],57:[2,28],66:[2,28],67:[2,28],68:[2,28],69:[2,28],71:[2,28],73:[2,28],74:[2,28],78:[2,28],84:[2,28],85:[2,28],86:[2,28],91:[2,28],93:[2,28],102:[2,28],104:[2,28],105:[2,28],106:[2,28],110:[2,28],118:[2,28],126:[2,28],129:[2,28],130:[2,28],133:[2,28],134:[2,28],135:[2,28],136:[2,28],137:[2,28],138:[2,28],139:[2,28]},{1:[2,29],6:[2,29],25:[2,29],26:[2,29],49:[2,29],54:[2,29],57:[2,29],66:[2,29],67:[2,29],68:[2,29],69:[2,29],71:[2,29],73:[2,29],74:[2,29],78:[2,29],84:[2,29],85:[2,29],86:[2,29],91:[2,29],93:[2,29],102:[2,29],104:[2,29],105:[2,29],106:[2,29],110:[2,29],118:[2,29],126:[2,29],129:[2,29],130:[2,29],133:[2,29],134:[2,29],135:[2,29],136:[2,29],137:[2,29],138:[2,29],139:[2,29]},{1:[2,30],6:[2,30],25:[2,30],26:[2,30],49:[2,30],54:[2,30],57:[2,30],66:[2,30],67:[2,30],68:[2,30],69:[2,30],71:[2,30],73:[2,30],74:[2,30],78:[2,30],84:[2,30],85:[2,30],86:[2,30],91:[2,30],93:[2,30],102:[2,30],104:[2,30],105:[2,30],106:[2,30],110:[2,30],118:[2,30],126:[2,30],129:[2,30],130:[2,30],133:[2,30],134:[2,30],135:[2,30],136:[2,30],137:[2,30],138:[2,30],139:[2,30]},{1:[2,31],6:[2,31],25:[2,31],26:[2,31],49:[2,31],54:[2,31],57:[2,31],66:[2,31],67:[2,31],68:[2,31],69:[2,31],71:[2,31],73:[2,31],74:[2,31],78:[2,31],84:[2,31],85:[2,31],86:[2,31],91:[2,31],93:[2,31],102:[2,31],104:[2,31],105:[2,31],106:[2,31],110:[2,31],118:[2,31],126:[2,31],129:[2,31],130:[2,31],133:[2,31],134:[2,31],135:[2,31],136:[2,31],137:[2,31],138:[2,31],139:[2,31]},{1:[2,32],6:[2,32],25:[2,32],26:[2,32],49:[2,32],54:[2,32],57:[2,32],66:[2,32],67:[2,32],68:[2,32],69:[2,32],71:[2,32],73:[2,32],74:[2,32],78:[2,32],84:[2,32],85:[2,32],86:[2,32],91:[2,32],93:[2,32],102:[2,32],104:[2,32],105:[2,32],106:[2,32],110:[2,32],118:[2,32],126:[2,32],129:[2,32],130:[2,32],133:[2,32],134:[2,32],135:[2,32],136:[2,32],137:[2,32],138:[2,32],139:[2,32]},{1:[2,33],6:[2,33],25:[2,33],26:[2,33],49:[2,33],54:[2,33],57:[2,33],66:[2,33],67:[2,33],68:[2,33],69:[2,33],71:[2,33],73:[2,33],74:[2,33],78:[2,33],84:[2,33],85:[2,33],86:[2,33],91:[2,33],93:[2,33],102:[2,33],104:[2,33],105:[2,33],106:[2,33],110:[2,33],118:[2,33],126:[2,33],129:[2,33],130:[2,33],133:[2,33],134:[2,33],135:[2,33],136:[2,33],137:[2,33],138:[2,33],139:[2,33]},{1:[2,34],6:[2,34],25:[2,34],26:[2,34],49:[2,34],54:[2,34],57:[2,34],66:[2,34],67:[2,34],68:[2,34],69:[2,34],71:[2,34],73:[2,34],74:[2,34],78:[2,34],84:[2,34],85:[2,34],86:[2,34],91:[2,34],93:[2,34],102:[2,34],104:[2,34],105:[2,34],106:[2,34],110:[2,34],118:[2,34],126:[2,34],129:[2,34],130:[2,34],133:[2,34],134:[2,34],135:[2,34],136:[2,34],137:[2,34],138:[2,34],139:[2,34]},{4:141,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,142],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:143,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,147],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],57:[1,149],58:46,59:47,60:148,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],87:145,88:[1,57],89:[1,58],90:[1,56],91:[1,144],94:146,96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,112],6:[2,112],25:[2,112],26:[2,112],49:[2,112],54:[2,112],57:[2,112],66:[2,112],67:[2,112],68:[2,112],69:[2,112],71:[2,112],73:[2,112],74:[2,112],78:[2,112],84:[2,112],85:[2,112],86:[2,112],91:[2,112],93:[2,112],102:[2,112],104:[2,112],105:[2,112],106:[2,112],110:[2,112],118:[2,112],126:[2,112],129:[2,112],130:[2,112],133:[2,112],134:[2,112],135:[2,112],136:[2,112],137:[2,112],138:[2,112],139:[2,112]},{1:[2,113],6:[2,113],25:[2,113],26:[2,113],27:150,28:[1,72],49:[2,113],54:[2,113],57:[2,113],66:[2,113],67:[2,113],68:[2,113],69:[2,113],71:[2,113],73:[2,113],74:[2,113],78:[2,113],84:[2,113],85:[2,113],86:[2,113],91:[2,113],93:[2,113],102:[2,113],104:[2,113],105:[2,113],106:[2,113],110:[2,113],118:[2,113],126:[2,113],129:[2,113],130:[2,113],133:[2,113],134:[2,113],135:[2,113],136:[2,113],137:[2,113],138:[2,113],139:[2,113]},{25:[2,50]},{25:[2,51]},{1:[2,68],6:[2,68],25:[2,68],26:[2,68],40:[2,68],49:[2,68],54:[2,68],57:[2,68],66:[2,68],67:[2,68],68:[2,68],69:[2,68],71:[2,68],73:[2,68],74:[2,68],78:[2,68],80:[2,68],84:[2,68],85:[2,68],86:[2,68],91:[2,68],93:[2,68],102:[2,68],104:[2,68],105:[2,68],106:[2,68],110:[2,68],118:[2,68],126:[2,68],129:[2,68],130:[2,68],131:[2,68],132:[2,68],133:[2,68],134:[2,68],135:[2,68],136:[2,68],137:[2,68],138:[2,68],139:[2,68],140:[2,68]},{1:[2,71],6:[2,71],25:[2,71],26:[2,71],40:[2,71],49:[2,71],54:[2,71],57:[2,71],66:[2,71],67:[2,71],68:[2,71],69:[2,71],71:[2,71],73:[2,71],74:[2,71],78:[2,71],80:[2,71],84:[2,71],85:[2,71],86:[2,71],91:[2,71],93:[2,71],102:[2,71],104:[2,71],105:[2,71],106:[2,71],110:[2,71],118:[2,71],126:[2,71],129:[2,71],130:[2,71],131:[2,71],132:[2,71],133:[2,71],134:[2,71],135:[2,71],136:[2,71],137:[2,71],138:[2,71],139:[2,71],140:[2,71]},{7:151,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:152,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:153,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:155,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:154,25:[1,115],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{27:160,28:[1,72],44:161,58:162,59:163,64:156,76:[1,69],89:[1,112],90:[1,56],113:157,114:[1,158],115:159},{112:164,116:[1,165],117:[1,166]},{6:[2,91],10:170,25:[2,91],27:171,28:[1,72],29:172,30:[1,70],31:[1,71],41:168,42:169,44:173,46:[1,45],54:[2,91],77:167,78:[2,91],89:[1,112]},{1:[2,26],6:[2,26],25:[2,26],26:[2,26],43:[2,26],49:[2,26],54:[2,26],57:[2,26],66:[2,26],67:[2,26],68:[2,26],69:[2,26],71:[2,26],73:[2,26],74:[2,26],78:[2,26],84:[2,26],85:[2,26],86:[2,26],91:[2,26],93:[2,26],102:[2,26],104:[2,26],105:[2,26],106:[2,26],110:[2,26],118:[2,26],126:[2,26],129:[2,26],130:[2,26],133:[2,26],134:[2,26],135:[2,26],136:[2,26],137:[2,26],138:[2,26],139:[2,26]},{1:[2,27],6:[2,27],25:[2,27],26:[2,27],43:[2,27],49:[2,27],54:[2,27],57:[2,27],66:[2,27],67:[2,27],68:[2,27],69:[2,27],71:[2,27],73:[2,27],74:[2,27],78:[2,27],84:[2,27],85:[2,27],86:[2,27],91:[2,27],93:[2,27],102:[2,27],104:[2,27],105:[2,27],106:[2,27],110:[2,27],118:[2,27],126:[2,27],129:[2,27],130:[2,27],133:[2,27],134:[2,27],135:[2,27],136:[2,27],137:[2,27],138:[2,27],139:[2,27]},{1:[2,25],6:[2,25],25:[2,25],26:[2,25],40:[2,25],43:[2,25],49:[2,25],54:[2,25],57:[2,25],66:[2,25],67:[2,25],68:[2,25],69:[2,25],71:[2,25],73:[2,25],74:[2,25],78:[2,25],80:[2,25],84:[2,25],85:[2,25],86:[2,25],91:[2,25],93:[2,25],102:[2,25],104:[2,25],105:[2,25],106:[2,25],110:[2,25],116:[2,25],117:[2,25],118:[2,25],126:[2,25],129:[2,25],130:[2,25],131:[2,25],132:[2,25],133:[2,25],134:[2,25],135:[2,25],136:[2,25],137:[2,25],138:[2,25],139:[2,25],140:[2,25]},{1:[2,5],5:174,6:[2,5],7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,26:[2,5],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],102:[2,5],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,196],6:[2,196],25:[2,196],26:[2,196],49:[2,196],54:[2,196],57:[2,196],73:[2,196],78:[2,196],86:[2,196],91:[2,196],93:[2,196],102:[2,196],104:[2,196],105:[2,196],106:[2,196],110:[2,196],118:[2,196],126:[2,196],129:[2,196],130:[2,196],133:[2,196],134:[2,196],135:[2,196],136:[2,196],137:[2,196],138:[2,196],139:[2,196]},{7:175,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:176,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:177,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:178,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:179,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:180,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:181,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:182,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:183,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,150],6:[2,150],25:[2,150],26:[2,150],49:[2,150],54:[2,150],57:[2,150],73:[2,150],78:[2,150],86:[2,150],91:[2,150],93:[2,150],102:[2,150],104:[2,150],105:[2,150],106:[2,150],110:[2,150],118:[2,150],126:[2,150],129:[2,150],130:[2,150],133:[2,150],134:[2,150],135:[2,150],136:[2,150],137:[2,150],138:[2,150],139:[2,150]},{1:[2,155],6:[2,155],25:[2,155],26:[2,155],49:[2,155],54:[2,155],57:[2,155],73:[2,155],78:[2,155],86:[2,155],91:[2,155],93:[2,155],102:[2,155],104:[2,155],105:[2,155],106:[2,155],110:[2,155],118:[2,155],126:[2,155],129:[2,155],130:[2,155],133:[2,155],134:[2,155],135:[2,155],136:[2,155],137:[2,155],138:[2,155],139:[2,155]},{7:184,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,149],6:[2,149],25:[2,149],26:[2,149],49:[2,149],54:[2,149],57:[2,149],73:[2,149],78:[2,149],86:[2,149],91:[2,149],93:[2,149],102:[2,149],104:[2,149],105:[2,149],106:[2,149],110:[2,149],118:[2,149],126:[2,149],129:[2,149],130:[2,149],133:[2,149],134:[2,149],135:[2,149],136:[2,149],137:[2,149],138:[2,149],139:[2,149]},{1:[2,154],6:[2,154],25:[2,154],26:[2,154],49:[2,154],54:[2,154],57:[2,154],73:[2,154],78:[2,154],86:[2,154],91:[2,154],93:[2,154],102:[2,154],104:[2,154],105:[2,154],106:[2,154],110:[2,154],118:[2,154],126:[2,154],129:[2,154],130:[2,154],133:[2,154],134:[2,154],135:[2,154],136:[2,154],137:[2,154],138:[2,154],139:[2,154]},{82:185,85:[1,103]},{1:[2,69],6:[2,69],25:[2,69],26:[2,69],40:[2,69],49:[2,69],54:[2,69],57:[2,69],66:[2,69],67:[2,69],68:[2,69],69:[2,69],71:[2,69],73:[2,69],74:[2,69],78:[2,69],80:[2,69],84:[2,69],85:[2,69],86:[2,69],91:[2,69],93:[2,69],102:[2,69],104:[2,69],105:[2,69],106:[2,69],110:[2,69],118:[2,69],126:[2,69],129:[2,69],130:[2,69],131:[2,69],132:[2,69],133:[2,69],134:[2,69],135:[2,69],136:[2,69],137:[2,69],138:[2,69],139:[2,69],140:[2,69]},{85:[2,109]},{27:186,28:[1,72]},{27:187,28:[1,72]},{1:[2,84],6:[2,84],25:[2,84],26:[2,84],27:188,28:[1,72],40:[2,84],49:[2,84],54:[2,84],57:[2,84],66:[2,84],67:[2,84],68:[2,84],69:[2,84],71:[2,84],73:[2,84],74:[2,84],78:[2,84],80:[2,84],84:[2,84],85:[2,84],86:[2,84],91:[2,84],93:[2,84],102:[2,84],104:[2,84],105:[2,84],106:[2,84],110:[2,84],118:[2,84],126:[2,84],129:[2,84],130:[2,84],131:[2,84],132:[2,84],133:[2,84],134:[2,84],135:[2,84],136:[2,84],137:[2,84],138:[2,84],139:[2,84],140:[2,84]},{27:189,28:[1,72]},{1:[2,85],6:[2,85],25:[2,85],26:[2,85],40:[2,85],49:[2,85],54:[2,85],57:[2,85],66:[2,85],67:[2,85],68:[2,85],69:[2,85],71:[2,85],73:[2,85],74:[2,85],78:[2,85],80:[2,85],84:[2,85],85:[2,85],86:[2,85],91:[2,85],93:[2,85],102:[2,85],104:[2,85],105:[2,85],106:[2,85],110:[2,85],118:[2,85],126:[2,85],129:[2,85],130:[2,85],131:[2,85],132:[2,85],133:[2,85],134:[2,85],135:[2,85],136:[2,85],137:[2,85],138:[2,85],139:[2,85],140:[2,85]},{7:191,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],57:[1,195],58:46,59:47,61:35,63:23,64:24,65:25,72:190,75:192,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],92:193,93:[1,194],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{70:196,71:[1,97],74:[1,98]},{82:197,85:[1,103]},{1:[2,70],6:[2,70],25:[2,70],26:[2,70],40:[2,70],49:[2,70],54:[2,70],57:[2,70],66:[2,70],67:[2,70],68:[2,70],69:[2,70],71:[2,70],73:[2,70],74:[2,70],78:[2,70],80:[2,70],84:[2,70],85:[2,70],86:[2,70],91:[2,70],93:[2,70],102:[2,70],104:[2,70],105:[2,70],106:[2,70],110:[2,70],118:[2,70],126:[2,70],129:[2,70],130:[2,70],131:[2,70],132:[2,70],133:[2,70],134:[2,70],135:[2,70],136:[2,70],137:[2,70],138:[2,70],139:[2,70],140:[2,70]},{6:[1,199],7:198,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,200],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,107],6:[2,107],25:[2,107],26:[2,107],49:[2,107],54:[2,107],57:[2,107],66:[2,107],67:[2,107],68:[2,107],69:[2,107],71:[2,107],73:[2,107],74:[2,107],78:[2,107],84:[2,107],85:[2,107],86:[2,107],91:[2,107],93:[2,107],102:[2,107],104:[2,107],105:[2,107],106:[2,107],110:[2,107],118:[2,107],126:[2,107],129:[2,107],130:[2,107],133:[2,107],134:[2,107],135:[2,107],136:[2,107],137:[2,107],138:[2,107],139:[2,107]},{7:203,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,147],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],57:[1,149],58:46,59:47,60:148,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],86:[1,201],87:202,88:[1,57],89:[1,58],90:[1,56],94:146,96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{6:[2,52],25:[2,52],49:[1,204],53:206,54:[1,205]},{6:[2,55],25:[2,55],26:[2,55],49:[2,55],54:[2,55]},{6:[2,59],25:[2,59],26:[2,59],40:[1,208],49:[2,59],54:[2,59],57:[1,207]},{6:[2,62],25:[2,62],26:[2,62],49:[2,62],54:[2,62]},{6:[2,63],25:[2,63],26:[2,63],40:[2,63],49:[2,63],54:[2,63],57:[2,63]},{6:[2,64],25:[2,64],26:[2,64],40:[2,64],49:[2,64],54:[2,64],57:[2,64]},{6:[2,65],25:[2,65],26:[2,65],40:[2,65],49:[2,65],54:[2,65],57:[2,65]},{6:[2,66],25:[2,66],26:[2,66],40:[2,66],49:[2,66],54:[2,66],57:[2,66]},{27:150,28:[1,72]},{7:203,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,147],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],57:[1,149],58:46,59:47,60:148,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],87:145,88:[1,57],89:[1,58],90:[1,56],91:[1,144],94:146,96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,49],6:[2,49],25:[2,49],26:[2,49],49:[2,49],54:[2,49],57:[2,49],73:[2,49],78:[2,49],86:[2,49],91:[2,49],93:[2,49],102:[2,49],104:[2,49],105:[2,49],106:[2,49],110:[2,49],118:[2,49],126:[2,49],129:[2,49],130:[2,49],133:[2,49],134:[2,49],135:[2,49],136:[2,49],137:[2,49],138:[2,49],139:[2,49]},{4:210,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,26:[1,209],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,188],6:[2,188],25:[2,188],26:[2,188],49:[2,188],54:[2,188],57:[2,188],73:[2,188],78:[2,188],86:[2,188],91:[2,188],93:[2,188],102:[2,188],103:84,104:[2,188],105:[2,188],106:[2,188],109:85,110:[2,188],111:68,118:[2,188],126:[2,188],129:[2,188],130:[2,188],133:[1,74],134:[2,188],135:[2,188],136:[2,188],137:[2,188],138:[2,188],139:[2,188]},{103:87,104:[1,64],106:[1,65],109:88,110:[1,67],111:68,126:[1,86]},{1:[2,189],6:[2,189],25:[2,189],26:[2,189],49:[2,189],54:[2,189],57:[2,189],73:[2,189],78:[2,189],86:[2,189],91:[2,189],93:[2,189],102:[2,189],103:84,104:[2,189],105:[2,189],106:[2,189],109:85,110:[2,189],111:68,118:[2,189],126:[2,189],129:[2,189],130:[2,189],133:[1,74],134:[2,189],135:[1,78],136:[2,189],137:[2,189],138:[2,189],139:[2,189]},{1:[2,190],6:[2,190],25:[2,190],26:[2,190],49:[2,190],54:[2,190],57:[2,190],73:[2,190],78:[2,190],86:[2,190],91:[2,190],93:[2,190],102:[2,190],103:84,104:[2,190],105:[2,190],106:[2,190],109:85,110:[2,190],111:68,118:[2,190],126:[2,190],129:[2,190],130:[2,190],133:[1,74],134:[2,190],135:[1,78],136:[2,190],137:[2,190],138:[2,190],139:[2,190]},{1:[2,191],6:[2,191],25:[2,191],26:[2,191],49:[2,191],54:[2,191],57:[2,191],73:[2,191],78:[2,191],86:[2,191],91:[2,191],93:[2,191],102:[2,191],103:84,104:[2,191],105:[2,191],106:[2,191],109:85,110:[2,191],111:68,118:[2,191],126:[2,191],129:[2,191],130:[2,191],133:[1,74],134:[2,191],135:[1,78],136:[2,191],137:[2,191],138:[2,191],139:[2,191]},{1:[2,192],6:[2,192],25:[2,192],26:[2,192],49:[2,192],54:[2,192],57:[2,192],66:[2,72],67:[2,72],68:[2,72],69:[2,72],71:[2,72],73:[2,192],74:[2,72],78:[2,192],84:[2,72],85:[2,72],86:[2,192],91:[2,192],93:[2,192],102:[2,192],104:[2,192],105:[2,192],106:[2,192],110:[2,192],118:[2,192],126:[2,192],129:[2,192],130:[2,192],133:[2,192],134:[2,192],135:[2,192],136:[2,192],137:[2,192],138:[2,192],139:[2,192]},{62:90,66:[1,92],67:[1,93],68:[1,94],69:[1,95],70:96,71:[1,97],74:[1,98],81:89,84:[1,91],85:[2,108]},{62:100,66:[1,92],67:[1,93],68:[1,94],69:[1,95],70:96,71:[1,97],74:[1,98],81:99,84:[1,91],85:[2,108]},{66:[2,75],67:[2,75],68:[2,75],69:[2,75],71:[2,75],74:[2,75],84:[2,75],85:[2,75]},{1:[2,193],6:[2,193],25:[2,193],26:[2,193],49:[2,193],54:[2,193],57:[2,193],66:[2,72],67:[2,72],68:[2,72],69:[2,72],71:[2,72],73:[2,193],74:[2,72],78:[2,193],84:[2,72],85:[2,72],86:[2,193],91:[2,193],93:[2,193],102:[2,193],104:[2,193],105:[2,193],106:[2,193],110:[2,193],118:[2,193],126:[2,193],129:[2,193],130:[2,193],133:[2,193],134:[2,193],135:[2,193],136:[2,193],137:[2,193],138:[2,193],139:[2,193]},{1:[2,194],6:[2,194],25:[2,194],26:[2,194],49:[2,194],54:[2,194],57:[2,194],73:[2,194],78:[2,194],86:[2,194],91:[2,194],93:[2,194],102:[2,194],104:[2,194],105:[2,194],106:[2,194],110:[2,194],118:[2,194],126:[2,194],129:[2,194],130:[2,194],133:[2,194],134:[2,194],135:[2,194],136:[2,194],137:[2,194],138:[2,194],139:[2,194]},{1:[2,195],6:[2,195],25:[2,195],26:[2,195],49:[2,195],54:[2,195],57:[2,195],73:[2,195],78:[2,195],86:[2,195],91:[2,195],93:[2,195],102:[2,195],104:[2,195],105:[2,195],106:[2,195],110:[2,195],118:[2,195],126:[2,195],129:[2,195],130:[2,195],133:[2,195],134:[2,195],135:[2,195],136:[2,195],137:[2,195],138:[2,195],139:[2,195]},{6:[1,213],7:211,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,212],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:214,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{24:215,25:[1,115],125:[1,216]},{1:[2,134],6:[2,134],25:[2,134],26:[2,134],49:[2,134],54:[2,134],57:[2,134],73:[2,134],78:[2,134],86:[2,134],91:[2,134],93:[2,134],97:217,98:[1,218],99:[1,219],102:[2,134],104:[2,134],105:[2,134],106:[2,134],110:[2,134],118:[2,134],126:[2,134],129:[2,134],130:[2,134],133:[2,134],134:[2,134],135:[2,134],136:[2,134],137:[2,134],138:[2,134],139:[2,134]},{1:[2,148],6:[2,148],25:[2,148],26:[2,148],49:[2,148],54:[2,148],57:[2,148],73:[2,148],78:[2,148],86:[2,148],91:[2,148],93:[2,148],102:[2,148],104:[2,148],105:[2,148],106:[2,148],110:[2,148],118:[2,148],126:[2,148],129:[2,148],130:[2,148],133:[2,148],134:[2,148],135:[2,148],136:[2,148],137:[2,148],138:[2,148],139:[2,148]},{1:[2,156],6:[2,156],25:[2,156],26:[2,156],49:[2,156],54:[2,156],57:[2,156],73:[2,156],78:[2,156],86:[2,156],91:[2,156],93:[2,156],102:[2,156],104:[2,156],105:[2,156],106:[2,156],110:[2,156],118:[2,156],126:[2,156],129:[2,156],130:[2,156],133:[2,156],134:[2,156],135:[2,156],136:[2,156],137:[2,156],138:[2,156],139:[2,156]},{25:[1,220],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{120:221,122:222,123:[1,223]},{1:[2,97],6:[2,97],25:[2,97],26:[2,97],49:[2,97],54:[2,97],57:[2,97],73:[2,97],78:[2,97],86:[2,97],91:[2,97],93:[2,97],102:[2,97],104:[2,97],105:[2,97],106:[2,97],110:[2,97],118:[2,97],126:[2,97],129:[2,97],130:[2,97],133:[2,97],134:[2,97],135:[2,97],136:[2,97],137:[2,97],138:[2,97],139:[2,97]},{7:224,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,100],6:[2,100],24:225,25:[1,115],26:[2,100],49:[2,100],54:[2,100],57:[2,100],66:[2,72],67:[2,72],68:[2,72],69:[2,72],71:[2,72],73:[2,100],74:[2,72],78:[2,100],80:[1,226],84:[2,72],85:[2,72],86:[2,100],91:[2,100],93:[2,100],102:[2,100],104:[2,100],105:[2,100],106:[2,100],110:[2,100],118:[2,100],126:[2,100],129:[2,100],130:[2,100],133:[2,100],134:[2,100],135:[2,100],136:[2,100],137:[2,100],138:[2,100],139:[2,100]},{1:[2,141],6:[2,141],25:[2,141],26:[2,141],49:[2,141],54:[2,141],57:[2,141],73:[2,141],78:[2,141],86:[2,141],91:[2,141],93:[2,141],102:[2,141],103:84,104:[2,141],105:[2,141],106:[2,141],109:85,110:[2,141],111:68,118:[2,141],126:[2,141],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,45],6:[2,45],26:[2,45],102:[2,45],103:84,104:[2,45],106:[2,45],109:85,110:[2,45],111:68,126:[2,45],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{6:[1,73],102:[1,227]},{4:228,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{6:[2,129],25:[2,129],54:[2,129],57:[1,230],91:[2,129],92:229,93:[1,194],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,115],6:[2,115],25:[2,115],26:[2,115],40:[2,115],49:[2,115],54:[2,115],57:[2,115],66:[2,115],67:[2,115],68:[2,115],69:[2,115],71:[2,115],73:[2,115],74:[2,115],78:[2,115],84:[2,115],85:[2,115],86:[2,115],91:[2,115],93:[2,115],102:[2,115],104:[2,115],105:[2,115],106:[2,115],110:[2,115],116:[2,115],117:[2,115],118:[2,115],126:[2,115],129:[2,115],130:[2,115],133:[2,115],134:[2,115],135:[2,115],136:[2,115],137:[2,115],138:[2,115],139:[2,115]},{6:[2,52],25:[2,52],53:231,54:[1,232],91:[2,52]},{6:[2,124],25:[2,124],26:[2,124],54:[2,124],86:[2,124],91:[2,124]},{7:203,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,147],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],57:[1,149],58:46,59:47,60:148,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],87:233,88:[1,57],89:[1,58],90:[1,56],94:146,96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{6:[2,130],25:[2,130],26:[2,130],54:[2,130],86:[2,130],91:[2,130]},{6:[2,131],25:[2,131],26:[2,131],54:[2,131],86:[2,131],91:[2,131]},{1:[2,114],6:[2,114],25:[2,114],26:[2,114],40:[2,114],43:[2,114],49:[2,114],54:[2,114],57:[2,114],66:[2,114],67:[2,114],68:[2,114],69:[2,114],71:[2,114],73:[2,114],74:[2,114],78:[2,114],80:[2,114],84:[2,114],85:[2,114],86:[2,114],91:[2,114],93:[2,114],102:[2,114],104:[2,114],105:[2,114],106:[2,114],110:[2,114],116:[2,114],117:[2,114],118:[2,114],126:[2,114],129:[2,114],130:[2,114],131:[2,114],132:[2,114],133:[2,114],134:[2,114],135:[2,114],136:[2,114],137:[2,114],138:[2,114],139:[2,114],140:[2,114]},{24:234,25:[1,115],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,144],6:[2,144],25:[2,144],26:[2,144],49:[2,144],54:[2,144],57:[2,144],73:[2,144],78:[2,144],86:[2,144],91:[2,144],93:[2,144],102:[2,144],103:84,104:[1,64],105:[1,235],106:[1,65],109:85,110:[1,67],111:68,118:[2,144],126:[2,144],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,146],6:[2,146],25:[2,146],26:[2,146],49:[2,146],54:[2,146],57:[2,146],73:[2,146],78:[2,146],86:[2,146],91:[2,146],93:[2,146],102:[2,146],103:84,104:[1,64],105:[1,236],106:[1,65],109:85,110:[1,67],111:68,118:[2,146],126:[2,146],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,152],6:[2,152],25:[2,152],26:[2,152],49:[2,152],54:[2,152],57:[2,152],73:[2,152],78:[2,152],86:[2,152],91:[2,152],93:[2,152],102:[2,152],104:[2,152],105:[2,152],106:[2,152],110:[2,152],118:[2,152],126:[2,152],129:[2,152],130:[2,152],133:[2,152],134:[2,152],135:[2,152],136:[2,152],137:[2,152],138:[2,152],139:[2,152]},{1:[2,153],6:[2,153],25:[2,153],26:[2,153],49:[2,153],54:[2,153],57:[2,153],73:[2,153],78:[2,153],86:[2,153],91:[2,153],93:[2,153],102:[2,153],103:84,104:[1,64],105:[2,153],106:[1,65],109:85,110:[1,67],111:68,118:[2,153],126:[2,153],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,157],6:[2,157],25:[2,157],26:[2,157],49:[2,157],54:[2,157],57:[2,157],73:[2,157],78:[2,157],86:[2,157],91:[2,157],93:[2,157],102:[2,157],104:[2,157],105:[2,157],106:[2,157],110:[2,157],118:[2,157],126:[2,157],129:[2,157],130:[2,157],133:[2,157],134:[2,157],135:[2,157],136:[2,157],137:[2,157],138:[2,157],139:[2,157]},{116:[2,159],117:[2,159]},{27:160,28:[1,72],44:161,58:162,59:163,76:[1,69],89:[1,112],90:[1,113],113:237,115:159},{54:[1,238],116:[2,165],117:[2,165]},{54:[2,161],116:[2,161],117:[2,161]},{54:[2,162],116:[2,162],117:[2,162]},{54:[2,163],116:[2,163],117:[2,163]},{54:[2,164],116:[2,164],117:[2,164]},{1:[2,158],6:[2,158],25:[2,158],26:[2,158],49:[2,158],54:[2,158],57:[2,158],73:[2,158],78:[2,158],86:[2,158],91:[2,158],93:[2,158],102:[2,158],104:[2,158],105:[2,158],106:[2,158],110:[2,158],118:[2,158],126:[2,158],129:[2,158],130:[2,158],133:[2,158],134:[2,158],135:[2,158],136:[2,158],137:[2,158],138:[2,158],139:[2,158]},{7:239,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:240,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{6:[2,52],25:[2,52],53:241,54:[1,242],78:[2,52]},{6:[2,92],25:[2,92],26:[2,92],54:[2,92],78:[2,92]},{6:[2,38],25:[2,38],26:[2,38],43:[1,243],54:[2,38],78:[2,38]},{6:[2,41],25:[2,41],26:[2,41],54:[2,41],78:[2,41]},{6:[2,42],25:[2,42],26:[2,42],43:[2,42],54:[2,42],78:[2,42]},{6:[2,43],25:[2,43],26:[2,43],43:[2,43],54:[2,43],78:[2,43]},{6:[2,44],25:[2,44],26:[2,44],43:[2,44],54:[2,44],78:[2,44]},{1:[2,4],6:[2,4],26:[2,4],102:[2,4]},{1:[2,197],6:[2,197],25:[2,197],26:[2,197],49:[2,197],54:[2,197],57:[2,197],73:[2,197],78:[2,197],86:[2,197],91:[2,197],93:[2,197],102:[2,197],103:84,104:[2,197],105:[2,197],106:[2,197],109:85,110:[2,197],111:68,118:[2,197],126:[2,197],129:[2,197],130:[2,197],133:[1,74],134:[1,77],135:[1,78],136:[2,197],137:[2,197],138:[2,197],139:[2,197]},{1:[2,198],6:[2,198],25:[2,198],26:[2,198],49:[2,198],54:[2,198],57:[2,198],73:[2,198],78:[2,198],86:[2,198],91:[2,198],93:[2,198],102:[2,198],103:84,104:[2,198],105:[2,198],106:[2,198],109:85,110:[2,198],111:68,118:[2,198],126:[2,198],129:[2,198],130:[2,198],133:[1,74],134:[1,77],135:[1,78],136:[2,198],137:[2,198],138:[2,198],139:[2,198]},{1:[2,199],6:[2,199],25:[2,199],26:[2,199],49:[2,199],54:[2,199],57:[2,199],73:[2,199],78:[2,199],86:[2,199],91:[2,199],93:[2,199],102:[2,199],103:84,104:[2,199],105:[2,199],106:[2,199],109:85,110:[2,199],111:68,118:[2,199],126:[2,199],129:[2,199],130:[2,199],133:[1,74],134:[2,199],135:[1,78],136:[2,199],137:[2,199],138:[2,199],139:[2,199]},{1:[2,200],6:[2,200],25:[2,200],26:[2,200],49:[2,200],54:[2,200],57:[2,200],73:[2,200],78:[2,200],86:[2,200],91:[2,200],93:[2,200],102:[2,200],103:84,104:[2,200],105:[2,200],106:[2,200],109:85,110:[2,200],111:68,118:[2,200],126:[2,200],129:[2,200],130:[2,200],133:[1,74],134:[2,200],135:[1,78],136:[2,200],137:[2,200],138:[2,200],139:[2,200]},{1:[2,201],6:[2,201],25:[2,201],26:[2,201],49:[2,201],54:[2,201],57:[2,201],73:[2,201],78:[2,201],86:[2,201],91:[2,201],93:[2,201],102:[2,201],103:84,104:[2,201],105:[2,201],106:[2,201],109:85,110:[2,201],111:68,118:[2,201],126:[2,201],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[2,201],137:[2,201],138:[2,201],139:[2,201]},{1:[2,202],6:[2,202],25:[2,202],26:[2,202],49:[2,202],54:[2,202],57:[2,202],73:[2,202],78:[2,202],86:[2,202],91:[2,202],93:[2,202],102:[2,202],103:84,104:[2,202],105:[2,202],106:[2,202],109:85,110:[2,202],111:68,118:[2,202],126:[2,202],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[2,202],138:[2,202],139:[1,82]},{1:[2,203],6:[2,203],25:[2,203],26:[2,203],49:[2,203],54:[2,203],57:[2,203],73:[2,203],78:[2,203],86:[2,203],91:[2,203],93:[2,203],102:[2,203],103:84,104:[2,203],105:[2,203],106:[2,203],109:85,110:[2,203],111:68,118:[2,203],126:[2,203],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[2,203],139:[1,82]},{1:[2,204],6:[2,204],25:[2,204],26:[2,204],49:[2,204],54:[2,204],57:[2,204],73:[2,204],78:[2,204],86:[2,204],91:[2,204],93:[2,204],102:[2,204],103:84,104:[2,204],105:[2,204],106:[2,204],109:85,110:[2,204],111:68,118:[2,204],126:[2,204],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[2,204],138:[2,204],139:[2,204]},{1:[2,187],6:[2,187],25:[2,187],26:[2,187],49:[2,187],54:[2,187],57:[2,187],73:[2,187],78:[2,187],86:[2,187],91:[2,187],93:[2,187],102:[2,187],103:84,104:[1,64],105:[2,187],106:[1,65],109:85,110:[1,67],111:68,118:[2,187],126:[2,187],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,186],6:[2,186],25:[2,186],26:[2,186],49:[2,186],54:[2,186],57:[2,186],73:[2,186],78:[2,186],86:[2,186],91:[2,186],93:[2,186],102:[2,186],103:84,104:[1,64],105:[2,186],106:[1,65],109:85,110:[1,67],111:68,118:[2,186],126:[2,186],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,104],6:[2,104],25:[2,104],26:[2,104],49:[2,104],54:[2,104],57:[2,104],66:[2,104],67:[2,104],68:[2,104],69:[2,104],71:[2,104],73:[2,104],74:[2,104],78:[2,104],84:[2,104],85:[2,104],86:[2,104],91:[2,104],93:[2,104],102:[2,104],104:[2,104],105:[2,104],106:[2,104],110:[2,104],118:[2,104],126:[2,104],129:[2,104],130:[2,104],133:[2,104],134:[2,104],135:[2,104],136:[2,104],137:[2,104],138:[2,104],139:[2,104]},{1:[2,80],6:[2,80],25:[2,80],26:[2,80],40:[2,80],49:[2,80],54:[2,80],57:[2,80],66:[2,80],67:[2,80],68:[2,80],69:[2,80],71:[2,80],73:[2,80],74:[2,80],78:[2,80],80:[2,80],84:[2,80],85:[2,80],86:[2,80],91:[2,80],93:[2,80],102:[2,80],104:[2,80],105:[2,80],106:[2,80],110:[2,80],118:[2,80],126:[2,80],129:[2,80],130:[2,80],131:[2,80],132:[2,80],133:[2,80],134:[2,80],135:[2,80],136:[2,80],137:[2,80],138:[2,80],139:[2,80],140:[2,80]},{1:[2,81],6:[2,81],25:[2,81],26:[2,81],40:[2,81],49:[2,81],54:[2,81],57:[2,81],66:[2,81],67:[2,81],68:[2,81],69:[2,81],71:[2,81],73:[2,81],74:[2,81],78:[2,81],80:[2,81],84:[2,81],85:[2,81],86:[2,81],91:[2,81],93:[2,81],102:[2,81],104:[2,81],105:[2,81],106:[2,81],110:[2,81],118:[2,81],126:[2,81],129:[2,81],130:[2,81],131:[2,81],132:[2,81],133:[2,81],134:[2,81],135:[2,81],136:[2,81],137:[2,81],138:[2,81],139:[2,81],140:[2,81]},{1:[2,82],6:[2,82],25:[2,82],26:[2,82],40:[2,82],49:[2,82],54:[2,82],57:[2,82],66:[2,82],67:[2,82],68:[2,82],69:[2,82],71:[2,82],73:[2,82],74:[2,82],78:[2,82],80:[2,82],84:[2,82],85:[2,82],86:[2,82],91:[2,82],93:[2,82],102:[2,82],104:[2,82],105:[2,82],106:[2,82],110:[2,82],118:[2,82],126:[2,82],129:[2,82],130:[2,82],131:[2,82],132:[2,82],133:[2,82],134:[2,82],135:[2,82],136:[2,82],137:[2,82],138:[2,82],139:[2,82],140:[2,82]},{1:[2,83],6:[2,83],25:[2,83],26:[2,83],40:[2,83],49:[2,83],54:[2,83],57:[2,83],66:[2,83],67:[2,83],68:[2,83],69:[2,83],71:[2,83],73:[2,83],74:[2,83],78:[2,83],80:[2,83],84:[2,83],85:[2,83],86:[2,83],91:[2,83],93:[2,83],102:[2,83],104:[2,83],105:[2,83],106:[2,83],110:[2,83],118:[2,83],126:[2,83],129:[2,83],130:[2,83],131:[2,83],132:[2,83],133:[2,83],134:[2,83],135:[2,83],136:[2,83],137:[2,83],138:[2,83],139:[2,83],140:[2,83]},{73:[1,244]},{57:[1,195],73:[2,88],92:245,93:[1,194],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{73:[2,89]},{7:246,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,73:[2,123],76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{11:[2,117],28:[2,117],30:[2,117],31:[2,117],33:[2,117],34:[2,117],35:[2,117],36:[2,117],37:[2,117],38:[2,117],45:[2,117],46:[2,117],47:[2,117],51:[2,117],52:[2,117],73:[2,117],76:[2,117],79:[2,117],83:[2,117],88:[2,117],89:[2,117],90:[2,117],96:[2,117],100:[2,117],101:[2,117],104:[2,117],106:[2,117],108:[2,117],110:[2,117],119:[2,117],125:[2,117],127:[2,117],128:[2,117],129:[2,117],130:[2,117],131:[2,117],132:[2,117]},{11:[2,118],28:[2,118],30:[2,118],31:[2,118],33:[2,118],34:[2,118],35:[2,118],36:[2,118],37:[2,118],38:[2,118],45:[2,118],46:[2,118],47:[2,118],51:[2,118],52:[2,118],73:[2,118],76:[2,118],79:[2,118],83:[2,118],88:[2,118],89:[2,118],90:[2,118],96:[2,118],100:[2,118],101:[2,118],104:[2,118],106:[2,118],108:[2,118],110:[2,118],119:[2,118],125:[2,118],127:[2,118],128:[2,118],129:[2,118],130:[2,118],131:[2,118],132:[2,118]},{1:[2,87],6:[2,87],25:[2,87],26:[2,87],40:[2,87],49:[2,87],54:[2,87],57:[2,87],66:[2,87],67:[2,87],68:[2,87],69:[2,87],71:[2,87],73:[2,87],74:[2,87],78:[2,87],80:[2,87],84:[2,87],85:[2,87],86:[2,87],91:[2,87],93:[2,87],102:[2,87],104:[2,87],105:[2,87],106:[2,87],110:[2,87],118:[2,87],126:[2,87],129:[2,87],130:[2,87],131:[2,87],132:[2,87],133:[2,87],134:[2,87],135:[2,87],136:[2,87],137:[2,87],138:[2,87],139:[2,87],140:[2,87]},{1:[2,105],6:[2,105],25:[2,105],26:[2,105],49:[2,105],54:[2,105],57:[2,105],66:[2,105],67:[2,105],68:[2,105],69:[2,105],71:[2,105],73:[2,105],74:[2,105],78:[2,105],84:[2,105],85:[2,105],86:[2,105],91:[2,105],93:[2,105],102:[2,105],104:[2,105],105:[2,105],106:[2,105],110:[2,105],118:[2,105],126:[2,105],129:[2,105],130:[2,105],133:[2,105],134:[2,105],135:[2,105],136:[2,105],137:[2,105],138:[2,105],139:[2,105]},{1:[2,35],6:[2,35],25:[2,35],26:[2,35],49:[2,35],54:[2,35],57:[2,35],73:[2,35],78:[2,35],86:[2,35],91:[2,35],93:[2,35],102:[2,35],103:84,104:[2,35],105:[2,35],106:[2,35],109:85,110:[2,35],111:68,118:[2,35],126:[2,35],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{7:247,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:248,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,110],6:[2,110],25:[2,110],26:[2,110],49:[2,110],54:[2,110],57:[2,110],66:[2,110],67:[2,110],68:[2,110],69:[2,110],71:[2,110],73:[2,110],74:[2,110],78:[2,110],84:[2,110],85:[2,110],86:[2,110],91:[2,110],93:[2,110],102:[2,110],104:[2,110],105:[2,110],106:[2,110],110:[2,110],118:[2,110],126:[2,110],129:[2,110],130:[2,110],133:[2,110],134:[2,110],135:[2,110],136:[2,110],137:[2,110],138:[2,110],139:[2,110]},{6:[2,52],25:[2,52],53:249,54:[1,232],86:[2,52]},{6:[2,129],25:[2,129],26:[2,129],54:[2,129],57:[1,250],86:[2,129],91:[2,129],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{50:251,51:[1,59],52:[1,60]},{6:[2,53],25:[2,53],26:[2,53],27:108,28:[1,72],44:109,55:252,56:106,57:[1,107],58:110,59:111,76:[1,69],89:[1,112],90:[1,113]},{6:[1,253],25:[1,254]},{6:[2,60],25:[2,60],26:[2,60],49:[2,60],54:[2,60]},{7:255,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,23],6:[2,23],25:[2,23],26:[2,23],49:[2,23],54:[2,23],57:[2,23],73:[2,23],78:[2,23],86:[2,23],91:[2,23],93:[2,23],98:[2,23],99:[2,23],102:[2,23],104:[2,23],105:[2,23],106:[2,23],110:[2,23],118:[2,23],121:[2,23],123:[2,23],126:[2,23],129:[2,23],130:[2,23],133:[2,23],134:[2,23],135:[2,23],136:[2,23],137:[2,23],138:[2,23],139:[2,23]},{6:[1,73],26:[1,256]},{1:[2,205],6:[2,205],25:[2,205],26:[2,205],49:[2,205],54:[2,205],57:[2,205],73:[2,205],78:[2,205],86:[2,205],91:[2,205],93:[2,205],102:[2,205],103:84,104:[2,205],105:[2,205],106:[2,205],109:85,110:[2,205],111:68,118:[2,205],126:[2,205],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{7:257,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:258,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,208],6:[2,208],25:[2,208],26:[2,208],49:[2,208],54:[2,208],57:[2,208],73:[2,208],78:[2,208],86:[2,208],91:[2,208],93:[2,208],102:[2,208],103:84,104:[2,208],105:[2,208],106:[2,208],109:85,110:[2,208],111:68,118:[2,208],126:[2,208],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,185],6:[2,185],25:[2,185],26:[2,185],49:[2,185],54:[2,185],57:[2,185],73:[2,185],78:[2,185],86:[2,185],91:[2,185],93:[2,185],102:[2,185],104:[2,185],105:[2,185],106:[2,185],110:[2,185],118:[2,185],126:[2,185],129:[2,185],130:[2,185],133:[2,185],134:[2,185],135:[2,185],136:[2,185],137:[2,185],138:[2,185],139:[2,185]},{7:259,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,135],6:[2,135],25:[2,135],26:[2,135],49:[2,135],54:[2,135],57:[2,135],73:[2,135],78:[2,135],86:[2,135],91:[2,135],93:[2,135],98:[1,260],102:[2,135],104:[2,135],105:[2,135],106:[2,135],110:[2,135],118:[2,135],126:[2,135],129:[2,135],130:[2,135],133:[2,135],134:[2,135],135:[2,135],136:[2,135],137:[2,135],138:[2,135],139:[2,135]},{24:261,25:[1,115]},{24:264,25:[1,115],27:262,28:[1,72],59:263,76:[1,69]},{120:265,122:222,123:[1,223]},{26:[1,266],121:[1,267],122:268,123:[1,223]},{26:[2,178],121:[2,178],123:[2,178]},{7:270,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],95:269,96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,98],6:[2,98],24:271,25:[1,115],26:[2,98],49:[2,98],54:[2,98],57:[2,98],73:[2,98],78:[2,98],86:[2,98],91:[2,98],93:[2,98],102:[2,98],103:84,104:[1,64],105:[2,98],106:[1,65],109:85,110:[1,67],111:68,118:[2,98],126:[2,98],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,101],6:[2,101],25:[2,101],26:[2,101],49:[2,101],54:[2,101],57:[2,101],73:[2,101],78:[2,101],86:[2,101],91:[2,101],93:[2,101],102:[2,101],104:[2,101],105:[2,101],106:[2,101],110:[2,101],118:[2,101],126:[2,101],129:[2,101],130:[2,101],133:[2,101],134:[2,101],135:[2,101],136:[2,101],137:[2,101],138:[2,101],139:[2,101]},{7:272,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,142],6:[2,142],25:[2,142],26:[2,142],49:[2,142],54:[2,142],57:[2,142],66:[2,142],67:[2,142],68:[2,142],69:[2,142],71:[2,142],73:[2,142],74:[2,142],78:[2,142],84:[2,142],85:[2,142],86:[2,142],91:[2,142],93:[2,142],102:[2,142],104:[2,142],105:[2,142],106:[2,142],110:[2,142],118:[2,142],126:[2,142],129:[2,142],130:[2,142],133:[2,142],134:[2,142],135:[2,142],136:[2,142],137:[2,142],138:[2,142],139:[2,142]},{6:[1,73],26:[1,273]},{7:274,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{6:[2,67],11:[2,118],25:[2,67],28:[2,118],30:[2,118],31:[2,118],33:[2,118],34:[2,118],35:[2,118],36:[2,118],37:[2,118],38:[2,118],45:[2,118],46:[2,118],47:[2,118],51:[2,118],52:[2,118],54:[2,67],76:[2,118],79:[2,118],83:[2,118],88:[2,118],89:[2,118],90:[2,118],91:[2,67],96:[2,118],100:[2,118],101:[2,118],104:[2,118],106:[2,118],108:[2,118],110:[2,118],119:[2,118],125:[2,118],127:[2,118],128:[2,118],129:[2,118],130:[2,118],131:[2,118],132:[2,118]},{6:[1,276],25:[1,277],91:[1,275]},{6:[2,53],7:203,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[2,53],26:[2,53],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],57:[1,149],58:46,59:47,60:148,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],86:[2,53],88:[1,57],89:[1,58],90:[1,56],91:[2,53],94:278,96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{6:[2,52],25:[2,52],26:[2,52],53:279,54:[1,232]},{1:[2,182],6:[2,182],25:[2,182],26:[2,182],49:[2,182],54:[2,182],57:[2,182],73:[2,182],78:[2,182],86:[2,182],91:[2,182],93:[2,182],102:[2,182],104:[2,182],105:[2,182],106:[2,182],110:[2,182],118:[2,182],121:[2,182],126:[2,182],129:[2,182],130:[2,182],133:[2,182],134:[2,182],135:[2,182],136:[2,182],137:[2,182],138:[2,182],139:[2,182]},{7:280,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:281,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{116:[2,160],117:[2,160]},{27:160,28:[1,72],44:161,58:162,59:163,76:[1,69],89:[1,112],90:[1,113],115:282},{1:[2,167],6:[2,167],25:[2,167],26:[2,167],49:[2,167],54:[2,167],57:[2,167],73:[2,167],78:[2,167],86:[2,167],91:[2,167],93:[2,167],102:[2,167],103:84,104:[2,167],105:[1,283],106:[2,167],109:85,110:[2,167],111:68,118:[1,284],126:[2,167],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,168],6:[2,168],25:[2,168],26:[2,168],49:[2,168],54:[2,168],57:[2,168],73:[2,168],78:[2,168],86:[2,168],91:[2,168],93:[2,168],102:[2,168],103:84,104:[2,168],105:[1,285],106:[2,168],109:85,110:[2,168],111:68,118:[2,168],126:[2,168],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{6:[1,287],25:[1,288],78:[1,286]},{6:[2,53],10:170,25:[2,53],26:[2,53],27:171,28:[1,72],29:172,30:[1,70],31:[1,71],41:289,42:169,44:173,46:[1,45],78:[2,53],89:[1,112]},{7:290,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,291],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,86],6:[2,86],25:[2,86],26:[2,86],40:[2,86],49:[2,86],54:[2,86],57:[2,86],66:[2,86],67:[2,86],68:[2,86],69:[2,86],71:[2,86],73:[2,86],74:[2,86],78:[2,86],80:[2,86],84:[2,86],85:[2,86],86:[2,86],91:[2,86],93:[2,86],102:[2,86],104:[2,86],105:[2,86],106:[2,86],110:[2,86],118:[2,86],126:[2,86],129:[2,86],130:[2,86],131:[2,86],132:[2,86],133:[2,86],134:[2,86],135:[2,86],136:[2,86],137:[2,86],138:[2,86],139:[2,86],140:[2,86]},{7:292,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,73:[2,121],76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{73:[2,122],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,36],6:[2,36],25:[2,36],26:[2,36],49:[2,36],54:[2,36],57:[2,36],73:[2,36],78:[2,36],86:[2,36],91:[2,36],93:[2,36],102:[2,36],103:84,104:[2,36],105:[2,36],106:[2,36],109:85,110:[2,36],111:68,118:[2,36],126:[2,36],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{26:[1,293],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{6:[1,276],25:[1,277],86:[1,294]},{6:[2,67],25:[2,67],26:[2,67],54:[2,67],86:[2,67],91:[2,67]},{24:295,25:[1,115]},{6:[2,56],25:[2,56],26:[2,56],49:[2,56],54:[2,56]},{27:108,28:[1,72],44:109,55:296,56:106,57:[1,107],58:110,59:111,76:[1,69],89:[1,112],90:[1,113]},{6:[2,54],25:[2,54],26:[2,54],27:108,28:[1,72],44:109,48:297,54:[2,54],55:105,56:106,57:[1,107],58:110,59:111,76:[1,69],89:[1,112],90:[1,113]},{6:[2,61],25:[2,61],26:[2,61],49:[2,61],54:[2,61],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,24],6:[2,24],25:[2,24],26:[2,24],49:[2,24],54:[2,24],57:[2,24],73:[2,24],78:[2,24],86:[2,24],91:[2,24],93:[2,24],98:[2,24],99:[2,24],102:[2,24],104:[2,24],105:[2,24],106:[2,24],110:[2,24],118:[2,24],121:[2,24],123:[2,24],126:[2,24],129:[2,24],130:[2,24],133:[2,24],134:[2,24],135:[2,24],136:[2,24],137:[2,24],138:[2,24],139:[2,24]},{26:[1,298],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,207],6:[2,207],25:[2,207],26:[2,207],49:[2,207],54:[2,207],57:[2,207],73:[2,207],78:[2,207],86:[2,207],91:[2,207],93:[2,207],102:[2,207],103:84,104:[2,207],105:[2,207],106:[2,207],109:85,110:[2,207],111:68,118:[2,207],126:[2,207],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{24:299,25:[1,115],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{24:300,25:[1,115]},{1:[2,136],6:[2,136],25:[2,136],26:[2,136],49:[2,136],54:[2,136],57:[2,136],73:[2,136],78:[2,136],86:[2,136],91:[2,136],93:[2,136],102:[2,136],104:[2,136],105:[2,136],106:[2,136],110:[2,136],118:[2,136],126:[2,136],129:[2,136],130:[2,136],133:[2,136],134:[2,136],135:[2,136],136:[2,136],137:[2,136],138:[2,136],139:[2,136]},{24:301,25:[1,115]},{24:302,25:[1,115]},{1:[2,140],6:[2,140],25:[2,140],26:[2,140],49:[2,140],54:[2,140],57:[2,140],73:[2,140],78:[2,140],86:[2,140],91:[2,140],93:[2,140],98:[2,140],102:[2,140],104:[2,140],105:[2,140],106:[2,140],110:[2,140],118:[2,140],126:[2,140],129:[2,140],130:[2,140],133:[2,140],134:[2,140],135:[2,140],136:[2,140],137:[2,140],138:[2,140],139:[2,140]},{26:[1,303],121:[1,304],122:268,123:[1,223]},{1:[2,176],6:[2,176],25:[2,176],26:[2,176],49:[2,176],54:[2,176],57:[2,176],73:[2,176],78:[2,176],86:[2,176],91:[2,176],93:[2,176],102:[2,176],104:[2,176],105:[2,176],106:[2,176],110:[2,176],118:[2,176],126:[2,176],129:[2,176],130:[2,176],133:[2,176],134:[2,176],135:[2,176],136:[2,176],137:[2,176],138:[2,176],139:[2,176]},{24:305,25:[1,115]},{26:[2,179],121:[2,179],123:[2,179]},{24:306,25:[1,115],54:[1,307]},{25:[2,132],54:[2,132],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,99],6:[2,99],25:[2,99],26:[2,99],49:[2,99],54:[2,99],57:[2,99],73:[2,99],78:[2,99],86:[2,99],91:[2,99],93:[2,99],102:[2,99],104:[2,99],105:[2,99],106:[2,99],110:[2,99],118:[2,99],126:[2,99],129:[2,99],130:[2,99],133:[2,99],134:[2,99],135:[2,99],136:[2,99],137:[2,99],138:[2,99],139:[2,99]},{1:[2,102],6:[2,102],24:308,25:[1,115],26:[2,102],49:[2,102],54:[2,102],57:[2,102],73:[2,102],78:[2,102],86:[2,102],91:[2,102],93:[2,102],102:[2,102],103:84,104:[1,64],105:[2,102],106:[1,65],109:85,110:[1,67],111:68,118:[2,102],126:[2,102],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{102:[1,309]},{91:[1,310],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,116],6:[2,116],25:[2,116],26:[2,116],40:[2,116],49:[2,116],54:[2,116],57:[2,116],66:[2,116],67:[2,116],68:[2,116],69:[2,116],71:[2,116],73:[2,116],74:[2,116],78:[2,116],84:[2,116],85:[2,116],86:[2,116],91:[2,116],93:[2,116],102:[2,116],104:[2,116],105:[2,116],106:[2,116],110:[2,116],116:[2,116],117:[2,116],118:[2,116],126:[2,116],129:[2,116],130:[2,116],133:[2,116],134:[2,116],135:[2,116],136:[2,116],137:[2,116],138:[2,116],139:[2,116]},{7:203,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],57:[1,149],58:46,59:47,60:148,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],94:311,96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:203,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,147],27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],57:[1,149],58:46,59:47,60:148,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],87:312,88:[1,57],89:[1,58],90:[1,56],94:146,96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{6:[2,125],25:[2,125],26:[2,125],54:[2,125],86:[2,125],91:[2,125]},{6:[1,276],25:[1,277],26:[1,313]},{1:[2,145],6:[2,145],25:[2,145],26:[2,145],49:[2,145],54:[2,145],57:[2,145],73:[2,145],78:[2,145],86:[2,145],91:[2,145],93:[2,145],102:[2,145],103:84,104:[1,64],105:[2,145],106:[1,65],109:85,110:[1,67],111:68,118:[2,145],126:[2,145],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,147],6:[2,147],25:[2,147],26:[2,147],49:[2,147],54:[2,147],57:[2,147],73:[2,147],78:[2,147],86:[2,147],91:[2,147],93:[2,147],102:[2,147],103:84,104:[1,64],105:[2,147],106:[1,65],109:85,110:[1,67],111:68,118:[2,147],126:[2,147],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{116:[2,166],117:[2,166]},{7:314,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:315,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:316,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,90],6:[2,90],25:[2,90],26:[2,90],40:[2,90],49:[2,90],54:[2,90],57:[2,90],66:[2,90],67:[2,90],68:[2,90],69:[2,90],71:[2,90],73:[2,90],74:[2,90],78:[2,90],84:[2,90],85:[2,90],86:[2,90],91:[2,90],93:[2,90],102:[2,90],104:[2,90],105:[2,90],106:[2,90],110:[2,90],116:[2,90],117:[2,90],118:[2,90],126:[2,90],129:[2,90],130:[2,90],133:[2,90],134:[2,90],135:[2,90],136:[2,90],137:[2,90],138:[2,90],139:[2,90]},{10:170,27:171,28:[1,72],29:172,30:[1,70],31:[1,71],41:317,42:169,44:173,46:[1,45],89:[1,112]},{6:[2,91],10:170,25:[2,91],26:[2,91],27:171,28:[1,72],29:172,30:[1,70],31:[1,71],41:168,42:169,44:173,46:[1,45],54:[2,91],77:318,89:[1,112]},{6:[2,93],25:[2,93],26:[2,93],54:[2,93],78:[2,93]},{6:[2,39],25:[2,39],26:[2,39],54:[2,39],78:[2,39],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{7:319,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{73:[2,120],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,37],6:[2,37],25:[2,37],26:[2,37],49:[2,37],54:[2,37],57:[2,37],73:[2,37],78:[2,37],86:[2,37],91:[2,37],93:[2,37],102:[2,37],104:[2,37],105:[2,37],106:[2,37],110:[2,37],118:[2,37],126:[2,37],129:[2,37],130:[2,37],133:[2,37],134:[2,37],135:[2,37],136:[2,37],137:[2,37],138:[2,37],139:[2,37]},{1:[2,111],6:[2,111],25:[2,111],26:[2,111],49:[2,111],54:[2,111],57:[2,111],66:[2,111],67:[2,111],68:[2,111],69:[2,111],71:[2,111],73:[2,111],74:[2,111],78:[2,111],84:[2,111],85:[2,111],86:[2,111],91:[2,111],93:[2,111],102:[2,111],104:[2,111],105:[2,111],106:[2,111],110:[2,111],118:[2,111],126:[2,111],129:[2,111],130:[2,111],133:[2,111],134:[2,111],135:[2,111],136:[2,111],137:[2,111],138:[2,111],139:[2,111]},{1:[2,48],6:[2,48],25:[2,48],26:[2,48],49:[2,48],54:[2,48],57:[2,48],73:[2,48],78:[2,48],86:[2,48],91:[2,48],93:[2,48],102:[2,48],104:[2,48],105:[2,48],106:[2,48],110:[2,48],118:[2,48],126:[2,48],129:[2,48],130:[2,48],133:[2,48],134:[2,48],135:[2,48],136:[2,48],137:[2,48],138:[2,48],139:[2,48]},{6:[2,57],25:[2,57],26:[2,57],49:[2,57],54:[2,57]},{6:[2,52],25:[2,52],26:[2,52],53:320,54:[1,205]},{1:[2,206],6:[2,206],25:[2,206],26:[2,206],49:[2,206],54:[2,206],57:[2,206],73:[2,206],78:[2,206],86:[2,206],91:[2,206],93:[2,206],102:[2,206],104:[2,206],105:[2,206],106:[2,206],110:[2,206],118:[2,206],126:[2,206],129:[2,206],130:[2,206],133:[2,206],134:[2,206],135:[2,206],136:[2,206],137:[2,206],138:[2,206],139:[2,206]},{1:[2,183],6:[2,183],25:[2,183],26:[2,183],49:[2,183],54:[2,183],57:[2,183],73:[2,183],78:[2,183],86:[2,183],91:[2,183],93:[2,183],102:[2,183],104:[2,183],105:[2,183],106:[2,183],110:[2,183],118:[2,183],121:[2,183],126:[2,183],129:[2,183],130:[2,183],133:[2,183],134:[2,183],135:[2,183],136:[2,183],137:[2,183],138:[2,183],139:[2,183]},{1:[2,137],6:[2,137],25:[2,137],26:[2,137],49:[2,137],54:[2,137],57:[2,137],73:[2,137],78:[2,137],86:[2,137],91:[2,137],93:[2,137],102:[2,137],104:[2,137],105:[2,137],106:[2,137],110:[2,137],118:[2,137],126:[2,137],129:[2,137],130:[2,137],133:[2,137],134:[2,137],135:[2,137],136:[2,137],137:[2,137],138:[2,137],139:[2,137]},{1:[2,138],6:[2,138],25:[2,138],26:[2,138],49:[2,138],54:[2,138],57:[2,138],73:[2,138],78:[2,138],86:[2,138],91:[2,138],93:[2,138],98:[2,138],102:[2,138],104:[2,138],105:[2,138],106:[2,138],110:[2,138],118:[2,138],126:[2,138],129:[2,138],130:[2,138],133:[2,138],134:[2,138],135:[2,138],136:[2,138],137:[2,138],138:[2,138],139:[2,138]},{1:[2,139],6:[2,139],25:[2,139],26:[2,139],49:[2,139],54:[2,139],57:[2,139],73:[2,139],78:[2,139],86:[2,139],91:[2,139],93:[2,139],98:[2,139],102:[2,139],104:[2,139],105:[2,139],106:[2,139],110:[2,139],118:[2,139],126:[2,139],129:[2,139],130:[2,139],133:[2,139],134:[2,139],135:[2,139],136:[2,139],137:[2,139],138:[2,139],139:[2,139]},{1:[2,174],6:[2,174],25:[2,174],26:[2,174],49:[2,174],54:[2,174],57:[2,174],73:[2,174],78:[2,174],86:[2,174],91:[2,174],93:[2,174],102:[2,174],104:[2,174],105:[2,174],106:[2,174],110:[2,174],118:[2,174],126:[2,174],129:[2,174],130:[2,174],133:[2,174],134:[2,174],135:[2,174],136:[2,174],137:[2,174],138:[2,174],139:[2,174]},{24:321,25:[1,115]},{26:[1,322]},{6:[1,323],26:[2,180],121:[2,180],123:[2,180]},{7:324,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{1:[2,103],6:[2,103],25:[2,103],26:[2,103],49:[2,103],54:[2,103],57:[2,103],73:[2,103],78:[2,103],86:[2,103],91:[2,103],93:[2,103],102:[2,103],104:[2,103],105:[2,103],106:[2,103],110:[2,103],118:[2,103],126:[2,103],129:[2,103],130:[2,103],133:[2,103],134:[2,103],135:[2,103],136:[2,103],137:[2,103],138:[2,103],139:[2,103]},{1:[2,143],6:[2,143],25:[2,143],26:[2,143],49:[2,143],54:[2,143],57:[2,143],66:[2,143],67:[2,143],68:[2,143],69:[2,143],71:[2,143],73:[2,143],74:[2,143],78:[2,143],84:[2,143],85:[2,143],86:[2,143],91:[2,143],93:[2,143],102:[2,143],104:[2,143],105:[2,143],106:[2,143],110:[2,143],118:[2,143],126:[2,143],129:[2,143],130:[2,143],133:[2,143],134:[2,143],135:[2,143],136:[2,143],137:[2,143],138:[2,143],139:[2,143]},{1:[2,119],6:[2,119],25:[2,119],26:[2,119],49:[2,119],54:[2,119],57:[2,119],66:[2,119],67:[2,119],68:[2,119],69:[2,119],71:[2,119],73:[2,119],74:[2,119],78:[2,119],84:[2,119],85:[2,119],86:[2,119],91:[2,119],93:[2,119],102:[2,119],104:[2,119],105:[2,119],106:[2,119],110:[2,119],118:[2,119],126:[2,119],129:[2,119],130:[2,119],133:[2,119],134:[2,119],135:[2,119],136:[2,119],137:[2,119],138:[2,119],139:[2,119]},{6:[2,126],25:[2,126],26:[2,126],54:[2,126],86:[2,126],91:[2,126]},{6:[2,52],25:[2,52],26:[2,52],53:325,54:[1,232]},{6:[2,127],25:[2,127],26:[2,127],54:[2,127],86:[2,127],91:[2,127]},{1:[2,169],6:[2,169],25:[2,169],26:[2,169],49:[2,169],54:[2,169],57:[2,169],73:[2,169],78:[2,169],86:[2,169],91:[2,169],93:[2,169],102:[2,169],103:84,104:[2,169],105:[2,169],106:[2,169],109:85,110:[2,169],111:68,118:[1,326],126:[2,169],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,171],6:[2,171],25:[2,171],26:[2,171],49:[2,171],54:[2,171],57:[2,171],73:[2,171],78:[2,171],86:[2,171],91:[2,171],93:[2,171],102:[2,171],103:84,104:[2,171],105:[1,327],106:[2,171],109:85,110:[2,171],111:68,118:[2,171],126:[2,171],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,170],6:[2,170],25:[2,170],26:[2,170],49:[2,170],54:[2,170],57:[2,170],73:[2,170],78:[2,170],86:[2,170],91:[2,170],93:[2,170],102:[2,170],103:84,104:[2,170],105:[2,170],106:[2,170],109:85,110:[2,170],111:68,118:[2,170],126:[2,170],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{6:[2,94],25:[2,94],26:[2,94],54:[2,94],78:[2,94]},{6:[2,52],25:[2,52],26:[2,52],53:328,54:[1,242]},{26:[1,329],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{6:[1,253],25:[1,254],26:[1,330]},{26:[1,331]},{1:[2,177],6:[2,177],25:[2,177],26:[2,177],49:[2,177],54:[2,177],57:[2,177],73:[2,177],78:[2,177],86:[2,177],91:[2,177],93:[2,177],102:[2,177],104:[2,177],105:[2,177],106:[2,177],110:[2,177],118:[2,177],126:[2,177],129:[2,177],130:[2,177],133:[2,177],134:[2,177],135:[2,177],136:[2,177],137:[2,177],138:[2,177],139:[2,177]},{26:[2,181],121:[2,181],123:[2,181]},{25:[2,133],54:[2,133],103:84,104:[1,64],106:[1,65],109:85,110:[1,67],111:68,126:[1,83],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{6:[1,276],25:[1,277],26:[1,332]},{7:333,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{7:334,8:117,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:61,28:[1,72],29:48,30:[1,70],31:[1,71],32:22,33:[1,49],34:[1,50],35:[1,51],36:[1,52],37:[1,53],38:[1,54],39:21,44:62,45:[1,44],46:[1,45],47:[1,27],50:28,51:[1,59],52:[1,60],58:46,59:47,61:35,63:23,64:24,65:25,76:[1,69],79:[1,42],83:[1,26],88:[1,57],89:[1,58],90:[1,56],96:[1,37],100:[1,43],101:[1,55],103:38,104:[1,64],106:[1,65],107:39,108:[1,66],109:40,110:[1,67],111:68,119:[1,41],124:36,125:[1,63],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33],132:[1,34]},{6:[1,287],25:[1,288],26:[1,335]},{6:[2,40],25:[2,40],26:[2,40],54:[2,40],78:[2,40]},{6:[2,58],25:[2,58],26:[2,58],49:[2,58],54:[2,58]},{1:[2,175],6:[2,175],25:[2,175],26:[2,175],49:[2,175],54:[2,175],57:[2,175],73:[2,175],78:[2,175],86:[2,175],91:[2,175],93:[2,175],102:[2,175],104:[2,175],105:[2,175],106:[2,175],110:[2,175],118:[2,175],126:[2,175],129:[2,175],130:[2,175],133:[2,175],134:[2,175],135:[2,175],136:[2,175],137:[2,175],138:[2,175],139:[2,175]},{6:[2,128],25:[2,128],26:[2,128],54:[2,128],86:[2,128],91:[2,128]},{1:[2,172],6:[2,172],25:[2,172],26:[2,172],49:[2,172],54:[2,172],57:[2,172],73:[2,172],78:[2,172],86:[2,172],91:[2,172],93:[2,172],102:[2,172],103:84,104:[2,172],105:[2,172],106:[2,172],109:85,110:[2,172],111:68,118:[2,172],126:[2,172],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{1:[2,173],6:[2,173],25:[2,173],26:[2,173],49:[2,173],54:[2,173],57:[2,173],73:[2,173],78:[2,173],86:[2,173],91:[2,173],93:[2,173],102:[2,173],103:84,104:[2,173],105:[2,173],106:[2,173],109:85,110:[2,173],111:68,118:[2,173],126:[2,173],129:[1,76],130:[1,75],133:[1,74],134:[1,77],135:[1,78],136:[1,79],137:[1,80],138:[1,81],139:[1,82]},{6:[2,95],25:[2,95],26:[2,95],54:[2,95],78:[2,95]}],
|
||
defaultActions: {59:[2,50],60:[2,51],91:[2,109],192:[2,89]},
|
||
parseError: function parseError(str, hash) {
|
||
if (hash.recoverable) {
|
||
this.trace(str);
|
||
} else {
|
||
throw new Error(str);
|
||
}
|
||
},
|
||
parse: function parse(input) {
|
||
var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
|
||
var args = lstack.slice.call(arguments, 1);
|
||
this.lexer.setInput(input);
|
||
this.lexer.yy = this.yy;
|
||
this.yy.lexer = this.lexer;
|
||
this.yy.parser = this;
|
||
if (typeof this.lexer.yylloc == 'undefined') {
|
||
this.lexer.yylloc = {};
|
||
}
|
||
var yyloc = this.lexer.yylloc;
|
||
lstack.push(yyloc);
|
||
var ranges = this.lexer.options && this.lexer.options.ranges;
|
||
if (typeof this.yy.parseError === 'function') {
|
||
this.parseError = this.yy.parseError;
|
||
} else {
|
||
this.parseError = Object.getPrototypeOf(this).parseError;
|
||
}
|
||
function popStack(n) {
|
||
stack.length = stack.length - 2 * n;
|
||
vstack.length = vstack.length - n;
|
||
lstack.length = lstack.length - n;
|
||
}
|
||
function lex() {
|
||
var token;
|
||
token = self.lexer.lex() || EOF;
|
||
if (typeof token !== 'number') {
|
||
token = self.symbols_[token] || token;
|
||
}
|
||
return token;
|
||
}
|
||
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
|
||
while (true) {
|
||
state = stack[stack.length - 1];
|
||
if (this.defaultActions[state]) {
|
||
action = this.defaultActions[state];
|
||
} else {
|
||
if (symbol === null || typeof symbol == 'undefined') {
|
||
symbol = lex();
|
||
}
|
||
action = table[state] && table[state][symbol];
|
||
}
|
||
if (typeof action === 'undefined' || !action.length || !action[0]) {
|
||
var errStr = '';
|
||
expected = [];
|
||
for (p in table[state]) {
|
||
if (this.terminals_[p] && p > TERROR) {
|
||
expected.push('\'' + this.terminals_[p] + '\'');
|
||
}
|
||
}
|
||
if (this.lexer.showPosition) {
|
||
errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + this.lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
|
||
} else {
|
||
errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
|
||
}
|
||
this.parseError(errStr, {
|
||
text: this.lexer.match,
|
||
token: this.terminals_[symbol] || symbol,
|
||
line: this.lexer.yylineno,
|
||
loc: yyloc,
|
||
expected: expected
|
||
});
|
||
}
|
||
if (action[0] instanceof Array && action.length > 1) {
|
||
throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
|
||
}
|
||
switch (action[0]) {
|
||
case 1:
|
||
stack.push(symbol);
|
||
vstack.push(this.lexer.yytext);
|
||
lstack.push(this.lexer.yylloc);
|
||
stack.push(action[1]);
|
||
symbol = null;
|
||
if (!preErrorSymbol) {
|
||
yyleng = this.lexer.yyleng;
|
||
yytext = this.lexer.yytext;
|
||
yylineno = this.lexer.yylineno;
|
||
yyloc = this.lexer.yylloc;
|
||
if (recovering > 0) {
|
||
recovering--;
|
||
}
|
||
} else {
|
||
symbol = preErrorSymbol;
|
||
preErrorSymbol = null;
|
||
}
|
||
break;
|
||
case 2:
|
||
len = this.productions_[action[1]][1];
|
||
yyval.$ = vstack[vstack.length - len];
|
||
yyval._$ = {
|
||
first_line: lstack[lstack.length - (len || 1)].first_line,
|
||
last_line: lstack[lstack.length - 1].last_line,
|
||
first_column: lstack[lstack.length - (len || 1)].first_column,
|
||
last_column: lstack[lstack.length - 1].last_column
|
||
};
|
||
if (ranges) {
|
||
yyval._$.range = [
|
||
lstack[lstack.length - (len || 1)].range[0],
|
||
lstack[lstack.length - 1].range[1]
|
||
];
|
||
}
|
||
r = this.performAction.apply(yyval, [
|
||
yytext,
|
||
yyleng,
|
||
yylineno,
|
||
this.yy,
|
||
action[1],
|
||
vstack,
|
||
lstack
|
||
].concat(args));
|
||
if (typeof r !== 'undefined') {
|
||
return r;
|
||
}
|
||
if (len) {
|
||
stack = stack.slice(0, -1 * len * 2);
|
||
vstack = vstack.slice(0, -1 * len);
|
||
lstack = lstack.slice(0, -1 * len);
|
||
}
|
||
stack.push(this.productions_[action[1]][0]);
|
||
vstack.push(yyval.$);
|
||
lstack.push(yyval._$);
|
||
newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
|
||
stack.push(newState);
|
||
break;
|
||
case 3:
|
||
return true;
|
||
}
|
||
}
|
||
return true;
|
||
}};
|
||
|
||
function Parser () {
|
||
this.yy = {};
|
||
}
|
||
Parser.prototype = parser;parser.Parser = Parser;
|
||
return new Parser;
|
||
})();
|
||
|
||
|
||
if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
|
||
exports.parser = parser;
|
||
exports.Parser = parser.Parser;
|
||
exports.parse = function () { return parser.parse.apply(parser, arguments); };
|
||
exports.main = function commonjsMain(args) {
|
||
if (!args[1]) {
|
||
console.log('Usage: '+args[0]+' FILE');
|
||
process.exit(1);
|
||
}
|
||
var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
|
||
return exports.parser.parse(source);
|
||
};
|
||
if (typeof module !== 'undefined' && require.main === module) {
|
||
exports.main(process.argv.slice(1));
|
||
}
|
||
}
|
||
}).call(this,require("1YiZ5S"))
|
||
},{"1YiZ5S":62,"fs":56,"path":61}],52:[function(require,module,exports){
|
||
// Generated by CoffeeScript 1.8.0
|
||
(function() {
|
||
var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, helpers, loadFile, path, _i, _len, _ref;
|
||
|
||
CoffeeScript = require('./coffee-script');
|
||
|
||
child_process = require('child_process');
|
||
|
||
helpers = require('./helpers');
|
||
|
||
path = require('path');
|
||
|
||
loadFile = function(module, filename) {
|
||
var answer;
|
||
answer = CoffeeScript._compileFile(filename, false);
|
||
return module._compile(answer, filename);
|
||
};
|
||
|
||
if (require.extensions) {
|
||
_ref = CoffeeScript.FILE_EXTENSIONS;
|
||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||
ext = _ref[_i];
|
||
require.extensions[ext] = loadFile;
|
||
}
|
||
Module = require('module');
|
||
findExtension = function(filename) {
|
||
var curExtension, extensions;
|
||
extensions = path.basename(filename).split('.');
|
||
if (extensions[0] === '') {
|
||
extensions.shift();
|
||
}
|
||
while (extensions.shift()) {
|
||
curExtension = '.' + extensions.join('.');
|
||
if (Module._extensions[curExtension]) {
|
||
return curExtension;
|
||
}
|
||
}
|
||
return '.js';
|
||
};
|
||
Module.prototype.load = function(filename) {
|
||
var extension;
|
||
this.filename = filename;
|
||
this.paths = Module._nodeModulePaths(path.dirname(filename));
|
||
extension = findExtension(filename);
|
||
Module._extensions[extension](this, filename);
|
||
return this.loaded = true;
|
||
};
|
||
}
|
||
|
||
if (child_process) {
|
||
fork = child_process.fork;
|
||
binary = require.resolve('../../bin/coffee');
|
||
child_process.fork = function(path, args, options) {
|
||
if (helpers.isCoffee(path)) {
|
||
if (!Array.isArray(args)) {
|
||
options = args || {};
|
||
args = [];
|
||
}
|
||
args = [path].concat(args);
|
||
path = binary;
|
||
}
|
||
return fork(path, args, options);
|
||
};
|
||
}
|
||
|
||
}).call(this);
|
||
|
||
},{"./coffee-script":47,"./helpers":48,"child_process":56,"module":56,"path":61}],53:[function(require,module,exports){
|
||
// Generated by CoffeeScript 1.8.0
|
||
(function() {
|
||
var BALANCED_PAIRS, CALL_CLOSERS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, generate, left, rite, _i, _len, _ref,
|
||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
||
__slice = [].slice;
|
||
|
||
generate = function(tag, value, origin) {
|
||
var tok;
|
||
tok = [tag, value];
|
||
tok.generated = true;
|
||
if (origin) {
|
||
tok.origin = origin;
|
||
}
|
||
return tok;
|
||
};
|
||
|
||
exports.Rewriter = (function() {
|
||
function Rewriter() {}
|
||
|
||
Rewriter.prototype.rewrite = function(tokens) {
|
||
this.tokens = tokens;
|
||
this.removeLeadingNewlines();
|
||
this.closeOpenCalls();
|
||
this.closeOpenIndexes();
|
||
this.normalizeLines();
|
||
this.tagPostfixConditionals();
|
||
this.addImplicitBracesAndParens();
|
||
this.addLocationDataToGeneratedTokens();
|
||
return this.tokens;
|
||
};
|
||
|
||
Rewriter.prototype.scanTokens = function(block) {
|
||
var i, token, tokens;
|
||
tokens = this.tokens;
|
||
i = 0;
|
||
while (token = tokens[i]) {
|
||
i += block.call(this, token, i, tokens);
|
||
}
|
||
return true;
|
||
};
|
||
|
||
Rewriter.prototype.detectEnd = function(i, condition, action) {
|
||
var levels, token, tokens, _ref, _ref1;
|
||
tokens = this.tokens;
|
||
levels = 0;
|
||
while (token = tokens[i]) {
|
||
if (levels === 0 && condition.call(this, token, i)) {
|
||
return action.call(this, token, i);
|
||
}
|
||
if (!token || levels < 0) {
|
||
return action.call(this, token, i - 1);
|
||
}
|
||
if (_ref = token[0], __indexOf.call(EXPRESSION_START, _ref) >= 0) {
|
||
levels += 1;
|
||
} else if (_ref1 = token[0], __indexOf.call(EXPRESSION_END, _ref1) >= 0) {
|
||
levels -= 1;
|
||
}
|
||
i += 1;
|
||
}
|
||
return i - 1;
|
||
};
|
||
|
||
Rewriter.prototype.removeLeadingNewlines = function() {
|
||
var i, tag, _i, _len, _ref;
|
||
_ref = this.tokens;
|
||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
||
tag = _ref[i][0];
|
||
if (tag !== 'TERMINATOR') {
|
||
break;
|
||
}
|
||
}
|
||
if (i) {
|
||
return this.tokens.splice(0, i);
|
||
}
|
||
};
|
||
|
||
Rewriter.prototype.closeOpenCalls = function() {
|
||
var action, condition;
|
||
condition = function(token, i) {
|
||
var _ref;
|
||
return ((_ref = token[0]) === ')' || _ref === 'CALL_END') || token[0] === 'OUTDENT' && this.tag(i - 1) === ')';
|
||
};
|
||
action = function(token, i) {
|
||
return this.tokens[token[0] === 'OUTDENT' ? i - 1 : i][0] = 'CALL_END';
|
||
};
|
||
return this.scanTokens(function(token, i) {
|
||
if (token[0] === 'CALL_START') {
|
||
this.detectEnd(i + 1, condition, action);
|
||
}
|
||
return 1;
|
||
});
|
||
};
|
||
|
||
Rewriter.prototype.closeOpenIndexes = function() {
|
||
var action, condition;
|
||
condition = function(token, i) {
|
||
var _ref;
|
||
return (_ref = token[0]) === ']' || _ref === 'INDEX_END';
|
||
};
|
||
action = function(token, i) {
|
||
return token[0] = 'INDEX_END';
|
||
};
|
||
return this.scanTokens(function(token, i) {
|
||
if (token[0] === 'INDEX_START') {
|
||
this.detectEnd(i + 1, condition, action);
|
||
}
|
||
return 1;
|
||
});
|
||
};
|
||
|
||
Rewriter.prototype.matchTags = function() {
|
||
var fuzz, i, j, pattern, _i, _ref, _ref1;
|
||
i = arguments[0], pattern = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
||
fuzz = 0;
|
||
for (j = _i = 0, _ref = pattern.length; 0 <= _ref ? _i < _ref : _i > _ref; j = 0 <= _ref ? ++_i : --_i) {
|
||
while (this.tag(i + j + fuzz) === 'HERECOMMENT') {
|
||
fuzz += 2;
|
||
}
|
||
if (pattern[j] == null) {
|
||
continue;
|
||
}
|
||
if (typeof pattern[j] === 'string') {
|
||
pattern[j] = [pattern[j]];
|
||
}
|
||
if (_ref1 = this.tag(i + j + fuzz), __indexOf.call(pattern[j], _ref1) < 0) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
};
|
||
|
||
Rewriter.prototype.looksObjectish = function(j) {
|
||
return this.matchTags(j, '@', null, ':') || this.matchTags(j, null, ':');
|
||
};
|
||
|
||
Rewriter.prototype.findTagsBackwards = function(i, tags) {
|
||
var backStack, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
|
||
backStack = [];
|
||
while (i >= 0 && (backStack.length || (_ref2 = this.tag(i), __indexOf.call(tags, _ref2) < 0) && ((_ref3 = this.tag(i), __indexOf.call(EXPRESSION_START, _ref3) < 0) || this.tokens[i].generated) && (_ref4 = this.tag(i), __indexOf.call(LINEBREAKS, _ref4) < 0))) {
|
||
if (_ref = this.tag(i), __indexOf.call(EXPRESSION_END, _ref) >= 0) {
|
||
backStack.push(this.tag(i));
|
||
}
|
||
if ((_ref1 = this.tag(i), __indexOf.call(EXPRESSION_START, _ref1) >= 0) && backStack.length) {
|
||
backStack.pop();
|
||
}
|
||
i -= 1;
|
||
}
|
||
return _ref5 = this.tag(i), __indexOf.call(tags, _ref5) >= 0;
|
||
};
|
||
|
||
Rewriter.prototype.addImplicitBracesAndParens = function() {
|
||
var stack;
|
||
stack = [];
|
||
return this.scanTokens(function(token, i, tokens) {
|
||
var endImplicitCall, endImplicitObject, forward, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, newLine, nextTag, offset, prevTag, prevToken, s, sameLine, stackIdx, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
|
||
tag = token[0];
|
||
prevTag = (prevToken = i > 0 ? tokens[i - 1] : [])[0];
|
||
nextTag = (i < tokens.length - 1 ? tokens[i + 1] : [])[0];
|
||
stackTop = function() {
|
||
return stack[stack.length - 1];
|
||
};
|
||
startIdx = i;
|
||
forward = function(n) {
|
||
return i - startIdx + n;
|
||
};
|
||
inImplicit = function() {
|
||
var _ref, _ref1;
|
||
return (_ref = stackTop()) != null ? (_ref1 = _ref[2]) != null ? _ref1.ours : void 0 : void 0;
|
||
};
|
||
inImplicitCall = function() {
|
||
var _ref;
|
||
return inImplicit() && ((_ref = stackTop()) != null ? _ref[0] : void 0) === '(';
|
||
};
|
||
inImplicitObject = function() {
|
||
var _ref;
|
||
return inImplicit() && ((_ref = stackTop()) != null ? _ref[0] : void 0) === '{';
|
||
};
|
||
inImplicitControl = function() {
|
||
var _ref;
|
||
return inImplicit && ((_ref = stackTop()) != null ? _ref[0] : void 0) === 'CONTROL';
|
||
};
|
||
startImplicitCall = function(j) {
|
||
var idx;
|
||
idx = j != null ? j : i;
|
||
stack.push([
|
||
'(', idx, {
|
||
ours: true
|
||
}
|
||
]);
|
||
tokens.splice(idx, 0, generate('CALL_START', '('));
|
||
if (j == null) {
|
||
return i += 1;
|
||
}
|
||
};
|
||
endImplicitCall = function() {
|
||
stack.pop();
|
||
tokens.splice(i, 0, generate('CALL_END', ')'));
|
||
return i += 1;
|
||
};
|
||
startImplicitObject = function(j, startsLine) {
|
||
var idx;
|
||
if (startsLine == null) {
|
||
startsLine = true;
|
||
}
|
||
idx = j != null ? j : i;
|
||
stack.push([
|
||
'{', idx, {
|
||
sameLine: true,
|
||
startsLine: startsLine,
|
||
ours: true
|
||
}
|
||
]);
|
||
tokens.splice(idx, 0, generate('{', generate(new String('{')), token));
|
||
if (j == null) {
|
||
return i += 1;
|
||
}
|
||
};
|
||
endImplicitObject = function(j) {
|
||
j = j != null ? j : i;
|
||
stack.pop();
|
||
tokens.splice(j, 0, generate('}', '}', token));
|
||
return i += 1;
|
||
};
|
||
if (inImplicitCall() && (tag === 'IF' || tag === 'TRY' || tag === 'FINALLY' || tag === 'CATCH' || tag === 'CLASS' || tag === 'SWITCH')) {
|
||
stack.push([
|
||
'CONTROL', i, {
|
||
ours: true
|
||
}
|
||
]);
|
||
return forward(1);
|
||
}
|
||
if (tag === 'INDENT' && inImplicit()) {
|
||
if (prevTag !== '=>' && prevTag !== '->' && prevTag !== '[' && prevTag !== '(' && prevTag !== ',' && prevTag !== '{' && prevTag !== 'TRY' && prevTag !== 'ELSE' && prevTag !== '=') {
|
||
while (inImplicitCall()) {
|
||
endImplicitCall();
|
||
}
|
||
}
|
||
if (inImplicitControl()) {
|
||
stack.pop();
|
||
}
|
||
stack.push([tag, i]);
|
||
return forward(1);
|
||
}
|
||
if (__indexOf.call(EXPRESSION_START, tag) >= 0) {
|
||
stack.push([tag, i]);
|
||
return forward(1);
|
||
}
|
||
if (__indexOf.call(EXPRESSION_END, tag) >= 0) {
|
||
while (inImplicit()) {
|
||
if (inImplicitCall()) {
|
||
endImplicitCall();
|
||
} else if (inImplicitObject()) {
|
||
endImplicitObject();
|
||
} else {
|
||
stack.pop();
|
||
}
|
||
}
|
||
stack.pop();
|
||
}
|
||
if ((__indexOf.call(IMPLICIT_FUNC, tag) >= 0 && token.spaced && !token.stringEnd || tag === '?' && i > 0 && !tokens[i - 1].spaced) && (__indexOf.call(IMPLICIT_CALL, nextTag) >= 0 || __indexOf.call(IMPLICIT_UNSPACED_CALL, nextTag) >= 0 && !((_ref = tokens[i + 1]) != null ? _ref.spaced : void 0) && !((_ref1 = tokens[i + 1]) != null ? _ref1.newLine : void 0))) {
|
||
if (tag === '?') {
|
||
tag = token[0] = 'FUNC_EXIST';
|
||
}
|
||
startImplicitCall(i + 1);
|
||
return forward(2);
|
||
}
|
||
if (__indexOf.call(IMPLICIT_FUNC, tag) >= 0 && this.matchTags(i + 1, 'INDENT', null, ':') && !this.findTagsBackwards(i, ['CLASS', 'EXTENDS', 'IF', 'CATCH', 'SWITCH', 'LEADING_WHEN', 'FOR', 'WHILE', 'UNTIL'])) {
|
||
startImplicitCall(i + 1);
|
||
stack.push(['INDENT', i + 2]);
|
||
return forward(3);
|
||
}
|
||
if (tag === ':') {
|
||
if (this.tag(i - 2) === '@') {
|
||
s = i - 2;
|
||
} else {
|
||
s = i - 1;
|
||
}
|
||
while (this.tag(s - 2) === 'HERECOMMENT') {
|
||
s -= 2;
|
||
}
|
||
this.insideForDeclaration = nextTag === 'FOR';
|
||
startsLine = s === 0 || (_ref2 = this.tag(s - 1), __indexOf.call(LINEBREAKS, _ref2) >= 0) || tokens[s - 1].newLine;
|
||
if (stackTop()) {
|
||
_ref3 = stackTop(), stackTag = _ref3[0], stackIdx = _ref3[1];
|
||
if ((stackTag === '{' || stackTag === 'INDENT' && this.tag(stackIdx - 1) === '{') && (startsLine || this.tag(s - 1) === ',' || this.tag(s - 1) === '{')) {
|
||
return forward(1);
|
||
}
|
||
}
|
||
startImplicitObject(s, !!startsLine);
|
||
return forward(2);
|
||
}
|
||
if (inImplicitObject() && __indexOf.call(LINEBREAKS, tag) >= 0) {
|
||
stackTop()[2].sameLine = false;
|
||
}
|
||
newLine = prevTag === 'OUTDENT' || prevToken.newLine;
|
||
if (__indexOf.call(IMPLICIT_END, tag) >= 0 || __indexOf.call(CALL_CLOSERS, tag) >= 0 && newLine) {
|
||
while (inImplicit()) {
|
||
_ref4 = stackTop(), stackTag = _ref4[0], stackIdx = _ref4[1], (_ref5 = _ref4[2], sameLine = _ref5.sameLine, startsLine = _ref5.startsLine);
|
||
if (inImplicitCall() && prevTag !== ',') {
|
||
endImplicitCall();
|
||
} else if (inImplicitObject() && !this.insideForDeclaration && sameLine && tag !== 'TERMINATOR' && prevTag !== ':' && endImplicitObject()) {
|
||
|
||
} else if (inImplicitObject() && tag === 'TERMINATOR' && prevTag !== ',' && !(startsLine && this.looksObjectish(i + 1))) {
|
||
endImplicitObject();
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (tag === ',' && !this.looksObjectish(i + 1) && inImplicitObject() && !this.insideForDeclaration && (nextTag !== 'TERMINATOR' || !this.looksObjectish(i + 2))) {
|
||
offset = nextTag === 'OUTDENT' ? 1 : 0;
|
||
while (inImplicitObject()) {
|
||
endImplicitObject(i + offset);
|
||
}
|
||
}
|
||
return forward(1);
|
||
});
|
||
};
|
||
|
||
Rewriter.prototype.addLocationDataToGeneratedTokens = function() {
|
||
return this.scanTokens(function(token, i, tokens) {
|
||
var column, line, nextLocation, prevLocation, _ref, _ref1;
|
||
if (token[2]) {
|
||
return 1;
|
||
}
|
||
if (!(token.generated || token.explicit)) {
|
||
return 1;
|
||
}
|
||
if (token[0] === '{' && (nextLocation = (_ref = tokens[i + 1]) != null ? _ref[2] : void 0)) {
|
||
line = nextLocation.first_line, column = nextLocation.first_column;
|
||
} else if (prevLocation = (_ref1 = tokens[i - 1]) != null ? _ref1[2] : void 0) {
|
||
line = prevLocation.last_line, column = prevLocation.last_column;
|
||
} else {
|
||
line = column = 0;
|
||
}
|
||
token[2] = {
|
||
first_line: line,
|
||
first_column: column,
|
||
last_line: line,
|
||
last_column: column
|
||
};
|
||
return 1;
|
||
});
|
||
};
|
||
|
||
Rewriter.prototype.normalizeLines = function() {
|
||
var action, condition, indent, outdent, starter;
|
||
starter = indent = outdent = null;
|
||
condition = function(token, i) {
|
||
var _ref, _ref1, _ref2, _ref3;
|
||
return token[1] !== ';' && (_ref = token[0], __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) && !(token[0] === 'TERMINATOR' && (_ref1 = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref1) >= 0)) && !(token[0] === 'ELSE' && starter !== 'THEN') && !(((_ref2 = token[0]) === 'CATCH' || _ref2 === 'FINALLY') && (starter === '->' || starter === '=>')) || (_ref3 = token[0], __indexOf.call(CALL_CLOSERS, _ref3) >= 0) && this.tokens[i - 1].newLine;
|
||
};
|
||
action = function(token, i) {
|
||
return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent);
|
||
};
|
||
return this.scanTokens(function(token, i, tokens) {
|
||
var j, tag, _i, _ref, _ref1, _ref2;
|
||
tag = token[0];
|
||
if (tag === 'TERMINATOR') {
|
||
if (this.tag(i + 1) === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') {
|
||
tokens.splice.apply(tokens, [i, 1].concat(__slice.call(this.indentation())));
|
||
return 1;
|
||
}
|
||
if (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0) {
|
||
tokens.splice(i, 1);
|
||
return 0;
|
||
}
|
||
}
|
||
if (tag === 'CATCH') {
|
||
for (j = _i = 1; _i <= 2; j = ++_i) {
|
||
if (!((_ref1 = this.tag(i + j)) === 'OUTDENT' || _ref1 === 'TERMINATOR' || _ref1 === 'FINALLY')) {
|
||
continue;
|
||
}
|
||
tokens.splice.apply(tokens, [i + j, 0].concat(__slice.call(this.indentation())));
|
||
return 2 + j;
|
||
}
|
||
}
|
||
if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) {
|
||
starter = tag;
|
||
_ref2 = this.indentation(tokens[i]), indent = _ref2[0], outdent = _ref2[1];
|
||
if (starter === 'THEN') {
|
||
indent.fromThen = true;
|
||
}
|
||
tokens.splice(i + 1, 0, indent);
|
||
this.detectEnd(i + 2, condition, action);
|
||
if (tag === 'THEN') {
|
||
tokens.splice(i, 1);
|
||
}
|
||
return 1;
|
||
}
|
||
return 1;
|
||
});
|
||
};
|
||
|
||
Rewriter.prototype.tagPostfixConditionals = function() {
|
||
var action, condition, original;
|
||
original = null;
|
||
condition = function(token, i) {
|
||
var prevTag, tag;
|
||
tag = token[0];
|
||
prevTag = this.tokens[i - 1][0];
|
||
return tag === 'TERMINATOR' || (tag === 'INDENT' && __indexOf.call(SINGLE_LINERS, prevTag) < 0);
|
||
};
|
||
action = function(token, i) {
|
||
if (token[0] !== 'INDENT' || (token.generated && !token.fromThen)) {
|
||
return original[0] = 'POST_' + original[0];
|
||
}
|
||
};
|
||
return this.scanTokens(function(token, i) {
|
||
if (token[0] !== 'IF') {
|
||
return 1;
|
||
}
|
||
original = token;
|
||
this.detectEnd(i + 1, condition, action);
|
||
return 1;
|
||
});
|
||
};
|
||
|
||
Rewriter.prototype.indentation = function(origin) {
|
||
var indent, outdent;
|
||
indent = ['INDENT', 2];
|
||
outdent = ['OUTDENT', 2];
|
||
if (origin) {
|
||
indent.generated = outdent.generated = true;
|
||
indent.origin = outdent.origin = origin;
|
||
} else {
|
||
indent.explicit = outdent.explicit = true;
|
||
}
|
||
return [indent, outdent];
|
||
};
|
||
|
||
Rewriter.prototype.generate = generate;
|
||
|
||
Rewriter.prototype.tag = function(i) {
|
||
var _ref;
|
||
return (_ref = this.tokens[i]) != null ? _ref[0] : void 0;
|
||
};
|
||
|
||
return Rewriter;
|
||
|
||
})();
|
||
|
||
BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END']];
|
||
|
||
exports.INVERSES = INVERSES = {};
|
||
|
||
EXPRESSION_START = [];
|
||
|
||
EXPRESSION_END = [];
|
||
|
||
for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) {
|
||
_ref = BALANCED_PAIRS[_i], left = _ref[0], rite = _ref[1];
|
||
EXPRESSION_START.push(INVERSES[rite] = left);
|
||
EXPRESSION_END.push(INVERSES[left] = rite);
|
||
}
|
||
|
||
EXPRESSION_CLOSE = ['CATCH', 'THEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
|
||
|
||
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
|
||
|
||
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
|
||
|
||
IMPLICIT_UNSPACED_CALL = ['+', '-'];
|
||
|
||
IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY', 'LOOP', 'TERMINATOR'];
|
||
|
||
SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'];
|
||
|
||
SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN'];
|
||
|
||
LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT'];
|
||
|
||
CALL_CLOSERS = ['.', '?.', '::', '?::'];
|
||
|
||
}).call(this);
|
||
|
||
},{}],54:[function(require,module,exports){
|
||
// Generated by CoffeeScript 1.8.0
|
||
(function() {
|
||
var Scope, extend, last, _ref;
|
||
|
||
_ref = require('./helpers'), extend = _ref.extend, last = _ref.last;
|
||
|
||
exports.Scope = Scope = (function() {
|
||
Scope.root = null;
|
||
|
||
function Scope(parent, expressions, method) {
|
||
this.parent = parent;
|
||
this.expressions = expressions;
|
||
this.method = method;
|
||
this.variables = [
|
||
{
|
||
name: 'arguments',
|
||
type: 'arguments'
|
||
}
|
||
];
|
||
this.positions = {};
|
||
if (!this.parent) {
|
||
Scope.root = this;
|
||
}
|
||
}
|
||
|
||
Scope.prototype.add = function(name, type, immediate) {
|
||
if (this.shared && !immediate) {
|
||
return this.parent.add(name, type, immediate);
|
||
}
|
||
if (Object.prototype.hasOwnProperty.call(this.positions, name)) {
|
||
return this.variables[this.positions[name]].type = type;
|
||
} else {
|
||
return this.positions[name] = this.variables.push({
|
||
name: name,
|
||
type: type
|
||
}) - 1;
|
||
}
|
||
};
|
||
|
||
Scope.prototype.namedMethod = function() {
|
||
var _ref1;
|
||
if (((_ref1 = this.method) != null ? _ref1.name : void 0) || !this.parent) {
|
||
return this.method;
|
||
}
|
||
return this.parent.namedMethod();
|
||
};
|
||
|
||
Scope.prototype.find = function(name) {
|
||
if (this.check(name)) {
|
||
return true;
|
||
}
|
||
this.add(name, 'var');
|
||
return false;
|
||
};
|
||
|
||
Scope.prototype.parameter = function(name) {
|
||
if (this.shared && this.parent.check(name, true)) {
|
||
return;
|
||
}
|
||
return this.add(name, 'param');
|
||
};
|
||
|
||
Scope.prototype.check = function(name) {
|
||
var _ref1;
|
||
return !!(this.type(name) || ((_ref1 = this.parent) != null ? _ref1.check(name) : void 0));
|
||
};
|
||
|
||
Scope.prototype.temporary = function(name, index) {
|
||
if (name.length > 1) {
|
||
return '_' + name + (index > 1 ? index - 1 : '');
|
||
} else {
|
||
return '_' + (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a');
|
||
}
|
||
};
|
||
|
||
Scope.prototype.type = function(name) {
|
||
var v, _i, _len, _ref1;
|
||
_ref1 = this.variables;
|
||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||
v = _ref1[_i];
|
||
if (v.name === name) {
|
||
return v.type;
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
|
||
Scope.prototype.freeVariable = function(name, reserve) {
|
||
var index, temp;
|
||
if (reserve == null) {
|
||
reserve = true;
|
||
}
|
||
index = 0;
|
||
while (this.check((temp = this.temporary(name, index)))) {
|
||
index++;
|
||
}
|
||
if (reserve) {
|
||
this.add(temp, 'var', true);
|
||
}
|
||
return temp;
|
||
};
|
||
|
||
Scope.prototype.assign = function(name, value) {
|
||
this.add(name, {
|
||
value: value,
|
||
assigned: true
|
||
}, true);
|
||
return this.hasAssignments = true;
|
||
};
|
||
|
||
Scope.prototype.hasDeclarations = function() {
|
||
return !!this.declaredVariables().length;
|
||
};
|
||
|
||
Scope.prototype.declaredVariables = function() {
|
||
var realVars, tempVars, v, _i, _len, _ref1;
|
||
realVars = [];
|
||
tempVars = [];
|
||
_ref1 = this.variables;
|
||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||
v = _ref1[_i];
|
||
if (v.type === 'var') {
|
||
(v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name);
|
||
}
|
||
}
|
||
return realVars.sort().concat(tempVars.sort());
|
||
};
|
||
|
||
Scope.prototype.assignedVariables = function() {
|
||
var v, _i, _len, _ref1, _results;
|
||
_ref1 = this.variables;
|
||
_results = [];
|
||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||
v = _ref1[_i];
|
||
if (v.type.assigned) {
|
||
_results.push("" + v.name + " = " + v.type.value);
|
||
}
|
||
}
|
||
return _results;
|
||
};
|
||
|
||
return Scope;
|
||
|
||
})();
|
||
|
||
}).call(this);
|
||
|
||
},{"./helpers":48}],55:[function(require,module,exports){
|
||
// Generated by CoffeeScript 1.8.0
|
||
(function() {
|
||
var LineMap, SourceMap;
|
||
|
||
LineMap = (function() {
|
||
function LineMap(line) {
|
||
this.line = line;
|
||
this.columns = [];
|
||
}
|
||
|
||
LineMap.prototype.add = function(column, _arg, options) {
|
||
var sourceColumn, sourceLine;
|
||
sourceLine = _arg[0], sourceColumn = _arg[1];
|
||
if (options == null) {
|
||
options = {};
|
||
}
|
||
if (this.columns[column] && options.noReplace) {
|
||
return;
|
||
}
|
||
return this.columns[column] = {
|
||
line: this.line,
|
||
column: column,
|
||
sourceLine: sourceLine,
|
||
sourceColumn: sourceColumn
|
||
};
|
||
};
|
||
|
||
LineMap.prototype.sourceLocation = function(column) {
|
||
var mapping;
|
||
while (!((mapping = this.columns[column]) || (column <= 0))) {
|
||
column--;
|
||
}
|
||
return mapping && [mapping.sourceLine, mapping.sourceColumn];
|
||
};
|
||
|
||
return LineMap;
|
||
|
||
})();
|
||
|
||
SourceMap = (function() {
|
||
var BASE64_CHARS, VLQ_CONTINUATION_BIT, VLQ_SHIFT, VLQ_VALUE_MASK;
|
||
|
||
function SourceMap() {
|
||
this.lines = [];
|
||
}
|
||
|
||
SourceMap.prototype.add = function(sourceLocation, generatedLocation, options) {
|
||
var column, line, lineMap, _base;
|
||
if (options == null) {
|
||
options = {};
|
||
}
|
||
line = generatedLocation[0], column = generatedLocation[1];
|
||
lineMap = ((_base = this.lines)[line] || (_base[line] = new LineMap(line)));
|
||
return lineMap.add(column, sourceLocation, options);
|
||
};
|
||
|
||
SourceMap.prototype.sourceLocation = function(_arg) {
|
||
var column, line, lineMap;
|
||
line = _arg[0], column = _arg[1];
|
||
while (!((lineMap = this.lines[line]) || (line <= 0))) {
|
||
line--;
|
||
}
|
||
return lineMap && lineMap.sourceLocation(column);
|
||
};
|
||
|
||
SourceMap.prototype.generate = function(options, code) {
|
||
var buffer, lastColumn, lastSourceColumn, lastSourceLine, lineMap, lineNumber, mapping, needComma, v3, writingline, _i, _j, _len, _len1, _ref, _ref1;
|
||
if (options == null) {
|
||
options = {};
|
||
}
|
||
if (code == null) {
|
||
code = null;
|
||
}
|
||
writingline = 0;
|
||
lastColumn = 0;
|
||
lastSourceLine = 0;
|
||
lastSourceColumn = 0;
|
||
needComma = false;
|
||
buffer = "";
|
||
_ref = this.lines;
|
||
for (lineNumber = _i = 0, _len = _ref.length; _i < _len; lineNumber = ++_i) {
|
||
lineMap = _ref[lineNumber];
|
||
if (lineMap) {
|
||
_ref1 = lineMap.columns;
|
||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||
mapping = _ref1[_j];
|
||
if (!(mapping)) {
|
||
continue;
|
||
}
|
||
while (writingline < mapping.line) {
|
||
lastColumn = 0;
|
||
needComma = false;
|
||
buffer += ";";
|
||
writingline++;
|
||
}
|
||
if (needComma) {
|
||
buffer += ",";
|
||
needComma = false;
|
||
}
|
||
buffer += this.encodeVlq(mapping.column - lastColumn);
|
||
lastColumn = mapping.column;
|
||
buffer += this.encodeVlq(0);
|
||
buffer += this.encodeVlq(mapping.sourceLine - lastSourceLine);
|
||
lastSourceLine = mapping.sourceLine;
|
||
buffer += this.encodeVlq(mapping.sourceColumn - lastSourceColumn);
|
||
lastSourceColumn = mapping.sourceColumn;
|
||
needComma = true;
|
||
}
|
||
}
|
||
}
|
||
v3 = {
|
||
version: 3,
|
||
file: options.generatedFile || '',
|
||
sourceRoot: options.sourceRoot || '',
|
||
sources: options.sourceFiles || [''],
|
||
names: [],
|
||
mappings: buffer
|
||
};
|
||
if (options.inline) {
|
||
v3.sourcesContent = [code];
|
||
}
|
||
return JSON.stringify(v3, null, 2);
|
||
};
|
||
|
||
VLQ_SHIFT = 5;
|
||
|
||
VLQ_CONTINUATION_BIT = 1 << VLQ_SHIFT;
|
||
|
||
VLQ_VALUE_MASK = VLQ_CONTINUATION_BIT - 1;
|
||
|
||
SourceMap.prototype.encodeVlq = function(value) {
|
||
var answer, nextChunk, signBit, valueToEncode;
|
||
answer = '';
|
||
signBit = value < 0 ? 1 : 0;
|
||
valueToEncode = (Math.abs(value) << 1) + signBit;
|
||
while (valueToEncode || !answer) {
|
||
nextChunk = valueToEncode & VLQ_VALUE_MASK;
|
||
valueToEncode = valueToEncode >> VLQ_SHIFT;
|
||
if (valueToEncode) {
|
||
nextChunk |= VLQ_CONTINUATION_BIT;
|
||
}
|
||
answer += this.encodeBase64(nextChunk);
|
||
}
|
||
return answer;
|
||
};
|
||
|
||
BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||
|
||
SourceMap.prototype.encodeBase64 = function(value) {
|
||
return BASE64_CHARS[value] || (function() {
|
||
throw new Error("Cannot Base64 encode value: " + value);
|
||
})();
|
||
};
|
||
|
||
return SourceMap;
|
||
|
||
})();
|
||
|
||
module.exports = SourceMap;
|
||
|
||
}).call(this);
|
||
|
||
},{}],56:[function(require,module,exports){
|
||
|
||
},{}],57:[function(require,module,exports){
|
||
/*!
|
||
* The buffer module from node.js, for the browser.
|
||
*
|
||
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
|
||
* @license MIT
|
||
*/
|
||
|
||
var base64 = require('base64-js')
|
||
var ieee754 = require('ieee754')
|
||
|
||
exports.Buffer = Buffer
|
||
exports.SlowBuffer = Buffer
|
||
exports.INSPECT_MAX_BYTES = 50
|
||
Buffer.poolSize = 8192
|
||
|
||
/**
|
||
* If `Buffer._useTypedArrays`:
|
||
* === true Use Uint8Array implementation (fastest)
|
||
* === false Use Object implementation (compatible down to IE6)
|
||
*/
|
||
Buffer._useTypedArrays = (function () {
|
||
// Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+,
|
||
// Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding
|
||
// properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support
|
||
// because we need to be able to add all the node Buffer API methods. This is an issue
|
||
// in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438
|
||
try {
|
||
var buf = new ArrayBuffer(0)
|
||
var arr = new Uint8Array(buf)
|
||
arr.foo = function () { return 42 }
|
||
return 42 === arr.foo() &&
|
||
typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray`
|
||
} catch (e) {
|
||
return false
|
||
}
|
||
})()
|
||
|
||
/**
|
||
* Class: Buffer
|
||
* =============
|
||
*
|
||
* The Buffer constructor returns instances of `Uint8Array` that are augmented
|
||
* with function properties for all the node `Buffer` API functions. We use
|
||
* `Uint8Array` so that square bracket notation works as expected -- it returns
|
||
* a single octet.
|
||
*
|
||
* By augmenting the instances, we can avoid modifying the `Uint8Array`
|
||
* prototype.
|
||
*/
|
||
function Buffer (subject, encoding, noZero) {
|
||
if (!(this instanceof Buffer))
|
||
return new Buffer(subject, encoding, noZero)
|
||
|
||
var type = typeof subject
|
||
|
||
// Workaround: node's base64 implementation allows for non-padded strings
|
||
// while base64-js does not.
|
||
if (encoding === 'base64' && type === 'string') {
|
||
subject = stringtrim(subject)
|
||
while (subject.length % 4 !== 0) {
|
||
subject = subject + '='
|
||
}
|
||
}
|
||
|
||
// Find the length
|
||
var length
|
||
if (type === 'number')
|
||
length = coerce(subject)
|
||
else if (type === 'string')
|
||
length = Buffer.byteLength(subject, encoding)
|
||
else if (type === 'object')
|
||
length = coerce(subject.length) // assume that object is array-like
|
||
else
|
||
throw new Error('First argument needs to be a number, array or string.')
|
||
|
||
var buf
|
||
if (Buffer._useTypedArrays) {
|
||
// Preferred: Return an augmented `Uint8Array` instance for best performance
|
||
buf = Buffer._augment(new Uint8Array(length))
|
||
} else {
|
||
// Fallback: Return THIS instance of Buffer (created by `new`)
|
||
buf = this
|
||
buf.length = length
|
||
buf._isBuffer = true
|
||
}
|
||
|
||
var i
|
||
if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') {
|
||
// Speed optimization -- use set if we're copying from a typed array
|
||
buf._set(subject)
|
||
} else if (isArrayish(subject)) {
|
||
// Treat array-ish objects as a byte array
|
||
for (i = 0; i < length; i++) {
|
||
if (Buffer.isBuffer(subject))
|
||
buf[i] = subject.readUInt8(i)
|
||
else
|
||
buf[i] = subject[i]
|
||
}
|
||
} else if (type === 'string') {
|
||
buf.write(subject, 0, encoding)
|
||
} else if (type === 'number' && !Buffer._useTypedArrays && !noZero) {
|
||
for (i = 0; i < length; i++) {
|
||
buf[i] = 0
|
||
}
|
||
}
|
||
|
||
return buf
|
||
}
|
||
|
||
// STATIC METHODS
|
||
// ==============
|
||
|
||
Buffer.isEncoding = function (encoding) {
|
||
switch (String(encoding).toLowerCase()) {
|
||
case 'hex':
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
case 'ascii':
|
||
case 'binary':
|
||
case 'base64':
|
||
case 'raw':
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
return true
|
||
default:
|
||
return false
|
||
}
|
||
}
|
||
|
||
Buffer.isBuffer = function (b) {
|
||
return !!(b !== null && b !== undefined && b._isBuffer)
|
||
}
|
||
|
||
Buffer.byteLength = function (str, encoding) {
|
||
var ret
|
||
str = str + ''
|
||
switch (encoding || 'utf8') {
|
||
case 'hex':
|
||
ret = str.length / 2
|
||
break
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
ret = utf8ToBytes(str).length
|
||
break
|
||
case 'ascii':
|
||
case 'binary':
|
||
case 'raw':
|
||
ret = str.length
|
||
break
|
||
case 'base64':
|
||
ret = base64ToBytes(str).length
|
||
break
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
ret = str.length * 2
|
||
break
|
||
default:
|
||
throw new Error('Unknown encoding')
|
||
}
|
||
return ret
|
||
}
|
||
|
||
Buffer.concat = function (list, totalLength) {
|
||
assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\n' +
|
||
'list should be an Array.')
|
||
|
||
if (list.length === 0) {
|
||
return new Buffer(0)
|
||
} else if (list.length === 1) {
|
||
return list[0]
|
||
}
|
||
|
||
var i
|
||
if (typeof totalLength !== 'number') {
|
||
totalLength = 0
|
||
for (i = 0; i < list.length; i++) {
|
||
totalLength += list[i].length
|
||
}
|
||
}
|
||
|
||
var buf = new Buffer(totalLength)
|
||
var pos = 0
|
||
for (i = 0; i < list.length; i++) {
|
||
var item = list[i]
|
||
item.copy(buf, pos)
|
||
pos += item.length
|
||
}
|
||
return buf
|
||
}
|
||
|
||
// BUFFER INSTANCE METHODS
|
||
// =======================
|
||
|
||
function _hexWrite (buf, string, offset, length) {
|
||
offset = Number(offset) || 0
|
||
var remaining = buf.length - offset
|
||
if (!length) {
|
||
length = remaining
|
||
} else {
|
||
length = Number(length)
|
||
if (length > remaining) {
|
||
length = remaining
|
||
}
|
||
}
|
||
|
||
// must be an even number of digits
|
||
var strLen = string.length
|
||
assert(strLen % 2 === 0, 'Invalid hex string')
|
||
|
||
if (length > strLen / 2) {
|
||
length = strLen / 2
|
||
}
|
||
for (var i = 0; i < length; i++) {
|
||
var byte = parseInt(string.substr(i * 2, 2), 16)
|
||
assert(!isNaN(byte), 'Invalid hex string')
|
||
buf[offset + i] = byte
|
||
}
|
||
Buffer._charsWritten = i * 2
|
||
return i
|
||
}
|
||
|
||
function _utf8Write (buf, string, offset, length) {
|
||
var charsWritten = Buffer._charsWritten =
|
||
blitBuffer(utf8ToBytes(string), buf, offset, length)
|
||
return charsWritten
|
||
}
|
||
|
||
function _asciiWrite (buf, string, offset, length) {
|
||
var charsWritten = Buffer._charsWritten =
|
||
blitBuffer(asciiToBytes(string), buf, offset, length)
|
||
return charsWritten
|
||
}
|
||
|
||
function _binaryWrite (buf, string, offset, length) {
|
||
return _asciiWrite(buf, string, offset, length)
|
||
}
|
||
|
||
function _base64Write (buf, string, offset, length) {
|
||
var charsWritten = Buffer._charsWritten =
|
||
blitBuffer(base64ToBytes(string), buf, offset, length)
|
||
return charsWritten
|
||
}
|
||
|
||
function _utf16leWrite (buf, string, offset, length) {
|
||
var charsWritten = Buffer._charsWritten =
|
||
blitBuffer(utf16leToBytes(string), buf, offset, length)
|
||
return charsWritten
|
||
}
|
||
|
||
Buffer.prototype.write = function (string, offset, length, encoding) {
|
||
// Support both (string, offset, length, encoding)
|
||
// and the legacy (string, encoding, offset, length)
|
||
if (isFinite(offset)) {
|
||
if (!isFinite(length)) {
|
||
encoding = length
|
||
length = undefined
|
||
}
|
||
} else { // legacy
|
||
var swap = encoding
|
||
encoding = offset
|
||
offset = length
|
||
length = swap
|
||
}
|
||
|
||
offset = Number(offset) || 0
|
||
var remaining = this.length - offset
|
||
if (!length) {
|
||
length = remaining
|
||
} else {
|
||
length = Number(length)
|
||
if (length > remaining) {
|
||
length = remaining
|
||
}
|
||
}
|
||
encoding = String(encoding || 'utf8').toLowerCase()
|
||
|
||
var ret
|
||
switch (encoding) {
|
||
case 'hex':
|
||
ret = _hexWrite(this, string, offset, length)
|
||
break
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
ret = _utf8Write(this, string, offset, length)
|
||
break
|
||
case 'ascii':
|
||
ret = _asciiWrite(this, string, offset, length)
|
||
break
|
||
case 'binary':
|
||
ret = _binaryWrite(this, string, offset, length)
|
||
break
|
||
case 'base64':
|
||
ret = _base64Write(this, string, offset, length)
|
||
break
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
ret = _utf16leWrite(this, string, offset, length)
|
||
break
|
||
default:
|
||
throw new Error('Unknown encoding')
|
||
}
|
||
return ret
|
||
}
|
||
|
||
Buffer.prototype.toString = function (encoding, start, end) {
|
||
var self = this
|
||
|
||
encoding = String(encoding || 'utf8').toLowerCase()
|
||
start = Number(start) || 0
|
||
end = (end !== undefined)
|
||
? Number(end)
|
||
: end = self.length
|
||
|
||
// Fastpath empty strings
|
||
if (end === start)
|
||
return ''
|
||
|
||
var ret
|
||
switch (encoding) {
|
||
case 'hex':
|
||
ret = _hexSlice(self, start, end)
|
||
break
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
ret = _utf8Slice(self, start, end)
|
||
break
|
||
case 'ascii':
|
||
ret = _asciiSlice(self, start, end)
|
||
break
|
||
case 'binary':
|
||
ret = _binarySlice(self, start, end)
|
||
break
|
||
case 'base64':
|
||
ret = _base64Slice(self, start, end)
|
||
break
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
ret = _utf16leSlice(self, start, end)
|
||
break
|
||
default:
|
||
throw new Error('Unknown encoding')
|
||
}
|
||
return ret
|
||
}
|
||
|
||
Buffer.prototype.toJSON = function () {
|
||
return {
|
||
type: 'Buffer',
|
||
data: Array.prototype.slice.call(this._arr || this, 0)
|
||
}
|
||
}
|
||
|
||
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
|
||
Buffer.prototype.copy = function (target, target_start, start, end) {
|
||
var source = this
|
||
|
||
if (!start) start = 0
|
||
if (!end && end !== 0) end = this.length
|
||
if (!target_start) target_start = 0
|
||
|
||
// Copy 0 bytes; we're done
|
||
if (end === start) return
|
||
if (target.length === 0 || source.length === 0) return
|
||
|
||
// Fatal error conditions
|
||
assert(end >= start, 'sourceEnd < sourceStart')
|
||
assert(target_start >= 0 && target_start < target.length,
|
||
'targetStart out of bounds')
|
||
assert(start >= 0 && start < source.length, 'sourceStart out of bounds')
|
||
assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds')
|
||
|
||
// Are we oob?
|
||
if (end > this.length)
|
||
end = this.length
|
||
if (target.length - target_start < end - start)
|
||
end = target.length - target_start + start
|
||
|
||
var len = end - start
|
||
|
||
if (len < 100 || !Buffer._useTypedArrays) {
|
||
for (var i = 0; i < len; i++)
|
||
target[i + target_start] = this[i + start]
|
||
} else {
|
||
target._set(this.subarray(start, start + len), target_start)
|
||
}
|
||
}
|
||
|
||
function _base64Slice (buf, start, end) {
|
||
if (start === 0 && end === buf.length) {
|
||
return base64.fromByteArray(buf)
|
||
} else {
|
||
return base64.fromByteArray(buf.slice(start, end))
|
||
}
|
||
}
|
||
|
||
function _utf8Slice (buf, start, end) {
|
||
var res = ''
|
||
var tmp = ''
|
||
end = Math.min(buf.length, end)
|
||
|
||
for (var i = start; i < end; i++) {
|
||
if (buf[i] <= 0x7F) {
|
||
res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])
|
||
tmp = ''
|
||
} else {
|
||
tmp += '%' + buf[i].toString(16)
|
||
}
|
||
}
|
||
|
||
return res + decodeUtf8Char(tmp)
|
||
}
|
||
|
||
function _asciiSlice (buf, start, end) {
|
||
var ret = ''
|
||
end = Math.min(buf.length, end)
|
||
|
||
for (var i = start; i < end; i++)
|
||
ret += String.fromCharCode(buf[i])
|
||
return ret
|
||
}
|
||
|
||
function _binarySlice (buf, start, end) {
|
||
return _asciiSlice(buf, start, end)
|
||
}
|
||
|
||
function _hexSlice (buf, start, end) {
|
||
var len = buf.length
|
||
|
||
if (!start || start < 0) start = 0
|
||
if (!end || end < 0 || end > len) end = len
|
||
|
||
var out = ''
|
||
for (var i = start; i < end; i++) {
|
||
out += toHex(buf[i])
|
||
}
|
||
return out
|
||
}
|
||
|
||
function _utf16leSlice (buf, start, end) {
|
||
var bytes = buf.slice(start, end)
|
||
var res = ''
|
||
for (var i = 0; i < bytes.length; i += 2) {
|
||
res += String.fromCharCode(bytes[i] + bytes[i+1] * 256)
|
||
}
|
||
return res
|
||
}
|
||
|
||
Buffer.prototype.slice = function (start, end) {
|
||
var len = this.length
|
||
start = clamp(start, len, 0)
|
||
end = clamp(end, len, len)
|
||
|
||
if (Buffer._useTypedArrays) {
|
||
return Buffer._augment(this.subarray(start, end))
|
||
} else {
|
||
var sliceLen = end - start
|
||
var newBuf = new Buffer(sliceLen, undefined, true)
|
||
for (var i = 0; i < sliceLen; i++) {
|
||
newBuf[i] = this[i + start]
|
||
}
|
||
return newBuf
|
||
}
|
||
}
|
||
|
||
// `get` will be removed in Node 0.13+
|
||
Buffer.prototype.get = function (offset) {
|
||
console.log('.get() is deprecated. Access using array indexes instead.')
|
||
return this.readUInt8(offset)
|
||
}
|
||
|
||
// `set` will be removed in Node 0.13+
|
||
Buffer.prototype.set = function (v, offset) {
|
||
console.log('.set() is deprecated. Access using array indexes instead.')
|
||
return this.writeUInt8(v, offset)
|
||
}
|
||
|
||
Buffer.prototype.readUInt8 = function (offset, noAssert) {
|
||
if (!noAssert) {
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset < this.length, 'Trying to read beyond buffer length')
|
||
}
|
||
|
||
if (offset >= this.length)
|
||
return
|
||
|
||
return this[offset]
|
||
}
|
||
|
||
function _readUInt16 (buf, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')
|
||
}
|
||
|
||
var len = buf.length
|
||
if (offset >= len)
|
||
return
|
||
|
||
var val
|
||
if (littleEndian) {
|
||
val = buf[offset]
|
||
if (offset + 1 < len)
|
||
val |= buf[offset + 1] << 8
|
||
} else {
|
||
val = buf[offset] << 8
|
||
if (offset + 1 < len)
|
||
val |= buf[offset + 1]
|
||
}
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readUInt16LE = function (offset, noAssert) {
|
||
return _readUInt16(this, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.readUInt16BE = function (offset, noAssert) {
|
||
return _readUInt16(this, offset, false, noAssert)
|
||
}
|
||
|
||
function _readUInt32 (buf, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
|
||
}
|
||
|
||
var len = buf.length
|
||
if (offset >= len)
|
||
return
|
||
|
||
var val
|
||
if (littleEndian) {
|
||
if (offset + 2 < len)
|
||
val = buf[offset + 2] << 16
|
||
if (offset + 1 < len)
|
||
val |= buf[offset + 1] << 8
|
||
val |= buf[offset]
|
||
if (offset + 3 < len)
|
||
val = val + (buf[offset + 3] << 24 >>> 0)
|
||
} else {
|
||
if (offset + 1 < len)
|
||
val = buf[offset + 1] << 16
|
||
if (offset + 2 < len)
|
||
val |= buf[offset + 2] << 8
|
||
if (offset + 3 < len)
|
||
val |= buf[offset + 3]
|
||
val = val + (buf[offset] << 24 >>> 0)
|
||
}
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readUInt32LE = function (offset, noAssert) {
|
||
return _readUInt32(this, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.readUInt32BE = function (offset, noAssert) {
|
||
return _readUInt32(this, offset, false, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.readInt8 = function (offset, noAssert) {
|
||
if (!noAssert) {
|
||
assert(offset !== undefined && offset !== null,
|
||
'missing offset')
|
||
assert(offset < this.length, 'Trying to read beyond buffer length')
|
||
}
|
||
|
||
if (offset >= this.length)
|
||
return
|
||
|
||
var neg = this[offset] & 0x80
|
||
if (neg)
|
||
return (0xff - this[offset] + 1) * -1
|
||
else
|
||
return this[offset]
|
||
}
|
||
|
||
function _readInt16 (buf, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')
|
||
}
|
||
|
||
var len = buf.length
|
||
if (offset >= len)
|
||
return
|
||
|
||
var val = _readUInt16(buf, offset, littleEndian, true)
|
||
var neg = val & 0x8000
|
||
if (neg)
|
||
return (0xffff - val + 1) * -1
|
||
else
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readInt16LE = function (offset, noAssert) {
|
||
return _readInt16(this, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.readInt16BE = function (offset, noAssert) {
|
||
return _readInt16(this, offset, false, noAssert)
|
||
}
|
||
|
||
function _readInt32 (buf, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
|
||
}
|
||
|
||
var len = buf.length
|
||
if (offset >= len)
|
||
return
|
||
|
||
var val = _readUInt32(buf, offset, littleEndian, true)
|
||
var neg = val & 0x80000000
|
||
if (neg)
|
||
return (0xffffffff - val + 1) * -1
|
||
else
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readInt32LE = function (offset, noAssert) {
|
||
return _readInt32(this, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.readInt32BE = function (offset, noAssert) {
|
||
return _readInt32(this, offset, false, noAssert)
|
||
}
|
||
|
||
function _readFloat (buf, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
|
||
}
|
||
|
||
return ieee754.read(buf, offset, littleEndian, 23, 4)
|
||
}
|
||
|
||
Buffer.prototype.readFloatLE = function (offset, noAssert) {
|
||
return _readFloat(this, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.readFloatBE = function (offset, noAssert) {
|
||
return _readFloat(this, offset, false, noAssert)
|
||
}
|
||
|
||
function _readDouble (buf, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset + 7 < buf.length, 'Trying to read beyond buffer length')
|
||
}
|
||
|
||
return ieee754.read(buf, offset, littleEndian, 52, 8)
|
||
}
|
||
|
||
Buffer.prototype.readDoubleLE = function (offset, noAssert) {
|
||
return _readDouble(this, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.readDoubleBE = function (offset, noAssert) {
|
||
return _readDouble(this, offset, false, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeUInt8 = function (value, offset, noAssert) {
|
||
if (!noAssert) {
|
||
assert(value !== undefined && value !== null, 'missing value')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset < this.length, 'trying to write beyond buffer length')
|
||
verifuint(value, 0xff)
|
||
}
|
||
|
||
if (offset >= this.length) return
|
||
|
||
this[offset] = value
|
||
}
|
||
|
||
function _writeUInt16 (buf, value, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(value !== undefined && value !== null, 'missing value')
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset + 1 < buf.length, 'trying to write beyond buffer length')
|
||
verifuint(value, 0xffff)
|
||
}
|
||
|
||
var len = buf.length
|
||
if (offset >= len)
|
||
return
|
||
|
||
for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) {
|
||
buf[offset + i] =
|
||
(value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
|
||
(littleEndian ? i : 1 - i) * 8
|
||
}
|
||
}
|
||
|
||
Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) {
|
||
_writeUInt16(this, value, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) {
|
||
_writeUInt16(this, value, offset, false, noAssert)
|
||
}
|
||
|
||
function _writeUInt32 (buf, value, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(value !== undefined && value !== null, 'missing value')
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset + 3 < buf.length, 'trying to write beyond buffer length')
|
||
verifuint(value, 0xffffffff)
|
||
}
|
||
|
||
var len = buf.length
|
||
if (offset >= len)
|
||
return
|
||
|
||
for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) {
|
||
buf[offset + i] =
|
||
(value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
|
||
}
|
||
}
|
||
|
||
Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) {
|
||
_writeUInt32(this, value, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) {
|
||
_writeUInt32(this, value, offset, false, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeInt8 = function (value, offset, noAssert) {
|
||
if (!noAssert) {
|
||
assert(value !== undefined && value !== null, 'missing value')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset < this.length, 'Trying to write beyond buffer length')
|
||
verifsint(value, 0x7f, -0x80)
|
||
}
|
||
|
||
if (offset >= this.length)
|
||
return
|
||
|
||
if (value >= 0)
|
||
this.writeUInt8(value, offset, noAssert)
|
||
else
|
||
this.writeUInt8(0xff + value + 1, offset, noAssert)
|
||
}
|
||
|
||
function _writeInt16 (buf, value, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(value !== undefined && value !== null, 'missing value')
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset + 1 < buf.length, 'Trying to write beyond buffer length')
|
||
verifsint(value, 0x7fff, -0x8000)
|
||
}
|
||
|
||
var len = buf.length
|
||
if (offset >= len)
|
||
return
|
||
|
||
if (value >= 0)
|
||
_writeUInt16(buf, value, offset, littleEndian, noAssert)
|
||
else
|
||
_writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeInt16LE = function (value, offset, noAssert) {
|
||
_writeInt16(this, value, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeInt16BE = function (value, offset, noAssert) {
|
||
_writeInt16(this, value, offset, false, noAssert)
|
||
}
|
||
|
||
function _writeInt32 (buf, value, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(value !== undefined && value !== null, 'missing value')
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')
|
||
verifsint(value, 0x7fffffff, -0x80000000)
|
||
}
|
||
|
||
var len = buf.length
|
||
if (offset >= len)
|
||
return
|
||
|
||
if (value >= 0)
|
||
_writeUInt32(buf, value, offset, littleEndian, noAssert)
|
||
else
|
||
_writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeInt32LE = function (value, offset, noAssert) {
|
||
_writeInt32(this, value, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeInt32BE = function (value, offset, noAssert) {
|
||
_writeInt32(this, value, offset, false, noAssert)
|
||
}
|
||
|
||
function _writeFloat (buf, value, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(value !== undefined && value !== null, 'missing value')
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')
|
||
verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38)
|
||
}
|
||
|
||
var len = buf.length
|
||
if (offset >= len)
|
||
return
|
||
|
||
ieee754.write(buf, value, offset, littleEndian, 23, 4)
|
||
}
|
||
|
||
Buffer.prototype.writeFloatLE = function (value, offset, noAssert) {
|
||
_writeFloat(this, value, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeFloatBE = function (value, offset, noAssert) {
|
||
_writeFloat(this, value, offset, false, noAssert)
|
||
}
|
||
|
||
function _writeDouble (buf, value, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
assert(value !== undefined && value !== null, 'missing value')
|
||
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
|
||
assert(offset !== undefined && offset !== null, 'missing offset')
|
||
assert(offset + 7 < buf.length,
|
||
'Trying to write beyond buffer length')
|
||
verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308)
|
||
}
|
||
|
||
var len = buf.length
|
||
if (offset >= len)
|
||
return
|
||
|
||
ieee754.write(buf, value, offset, littleEndian, 52, 8)
|
||
}
|
||
|
||
Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) {
|
||
_writeDouble(this, value, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) {
|
||
_writeDouble(this, value, offset, false, noAssert)
|
||
}
|
||
|
||
// fill(value, start=0, end=buffer.length)
|
||
Buffer.prototype.fill = function (value, start, end) {
|
||
if (!value) value = 0
|
||
if (!start) start = 0
|
||
if (!end) end = this.length
|
||
|
||
if (typeof value === 'string') {
|
||
value = value.charCodeAt(0)
|
||
}
|
||
|
||
assert(typeof value === 'number' && !isNaN(value), 'value is not a number')
|
||
assert(end >= start, 'end < start')
|
||
|
||
// Fill 0 bytes; we're done
|
||
if (end === start) return
|
||
if (this.length === 0) return
|
||
|
||
assert(start >= 0 && start < this.length, 'start out of bounds')
|
||
assert(end >= 0 && end <= this.length, 'end out of bounds')
|
||
|
||
for (var i = start; i < end; i++) {
|
||
this[i] = value
|
||
}
|
||
}
|
||
|
||
Buffer.prototype.inspect = function () {
|
||
var out = []
|
||
var len = this.length
|
||
for (var i = 0; i < len; i++) {
|
||
out[i] = toHex(this[i])
|
||
if (i === exports.INSPECT_MAX_BYTES) {
|
||
out[i + 1] = '...'
|
||
break
|
||
}
|
||
}
|
||
return '<Buffer ' + out.join(' ') + '>'
|
||
}
|
||
|
||
/**
|
||
* Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
|
||
* Added in Node 0.12. Only available in browsers that support ArrayBuffer.
|
||
*/
|
||
Buffer.prototype.toArrayBuffer = function () {
|
||
if (typeof Uint8Array !== 'undefined') {
|
||
if (Buffer._useTypedArrays) {
|
||
return (new Buffer(this)).buffer
|
||
} else {
|
||
var buf = new Uint8Array(this.length)
|
||
for (var i = 0, len = buf.length; i < len; i += 1)
|
||
buf[i] = this[i]
|
||
return buf.buffer
|
||
}
|
||
} else {
|
||
throw new Error('Buffer.toArrayBuffer not supported in this browser')
|
||
}
|
||
}
|
||
|
||
// HELPER FUNCTIONS
|
||
// ================
|
||
|
||
function stringtrim (str) {
|
||
if (str.trim) return str.trim()
|
||
return str.replace(/^\s+|\s+$/g, '')
|
||
}
|
||
|
||
var BP = Buffer.prototype
|
||
|
||
/**
|
||
* Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
|
||
*/
|
||
Buffer._augment = function (arr) {
|
||
arr._isBuffer = true
|
||
|
||
// save reference to original Uint8Array get/set methods before overwriting
|
||
arr._get = arr.get
|
||
arr._set = arr.set
|
||
|
||
// deprecated, will be removed in node 0.13+
|
||
arr.get = BP.get
|
||
arr.set = BP.set
|
||
|
||
arr.write = BP.write
|
||
arr.toString = BP.toString
|
||
arr.toLocaleString = BP.toString
|
||
arr.toJSON = BP.toJSON
|
||
arr.copy = BP.copy
|
||
arr.slice = BP.slice
|
||
arr.readUInt8 = BP.readUInt8
|
||
arr.readUInt16LE = BP.readUInt16LE
|
||
arr.readUInt16BE = BP.readUInt16BE
|
||
arr.readUInt32LE = BP.readUInt32LE
|
||
arr.readUInt32BE = BP.readUInt32BE
|
||
arr.readInt8 = BP.readInt8
|
||
arr.readInt16LE = BP.readInt16LE
|
||
arr.readInt16BE = BP.readInt16BE
|
||
arr.readInt32LE = BP.readInt32LE
|
||
arr.readInt32BE = BP.readInt32BE
|
||
arr.readFloatLE = BP.readFloatLE
|
||
arr.readFloatBE = BP.readFloatBE
|
||
arr.readDoubleLE = BP.readDoubleLE
|
||
arr.readDoubleBE = BP.readDoubleBE
|
||
arr.writeUInt8 = BP.writeUInt8
|
||
arr.writeUInt16LE = BP.writeUInt16LE
|
||
arr.writeUInt16BE = BP.writeUInt16BE
|
||
arr.writeUInt32LE = BP.writeUInt32LE
|
||
arr.writeUInt32BE = BP.writeUInt32BE
|
||
arr.writeInt8 = BP.writeInt8
|
||
arr.writeInt16LE = BP.writeInt16LE
|
||
arr.writeInt16BE = BP.writeInt16BE
|
||
arr.writeInt32LE = BP.writeInt32LE
|
||
arr.writeInt32BE = BP.writeInt32BE
|
||
arr.writeFloatLE = BP.writeFloatLE
|
||
arr.writeFloatBE = BP.writeFloatBE
|
||
arr.writeDoubleLE = BP.writeDoubleLE
|
||
arr.writeDoubleBE = BP.writeDoubleBE
|
||
arr.fill = BP.fill
|
||
arr.inspect = BP.inspect
|
||
arr.toArrayBuffer = BP.toArrayBuffer
|
||
|
||
return arr
|
||
}
|
||
|
||
// slice(start, end)
|
||
function clamp (index, len, defaultValue) {
|
||
if (typeof index !== 'number') return defaultValue
|
||
index = ~~index; // Coerce to integer.
|
||
if (index >= len) return len
|
||
if (index >= 0) return index
|
||
index += len
|
||
if (index >= 0) return index
|
||
return 0
|
||
}
|
||
|
||
function coerce (length) {
|
||
// Coerce length to a number (possibly NaN), round up
|
||
// in case it's fractional (e.g. 123.456) then do a
|
||
// double negate to coerce a NaN to 0. Easy, right?
|
||
length = ~~Math.ceil(+length)
|
||
return length < 0 ? 0 : length
|
||
}
|
||
|
||
function isArray (subject) {
|
||
return (Array.isArray || function (subject) {
|
||
return Object.prototype.toString.call(subject) === '[object Array]'
|
||
})(subject)
|
||
}
|
||
|
||
function isArrayish (subject) {
|
||
return isArray(subject) || Buffer.isBuffer(subject) ||
|
||
subject && typeof subject === 'object' &&
|
||
typeof subject.length === 'number'
|
||
}
|
||
|
||
function toHex (n) {
|
||
if (n < 16) return '0' + n.toString(16)
|
||
return n.toString(16)
|
||
}
|
||
|
||
function utf8ToBytes (str) {
|
||
var byteArray = []
|
||
for (var i = 0; i < str.length; i++) {
|
||
var b = str.charCodeAt(i)
|
||
if (b <= 0x7F)
|
||
byteArray.push(str.charCodeAt(i))
|
||
else {
|
||
var start = i
|
||
if (b >= 0xD800 && b <= 0xDFFF) i++
|
||
var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%')
|
||
for (var j = 0; j < h.length; j++)
|
||
byteArray.push(parseInt(h[j], 16))
|
||
}
|
||
}
|
||
return byteArray
|
||
}
|
||
|
||
function asciiToBytes (str) {
|
||
var byteArray = []
|
||
for (var i = 0; i < str.length; i++) {
|
||
// Node's code seems to be doing this and not & 0x7F..
|
||
byteArray.push(str.charCodeAt(i) & 0xFF)
|
||
}
|
||
return byteArray
|
||
}
|
||
|
||
function utf16leToBytes (str) {
|
||
var c, hi, lo
|
||
var byteArray = []
|
||
for (var i = 0; i < str.length; i++) {
|
||
c = str.charCodeAt(i)
|
||
hi = c >> 8
|
||
lo = c % 256
|
||
byteArray.push(lo)
|
||
byteArray.push(hi)
|
||
}
|
||
|
||
return byteArray
|
||
}
|
||
|
||
function base64ToBytes (str) {
|
||
return base64.toByteArray(str)
|
||
}
|
||
|
||
function blitBuffer (src, dst, offset, length) {
|
||
var pos
|
||
for (var i = 0; i < length; i++) {
|
||
if ((i + offset >= dst.length) || (i >= src.length))
|
||
break
|
||
dst[i + offset] = src[i]
|
||
}
|
||
return i
|
||
}
|
||
|
||
function decodeUtf8Char (str) {
|
||
try {
|
||
return decodeURIComponent(str)
|
||
} catch (err) {
|
||
return String.fromCharCode(0xFFFD) // UTF 8 invalid char
|
||
}
|
||
}
|
||
|
||
/*
|
||
* We have to make sure that the value is a valid integer. This means that it
|
||
* is non-negative. It has no fractional component and that it does not
|
||
* exceed the maximum allowed value.
|
||
*/
|
||
function verifuint (value, max) {
|
||
assert(typeof value === 'number', 'cannot write a non-number as a number')
|
||
assert(value >= 0, 'specified a negative value for writing an unsigned value')
|
||
assert(value <= max, 'value is larger than maximum value for type')
|
||
assert(Math.floor(value) === value, 'value has a fractional component')
|
||
}
|
||
|
||
function verifsint (value, max, min) {
|
||
assert(typeof value === 'number', 'cannot write a non-number as a number')
|
||
assert(value <= max, 'value larger than maximum allowed value')
|
||
assert(value >= min, 'value smaller than minimum allowed value')
|
||
assert(Math.floor(value) === value, 'value has a fractional component')
|
||
}
|
||
|
||
function verifIEEE754 (value, max, min) {
|
||
assert(typeof value === 'number', 'cannot write a non-number as a number')
|
||
assert(value <= max, 'value larger than maximum allowed value')
|
||
assert(value >= min, 'value smaller than minimum allowed value')
|
||
}
|
||
|
||
function assert (test, message) {
|
||
if (!test) throw new Error(message || 'Failed assertion')
|
||
}
|
||
|
||
},{"base64-js":58,"ieee754":59}],58:[function(require,module,exports){
|
||
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||
|
||
;(function (exports) {
|
||
'use strict';
|
||
|
||
var Arr = (typeof Uint8Array !== 'undefined')
|
||
? Uint8Array
|
||
: Array
|
||
|
||
var PLUS = '+'.charCodeAt(0)
|
||
var SLASH = '/'.charCodeAt(0)
|
||
var NUMBER = '0'.charCodeAt(0)
|
||
var LOWER = 'a'.charCodeAt(0)
|
||
var UPPER = 'A'.charCodeAt(0)
|
||
|
||
function decode (elt) {
|
||
var code = elt.charCodeAt(0)
|
||
if (code === PLUS)
|
||
return 62 // '+'
|
||
if (code === SLASH)
|
||
return 63 // '/'
|
||
if (code < NUMBER)
|
||
return -1 //no match
|
||
if (code < NUMBER + 10)
|
||
return code - NUMBER + 26 + 26
|
||
if (code < UPPER + 26)
|
||
return code - UPPER
|
||
if (code < LOWER + 26)
|
||
return code - LOWER + 26
|
||
}
|
||
|
||
function b64ToByteArray (b64) {
|
||
var i, j, l, tmp, placeHolders, arr
|
||
|
||
if (b64.length % 4 > 0) {
|
||
throw new Error('Invalid string. Length must be a multiple of 4')
|
||
}
|
||
|
||
// the number of equal signs (place holders)
|
||
// if there are two placeholders, than the two characters before it
|
||
// represent one byte
|
||
// if there is only one, then the three characters before it represent 2 bytes
|
||
// this is just a cheap hack to not do indexOf twice
|
||
var len = b64.length
|
||
placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
|
||
|
||
// base64 is 4/3 + up to two characters of the original data
|
||
arr = new Arr(b64.length * 3 / 4 - placeHolders)
|
||
|
||
// if there are placeholders, only get up to the last complete 4 chars
|
||
l = placeHolders > 0 ? b64.length - 4 : b64.length
|
||
|
||
var L = 0
|
||
|
||
function push (v) {
|
||
arr[L++] = v
|
||
}
|
||
|
||
for (i = 0, j = 0; i < l; i += 4, j += 3) {
|
||
tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
|
||
push((tmp & 0xFF0000) >> 16)
|
||
push((tmp & 0xFF00) >> 8)
|
||
push(tmp & 0xFF)
|
||
}
|
||
|
||
if (placeHolders === 2) {
|
||
tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
|
||
push(tmp & 0xFF)
|
||
} else if (placeHolders === 1) {
|
||
tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
|
||
push((tmp >> 8) & 0xFF)
|
||
push(tmp & 0xFF)
|
||
}
|
||
|
||
return arr
|
||
}
|
||
|
||
function uint8ToBase64 (uint8) {
|
||
var i,
|
||
extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
|
||
output = "",
|
||
temp, length
|
||
|
||
function encode (num) {
|
||
return lookup.charAt(num)
|
||
}
|
||
|
||
function tripletToBase64 (num) {
|
||
return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
|
||
}
|
||
|
||
// go through the array every three bytes, we'll deal with trailing stuff later
|
||
for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
|
||
temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
|
||
output += tripletToBase64(temp)
|
||
}
|
||
|
||
// pad the end with zeros, but make sure to not forget the extra bytes
|
||
switch (extraBytes) {
|
||
case 1:
|
||
temp = uint8[uint8.length - 1]
|
||
output += encode(temp >> 2)
|
||
output += encode((temp << 4) & 0x3F)
|
||
output += '=='
|
||
break
|
||
case 2:
|
||
temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
|
||
output += encode(temp >> 10)
|
||
output += encode((temp >> 4) & 0x3F)
|
||
output += encode((temp << 2) & 0x3F)
|
||
output += '='
|
||
break
|
||
}
|
||
|
||
return output
|
||
}
|
||
|
||
exports.toByteArray = b64ToByteArray
|
||
exports.fromByteArray = uint8ToBase64
|
||
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
|
||
|
||
},{}],59:[function(require,module,exports){
|
||
exports.read = function(buffer, offset, isLE, mLen, nBytes) {
|
||
var e, m,
|
||
eLen = nBytes * 8 - mLen - 1,
|
||
eMax = (1 << eLen) - 1,
|
||
eBias = eMax >> 1,
|
||
nBits = -7,
|
||
i = isLE ? (nBytes - 1) : 0,
|
||
d = isLE ? -1 : 1,
|
||
s = buffer[offset + i];
|
||
|
||
i += d;
|
||
|
||
e = s & ((1 << (-nBits)) - 1);
|
||
s >>= (-nBits);
|
||
nBits += eLen;
|
||
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
|
||
|
||
m = e & ((1 << (-nBits)) - 1);
|
||
e >>= (-nBits);
|
||
nBits += mLen;
|
||
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
|
||
|
||
if (e === 0) {
|
||
e = 1 - eBias;
|
||
} else if (e === eMax) {
|
||
return m ? NaN : ((s ? -1 : 1) * Infinity);
|
||
} else {
|
||
m = m + Math.pow(2, mLen);
|
||
e = e - eBias;
|
||
}
|
||
return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
|
||
};
|
||
|
||
exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
|
||
var e, m, c,
|
||
eLen = nBytes * 8 - mLen - 1,
|
||
eMax = (1 << eLen) - 1,
|
||
eBias = eMax >> 1,
|
||
rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
|
||
i = isLE ? 0 : (nBytes - 1),
|
||
d = isLE ? 1 : -1,
|
||
s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
|
||
|
||
value = Math.abs(value);
|
||
|
||
if (isNaN(value) || value === Infinity) {
|
||
m = isNaN(value) ? 1 : 0;
|
||
e = eMax;
|
||
} else {
|
||
e = Math.floor(Math.log(value) / Math.LN2);
|
||
if (value * (c = Math.pow(2, -e)) < 1) {
|
||
e--;
|
||
c *= 2;
|
||
}
|
||
if (e + eBias >= 1) {
|
||
value += rt / c;
|
||
} else {
|
||
value += rt * Math.pow(2, 1 - eBias);
|
||
}
|
||
if (value * c >= 2) {
|
||
e++;
|
||
c /= 2;
|
||
}
|
||
|
||
if (e + eBias >= eMax) {
|
||
m = 0;
|
||
e = eMax;
|
||
} else if (e + eBias >= 1) {
|
||
m = (value * c - 1) * Math.pow(2, mLen);
|
||
e = e + eBias;
|
||
} else {
|
||
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
|
||
e = 0;
|
||
}
|
||
}
|
||
|
||
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);
|
||
|
||
e = (e << mLen) | m;
|
||
eLen += mLen;
|
||
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);
|
||
|
||
buffer[offset + i - d] |= s * 128;
|
||
};
|
||
|
||
},{}],60:[function(require,module,exports){
|
||
if (typeof Object.create === 'function') {
|
||
// implementation from standard node.js 'util' module
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
ctor.super_ = superCtor
|
||
ctor.prototype = Object.create(superCtor.prototype, {
|
||
constructor: {
|
||
value: ctor,
|
||
enumerable: false,
|
||
writable: true,
|
||
configurable: true
|
||
}
|
||
});
|
||
};
|
||
} else {
|
||
// old school shim for old browsers
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
ctor.super_ = superCtor
|
||
var TempCtor = function () {}
|
||
TempCtor.prototype = superCtor.prototype
|
||
ctor.prototype = new TempCtor()
|
||
ctor.prototype.constructor = ctor
|
||
}
|
||
}
|
||
|
||
},{}],61:[function(require,module,exports){
|
||
(function (process){
|
||
// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// 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", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
// resolves . and .. elements in a path array with directory names there
|
||
// must be no slashes, empty elements, or device names (c:\) in the array
|
||
// (so also no leading and trailing slashes - it does not distinguish
|
||
// relative and absolute paths)
|
||
function normalizeArray(parts, allowAboveRoot) {
|
||
// if the path tries to go above the root, `up` ends up > 0
|
||
var up = 0;
|
||
for (var i = parts.length - 1; i >= 0; i--) {
|
||
var last = parts[i];
|
||
if (last === '.') {
|
||
parts.splice(i, 1);
|
||
} else if (last === '..') {
|
||
parts.splice(i, 1);
|
||
up++;
|
||
} else if (up) {
|
||
parts.splice(i, 1);
|
||
up--;
|
||
}
|
||
}
|
||
|
||
// if the path is allowed to go above the root, restore leading ..s
|
||
if (allowAboveRoot) {
|
||
for (; up--; up) {
|
||
parts.unshift('..');
|
||
}
|
||
}
|
||
|
||
return parts;
|
||
}
|
||
|
||
// Split a filename into [root, dir, basename, ext], unix version
|
||
// 'root' is just a slash, or nothing.
|
||
var splitPathRe =
|
||
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
|
||
var splitPath = function(filename) {
|
||
return splitPathRe.exec(filename).slice(1);
|
||
};
|
||
|
||
// path.resolve([from ...], to)
|
||
// posix version
|
||
exports.resolve = function() {
|
||
var resolvedPath = '',
|
||
resolvedAbsolute = false;
|
||
|
||
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
|
||
var path = (i >= 0) ? arguments[i] : process.cwd();
|
||
|
||
// Skip empty and invalid entries
|
||
if (typeof path !== 'string') {
|
||
throw new TypeError('Arguments to path.resolve must be strings');
|
||
} else if (!path) {
|
||
continue;
|
||
}
|
||
|
||
resolvedPath = path + '/' + resolvedPath;
|
||
resolvedAbsolute = path.charAt(0) === '/';
|
||
}
|
||
|
||
// At this point the path should be resolved to a full absolute path, but
|
||
// handle relative paths to be safe (might happen when process.cwd() fails)
|
||
|
||
// Normalize the path
|
||
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
|
||
return !!p;
|
||
}), !resolvedAbsolute).join('/');
|
||
|
||
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
|
||
};
|
||
|
||
// path.normalize(path)
|
||
// posix version
|
||
exports.normalize = function(path) {
|
||
var isAbsolute = exports.isAbsolute(path),
|
||
trailingSlash = substr(path, -1) === '/';
|
||
|
||
// Normalize the path
|
||
path = normalizeArray(filter(path.split('/'), function(p) {
|
||
return !!p;
|
||
}), !isAbsolute).join('/');
|
||
|
||
if (!path && !isAbsolute) {
|
||
path = '.';
|
||
}
|
||
if (path && trailingSlash) {
|
||
path += '/';
|
||
}
|
||
|
||
return (isAbsolute ? '/' : '') + path;
|
||
};
|
||
|
||
// posix version
|
||
exports.isAbsolute = function(path) {
|
||
return path.charAt(0) === '/';
|
||
};
|
||
|
||
// posix version
|
||
exports.join = function() {
|
||
var paths = Array.prototype.slice.call(arguments, 0);
|
||
return exports.normalize(filter(paths, function(p, index) {
|
||
if (typeof p !== 'string') {
|
||
throw new TypeError('Arguments to path.join must be strings');
|
||
}
|
||
return p;
|
||
}).join('/'));
|
||
};
|
||
|
||
|
||
// path.relative(from, to)
|
||
// posix version
|
||
exports.relative = function(from, to) {
|
||
from = exports.resolve(from).substr(1);
|
||
to = exports.resolve(to).substr(1);
|
||
|
||
function trim(arr) {
|
||
var start = 0;
|
||
for (; start < arr.length; start++) {
|
||
if (arr[start] !== '') break;
|
||
}
|
||
|
||
var end = arr.length - 1;
|
||
for (; end >= 0; end--) {
|
||
if (arr[end] !== '') break;
|
||
}
|
||
|
||
if (start > end) return [];
|
||
return arr.slice(start, end - start + 1);
|
||
}
|
||
|
||
var fromParts = trim(from.split('/'));
|
||
var toParts = trim(to.split('/'));
|
||
|
||
var length = Math.min(fromParts.length, toParts.length);
|
||
var samePartsLength = length;
|
||
for (var i = 0; i < length; i++) {
|
||
if (fromParts[i] !== toParts[i]) {
|
||
samePartsLength = i;
|
||
break;
|
||
}
|
||
}
|
||
|
||
var outputParts = [];
|
||
for (var i = samePartsLength; i < fromParts.length; i++) {
|
||
outputParts.push('..');
|
||
}
|
||
|
||
outputParts = outputParts.concat(toParts.slice(samePartsLength));
|
||
|
||
return outputParts.join('/');
|
||
};
|
||
|
||
exports.sep = '/';
|
||
exports.delimiter = ':';
|
||
|
||
exports.dirname = function(path) {
|
||
var result = splitPath(path),
|
||
root = result[0],
|
||
dir = result[1];
|
||
|
||
if (!root && !dir) {
|
||
// No dirname whatsoever
|
||
return '.';
|
||
}
|
||
|
||
if (dir) {
|
||
// It has a dirname, strip trailing slash
|
||
dir = dir.substr(0, dir.length - 1);
|
||
}
|
||
|
||
return root + dir;
|
||
};
|
||
|
||
|
||
exports.basename = function(path, ext) {
|
||
var f = splitPath(path)[2];
|
||
// TODO: make this comparison case-insensitive on windows?
|
||
if (ext && f.substr(-1 * ext.length) === ext) {
|
||
f = f.substr(0, f.length - ext.length);
|
||
}
|
||
return f;
|
||
};
|
||
|
||
|
||
exports.extname = function(path) {
|
||
return splitPath(path)[3];
|
||
};
|
||
|
||
function filter (xs, f) {
|
||
if (xs.filter) return xs.filter(f);
|
||
var res = [];
|
||
for (var i = 0; i < xs.length; i++) {
|
||
if (f(xs[i], i, xs)) res.push(xs[i]);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
// String.prototype.substr - negative index don't work in IE8
|
||
var substr = 'ab'.substr(-1) === 'b'
|
||
? function (str, start, len) { return str.substr(start, len) }
|
||
: function (str, start, len) {
|
||
if (start < 0) start = str.length + start;
|
||
return str.substr(start, len);
|
||
}
|
||
;
|
||
|
||
}).call(this,require("1YiZ5S"))
|
||
},{"1YiZ5S":62}],62:[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) {
|
||
var source = ev.source;
|
||
if ((source === window || source === null) && 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 = [];
|
||
|
||
function noop() {}
|
||
|
||
process.on = noop;
|
||
process.addListener = noop;
|
||
process.once = noop;
|
||
process.off = noop;
|
||
process.removeListener = noop;
|
||
process.removeAllListeners = noop;
|
||
process.emit = noop;
|
||
|
||
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');
|
||
};
|
||
|
||
},{}],63:[function(require,module,exports){
|
||
module.exports = function isBuffer(arg) {
|
||
return arg && typeof arg === 'object'
|
||
&& typeof arg.copy === 'function'
|
||
&& typeof arg.fill === 'function'
|
||
&& typeof arg.readUInt8 === 'function';
|
||
}
|
||
},{}],64:[function(require,module,exports){
|
||
(function (process,global){
|
||
// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// 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", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
var formatRegExp = /%[sdj%]/g;
|
||
exports.format = function(f) {
|
||
if (!isString(f)) {
|
||
var objects = [];
|
||
for (var i = 0; i < arguments.length; i++) {
|
||
objects.push(inspect(arguments[i]));
|
||
}
|
||
return objects.join(' ');
|
||
}
|
||
|
||
var i = 1;
|
||
var args = arguments;
|
||
var len = args.length;
|
||
var str = String(f).replace(formatRegExp, function(x) {
|
||
if (x === '%%') return '%';
|
||
if (i >= len) return x;
|
||
switch (x) {
|
||
case '%s': return String(args[i++]);
|
||
case '%d': return Number(args[i++]);
|
||
case '%j':
|
||
try {
|
||
return JSON.stringify(args[i++]);
|
||
} catch (_) {
|
||
return '[Circular]';
|
||
}
|
||
default:
|
||
return x;
|
||
}
|
||
});
|
||
for (var x = args[i]; i < len; x = args[++i]) {
|
||
if (isNull(x) || !isObject(x)) {
|
||
str += ' ' + x;
|
||
} else {
|
||
str += ' ' + inspect(x);
|
||
}
|
||
}
|
||
return str;
|
||
};
|
||
|
||
|
||
// Mark that a method should not be used.
|
||
// Returns a modified function which warns once by default.
|
||
// If --no-deprecation is set, then it is a no-op.
|
||
exports.deprecate = function(fn, msg) {
|
||
// Allow for deprecating things in the process of starting up.
|
||
if (isUndefined(global.process)) {
|
||
return function() {
|
||
return exports.deprecate(fn, msg).apply(this, arguments);
|
||
};
|
||
}
|
||
|
||
if (process.noDeprecation === true) {
|
||
return fn;
|
||
}
|
||
|
||
var warned = false;
|
||
function deprecated() {
|
||
if (!warned) {
|
||
if (process.throwDeprecation) {
|
||
throw new Error(msg);
|
||
} else if (process.traceDeprecation) {
|
||
console.trace(msg);
|
||
} else {
|
||
console.error(msg);
|
||
}
|
||
warned = true;
|
||
}
|
||
return fn.apply(this, arguments);
|
||
}
|
||
|
||
return deprecated;
|
||
};
|
||
|
||
|
||
var debugs = {};
|
||
var debugEnviron;
|
||
exports.debuglog = function(set) {
|
||
if (isUndefined(debugEnviron))
|
||
debugEnviron = process.env.NODE_DEBUG || '';
|
||
set = set.toUpperCase();
|
||
if (!debugs[set]) {
|
||
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
|
||
var pid = process.pid;
|
||
debugs[set] = function() {
|
||
var msg = exports.format.apply(exports, arguments);
|
||
console.error('%s %d: %s', set, pid, msg);
|
||
};
|
||
} else {
|
||
debugs[set] = function() {};
|
||
}
|
||
}
|
||
return debugs[set];
|
||
};
|
||
|
||
|
||
/**
|
||
* Echos the value of a value. Trys to print the value out
|
||
* in the best way possible given the different types.
|
||
*
|
||
* @param {Object} obj The object to print out.
|
||
* @param {Object} opts Optional options object that alters the output.
|
||
*/
|
||
/* legacy: obj, showHidden, depth, colors*/
|
||
function inspect(obj, opts) {
|
||
// default options
|
||
var ctx = {
|
||
seen: [],
|
||
stylize: stylizeNoColor
|
||
};
|
||
// legacy...
|
||
if (arguments.length >= 3) ctx.depth = arguments[2];
|
||
if (arguments.length >= 4) ctx.colors = arguments[3];
|
||
if (isBoolean(opts)) {
|
||
// legacy...
|
||
ctx.showHidden = opts;
|
||
} else if (opts) {
|
||
// got an "options" object
|
||
exports._extend(ctx, opts);
|
||
}
|
||
// set default options
|
||
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
|
||
if (isUndefined(ctx.depth)) ctx.depth = 2;
|
||
if (isUndefined(ctx.colors)) ctx.colors = false;
|
||
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
|
||
if (ctx.colors) ctx.stylize = stylizeWithColor;
|
||
return formatValue(ctx, obj, ctx.depth);
|
||
}
|
||
exports.inspect = inspect;
|
||
|
||
|
||
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
|
||
inspect.colors = {
|
||
'bold' : [1, 22],
|
||
'italic' : [3, 23],
|
||
'underline' : [4, 24],
|
||
'inverse' : [7, 27],
|
||
'white' : [37, 39],
|
||
'grey' : [90, 39],
|
||
'black' : [30, 39],
|
||
'blue' : [34, 39],
|
||
'cyan' : [36, 39],
|
||
'green' : [32, 39],
|
||
'magenta' : [35, 39],
|
||
'red' : [31, 39],
|
||
'yellow' : [33, 39]
|
||
};
|
||
|
||
// Don't use 'blue' not visible on cmd.exe
|
||
inspect.styles = {
|
||
'special': 'cyan',
|
||
'number': 'yellow',
|
||
'boolean': 'yellow',
|
||
'undefined': 'grey',
|
||
'null': 'bold',
|
||
'string': 'green',
|
||
'date': 'magenta',
|
||
// "name": intentionally not styling
|
||
'regexp': 'red'
|
||
};
|
||
|
||
|
||
function stylizeWithColor(str, styleType) {
|
||
var style = inspect.styles[styleType];
|
||
|
||
if (style) {
|
||
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
|
||
'\u001b[' + inspect.colors[style][1] + 'm';
|
||
} else {
|
||
return str;
|
||
}
|
||
}
|
||
|
||
|
||
function stylizeNoColor(str, styleType) {
|
||
return str;
|
||
}
|
||
|
||
|
||
function arrayToHash(array) {
|
||
var hash = {};
|
||
|
||
array.forEach(function(val, idx) {
|
||
hash[val] = true;
|
||
});
|
||
|
||
return hash;
|
||
}
|
||
|
||
|
||
function formatValue(ctx, value, recurseTimes) {
|
||
// Provide a hook for user-specified inspect functions.
|
||
// Check that value is an object with an inspect function on it
|
||
if (ctx.customInspect &&
|
||
value &&
|
||
isFunction(value.inspect) &&
|
||
// Filter out the util module, it's inspect function is special
|
||
value.inspect !== exports.inspect &&
|
||
// Also filter out any prototype objects using the circular check.
|
||
!(value.constructor && value.constructor.prototype === value)) {
|
||
var ret = value.inspect(recurseTimes, ctx);
|
||
if (!isString(ret)) {
|
||
ret = formatValue(ctx, ret, recurseTimes);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
// Primitive types cannot have properties
|
||
var primitive = formatPrimitive(ctx, value);
|
||
if (primitive) {
|
||
return primitive;
|
||
}
|
||
|
||
// Look up the keys of the object.
|
||
var keys = Object.keys(value);
|
||
var visibleKeys = arrayToHash(keys);
|
||
|
||
if (ctx.showHidden) {
|
||
keys = Object.getOwnPropertyNames(value);
|
||
}
|
||
|
||
// IE doesn't make error fields non-enumerable
|
||
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
|
||
if (isError(value)
|
||
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
|
||
return formatError(value);
|
||
}
|
||
|
||
// Some type of object without properties can be shortcutted.
|
||
if (keys.length === 0) {
|
||
if (isFunction(value)) {
|
||
var name = value.name ? ': ' + value.name : '';
|
||
return ctx.stylize('[Function' + name + ']', 'special');
|
||
}
|
||
if (isRegExp(value)) {
|
||
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
||
}
|
||
if (isDate(value)) {
|
||
return ctx.stylize(Date.prototype.toString.call(value), 'date');
|
||
}
|
||
if (isError(value)) {
|
||
return formatError(value);
|
||
}
|
||
}
|
||
|
||
var base = '', array = false, braces = ['{', '}'];
|
||
|
||
// Make Array say that they are Array
|
||
if (isArray(value)) {
|
||
array = true;
|
||
braces = ['[', ']'];
|
||
}
|
||
|
||
// Make functions say that they are functions
|
||
if (isFunction(value)) {
|
||
var n = value.name ? ': ' + value.name : '';
|
||
base = ' [Function' + n + ']';
|
||
}
|
||
|
||
// Make RegExps say that they are RegExps
|
||
if (isRegExp(value)) {
|
||
base = ' ' + RegExp.prototype.toString.call(value);
|
||
}
|
||
|
||
// Make dates with properties first say the date
|
||
if (isDate(value)) {
|
||
base = ' ' + Date.prototype.toUTCString.call(value);
|
||
}
|
||
|
||
// Make error with message first say the error
|
||
if (isError(value)) {
|
||
base = ' ' + formatError(value);
|
||
}
|
||
|
||
if (keys.length === 0 && (!array || value.length == 0)) {
|
||
return braces[0] + base + braces[1];
|
||
}
|
||
|
||
if (recurseTimes < 0) {
|
||
if (isRegExp(value)) {
|
||
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
||
} else {
|
||
return ctx.stylize('[Object]', 'special');
|
||
}
|
||
}
|
||
|
||
ctx.seen.push(value);
|
||
|
||
var output;
|
||
if (array) {
|
||
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
|
||
} else {
|
||
output = keys.map(function(key) {
|
||
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
|
||
});
|
||
}
|
||
|
||
ctx.seen.pop();
|
||
|
||
return reduceToSingleString(output, base, braces);
|
||
}
|
||
|
||
|
||
function formatPrimitive(ctx, value) {
|
||
if (isUndefined(value))
|
||
return ctx.stylize('undefined', 'undefined');
|
||
if (isString(value)) {
|
||
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
|
||
.replace(/'/g, "\\'")
|
||
.replace(/\\"/g, '"') + '\'';
|
||
return ctx.stylize(simple, 'string');
|
||
}
|
||
if (isNumber(value))
|
||
return ctx.stylize('' + value, 'number');
|
||
if (isBoolean(value))
|
||
return ctx.stylize('' + value, 'boolean');
|
||
// For some reason typeof null is "object", so special case here.
|
||
if (isNull(value))
|
||
return ctx.stylize('null', 'null');
|
||
}
|
||
|
||
|
||
function formatError(value) {
|
||
return '[' + Error.prototype.toString.call(value) + ']';
|
||
}
|
||
|
||
|
||
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
|
||
var output = [];
|
||
for (var i = 0, l = value.length; i < l; ++i) {
|
||
if (hasOwnProperty(value, String(i))) {
|
||
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
||
String(i), true));
|
||
} else {
|
||
output.push('');
|
||
}
|
||
}
|
||
keys.forEach(function(key) {
|
||
if (!key.match(/^\d+$/)) {
|
||
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
||
key, true));
|
||
}
|
||
});
|
||
return output;
|
||
}
|
||
|
||
|
||
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
|
||
var name, str, desc;
|
||
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
|
||
if (desc.get) {
|
||
if (desc.set) {
|
||
str = ctx.stylize('[Getter/Setter]', 'special');
|
||
} else {
|
||
str = ctx.stylize('[Getter]', 'special');
|
||
}
|
||
} else {
|
||
if (desc.set) {
|
||
str = ctx.stylize('[Setter]', 'special');
|
||
}
|
||
}
|
||
if (!hasOwnProperty(visibleKeys, key)) {
|
||
name = '[' + key + ']';
|
||
}
|
||
if (!str) {
|
||
if (ctx.seen.indexOf(desc.value) < 0) {
|
||
if (isNull(recurseTimes)) {
|
||
str = formatValue(ctx, desc.value, null);
|
||
} else {
|
||
str = formatValue(ctx, desc.value, recurseTimes - 1);
|
||
}
|
||
if (str.indexOf('\n') > -1) {
|
||
if (array) {
|
||
str = str.split('\n').map(function(line) {
|
||
return ' ' + line;
|
||
}).join('\n').substr(2);
|
||
} else {
|
||
str = '\n' + str.split('\n').map(function(line) {
|
||
return ' ' + line;
|
||
}).join('\n');
|
||
}
|
||
}
|
||
} else {
|
||
str = ctx.stylize('[Circular]', 'special');
|
||
}
|
||
}
|
||
if (isUndefined(name)) {
|
||
if (array && key.match(/^\d+$/)) {
|
||
return str;
|
||
}
|
||
name = JSON.stringify('' + key);
|
||
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
||
name = name.substr(1, name.length - 2);
|
||
name = ctx.stylize(name, 'name');
|
||
} else {
|
||
name = name.replace(/'/g, "\\'")
|
||
.replace(/\\"/g, '"')
|
||
.replace(/(^"|"$)/g, "'");
|
||
name = ctx.stylize(name, 'string');
|
||
}
|
||
}
|
||
|
||
return name + ': ' + str;
|
||
}
|
||
|
||
|
||
function reduceToSingleString(output, base, braces) {
|
||
var numLinesEst = 0;
|
||
var length = output.reduce(function(prev, cur) {
|
||
numLinesEst++;
|
||
if (cur.indexOf('\n') >= 0) numLinesEst++;
|
||
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
|
||
}, 0);
|
||
|
||
if (length > 60) {
|
||
return braces[0] +
|
||
(base === '' ? '' : base + '\n ') +
|
||
' ' +
|
||
output.join(',\n ') +
|
||
' ' +
|
||
braces[1];
|
||
}
|
||
|
||
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
|
||
}
|
||
|
||
|
||
// NOTE: These type checking functions intentionally don't use `instanceof`
|
||
// because it is fragile and can be easily faked with `Object.create()`.
|
||
function isArray(ar) {
|
||
return Array.isArray(ar);
|
||
}
|
||
exports.isArray = isArray;
|
||
|
||
function isBoolean(arg) {
|
||
return typeof arg === 'boolean';
|
||
}
|
||
exports.isBoolean = isBoolean;
|
||
|
||
function isNull(arg) {
|
||
return arg === null;
|
||
}
|
||
exports.isNull = isNull;
|
||
|
||
function isNullOrUndefined(arg) {
|
||
return arg == null;
|
||
}
|
||
exports.isNullOrUndefined = isNullOrUndefined;
|
||
|
||
function isNumber(arg) {
|
||
return typeof arg === 'number';
|
||
}
|
||
exports.isNumber = isNumber;
|
||
|
||
function isString(arg) {
|
||
return typeof arg === 'string';
|
||
}
|
||
exports.isString = isString;
|
||
|
||
function isSymbol(arg) {
|
||
return typeof arg === 'symbol';
|
||
}
|
||
exports.isSymbol = isSymbol;
|
||
|
||
function isUndefined(arg) {
|
||
return arg === void 0;
|
||
}
|
||
exports.isUndefined = isUndefined;
|
||
|
||
function isRegExp(re) {
|
||
return isObject(re) && objectToString(re) === '[object RegExp]';
|
||
}
|
||
exports.isRegExp = isRegExp;
|
||
|
||
function isObject(arg) {
|
||
return typeof arg === 'object' && arg !== null;
|
||
}
|
||
exports.isObject = isObject;
|
||
|
||
function isDate(d) {
|
||
return isObject(d) && objectToString(d) === '[object Date]';
|
||
}
|
||
exports.isDate = isDate;
|
||
|
||
function isError(e) {
|
||
return isObject(e) &&
|
||
(objectToString(e) === '[object Error]' || e instanceof Error);
|
||
}
|
||
exports.isError = isError;
|
||
|
||
function isFunction(arg) {
|
||
return typeof arg === 'function';
|
||
}
|
||
exports.isFunction = isFunction;
|
||
|
||
function isPrimitive(arg) {
|
||
return arg === null ||
|
||
typeof arg === 'boolean' ||
|
||
typeof arg === 'number' ||
|
||
typeof arg === 'string' ||
|
||
typeof arg === 'symbol' || // ES6 symbol
|
||
typeof arg === 'undefined';
|
||
}
|
||
exports.isPrimitive = isPrimitive;
|
||
|
||
exports.isBuffer = require('./support/isBuffer');
|
||
|
||
function objectToString(o) {
|
||
return Object.prototype.toString.call(o);
|
||
}
|
||
|
||
|
||
function pad(n) {
|
||
return n < 10 ? '0' + n.toString(10) : n.toString(10);
|
||
}
|
||
|
||
|
||
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
|
||
'Oct', 'Nov', 'Dec'];
|
||
|
||
// 26 Feb 16:19:34
|
||
function timestamp() {
|
||
var d = new Date();
|
||
var time = [pad(d.getHours()),
|
||
pad(d.getMinutes()),
|
||
pad(d.getSeconds())].join(':');
|
||
return [d.getDate(), months[d.getMonth()], time].join(' ');
|
||
}
|
||
|
||
|
||
// log is just a thin wrapper to console.log that prepends a timestamp
|
||
exports.log = function() {
|
||
console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
|
||
};
|
||
|
||
|
||
/**
|
||
* Inherit the prototype methods from one constructor into another.
|
||
*
|
||
* The Function.prototype.inherits from lang.js rewritten as a standalone
|
||
* function (not on Function.prototype). NOTE: If this file is to be loaded
|
||
* during bootstrapping this function needs to be rewritten using some native
|
||
* functions as prototype setup using normal JavaScript does not work as
|
||
* expected during bootstrapping (see mirror.js in r114903).
|
||
*
|
||
* @param {function} ctor Constructor function which needs to inherit the
|
||
* prototype.
|
||
* @param {function} superCtor Constructor function to inherit prototype from.
|
||
*/
|
||
exports.inherits = require('inherits');
|
||
|
||
exports._extend = function(origin, add) {
|
||
// Don't do anything if add isn't an object
|
||
if (!add || !isObject(add)) return origin;
|
||
|
||
var keys = Object.keys(add);
|
||
var i = keys.length;
|
||
while (i--) {
|
||
origin[keys[i]] = add[keys[i]];
|
||
}
|
||
return origin;
|
||
};
|
||
|
||
function hasOwnProperty(obj, prop) {
|
||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||
}
|
||
|
||
}).call(this,require("1YiZ5S"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
},{"./support/isBuffer":63,"1YiZ5S":62,"inherits":60}],65:[function(require,module,exports){
|
||
var indexOf = require('indexof');
|
||
|
||
var Object_keys = function (obj) {
|
||
if (Object.keys) return Object.keys(obj)
|
||
else {
|
||
var res = [];
|
||
for (var key in obj) res.push(key)
|
||
return res;
|
||
}
|
||
};
|
||
|
||
var forEach = function (xs, fn) {
|
||
if (xs.forEach) return xs.forEach(fn)
|
||
else for (var i = 0; i < xs.length; i++) {
|
||
fn(xs[i], i, xs);
|
||
}
|
||
};
|
||
|
||
var defineProp = (function() {
|
||
try {
|
||
Object.defineProperty({}, '_', {});
|
||
return function(obj, name, value) {
|
||
Object.defineProperty(obj, name, {
|
||
writable: true,
|
||
enumerable: false,
|
||
configurable: true,
|
||
value: value
|
||
})
|
||
};
|
||
} catch(e) {
|
||
return function(obj, name, value) {
|
||
obj[name] = value;
|
||
};
|
||
}
|
||
}());
|
||
|
||
var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function',
|
||
'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError',
|
||
'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError',
|
||
'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape',
|
||
'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape'];
|
||
|
||
function Context() {}
|
||
Context.prototype = {};
|
||
|
||
var Script = exports.Script = function NodeScript (code) {
|
||
if (!(this instanceof Script)) return new Script(code);
|
||
this.code = code;
|
||
};
|
||
|
||
Script.prototype.runInContext = function (context) {
|
||
if (!(context instanceof Context)) {
|
||
throw new TypeError("needs a 'context' argument.");
|
||
}
|
||
|
||
var iframe = document.createElement('iframe');
|
||
if (!iframe.style) iframe.style = {};
|
||
iframe.style.display = 'none';
|
||
|
||
document.body.appendChild(iframe);
|
||
|
||
var win = iframe.contentWindow;
|
||
var wEval = win.eval, wExecScript = win.execScript;
|
||
|
||
if (!wEval && wExecScript) {
|
||
// win.eval() magically appears when this is called in IE:
|
||
wExecScript.call(win, 'null');
|
||
wEval = win.eval;
|
||
}
|
||
|
||
forEach(Object_keys(context), function (key) {
|
||
win[key] = context[key];
|
||
});
|
||
forEach(globals, function (key) {
|
||
if (context[key]) {
|
||
win[key] = context[key];
|
||
}
|
||
});
|
||
|
||
var winKeys = Object_keys(win);
|
||
|
||
var res = wEval.call(win, this.code);
|
||
|
||
forEach(Object_keys(win), function (key) {
|
||
// Avoid copying circular objects like `top` and `window` by only
|
||
// updating existing context properties or new properties in the `win`
|
||
// that was only introduced after the eval.
|
||
if (key in context || indexOf(winKeys, key) === -1) {
|
||
context[key] = win[key];
|
||
}
|
||
});
|
||
|
||
forEach(globals, function (key) {
|
||
if (!(key in context)) {
|
||
defineProp(context, key, win[key]);
|
||
}
|
||
});
|
||
|
||
document.body.removeChild(iframe);
|
||
|
||
return res;
|
||
};
|
||
|
||
Script.prototype.runInThisContext = function () {
|
||
return eval(this.code); // maybe...
|
||
};
|
||
|
||
Script.prototype.runInNewContext = function (context) {
|
||
var ctx = Script.createContext(context);
|
||
var res = this.runInContext(ctx);
|
||
|
||
forEach(Object_keys(ctx), function (key) {
|
||
context[key] = ctx[key];
|
||
});
|
||
|
||
return res;
|
||
};
|
||
|
||
forEach(Object_keys(Script.prototype), function (name) {
|
||
exports[name] = Script[name] = function (code) {
|
||
var s = Script(code);
|
||
return s[name].apply(s, [].slice.call(arguments, 1));
|
||
};
|
||
});
|
||
|
||
exports.createScript = function (code) {
|
||
return exports.Script(code);
|
||
};
|
||
|
||
exports.createContext = Script.createContext = function (context) {
|
||
var copy = new Context();
|
||
if(typeof context === 'object') {
|
||
forEach(Object_keys(context), function (key) {
|
||
copy[key] = context[key];
|
||
});
|
||
}
|
||
return copy;
|
||
};
|
||
|
||
},{"indexof":66}],66:[function(require,module,exports){
|
||
|
||
var indexOf = [].indexOf;
|
||
|
||
module.exports = function(arr, obj){
|
||
if (indexOf) return arr.indexOf(obj);
|
||
for (var i = 0; i < arr.length; ++i) {
|
||
if (arr[i] === obj) return i;
|
||
}
|
||
return -1;
|
||
};
|
||
},{}],67:[function(require,module,exports){
|
||
/*!
|
||
* jQuery JavaScript Library v2.1.1
|
||
* http://jquery.com/
|
||
*
|
||
* Includes Sizzle.js
|
||
* http://sizzlejs.com/
|
||
*
|
||
* Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
|
||
* Released under the MIT license
|
||
* http://jquery.org/license
|
||
*
|
||
* Date: 2014-05-01T17:11Z
|
||
*/
|
||
|
||
(function( global, factory ) {
|
||
|
||
if ( typeof module === "object" && typeof module.exports === "object" ) {
|
||
// For CommonJS and CommonJS-like environments where a proper window is present,
|
||
// execute the factory and get jQuery
|
||
// For environments that do not inherently posses a window with a document
|
||
// (such as Node.js), expose a jQuery-making factory as module.exports
|
||
// This accentuates the need for the creation of a real window
|
||
// e.g. var jQuery = require("jquery")(window);
|
||
// See ticket #14549 for more info
|
||
module.exports = global.document ?
|
||
factory( global, true ) :
|
||
function( w ) {
|
||
if ( !w.document ) {
|
||
throw new Error( "jQuery requires a window with a document" );
|
||
}
|
||
return factory( w );
|
||
};
|
||
} else {
|
||
factory( global );
|
||
}
|
||
|
||
// Pass this if window is not defined yet
|
||
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
|
||
|
||
// Can't do this because several apps including ASP.NET trace
|
||
// the stack via arguments.caller.callee and Firefox dies if
|
||
// you try to trace through "use strict" call chains. (#13335)
|
||
// Support: Firefox 18+
|
||
//
|
||
|
||
var arr = [];
|
||
|
||
var slice = arr.slice;
|
||
|
||
var concat = arr.concat;
|
||
|
||
var push = arr.push;
|
||
|
||
var indexOf = arr.indexOf;
|
||
|
||
var class2type = {};
|
||
|
||
var toString = class2type.toString;
|
||
|
||
var hasOwn = class2type.hasOwnProperty;
|
||
|
||
var support = {};
|
||
|
||
|
||
|
||
var
|
||
// Use the correct document accordingly with window argument (sandbox)
|
||
document = window.document,
|
||
|
||
version = "2.1.1",
|
||
|
||
// Define a local copy of jQuery
|
||
jQuery = function( selector, context ) {
|
||
// The jQuery object is actually just the init constructor 'enhanced'
|
||
// Need init if jQuery is called (just allow error to be thrown if not included)
|
||
return new jQuery.fn.init( selector, context );
|
||
},
|
||
|
||
// Support: Android<4.1
|
||
// Make sure we trim BOM and NBSP
|
||
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
|
||
|
||
// Matches dashed string for camelizing
|
||
rmsPrefix = /^-ms-/,
|
||
rdashAlpha = /-([\da-z])/gi,
|
||
|
||
// Used by jQuery.camelCase as callback to replace()
|
||
fcamelCase = function( all, letter ) {
|
||
return letter.toUpperCase();
|
||
};
|
||
|
||
jQuery.fn = jQuery.prototype = {
|
||
// The current version of jQuery being used
|
||
jquery: version,
|
||
|
||
constructor: jQuery,
|
||
|
||
// Start with an empty selector
|
||
selector: "",
|
||
|
||
// The default length of a jQuery object is 0
|
||
length: 0,
|
||
|
||
toArray: function() {
|
||
return slice.call( this );
|
||
},
|
||
|
||
// Get the Nth element in the matched element set OR
|
||
// Get the whole matched element set as a clean array
|
||
get: function( num ) {
|
||
return num != null ?
|
||
|
||
// Return just the one element from the set
|
||
( num < 0 ? this[ num + this.length ] : this[ num ] ) :
|
||
|
||
// Return all the elements in a clean array
|
||
slice.call( this );
|
||
},
|
||
|
||
// Take an array of elements and push it onto the stack
|
||
// (returning the new matched element set)
|
||
pushStack: function( elems ) {
|
||
|
||
// Build a new jQuery matched element set
|
||
var ret = jQuery.merge( this.constructor(), elems );
|
||
|
||
// Add the old object onto the stack (as a reference)
|
||
ret.prevObject = this;
|
||
ret.context = this.context;
|
||
|
||
// Return the newly-formed element set
|
||
return ret;
|
||
},
|
||
|
||
// Execute a callback for every element in the matched set.
|
||
// (You can seed the arguments with an array of args, but this is
|
||
// only used internally.)
|
||
each: function( callback, args ) {
|
||
return jQuery.each( this, callback, args );
|
||
},
|
||
|
||
map: function( callback ) {
|
||
return this.pushStack( jQuery.map(this, function( elem, i ) {
|
||
return callback.call( elem, i, elem );
|
||
}));
|
||
},
|
||
|
||
slice: function() {
|
||
return this.pushStack( slice.apply( this, arguments ) );
|
||
},
|
||
|
||
first: function() {
|
||
return this.eq( 0 );
|
||
},
|
||
|
||
last: function() {
|
||
return this.eq( -1 );
|
||
},
|
||
|
||
eq: function( i ) {
|
||
var len = this.length,
|
||
j = +i + ( i < 0 ? len : 0 );
|
||
return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
|
||
},
|
||
|
||
end: function() {
|
||
return this.prevObject || this.constructor(null);
|
||
},
|
||
|
||
// For internal use only.
|
||
// Behaves like an Array's method, not like a jQuery method.
|
||
push: push,
|
||
sort: arr.sort,
|
||
splice: arr.splice
|
||
};
|
||
|
||
jQuery.extend = jQuery.fn.extend = function() {
|
||
var options, name, src, copy, copyIsArray, clone,
|
||
target = arguments[0] || {},
|
||
i = 1,
|
||
length = arguments.length,
|
||
deep = false;
|
||
|
||
// Handle a deep copy situation
|
||
if ( typeof target === "boolean" ) {
|
||
deep = target;
|
||
|
||
// skip the boolean and the target
|
||
target = arguments[ i ] || {};
|
||
i++;
|
||
}
|
||
|
||
// Handle case when target is a string or something (possible in deep copy)
|
||
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
|
||
target = {};
|
||
}
|
||
|
||
// extend jQuery itself if only one argument is passed
|
||
if ( i === length ) {
|
||
target = this;
|
||
i--;
|
||
}
|
||
|
||
for ( ; i < length; i++ ) {
|
||
// Only deal with non-null/undefined values
|
||
if ( (options = arguments[ i ]) != null ) {
|
||
// Extend the base object
|
||
for ( name in options ) {
|
||
src = target[ name ];
|
||
copy = options[ name ];
|
||
|
||
// Prevent never-ending loop
|
||
if ( target === copy ) {
|
||
continue;
|
||
}
|
||
|
||
// Recurse if we're merging plain objects or arrays
|
||
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
|
||
if ( copyIsArray ) {
|
||
copyIsArray = false;
|
||
clone = src && jQuery.isArray(src) ? src : [];
|
||
|
||
} else {
|
||
clone = src && jQuery.isPlainObject(src) ? src : {};
|
||
}
|
||
|
||
// Never move original objects, clone them
|
||
target[ name ] = jQuery.extend( deep, clone, copy );
|
||
|
||
// Don't bring in undefined values
|
||
} else if ( copy !== undefined ) {
|
||
target[ name ] = copy;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Return the modified object
|
||
return target;
|
||
};
|
||
|
||
jQuery.extend({
|
||
// Unique for each copy of jQuery on the page
|
||
expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
|
||
|
||
// Assume jQuery is ready without the ready module
|
||
isReady: true,
|
||
|
||
error: function( msg ) {
|
||
throw new Error( msg );
|
||
},
|
||
|
||
noop: function() {},
|
||
|
||
// See test/unit/core.js for details concerning isFunction.
|
||
// Since version 1.3, DOM methods and functions like alert
|
||
// aren't supported. They return false on IE (#2968).
|
||
isFunction: function( obj ) {
|
||
return jQuery.type(obj) === "function";
|
||
},
|
||
|
||
isArray: Array.isArray,
|
||
|
||
isWindow: function( obj ) {
|
||
return obj != null && obj === obj.window;
|
||
},
|
||
|
||
isNumeric: function( obj ) {
|
||
// parseFloat NaNs numeric-cast false positives (null|true|false|"")
|
||
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
|
||
// subtraction forces infinities to NaN
|
||
return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;
|
||
},
|
||
|
||
isPlainObject: function( obj ) {
|
||
// Not plain objects:
|
||
// - Any object or value whose internal [[Class]] property is not "[object Object]"
|
||
// - DOM nodes
|
||
// - window
|
||
if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
|
||
return false;
|
||
}
|
||
|
||
if ( obj.constructor &&
|
||
!hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
|
||
return false;
|
||
}
|
||
|
||
// If the function hasn't returned already, we're confident that
|
||
// |obj| is a plain object, created by {} or constructed with new Object
|
||
return true;
|
||
},
|
||
|
||
isEmptyObject: function( obj ) {
|
||
var name;
|
||
for ( name in obj ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
|
||
type: function( obj ) {
|
||
if ( obj == null ) {
|
||
return obj + "";
|
||
}
|
||
// Support: Android < 4.0, iOS < 6 (functionish RegExp)
|
||
return typeof obj === "object" || typeof obj === "function" ?
|
||
class2type[ toString.call(obj) ] || "object" :
|
||
typeof obj;
|
||
},
|
||
|
||
// Evaluates a script in a global context
|
||
globalEval: function( code ) {
|
||
var script,
|
||
indirect = eval;
|
||
|
||
code = jQuery.trim( code );
|
||
|
||
if ( code ) {
|
||
// If the code includes a valid, prologue position
|
||
// strict mode pragma, execute code by injecting a
|
||
// script tag into the document.
|
||
if ( code.indexOf("use strict") === 1 ) {
|
||
script = document.createElement("script");
|
||
script.text = code;
|
||
document.head.appendChild( script ).parentNode.removeChild( script );
|
||
} else {
|
||
// Otherwise, avoid the DOM node creation, insertion
|
||
// and removal by using an indirect global eval
|
||
indirect( code );
|
||
}
|
||
}
|
||
},
|
||
|
||
// Convert dashed to camelCase; used by the css and data modules
|
||
// Microsoft forgot to hump their vendor prefix (#9572)
|
||
camelCase: function( string ) {
|
||
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
|
||
},
|
||
|
||
nodeName: function( elem, name ) {
|
||
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
|
||
},
|
||
|
||
// args is for internal usage only
|
||
each: function( obj, callback, args ) {
|
||
var value,
|
||
i = 0,
|
||
length = obj.length,
|
||
isArray = isArraylike( obj );
|
||
|
||
if ( args ) {
|
||
if ( isArray ) {
|
||
for ( ; i < length; i++ ) {
|
||
value = callback.apply( obj[ i ], args );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
for ( i in obj ) {
|
||
value = callback.apply( obj[ i ], args );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// A special, fast, case for the most common use of each
|
||
} else {
|
||
if ( isArray ) {
|
||
for ( ; i < length; i++ ) {
|
||
value = callback.call( obj[ i ], i, obj[ i ] );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
for ( i in obj ) {
|
||
value = callback.call( obj[ i ], i, obj[ i ] );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return obj;
|
||
},
|
||
|
||
// Support: Android<4.1
|
||
trim: function( text ) {
|
||
return text == null ?
|
||
"" :
|
||
( text + "" ).replace( rtrim, "" );
|
||
},
|
||
|
||
// results is for internal usage only
|
||
makeArray: function( arr, results ) {
|
||
var ret = results || [];
|
||
|
||
if ( arr != null ) {
|
||
if ( isArraylike( Object(arr) ) ) {
|
||
jQuery.merge( ret,
|
||
typeof arr === "string" ?
|
||
[ arr ] : arr
|
||
);
|
||
} else {
|
||
push.call( ret, arr );
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
},
|
||
|
||
inArray: function( elem, arr, i ) {
|
||
return arr == null ? -1 : indexOf.call( arr, elem, i );
|
||
},
|
||
|
||
merge: function( first, second ) {
|
||
var len = +second.length,
|
||
j = 0,
|
||
i = first.length;
|
||
|
||
for ( ; j < len; j++ ) {
|
||
first[ i++ ] = second[ j ];
|
||
}
|
||
|
||
first.length = i;
|
||
|
||
return first;
|
||
},
|
||
|
||
grep: function( elems, callback, invert ) {
|
||
var callbackInverse,
|
||
matches = [],
|
||
i = 0,
|
||
length = elems.length,
|
||
callbackExpect = !invert;
|
||
|
||
// Go through the array, only saving the items
|
||
// that pass the validator function
|
||
for ( ; i < length; i++ ) {
|
||
callbackInverse = !callback( elems[ i ], i );
|
||
if ( callbackInverse !== callbackExpect ) {
|
||
matches.push( elems[ i ] );
|
||
}
|
||
}
|
||
|
||
return matches;
|
||
},
|
||
|
||
// arg is for internal usage only
|
||
map: function( elems, callback, arg ) {
|
||
var value,
|
||
i = 0,
|
||
length = elems.length,
|
||
isArray = isArraylike( elems ),
|
||
ret = [];
|
||
|
||
// Go through the array, translating each of the items to their new values
|
||
if ( isArray ) {
|
||
for ( ; i < length; i++ ) {
|
||
value = callback( elems[ i ], i, arg );
|
||
|
||
if ( value != null ) {
|
||
ret.push( value );
|
||
}
|
||
}
|
||
|
||
// Go through every key on the object,
|
||
} else {
|
||
for ( i in elems ) {
|
||
value = callback( elems[ i ], i, arg );
|
||
|
||
if ( value != null ) {
|
||
ret.push( value );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Flatten any nested arrays
|
||
return concat.apply( [], ret );
|
||
},
|
||
|
||
// A global GUID counter for objects
|
||
guid: 1,
|
||
|
||
// Bind a function to a context, optionally partially applying any
|
||
// arguments.
|
||
proxy: function( fn, context ) {
|
||
var tmp, args, proxy;
|
||
|
||
if ( typeof context === "string" ) {
|
||
tmp = fn[ context ];
|
||
context = fn;
|
||
fn = tmp;
|
||
}
|
||
|
||
// Quick check to determine if target is callable, in the spec
|
||
// this throws a TypeError, but we will just return undefined.
|
||
if ( !jQuery.isFunction( fn ) ) {
|
||
return undefined;
|
||
}
|
||
|
||
// Simulated bind
|
||
args = slice.call( arguments, 2 );
|
||
proxy = function() {
|
||
return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
|
||
};
|
||
|
||
// Set the guid of unique handler to the same of original handler, so it can be removed
|
||
proxy.guid = fn.guid = fn.guid || jQuery.guid++;
|
||
|
||
return proxy;
|
||
},
|
||
|
||
now: Date.now,
|
||
|
||
// jQuery.support is not used in Core but other projects attach their
|
||
// properties to it so it needs to exist.
|
||
support: support
|
||
});
|
||
|
||
// Populate the class2type map
|
||
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
|
||
class2type[ "[object " + name + "]" ] = name.toLowerCase();
|
||
});
|
||
|
||
function isArraylike( obj ) {
|
||
var length = obj.length,
|
||
type = jQuery.type( obj );
|
||
|
||
if ( type === "function" || jQuery.isWindow( obj ) ) {
|
||
return false;
|
||
}
|
||
|
||
if ( obj.nodeType === 1 && length ) {
|
||
return true;
|
||
}
|
||
|
||
return type === "array" || length === 0 ||
|
||
typeof length === "number" && length > 0 && ( length - 1 ) in obj;
|
||
}
|
||
var Sizzle =
|
||
/*!
|
||
* Sizzle CSS Selector Engine v1.10.19
|
||
* http://sizzlejs.com/
|
||
*
|
||
* Copyright 2013 jQuery Foundation, Inc. and other contributors
|
||
* Released under the MIT license
|
||
* http://jquery.org/license
|
||
*
|
||
* Date: 2014-04-18
|
||
*/
|
||
(function( window ) {
|
||
|
||
var i,
|
||
support,
|
||
Expr,
|
||
getText,
|
||
isXML,
|
||
tokenize,
|
||
compile,
|
||
select,
|
||
outermostContext,
|
||
sortInput,
|
||
hasDuplicate,
|
||
|
||
// Local document vars
|
||
setDocument,
|
||
document,
|
||
docElem,
|
||
documentIsHTML,
|
||
rbuggyQSA,
|
||
rbuggyMatches,
|
||
matches,
|
||
contains,
|
||
|
||
// Instance-specific data
|
||
expando = "sizzle" + -(new Date()),
|
||
preferredDoc = window.document,
|
||
dirruns = 0,
|
||
done = 0,
|
||
classCache = createCache(),
|
||
tokenCache = createCache(),
|
||
compilerCache = createCache(),
|
||
sortOrder = function( a, b ) {
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
}
|
||
return 0;
|
||
},
|
||
|
||
// General-purpose constants
|
||
strundefined = typeof undefined,
|
||
MAX_NEGATIVE = 1 << 31,
|
||
|
||
// Instance methods
|
||
hasOwn = ({}).hasOwnProperty,
|
||
arr = [],
|
||
pop = arr.pop,
|
||
push_native = arr.push,
|
||
push = arr.push,
|
||
slice = arr.slice,
|
||
// Use a stripped-down indexOf if we can't use a native one
|
||
indexOf = arr.indexOf || function( elem ) {
|
||
var i = 0,
|
||
len = this.length;
|
||
for ( ; i < len; i++ ) {
|
||
if ( this[i] === elem ) {
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
},
|
||
|
||
booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
|
||
|
||
// Regular expressions
|
||
|
||
// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
|
||
whitespace = "[\\x20\\t\\r\\n\\f]",
|
||
// http://www.w3.org/TR/css3-syntax/#characters
|
||
characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
|
||
|
||
// Loosely modeled on CSS identifier characters
|
||
// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
|
||
// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
|
||
identifier = characterEncoding.replace( "w", "w#" ),
|
||
|
||
// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
|
||
attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
|
||
// Operator (capture 2)
|
||
"*([*^$|!~]?=)" + whitespace +
|
||
// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
|
||
"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
|
||
"*\\]",
|
||
|
||
pseudos = ":(" + characterEncoding + ")(?:\\((" +
|
||
// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
|
||
// 1. quoted (capture 3; capture 4 or capture 5)
|
||
"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
|
||
// 2. simple (capture 6)
|
||
"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
|
||
// 3. anything else (capture 2)
|
||
".*" +
|
||
")\\)|)",
|
||
|
||
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
|
||
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
|
||
|
||
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
|
||
rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
|
||
|
||
rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
|
||
|
||
rpseudo = new RegExp( pseudos ),
|
||
ridentifier = new RegExp( "^" + identifier + "$" ),
|
||
|
||
matchExpr = {
|
||
"ID": new RegExp( "^#(" + characterEncoding + ")" ),
|
||
"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
|
||
"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
|
||
"ATTR": new RegExp( "^" + attributes ),
|
||
"PSEUDO": new RegExp( "^" + pseudos ),
|
||
"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
|
||
"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
|
||
"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
|
||
"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
|
||
// For use in libraries implementing .is()
|
||
// We use this for POS matching in `select`
|
||
"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
|
||
whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
|
||
},
|
||
|
||
rinputs = /^(?:input|select|textarea|button)$/i,
|
||
rheader = /^h\d$/i,
|
||
|
||
rnative = /^[^{]+\{\s*\[native \w/,
|
||
|
||
// Easily-parseable/retrievable ID or TAG or CLASS selectors
|
||
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
|
||
|
||
rsibling = /[+~]/,
|
||
rescape = /'|\\/g,
|
||
|
||
// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
|
||
runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
|
||
funescape = function( _, escaped, escapedWhitespace ) {
|
||
var high = "0x" + escaped - 0x10000;
|
||
// NaN means non-codepoint
|
||
// Support: Firefox<24
|
||
// Workaround erroneous numeric interpretation of +"0x"
|
||
return high !== high || escapedWhitespace ?
|
||
escaped :
|
||
high < 0 ?
|
||
// BMP codepoint
|
||
String.fromCharCode( high + 0x10000 ) :
|
||
// Supplemental Plane codepoint (surrogate pair)
|
||
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
|
||
};
|
||
|
||
// Optimize for push.apply( _, NodeList )
|
||
try {
|
||
push.apply(
|
||
(arr = slice.call( preferredDoc.childNodes )),
|
||
preferredDoc.childNodes
|
||
);
|
||
// Support: Android<4.0
|
||
// Detect silently failing push.apply
|
||
arr[ preferredDoc.childNodes.length ].nodeType;
|
||
} catch ( e ) {
|
||
push = { apply: arr.length ?
|
||
|
||
// Leverage slice if possible
|
||
function( target, els ) {
|
||
push_native.apply( target, slice.call(els) );
|
||
} :
|
||
|
||
// Support: IE<9
|
||
// Otherwise append directly
|
||
function( target, els ) {
|
||
var j = target.length,
|
||
i = 0;
|
||
// Can't trust NodeList.length
|
||
while ( (target[j++] = els[i++]) ) {}
|
||
target.length = j - 1;
|
||
}
|
||
};
|
||
}
|
||
|
||
function Sizzle( selector, context, results, seed ) {
|
||
var match, elem, m, nodeType,
|
||
// QSA vars
|
||
i, groups, old, nid, newContext, newSelector;
|
||
|
||
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
|
||
setDocument( context );
|
||
}
|
||
|
||
context = context || document;
|
||
results = results || [];
|
||
|
||
if ( !selector || typeof selector !== "string" ) {
|
||
return results;
|
||
}
|
||
|
||
if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
|
||
return [];
|
||
}
|
||
|
||
if ( documentIsHTML && !seed ) {
|
||
|
||
// Shortcuts
|
||
if ( (match = rquickExpr.exec( selector )) ) {
|
||
// Speed-up: Sizzle("#ID")
|
||
if ( (m = match[1]) ) {
|
||
if ( nodeType === 9 ) {
|
||
elem = context.getElementById( m );
|
||
// Check parentNode to catch when Blackberry 4.6 returns
|
||
// nodes that are no longer in the document (jQuery #6963)
|
||
if ( elem && elem.parentNode ) {
|
||
// Handle the case where IE, Opera, and Webkit return items
|
||
// by name instead of ID
|
||
if ( elem.id === m ) {
|
||
results.push( elem );
|
||
return results;
|
||
}
|
||
} else {
|
||
return results;
|
||
}
|
||
} else {
|
||
// Context is not a document
|
||
if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
|
||
contains( context, elem ) && elem.id === m ) {
|
||
results.push( elem );
|
||
return results;
|
||
}
|
||
}
|
||
|
||
// Speed-up: Sizzle("TAG")
|
||
} else if ( match[2] ) {
|
||
push.apply( results, context.getElementsByTagName( selector ) );
|
||
return results;
|
||
|
||
// Speed-up: Sizzle(".CLASS")
|
||
} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
|
||
push.apply( results, context.getElementsByClassName( m ) );
|
||
return results;
|
||
}
|
||
}
|
||
|
||
// QSA path
|
||
if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
|
||
nid = old = expando;
|
||
newContext = context;
|
||
newSelector = nodeType === 9 && selector;
|
||
|
||
// qSA works strangely on Element-rooted queries
|
||
// We can work around this by specifying an extra ID on the root
|
||
// and working up from there (Thanks to Andrew Dupont for the technique)
|
||
// IE 8 doesn't work on object elements
|
||
if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
|
||
groups = tokenize( selector );
|
||
|
||
if ( (old = context.getAttribute("id")) ) {
|
||
nid = old.replace( rescape, "\\$&" );
|
||
} else {
|
||
context.setAttribute( "id", nid );
|
||
}
|
||
nid = "[id='" + nid + "'] ";
|
||
|
||
i = groups.length;
|
||
while ( i-- ) {
|
||
groups[i] = nid + toSelector( groups[i] );
|
||
}
|
||
newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
|
||
newSelector = groups.join(",");
|
||
}
|
||
|
||
if ( newSelector ) {
|
||
try {
|
||
push.apply( results,
|
||
newContext.querySelectorAll( newSelector )
|
||
);
|
||
return results;
|
||
} catch(qsaError) {
|
||
} finally {
|
||
if ( !old ) {
|
||
context.removeAttribute("id");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// All others
|
||
return select( selector.replace( rtrim, "$1" ), context, results, seed );
|
||
}
|
||
|
||
/**
|
||
* Create key-value caches of limited size
|
||
* @returns {Function(string, Object)} Returns the Object data after storing it on itself with
|
||
* property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
|
||
* deleting the oldest entry
|
||
*/
|
||
function createCache() {
|
||
var keys = [];
|
||
|
||
function cache( key, value ) {
|
||
// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
|
||
if ( keys.push( key + " " ) > Expr.cacheLength ) {
|
||
// Only keep the most recent entries
|
||
delete cache[ keys.shift() ];
|
||
}
|
||
return (cache[ key + " " ] = value);
|
||
}
|
||
return cache;
|
||
}
|
||
|
||
/**
|
||
* Mark a function for special use by Sizzle
|
||
* @param {Function} fn The function to mark
|
||
*/
|
||
function markFunction( fn ) {
|
||
fn[ expando ] = true;
|
||
return fn;
|
||
}
|
||
|
||
/**
|
||
* Support testing using an element
|
||
* @param {Function} fn Passed the created div and expects a boolean result
|
||
*/
|
||
function assert( fn ) {
|
||
var div = document.createElement("div");
|
||
|
||
try {
|
||
return !!fn( div );
|
||
} catch (e) {
|
||
return false;
|
||
} finally {
|
||
// Remove from its parent by default
|
||
if ( div.parentNode ) {
|
||
div.parentNode.removeChild( div );
|
||
}
|
||
// release memory in IE
|
||
div = null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Adds the same handler for all of the specified attrs
|
||
* @param {String} attrs Pipe-separated list of attributes
|
||
* @param {Function} handler The method that will be applied
|
||
*/
|
||
function addHandle( attrs, handler ) {
|
||
var arr = attrs.split("|"),
|
||
i = attrs.length;
|
||
|
||
while ( i-- ) {
|
||
Expr.attrHandle[ arr[i] ] = handler;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Checks document order of two siblings
|
||
* @param {Element} a
|
||
* @param {Element} b
|
||
* @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
|
||
*/
|
||
function siblingCheck( a, b ) {
|
||
var cur = b && a,
|
||
diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
|
||
( ~b.sourceIndex || MAX_NEGATIVE ) -
|
||
( ~a.sourceIndex || MAX_NEGATIVE );
|
||
|
||
// Use IE sourceIndex if available on both nodes
|
||
if ( diff ) {
|
||
return diff;
|
||
}
|
||
|
||
// Check if b follows a
|
||
if ( cur ) {
|
||
while ( (cur = cur.nextSibling) ) {
|
||
if ( cur === b ) {
|
||
return -1;
|
||
}
|
||
}
|
||
}
|
||
|
||
return a ? 1 : -1;
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for input types
|
||
* @param {String} type
|
||
*/
|
||
function createInputPseudo( type ) {
|
||
return function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return name === "input" && elem.type === type;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for buttons
|
||
* @param {String} type
|
||
*/
|
||
function createButtonPseudo( type ) {
|
||
return function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return (name === "input" || name === "button") && elem.type === type;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for positionals
|
||
* @param {Function} fn
|
||
*/
|
||
function createPositionalPseudo( fn ) {
|
||
return markFunction(function( argument ) {
|
||
argument = +argument;
|
||
return markFunction(function( seed, matches ) {
|
||
var j,
|
||
matchIndexes = fn( [], seed.length, argument ),
|
||
i = matchIndexes.length;
|
||
|
||
// Match elements found at the specified indexes
|
||
while ( i-- ) {
|
||
if ( seed[ (j = matchIndexes[i]) ] ) {
|
||
seed[j] = !(matches[j] = seed[j]);
|
||
}
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Checks a node for validity as a Sizzle context
|
||
* @param {Element|Object=} context
|
||
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
|
||
*/
|
||
function testContext( context ) {
|
||
return context && typeof context.getElementsByTagName !== strundefined && context;
|
||
}
|
||
|
||
// Expose support vars for convenience
|
||
support = Sizzle.support = {};
|
||
|
||
/**
|
||
* Detects XML nodes
|
||
* @param {Element|Object} elem An element or a document
|
||
* @returns {Boolean} True iff elem is a non-HTML XML node
|
||
*/
|
||
isXML = Sizzle.isXML = function( elem ) {
|
||
// documentElement is verified for cases where it doesn't yet exist
|
||
// (such as loading iframes in IE - #4833)
|
||
var documentElement = elem && (elem.ownerDocument || elem).documentElement;
|
||
return documentElement ? documentElement.nodeName !== "HTML" : false;
|
||
};
|
||
|
||
/**
|
||
* Sets document-related variables once based on the current document
|
||
* @param {Element|Object} [doc] An element or document object to use to set the document
|
||
* @returns {Object} Returns the current document
|
||
*/
|
||
setDocument = Sizzle.setDocument = function( node ) {
|
||
var hasCompare,
|
||
doc = node ? node.ownerDocument || node : preferredDoc,
|
||
parent = doc.defaultView;
|
||
|
||
// If no document and documentElement is available, return
|
||
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
|
||
return document;
|
||
}
|
||
|
||
// Set our document
|
||
document = doc;
|
||
docElem = doc.documentElement;
|
||
|
||
// Support tests
|
||
documentIsHTML = !isXML( doc );
|
||
|
||
// Support: IE>8
|
||
// If iframe document is assigned to "document" variable and if iframe has been reloaded,
|
||
// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
|
||
// IE6-8 do not support the defaultView property so parent will be undefined
|
||
if ( parent && parent !== parent.top ) {
|
||
// IE11 does not have attachEvent, so all must suffer
|
||
if ( parent.addEventListener ) {
|
||
parent.addEventListener( "unload", function() {
|
||
setDocument();
|
||
}, false );
|
||
} else if ( parent.attachEvent ) {
|
||
parent.attachEvent( "onunload", function() {
|
||
setDocument();
|
||
});
|
||
}
|
||
}
|
||
|
||
/* Attributes
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Support: IE<8
|
||
// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
|
||
support.attributes = assert(function( div ) {
|
||
div.className = "i";
|
||
return !div.getAttribute("className");
|
||
});
|
||
|
||
/* getElement(s)By*
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Check if getElementsByTagName("*") returns only elements
|
||
support.getElementsByTagName = assert(function( div ) {
|
||
div.appendChild( doc.createComment("") );
|
||
return !div.getElementsByTagName("*").length;
|
||
});
|
||
|
||
// Check if getElementsByClassName can be trusted
|
||
support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
|
||
div.innerHTML = "<div class='a'></div><div class='a i'></div>";
|
||
|
||
// Support: Safari<4
|
||
// Catch class over-caching
|
||
div.firstChild.className = "i";
|
||
// Support: Opera<10
|
||
// Catch gEBCN failure to find non-leading classes
|
||
return div.getElementsByClassName("i").length === 2;
|
||
});
|
||
|
||
// Support: IE<10
|
||
// Check if getElementById returns elements by name
|
||
// The broken getElementById methods don't pick up programatically-set names,
|
||
// so use a roundabout getElementsByName test
|
||
support.getById = assert(function( div ) {
|
||
docElem.appendChild( div ).id = expando;
|
||
return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
|
||
});
|
||
|
||
// ID find and filter
|
||
if ( support.getById ) {
|
||
Expr.find["ID"] = function( id, context ) {
|
||
if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
|
||
var m = context.getElementById( id );
|
||
// Check parentNode to catch when Blackberry 4.6 returns
|
||
// nodes that are no longer in the document #6963
|
||
return m && m.parentNode ? [ m ] : [];
|
||
}
|
||
};
|
||
Expr.filter["ID"] = function( id ) {
|
||
var attrId = id.replace( runescape, funescape );
|
||
return function( elem ) {
|
||
return elem.getAttribute("id") === attrId;
|
||
};
|
||
};
|
||
} else {
|
||
// Support: IE6/7
|
||
// getElementById is not reliable as a find shortcut
|
||
delete Expr.find["ID"];
|
||
|
||
Expr.filter["ID"] = function( id ) {
|
||
var attrId = id.replace( runescape, funescape );
|
||
return function( elem ) {
|
||
var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
|
||
return node && node.value === attrId;
|
||
};
|
||
};
|
||
}
|
||
|
||
// Tag
|
||
Expr.find["TAG"] = support.getElementsByTagName ?
|
||
function( tag, context ) {
|
||
if ( typeof context.getElementsByTagName !== strundefined ) {
|
||
return context.getElementsByTagName( tag );
|
||
}
|
||
} :
|
||
function( tag, context ) {
|
||
var elem,
|
||
tmp = [],
|
||
i = 0,
|
||
results = context.getElementsByTagName( tag );
|
||
|
||
// Filter out possible comments
|
||
if ( tag === "*" ) {
|
||
while ( (elem = results[i++]) ) {
|
||
if ( elem.nodeType === 1 ) {
|
||
tmp.push( elem );
|
||
}
|
||
}
|
||
|
||
return tmp;
|
||
}
|
||
return results;
|
||
};
|
||
|
||
// Class
|
||
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
|
||
if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
|
||
return context.getElementsByClassName( className );
|
||
}
|
||
};
|
||
|
||
/* QSA/matchesSelector
|
||
---------------------------------------------------------------------- */
|
||
|
||
// QSA and matchesSelector support
|
||
|
||
// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
|
||
rbuggyMatches = [];
|
||
|
||
// qSa(:focus) reports false when true (Chrome 21)
|
||
// We allow this because of a bug in IE8/9 that throws an error
|
||
// whenever `document.activeElement` is accessed on an iframe
|
||
// So, we allow :focus to pass through QSA all the time to avoid the IE error
|
||
// See http://bugs.jquery.com/ticket/13378
|
||
rbuggyQSA = [];
|
||
|
||
if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
|
||
// Build QSA regex
|
||
// Regex strategy adopted from Diego Perini
|
||
assert(function( div ) {
|
||
// Select is set to empty string on purpose
|
||
// This is to test IE's treatment of not explicitly
|
||
// setting a boolean content attribute,
|
||
// since its presence should be enough
|
||
// http://bugs.jquery.com/ticket/12359
|
||
div.innerHTML = "<select msallowclip=''><option selected=''></option></select>";
|
||
|
||
// Support: IE8, Opera 11-12.16
|
||
// Nothing should be selected when empty strings follow ^= or $= or *=
|
||
// The test attribute must be unknown in Opera but "safe" for WinRT
|
||
// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
|
||
if ( div.querySelectorAll("[msallowclip^='']").length ) {
|
||
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
|
||
}
|
||
|
||
// Support: IE8
|
||
// Boolean attributes and "value" are not treated correctly
|
||
if ( !div.querySelectorAll("[selected]").length ) {
|
||
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
|
||
}
|
||
|
||
// Webkit/Opera - :checked should return selected option elements
|
||
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
|
||
// IE8 throws error here and will not see later tests
|
||
if ( !div.querySelectorAll(":checked").length ) {
|
||
rbuggyQSA.push(":checked");
|
||
}
|
||
});
|
||
|
||
assert(function( div ) {
|
||
// Support: Windows 8 Native Apps
|
||
// The type and name attributes are restricted during .innerHTML assignment
|
||
var input = doc.createElement("input");
|
||
input.setAttribute( "type", "hidden" );
|
||
div.appendChild( input ).setAttribute( "name", "D" );
|
||
|
||
// Support: IE8
|
||
// Enforce case-sensitivity of name attribute
|
||
if ( div.querySelectorAll("[name=d]").length ) {
|
||
rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
|
||
}
|
||
|
||
// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
|
||
// IE8 throws error here and will not see later tests
|
||
if ( !div.querySelectorAll(":enabled").length ) {
|
||
rbuggyQSA.push( ":enabled", ":disabled" );
|
||
}
|
||
|
||
// Opera 10-11 does not throw on post-comma invalid pseudos
|
||
div.querySelectorAll("*,:x");
|
||
rbuggyQSA.push(",.*:");
|
||
});
|
||
}
|
||
|
||
if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
|
||
docElem.webkitMatchesSelector ||
|
||
docElem.mozMatchesSelector ||
|
||
docElem.oMatchesSelector ||
|
||
docElem.msMatchesSelector) )) ) {
|
||
|
||
assert(function( div ) {
|
||
// Check to see if it's possible to do matchesSelector
|
||
// on a disconnected node (IE 9)
|
||
support.disconnectedMatch = matches.call( div, "div" );
|
||
|
||
// This should fail with an exception
|
||
// Gecko does not error, returns false instead
|
||
matches.call( div, "[s!='']:x" );
|
||
rbuggyMatches.push( "!=", pseudos );
|
||
});
|
||
}
|
||
|
||
rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
|
||
rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
|
||
|
||
/* Contains
|
||
---------------------------------------------------------------------- */
|
||
hasCompare = rnative.test( docElem.compareDocumentPosition );
|
||
|
||
// Element contains another
|
||
// Purposefully does not implement inclusive descendent
|
||
// As in, an element does not contain itself
|
||
contains = hasCompare || rnative.test( docElem.contains ) ?
|
||
function( a, b ) {
|
||
var adown = a.nodeType === 9 ? a.documentElement : a,
|
||
bup = b && b.parentNode;
|
||
return a === bup || !!( bup && bup.nodeType === 1 && (
|
||
adown.contains ?
|
||
adown.contains( bup ) :
|
||
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
|
||
));
|
||
} :
|
||
function( a, b ) {
|
||
if ( b ) {
|
||
while ( (b = b.parentNode) ) {
|
||
if ( b === a ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
/* Sorting
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Document order sorting
|
||
sortOrder = hasCompare ?
|
||
function( a, b ) {
|
||
|
||
// Flag for duplicate removal
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
return 0;
|
||
}
|
||
|
||
// Sort on method existence if only one input has compareDocumentPosition
|
||
var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
|
||
if ( compare ) {
|
||
return compare;
|
||
}
|
||
|
||
// Calculate position if both inputs belong to the same document
|
||
compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
|
||
a.compareDocumentPosition( b ) :
|
||
|
||
// Otherwise we know they are disconnected
|
||
1;
|
||
|
||
// Disconnected nodes
|
||
if ( compare & 1 ||
|
||
(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
|
||
|
||
// Choose the first element that is related to our preferred document
|
||
if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
|
||
return -1;
|
||
}
|
||
if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
|
||
return 1;
|
||
}
|
||
|
||
// Maintain original order
|
||
return sortInput ?
|
||
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
|
||
0;
|
||
}
|
||
|
||
return compare & 4 ? -1 : 1;
|
||
} :
|
||
function( a, b ) {
|
||
// Exit early if the nodes are identical
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
return 0;
|
||
}
|
||
|
||
var cur,
|
||
i = 0,
|
||
aup = a.parentNode,
|
||
bup = b.parentNode,
|
||
ap = [ a ],
|
||
bp = [ b ];
|
||
|
||
// Parentless nodes are either documents or disconnected
|
||
if ( !aup || !bup ) {
|
||
return a === doc ? -1 :
|
||
b === doc ? 1 :
|
||
aup ? -1 :
|
||
bup ? 1 :
|
||
sortInput ?
|
||
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
|
||
0;
|
||
|
||
// If the nodes are siblings, we can do a quick check
|
||
} else if ( aup === bup ) {
|
||
return siblingCheck( a, b );
|
||
}
|
||
|
||
// Otherwise we need full lists of their ancestors for comparison
|
||
cur = a;
|
||
while ( (cur = cur.parentNode) ) {
|
||
ap.unshift( cur );
|
||
}
|
||
cur = b;
|
||
while ( (cur = cur.parentNode) ) {
|
||
bp.unshift( cur );
|
||
}
|
||
|
||
// Walk down the tree looking for a discrepancy
|
||
while ( ap[i] === bp[i] ) {
|
||
i++;
|
||
}
|
||
|
||
return i ?
|
||
// Do a sibling check if the nodes have a common ancestor
|
||
siblingCheck( ap[i], bp[i] ) :
|
||
|
||
// Otherwise nodes in our document sort first
|
||
ap[i] === preferredDoc ? -1 :
|
||
bp[i] === preferredDoc ? 1 :
|
||
0;
|
||
};
|
||
|
||
return doc;
|
||
};
|
||
|
||
Sizzle.matches = function( expr, elements ) {
|
||
return Sizzle( expr, null, null, elements );
|
||
};
|
||
|
||
Sizzle.matchesSelector = function( elem, expr ) {
|
||
// Set document vars if needed
|
||
if ( ( elem.ownerDocument || elem ) !== document ) {
|
||
setDocument( elem );
|
||
}
|
||
|
||
// Make sure that attribute selectors are quoted
|
||
expr = expr.replace( rattributeQuotes, "='$1']" );
|
||
|
||
if ( support.matchesSelector && documentIsHTML &&
|
||
( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
|
||
( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
|
||
|
||
try {
|
||
var ret = matches.call( elem, expr );
|
||
|
||
// IE 9's matchesSelector returns false on disconnected nodes
|
||
if ( ret || support.disconnectedMatch ||
|
||
// As well, disconnected nodes are said to be in a document
|
||
// fragment in IE 9
|
||
elem.document && elem.document.nodeType !== 11 ) {
|
||
return ret;
|
||
}
|
||
} catch(e) {}
|
||
}
|
||
|
||
return Sizzle( expr, document, null, [ elem ] ).length > 0;
|
||
};
|
||
|
||
Sizzle.contains = function( context, elem ) {
|
||
// Set document vars if needed
|
||
if ( ( context.ownerDocument || context ) !== document ) {
|
||
setDocument( context );
|
||
}
|
||
return contains( context, elem );
|
||
};
|
||
|
||
Sizzle.attr = function( elem, name ) {
|
||
// Set document vars if needed
|
||
if ( ( elem.ownerDocument || elem ) !== document ) {
|
||
setDocument( elem );
|
||
}
|
||
|
||
var fn = Expr.attrHandle[ name.toLowerCase() ],
|
||
// Don't get fooled by Object.prototype properties (jQuery #13807)
|
||
val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
|
||
fn( elem, name, !documentIsHTML ) :
|
||
undefined;
|
||
|
||
return val !== undefined ?
|
||
val :
|
||
support.attributes || !documentIsHTML ?
|
||
elem.getAttribute( name ) :
|
||
(val = elem.getAttributeNode(name)) && val.specified ?
|
||
val.value :
|
||
null;
|
||
};
|
||
|
||
Sizzle.error = function( msg ) {
|
||
throw new Error( "Syntax error, unrecognized expression: " + msg );
|
||
};
|
||
|
||
/**
|
||
* Document sorting and removing duplicates
|
||
* @param {ArrayLike} results
|
||
*/
|
||
Sizzle.uniqueSort = function( results ) {
|
||
var elem,
|
||
duplicates = [],
|
||
j = 0,
|
||
i = 0;
|
||
|
||
// Unless we *know* we can detect duplicates, assume their presence
|
||
hasDuplicate = !support.detectDuplicates;
|
||
sortInput = !support.sortStable && results.slice( 0 );
|
||
results.sort( sortOrder );
|
||
|
||
if ( hasDuplicate ) {
|
||
while ( (elem = results[i++]) ) {
|
||
if ( elem === results[ i ] ) {
|
||
j = duplicates.push( i );
|
||
}
|
||
}
|
||
while ( j-- ) {
|
||
results.splice( duplicates[ j ], 1 );
|
||
}
|
||
}
|
||
|
||
// Clear input after sorting to release objects
|
||
// See https://github.com/jquery/sizzle/pull/225
|
||
sortInput = null;
|
||
|
||
return results;
|
||
};
|
||
|
||
/**
|
||
* Utility function for retrieving the text value of an array of DOM nodes
|
||
* @param {Array|Element} elem
|
||
*/
|
||
getText = Sizzle.getText = function( elem ) {
|
||
var node,
|
||
ret = "",
|
||
i = 0,
|
||
nodeType = elem.nodeType;
|
||
|
||
if ( !nodeType ) {
|
||
// If no nodeType, this is expected to be an array
|
||
while ( (node = elem[i++]) ) {
|
||
// Do not traverse comment nodes
|
||
ret += getText( node );
|
||
}
|
||
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
|
||
// Use textContent for elements
|
||
// innerText usage removed for consistency of new lines (jQuery #11153)
|
||
if ( typeof elem.textContent === "string" ) {
|
||
return elem.textContent;
|
||
} else {
|
||
// Traverse its children
|
||
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
|
||
ret += getText( elem );
|
||
}
|
||
}
|
||
} else if ( nodeType === 3 || nodeType === 4 ) {
|
||
return elem.nodeValue;
|
||
}
|
||
// Do not include comment or processing instruction nodes
|
||
|
||
return ret;
|
||
};
|
||
|
||
Expr = Sizzle.selectors = {
|
||
|
||
// Can be adjusted by the user
|
||
cacheLength: 50,
|
||
|
||
createPseudo: markFunction,
|
||
|
||
match: matchExpr,
|
||
|
||
attrHandle: {},
|
||
|
||
find: {},
|
||
|
||
relative: {
|
||
">": { dir: "parentNode", first: true },
|
||
" ": { dir: "parentNode" },
|
||
"+": { dir: "previousSibling", first: true },
|
||
"~": { dir: "previousSibling" }
|
||
},
|
||
|
||
preFilter: {
|
||
"ATTR": function( match ) {
|
||
match[1] = match[1].replace( runescape, funescape );
|
||
|
||
// Move the given value to match[3] whether quoted or unquoted
|
||
match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
|
||
|
||
if ( match[2] === "~=" ) {
|
||
match[3] = " " + match[3] + " ";
|
||
}
|
||
|
||
return match.slice( 0, 4 );
|
||
},
|
||
|
||
"CHILD": function( match ) {
|
||
/* matches from matchExpr["CHILD"]
|
||
1 type (only|nth|...)
|
||
2 what (child|of-type)
|
||
3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
|
||
4 xn-component of xn+y argument ([+-]?\d*n|)
|
||
5 sign of xn-component
|
||
6 x of xn-component
|
||
7 sign of y-component
|
||
8 y of y-component
|
||
*/
|
||
match[1] = match[1].toLowerCase();
|
||
|
||
if ( match[1].slice( 0, 3 ) === "nth" ) {
|
||
// nth-* requires argument
|
||
if ( !match[3] ) {
|
||
Sizzle.error( match[0] );
|
||
}
|
||
|
||
// numeric x and y parameters for Expr.filter.CHILD
|
||
// remember that false/true cast respectively to 0/1
|
||
match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
|
||
match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
|
||
|
||
// other types prohibit arguments
|
||
} else if ( match[3] ) {
|
||
Sizzle.error( match[0] );
|
||
}
|
||
|
||
return match;
|
||
},
|
||
|
||
"PSEUDO": function( match ) {
|
||
var excess,
|
||
unquoted = !match[6] && match[2];
|
||
|
||
if ( matchExpr["CHILD"].test( match[0] ) ) {
|
||
return null;
|
||
}
|
||
|
||
// Accept quoted arguments as-is
|
||
if ( match[3] ) {
|
||
match[2] = match[4] || match[5] || "";
|
||
|
||
// Strip excess characters from unquoted arguments
|
||
} else if ( unquoted && rpseudo.test( unquoted ) &&
|
||
// Get excess from tokenize (recursively)
|
||
(excess = tokenize( unquoted, true )) &&
|
||
// advance to the next closing parenthesis
|
||
(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
|
||
|
||
// excess is a negative index
|
||
match[0] = match[0].slice( 0, excess );
|
||
match[2] = unquoted.slice( 0, excess );
|
||
}
|
||
|
||
// Return only captures needed by the pseudo filter method (type and argument)
|
||
return match.slice( 0, 3 );
|
||
}
|
||
},
|
||
|
||
filter: {
|
||
|
||
"TAG": function( nodeNameSelector ) {
|
||
var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
|
||
return nodeNameSelector === "*" ?
|
||
function() { return true; } :
|
||
function( elem ) {
|
||
return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
|
||
};
|
||
},
|
||
|
||
"CLASS": function( className ) {
|
||
var pattern = classCache[ className + " " ];
|
||
|
||
return pattern ||
|
||
(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
|
||
classCache( className, function( elem ) {
|
||
return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
|
||
});
|
||
},
|
||
|
||
"ATTR": function( name, operator, check ) {
|
||
return function( elem ) {
|
||
var result = Sizzle.attr( elem, name );
|
||
|
||
if ( result == null ) {
|
||
return operator === "!=";
|
||
}
|
||
if ( !operator ) {
|
||
return true;
|
||
}
|
||
|
||
result += "";
|
||
|
||
return operator === "=" ? result === check :
|
||
operator === "!=" ? result !== check :
|
||
operator === "^=" ? check && result.indexOf( check ) === 0 :
|
||
operator === "*=" ? check && result.indexOf( check ) > -1 :
|
||
operator === "$=" ? check && result.slice( -check.length ) === check :
|
||
operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
|
||
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
|
||
false;
|
||
};
|
||
},
|
||
|
||
"CHILD": function( type, what, argument, first, last ) {
|
||
var simple = type.slice( 0, 3 ) !== "nth",
|
||
forward = type.slice( -4 ) !== "last",
|
||
ofType = what === "of-type";
|
||
|
||
return first === 1 && last === 0 ?
|
||
|
||
// Shortcut for :nth-*(n)
|
||
function( elem ) {
|
||
return !!elem.parentNode;
|
||
} :
|
||
|
||
function( elem, context, xml ) {
|
||
var cache, outerCache, node, diff, nodeIndex, start,
|
||
dir = simple !== forward ? "nextSibling" : "previousSibling",
|
||
parent = elem.parentNode,
|
||
name = ofType && elem.nodeName.toLowerCase(),
|
||
useCache = !xml && !ofType;
|
||
|
||
if ( parent ) {
|
||
|
||
// :(first|last|only)-(child|of-type)
|
||
if ( simple ) {
|
||
while ( dir ) {
|
||
node = elem;
|
||
while ( (node = node[ dir ]) ) {
|
||
if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
|
||
return false;
|
||
}
|
||
}
|
||
// Reverse direction for :only-* (if we haven't yet done so)
|
||
start = dir = type === "only" && !start && "nextSibling";
|
||
}
|
||
return true;
|
||
}
|
||
|
||
start = [ forward ? parent.firstChild : parent.lastChild ];
|
||
|
||
// non-xml :nth-child(...) stores cache data on `parent`
|
||
if ( forward && useCache ) {
|
||
// Seek `elem` from a previously-cached index
|
||
outerCache = parent[ expando ] || (parent[ expando ] = {});
|
||
cache = outerCache[ type ] || [];
|
||
nodeIndex = cache[0] === dirruns && cache[1];
|
||
diff = cache[0] === dirruns && cache[2];
|
||
node = nodeIndex && parent.childNodes[ nodeIndex ];
|
||
|
||
while ( (node = ++nodeIndex && node && node[ dir ] ||
|
||
|
||
// Fallback to seeking `elem` from the start
|
||
(diff = nodeIndex = 0) || start.pop()) ) {
|
||
|
||
// When found, cache indexes on `parent` and break
|
||
if ( node.nodeType === 1 && ++diff && node === elem ) {
|
||
outerCache[ type ] = [ dirruns, nodeIndex, diff ];
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Use previously-cached element index if available
|
||
} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
|
||
diff = cache[1];
|
||
|
||
// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
|
||
} else {
|
||
// Use the same loop as above to seek `elem` from the start
|
||
while ( (node = ++nodeIndex && node && node[ dir ] ||
|
||
(diff = nodeIndex = 0) || start.pop()) ) {
|
||
|
||
if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
|
||
// Cache the index of each encountered element
|
||
if ( useCache ) {
|
||
(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
|
||
}
|
||
|
||
if ( node === elem ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Incorporate the offset, then check against cycle size
|
||
diff -= last;
|
||
return diff === first || ( diff % first === 0 && diff / first >= 0 );
|
||
}
|
||
};
|
||
},
|
||
|
||
"PSEUDO": function( pseudo, argument ) {
|
||
// pseudo-class names are case-insensitive
|
||
// http://www.w3.org/TR/selectors/#pseudo-classes
|
||
// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
|
||
// Remember that setFilters inherits from pseudos
|
||
var args,
|
||
fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
|
||
Sizzle.error( "unsupported pseudo: " + pseudo );
|
||
|
||
// The user may use createPseudo to indicate that
|
||
// arguments are needed to create the filter function
|
||
// just as Sizzle does
|
||
if ( fn[ expando ] ) {
|
||
return fn( argument );
|
||
}
|
||
|
||
// But maintain support for old signatures
|
||
if ( fn.length > 1 ) {
|
||
args = [ pseudo, pseudo, "", argument ];
|
||
return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
|
||
markFunction(function( seed, matches ) {
|
||
var idx,
|
||
matched = fn( seed, argument ),
|
||
i = matched.length;
|
||
while ( i-- ) {
|
||
idx = indexOf.call( seed, matched[i] );
|
||
seed[ idx ] = !( matches[ idx ] = matched[i] );
|
||
}
|
||
}) :
|
||
function( elem ) {
|
||
return fn( elem, 0, args );
|
||
};
|
||
}
|
||
|
||
return fn;
|
||
}
|
||
},
|
||
|
||
pseudos: {
|
||
// Potentially complex pseudos
|
||
"not": markFunction(function( selector ) {
|
||
// Trim the selector passed to compile
|
||
// to avoid treating leading and trailing
|
||
// spaces as combinators
|
||
var input = [],
|
||
results = [],
|
||
matcher = compile( selector.replace( rtrim, "$1" ) );
|
||
|
||
return matcher[ expando ] ?
|
||
markFunction(function( seed, matches, context, xml ) {
|
||
var elem,
|
||
unmatched = matcher( seed, null, xml, [] ),
|
||
i = seed.length;
|
||
|
||
// Match elements unmatched by `matcher`
|
||
while ( i-- ) {
|
||
if ( (elem = unmatched[i]) ) {
|
||
seed[i] = !(matches[i] = elem);
|
||
}
|
||
}
|
||
}) :
|
||
function( elem, context, xml ) {
|
||
input[0] = elem;
|
||
matcher( input, null, xml, results );
|
||
return !results.pop();
|
||
};
|
||
}),
|
||
|
||
"has": markFunction(function( selector ) {
|
||
return function( elem ) {
|
||
return Sizzle( selector, elem ).length > 0;
|
||
};
|
||
}),
|
||
|
||
"contains": markFunction(function( text ) {
|
||
return function( elem ) {
|
||
return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
|
||
};
|
||
}),
|
||
|
||
// "Whether an element is represented by a :lang() selector
|
||
// is based solely on the element's language value
|
||
// being equal to the identifier C,
|
||
// or beginning with the identifier C immediately followed by "-".
|
||
// The matching of C against the element's language value is performed case-insensitively.
|
||
// The identifier C does not have to be a valid language name."
|
||
// http://www.w3.org/TR/selectors/#lang-pseudo
|
||
"lang": markFunction( function( lang ) {
|
||
// lang value must be a valid identifier
|
||
if ( !ridentifier.test(lang || "") ) {
|
||
Sizzle.error( "unsupported lang: " + lang );
|
||
}
|
||
lang = lang.replace( runescape, funescape ).toLowerCase();
|
||
return function( elem ) {
|
||
var elemLang;
|
||
do {
|
||
if ( (elemLang = documentIsHTML ?
|
||
elem.lang :
|
||
elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
|
||
|
||
elemLang = elemLang.toLowerCase();
|
||
return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
|
||
}
|
||
} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
|
||
return false;
|
||
};
|
||
}),
|
||
|
||
// Miscellaneous
|
||
"target": function( elem ) {
|
||
var hash = window.location && window.location.hash;
|
||
return hash && hash.slice( 1 ) === elem.id;
|
||
},
|
||
|
||
"root": function( elem ) {
|
||
return elem === docElem;
|
||
},
|
||
|
||
"focus": function( elem ) {
|
||
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
|
||
},
|
||
|
||
// Boolean properties
|
||
"enabled": function( elem ) {
|
||
return elem.disabled === false;
|
||
},
|
||
|
||
"disabled": function( elem ) {
|
||
return elem.disabled === true;
|
||
},
|
||
|
||
"checked": function( elem ) {
|
||
// In CSS3, :checked should return both checked and selected elements
|
||
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
|
||
var nodeName = elem.nodeName.toLowerCase();
|
||
return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
|
||
},
|
||
|
||
"selected": function( elem ) {
|
||
// Accessing this property makes selected-by-default
|
||
// options in Safari work properly
|
||
if ( elem.parentNode ) {
|
||
elem.parentNode.selectedIndex;
|
||
}
|
||
|
||
return elem.selected === true;
|
||
},
|
||
|
||
// Contents
|
||
"empty": function( elem ) {
|
||
// http://www.w3.org/TR/selectors/#empty-pseudo
|
||
// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
|
||
// but not by others (comment: 8; processing instruction: 7; etc.)
|
||
// nodeType < 6 works because attributes (2) do not appear as children
|
||
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
|
||
if ( elem.nodeType < 6 ) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
},
|
||
|
||
"parent": function( elem ) {
|
||
return !Expr.pseudos["empty"]( elem );
|
||
},
|
||
|
||
// Element/input types
|
||
"header": function( elem ) {
|
||
return rheader.test( elem.nodeName );
|
||
},
|
||
|
||
"input": function( elem ) {
|
||
return rinputs.test( elem.nodeName );
|
||
},
|
||
|
||
"button": function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return name === "input" && elem.type === "button" || name === "button";
|
||
},
|
||
|
||
"text": function( elem ) {
|
||
var attr;
|
||
return elem.nodeName.toLowerCase() === "input" &&
|
||
elem.type === "text" &&
|
||
|
||
// Support: IE<8
|
||
// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
|
||
( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
|
||
},
|
||
|
||
// Position-in-collection
|
||
"first": createPositionalPseudo(function() {
|
||
return [ 0 ];
|
||
}),
|
||
|
||
"last": createPositionalPseudo(function( matchIndexes, length ) {
|
||
return [ length - 1 ];
|
||
}),
|
||
|
||
"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
return [ argument < 0 ? argument + length : argument ];
|
||
}),
|
||
|
||
"even": createPositionalPseudo(function( matchIndexes, length ) {
|
||
var i = 0;
|
||
for ( ; i < length; i += 2 ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"odd": createPositionalPseudo(function( matchIndexes, length ) {
|
||
var i = 1;
|
||
for ( ; i < length; i += 2 ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
var i = argument < 0 ? argument + length : argument;
|
||
for ( ; --i >= 0; ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
var i = argument < 0 ? argument + length : argument;
|
||
for ( ; ++i < length; ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
})
|
||
}
|
||
};
|
||
|
||
Expr.pseudos["nth"] = Expr.pseudos["eq"];
|
||
|
||
// Add button/input type pseudos
|
||
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
|
||
Expr.pseudos[ i ] = createInputPseudo( i );
|
||
}
|
||
for ( i in { submit: true, reset: true } ) {
|
||
Expr.pseudos[ i ] = createButtonPseudo( i );
|
||
}
|
||
|
||
// Easy API for creating new setFilters
|
||
function setFilters() {}
|
||
setFilters.prototype = Expr.filters = Expr.pseudos;
|
||
Expr.setFilters = new setFilters();
|
||
|
||
tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
|
||
var matched, match, tokens, type,
|
||
soFar, groups, preFilters,
|
||
cached = tokenCache[ selector + " " ];
|
||
|
||
if ( cached ) {
|
||
return parseOnly ? 0 : cached.slice( 0 );
|
||
}
|
||
|
||
soFar = selector;
|
||
groups = [];
|
||
preFilters = Expr.preFilter;
|
||
|
||
while ( soFar ) {
|
||
|
||
// Comma and first run
|
||
if ( !matched || (match = rcomma.exec( soFar )) ) {
|
||
if ( match ) {
|
||
// Don't consume trailing commas as valid
|
||
soFar = soFar.slice( match[0].length ) || soFar;
|
||
}
|
||
groups.push( (tokens = []) );
|
||
}
|
||
|
||
matched = false;
|
||
|
||
// Combinators
|
||
if ( (match = rcombinators.exec( soFar )) ) {
|
||
matched = match.shift();
|
||
tokens.push({
|
||
value: matched,
|
||
// Cast descendant combinators to space
|
||
type: match[0].replace( rtrim, " " )
|
||
});
|
||
soFar = soFar.slice( matched.length );
|
||
}
|
||
|
||
// Filters
|
||
for ( type in Expr.filter ) {
|
||
if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
|
||
(match = preFilters[ type ]( match ))) ) {
|
||
matched = match.shift();
|
||
tokens.push({
|
||
value: matched,
|
||
type: type,
|
||
matches: match
|
||
});
|
||
soFar = soFar.slice( matched.length );
|
||
}
|
||
}
|
||
|
||
if ( !matched ) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Return the length of the invalid excess
|
||
// if we're just parsing
|
||
// Otherwise, throw an error or return tokens
|
||
return parseOnly ?
|
||
soFar.length :
|
||
soFar ?
|
||
Sizzle.error( selector ) :
|
||
// Cache the tokens
|
||
tokenCache( selector, groups ).slice( 0 );
|
||
};
|
||
|
||
function toSelector( tokens ) {
|
||
var i = 0,
|
||
len = tokens.length,
|
||
selector = "";
|
||
for ( ; i < len; i++ ) {
|
||
selector += tokens[i].value;
|
||
}
|
||
return selector;
|
||
}
|
||
|
||
function addCombinator( matcher, combinator, base ) {
|
||
var dir = combinator.dir,
|
||
checkNonElements = base && dir === "parentNode",
|
||
doneName = done++;
|
||
|
||
return combinator.first ?
|
||
// Check against closest ancestor/preceding element
|
||
function( elem, context, xml ) {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
return matcher( elem, context, xml );
|
||
}
|
||
}
|
||
} :
|
||
|
||
// Check against all ancestor/preceding elements
|
||
function( elem, context, xml ) {
|
||
var oldCache, outerCache,
|
||
newCache = [ dirruns, doneName ];
|
||
|
||
// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
|
||
if ( xml ) {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
if ( matcher( elem, context, xml ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
outerCache = elem[ expando ] || (elem[ expando ] = {});
|
||
if ( (oldCache = outerCache[ dir ]) &&
|
||
oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
|
||
|
||
// Assign to newCache so results back-propagate to previous elements
|
||
return (newCache[ 2 ] = oldCache[ 2 ]);
|
||
} else {
|
||
// Reuse newcache so results back-propagate to previous elements
|
||
outerCache[ dir ] = newCache;
|
||
|
||
// A match means we're done; a fail means we have to keep checking
|
||
if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
function elementMatcher( matchers ) {
|
||
return matchers.length > 1 ?
|
||
function( elem, context, xml ) {
|
||
var i = matchers.length;
|
||
while ( i-- ) {
|
||
if ( !matchers[i]( elem, context, xml ) ) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
} :
|
||
matchers[0];
|
||
}
|
||
|
||
function multipleContexts( selector, contexts, results ) {
|
||
var i = 0,
|
||
len = contexts.length;
|
||
for ( ; i < len; i++ ) {
|
||
Sizzle( selector, contexts[i], results );
|
||
}
|
||
return results;
|
||
}
|
||
|
||
function condense( unmatched, map, filter, context, xml ) {
|
||
var elem,
|
||
newUnmatched = [],
|
||
i = 0,
|
||
len = unmatched.length,
|
||
mapped = map != null;
|
||
|
||
for ( ; i < len; i++ ) {
|
||
if ( (elem = unmatched[i]) ) {
|
||
if ( !filter || filter( elem, context, xml ) ) {
|
||
newUnmatched.push( elem );
|
||
if ( mapped ) {
|
||
map.push( i );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return newUnmatched;
|
||
}
|
||
|
||
function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
|
||
if ( postFilter && !postFilter[ expando ] ) {
|
||
postFilter = setMatcher( postFilter );
|
||
}
|
||
if ( postFinder && !postFinder[ expando ] ) {
|
||
postFinder = setMatcher( postFinder, postSelector );
|
||
}
|
||
return markFunction(function( seed, results, context, xml ) {
|
||
var temp, i, elem,
|
||
preMap = [],
|
||
postMap = [],
|
||
preexisting = results.length,
|
||
|
||
// Get initial elements from seed or context
|
||
elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
|
||
|
||
// Prefilter to get matcher input, preserving a map for seed-results synchronization
|
||
matcherIn = preFilter && ( seed || !selector ) ?
|
||
condense( elems, preMap, preFilter, context, xml ) :
|
||
elems,
|
||
|
||
matcherOut = matcher ?
|
||
// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
|
||
postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
|
||
|
||
// ...intermediate processing is necessary
|
||
[] :
|
||
|
||
// ...otherwise use results directly
|
||
results :
|
||
matcherIn;
|
||
|
||
// Find primary matches
|
||
if ( matcher ) {
|
||
matcher( matcherIn, matcherOut, context, xml );
|
||
}
|
||
|
||
// Apply postFilter
|
||
if ( postFilter ) {
|
||
temp = condense( matcherOut, postMap );
|
||
postFilter( temp, [], context, xml );
|
||
|
||
// Un-match failing elements by moving them back to matcherIn
|
||
i = temp.length;
|
||
while ( i-- ) {
|
||
if ( (elem = temp[i]) ) {
|
||
matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( seed ) {
|
||
if ( postFinder || preFilter ) {
|
||
if ( postFinder ) {
|
||
// Get the final matcherOut by condensing this intermediate into postFinder contexts
|
||
temp = [];
|
||
i = matcherOut.length;
|
||
while ( i-- ) {
|
||
if ( (elem = matcherOut[i]) ) {
|
||
// Restore matcherIn since elem is not yet a final match
|
||
temp.push( (matcherIn[i] = elem) );
|
||
}
|
||
}
|
||
postFinder( null, (matcherOut = []), temp, xml );
|
||
}
|
||
|
||
// Move matched elements from seed to results to keep them synchronized
|
||
i = matcherOut.length;
|
||
while ( i-- ) {
|
||
if ( (elem = matcherOut[i]) &&
|
||
(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
|
||
|
||
seed[temp] = !(results[temp] = elem);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Add elements to results, through postFinder if defined
|
||
} else {
|
||
matcherOut = condense(
|
||
matcherOut === results ?
|
||
matcherOut.splice( preexisting, matcherOut.length ) :
|
||
matcherOut
|
||
);
|
||
if ( postFinder ) {
|
||
postFinder( null, results, matcherOut, xml );
|
||
} else {
|
||
push.apply( results, matcherOut );
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
function matcherFromTokens( tokens ) {
|
||
var checkContext, matcher, j,
|
||
len = tokens.length,
|
||
leadingRelative = Expr.relative[ tokens[0].type ],
|
||
implicitRelative = leadingRelative || Expr.relative[" "],
|
||
i = leadingRelative ? 1 : 0,
|
||
|
||
// The foundational matcher ensures that elements are reachable from top-level context(s)
|
||
matchContext = addCombinator( function( elem ) {
|
||
return elem === checkContext;
|
||
}, implicitRelative, true ),
|
||
matchAnyContext = addCombinator( function( elem ) {
|
||
return indexOf.call( checkContext, elem ) > -1;
|
||
}, implicitRelative, true ),
|
||
matchers = [ function( elem, context, xml ) {
|
||
return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
|
||
(checkContext = context).nodeType ?
|
||
matchContext( elem, context, xml ) :
|
||
matchAnyContext( elem, context, xml ) );
|
||
} ];
|
||
|
||
for ( ; i < len; i++ ) {
|
||
if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
|
||
matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
|
||
} else {
|
||
matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
|
||
|
||
// Return special upon seeing a positional matcher
|
||
if ( matcher[ expando ] ) {
|
||
// Find the next relative operator (if any) for proper handling
|
||
j = ++i;
|
||
for ( ; j < len; j++ ) {
|
||
if ( Expr.relative[ tokens[j].type ] ) {
|
||
break;
|
||
}
|
||
}
|
||
return setMatcher(
|
||
i > 1 && elementMatcher( matchers ),
|
||
i > 1 && toSelector(
|
||
// If the preceding token was a descendant combinator, insert an implicit any-element `*`
|
||
tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
|
||
).replace( rtrim, "$1" ),
|
||
matcher,
|
||
i < j && matcherFromTokens( tokens.slice( i, j ) ),
|
||
j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
|
||
j < len && toSelector( tokens )
|
||
);
|
||
}
|
||
matchers.push( matcher );
|
||
}
|
||
}
|
||
|
||
return elementMatcher( matchers );
|
||
}
|
||
|
||
function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
|
||
var bySet = setMatchers.length > 0,
|
||
byElement = elementMatchers.length > 0,
|
||
superMatcher = function( seed, context, xml, results, outermost ) {
|
||
var elem, j, matcher,
|
||
matchedCount = 0,
|
||
i = "0",
|
||
unmatched = seed && [],
|
||
setMatched = [],
|
||
contextBackup = outermostContext,
|
||
// We must always have either seed elements or outermost context
|
||
elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
|
||
// Use integer dirruns iff this is the outermost matcher
|
||
dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
|
||
len = elems.length;
|
||
|
||
if ( outermost ) {
|
||
outermostContext = context !== document && context;
|
||
}
|
||
|
||
// Add elements passing elementMatchers directly to results
|
||
// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
|
||
// Support: IE<9, Safari
|
||
// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
|
||
for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
|
||
if ( byElement && elem ) {
|
||
j = 0;
|
||
while ( (matcher = elementMatchers[j++]) ) {
|
||
if ( matcher( elem, context, xml ) ) {
|
||
results.push( elem );
|
||
break;
|
||
}
|
||
}
|
||
if ( outermost ) {
|
||
dirruns = dirrunsUnique;
|
||
}
|
||
}
|
||
|
||
// Track unmatched elements for set filters
|
||
if ( bySet ) {
|
||
// They will have gone through all possible matchers
|
||
if ( (elem = !matcher && elem) ) {
|
||
matchedCount--;
|
||
}
|
||
|
||
// Lengthen the array for every element, matched or not
|
||
if ( seed ) {
|
||
unmatched.push( elem );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Apply set filters to unmatched elements
|
||
matchedCount += i;
|
||
if ( bySet && i !== matchedCount ) {
|
||
j = 0;
|
||
while ( (matcher = setMatchers[j++]) ) {
|
||
matcher( unmatched, setMatched, context, xml );
|
||
}
|
||
|
||
if ( seed ) {
|
||
// Reintegrate element matches to eliminate the need for sorting
|
||
if ( matchedCount > 0 ) {
|
||
while ( i-- ) {
|
||
if ( !(unmatched[i] || setMatched[i]) ) {
|
||
setMatched[i] = pop.call( results );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Discard index placeholder values to get only actual matches
|
||
setMatched = condense( setMatched );
|
||
}
|
||
|
||
// Add matches to results
|
||
push.apply( results, setMatched );
|
||
|
||
// Seedless set matches succeeding multiple successful matchers stipulate sorting
|
||
if ( outermost && !seed && setMatched.length > 0 &&
|
||
( matchedCount + setMatchers.length ) > 1 ) {
|
||
|
||
Sizzle.uniqueSort( results );
|
||
}
|
||
}
|
||
|
||
// Override manipulation of globals by nested matchers
|
||
if ( outermost ) {
|
||
dirruns = dirrunsUnique;
|
||
outermostContext = contextBackup;
|
||
}
|
||
|
||
return unmatched;
|
||
};
|
||
|
||
return bySet ?
|
||
markFunction( superMatcher ) :
|
||
superMatcher;
|
||
}
|
||
|
||
compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
|
||
var i,
|
||
setMatchers = [],
|
||
elementMatchers = [],
|
||
cached = compilerCache[ selector + " " ];
|
||
|
||
if ( !cached ) {
|
||
// Generate a function of recursive functions that can be used to check each element
|
||
if ( !match ) {
|
||
match = tokenize( selector );
|
||
}
|
||
i = match.length;
|
||
while ( i-- ) {
|
||
cached = matcherFromTokens( match[i] );
|
||
if ( cached[ expando ] ) {
|
||
setMatchers.push( cached );
|
||
} else {
|
||
elementMatchers.push( cached );
|
||
}
|
||
}
|
||
|
||
// Cache the compiled function
|
||
cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
|
||
|
||
// Save selector and tokenization
|
||
cached.selector = selector;
|
||
}
|
||
return cached;
|
||
};
|
||
|
||
/**
|
||
* A low-level selection function that works with Sizzle's compiled
|
||
* selector functions
|
||
* @param {String|Function} selector A selector or a pre-compiled
|
||
* selector function built with Sizzle.compile
|
||
* @param {Element} context
|
||
* @param {Array} [results]
|
||
* @param {Array} [seed] A set of elements to match against
|
||
*/
|
||
select = Sizzle.select = function( selector, context, results, seed ) {
|
||
var i, tokens, token, type, find,
|
||
compiled = typeof selector === "function" && selector,
|
||
match = !seed && tokenize( (selector = compiled.selector || selector) );
|
||
|
||
results = results || [];
|
||
|
||
// Try to minimize operations if there is no seed and only one group
|
||
if ( match.length === 1 ) {
|
||
|
||
// Take a shortcut and set the context if the root selector is an ID
|
||
tokens = match[0] = match[0].slice( 0 );
|
||
if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
|
||
support.getById && context.nodeType === 9 && documentIsHTML &&
|
||
Expr.relative[ tokens[1].type ] ) {
|
||
|
||
context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
|
||
if ( !context ) {
|
||
return results;
|
||
|
||
// Precompiled matchers will still verify ancestry, so step up a level
|
||
} else if ( compiled ) {
|
||
context = context.parentNode;
|
||
}
|
||
|
||
selector = selector.slice( tokens.shift().value.length );
|
||
}
|
||
|
||
// Fetch a seed set for right-to-left matching
|
||
i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
|
||
while ( i-- ) {
|
||
token = tokens[i];
|
||
|
||
// Abort if we hit a combinator
|
||
if ( Expr.relative[ (type = token.type) ] ) {
|
||
break;
|
||
}
|
||
if ( (find = Expr.find[ type ]) ) {
|
||
// Search, expanding context for leading sibling combinators
|
||
if ( (seed = find(
|
||
token.matches[0].replace( runescape, funescape ),
|
||
rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
|
||
)) ) {
|
||
|
||
// If seed is empty or no tokens remain, we can return early
|
||
tokens.splice( i, 1 );
|
||
selector = seed.length && toSelector( tokens );
|
||
if ( !selector ) {
|
||
push.apply( results, seed );
|
||
return results;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Compile and execute a filtering function if one is not provided
|
||
// Provide `match` to avoid retokenization if we modified the selector above
|
||
( compiled || compile( selector, match ) )(
|
||
seed,
|
||
context,
|
||
!documentIsHTML,
|
||
results,
|
||
rsibling.test( selector ) && testContext( context.parentNode ) || context
|
||
);
|
||
return results;
|
||
};
|
||
|
||
// One-time assignments
|
||
|
||
// Sort stability
|
||
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
|
||
|
||
// Support: Chrome<14
|
||
// Always assume duplicates if they aren't passed to the comparison function
|
||
support.detectDuplicates = !!hasDuplicate;
|
||
|
||
// Initialize against the default document
|
||
setDocument();
|
||
|
||
// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
|
||
// Detached nodes confoundingly follow *each other*
|
||
support.sortDetached = assert(function( div1 ) {
|
||
// Should return 1, but returns 4 (following)
|
||
return div1.compareDocumentPosition( document.createElement("div") ) & 1;
|
||
});
|
||
|
||
// Support: IE<8
|
||
// Prevent attribute/property "interpolation"
|
||
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
|
||
if ( !assert(function( div ) {
|
||
div.innerHTML = "<a href='#'></a>";
|
||
return div.firstChild.getAttribute("href") === "#" ;
|
||
}) ) {
|
||
addHandle( "type|href|height|width", function( elem, name, isXML ) {
|
||
if ( !isXML ) {
|
||
return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
|
||
}
|
||
});
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Use defaultValue in place of getAttribute("value")
|
||
if ( !support.attributes || !assert(function( div ) {
|
||
div.innerHTML = "<input/>";
|
||
div.firstChild.setAttribute( "value", "" );
|
||
return div.firstChild.getAttribute( "value" ) === "";
|
||
}) ) {
|
||
addHandle( "value", function( elem, name, isXML ) {
|
||
if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
|
||
return elem.defaultValue;
|
||
}
|
||
});
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Use getAttributeNode to fetch booleans when getAttribute lies
|
||
if ( !assert(function( div ) {
|
||
return div.getAttribute("disabled") == null;
|
||
}) ) {
|
||
addHandle( booleans, function( elem, name, isXML ) {
|
||
var val;
|
||
if ( !isXML ) {
|
||
return elem[ name ] === true ? name.toLowerCase() :
|
||
(val = elem.getAttributeNode( name )) && val.specified ?
|
||
val.value :
|
||
null;
|
||
}
|
||
});
|
||
}
|
||
|
||
return Sizzle;
|
||
|
||
})( window );
|
||
|
||
|
||
|
||
jQuery.find = Sizzle;
|
||
jQuery.expr = Sizzle.selectors;
|
||
jQuery.expr[":"] = jQuery.expr.pseudos;
|
||
jQuery.unique = Sizzle.uniqueSort;
|
||
jQuery.text = Sizzle.getText;
|
||
jQuery.isXMLDoc = Sizzle.isXML;
|
||
jQuery.contains = Sizzle.contains;
|
||
|
||
|
||
|
||
var rneedsContext = jQuery.expr.match.needsContext;
|
||
|
||
var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
|
||
|
||
|
||
|
||
var risSimple = /^.[^:#\[\.,]*$/;
|
||
|
||
// Implement the identical functionality for filter and not
|
||
function winnow( elements, qualifier, not ) {
|
||
if ( jQuery.isFunction( qualifier ) ) {
|
||
return jQuery.grep( elements, function( elem, i ) {
|
||
/* jshint -W018 */
|
||
return !!qualifier.call( elem, i, elem ) !== not;
|
||
});
|
||
|
||
}
|
||
|
||
if ( qualifier.nodeType ) {
|
||
return jQuery.grep( elements, function( elem ) {
|
||
return ( elem === qualifier ) !== not;
|
||
});
|
||
|
||
}
|
||
|
||
if ( typeof qualifier === "string" ) {
|
||
if ( risSimple.test( qualifier ) ) {
|
||
return jQuery.filter( qualifier, elements, not );
|
||
}
|
||
|
||
qualifier = jQuery.filter( qualifier, elements );
|
||
}
|
||
|
||
return jQuery.grep( elements, function( elem ) {
|
||
return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
|
||
});
|
||
}
|
||
|
||
jQuery.filter = function( expr, elems, not ) {
|
||
var elem = elems[ 0 ];
|
||
|
||
if ( not ) {
|
||
expr = ":not(" + expr + ")";
|
||
}
|
||
|
||
return elems.length === 1 && elem.nodeType === 1 ?
|
||
jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
|
||
jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
|
||
return elem.nodeType === 1;
|
||
}));
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
find: function( selector ) {
|
||
var i,
|
||
len = this.length,
|
||
ret = [],
|
||
self = this;
|
||
|
||
if ( typeof selector !== "string" ) {
|
||
return this.pushStack( jQuery( selector ).filter(function() {
|
||
for ( i = 0; i < len; i++ ) {
|
||
if ( jQuery.contains( self[ i ], this ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
}) );
|
||
}
|
||
|
||
for ( i = 0; i < len; i++ ) {
|
||
jQuery.find( selector, self[ i ], ret );
|
||
}
|
||
|
||
// Needed because $( selector, context ) becomes $( context ).find( selector )
|
||
ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
|
||
ret.selector = this.selector ? this.selector + " " + selector : selector;
|
||
return ret;
|
||
},
|
||
filter: function( selector ) {
|
||
return this.pushStack( winnow(this, selector || [], false) );
|
||
},
|
||
not: function( selector ) {
|
||
return this.pushStack( winnow(this, selector || [], true) );
|
||
},
|
||
is: function( selector ) {
|
||
return !!winnow(
|
||
this,
|
||
|
||
// If this is a positional/relative selector, check membership in the returned set
|
||
// so $("p:first").is("p:last") won't return true for a doc with two "p".
|
||
typeof selector === "string" && rneedsContext.test( selector ) ?
|
||
jQuery( selector ) :
|
||
selector || [],
|
||
false
|
||
).length;
|
||
}
|
||
});
|
||
|
||
|
||
// Initialize a jQuery object
|
||
|
||
|
||
// A central reference to the root jQuery(document)
|
||
var rootjQuery,
|
||
|
||
// A simple way to check for HTML strings
|
||
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
|
||
// Strict HTML recognition (#11290: must start with <)
|
||
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
|
||
|
||
init = jQuery.fn.init = function( selector, context ) {
|
||
var match, elem;
|
||
|
||
// HANDLE: $(""), $(null), $(undefined), $(false)
|
||
if ( !selector ) {
|
||
return this;
|
||
}
|
||
|
||
// Handle HTML strings
|
||
if ( typeof selector === "string" ) {
|
||
if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) {
|
||
// Assume that strings that start and end with <> are HTML and skip the regex check
|
||
match = [ null, selector, null ];
|
||
|
||
} else {
|
||
match = rquickExpr.exec( selector );
|
||
}
|
||
|
||
// Match html or make sure no context is specified for #id
|
||
if ( match && (match[1] || !context) ) {
|
||
|
||
// HANDLE: $(html) -> $(array)
|
||
if ( match[1] ) {
|
||
context = context instanceof jQuery ? context[0] : context;
|
||
|
||
// scripts is true for back-compat
|
||
// Intentionally let the error be thrown if parseHTML is not present
|
||
jQuery.merge( this, jQuery.parseHTML(
|
||
match[1],
|
||
context && context.nodeType ? context.ownerDocument || context : document,
|
||
true
|
||
) );
|
||
|
||
// HANDLE: $(html, props)
|
||
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
|
||
for ( match in context ) {
|
||
// Properties of context are called as methods if possible
|
||
if ( jQuery.isFunction( this[ match ] ) ) {
|
||
this[ match ]( context[ match ] );
|
||
|
||
// ...and otherwise set as attributes
|
||
} else {
|
||
this.attr( match, context[ match ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
|
||
// HANDLE: $(#id)
|
||
} else {
|
||
elem = document.getElementById( match[2] );
|
||
|
||
// Check parentNode to catch when Blackberry 4.6 returns
|
||
// nodes that are no longer in the document #6963
|
||
if ( elem && elem.parentNode ) {
|
||
// Inject the element directly into the jQuery object
|
||
this.length = 1;
|
||
this[0] = elem;
|
||
}
|
||
|
||
this.context = document;
|
||
this.selector = selector;
|
||
return this;
|
||
}
|
||
|
||
// HANDLE: $(expr, $(...))
|
||
} else if ( !context || context.jquery ) {
|
||
return ( context || rootjQuery ).find( selector );
|
||
|
||
// HANDLE: $(expr, context)
|
||
// (which is just equivalent to: $(context).find(expr)
|
||
} else {
|
||
return this.constructor( context ).find( selector );
|
||
}
|
||
|
||
// HANDLE: $(DOMElement)
|
||
} else if ( selector.nodeType ) {
|
||
this.context = this[0] = selector;
|
||
this.length = 1;
|
||
return this;
|
||
|
||
// HANDLE: $(function)
|
||
// Shortcut for document ready
|
||
} else if ( jQuery.isFunction( selector ) ) {
|
||
return typeof rootjQuery.ready !== "undefined" ?
|
||
rootjQuery.ready( selector ) :
|
||
// Execute immediately if ready is not present
|
||
selector( jQuery );
|
||
}
|
||
|
||
if ( selector.selector !== undefined ) {
|
||
this.selector = selector.selector;
|
||
this.context = selector.context;
|
||
}
|
||
|
||
return jQuery.makeArray( selector, this );
|
||
};
|
||
|
||
// Give the init function the jQuery prototype for later instantiation
|
||
init.prototype = jQuery.fn;
|
||
|
||
// Initialize central reference
|
||
rootjQuery = jQuery( document );
|
||
|
||
|
||
var rparentsprev = /^(?:parents|prev(?:Until|All))/,
|
||
// methods guaranteed to produce a unique set when starting from a unique set
|
||
guaranteedUnique = {
|
||
children: true,
|
||
contents: true,
|
||
next: true,
|
||
prev: true
|
||
};
|
||
|
||
jQuery.extend({
|
||
dir: function( elem, dir, until ) {
|
||
var matched = [],
|
||
truncate = until !== undefined;
|
||
|
||
while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
|
||
if ( elem.nodeType === 1 ) {
|
||
if ( truncate && jQuery( elem ).is( until ) ) {
|
||
break;
|
||
}
|
||
matched.push( elem );
|
||
}
|
||
}
|
||
return matched;
|
||
},
|
||
|
||
sibling: function( n, elem ) {
|
||
var matched = [];
|
||
|
||
for ( ; n; n = n.nextSibling ) {
|
||
if ( n.nodeType === 1 && n !== elem ) {
|
||
matched.push( n );
|
||
}
|
||
}
|
||
|
||
return matched;
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
has: function( target ) {
|
||
var targets = jQuery( target, this ),
|
||
l = targets.length;
|
||
|
||
return this.filter(function() {
|
||
var i = 0;
|
||
for ( ; i < l; i++ ) {
|
||
if ( jQuery.contains( this, targets[i] ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
closest: function( selectors, context ) {
|
||
var cur,
|
||
i = 0,
|
||
l = this.length,
|
||
matched = [],
|
||
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
|
||
jQuery( selectors, context || this.context ) :
|
||
0;
|
||
|
||
for ( ; i < l; i++ ) {
|
||
for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
|
||
// Always skip document fragments
|
||
if ( cur.nodeType < 11 && (pos ?
|
||
pos.index(cur) > -1 :
|
||
|
||
// Don't pass non-elements to Sizzle
|
||
cur.nodeType === 1 &&
|
||
jQuery.find.matchesSelector(cur, selectors)) ) {
|
||
|
||
matched.push( cur );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
|
||
},
|
||
|
||
// Determine the position of an element within
|
||
// the matched set of elements
|
||
index: function( elem ) {
|
||
|
||
// No argument, return index in parent
|
||
if ( !elem ) {
|
||
return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
|
||
}
|
||
|
||
// index in selector
|
||
if ( typeof elem === "string" ) {
|
||
return indexOf.call( jQuery( elem ), this[ 0 ] );
|
||
}
|
||
|
||
// Locate the position of the desired element
|
||
return indexOf.call( this,
|
||
|
||
// If it receives a jQuery object, the first element is used
|
||
elem.jquery ? elem[ 0 ] : elem
|
||
);
|
||
},
|
||
|
||
add: function( selector, context ) {
|
||
return this.pushStack(
|
||
jQuery.unique(
|
||
jQuery.merge( this.get(), jQuery( selector, context ) )
|
||
)
|
||
);
|
||
},
|
||
|
||
addBack: function( selector ) {
|
||
return this.add( selector == null ?
|
||
this.prevObject : this.prevObject.filter(selector)
|
||
);
|
||
}
|
||
});
|
||
|
||
function sibling( cur, dir ) {
|
||
while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
|
||
return cur;
|
||
}
|
||
|
||
jQuery.each({
|
||
parent: function( elem ) {
|
||
var parent = elem.parentNode;
|
||
return parent && parent.nodeType !== 11 ? parent : null;
|
||
},
|
||
parents: function( elem ) {
|
||
return jQuery.dir( elem, "parentNode" );
|
||
},
|
||
parentsUntil: function( elem, i, until ) {
|
||
return jQuery.dir( elem, "parentNode", until );
|
||
},
|
||
next: function( elem ) {
|
||
return sibling( elem, "nextSibling" );
|
||
},
|
||
prev: function( elem ) {
|
||
return sibling( elem, "previousSibling" );
|
||
},
|
||
nextAll: function( elem ) {
|
||
return jQuery.dir( elem, "nextSibling" );
|
||
},
|
||
prevAll: function( elem ) {
|
||
return jQuery.dir( elem, "previousSibling" );
|
||
},
|
||
nextUntil: function( elem, i, until ) {
|
||
return jQuery.dir( elem, "nextSibling", until );
|
||
},
|
||
prevUntil: function( elem, i, until ) {
|
||
return jQuery.dir( elem, "previousSibling", until );
|
||
},
|
||
siblings: function( elem ) {
|
||
return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
|
||
},
|
||
children: function( elem ) {
|
||
return jQuery.sibling( elem.firstChild );
|
||
},
|
||
contents: function( elem ) {
|
||
return elem.contentDocument || jQuery.merge( [], elem.childNodes );
|
||
}
|
||
}, function( name, fn ) {
|
||
jQuery.fn[ name ] = function( until, selector ) {
|
||
var matched = jQuery.map( this, fn, until );
|
||
|
||
if ( name.slice( -5 ) !== "Until" ) {
|
||
selector = until;
|
||
}
|
||
|
||
if ( selector && typeof selector === "string" ) {
|
||
matched = jQuery.filter( selector, matched );
|
||
}
|
||
|
||
if ( this.length > 1 ) {
|
||
// Remove duplicates
|
||
if ( !guaranteedUnique[ name ] ) {
|
||
jQuery.unique( matched );
|
||
}
|
||
|
||
// Reverse order for parents* and prev-derivatives
|
||
if ( rparentsprev.test( name ) ) {
|
||
matched.reverse();
|
||
}
|
||
}
|
||
|
||
return this.pushStack( matched );
|
||
};
|
||
});
|
||
var rnotwhite = (/\S+/g);
|
||
|
||
|
||
|
||
// String to Object options format cache
|
||
var optionsCache = {};
|
||
|
||
// Convert String-formatted options into Object-formatted ones and store in cache
|
||
function createOptions( options ) {
|
||
var object = optionsCache[ options ] = {};
|
||
jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
|
||
object[ flag ] = true;
|
||
});
|
||
return object;
|
||
}
|
||
|
||
/*
|
||
* Create a callback list using the following parameters:
|
||
*
|
||
* options: an optional list of space-separated options that will change how
|
||
* the callback list behaves or a more traditional option object
|
||
*
|
||
* By default a callback list will act like an event callback list and can be
|
||
* "fired" multiple times.
|
||
*
|
||
* Possible options:
|
||
*
|
||
* once: will ensure the callback list can only be fired once (like a Deferred)
|
||
*
|
||
* memory: will keep track of previous values and will call any callback added
|
||
* after the list has been fired right away with the latest "memorized"
|
||
* values (like a Deferred)
|
||
*
|
||
* unique: will ensure a callback can only be added once (no duplicate in the list)
|
||
*
|
||
* stopOnFalse: interrupt callings when a callback returns false
|
||
*
|
||
*/
|
||
jQuery.Callbacks = function( options ) {
|
||
|
||
// Convert options from String-formatted to Object-formatted if needed
|
||
// (we check in cache first)
|
||
options = typeof options === "string" ?
|
||
( optionsCache[ options ] || createOptions( options ) ) :
|
||
jQuery.extend( {}, options );
|
||
|
||
var // Last fire value (for non-forgettable lists)
|
||
memory,
|
||
// Flag to know if list was already fired
|
||
fired,
|
||
// Flag to know if list is currently firing
|
||
firing,
|
||
// First callback to fire (used internally by add and fireWith)
|
||
firingStart,
|
||
// End of the loop when firing
|
||
firingLength,
|
||
// Index of currently firing callback (modified by remove if needed)
|
||
firingIndex,
|
||
// Actual callback list
|
||
list = [],
|
||
// Stack of fire calls for repeatable lists
|
||
stack = !options.once && [],
|
||
// Fire callbacks
|
||
fire = function( data ) {
|
||
memory = options.memory && data;
|
||
fired = true;
|
||
firingIndex = firingStart || 0;
|
||
firingStart = 0;
|
||
firingLength = list.length;
|
||
firing = true;
|
||
for ( ; list && firingIndex < firingLength; firingIndex++ ) {
|
||
if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
|
||
memory = false; // To prevent further calls using add
|
||
break;
|
||
}
|
||
}
|
||
firing = false;
|
||
if ( list ) {
|
||
if ( stack ) {
|
||
if ( stack.length ) {
|
||
fire( stack.shift() );
|
||
}
|
||
} else if ( memory ) {
|
||
list = [];
|
||
} else {
|
||
self.disable();
|
||
}
|
||
}
|
||
},
|
||
// Actual Callbacks object
|
||
self = {
|
||
// Add a callback or a collection of callbacks to the list
|
||
add: function() {
|
||
if ( list ) {
|
||
// First, we save the current length
|
||
var start = list.length;
|
||
(function add( args ) {
|
||
jQuery.each( args, function( _, arg ) {
|
||
var type = jQuery.type( arg );
|
||
if ( type === "function" ) {
|
||
if ( !options.unique || !self.has( arg ) ) {
|
||
list.push( arg );
|
||
}
|
||
} else if ( arg && arg.length && type !== "string" ) {
|
||
// Inspect recursively
|
||
add( arg );
|
||
}
|
||
});
|
||
})( arguments );
|
||
// Do we need to add the callbacks to the
|
||
// current firing batch?
|
||
if ( firing ) {
|
||
firingLength = list.length;
|
||
// With memory, if we're not firing then
|
||
// we should call right away
|
||
} else if ( memory ) {
|
||
firingStart = start;
|
||
fire( memory );
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
// Remove a callback from the list
|
||
remove: function() {
|
||
if ( list ) {
|
||
jQuery.each( arguments, function( _, arg ) {
|
||
var index;
|
||
while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
|
||
list.splice( index, 1 );
|
||
// Handle firing indexes
|
||
if ( firing ) {
|
||
if ( index <= firingLength ) {
|
||
firingLength--;
|
||
}
|
||
if ( index <= firingIndex ) {
|
||
firingIndex--;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
return this;
|
||
},
|
||
// Check if a given callback is in the list.
|
||
// If no argument is given, return whether or not list has callbacks attached.
|
||
has: function( fn ) {
|
||
return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
|
||
},
|
||
// Remove all callbacks from the list
|
||
empty: function() {
|
||
list = [];
|
||
firingLength = 0;
|
||
return this;
|
||
},
|
||
// Have the list do nothing anymore
|
||
disable: function() {
|
||
list = stack = memory = undefined;
|
||
return this;
|
||
},
|
||
// Is it disabled?
|
||
disabled: function() {
|
||
return !list;
|
||
},
|
||
// Lock the list in its current state
|
||
lock: function() {
|
||
stack = undefined;
|
||
if ( !memory ) {
|
||
self.disable();
|
||
}
|
||
return this;
|
||
},
|
||
// Is it locked?
|
||
locked: function() {
|
||
return !stack;
|
||
},
|
||
// Call all callbacks with the given context and arguments
|
||
fireWith: function( context, args ) {
|
||
if ( list && ( !fired || stack ) ) {
|
||
args = args || [];
|
||
args = [ context, args.slice ? args.slice() : args ];
|
||
if ( firing ) {
|
||
stack.push( args );
|
||
} else {
|
||
fire( args );
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
// Call all the callbacks with the given arguments
|
||
fire: function() {
|
||
self.fireWith( this, arguments );
|
||
return this;
|
||
},
|
||
// To know if the callbacks have already been called at least once
|
||
fired: function() {
|
||
return !!fired;
|
||
}
|
||
};
|
||
|
||
return self;
|
||
};
|
||
|
||
|
||
jQuery.extend({
|
||
|
||
Deferred: function( func ) {
|
||
var tuples = [
|
||
// action, add listener, listener list, final state
|
||
[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
|
||
[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
|
||
[ "notify", "progress", jQuery.Callbacks("memory") ]
|
||
],
|
||
state = "pending",
|
||
promise = {
|
||
state: function() {
|
||
return state;
|
||
},
|
||
always: function() {
|
||
deferred.done( arguments ).fail( arguments );
|
||
return this;
|
||
},
|
||
then: function( /* fnDone, fnFail, fnProgress */ ) {
|
||
var fns = arguments;
|
||
return jQuery.Deferred(function( newDefer ) {
|
||
jQuery.each( tuples, function( i, tuple ) {
|
||
var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
|
||
// deferred[ done | fail | progress ] for forwarding actions to newDefer
|
||
deferred[ tuple[1] ](function() {
|
||
var returned = fn && fn.apply( this, arguments );
|
||
if ( returned && jQuery.isFunction( returned.promise ) ) {
|
||
returned.promise()
|
||
.done( newDefer.resolve )
|
||
.fail( newDefer.reject )
|
||
.progress( newDefer.notify );
|
||
} else {
|
||
newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
|
||
}
|
||
});
|
||
});
|
||
fns = null;
|
||
}).promise();
|
||
},
|
||
// Get a promise for this deferred
|
||
// If obj is provided, the promise aspect is added to the object
|
||
promise: function( obj ) {
|
||
return obj != null ? jQuery.extend( obj, promise ) : promise;
|
||
}
|
||
},
|
||
deferred = {};
|
||
|
||
// Keep pipe for back-compat
|
||
promise.pipe = promise.then;
|
||
|
||
// Add list-specific methods
|
||
jQuery.each( tuples, function( i, tuple ) {
|
||
var list = tuple[ 2 ],
|
||
stateString = tuple[ 3 ];
|
||
|
||
// promise[ done | fail | progress ] = list.add
|
||
promise[ tuple[1] ] = list.add;
|
||
|
||
// Handle state
|
||
if ( stateString ) {
|
||
list.add(function() {
|
||
// state = [ resolved | rejected ]
|
||
state = stateString;
|
||
|
||
// [ reject_list | resolve_list ].disable; progress_list.lock
|
||
}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
|
||
}
|
||
|
||
// deferred[ resolve | reject | notify ]
|
||
deferred[ tuple[0] ] = function() {
|
||
deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
|
||
return this;
|
||
};
|
||
deferred[ tuple[0] + "With" ] = list.fireWith;
|
||
});
|
||
|
||
// Make the deferred a promise
|
||
promise.promise( deferred );
|
||
|
||
// Call given func if any
|
||
if ( func ) {
|
||
func.call( deferred, deferred );
|
||
}
|
||
|
||
// All done!
|
||
return deferred;
|
||
},
|
||
|
||
// Deferred helper
|
||
when: function( subordinate /* , ..., subordinateN */ ) {
|
||
var i = 0,
|
||
resolveValues = slice.call( arguments ),
|
||
length = resolveValues.length,
|
||
|
||
// the count of uncompleted subordinates
|
||
remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
|
||
|
||
// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
|
||
deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
|
||
|
||
// Update function for both resolve and progress values
|
||
updateFunc = function( i, contexts, values ) {
|
||
return function( value ) {
|
||
contexts[ i ] = this;
|
||
values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
|
||
if ( values === progressValues ) {
|
||
deferred.notifyWith( contexts, values );
|
||
} else if ( !( --remaining ) ) {
|
||
deferred.resolveWith( contexts, values );
|
||
}
|
||
};
|
||
},
|
||
|
||
progressValues, progressContexts, resolveContexts;
|
||
|
||
// add listeners to Deferred subordinates; treat others as resolved
|
||
if ( length > 1 ) {
|
||
progressValues = new Array( length );
|
||
progressContexts = new Array( length );
|
||
resolveContexts = new Array( length );
|
||
for ( ; i < length; i++ ) {
|
||
if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
|
||
resolveValues[ i ].promise()
|
||
.done( updateFunc( i, resolveContexts, resolveValues ) )
|
||
.fail( deferred.reject )
|
||
.progress( updateFunc( i, progressContexts, progressValues ) );
|
||
} else {
|
||
--remaining;
|
||
}
|
||
}
|
||
}
|
||
|
||
// if we're not waiting on anything, resolve the master
|
||
if ( !remaining ) {
|
||
deferred.resolveWith( resolveContexts, resolveValues );
|
||
}
|
||
|
||
return deferred.promise();
|
||
}
|
||
});
|
||
|
||
|
||
// The deferred used on DOM ready
|
||
var readyList;
|
||
|
||
jQuery.fn.ready = function( fn ) {
|
||
// Add the callback
|
||
jQuery.ready.promise().done( fn );
|
||
|
||
return this;
|
||
};
|
||
|
||
jQuery.extend({
|
||
// Is the DOM ready to be used? Set to true once it occurs.
|
||
isReady: false,
|
||
|
||
// A counter to track how many items to wait for before
|
||
// the ready event fires. See #6781
|
||
readyWait: 1,
|
||
|
||
// Hold (or release) the ready event
|
||
holdReady: function( hold ) {
|
||
if ( hold ) {
|
||
jQuery.readyWait++;
|
||
} else {
|
||
jQuery.ready( true );
|
||
}
|
||
},
|
||
|
||
// Handle when the DOM is ready
|
||
ready: function( wait ) {
|
||
|
||
// Abort if there are pending holds or we're already ready
|
||
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
|
||
return;
|
||
}
|
||
|
||
// Remember that the DOM is ready
|
||
jQuery.isReady = true;
|
||
|
||
// If a normal DOM Ready event fired, decrement, and wait if need be
|
||
if ( wait !== true && --jQuery.readyWait > 0 ) {
|
||
return;
|
||
}
|
||
|
||
// If there are functions bound, to execute
|
||
readyList.resolveWith( document, [ jQuery ] );
|
||
|
||
// Trigger any bound ready events
|
||
if ( jQuery.fn.triggerHandler ) {
|
||
jQuery( document ).triggerHandler( "ready" );
|
||
jQuery( document ).off( "ready" );
|
||
}
|
||
}
|
||
});
|
||
|
||
/**
|
||
* The ready event handler and self cleanup method
|
||
*/
|
||
function completed() {
|
||
document.removeEventListener( "DOMContentLoaded", completed, false );
|
||
window.removeEventListener( "load", completed, false );
|
||
jQuery.ready();
|
||
}
|
||
|
||
jQuery.ready.promise = function( obj ) {
|
||
if ( !readyList ) {
|
||
|
||
readyList = jQuery.Deferred();
|
||
|
||
// Catch cases where $(document).ready() is called after the browser event has already occurred.
|
||
// we once tried to use readyState "interactive" here, but it caused issues like the one
|
||
// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
|
||
if ( document.readyState === "complete" ) {
|
||
// Handle it asynchronously to allow scripts the opportunity to delay ready
|
||
setTimeout( jQuery.ready );
|
||
|
||
} else {
|
||
|
||
// Use the handy event callback
|
||
document.addEventListener( "DOMContentLoaded", completed, false );
|
||
|
||
// A fallback to window.onload, that will always work
|
||
window.addEventListener( "load", completed, false );
|
||
}
|
||
}
|
||
return readyList.promise( obj );
|
||
};
|
||
|
||
// Kick off the DOM ready check even if the user does not
|
||
jQuery.ready.promise();
|
||
|
||
|
||
|
||
|
||
// Multifunctional method to get and set values of a collection
|
||
// The value/s can optionally be executed if it's a function
|
||
var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
|
||
var i = 0,
|
||
len = elems.length,
|
||
bulk = key == null;
|
||
|
||
// Sets many values
|
||
if ( jQuery.type( key ) === "object" ) {
|
||
chainable = true;
|
||
for ( i in key ) {
|
||
jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
|
||
}
|
||
|
||
// Sets one value
|
||
} else if ( value !== undefined ) {
|
||
chainable = true;
|
||
|
||
if ( !jQuery.isFunction( value ) ) {
|
||
raw = true;
|
||
}
|
||
|
||
if ( bulk ) {
|
||
// Bulk operations run against the entire set
|
||
if ( raw ) {
|
||
fn.call( elems, value );
|
||
fn = null;
|
||
|
||
// ...except when executing function values
|
||
} else {
|
||
bulk = fn;
|
||
fn = function( elem, key, value ) {
|
||
return bulk.call( jQuery( elem ), value );
|
||
};
|
||
}
|
||
}
|
||
|
||
if ( fn ) {
|
||
for ( ; i < len; i++ ) {
|
||
fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
return chainable ?
|
||
elems :
|
||
|
||
// Gets
|
||
bulk ?
|
||
fn.call( elems ) :
|
||
len ? fn( elems[0], key ) : emptyGet;
|
||
};
|
||
|
||
|
||
/**
|
||
* Determines whether an object can have data
|
||
*/
|
||
jQuery.acceptData = function( owner ) {
|
||
// Accepts only:
|
||
// - Node
|
||
// - Node.ELEMENT_NODE
|
||
// - Node.DOCUMENT_NODE
|
||
// - Object
|
||
// - Any
|
||
/* jshint -W018 */
|
||
return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
|
||
};
|
||
|
||
|
||
function Data() {
|
||
// Support: Android < 4,
|
||
// Old WebKit does not have Object.preventExtensions/freeze method,
|
||
// return new empty object instead with no [[set]] accessor
|
||
Object.defineProperty( this.cache = {}, 0, {
|
||
get: function() {
|
||
return {};
|
||
}
|
||
});
|
||
|
||
this.expando = jQuery.expando + Math.random();
|
||
}
|
||
|
||
Data.uid = 1;
|
||
Data.accepts = jQuery.acceptData;
|
||
|
||
Data.prototype = {
|
||
key: function( owner ) {
|
||
// We can accept data for non-element nodes in modern browsers,
|
||
// but we should not, see #8335.
|
||
// Always return the key for a frozen object.
|
||
if ( !Data.accepts( owner ) ) {
|
||
return 0;
|
||
}
|
||
|
||
var descriptor = {},
|
||
// Check if the owner object already has a cache key
|
||
unlock = owner[ this.expando ];
|
||
|
||
// If not, create one
|
||
if ( !unlock ) {
|
||
unlock = Data.uid++;
|
||
|
||
// Secure it in a non-enumerable, non-writable property
|
||
try {
|
||
descriptor[ this.expando ] = { value: unlock };
|
||
Object.defineProperties( owner, descriptor );
|
||
|
||
// Support: Android < 4
|
||
// Fallback to a less secure definition
|
||
} catch ( e ) {
|
||
descriptor[ this.expando ] = unlock;
|
||
jQuery.extend( owner, descriptor );
|
||
}
|
||
}
|
||
|
||
// Ensure the cache object
|
||
if ( !this.cache[ unlock ] ) {
|
||
this.cache[ unlock ] = {};
|
||
}
|
||
|
||
return unlock;
|
||
},
|
||
set: function( owner, data, value ) {
|
||
var prop,
|
||
// There may be an unlock assigned to this node,
|
||
// if there is no entry for this "owner", create one inline
|
||
// and set the unlock as though an owner entry had always existed
|
||
unlock = this.key( owner ),
|
||
cache = this.cache[ unlock ];
|
||
|
||
// Handle: [ owner, key, value ] args
|
||
if ( typeof data === "string" ) {
|
||
cache[ data ] = value;
|
||
|
||
// Handle: [ owner, { properties } ] args
|
||
} else {
|
||
// Fresh assignments by object are shallow copied
|
||
if ( jQuery.isEmptyObject( cache ) ) {
|
||
jQuery.extend( this.cache[ unlock ], data );
|
||
// Otherwise, copy the properties one-by-one to the cache object
|
||
} else {
|
||
for ( prop in data ) {
|
||
cache[ prop ] = data[ prop ];
|
||
}
|
||
}
|
||
}
|
||
return cache;
|
||
},
|
||
get: function( owner, key ) {
|
||
// Either a valid cache is found, or will be created.
|
||
// New caches will be created and the unlock returned,
|
||
// allowing direct access to the newly created
|
||
// empty data object. A valid owner object must be provided.
|
||
var cache = this.cache[ this.key( owner ) ];
|
||
|
||
return key === undefined ?
|
||
cache : cache[ key ];
|
||
},
|
||
access: function( owner, key, value ) {
|
||
var stored;
|
||
// In cases where either:
|
||
//
|
||
// 1. No key was specified
|
||
// 2. A string key was specified, but no value provided
|
||
//
|
||
// Take the "read" path and allow the get method to determine
|
||
// which value to return, respectively either:
|
||
//
|
||
// 1. The entire cache object
|
||
// 2. The data stored at the key
|
||
//
|
||
if ( key === undefined ||
|
||
((key && typeof key === "string") && value === undefined) ) {
|
||
|
||
stored = this.get( owner, key );
|
||
|
||
return stored !== undefined ?
|
||
stored : this.get( owner, jQuery.camelCase(key) );
|
||
}
|
||
|
||
// [*]When the key is not a string, or both a key and value
|
||
// are specified, set or extend (existing objects) with either:
|
||
//
|
||
// 1. An object of properties
|
||
// 2. A key and value
|
||
//
|
||
this.set( owner, key, value );
|
||
|
||
// Since the "set" path can have two possible entry points
|
||
// return the expected data based on which path was taken[*]
|
||
return value !== undefined ? value : key;
|
||
},
|
||
remove: function( owner, key ) {
|
||
var i, name, camel,
|
||
unlock = this.key( owner ),
|
||
cache = this.cache[ unlock ];
|
||
|
||
if ( key === undefined ) {
|
||
this.cache[ unlock ] = {};
|
||
|
||
} else {
|
||
// Support array or space separated string of keys
|
||
if ( jQuery.isArray( key ) ) {
|
||
// If "name" is an array of keys...
|
||
// When data is initially created, via ("key", "val") signature,
|
||
// keys will be converted to camelCase.
|
||
// Since there is no way to tell _how_ a key was added, remove
|
||
// both plain key and camelCase key. #12786
|
||
// This will only penalize the array argument path.
|
||
name = key.concat( key.map( jQuery.camelCase ) );
|
||
} else {
|
||
camel = jQuery.camelCase( key );
|
||
// Try the string as a key before any manipulation
|
||
if ( key in cache ) {
|
||
name = [ key, camel ];
|
||
} else {
|
||
// If a key with the spaces exists, use it.
|
||
// Otherwise, create an array by matching non-whitespace
|
||
name = camel;
|
||
name = name in cache ?
|
||
[ name ] : ( name.match( rnotwhite ) || [] );
|
||
}
|
||
}
|
||
|
||
i = name.length;
|
||
while ( i-- ) {
|
||
delete cache[ name[ i ] ];
|
||
}
|
||
}
|
||
},
|
||
hasData: function( owner ) {
|
||
return !jQuery.isEmptyObject(
|
||
this.cache[ owner[ this.expando ] ] || {}
|
||
);
|
||
},
|
||
discard: function( owner ) {
|
||
if ( owner[ this.expando ] ) {
|
||
delete this.cache[ owner[ this.expando ] ];
|
||
}
|
||
}
|
||
};
|
||
var data_priv = new Data();
|
||
|
||
var data_user = new Data();
|
||
|
||
|
||
|
||
/*
|
||
Implementation Summary
|
||
|
||
1. Enforce API surface and semantic compatibility with 1.9.x branch
|
||
2. Improve the module's maintainability by reducing the storage
|
||
paths to a single mechanism.
|
||
3. Use the same single mechanism to support "private" and "user" data.
|
||
4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
|
||
5. Avoid exposing implementation details on user objects (eg. expando properties)
|
||
6. Provide a clear path for implementation upgrade to WeakMap in 2014
|
||
*/
|
||
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
|
||
rmultiDash = /([A-Z])/g;
|
||
|
||
function dataAttr( elem, key, data ) {
|
||
var name;
|
||
|
||
// If nothing was found internally, try to fetch any
|
||
// data from the HTML5 data-* attribute
|
||
if ( data === undefined && elem.nodeType === 1 ) {
|
||
name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
|
||
data = elem.getAttribute( name );
|
||
|
||
if ( typeof data === "string" ) {
|
||
try {
|
||
data = data === "true" ? true :
|
||
data === "false" ? false :
|
||
data === "null" ? null :
|
||
// Only convert to a number if it doesn't change the string
|
||
+data + "" === data ? +data :
|
||
rbrace.test( data ) ? jQuery.parseJSON( data ) :
|
||
data;
|
||
} catch( e ) {}
|
||
|
||
// Make sure we set the data so it isn't changed later
|
||
data_user.set( elem, key, data );
|
||
} else {
|
||
data = undefined;
|
||
}
|
||
}
|
||
return data;
|
||
}
|
||
|
||
jQuery.extend({
|
||
hasData: function( elem ) {
|
||
return data_user.hasData( elem ) || data_priv.hasData( elem );
|
||
},
|
||
|
||
data: function( elem, name, data ) {
|
||
return data_user.access( elem, name, data );
|
||
},
|
||
|
||
removeData: function( elem, name ) {
|
||
data_user.remove( elem, name );
|
||
},
|
||
|
||
// TODO: Now that all calls to _data and _removeData have been replaced
|
||
// with direct calls to data_priv methods, these can be deprecated.
|
||
_data: function( elem, name, data ) {
|
||
return data_priv.access( elem, name, data );
|
||
},
|
||
|
||
_removeData: function( elem, name ) {
|
||
data_priv.remove( elem, name );
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
data: function( key, value ) {
|
||
var i, name, data,
|
||
elem = this[ 0 ],
|
||
attrs = elem && elem.attributes;
|
||
|
||
// Gets all values
|
||
if ( key === undefined ) {
|
||
if ( this.length ) {
|
||
data = data_user.get( elem );
|
||
|
||
if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
|
||
i = attrs.length;
|
||
while ( i-- ) {
|
||
|
||
// Support: IE11+
|
||
// The attrs elements can be null (#14894)
|
||
if ( attrs[ i ] ) {
|
||
name = attrs[ i ].name;
|
||
if ( name.indexOf( "data-" ) === 0 ) {
|
||
name = jQuery.camelCase( name.slice(5) );
|
||
dataAttr( elem, name, data[ name ] );
|
||
}
|
||
}
|
||
}
|
||
data_priv.set( elem, "hasDataAttrs", true );
|
||
}
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
// Sets multiple values
|
||
if ( typeof key === "object" ) {
|
||
return this.each(function() {
|
||
data_user.set( this, key );
|
||
});
|
||
}
|
||
|
||
return access( this, function( value ) {
|
||
var data,
|
||
camelKey = jQuery.camelCase( key );
|
||
|
||
// The calling jQuery object (element matches) is not empty
|
||
// (and therefore has an element appears at this[ 0 ]) and the
|
||
// `value` parameter was not undefined. An empty jQuery object
|
||
// will result in `undefined` for elem = this[ 0 ] which will
|
||
// throw an exception if an attempt to read a data cache is made.
|
||
if ( elem && value === undefined ) {
|
||
// Attempt to get data from the cache
|
||
// with the key as-is
|
||
data = data_user.get( elem, key );
|
||
if ( data !== undefined ) {
|
||
return data;
|
||
}
|
||
|
||
// Attempt to get data from the cache
|
||
// with the key camelized
|
||
data = data_user.get( elem, camelKey );
|
||
if ( data !== undefined ) {
|
||
return data;
|
||
}
|
||
|
||
// Attempt to "discover" the data in
|
||
// HTML5 custom data-* attrs
|
||
data = dataAttr( elem, camelKey, undefined );
|
||
if ( data !== undefined ) {
|
||
return data;
|
||
}
|
||
|
||
// We tried really hard, but the data doesn't exist.
|
||
return;
|
||
}
|
||
|
||
// Set the data...
|
||
this.each(function() {
|
||
// First, attempt to store a copy or reference of any
|
||
// data that might've been store with a camelCased key.
|
||
var data = data_user.get( this, camelKey );
|
||
|
||
// For HTML5 data-* attribute interop, we have to
|
||
// store property names with dashes in a camelCase form.
|
||
// This might not apply to all properties...*
|
||
data_user.set( this, camelKey, value );
|
||
|
||
// *... In the case of properties that might _actually_
|
||
// have dashes, we need to also store a copy of that
|
||
// unchanged property.
|
||
if ( key.indexOf("-") !== -1 && data !== undefined ) {
|
||
data_user.set( this, key, value );
|
||
}
|
||
});
|
||
}, null, value, arguments.length > 1, null, true );
|
||
},
|
||
|
||
removeData: function( key ) {
|
||
return this.each(function() {
|
||
data_user.remove( this, key );
|
||
});
|
||
}
|
||
});
|
||
|
||
|
||
jQuery.extend({
|
||
queue: function( elem, type, data ) {
|
||
var queue;
|
||
|
||
if ( elem ) {
|
||
type = ( type || "fx" ) + "queue";
|
||
queue = data_priv.get( elem, type );
|
||
|
||
// Speed up dequeue by getting out quickly if this is just a lookup
|
||
if ( data ) {
|
||
if ( !queue || jQuery.isArray( data ) ) {
|
||
queue = data_priv.access( elem, type, jQuery.makeArray(data) );
|
||
} else {
|
||
queue.push( data );
|
||
}
|
||
}
|
||
return queue || [];
|
||
}
|
||
},
|
||
|
||
dequeue: function( elem, type ) {
|
||
type = type || "fx";
|
||
|
||
var queue = jQuery.queue( elem, type ),
|
||
startLength = queue.length,
|
||
fn = queue.shift(),
|
||
hooks = jQuery._queueHooks( elem, type ),
|
||
next = function() {
|
||
jQuery.dequeue( elem, type );
|
||
};
|
||
|
||
// If the fx queue is dequeued, always remove the progress sentinel
|
||
if ( fn === "inprogress" ) {
|
||
fn = queue.shift();
|
||
startLength--;
|
||
}
|
||
|
||
if ( fn ) {
|
||
|
||
// Add a progress sentinel to prevent the fx queue from being
|
||
// automatically dequeued
|
||
if ( type === "fx" ) {
|
||
queue.unshift( "inprogress" );
|
||
}
|
||
|
||
// clear up the last queue stop function
|
||
delete hooks.stop;
|
||
fn.call( elem, next, hooks );
|
||
}
|
||
|
||
if ( !startLength && hooks ) {
|
||
hooks.empty.fire();
|
||
}
|
||
},
|
||
|
||
// not intended for public consumption - generates a queueHooks object, or returns the current one
|
||
_queueHooks: function( elem, type ) {
|
||
var key = type + "queueHooks";
|
||
return data_priv.get( elem, key ) || data_priv.access( elem, key, {
|
||
empty: jQuery.Callbacks("once memory").add(function() {
|
||
data_priv.remove( elem, [ type + "queue", key ] );
|
||
})
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
queue: function( type, data ) {
|
||
var setter = 2;
|
||
|
||
if ( typeof type !== "string" ) {
|
||
data = type;
|
||
type = "fx";
|
||
setter--;
|
||
}
|
||
|
||
if ( arguments.length < setter ) {
|
||
return jQuery.queue( this[0], type );
|
||
}
|
||
|
||
return data === undefined ?
|
||
this :
|
||
this.each(function() {
|
||
var queue = jQuery.queue( this, type, data );
|
||
|
||
// ensure a hooks for this queue
|
||
jQuery._queueHooks( this, type );
|
||
|
||
if ( type === "fx" && queue[0] !== "inprogress" ) {
|
||
jQuery.dequeue( this, type );
|
||
}
|
||
});
|
||
},
|
||
dequeue: function( type ) {
|
||
return this.each(function() {
|
||
jQuery.dequeue( this, type );
|
||
});
|
||
},
|
||
clearQueue: function( type ) {
|
||
return this.queue( type || "fx", [] );
|
||
},
|
||
// Get a promise resolved when queues of a certain type
|
||
// are emptied (fx is the type by default)
|
||
promise: function( type, obj ) {
|
||
var tmp,
|
||
count = 1,
|
||
defer = jQuery.Deferred(),
|
||
elements = this,
|
||
i = this.length,
|
||
resolve = function() {
|
||
if ( !( --count ) ) {
|
||
defer.resolveWith( elements, [ elements ] );
|
||
}
|
||
};
|
||
|
||
if ( typeof type !== "string" ) {
|
||
obj = type;
|
||
type = undefined;
|
||
}
|
||
type = type || "fx";
|
||
|
||
while ( i-- ) {
|
||
tmp = data_priv.get( elements[ i ], type + "queueHooks" );
|
||
if ( tmp && tmp.empty ) {
|
||
count++;
|
||
tmp.empty.add( resolve );
|
||
}
|
||
}
|
||
resolve();
|
||
return defer.promise( obj );
|
||
}
|
||
});
|
||
var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
|
||
|
||
var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
|
||
|
||
var isHidden = function( elem, el ) {
|
||
// isHidden might be called from jQuery#filter function;
|
||
// in that case, element will be second argument
|
||
elem = el || elem;
|
||
return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
|
||
};
|
||
|
||
var rcheckableType = (/^(?:checkbox|radio)$/i);
|
||
|
||
|
||
|
||
(function() {
|
||
var fragment = document.createDocumentFragment(),
|
||
div = fragment.appendChild( document.createElement( "div" ) ),
|
||
input = document.createElement( "input" );
|
||
|
||
// #11217 - WebKit loses check when the name is after the checked attribute
|
||
// Support: Windows Web Apps (WWA)
|
||
// `name` and `type` need .setAttribute for WWA
|
||
input.setAttribute( "type", "radio" );
|
||
input.setAttribute( "checked", "checked" );
|
||
input.setAttribute( "name", "t" );
|
||
|
||
div.appendChild( input );
|
||
|
||
// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
|
||
// old WebKit doesn't clone checked state correctly in fragments
|
||
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
|
||
|
||
// Make sure textarea (and checkbox) defaultValue is properly cloned
|
||
// Support: IE9-IE11+
|
||
div.innerHTML = "<textarea>x</textarea>";
|
||
support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
|
||
})();
|
||
var strundefined = typeof undefined;
|
||
|
||
|
||
|
||
support.focusinBubbles = "onfocusin" in window;
|
||
|
||
|
||
var
|
||
rkeyEvent = /^key/,
|
||
rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
|
||
rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
|
||
rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
|
||
|
||
function returnTrue() {
|
||
return true;
|
||
}
|
||
|
||
function returnFalse() {
|
||
return false;
|
||
}
|
||
|
||
function safeActiveElement() {
|
||
try {
|
||
return document.activeElement;
|
||
} catch ( err ) { }
|
||
}
|
||
|
||
/*
|
||
* Helper functions for managing events -- not part of the public interface.
|
||
* Props to Dean Edwards' addEvent library for many of the ideas.
|
||
*/
|
||
jQuery.event = {
|
||
|
||
global: {},
|
||
|
||
add: function( elem, types, handler, data, selector ) {
|
||
|
||
var handleObjIn, eventHandle, tmp,
|
||
events, t, handleObj,
|
||
special, handlers, type, namespaces, origType,
|
||
elemData = data_priv.get( elem );
|
||
|
||
// Don't attach events to noData or text/comment nodes (but allow plain objects)
|
||
if ( !elemData ) {
|
||
return;
|
||
}
|
||
|
||
// Caller can pass in an object of custom data in lieu of the handler
|
||
if ( handler.handler ) {
|
||
handleObjIn = handler;
|
||
handler = handleObjIn.handler;
|
||
selector = handleObjIn.selector;
|
||
}
|
||
|
||
// Make sure that the handler has a unique ID, used to find/remove it later
|
||
if ( !handler.guid ) {
|
||
handler.guid = jQuery.guid++;
|
||
}
|
||
|
||
// Init the element's event structure and main handler, if this is the first
|
||
if ( !(events = elemData.events) ) {
|
||
events = elemData.events = {};
|
||
}
|
||
if ( !(eventHandle = elemData.handle) ) {
|
||
eventHandle = elemData.handle = function( e ) {
|
||
// Discard the second event of a jQuery.event.trigger() and
|
||
// when an event is called after a page has unloaded
|
||
return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
|
||
jQuery.event.dispatch.apply( elem, arguments ) : undefined;
|
||
};
|
||
}
|
||
|
||
// Handle multiple events separated by a space
|
||
types = ( types || "" ).match( rnotwhite ) || [ "" ];
|
||
t = types.length;
|
||
while ( t-- ) {
|
||
tmp = rtypenamespace.exec( types[t] ) || [];
|
||
type = origType = tmp[1];
|
||
namespaces = ( tmp[2] || "" ).split( "." ).sort();
|
||
|
||
// There *must* be a type, no attaching namespace-only handlers
|
||
if ( !type ) {
|
||
continue;
|
||
}
|
||
|
||
// If event changes its type, use the special event handlers for the changed type
|
||
special = jQuery.event.special[ type ] || {};
|
||
|
||
// If selector defined, determine special event api type, otherwise given type
|
||
type = ( selector ? special.delegateType : special.bindType ) || type;
|
||
|
||
// Update special based on newly reset type
|
||
special = jQuery.event.special[ type ] || {};
|
||
|
||
// handleObj is passed to all event handlers
|
||
handleObj = jQuery.extend({
|
||
type: type,
|
||
origType: origType,
|
||
data: data,
|
||
handler: handler,
|
||
guid: handler.guid,
|
||
selector: selector,
|
||
needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
|
||
namespace: namespaces.join(".")
|
||
}, handleObjIn );
|
||
|
||
// Init the event handler queue if we're the first
|
||
if ( !(handlers = events[ type ]) ) {
|
||
handlers = events[ type ] = [];
|
||
handlers.delegateCount = 0;
|
||
|
||
// Only use addEventListener if the special events handler returns false
|
||
if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
|
||
if ( elem.addEventListener ) {
|
||
elem.addEventListener( type, eventHandle, false );
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( special.add ) {
|
||
special.add.call( elem, handleObj );
|
||
|
||
if ( !handleObj.handler.guid ) {
|
||
handleObj.handler.guid = handler.guid;
|
||
}
|
||
}
|
||
|
||
// Add to the element's handler list, delegates in front
|
||
if ( selector ) {
|
||
handlers.splice( handlers.delegateCount++, 0, handleObj );
|
||
} else {
|
||
handlers.push( handleObj );
|
||
}
|
||
|
||
// Keep track of which events have ever been used, for event optimization
|
||
jQuery.event.global[ type ] = true;
|
||
}
|
||
|
||
},
|
||
|
||
// Detach an event or set of events from an element
|
||
remove: function( elem, types, handler, selector, mappedTypes ) {
|
||
|
||
var j, origCount, tmp,
|
||
events, t, handleObj,
|
||
special, handlers, type, namespaces, origType,
|
||
elemData = data_priv.hasData( elem ) && data_priv.get( elem );
|
||
|
||
if ( !elemData || !(events = elemData.events) ) {
|
||
return;
|
||
}
|
||
|
||
// Once for each type.namespace in types; type may be omitted
|
||
types = ( types || "" ).match( rnotwhite ) || [ "" ];
|
||
t = types.length;
|
||
while ( t-- ) {
|
||
tmp = rtypenamespace.exec( types[t] ) || [];
|
||
type = origType = tmp[1];
|
||
namespaces = ( tmp[2] || "" ).split( "." ).sort();
|
||
|
||
// Unbind all events (on this namespace, if provided) for the element
|
||
if ( !type ) {
|
||
for ( type in events ) {
|
||
jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
|
||
}
|
||
continue;
|
||
}
|
||
|
||
special = jQuery.event.special[ type ] || {};
|
||
type = ( selector ? special.delegateType : special.bindType ) || type;
|
||
handlers = events[ type ] || [];
|
||
tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
|
||
|
||
// Remove matching events
|
||
origCount = j = handlers.length;
|
||
while ( j-- ) {
|
||
handleObj = handlers[ j ];
|
||
|
||
if ( ( mappedTypes || origType === handleObj.origType ) &&
|
||
( !handler || handler.guid === handleObj.guid ) &&
|
||
( !tmp || tmp.test( handleObj.namespace ) ) &&
|
||
( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
|
||
handlers.splice( j, 1 );
|
||
|
||
if ( handleObj.selector ) {
|
||
handlers.delegateCount--;
|
||
}
|
||
if ( special.remove ) {
|
||
special.remove.call( elem, handleObj );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Remove generic event handler if we removed something and no more handlers exist
|
||
// (avoids potential for endless recursion during removal of special event handlers)
|
||
if ( origCount && !handlers.length ) {
|
||
if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
|
||
jQuery.removeEvent( elem, type, elemData.handle );
|
||
}
|
||
|
||
delete events[ type ];
|
||
}
|
||
}
|
||
|
||
// Remove the expando if it's no longer used
|
||
if ( jQuery.isEmptyObject( events ) ) {
|
||
delete elemData.handle;
|
||
data_priv.remove( elem, "events" );
|
||
}
|
||
},
|
||
|
||
trigger: function( event, data, elem, onlyHandlers ) {
|
||
|
||
var i, cur, tmp, bubbleType, ontype, handle, special,
|
||
eventPath = [ elem || document ],
|
||
type = hasOwn.call( event, "type" ) ? event.type : event,
|
||
namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
|
||
|
||
cur = tmp = elem = elem || document;
|
||
|
||
// Don't do events on text and comment nodes
|
||
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
|
||
return;
|
||
}
|
||
|
||
// focus/blur morphs to focusin/out; ensure we're not firing them right now
|
||
if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
|
||
return;
|
||
}
|
||
|
||
if ( type.indexOf(".") >= 0 ) {
|
||
// Namespaced trigger; create a regexp to match event type in handle()
|
||
namespaces = type.split(".");
|
||
type = namespaces.shift();
|
||
namespaces.sort();
|
||
}
|
||
ontype = type.indexOf(":") < 0 && "on" + type;
|
||
|
||
// Caller can pass in a jQuery.Event object, Object, or just an event type string
|
||
event = event[ jQuery.expando ] ?
|
||
event :
|
||
new jQuery.Event( type, typeof event === "object" && event );
|
||
|
||
// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
|
||
event.isTrigger = onlyHandlers ? 2 : 3;
|
||
event.namespace = namespaces.join(".");
|
||
event.namespace_re = event.namespace ?
|
||
new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
|
||
null;
|
||
|
||
// Clean up the event in case it is being reused
|
||
event.result = undefined;
|
||
if ( !event.target ) {
|
||
event.target = elem;
|
||
}
|
||
|
||
// Clone any incoming data and prepend the event, creating the handler arg list
|
||
data = data == null ?
|
||
[ event ] :
|
||
jQuery.makeArray( data, [ event ] );
|
||
|
||
// Allow special events to draw outside the lines
|
||
special = jQuery.event.special[ type ] || {};
|
||
if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
|
||
return;
|
||
}
|
||
|
||
// Determine event propagation path in advance, per W3C events spec (#9951)
|
||
// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
|
||
if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
|
||
|
||
bubbleType = special.delegateType || type;
|
||
if ( !rfocusMorph.test( bubbleType + type ) ) {
|
||
cur = cur.parentNode;
|
||
}
|
||
for ( ; cur; cur = cur.parentNode ) {
|
||
eventPath.push( cur );
|
||
tmp = cur;
|
||
}
|
||
|
||
// Only add window if we got to document (e.g., not plain obj or detached DOM)
|
||
if ( tmp === (elem.ownerDocument || document) ) {
|
||
eventPath.push( tmp.defaultView || tmp.parentWindow || window );
|
||
}
|
||
}
|
||
|
||
// Fire handlers on the event path
|
||
i = 0;
|
||
while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
|
||
|
||
event.type = i > 1 ?
|
||
bubbleType :
|
||
special.bindType || type;
|
||
|
||
// jQuery handler
|
||
handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
|
||
if ( handle ) {
|
||
handle.apply( cur, data );
|
||
}
|
||
|
||
// Native handler
|
||
handle = ontype && cur[ ontype ];
|
||
if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
|
||
event.result = handle.apply( cur, data );
|
||
if ( event.result === false ) {
|
||
event.preventDefault();
|
||
}
|
||
}
|
||
}
|
||
event.type = type;
|
||
|
||
// If nobody prevented the default action, do it now
|
||
if ( !onlyHandlers && !event.isDefaultPrevented() ) {
|
||
|
||
if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
|
||
jQuery.acceptData( elem ) ) {
|
||
|
||
// Call a native DOM method on the target with the same name name as the event.
|
||
// Don't do default actions on window, that's where global variables be (#6170)
|
||
if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
|
||
|
||
// Don't re-trigger an onFOO event when we call its FOO() method
|
||
tmp = elem[ ontype ];
|
||
|
||
if ( tmp ) {
|
||
elem[ ontype ] = null;
|
||
}
|
||
|
||
// Prevent re-triggering of the same event, since we already bubbled it above
|
||
jQuery.event.triggered = type;
|
||
elem[ type ]();
|
||
jQuery.event.triggered = undefined;
|
||
|
||
if ( tmp ) {
|
||
elem[ ontype ] = tmp;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return event.result;
|
||
},
|
||
|
||
dispatch: function( event ) {
|
||
|
||
// Make a writable jQuery.Event from the native event object
|
||
event = jQuery.event.fix( event );
|
||
|
||
var i, j, ret, matched, handleObj,
|
||
handlerQueue = [],
|
||
args = slice.call( arguments ),
|
||
handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
|
||
special = jQuery.event.special[ event.type ] || {};
|
||
|
||
// Use the fix-ed jQuery.Event rather than the (read-only) native event
|
||
args[0] = event;
|
||
event.delegateTarget = this;
|
||
|
||
// Call the preDispatch hook for the mapped type, and let it bail if desired
|
||
if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
|
||
return;
|
||
}
|
||
|
||
// Determine handlers
|
||
handlerQueue = jQuery.event.handlers.call( this, event, handlers );
|
||
|
||
// Run delegates first; they may want to stop propagation beneath us
|
||
i = 0;
|
||
while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
|
||
event.currentTarget = matched.elem;
|
||
|
||
j = 0;
|
||
while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
|
||
|
||
// Triggered event must either 1) have no namespace, or
|
||
// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
|
||
if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
|
||
|
||
event.handleObj = handleObj;
|
||
event.data = handleObj.data;
|
||
|
||
ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
|
||
.apply( matched.elem, args );
|
||
|
||
if ( ret !== undefined ) {
|
||
if ( (event.result = ret) === false ) {
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Call the postDispatch hook for the mapped type
|
||
if ( special.postDispatch ) {
|
||
special.postDispatch.call( this, event );
|
||
}
|
||
|
||
return event.result;
|
||
},
|
||
|
||
handlers: function( event, handlers ) {
|
||
var i, matches, sel, handleObj,
|
||
handlerQueue = [],
|
||
delegateCount = handlers.delegateCount,
|
||
cur = event.target;
|
||
|
||
// Find delegate handlers
|
||
// Black-hole SVG <use> instance trees (#13180)
|
||
// Avoid non-left-click bubbling in Firefox (#3861)
|
||
if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
|
||
|
||
for ( ; cur !== this; cur = cur.parentNode || this ) {
|
||
|
||
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
|
||
if ( cur.disabled !== true || event.type !== "click" ) {
|
||
matches = [];
|
||
for ( i = 0; i < delegateCount; i++ ) {
|
||
handleObj = handlers[ i ];
|
||
|
||
// Don't conflict with Object.prototype properties (#13203)
|
||
sel = handleObj.selector + " ";
|
||
|
||
if ( matches[ sel ] === undefined ) {
|
||
matches[ sel ] = handleObj.needsContext ?
|
||
jQuery( sel, this ).index( cur ) >= 0 :
|
||
jQuery.find( sel, this, null, [ cur ] ).length;
|
||
}
|
||
if ( matches[ sel ] ) {
|
||
matches.push( handleObj );
|
||
}
|
||
}
|
||
if ( matches.length ) {
|
||
handlerQueue.push({ elem: cur, handlers: matches });
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Add the remaining (directly-bound) handlers
|
||
if ( delegateCount < handlers.length ) {
|
||
handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
|
||
}
|
||
|
||
return handlerQueue;
|
||
},
|
||
|
||
// Includes some event props shared by KeyEvent and MouseEvent
|
||
props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
|
||
|
||
fixHooks: {},
|
||
|
||
keyHooks: {
|
||
props: "char charCode key keyCode".split(" "),
|
||
filter: function( event, original ) {
|
||
|
||
// Add which for key events
|
||
if ( event.which == null ) {
|
||
event.which = original.charCode != null ? original.charCode : original.keyCode;
|
||
}
|
||
|
||
return event;
|
||
}
|
||
},
|
||
|
||
mouseHooks: {
|
||
props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
|
||
filter: function( event, original ) {
|
||
var eventDoc, doc, body,
|
||
button = original.button;
|
||
|
||
// Calculate pageX/Y if missing and clientX/Y available
|
||
if ( event.pageX == null && original.clientX != null ) {
|
||
eventDoc = event.target.ownerDocument || document;
|
||
doc = eventDoc.documentElement;
|
||
body = eventDoc.body;
|
||
|
||
event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
|
||
event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
|
||
}
|
||
|
||
// Add which for click: 1 === left; 2 === middle; 3 === right
|
||
// Note: button is not normalized, so don't use it
|
||
if ( !event.which && button !== undefined ) {
|
||
event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
|
||
}
|
||
|
||
return event;
|
||
}
|
||
},
|
||
|
||
fix: function( event ) {
|
||
if ( event[ jQuery.expando ] ) {
|
||
return event;
|
||
}
|
||
|
||
// Create a writable copy of the event object and normalize some properties
|
||
var i, prop, copy,
|
||
type = event.type,
|
||
originalEvent = event,
|
||
fixHook = this.fixHooks[ type ];
|
||
|
||
if ( !fixHook ) {
|
||
this.fixHooks[ type ] = fixHook =
|
||
rmouseEvent.test( type ) ? this.mouseHooks :
|
||
rkeyEvent.test( type ) ? this.keyHooks :
|
||
{};
|
||
}
|
||
copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
|
||
|
||
event = new jQuery.Event( originalEvent );
|
||
|
||
i = copy.length;
|
||
while ( i-- ) {
|
||
prop = copy[ i ];
|
||
event[ prop ] = originalEvent[ prop ];
|
||
}
|
||
|
||
// Support: Cordova 2.5 (WebKit) (#13255)
|
||
// All events should have a target; Cordova deviceready doesn't
|
||
if ( !event.target ) {
|
||
event.target = document;
|
||
}
|
||
|
||
// Support: Safari 6.0+, Chrome < 28
|
||
// Target should not be a text node (#504, #13143)
|
||
if ( event.target.nodeType === 3 ) {
|
||
event.target = event.target.parentNode;
|
||
}
|
||
|
||
return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
|
||
},
|
||
|
||
special: {
|
||
load: {
|
||
// Prevent triggered image.load events from bubbling to window.load
|
||
noBubble: true
|
||
},
|
||
focus: {
|
||
// Fire native event if possible so blur/focus sequence is correct
|
||
trigger: function() {
|
||
if ( this !== safeActiveElement() && this.focus ) {
|
||
this.focus();
|
||
return false;
|
||
}
|
||
},
|
||
delegateType: "focusin"
|
||
},
|
||
blur: {
|
||
trigger: function() {
|
||
if ( this === safeActiveElement() && this.blur ) {
|
||
this.blur();
|
||
return false;
|
||
}
|
||
},
|
||
delegateType: "focusout"
|
||
},
|
||
click: {
|
||
// For checkbox, fire native event so checked state will be right
|
||
trigger: function() {
|
||
if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
|
||
this.click();
|
||
return false;
|
||
}
|
||
},
|
||
|
||
// For cross-browser consistency, don't fire native .click() on links
|
||
_default: function( event ) {
|
||
return jQuery.nodeName( event.target, "a" );
|
||
}
|
||
},
|
||
|
||
beforeunload: {
|
||
postDispatch: function( event ) {
|
||
|
||
// Support: Firefox 20+
|
||
// Firefox doesn't alert if the returnValue field is not set.
|
||
if ( event.result !== undefined && event.originalEvent ) {
|
||
event.originalEvent.returnValue = event.result;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
simulate: function( type, elem, event, bubble ) {
|
||
// Piggyback on a donor event to simulate a different one.
|
||
// Fake originalEvent to avoid donor's stopPropagation, but if the
|
||
// simulated event prevents default then we do the same on the donor.
|
||
var e = jQuery.extend(
|
||
new jQuery.Event(),
|
||
event,
|
||
{
|
||
type: type,
|
||
isSimulated: true,
|
||
originalEvent: {}
|
||
}
|
||
);
|
||
if ( bubble ) {
|
||
jQuery.event.trigger( e, null, elem );
|
||
} else {
|
||
jQuery.event.dispatch.call( elem, e );
|
||
}
|
||
if ( e.isDefaultPrevented() ) {
|
||
event.preventDefault();
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.removeEvent = function( elem, type, handle ) {
|
||
if ( elem.removeEventListener ) {
|
||
elem.removeEventListener( type, handle, false );
|
||
}
|
||
};
|
||
|
||
jQuery.Event = function( src, props ) {
|
||
// Allow instantiation without the 'new' keyword
|
||
if ( !(this instanceof jQuery.Event) ) {
|
||
return new jQuery.Event( src, props );
|
||
}
|
||
|
||
// Event object
|
||
if ( src && src.type ) {
|
||
this.originalEvent = src;
|
||
this.type = src.type;
|
||
|
||
// Events bubbling up the document may have been marked as prevented
|
||
// by a handler lower down the tree; reflect the correct value.
|
||
this.isDefaultPrevented = src.defaultPrevented ||
|
||
src.defaultPrevented === undefined &&
|
||
// Support: Android < 4.0
|
||
src.returnValue === false ?
|
||
returnTrue :
|
||
returnFalse;
|
||
|
||
// Event type
|
||
} else {
|
||
this.type = src;
|
||
}
|
||
|
||
// Put explicitly provided properties onto the event object
|
||
if ( props ) {
|
||
jQuery.extend( this, props );
|
||
}
|
||
|
||
// Create a timestamp if incoming event doesn't have one
|
||
this.timeStamp = src && src.timeStamp || jQuery.now();
|
||
|
||
// Mark it as fixed
|
||
this[ jQuery.expando ] = true;
|
||
};
|
||
|
||
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
|
||
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
|
||
jQuery.Event.prototype = {
|
||
isDefaultPrevented: returnFalse,
|
||
isPropagationStopped: returnFalse,
|
||
isImmediatePropagationStopped: returnFalse,
|
||
|
||
preventDefault: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isDefaultPrevented = returnTrue;
|
||
|
||
if ( e && e.preventDefault ) {
|
||
e.preventDefault();
|
||
}
|
||
},
|
||
stopPropagation: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isPropagationStopped = returnTrue;
|
||
|
||
if ( e && e.stopPropagation ) {
|
||
e.stopPropagation();
|
||
}
|
||
},
|
||
stopImmediatePropagation: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isImmediatePropagationStopped = returnTrue;
|
||
|
||
if ( e && e.stopImmediatePropagation ) {
|
||
e.stopImmediatePropagation();
|
||
}
|
||
|
||
this.stopPropagation();
|
||
}
|
||
};
|
||
|
||
// Create mouseenter/leave events using mouseover/out and event-time checks
|
||
// Support: Chrome 15+
|
||
jQuery.each({
|
||
mouseenter: "mouseover",
|
||
mouseleave: "mouseout",
|
||
pointerenter: "pointerover",
|
||
pointerleave: "pointerout"
|
||
}, function( orig, fix ) {
|
||
jQuery.event.special[ orig ] = {
|
||
delegateType: fix,
|
||
bindType: fix,
|
||
|
||
handle: function( event ) {
|
||
var ret,
|
||
target = this,
|
||
related = event.relatedTarget,
|
||
handleObj = event.handleObj;
|
||
|
||
// For mousenter/leave call the handler if related is outside the target.
|
||
// NB: No relatedTarget if the mouse left/entered the browser window
|
||
if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
|
||
event.type = handleObj.origType;
|
||
ret = handleObj.handler.apply( this, arguments );
|
||
event.type = fix;
|
||
}
|
||
return ret;
|
||
}
|
||
};
|
||
});
|
||
|
||
// Create "bubbling" focus and blur events
|
||
// Support: Firefox, Chrome, Safari
|
||
if ( !support.focusinBubbles ) {
|
||
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
|
||
|
||
// Attach a single capturing handler on the document while someone wants focusin/focusout
|
||
var handler = function( event ) {
|
||
jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
|
||
};
|
||
|
||
jQuery.event.special[ fix ] = {
|
||
setup: function() {
|
||
var doc = this.ownerDocument || this,
|
||
attaches = data_priv.access( doc, fix );
|
||
|
||
if ( !attaches ) {
|
||
doc.addEventListener( orig, handler, true );
|
||
}
|
||
data_priv.access( doc, fix, ( attaches || 0 ) + 1 );
|
||
},
|
||
teardown: function() {
|
||
var doc = this.ownerDocument || this,
|
||
attaches = data_priv.access( doc, fix ) - 1;
|
||
|
||
if ( !attaches ) {
|
||
doc.removeEventListener( orig, handler, true );
|
||
data_priv.remove( doc, fix );
|
||
|
||
} else {
|
||
data_priv.access( doc, fix, attaches );
|
||
}
|
||
}
|
||
};
|
||
});
|
||
}
|
||
|
||
jQuery.fn.extend({
|
||
|
||
on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
|
||
var origFn, type;
|
||
|
||
// Types can be a map of types/handlers
|
||
if ( typeof types === "object" ) {
|
||
// ( types-Object, selector, data )
|
||
if ( typeof selector !== "string" ) {
|
||
// ( types-Object, data )
|
||
data = data || selector;
|
||
selector = undefined;
|
||
}
|
||
for ( type in types ) {
|
||
this.on( type, selector, data, types[ type ], one );
|
||
}
|
||
return this;
|
||
}
|
||
|
||
if ( data == null && fn == null ) {
|
||
// ( types, fn )
|
||
fn = selector;
|
||
data = selector = undefined;
|
||
} else if ( fn == null ) {
|
||
if ( typeof selector === "string" ) {
|
||
// ( types, selector, fn )
|
||
fn = data;
|
||
data = undefined;
|
||
} else {
|
||
// ( types, data, fn )
|
||
fn = data;
|
||
data = selector;
|
||
selector = undefined;
|
||
}
|
||
}
|
||
if ( fn === false ) {
|
||
fn = returnFalse;
|
||
} else if ( !fn ) {
|
||
return this;
|
||
}
|
||
|
||
if ( one === 1 ) {
|
||
origFn = fn;
|
||
fn = function( event ) {
|
||
// Can use an empty set, since event contains the info
|
||
jQuery().off( event );
|
||
return origFn.apply( this, arguments );
|
||
};
|
||
// Use same guid so caller can remove using origFn
|
||
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
|
||
}
|
||
return this.each( function() {
|
||
jQuery.event.add( this, types, fn, data, selector );
|
||
});
|
||
},
|
||
one: function( types, selector, data, fn ) {
|
||
return this.on( types, selector, data, fn, 1 );
|
||
},
|
||
off: function( types, selector, fn ) {
|
||
var handleObj, type;
|
||
if ( types && types.preventDefault && types.handleObj ) {
|
||
// ( event ) dispatched jQuery.Event
|
||
handleObj = types.handleObj;
|
||
jQuery( types.delegateTarget ).off(
|
||
handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
|
||
handleObj.selector,
|
||
handleObj.handler
|
||
);
|
||
return this;
|
||
}
|
||
if ( typeof types === "object" ) {
|
||
// ( types-object [, selector] )
|
||
for ( type in types ) {
|
||
this.off( type, selector, types[ type ] );
|
||
}
|
||
return this;
|
||
}
|
||
if ( selector === false || typeof selector === "function" ) {
|
||
// ( types [, fn] )
|
||
fn = selector;
|
||
selector = undefined;
|
||
}
|
||
if ( fn === false ) {
|
||
fn = returnFalse;
|
||
}
|
||
return this.each(function() {
|
||
jQuery.event.remove( this, types, fn, selector );
|
||
});
|
||
},
|
||
|
||
trigger: function( type, data ) {
|
||
return this.each(function() {
|
||
jQuery.event.trigger( type, data, this );
|
||
});
|
||
},
|
||
triggerHandler: function( type, data ) {
|
||
var elem = this[0];
|
||
if ( elem ) {
|
||
return jQuery.event.trigger( type, data, elem, true );
|
||
}
|
||
}
|
||
});
|
||
|
||
|
||
var
|
||
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
|
||
rtagName = /<([\w:]+)/,
|
||
rhtml = /<|&#?\w+;/,
|
||
rnoInnerhtml = /<(?:script|style|link)/i,
|
||
// checked="checked" or checked
|
||
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
|
||
rscriptType = /^$|\/(?:java|ecma)script/i,
|
||
rscriptTypeMasked = /^true\/(.*)/,
|
||
rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
|
||
|
||
// We have to close these tags to support XHTML (#13200)
|
||
wrapMap = {
|
||
|
||
// Support: IE 9
|
||
option: [ 1, "<select multiple='multiple'>", "</select>" ],
|
||
|
||
thead: [ 1, "<table>", "</table>" ],
|
||
col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
|
||
tr: [ 2, "<table><tbody>", "</tbody></table>" ],
|
||
td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
|
||
|
||
_default: [ 0, "", "" ]
|
||
};
|
||
|
||
// Support: IE 9
|
||
wrapMap.optgroup = wrapMap.option;
|
||
|
||
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
|
||
wrapMap.th = wrapMap.td;
|
||
|
||
// Support: 1.x compatibility
|
||
// Manipulating tables requires a tbody
|
||
function manipulationTarget( elem, content ) {
|
||
return jQuery.nodeName( elem, "table" ) &&
|
||
jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
|
||
|
||
elem.getElementsByTagName("tbody")[0] ||
|
||
elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
|
||
elem;
|
||
}
|
||
|
||
// Replace/restore the type attribute of script elements for safe DOM manipulation
|
||
function disableScript( elem ) {
|
||
elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
|
||
return elem;
|
||
}
|
||
function restoreScript( elem ) {
|
||
var match = rscriptTypeMasked.exec( elem.type );
|
||
|
||
if ( match ) {
|
||
elem.type = match[ 1 ];
|
||
} else {
|
||
elem.removeAttribute("type");
|
||
}
|
||
|
||
return elem;
|
||
}
|
||
|
||
// Mark scripts as having already been evaluated
|
||
function setGlobalEval( elems, refElements ) {
|
||
var i = 0,
|
||
l = elems.length;
|
||
|
||
for ( ; i < l; i++ ) {
|
||
data_priv.set(
|
||
elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
|
||
);
|
||
}
|
||
}
|
||
|
||
function cloneCopyEvent( src, dest ) {
|
||
var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
|
||
|
||
if ( dest.nodeType !== 1 ) {
|
||
return;
|
||
}
|
||
|
||
// 1. Copy private data: events, handlers, etc.
|
||
if ( data_priv.hasData( src ) ) {
|
||
pdataOld = data_priv.access( src );
|
||
pdataCur = data_priv.set( dest, pdataOld );
|
||
events = pdataOld.events;
|
||
|
||
if ( events ) {
|
||
delete pdataCur.handle;
|
||
pdataCur.events = {};
|
||
|
||
for ( type in events ) {
|
||
for ( i = 0, l = events[ type ].length; i < l; i++ ) {
|
||
jQuery.event.add( dest, type, events[ type ][ i ] );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 2. Copy user data
|
||
if ( data_user.hasData( src ) ) {
|
||
udataOld = data_user.access( src );
|
||
udataCur = jQuery.extend( {}, udataOld );
|
||
|
||
data_user.set( dest, udataCur );
|
||
}
|
||
}
|
||
|
||
function getAll( context, tag ) {
|
||
var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
|
||
context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
|
||
[];
|
||
|
||
return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
|
||
jQuery.merge( [ context ], ret ) :
|
||
ret;
|
||
}
|
||
|
||
// Support: IE >= 9
|
||
function fixInput( src, dest ) {
|
||
var nodeName = dest.nodeName.toLowerCase();
|
||
|
||
// Fails to persist the checked state of a cloned checkbox or radio button.
|
||
if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
|
||
dest.checked = src.checked;
|
||
|
||
// Fails to return the selected option to the default selected state when cloning options
|
||
} else if ( nodeName === "input" || nodeName === "textarea" ) {
|
||
dest.defaultValue = src.defaultValue;
|
||
}
|
||
}
|
||
|
||
jQuery.extend({
|
||
clone: function( elem, dataAndEvents, deepDataAndEvents ) {
|
||
var i, l, srcElements, destElements,
|
||
clone = elem.cloneNode( true ),
|
||
inPage = jQuery.contains( elem.ownerDocument, elem );
|
||
|
||
// Support: IE >= 9
|
||
// Fix Cloning issues
|
||
if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
|
||
!jQuery.isXMLDoc( elem ) ) {
|
||
|
||
// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
|
||
destElements = getAll( clone );
|
||
srcElements = getAll( elem );
|
||
|
||
for ( i = 0, l = srcElements.length; i < l; i++ ) {
|
||
fixInput( srcElements[ i ], destElements[ i ] );
|
||
}
|
||
}
|
||
|
||
// Copy the events from the original to the clone
|
||
if ( dataAndEvents ) {
|
||
if ( deepDataAndEvents ) {
|
||
srcElements = srcElements || getAll( elem );
|
||
destElements = destElements || getAll( clone );
|
||
|
||
for ( i = 0, l = srcElements.length; i < l; i++ ) {
|
||
cloneCopyEvent( srcElements[ i ], destElements[ i ] );
|
||
}
|
||
} else {
|
||
cloneCopyEvent( elem, clone );
|
||
}
|
||
}
|
||
|
||
// Preserve script evaluation history
|
||
destElements = getAll( clone, "script" );
|
||
if ( destElements.length > 0 ) {
|
||
setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
|
||
}
|
||
|
||
// Return the cloned set
|
||
return clone;
|
||
},
|
||
|
||
buildFragment: function( elems, context, scripts, selection ) {
|
||
var elem, tmp, tag, wrap, contains, j,
|
||
fragment = context.createDocumentFragment(),
|
||
nodes = [],
|
||
i = 0,
|
||
l = elems.length;
|
||
|
||
for ( ; i < l; i++ ) {
|
||
elem = elems[ i ];
|
||
|
||
if ( elem || elem === 0 ) {
|
||
|
||
// Add nodes directly
|
||
if ( jQuery.type( elem ) === "object" ) {
|
||
// Support: QtWebKit
|
||
// jQuery.merge because push.apply(_, arraylike) throws
|
||
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
|
||
|
||
// Convert non-html into a text node
|
||
} else if ( !rhtml.test( elem ) ) {
|
||
nodes.push( context.createTextNode( elem ) );
|
||
|
||
// Convert html into DOM nodes
|
||
} else {
|
||
tmp = tmp || fragment.appendChild( context.createElement("div") );
|
||
|
||
// Deserialize a standard representation
|
||
tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
|
||
wrap = wrapMap[ tag ] || wrapMap._default;
|
||
tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
|
||
|
||
// Descend through wrappers to the right content
|
||
j = wrap[ 0 ];
|
||
while ( j-- ) {
|
||
tmp = tmp.lastChild;
|
||
}
|
||
|
||
// Support: QtWebKit
|
||
// jQuery.merge because push.apply(_, arraylike) throws
|
||
jQuery.merge( nodes, tmp.childNodes );
|
||
|
||
// Remember the top-level container
|
||
tmp = fragment.firstChild;
|
||
|
||
// Fixes #12346
|
||
// Support: Webkit, IE
|
||
tmp.textContent = "";
|
||
}
|
||
}
|
||
}
|
||
|
||
// Remove wrapper from fragment
|
||
fragment.textContent = "";
|
||
|
||
i = 0;
|
||
while ( (elem = nodes[ i++ ]) ) {
|
||
|
||
// #4087 - If origin and destination elements are the same, and this is
|
||
// that element, do not do anything
|
||
if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
|
||
continue;
|
||
}
|
||
|
||
contains = jQuery.contains( elem.ownerDocument, elem );
|
||
|
||
// Append to fragment
|
||
tmp = getAll( fragment.appendChild( elem ), "script" );
|
||
|
||
// Preserve script evaluation history
|
||
if ( contains ) {
|
||
setGlobalEval( tmp );
|
||
}
|
||
|
||
// Capture executables
|
||
if ( scripts ) {
|
||
j = 0;
|
||
while ( (elem = tmp[ j++ ]) ) {
|
||
if ( rscriptType.test( elem.type || "" ) ) {
|
||
scripts.push( elem );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return fragment;
|
||
},
|
||
|
||
cleanData: function( elems ) {
|
||
var data, elem, type, key,
|
||
special = jQuery.event.special,
|
||
i = 0;
|
||
|
||
for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
|
||
if ( jQuery.acceptData( elem ) ) {
|
||
key = elem[ data_priv.expando ];
|
||
|
||
if ( key && (data = data_priv.cache[ key ]) ) {
|
||
if ( data.events ) {
|
||
for ( type in data.events ) {
|
||
if ( special[ type ] ) {
|
||
jQuery.event.remove( elem, type );
|
||
|
||
// This is a shortcut to avoid jQuery.event.remove's overhead
|
||
} else {
|
||
jQuery.removeEvent( elem, type, data.handle );
|
||
}
|
||
}
|
||
}
|
||
if ( data_priv.cache[ key ] ) {
|
||
// Discard any remaining `private` data
|
||
delete data_priv.cache[ key ];
|
||
}
|
||
}
|
||
}
|
||
// Discard any remaining `user` data
|
||
delete data_user.cache[ elem[ data_user.expando ] ];
|
||
}
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
text: function( value ) {
|
||
return access( this, function( value ) {
|
||
return value === undefined ?
|
||
jQuery.text( this ) :
|
||
this.empty().each(function() {
|
||
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
||
this.textContent = value;
|
||
}
|
||
});
|
||
}, null, value, arguments.length );
|
||
},
|
||
|
||
append: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
||
var target = manipulationTarget( this, elem );
|
||
target.appendChild( elem );
|
||
}
|
||
});
|
||
},
|
||
|
||
prepend: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
||
var target = manipulationTarget( this, elem );
|
||
target.insertBefore( elem, target.firstChild );
|
||
}
|
||
});
|
||
},
|
||
|
||
before: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.parentNode ) {
|
||
this.parentNode.insertBefore( elem, this );
|
||
}
|
||
});
|
||
},
|
||
|
||
after: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.parentNode ) {
|
||
this.parentNode.insertBefore( elem, this.nextSibling );
|
||
}
|
||
});
|
||
},
|
||
|
||
remove: function( selector, keepData /* Internal Use Only */ ) {
|
||
var elem,
|
||
elems = selector ? jQuery.filter( selector, this ) : this,
|
||
i = 0;
|
||
|
||
for ( ; (elem = elems[i]) != null; i++ ) {
|
||
if ( !keepData && elem.nodeType === 1 ) {
|
||
jQuery.cleanData( getAll( elem ) );
|
||
}
|
||
|
||
if ( elem.parentNode ) {
|
||
if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
|
||
setGlobalEval( getAll( elem, "script" ) );
|
||
}
|
||
elem.parentNode.removeChild( elem );
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
empty: function() {
|
||
var elem,
|
||
i = 0;
|
||
|
||
for ( ; (elem = this[i]) != null; i++ ) {
|
||
if ( elem.nodeType === 1 ) {
|
||
|
||
// Prevent memory leaks
|
||
jQuery.cleanData( getAll( elem, false ) );
|
||
|
||
// Remove any remaining nodes
|
||
elem.textContent = "";
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
clone: function( dataAndEvents, deepDataAndEvents ) {
|
||
dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
|
||
deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
|
||
|
||
return this.map(function() {
|
||
return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
|
||
});
|
||
},
|
||
|
||
html: function( value ) {
|
||
return access( this, function( value ) {
|
||
var elem = this[ 0 ] || {},
|
||
i = 0,
|
||
l = this.length;
|
||
|
||
if ( value === undefined && elem.nodeType === 1 ) {
|
||
return elem.innerHTML;
|
||
}
|
||
|
||
// See if we can take a shortcut and just use innerHTML
|
||
if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
|
||
!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
|
||
|
||
value = value.replace( rxhtmlTag, "<$1></$2>" );
|
||
|
||
try {
|
||
for ( ; i < l; i++ ) {
|
||
elem = this[ i ] || {};
|
||
|
||
// Remove element nodes and prevent memory leaks
|
||
if ( elem.nodeType === 1 ) {
|
||
jQuery.cleanData( getAll( elem, false ) );
|
||
elem.innerHTML = value;
|
||
}
|
||
}
|
||
|
||
elem = 0;
|
||
|
||
// If using innerHTML throws an exception, use the fallback method
|
||
} catch( e ) {}
|
||
}
|
||
|
||
if ( elem ) {
|
||
this.empty().append( value );
|
||
}
|
||
}, null, value, arguments.length );
|
||
},
|
||
|
||
replaceWith: function() {
|
||
var arg = arguments[ 0 ];
|
||
|
||
// Make the changes, replacing each context element with the new content
|
||
this.domManip( arguments, function( elem ) {
|
||
arg = this.parentNode;
|
||
|
||
jQuery.cleanData( getAll( this ) );
|
||
|
||
if ( arg ) {
|
||
arg.replaceChild( elem, this );
|
||
}
|
||
});
|
||
|
||
// Force removal if there was no new content (e.g., from empty arguments)
|
||
return arg && (arg.length || arg.nodeType) ? this : this.remove();
|
||
},
|
||
|
||
detach: function( selector ) {
|
||
return this.remove( selector, true );
|
||
},
|
||
|
||
domManip: function( args, callback ) {
|
||
|
||
// Flatten any nested arrays
|
||
args = concat.apply( [], args );
|
||
|
||
var fragment, first, scripts, hasScripts, node, doc,
|
||
i = 0,
|
||
l = this.length,
|
||
set = this,
|
||
iNoClone = l - 1,
|
||
value = args[ 0 ],
|
||
isFunction = jQuery.isFunction( value );
|
||
|
||
// We can't cloneNode fragments that contain checked, in WebKit
|
||
if ( isFunction ||
|
||
( l > 1 && typeof value === "string" &&
|
||
!support.checkClone && rchecked.test( value ) ) ) {
|
||
return this.each(function( index ) {
|
||
var self = set.eq( index );
|
||
if ( isFunction ) {
|
||
args[ 0 ] = value.call( this, index, self.html() );
|
||
}
|
||
self.domManip( args, callback );
|
||
});
|
||
}
|
||
|
||
if ( l ) {
|
||
fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
|
||
first = fragment.firstChild;
|
||
|
||
if ( fragment.childNodes.length === 1 ) {
|
||
fragment = first;
|
||
}
|
||
|
||
if ( first ) {
|
||
scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
|
||
hasScripts = scripts.length;
|
||
|
||
// Use the original fragment for the last item instead of the first because it can end up
|
||
// being emptied incorrectly in certain situations (#8070).
|
||
for ( ; i < l; i++ ) {
|
||
node = fragment;
|
||
|
||
if ( i !== iNoClone ) {
|
||
node = jQuery.clone( node, true, true );
|
||
|
||
// Keep references to cloned scripts for later restoration
|
||
if ( hasScripts ) {
|
||
// Support: QtWebKit
|
||
// jQuery.merge because push.apply(_, arraylike) throws
|
||
jQuery.merge( scripts, getAll( node, "script" ) );
|
||
}
|
||
}
|
||
|
||
callback.call( this[ i ], node, i );
|
||
}
|
||
|
||
if ( hasScripts ) {
|
||
doc = scripts[ scripts.length - 1 ].ownerDocument;
|
||
|
||
// Reenable scripts
|
||
jQuery.map( scripts, restoreScript );
|
||
|
||
// Evaluate executable scripts on first document insertion
|
||
for ( i = 0; i < hasScripts; i++ ) {
|
||
node = scripts[ i ];
|
||
if ( rscriptType.test( node.type || "" ) &&
|
||
!data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
|
||
|
||
if ( node.src ) {
|
||
// Optional AJAX dependency, but won't run scripts if not present
|
||
if ( jQuery._evalUrl ) {
|
||
jQuery._evalUrl( node.src );
|
||
}
|
||
} else {
|
||
jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
}
|
||
});
|
||
|
||
jQuery.each({
|
||
appendTo: "append",
|
||
prependTo: "prepend",
|
||
insertBefore: "before",
|
||
insertAfter: "after",
|
||
replaceAll: "replaceWith"
|
||
}, function( name, original ) {
|
||
jQuery.fn[ name ] = function( selector ) {
|
||
var elems,
|
||
ret = [],
|
||
insert = jQuery( selector ),
|
||
last = insert.length - 1,
|
||
i = 0;
|
||
|
||
for ( ; i <= last; i++ ) {
|
||
elems = i === last ? this : this.clone( true );
|
||
jQuery( insert[ i ] )[ original ]( elems );
|
||
|
||
// Support: QtWebKit
|
||
// .get() because push.apply(_, arraylike) throws
|
||
push.apply( ret, elems.get() );
|
||
}
|
||
|
||
return this.pushStack( ret );
|
||
};
|
||
});
|
||
|
||
|
||
var iframe,
|
||
elemdisplay = {};
|
||
|
||
/**
|
||
* Retrieve the actual display of a element
|
||
* @param {String} name nodeName of the element
|
||
* @param {Object} doc Document object
|
||
*/
|
||
// Called only from within defaultDisplay
|
||
function actualDisplay( name, doc ) {
|
||
var style,
|
||
elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
|
||
|
||
// getDefaultComputedStyle might be reliably used only on attached element
|
||
display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
|
||
|
||
// Use of this method is a temporary fix (more like optmization) until something better comes along,
|
||
// since it was removed from specification and supported only in FF
|
||
style.display : jQuery.css( elem[ 0 ], "display" );
|
||
|
||
// We don't have any data stored on the element,
|
||
// so use "detach" method as fast way to get rid of the element
|
||
elem.detach();
|
||
|
||
return display;
|
||
}
|
||
|
||
/**
|
||
* Try to determine the default display value of an element
|
||
* @param {String} nodeName
|
||
*/
|
||
function defaultDisplay( nodeName ) {
|
||
var doc = document,
|
||
display = elemdisplay[ nodeName ];
|
||
|
||
if ( !display ) {
|
||
display = actualDisplay( nodeName, doc );
|
||
|
||
// If the simple way fails, read from inside an iframe
|
||
if ( display === "none" || !display ) {
|
||
|
||
// Use the already-created iframe if possible
|
||
iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
|
||
|
||
// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
|
||
doc = iframe[ 0 ].contentDocument;
|
||
|
||
// Support: IE
|
||
doc.write();
|
||
doc.close();
|
||
|
||
display = actualDisplay( nodeName, doc );
|
||
iframe.detach();
|
||
}
|
||
|
||
// Store the correct default display
|
||
elemdisplay[ nodeName ] = display;
|
||
}
|
||
|
||
return display;
|
||
}
|
||
var rmargin = (/^margin/);
|
||
|
||
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
|
||
|
||
var getStyles = function( elem ) {
|
||
return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
|
||
};
|
||
|
||
|
||
|
||
function curCSS( elem, name, computed ) {
|
||
var width, minWidth, maxWidth, ret,
|
||
style = elem.style;
|
||
|
||
computed = computed || getStyles( elem );
|
||
|
||
// Support: IE9
|
||
// getPropertyValue is only needed for .css('filter') in IE9, see #12537
|
||
if ( computed ) {
|
||
ret = computed.getPropertyValue( name ) || computed[ name ];
|
||
}
|
||
|
||
if ( computed ) {
|
||
|
||
if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
|
||
ret = jQuery.style( elem, name );
|
||
}
|
||
|
||
// Support: iOS < 6
|
||
// A tribute to the "awesome hack by Dean Edwards"
|
||
// iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
|
||
// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
|
||
if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
|
||
|
||
// Remember the original values
|
||
width = style.width;
|
||
minWidth = style.minWidth;
|
||
maxWidth = style.maxWidth;
|
||
|
||
// Put in the new values to get a computed value out
|
||
style.minWidth = style.maxWidth = style.width = ret;
|
||
ret = computed.width;
|
||
|
||
// Revert the changed values
|
||
style.width = width;
|
||
style.minWidth = minWidth;
|
||
style.maxWidth = maxWidth;
|
||
}
|
||
}
|
||
|
||
return ret !== undefined ?
|
||
// Support: IE
|
||
// IE returns zIndex value as an integer.
|
||
ret + "" :
|
||
ret;
|
||
}
|
||
|
||
|
||
function addGetHookIf( conditionFn, hookFn ) {
|
||
// Define the hook, we'll check on the first run if it's really needed.
|
||
return {
|
||
get: function() {
|
||
if ( conditionFn() ) {
|
||
// Hook not needed (or it's not possible to use it due to missing dependency),
|
||
// remove it.
|
||
// Since there are no other hooks for marginRight, remove the whole object.
|
||
delete this.get;
|
||
return;
|
||
}
|
||
|
||
// Hook needed; redefine it so that the support test is not executed again.
|
||
|
||
return (this.get = hookFn).apply( this, arguments );
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
(function() {
|
||
var pixelPositionVal, boxSizingReliableVal,
|
||
docElem = document.documentElement,
|
||
container = document.createElement( "div" ),
|
||
div = document.createElement( "div" );
|
||
|
||
if ( !div.style ) {
|
||
return;
|
||
}
|
||
|
||
div.style.backgroundClip = "content-box";
|
||
div.cloneNode( true ).style.backgroundClip = "";
|
||
support.clearCloneStyle = div.style.backgroundClip === "content-box";
|
||
|
||
container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" +
|
||
"position:absolute";
|
||
container.appendChild( div );
|
||
|
||
// Executing both pixelPosition & boxSizingReliable tests require only one layout
|
||
// so they're executed at the same time to save the second computation.
|
||
function computePixelPositionAndBoxSizingReliable() {
|
||
div.style.cssText =
|
||
// Support: Firefox<29, Android 2.3
|
||
// Vendor-prefix box-sizing
|
||
"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
|
||
"box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
|
||
"border:1px;padding:1px;width:4px;position:absolute";
|
||
div.innerHTML = "";
|
||
docElem.appendChild( container );
|
||
|
||
var divStyle = window.getComputedStyle( div, null );
|
||
pixelPositionVal = divStyle.top !== "1%";
|
||
boxSizingReliableVal = divStyle.width === "4px";
|
||
|
||
docElem.removeChild( container );
|
||
}
|
||
|
||
// Support: node.js jsdom
|
||
// Don't assume that getComputedStyle is a property of the global object
|
||
if ( window.getComputedStyle ) {
|
||
jQuery.extend( support, {
|
||
pixelPosition: function() {
|
||
// This test is executed only once but we still do memoizing
|
||
// since we can use the boxSizingReliable pre-computing.
|
||
// No need to check if the test was already performed, though.
|
||
computePixelPositionAndBoxSizingReliable();
|
||
return pixelPositionVal;
|
||
},
|
||
boxSizingReliable: function() {
|
||
if ( boxSizingReliableVal == null ) {
|
||
computePixelPositionAndBoxSizingReliable();
|
||
}
|
||
return boxSizingReliableVal;
|
||
},
|
||
reliableMarginRight: function() {
|
||
// Support: Android 2.3
|
||
// Check if div with explicit width and no margin-right incorrectly
|
||
// gets computed margin-right based on width of container. (#3333)
|
||
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
|
||
// This support function is only executed once so no memoizing is needed.
|
||
var ret,
|
||
marginDiv = div.appendChild( document.createElement( "div" ) );
|
||
|
||
// Reset CSS: box-sizing; display; margin; border; padding
|
||
marginDiv.style.cssText = div.style.cssText =
|
||
// Support: Firefox<29, Android 2.3
|
||
// Vendor-prefix box-sizing
|
||
"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
|
||
"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
|
||
marginDiv.style.marginRight = marginDiv.style.width = "0";
|
||
div.style.width = "1px";
|
||
docElem.appendChild( container );
|
||
|
||
ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );
|
||
|
||
docElem.removeChild( container );
|
||
|
||
return ret;
|
||
}
|
||
});
|
||
}
|
||
})();
|
||
|
||
|
||
// A method for quickly swapping in/out CSS properties to get correct calculations.
|
||
jQuery.swap = function( elem, options, callback, args ) {
|
||
var ret, name,
|
||
old = {};
|
||
|
||
// Remember the old values, and insert the new ones
|
||
for ( name in options ) {
|
||
old[ name ] = elem.style[ name ];
|
||
elem.style[ name ] = options[ name ];
|
||
}
|
||
|
||
ret = callback.apply( elem, args || [] );
|
||
|
||
// Revert the old values
|
||
for ( name in options ) {
|
||
elem.style[ name ] = old[ name ];
|
||
}
|
||
|
||
return ret;
|
||
};
|
||
|
||
|
||
var
|
||
// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
|
||
// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
|
||
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
|
||
rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
|
||
rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
|
||
|
||
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
|
||
cssNormalTransform = {
|
||
letterSpacing: "0",
|
||
fontWeight: "400"
|
||
},
|
||
|
||
cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
|
||
|
||
// return a css property mapped to a potentially vendor prefixed property
|
||
function vendorPropName( style, name ) {
|
||
|
||
// shortcut for names that are not vendor prefixed
|
||
if ( name in style ) {
|
||
return name;
|
||
}
|
||
|
||
// check for vendor prefixed names
|
||
var capName = name[0].toUpperCase() + name.slice(1),
|
||
origName = name,
|
||
i = cssPrefixes.length;
|
||
|
||
while ( i-- ) {
|
||
name = cssPrefixes[ i ] + capName;
|
||
if ( name in style ) {
|
||
return name;
|
||
}
|
||
}
|
||
|
||
return origName;
|
||
}
|
||
|
||
function setPositiveNumber( elem, value, subtract ) {
|
||
var matches = rnumsplit.exec( value );
|
||
return matches ?
|
||
// Guard against undefined "subtract", e.g., when used as in cssHooks
|
||
Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
|
||
value;
|
||
}
|
||
|
||
function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
|
||
var i = extra === ( isBorderBox ? "border" : "content" ) ?
|
||
// If we already have the right measurement, avoid augmentation
|
||
4 :
|
||
// Otherwise initialize for horizontal or vertical properties
|
||
name === "width" ? 1 : 0,
|
||
|
||
val = 0;
|
||
|
||
for ( ; i < 4; i += 2 ) {
|
||
// both box models exclude margin, so add it if we want it
|
||
if ( extra === "margin" ) {
|
||
val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
|
||
}
|
||
|
||
if ( isBorderBox ) {
|
||
// border-box includes padding, so remove it if we want content
|
||
if ( extra === "content" ) {
|
||
val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
|
||
}
|
||
|
||
// at this point, extra isn't border nor margin, so remove border
|
||
if ( extra !== "margin" ) {
|
||
val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
|
||
}
|
||
} else {
|
||
// at this point, extra isn't content, so add padding
|
||
val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
|
||
|
||
// at this point, extra isn't content nor padding, so add border
|
||
if ( extra !== "padding" ) {
|
||
val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
|
||
}
|
||
}
|
||
}
|
||
|
||
return val;
|
||
}
|
||
|
||
function getWidthOrHeight( elem, name, extra ) {
|
||
|
||
// Start with offset property, which is equivalent to the border-box value
|
||
var valueIsBorderBox = true,
|
||
val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
|
||
styles = getStyles( elem ),
|
||
isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
|
||
|
||
// some non-html elements return undefined for offsetWidth, so check for null/undefined
|
||
// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
|
||
// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
|
||
if ( val <= 0 || val == null ) {
|
||
// Fall back to computed then uncomputed css if necessary
|
||
val = curCSS( elem, name, styles );
|
||
if ( val < 0 || val == null ) {
|
||
val = elem.style[ name ];
|
||
}
|
||
|
||
// Computed unit is not pixels. Stop here and return.
|
||
if ( rnumnonpx.test(val) ) {
|
||
return val;
|
||
}
|
||
|
||
// we need the check for style in case a browser which returns unreliable values
|
||
// for getComputedStyle silently falls back to the reliable elem.style
|
||
valueIsBorderBox = isBorderBox &&
|
||
( support.boxSizingReliable() || val === elem.style[ name ] );
|
||
|
||
// Normalize "", auto, and prepare for extra
|
||
val = parseFloat( val ) || 0;
|
||
}
|
||
|
||
// use the active box-sizing model to add/subtract irrelevant styles
|
||
return ( val +
|
||
augmentWidthOrHeight(
|
||
elem,
|
||
name,
|
||
extra || ( isBorderBox ? "border" : "content" ),
|
||
valueIsBorderBox,
|
||
styles
|
||
)
|
||
) + "px";
|
||
}
|
||
|
||
function showHide( elements, show ) {
|
||
var display, elem, hidden,
|
||
values = [],
|
||
index = 0,
|
||
length = elements.length;
|
||
|
||
for ( ; index < length; index++ ) {
|
||
elem = elements[ index ];
|
||
if ( !elem.style ) {
|
||
continue;
|
||
}
|
||
|
||
values[ index ] = data_priv.get( elem, "olddisplay" );
|
||
display = elem.style.display;
|
||
if ( show ) {
|
||
// Reset the inline display of this element to learn if it is
|
||
// being hidden by cascaded rules or not
|
||
if ( !values[ index ] && display === "none" ) {
|
||
elem.style.display = "";
|
||
}
|
||
|
||
// Set elements which have been overridden with display: none
|
||
// in a stylesheet to whatever the default browser style is
|
||
// for such an element
|
||
if ( elem.style.display === "" && isHidden( elem ) ) {
|
||
values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) );
|
||
}
|
||
} else {
|
||
hidden = isHidden( elem );
|
||
|
||
if ( display !== "none" || !hidden ) {
|
||
data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Set the display of most of the elements in a second loop
|
||
// to avoid the constant reflow
|
||
for ( index = 0; index < length; index++ ) {
|
||
elem = elements[ index ];
|
||
if ( !elem.style ) {
|
||
continue;
|
||
}
|
||
if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
|
||
elem.style.display = show ? values[ index ] || "" : "none";
|
||
}
|
||
}
|
||
|
||
return elements;
|
||
}
|
||
|
||
jQuery.extend({
|
||
// Add in style property hooks for overriding the default
|
||
// behavior of getting and setting a style property
|
||
cssHooks: {
|
||
opacity: {
|
||
get: function( elem, computed ) {
|
||
if ( computed ) {
|
||
// We should always get a number back from opacity
|
||
var ret = curCSS( elem, "opacity" );
|
||
return ret === "" ? "1" : ret;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
// Don't automatically add "px" to these possibly-unitless properties
|
||
cssNumber: {
|
||
"columnCount": true,
|
||
"fillOpacity": true,
|
||
"flexGrow": true,
|
||
"flexShrink": true,
|
||
"fontWeight": true,
|
||
"lineHeight": true,
|
||
"opacity": true,
|
||
"order": true,
|
||
"orphans": true,
|
||
"widows": true,
|
||
"zIndex": true,
|
||
"zoom": true
|
||
},
|
||
|
||
// Add in properties whose names you wish to fix before
|
||
// setting or getting the value
|
||
cssProps: {
|
||
// normalize float css property
|
||
"float": "cssFloat"
|
||
},
|
||
|
||
// Get and set the style property on a DOM Node
|
||
style: function( elem, name, value, extra ) {
|
||
// Don't set styles on text and comment nodes
|
||
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
|
||
return;
|
||
}
|
||
|
||
// Make sure that we're working with the right name
|
||
var ret, type, hooks,
|
||
origName = jQuery.camelCase( name ),
|
||
style = elem.style;
|
||
|
||
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
|
||
|
||
// gets hook for the prefixed version
|
||
// followed by the unprefixed version
|
||
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
||
|
||
// Check if we're setting a value
|
||
if ( value !== undefined ) {
|
||
type = typeof value;
|
||
|
||
// convert relative number strings (+= or -=) to relative numbers. #7345
|
||
if ( type === "string" && (ret = rrelNum.exec( value )) ) {
|
||
value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
|
||
// Fixes bug #9237
|
||
type = "number";
|
||
}
|
||
|
||
// Make sure that null and NaN values aren't set. See: #7116
|
||
if ( value == null || value !== value ) {
|
||
return;
|
||
}
|
||
|
||
// If a number was passed in, add 'px' to the (except for certain CSS properties)
|
||
if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
|
||
value += "px";
|
||
}
|
||
|
||
// Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
|
||
// but it would mean to define eight (for every problematic property) identical functions
|
||
if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
|
||
style[ name ] = "inherit";
|
||
}
|
||
|
||
// If a hook was provided, use that value, otherwise just set the specified value
|
||
if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
|
||
style[ name ] = value;
|
||
}
|
||
|
||
} else {
|
||
// If a hook was provided get the non-computed value from there
|
||
if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
|
||
return ret;
|
||
}
|
||
|
||
// Otherwise just get the value from the style object
|
||
return style[ name ];
|
||
}
|
||
},
|
||
|
||
css: function( elem, name, extra, styles ) {
|
||
var val, num, hooks,
|
||
origName = jQuery.camelCase( name );
|
||
|
||
// Make sure that we're working with the right name
|
||
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
|
||
|
||
// gets hook for the prefixed version
|
||
// followed by the unprefixed version
|
||
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
||
|
||
// If a hook was provided get the computed value from there
|
||
if ( hooks && "get" in hooks ) {
|
||
val = hooks.get( elem, true, extra );
|
||
}
|
||
|
||
// Otherwise, if a way to get the computed value exists, use that
|
||
if ( val === undefined ) {
|
||
val = curCSS( elem, name, styles );
|
||
}
|
||
|
||
//convert "normal" to computed value
|
||
if ( val === "normal" && name in cssNormalTransform ) {
|
||
val = cssNormalTransform[ name ];
|
||
}
|
||
|
||
// Return, converting to number if forced or a qualifier was provided and val looks numeric
|
||
if ( extra === "" || extra ) {
|
||
num = parseFloat( val );
|
||
return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
|
||
}
|
||
return val;
|
||
}
|
||
});
|
||
|
||
jQuery.each([ "height", "width" ], function( i, name ) {
|
||
jQuery.cssHooks[ name ] = {
|
||
get: function( elem, computed, extra ) {
|
||
if ( computed ) {
|
||
// certain elements can have dimension info if we invisibly show them
|
||
// however, it must have a current display style that would benefit from this
|
||
return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
|
||
jQuery.swap( elem, cssShow, function() {
|
||
return getWidthOrHeight( elem, name, extra );
|
||
}) :
|
||
getWidthOrHeight( elem, name, extra );
|
||
}
|
||
},
|
||
|
||
set: function( elem, value, extra ) {
|
||
var styles = extra && getStyles( elem );
|
||
return setPositiveNumber( elem, value, extra ?
|
||
augmentWidthOrHeight(
|
||
elem,
|
||
name,
|
||
extra,
|
||
jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
|
||
styles
|
||
) : 0
|
||
);
|
||
}
|
||
};
|
||
});
|
||
|
||
// Support: Android 2.3
|
||
jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
|
||
function( elem, computed ) {
|
||
if ( computed ) {
|
||
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
|
||
// Work around by temporarily setting element display to inline-block
|
||
return jQuery.swap( elem, { "display": "inline-block" },
|
||
curCSS, [ elem, "marginRight" ] );
|
||
}
|
||
}
|
||
);
|
||
|
||
// These hooks are used by animate to expand properties
|
||
jQuery.each({
|
||
margin: "",
|
||
padding: "",
|
||
border: "Width"
|
||
}, function( prefix, suffix ) {
|
||
jQuery.cssHooks[ prefix + suffix ] = {
|
||
expand: function( value ) {
|
||
var i = 0,
|
||
expanded = {},
|
||
|
||
// assumes a single number if not a string
|
||
parts = typeof value === "string" ? value.split(" ") : [ value ];
|
||
|
||
for ( ; i < 4; i++ ) {
|
||
expanded[ prefix + cssExpand[ i ] + suffix ] =
|
||
parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
|
||
}
|
||
|
||
return expanded;
|
||
}
|
||
};
|
||
|
||
if ( !rmargin.test( prefix ) ) {
|
||
jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
css: function( name, value ) {
|
||
return access( this, function( elem, name, value ) {
|
||
var styles, len,
|
||
map = {},
|
||
i = 0;
|
||
|
||
if ( jQuery.isArray( name ) ) {
|
||
styles = getStyles( elem );
|
||
len = name.length;
|
||
|
||
for ( ; i < len; i++ ) {
|
||
map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
|
||
}
|
||
|
||
return map;
|
||
}
|
||
|
||
return value !== undefined ?
|
||
jQuery.style( elem, name, value ) :
|
||
jQuery.css( elem, name );
|
||
}, name, value, arguments.length > 1 );
|
||
},
|
||
show: function() {
|
||
return showHide( this, true );
|
||
},
|
||
hide: function() {
|
||
return showHide( this );
|
||
},
|
||
toggle: function( state ) {
|
||
if ( typeof state === "boolean" ) {
|
||
return state ? this.show() : this.hide();
|
||
}
|
||
|
||
return this.each(function() {
|
||
if ( isHidden( this ) ) {
|
||
jQuery( this ).show();
|
||
} else {
|
||
jQuery( this ).hide();
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
|
||
function Tween( elem, options, prop, end, easing ) {
|
||
return new Tween.prototype.init( elem, options, prop, end, easing );
|
||
}
|
||
jQuery.Tween = Tween;
|
||
|
||
Tween.prototype = {
|
||
constructor: Tween,
|
||
init: function( elem, options, prop, end, easing, unit ) {
|
||
this.elem = elem;
|
||
this.prop = prop;
|
||
this.easing = easing || "swing";
|
||
this.options = options;
|
||
this.start = this.now = this.cur();
|
||
this.end = end;
|
||
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
|
||
},
|
||
cur: function() {
|
||
var hooks = Tween.propHooks[ this.prop ];
|
||
|
||
return hooks && hooks.get ?
|
||
hooks.get( this ) :
|
||
Tween.propHooks._default.get( this );
|
||
},
|
||
run: function( percent ) {
|
||
var eased,
|
||
hooks = Tween.propHooks[ this.prop ];
|
||
|
||
if ( this.options.duration ) {
|
||
this.pos = eased = jQuery.easing[ this.easing ](
|
||
percent, this.options.duration * percent, 0, 1, this.options.duration
|
||
);
|
||
} else {
|
||
this.pos = eased = percent;
|
||
}
|
||
this.now = ( this.end - this.start ) * eased + this.start;
|
||
|
||
if ( this.options.step ) {
|
||
this.options.step.call( this.elem, this.now, this );
|
||
}
|
||
|
||
if ( hooks && hooks.set ) {
|
||
hooks.set( this );
|
||
} else {
|
||
Tween.propHooks._default.set( this );
|
||
}
|
||
return this;
|
||
}
|
||
};
|
||
|
||
Tween.prototype.init.prototype = Tween.prototype;
|
||
|
||
Tween.propHooks = {
|
||
_default: {
|
||
get: function( tween ) {
|
||
var result;
|
||
|
||
if ( tween.elem[ tween.prop ] != null &&
|
||
(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
|
||
return tween.elem[ tween.prop ];
|
||
}
|
||
|
||
// passing an empty string as a 3rd parameter to .css will automatically
|
||
// attempt a parseFloat and fallback to a string if the parse fails
|
||
// so, simple values such as "10px" are parsed to Float.
|
||
// complex values such as "rotate(1rad)" are returned as is.
|
||
result = jQuery.css( tween.elem, tween.prop, "" );
|
||
// Empty strings, null, undefined and "auto" are converted to 0.
|
||
return !result || result === "auto" ? 0 : result;
|
||
},
|
||
set: function( tween ) {
|
||
// use step hook for back compat - use cssHook if its there - use .style if its
|
||
// available and use plain properties where available
|
||
if ( jQuery.fx.step[ tween.prop ] ) {
|
||
jQuery.fx.step[ tween.prop ]( tween );
|
||
} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
|
||
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
|
||
} else {
|
||
tween.elem[ tween.prop ] = tween.now;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
// Support: IE9
|
||
// Panic based approach to setting things on disconnected nodes
|
||
|
||
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
|
||
set: function( tween ) {
|
||
if ( tween.elem.nodeType && tween.elem.parentNode ) {
|
||
tween.elem[ tween.prop ] = tween.now;
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.easing = {
|
||
linear: function( p ) {
|
||
return p;
|
||
},
|
||
swing: function( p ) {
|
||
return 0.5 - Math.cos( p * Math.PI ) / 2;
|
||
}
|
||
};
|
||
|
||
jQuery.fx = Tween.prototype.init;
|
||
|
||
// Back Compat <1.8 extension point
|
||
jQuery.fx.step = {};
|
||
|
||
|
||
|
||
|
||
var
|
||
fxNow, timerId,
|
||
rfxtypes = /^(?:toggle|show|hide)$/,
|
||
rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
|
||
rrun = /queueHooks$/,
|
||
animationPrefilters = [ defaultPrefilter ],
|
||
tweeners = {
|
||
"*": [ function( prop, value ) {
|
||
var tween = this.createTween( prop, value ),
|
||
target = tween.cur(),
|
||
parts = rfxnum.exec( value ),
|
||
unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
|
||
|
||
// Starting value computation is required for potential unit mismatches
|
||
start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
|
||
rfxnum.exec( jQuery.css( tween.elem, prop ) ),
|
||
scale = 1,
|
||
maxIterations = 20;
|
||
|
||
if ( start && start[ 3 ] !== unit ) {
|
||
// Trust units reported by jQuery.css
|
||
unit = unit || start[ 3 ];
|
||
|
||
// Make sure we update the tween properties later on
|
||
parts = parts || [];
|
||
|
||
// Iteratively approximate from a nonzero starting point
|
||
start = +target || 1;
|
||
|
||
do {
|
||
// If previous iteration zeroed out, double until we get *something*
|
||
// Use a string for doubling factor so we don't accidentally see scale as unchanged below
|
||
scale = scale || ".5";
|
||
|
||
// Adjust and apply
|
||
start = start / scale;
|
||
jQuery.style( tween.elem, prop, start + unit );
|
||
|
||
// Update scale, tolerating zero or NaN from tween.cur()
|
||
// And breaking the loop if scale is unchanged or perfect, or if we've just had enough
|
||
} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
|
||
}
|
||
|
||
// Update tween properties
|
||
if ( parts ) {
|
||
start = tween.start = +start || +target || 0;
|
||
tween.unit = unit;
|
||
// If a +=/-= token was provided, we're doing a relative animation
|
||
tween.end = parts[ 1 ] ?
|
||
start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
|
||
+parts[ 2 ];
|
||
}
|
||
|
||
return tween;
|
||
} ]
|
||
};
|
||
|
||
// Animations created synchronously will run synchronously
|
||
function createFxNow() {
|
||
setTimeout(function() {
|
||
fxNow = undefined;
|
||
});
|
||
return ( fxNow = jQuery.now() );
|
||
}
|
||
|
||
// Generate parameters to create a standard animation
|
||
function genFx( type, includeWidth ) {
|
||
var which,
|
||
i = 0,
|
||
attrs = { height: type };
|
||
|
||
// if we include width, step value is 1 to do all cssExpand values,
|
||
// if we don't include width, step value is 2 to skip over Left and Right
|
||
includeWidth = includeWidth ? 1 : 0;
|
||
for ( ; i < 4 ; i += 2 - includeWidth ) {
|
||
which = cssExpand[ i ];
|
||
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
|
||
}
|
||
|
||
if ( includeWidth ) {
|
||
attrs.opacity = attrs.width = type;
|
||
}
|
||
|
||
return attrs;
|
||
}
|
||
|
||
function createTween( value, prop, animation ) {
|
||
var tween,
|
||
collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
|
||
index = 0,
|
||
length = collection.length;
|
||
for ( ; index < length; index++ ) {
|
||
if ( (tween = collection[ index ].call( animation, prop, value )) ) {
|
||
|
||
// we're done with this property
|
||
return tween;
|
||
}
|
||
}
|
||
}
|
||
|
||
function defaultPrefilter( elem, props, opts ) {
|
||
/* jshint validthis: true */
|
||
var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
|
||
anim = this,
|
||
orig = {},
|
||
style = elem.style,
|
||
hidden = elem.nodeType && isHidden( elem ),
|
||
dataShow = data_priv.get( elem, "fxshow" );
|
||
|
||
// handle queue: false promises
|
||
if ( !opts.queue ) {
|
||
hooks = jQuery._queueHooks( elem, "fx" );
|
||
if ( hooks.unqueued == null ) {
|
||
hooks.unqueued = 0;
|
||
oldfire = hooks.empty.fire;
|
||
hooks.empty.fire = function() {
|
||
if ( !hooks.unqueued ) {
|
||
oldfire();
|
||
}
|
||
};
|
||
}
|
||
hooks.unqueued++;
|
||
|
||
anim.always(function() {
|
||
// doing this makes sure that the complete handler will be called
|
||
// before this completes
|
||
anim.always(function() {
|
||
hooks.unqueued--;
|
||
if ( !jQuery.queue( elem, "fx" ).length ) {
|
||
hooks.empty.fire();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// height/width overflow pass
|
||
if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
|
||
// Make sure that nothing sneaks out
|
||
// Record all 3 overflow attributes because IE9-10 do not
|
||
// change the overflow attribute when overflowX and
|
||
// overflowY are set to the same value
|
||
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
|
||
|
||
// Set display property to inline-block for height/width
|
||
// animations on inline elements that are having width/height animated
|
||
display = jQuery.css( elem, "display" );
|
||
|
||
// Test default display if display is currently "none"
|
||
checkDisplay = display === "none" ?
|
||
data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
|
||
|
||
if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
|
||
style.display = "inline-block";
|
||
}
|
||
}
|
||
|
||
if ( opts.overflow ) {
|
||
style.overflow = "hidden";
|
||
anim.always(function() {
|
||
style.overflow = opts.overflow[ 0 ];
|
||
style.overflowX = opts.overflow[ 1 ];
|
||
style.overflowY = opts.overflow[ 2 ];
|
||
});
|
||
}
|
||
|
||
// show/hide pass
|
||
for ( prop in props ) {
|
||
value = props[ prop ];
|
||
if ( rfxtypes.exec( value ) ) {
|
||
delete props[ prop ];
|
||
toggle = toggle || value === "toggle";
|
||
if ( value === ( hidden ? "hide" : "show" ) ) {
|
||
|
||
// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
|
||
if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
|
||
hidden = true;
|
||
} else {
|
||
continue;
|
||
}
|
||
}
|
||
orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
|
||
|
||
// Any non-fx value stops us from restoring the original display value
|
||
} else {
|
||
display = undefined;
|
||
}
|
||
}
|
||
|
||
if ( !jQuery.isEmptyObject( orig ) ) {
|
||
if ( dataShow ) {
|
||
if ( "hidden" in dataShow ) {
|
||
hidden = dataShow.hidden;
|
||
}
|
||
} else {
|
||
dataShow = data_priv.access( elem, "fxshow", {} );
|
||
}
|
||
|
||
// store state if its toggle - enables .stop().toggle() to "reverse"
|
||
if ( toggle ) {
|
||
dataShow.hidden = !hidden;
|
||
}
|
||
if ( hidden ) {
|
||
jQuery( elem ).show();
|
||
} else {
|
||
anim.done(function() {
|
||
jQuery( elem ).hide();
|
||
});
|
||
}
|
||
anim.done(function() {
|
||
var prop;
|
||
|
||
data_priv.remove( elem, "fxshow" );
|
||
for ( prop in orig ) {
|
||
jQuery.style( elem, prop, orig[ prop ] );
|
||
}
|
||
});
|
||
for ( prop in orig ) {
|
||
tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
|
||
|
||
if ( !( prop in dataShow ) ) {
|
||
dataShow[ prop ] = tween.start;
|
||
if ( hidden ) {
|
||
tween.end = tween.start;
|
||
tween.start = prop === "width" || prop === "height" ? 1 : 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// If this is a noop like .hide().hide(), restore an overwritten display value
|
||
} else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
|
||
style.display = display;
|
||
}
|
||
}
|
||
|
||
function propFilter( props, specialEasing ) {
|
||
var index, name, easing, value, hooks;
|
||
|
||
// camelCase, specialEasing and expand cssHook pass
|
||
for ( index in props ) {
|
||
name = jQuery.camelCase( index );
|
||
easing = specialEasing[ name ];
|
||
value = props[ index ];
|
||
if ( jQuery.isArray( value ) ) {
|
||
easing = value[ 1 ];
|
||
value = props[ index ] = value[ 0 ];
|
||
}
|
||
|
||
if ( index !== name ) {
|
||
props[ name ] = value;
|
||
delete props[ index ];
|
||
}
|
||
|
||
hooks = jQuery.cssHooks[ name ];
|
||
if ( hooks && "expand" in hooks ) {
|
||
value = hooks.expand( value );
|
||
delete props[ name ];
|
||
|
||
// not quite $.extend, this wont overwrite keys already present.
|
||
// also - reusing 'index' from above because we have the correct "name"
|
||
for ( index in value ) {
|
||
if ( !( index in props ) ) {
|
||
props[ index ] = value[ index ];
|
||
specialEasing[ index ] = easing;
|
||
}
|
||
}
|
||
} else {
|
||
specialEasing[ name ] = easing;
|
||
}
|
||
}
|
||
}
|
||
|
||
function Animation( elem, properties, options ) {
|
||
var result,
|
||
stopped,
|
||
index = 0,
|
||
length = animationPrefilters.length,
|
||
deferred = jQuery.Deferred().always( function() {
|
||
// don't match elem in the :animated selector
|
||
delete tick.elem;
|
||
}),
|
||
tick = function() {
|
||
if ( stopped ) {
|
||
return false;
|
||
}
|
||
var currentTime = fxNow || createFxNow(),
|
||
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
|
||
// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
|
||
temp = remaining / animation.duration || 0,
|
||
percent = 1 - temp,
|
||
index = 0,
|
||
length = animation.tweens.length;
|
||
|
||
for ( ; index < length ; index++ ) {
|
||
animation.tweens[ index ].run( percent );
|
||
}
|
||
|
||
deferred.notifyWith( elem, [ animation, percent, remaining ]);
|
||
|
||
if ( percent < 1 && length ) {
|
||
return remaining;
|
||
} else {
|
||
deferred.resolveWith( elem, [ animation ] );
|
||
return false;
|
||
}
|
||
},
|
||
animation = deferred.promise({
|
||
elem: elem,
|
||
props: jQuery.extend( {}, properties ),
|
||
opts: jQuery.extend( true, { specialEasing: {} }, options ),
|
||
originalProperties: properties,
|
||
originalOptions: options,
|
||
startTime: fxNow || createFxNow(),
|
||
duration: options.duration,
|
||
tweens: [],
|
||
createTween: function( prop, end ) {
|
||
var tween = jQuery.Tween( elem, animation.opts, prop, end,
|
||
animation.opts.specialEasing[ prop ] || animation.opts.easing );
|
||
animation.tweens.push( tween );
|
||
return tween;
|
||
},
|
||
stop: function( gotoEnd ) {
|
||
var index = 0,
|
||
// if we are going to the end, we want to run all the tweens
|
||
// otherwise we skip this part
|
||
length = gotoEnd ? animation.tweens.length : 0;
|
||
if ( stopped ) {
|
||
return this;
|
||
}
|
||
stopped = true;
|
||
for ( ; index < length ; index++ ) {
|
||
animation.tweens[ index ].run( 1 );
|
||
}
|
||
|
||
// resolve when we played the last frame
|
||
// otherwise, reject
|
||
if ( gotoEnd ) {
|
||
deferred.resolveWith( elem, [ animation, gotoEnd ] );
|
||
} else {
|
||
deferred.rejectWith( elem, [ animation, gotoEnd ] );
|
||
}
|
||
return this;
|
||
}
|
||
}),
|
||
props = animation.props;
|
||
|
||
propFilter( props, animation.opts.specialEasing );
|
||
|
||
for ( ; index < length ; index++ ) {
|
||
result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
|
||
if ( result ) {
|
||
return result;
|
||
}
|
||
}
|
||
|
||
jQuery.map( props, createTween, animation );
|
||
|
||
if ( jQuery.isFunction( animation.opts.start ) ) {
|
||
animation.opts.start.call( elem, animation );
|
||
}
|
||
|
||
jQuery.fx.timer(
|
||
jQuery.extend( tick, {
|
||
elem: elem,
|
||
anim: animation,
|
||
queue: animation.opts.queue
|
||
})
|
||
);
|
||
|
||
// attach callbacks from options
|
||
return animation.progress( animation.opts.progress )
|
||
.done( animation.opts.done, animation.opts.complete )
|
||
.fail( animation.opts.fail )
|
||
.always( animation.opts.always );
|
||
}
|
||
|
||
jQuery.Animation = jQuery.extend( Animation, {
|
||
|
||
tweener: function( props, callback ) {
|
||
if ( jQuery.isFunction( props ) ) {
|
||
callback = props;
|
||
props = [ "*" ];
|
||
} else {
|
||
props = props.split(" ");
|
||
}
|
||
|
||
var prop,
|
||
index = 0,
|
||
length = props.length;
|
||
|
||
for ( ; index < length ; index++ ) {
|
||
prop = props[ index ];
|
||
tweeners[ prop ] = tweeners[ prop ] || [];
|
||
tweeners[ prop ].unshift( callback );
|
||
}
|
||
},
|
||
|
||
prefilter: function( callback, prepend ) {
|
||
if ( prepend ) {
|
||
animationPrefilters.unshift( callback );
|
||
} else {
|
||
animationPrefilters.push( callback );
|
||
}
|
||
}
|
||
});
|
||
|
||
jQuery.speed = function( speed, easing, fn ) {
|
||
var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
|
||
complete: fn || !fn && easing ||
|
||
jQuery.isFunction( speed ) && speed,
|
||
duration: speed,
|
||
easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
|
||
};
|
||
|
||
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
|
||
opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
|
||
|
||
// normalize opt.queue - true/undefined/null -> "fx"
|
||
if ( opt.queue == null || opt.queue === true ) {
|
||
opt.queue = "fx";
|
||
}
|
||
|
||
// Queueing
|
||
opt.old = opt.complete;
|
||
|
||
opt.complete = function() {
|
||
if ( jQuery.isFunction( opt.old ) ) {
|
||
opt.old.call( this );
|
||
}
|
||
|
||
if ( opt.queue ) {
|
||
jQuery.dequeue( this, opt.queue );
|
||
}
|
||
};
|
||
|
||
return opt;
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
fadeTo: function( speed, to, easing, callback ) {
|
||
|
||
// show any hidden elements after setting opacity to 0
|
||
return this.filter( isHidden ).css( "opacity", 0 ).show()
|
||
|
||
// animate to the value specified
|
||
.end().animate({ opacity: to }, speed, easing, callback );
|
||
},
|
||
animate: function( prop, speed, easing, callback ) {
|
||
var empty = jQuery.isEmptyObject( prop ),
|
||
optall = jQuery.speed( speed, easing, callback ),
|
||
doAnimation = function() {
|
||
// Operate on a copy of prop so per-property easing won't be lost
|
||
var anim = Animation( this, jQuery.extend( {}, prop ), optall );
|
||
|
||
// Empty animations, or finishing resolves immediately
|
||
if ( empty || data_priv.get( this, "finish" ) ) {
|
||
anim.stop( true );
|
||
}
|
||
};
|
||
doAnimation.finish = doAnimation;
|
||
|
||
return empty || optall.queue === false ?
|
||
this.each( doAnimation ) :
|
||
this.queue( optall.queue, doAnimation );
|
||
},
|
||
stop: function( type, clearQueue, gotoEnd ) {
|
||
var stopQueue = function( hooks ) {
|
||
var stop = hooks.stop;
|
||
delete hooks.stop;
|
||
stop( gotoEnd );
|
||
};
|
||
|
||
if ( typeof type !== "string" ) {
|
||
gotoEnd = clearQueue;
|
||
clearQueue = type;
|
||
type = undefined;
|
||
}
|
||
if ( clearQueue && type !== false ) {
|
||
this.queue( type || "fx", [] );
|
||
}
|
||
|
||
return this.each(function() {
|
||
var dequeue = true,
|
||
index = type != null && type + "queueHooks",
|
||
timers = jQuery.timers,
|
||
data = data_priv.get( this );
|
||
|
||
if ( index ) {
|
||
if ( data[ index ] && data[ index ].stop ) {
|
||
stopQueue( data[ index ] );
|
||
}
|
||
} else {
|
||
for ( index in data ) {
|
||
if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
|
||
stopQueue( data[ index ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
for ( index = timers.length; index--; ) {
|
||
if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
|
||
timers[ index ].anim.stop( gotoEnd );
|
||
dequeue = false;
|
||
timers.splice( index, 1 );
|
||
}
|
||
}
|
||
|
||
// start the next in the queue if the last step wasn't forced
|
||
// timers currently will call their complete callbacks, which will dequeue
|
||
// but only if they were gotoEnd
|
||
if ( dequeue || !gotoEnd ) {
|
||
jQuery.dequeue( this, type );
|
||
}
|
||
});
|
||
},
|
||
finish: function( type ) {
|
||
if ( type !== false ) {
|
||
type = type || "fx";
|
||
}
|
||
return this.each(function() {
|
||
var index,
|
||
data = data_priv.get( this ),
|
||
queue = data[ type + "queue" ],
|
||
hooks = data[ type + "queueHooks" ],
|
||
timers = jQuery.timers,
|
||
length = queue ? queue.length : 0;
|
||
|
||
// enable finishing flag on private data
|
||
data.finish = true;
|
||
|
||
// empty the queue first
|
||
jQuery.queue( this, type, [] );
|
||
|
||
if ( hooks && hooks.stop ) {
|
||
hooks.stop.call( this, true );
|
||
}
|
||
|
||
// look for any active animations, and finish them
|
||
for ( index = timers.length; index--; ) {
|
||
if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
|
||
timers[ index ].anim.stop( true );
|
||
timers.splice( index, 1 );
|
||
}
|
||
}
|
||
|
||
// look for any animations in the old queue and finish them
|
||
for ( index = 0; index < length; index++ ) {
|
||
if ( queue[ index ] && queue[ index ].finish ) {
|
||
queue[ index ].finish.call( this );
|
||
}
|
||
}
|
||
|
||
// turn off finishing flag
|
||
delete data.finish;
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
|
||
var cssFn = jQuery.fn[ name ];
|
||
jQuery.fn[ name ] = function( speed, easing, callback ) {
|
||
return speed == null || typeof speed === "boolean" ?
|
||
cssFn.apply( this, arguments ) :
|
||
this.animate( genFx( name, true ), speed, easing, callback );
|
||
};
|
||
});
|
||
|
||
// Generate shortcuts for custom animations
|
||
jQuery.each({
|
||
slideDown: genFx("show"),
|
||
slideUp: genFx("hide"),
|
||
slideToggle: genFx("toggle"),
|
||
fadeIn: { opacity: "show" },
|
||
fadeOut: { opacity: "hide" },
|
||
fadeToggle: { opacity: "toggle" }
|
||
}, function( name, props ) {
|
||
jQuery.fn[ name ] = function( speed, easing, callback ) {
|
||
return this.animate( props, speed, easing, callback );
|
||
};
|
||
});
|
||
|
||
jQuery.timers = [];
|
||
jQuery.fx.tick = function() {
|
||
var timer,
|
||
i = 0,
|
||
timers = jQuery.timers;
|
||
|
||
fxNow = jQuery.now();
|
||
|
||
for ( ; i < timers.length; i++ ) {
|
||
timer = timers[ i ];
|
||
// Checks the timer has not already been removed
|
||
if ( !timer() && timers[ i ] === timer ) {
|
||
timers.splice( i--, 1 );
|
||
}
|
||
}
|
||
|
||
if ( !timers.length ) {
|
||
jQuery.fx.stop();
|
||
}
|
||
fxNow = undefined;
|
||
};
|
||
|
||
jQuery.fx.timer = function( timer ) {
|
||
jQuery.timers.push( timer );
|
||
if ( timer() ) {
|
||
jQuery.fx.start();
|
||
} else {
|
||
jQuery.timers.pop();
|
||
}
|
||
};
|
||
|
||
jQuery.fx.interval = 13;
|
||
|
||
jQuery.fx.start = function() {
|
||
if ( !timerId ) {
|
||
timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
|
||
}
|
||
};
|
||
|
||
jQuery.fx.stop = function() {
|
||
clearInterval( timerId );
|
||
timerId = null;
|
||
};
|
||
|
||
jQuery.fx.speeds = {
|
||
slow: 600,
|
||
fast: 200,
|
||
// Default speed
|
||
_default: 400
|
||
};
|
||
|
||
|
||
// Based off of the plugin by Clint Helfers, with permission.
|
||
// http://blindsignals.com/index.php/2009/07/jquery-delay/
|
||
jQuery.fn.delay = function( time, type ) {
|
||
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
|
||
type = type || "fx";
|
||
|
||
return this.queue( type, function( next, hooks ) {
|
||
var timeout = setTimeout( next, time );
|
||
hooks.stop = function() {
|
||
clearTimeout( timeout );
|
||
};
|
||
});
|
||
};
|
||
|
||
|
||
(function() {
|
||
var input = document.createElement( "input" ),
|
||
select = document.createElement( "select" ),
|
||
opt = select.appendChild( document.createElement( "option" ) );
|
||
|
||
input.type = "checkbox";
|
||
|
||
// Support: iOS 5.1, Android 4.x, Android 2.3
|
||
// Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
|
||
support.checkOn = input.value !== "";
|
||
|
||
// Must access the parent to make an option select properly
|
||
// Support: IE9, IE10
|
||
support.optSelected = opt.selected;
|
||
|
||
// Make sure that the options inside disabled selects aren't marked as disabled
|
||
// (WebKit marks them as disabled)
|
||
select.disabled = true;
|
||
support.optDisabled = !opt.disabled;
|
||
|
||
// Check if an input maintains its value after becoming a radio
|
||
// Support: IE9, IE10
|
||
input = document.createElement( "input" );
|
||
input.value = "t";
|
||
input.type = "radio";
|
||
support.radioValue = input.value === "t";
|
||
})();
|
||
|
||
|
||
var nodeHook, boolHook,
|
||
attrHandle = jQuery.expr.attrHandle;
|
||
|
||
jQuery.fn.extend({
|
||
attr: function( name, value ) {
|
||
return access( this, jQuery.attr, name, value, arguments.length > 1 );
|
||
},
|
||
|
||
removeAttr: function( name ) {
|
||
return this.each(function() {
|
||
jQuery.removeAttr( this, name );
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.extend({
|
||
attr: function( elem, name, value ) {
|
||
var hooks, ret,
|
||
nType = elem.nodeType;
|
||
|
||
// don't get/set attributes on text, comment and attribute nodes
|
||
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
|
||
return;
|
||
}
|
||
|
||
// Fallback to prop when attributes are not supported
|
||
if ( typeof elem.getAttribute === strundefined ) {
|
||
return jQuery.prop( elem, name, value );
|
||
}
|
||
|
||
// All attributes are lowercase
|
||
// Grab necessary hook if one is defined
|
||
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
|
||
name = name.toLowerCase();
|
||
hooks = jQuery.attrHooks[ name ] ||
|
||
( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
|
||
}
|
||
|
||
if ( value !== undefined ) {
|
||
|
||
if ( value === null ) {
|
||
jQuery.removeAttr( elem, name );
|
||
|
||
} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
|
||
return ret;
|
||
|
||
} else {
|
||
elem.setAttribute( name, value + "" );
|
||
return value;
|
||
}
|
||
|
||
} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
|
||
return ret;
|
||
|
||
} else {
|
||
ret = jQuery.find.attr( elem, name );
|
||
|
||
// Non-existent attributes return null, we normalize to undefined
|
||
return ret == null ?
|
||
undefined :
|
||
ret;
|
||
}
|
||
},
|
||
|
||
removeAttr: function( elem, value ) {
|
||
var name, propName,
|
||
i = 0,
|
||
attrNames = value && value.match( rnotwhite );
|
||
|
||
if ( attrNames && elem.nodeType === 1 ) {
|
||
while ( (name = attrNames[i++]) ) {
|
||
propName = jQuery.propFix[ name ] || name;
|
||
|
||
// Boolean attributes get special treatment (#10870)
|
||
if ( jQuery.expr.match.bool.test( name ) ) {
|
||
// Set corresponding property to false
|
||
elem[ propName ] = false;
|
||
}
|
||
|
||
elem.removeAttribute( name );
|
||
}
|
||
}
|
||
},
|
||
|
||
attrHooks: {
|
||
type: {
|
||
set: function( elem, value ) {
|
||
if ( !support.radioValue && value === "radio" &&
|
||
jQuery.nodeName( elem, "input" ) ) {
|
||
// Setting the type on a radio button after the value resets the value in IE6-9
|
||
// Reset value to default in case type is set after value during creation
|
||
var val = elem.value;
|
||
elem.setAttribute( "type", value );
|
||
if ( val ) {
|
||
elem.value = val;
|
||
}
|
||
return value;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Hooks for boolean attributes
|
||
boolHook = {
|
||
set: function( elem, value, name ) {
|
||
if ( value === false ) {
|
||
// Remove boolean attributes when set to false
|
||
jQuery.removeAttr( elem, name );
|
||
} else {
|
||
elem.setAttribute( name, name );
|
||
}
|
||
return name;
|
||
}
|
||
};
|
||
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
|
||
var getter = attrHandle[ name ] || jQuery.find.attr;
|
||
|
||
attrHandle[ name ] = function( elem, name, isXML ) {
|
||
var ret, handle;
|
||
if ( !isXML ) {
|
||
// Avoid an infinite loop by temporarily removing this function from the getter
|
||
handle = attrHandle[ name ];
|
||
attrHandle[ name ] = ret;
|
||
ret = getter( elem, name, isXML ) != null ?
|
||
name.toLowerCase() :
|
||
null;
|
||
attrHandle[ name ] = handle;
|
||
}
|
||
return ret;
|
||
};
|
||
});
|
||
|
||
|
||
|
||
|
||
var rfocusable = /^(?:input|select|textarea|button)$/i;
|
||
|
||
jQuery.fn.extend({
|
||
prop: function( name, value ) {
|
||
return access( this, jQuery.prop, name, value, arguments.length > 1 );
|
||
},
|
||
|
||
removeProp: function( name ) {
|
||
return this.each(function() {
|
||
delete this[ jQuery.propFix[ name ] || name ];
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.extend({
|
||
propFix: {
|
||
"for": "htmlFor",
|
||
"class": "className"
|
||
},
|
||
|
||
prop: function( elem, name, value ) {
|
||
var ret, hooks, notxml,
|
||
nType = elem.nodeType;
|
||
|
||
// don't get/set properties on text, comment and attribute nodes
|
||
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
|
||
return;
|
||
}
|
||
|
||
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
|
||
|
||
if ( notxml ) {
|
||
// Fix name and attach hooks
|
||
name = jQuery.propFix[ name ] || name;
|
||
hooks = jQuery.propHooks[ name ];
|
||
}
|
||
|
||
if ( value !== undefined ) {
|
||
return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
|
||
ret :
|
||
( elem[ name ] = value );
|
||
|
||
} else {
|
||
return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
|
||
ret :
|
||
elem[ name ];
|
||
}
|
||
},
|
||
|
||
propHooks: {
|
||
tabIndex: {
|
||
get: function( elem ) {
|
||
return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
|
||
elem.tabIndex :
|
||
-1;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Support: IE9+
|
||
// Selectedness for an option in an optgroup can be inaccurate
|
||
if ( !support.optSelected ) {
|
||
jQuery.propHooks.selected = {
|
||
get: function( elem ) {
|
||
var parent = elem.parentNode;
|
||
if ( parent && parent.parentNode ) {
|
||
parent.parentNode.selectedIndex;
|
||
}
|
||
return null;
|
||
}
|
||
};
|
||
}
|
||
|
||
jQuery.each([
|
||
"tabIndex",
|
||
"readOnly",
|
||
"maxLength",
|
||
"cellSpacing",
|
||
"cellPadding",
|
||
"rowSpan",
|
||
"colSpan",
|
||
"useMap",
|
||
"frameBorder",
|
||
"contentEditable"
|
||
], function() {
|
||
jQuery.propFix[ this.toLowerCase() ] = this;
|
||
});
|
||
|
||
|
||
|
||
|
||
var rclass = /[\t\r\n\f]/g;
|
||
|
||
jQuery.fn.extend({
|
||
addClass: function( value ) {
|
||
var classes, elem, cur, clazz, j, finalValue,
|
||
proceed = typeof value === "string" && value,
|
||
i = 0,
|
||
len = this.length;
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each(function( j ) {
|
||
jQuery( this ).addClass( value.call( this, j, this.className ) );
|
||
});
|
||
}
|
||
|
||
if ( proceed ) {
|
||
// The disjunction here is for better compressibility (see removeClass)
|
||
classes = ( value || "" ).match( rnotwhite ) || [];
|
||
|
||
for ( ; i < len; i++ ) {
|
||
elem = this[ i ];
|
||
cur = elem.nodeType === 1 && ( elem.className ?
|
||
( " " + elem.className + " " ).replace( rclass, " " ) :
|
||
" "
|
||
);
|
||
|
||
if ( cur ) {
|
||
j = 0;
|
||
while ( (clazz = classes[j++]) ) {
|
||
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
|
||
cur += clazz + " ";
|
||
}
|
||
}
|
||
|
||
// only assign if different to avoid unneeded rendering.
|
||
finalValue = jQuery.trim( cur );
|
||
if ( elem.className !== finalValue ) {
|
||
elem.className = finalValue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
removeClass: function( value ) {
|
||
var classes, elem, cur, clazz, j, finalValue,
|
||
proceed = arguments.length === 0 || typeof value === "string" && value,
|
||
i = 0,
|
||
len = this.length;
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each(function( j ) {
|
||
jQuery( this ).removeClass( value.call( this, j, this.className ) );
|
||
});
|
||
}
|
||
if ( proceed ) {
|
||
classes = ( value || "" ).match( rnotwhite ) || [];
|
||
|
||
for ( ; i < len; i++ ) {
|
||
elem = this[ i ];
|
||
// This expression is here for better compressibility (see addClass)
|
||
cur = elem.nodeType === 1 && ( elem.className ?
|
||
( " " + elem.className + " " ).replace( rclass, " " ) :
|
||
""
|
||
);
|
||
|
||
if ( cur ) {
|
||
j = 0;
|
||
while ( (clazz = classes[j++]) ) {
|
||
// Remove *all* instances
|
||
while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
|
||
cur = cur.replace( " " + clazz + " ", " " );
|
||
}
|
||
}
|
||
|
||
// only assign if different to avoid unneeded rendering.
|
||
finalValue = value ? jQuery.trim( cur ) : "";
|
||
if ( elem.className !== finalValue ) {
|
||
elem.className = finalValue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
toggleClass: function( value, stateVal ) {
|
||
var type = typeof value;
|
||
|
||
if ( typeof stateVal === "boolean" && type === "string" ) {
|
||
return stateVal ? this.addClass( value ) : this.removeClass( value );
|
||
}
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each(function( i ) {
|
||
jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
|
||
});
|
||
}
|
||
|
||
return this.each(function() {
|
||
if ( type === "string" ) {
|
||
// toggle individual class names
|
||
var className,
|
||
i = 0,
|
||
self = jQuery( this ),
|
||
classNames = value.match( rnotwhite ) || [];
|
||
|
||
while ( (className = classNames[ i++ ]) ) {
|
||
// check each className given, space separated list
|
||
if ( self.hasClass( className ) ) {
|
||
self.removeClass( className );
|
||
} else {
|
||
self.addClass( className );
|
||
}
|
||
}
|
||
|
||
// Toggle whole class name
|
||
} else if ( type === strundefined || type === "boolean" ) {
|
||
if ( this.className ) {
|
||
// store className if set
|
||
data_priv.set( this, "__className__", this.className );
|
||
}
|
||
|
||
// If the element has a class name or if we're passed "false",
|
||
// then remove the whole classname (if there was one, the above saved it).
|
||
// Otherwise bring back whatever was previously saved (if anything),
|
||
// falling back to the empty string if nothing was stored.
|
||
this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
|
||
}
|
||
});
|
||
},
|
||
|
||
hasClass: function( selector ) {
|
||
var className = " " + selector + " ",
|
||
i = 0,
|
||
l = this.length;
|
||
for ( ; i < l; i++ ) {
|
||
if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
var rreturn = /\r/g;
|
||
|
||
jQuery.fn.extend({
|
||
val: function( value ) {
|
||
var hooks, ret, isFunction,
|
||
elem = this[0];
|
||
|
||
if ( !arguments.length ) {
|
||
if ( elem ) {
|
||
hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
|
||
|
||
if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
|
||
return ret;
|
||
}
|
||
|
||
ret = elem.value;
|
||
|
||
return typeof ret === "string" ?
|
||
// handle most common string cases
|
||
ret.replace(rreturn, "") :
|
||
// handle cases where value is null/undef or number
|
||
ret == null ? "" : ret;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
isFunction = jQuery.isFunction( value );
|
||
|
||
return this.each(function( i ) {
|
||
var val;
|
||
|
||
if ( this.nodeType !== 1 ) {
|
||
return;
|
||
}
|
||
|
||
if ( isFunction ) {
|
||
val = value.call( this, i, jQuery( this ).val() );
|
||
} else {
|
||
val = value;
|
||
}
|
||
|
||
// Treat null/undefined as ""; convert numbers to string
|
||
if ( val == null ) {
|
||
val = "";
|
||
|
||
} else if ( typeof val === "number" ) {
|
||
val += "";
|
||
|
||
} else if ( jQuery.isArray( val ) ) {
|
||
val = jQuery.map( val, function( value ) {
|
||
return value == null ? "" : value + "";
|
||
});
|
||
}
|
||
|
||
hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
|
||
|
||
// If set returns undefined, fall back to normal setting
|
||
if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
|
||
this.value = val;
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.extend({
|
||
valHooks: {
|
||
option: {
|
||
get: function( elem ) {
|
||
var val = jQuery.find.attr( elem, "value" );
|
||
return val != null ?
|
||
val :
|
||
// Support: IE10-11+
|
||
// option.text throws exceptions (#14686, #14858)
|
||
jQuery.trim( jQuery.text( elem ) );
|
||
}
|
||
},
|
||
select: {
|
||
get: function( elem ) {
|
||
var value, option,
|
||
options = elem.options,
|
||
index = elem.selectedIndex,
|
||
one = elem.type === "select-one" || index < 0,
|
||
values = one ? null : [],
|
||
max = one ? index + 1 : options.length,
|
||
i = index < 0 ?
|
||
max :
|
||
one ? index : 0;
|
||
|
||
// Loop through all the selected options
|
||
for ( ; i < max; i++ ) {
|
||
option = options[ i ];
|
||
|
||
// IE6-9 doesn't update selected after form reset (#2551)
|
||
if ( ( option.selected || i === index ) &&
|
||
// Don't return options that are disabled or in a disabled optgroup
|
||
( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) &&
|
||
( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
|
||
|
||
// Get the specific value for the option
|
||
value = jQuery( option ).val();
|
||
|
||
// We don't need an array for one selects
|
||
if ( one ) {
|
||
return value;
|
||
}
|
||
|
||
// Multi-Selects return an array
|
||
values.push( value );
|
||
}
|
||
}
|
||
|
||
return values;
|
||
},
|
||
|
||
set: function( elem, value ) {
|
||
var optionSet, option,
|
||
options = elem.options,
|
||
values = jQuery.makeArray( value ),
|
||
i = options.length;
|
||
|
||
while ( i-- ) {
|
||
option = options[ i ];
|
||
if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) {
|
||
optionSet = true;
|
||
}
|
||
}
|
||
|
||
// force browsers to behave consistently when non-matching value is set
|
||
if ( !optionSet ) {
|
||
elem.selectedIndex = -1;
|
||
}
|
||
return values;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Radios and checkboxes getter/setter
|
||
jQuery.each([ "radio", "checkbox" ], function() {
|
||
jQuery.valHooks[ this ] = {
|
||
set: function( elem, value ) {
|
||
if ( jQuery.isArray( value ) ) {
|
||
return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
|
||
}
|
||
}
|
||
};
|
||
if ( !support.checkOn ) {
|
||
jQuery.valHooks[ this ].get = function( elem ) {
|
||
// Support: Webkit
|
||
// "" is returned instead of "on" if a value isn't specified
|
||
return elem.getAttribute("value") === null ? "on" : elem.value;
|
||
};
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
// Return jQuery for attributes-only inclusion
|
||
|
||
|
||
jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
|
||
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
|
||
"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
|
||
|
||
// Handle event binding
|
||
jQuery.fn[ name ] = function( data, fn ) {
|
||
return arguments.length > 0 ?
|
||
this.on( name, null, data, fn ) :
|
||
this.trigger( name );
|
||
};
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
hover: function( fnOver, fnOut ) {
|
||
return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
|
||
},
|
||
|
||
bind: function( types, data, fn ) {
|
||
return this.on( types, null, data, fn );
|
||
},
|
||
unbind: function( types, fn ) {
|
||
return this.off( types, null, fn );
|
||
},
|
||
|
||
delegate: function( selector, types, data, fn ) {
|
||
return this.on( types, selector, data, fn );
|
||
},
|
||
undelegate: function( selector, types, fn ) {
|
||
// ( namespace ) or ( selector, types [, fn] )
|
||
return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
|
||
}
|
||
});
|
||
|
||
|
||
var nonce = jQuery.now();
|
||
|
||
var rquery = (/\?/);
|
||
|
||
|
||
|
||
// Support: Android 2.3
|
||
// Workaround failure to string-cast null input
|
||
jQuery.parseJSON = function( data ) {
|
||
return JSON.parse( data + "" );
|
||
};
|
||
|
||
|
||
// Cross-browser xml parsing
|
||
jQuery.parseXML = function( data ) {
|
||
var xml, tmp;
|
||
if ( !data || typeof data !== "string" ) {
|
||
return null;
|
||
}
|
||
|
||
// Support: IE9
|
||
try {
|
||
tmp = new DOMParser();
|
||
xml = tmp.parseFromString( data, "text/xml" );
|
||
} catch ( e ) {
|
||
xml = undefined;
|
||
}
|
||
|
||
if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
|
||
jQuery.error( "Invalid XML: " + data );
|
||
}
|
||
return xml;
|
||
};
|
||
|
||
|
||
var
|
||
// Document location
|
||
ajaxLocParts,
|
||
ajaxLocation,
|
||
|
||
rhash = /#.*$/,
|
||
rts = /([?&])_=[^&]*/,
|
||
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
|
||
// #7653, #8125, #8152: local protocol detection
|
||
rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
|
||
rnoContent = /^(?:GET|HEAD)$/,
|
||
rprotocol = /^\/\//,
|
||
rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
|
||
|
||
/* Prefilters
|
||
* 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
|
||
* 2) These are called:
|
||
* - BEFORE asking for a transport
|
||
* - AFTER param serialization (s.data is a string if s.processData is true)
|
||
* 3) key is the dataType
|
||
* 4) the catchall symbol "*" can be used
|
||
* 5) execution will start with transport dataType and THEN continue down to "*" if needed
|
||
*/
|
||
prefilters = {},
|
||
|
||
/* Transports bindings
|
||
* 1) key is the dataType
|
||
* 2) the catchall symbol "*" can be used
|
||
* 3) selection will start with transport dataType and THEN go to "*" if needed
|
||
*/
|
||
transports = {},
|
||
|
||
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
|
||
allTypes = "*/".concat("*");
|
||
|
||
// #8138, IE may throw an exception when accessing
|
||
// a field from window.location if document.domain has been set
|
||
try {
|
||
ajaxLocation = location.href;
|
||
} catch( e ) {
|
||
// Use the href attribute of an A element
|
||
// since IE will modify it given document.location
|
||
ajaxLocation = document.createElement( "a" );
|
||
ajaxLocation.href = "";
|
||
ajaxLocation = ajaxLocation.href;
|
||
}
|
||
|
||
// Segment location into parts
|
||
ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
|
||
|
||
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
|
||
function addToPrefiltersOrTransports( structure ) {
|
||
|
||
// dataTypeExpression is optional and defaults to "*"
|
||
return function( dataTypeExpression, func ) {
|
||
|
||
if ( typeof dataTypeExpression !== "string" ) {
|
||
func = dataTypeExpression;
|
||
dataTypeExpression = "*";
|
||
}
|
||
|
||
var dataType,
|
||
i = 0,
|
||
dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
|
||
|
||
if ( jQuery.isFunction( func ) ) {
|
||
// For each dataType in the dataTypeExpression
|
||
while ( (dataType = dataTypes[i++]) ) {
|
||
// Prepend if requested
|
||
if ( dataType[0] === "+" ) {
|
||
dataType = dataType.slice( 1 ) || "*";
|
||
(structure[ dataType ] = structure[ dataType ] || []).unshift( func );
|
||
|
||
// Otherwise append
|
||
} else {
|
||
(structure[ dataType ] = structure[ dataType ] || []).push( func );
|
||
}
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
// Base inspection function for prefilters and transports
|
||
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
|
||
|
||
var inspected = {},
|
||
seekingTransport = ( structure === transports );
|
||
|
||
function inspect( dataType ) {
|
||
var selected;
|
||
inspected[ dataType ] = true;
|
||
jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
|
||
var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
|
||
if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
|
||
options.dataTypes.unshift( dataTypeOrTransport );
|
||
inspect( dataTypeOrTransport );
|
||
return false;
|
||
} else if ( seekingTransport ) {
|
||
return !( selected = dataTypeOrTransport );
|
||
}
|
||
});
|
||
return selected;
|
||
}
|
||
|
||
return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
|
||
}
|
||
|
||
// A special extend for ajax options
|
||
// that takes "flat" options (not to be deep extended)
|
||
// Fixes #9887
|
||
function ajaxExtend( target, src ) {
|
||
var key, deep,
|
||
flatOptions = jQuery.ajaxSettings.flatOptions || {};
|
||
|
||
for ( key in src ) {
|
||
if ( src[ key ] !== undefined ) {
|
||
( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
|
||
}
|
||
}
|
||
if ( deep ) {
|
||
jQuery.extend( true, target, deep );
|
||
}
|
||
|
||
return target;
|
||
}
|
||
|
||
/* Handles responses to an ajax request:
|
||
* - finds the right dataType (mediates between content-type and expected dataType)
|
||
* - returns the corresponding response
|
||
*/
|
||
function ajaxHandleResponses( s, jqXHR, responses ) {
|
||
|
||
var ct, type, finalDataType, firstDataType,
|
||
contents = s.contents,
|
||
dataTypes = s.dataTypes;
|
||
|
||
// Remove auto dataType and get content-type in the process
|
||
while ( dataTypes[ 0 ] === "*" ) {
|
||
dataTypes.shift();
|
||
if ( ct === undefined ) {
|
||
ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
|
||
}
|
||
}
|
||
|
||
// Check if we're dealing with a known content-type
|
||
if ( ct ) {
|
||
for ( type in contents ) {
|
||
if ( contents[ type ] && contents[ type ].test( ct ) ) {
|
||
dataTypes.unshift( type );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Check to see if we have a response for the expected dataType
|
||
if ( dataTypes[ 0 ] in responses ) {
|
||
finalDataType = dataTypes[ 0 ];
|
||
} else {
|
||
// Try convertible dataTypes
|
||
for ( type in responses ) {
|
||
if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
|
||
finalDataType = type;
|
||
break;
|
||
}
|
||
if ( !firstDataType ) {
|
||
firstDataType = type;
|
||
}
|
||
}
|
||
// Or just use first one
|
||
finalDataType = finalDataType || firstDataType;
|
||
}
|
||
|
||
// If we found a dataType
|
||
// We add the dataType to the list if needed
|
||
// and return the corresponding response
|
||
if ( finalDataType ) {
|
||
if ( finalDataType !== dataTypes[ 0 ] ) {
|
||
dataTypes.unshift( finalDataType );
|
||
}
|
||
return responses[ finalDataType ];
|
||
}
|
||
}
|
||
|
||
/* Chain conversions given the request and the original response
|
||
* Also sets the responseXXX fields on the jqXHR instance
|
||
*/
|
||
function ajaxConvert( s, response, jqXHR, isSuccess ) {
|
||
var conv2, current, conv, tmp, prev,
|
||
converters = {},
|
||
// Work with a copy of dataTypes in case we need to modify it for conversion
|
||
dataTypes = s.dataTypes.slice();
|
||
|
||
// Create converters map with lowercased keys
|
||
if ( dataTypes[ 1 ] ) {
|
||
for ( conv in s.converters ) {
|
||
converters[ conv.toLowerCase() ] = s.converters[ conv ];
|
||
}
|
||
}
|
||
|
||
current = dataTypes.shift();
|
||
|
||
// Convert to each sequential dataType
|
||
while ( current ) {
|
||
|
||
if ( s.responseFields[ current ] ) {
|
||
jqXHR[ s.responseFields[ current ] ] = response;
|
||
}
|
||
|
||
// Apply the dataFilter if provided
|
||
if ( !prev && isSuccess && s.dataFilter ) {
|
||
response = s.dataFilter( response, s.dataType );
|
||
}
|
||
|
||
prev = current;
|
||
current = dataTypes.shift();
|
||
|
||
if ( current ) {
|
||
|
||
// There's only work to do if current dataType is non-auto
|
||
if ( current === "*" ) {
|
||
|
||
current = prev;
|
||
|
||
// Convert response if prev dataType is non-auto and differs from current
|
||
} else if ( prev !== "*" && prev !== current ) {
|
||
|
||
// Seek a direct converter
|
||
conv = converters[ prev + " " + current ] || converters[ "* " + current ];
|
||
|
||
// If none found, seek a pair
|
||
if ( !conv ) {
|
||
for ( conv2 in converters ) {
|
||
|
||
// If conv2 outputs current
|
||
tmp = conv2.split( " " );
|
||
if ( tmp[ 1 ] === current ) {
|
||
|
||
// If prev can be converted to accepted input
|
||
conv = converters[ prev + " " + tmp[ 0 ] ] ||
|
||
converters[ "* " + tmp[ 0 ] ];
|
||
if ( conv ) {
|
||
// Condense equivalence converters
|
||
if ( conv === true ) {
|
||
conv = converters[ conv2 ];
|
||
|
||
// Otherwise, insert the intermediate dataType
|
||
} else if ( converters[ conv2 ] !== true ) {
|
||
current = tmp[ 0 ];
|
||
dataTypes.unshift( tmp[ 1 ] );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Apply converter (if not an equivalence)
|
||
if ( conv !== true ) {
|
||
|
||
// Unless errors are allowed to bubble, catch and return them
|
||
if ( conv && s[ "throws" ] ) {
|
||
response = conv( response );
|
||
} else {
|
||
try {
|
||
response = conv( response );
|
||
} catch ( e ) {
|
||
return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return { state: "success", data: response };
|
||
}
|
||
|
||
jQuery.extend({
|
||
|
||
// Counter for holding the number of active queries
|
||
active: 0,
|
||
|
||
// Last-Modified header cache for next request
|
||
lastModified: {},
|
||
etag: {},
|
||
|
||
ajaxSettings: {
|
||
url: ajaxLocation,
|
||
type: "GET",
|
||
isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
|
||
global: true,
|
||
processData: true,
|
||
async: true,
|
||
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
|
||
/*
|
||
timeout: 0,
|
||
data: null,
|
||
dataType: null,
|
||
username: null,
|
||
password: null,
|
||
cache: null,
|
||
throws: false,
|
||
traditional: false,
|
||
headers: {},
|
||
*/
|
||
|
||
accepts: {
|
||
"*": allTypes,
|
||
text: "text/plain",
|
||
html: "text/html",
|
||
xml: "application/xml, text/xml",
|
||
json: "application/json, text/javascript"
|
||
},
|
||
|
||
contents: {
|
||
xml: /xml/,
|
||
html: /html/,
|
||
json: /json/
|
||
},
|
||
|
||
responseFields: {
|
||
xml: "responseXML",
|
||
text: "responseText",
|
||
json: "responseJSON"
|
||
},
|
||
|
||
// Data converters
|
||
// Keys separate source (or catchall "*") and destination types with a single space
|
||
converters: {
|
||
|
||
// Convert anything to text
|
||
"* text": String,
|
||
|
||
// Text to html (true = no transformation)
|
||
"text html": true,
|
||
|
||
// Evaluate text as a json expression
|
||
"text json": jQuery.parseJSON,
|
||
|
||
// Parse text as xml
|
||
"text xml": jQuery.parseXML
|
||
},
|
||
|
||
// For options that shouldn't be deep extended:
|
||
// you can add your own custom options here if
|
||
// and when you create one that shouldn't be
|
||
// deep extended (see ajaxExtend)
|
||
flatOptions: {
|
||
url: true,
|
||
context: true
|
||
}
|
||
},
|
||
|
||
// Creates a full fledged settings object into target
|
||
// with both ajaxSettings and settings fields.
|
||
// If target is omitted, writes into ajaxSettings.
|
||
ajaxSetup: function( target, settings ) {
|
||
return settings ?
|
||
|
||
// Building a settings object
|
||
ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
|
||
|
||
// Extending ajaxSettings
|
||
ajaxExtend( jQuery.ajaxSettings, target );
|
||
},
|
||
|
||
ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
|
||
ajaxTransport: addToPrefiltersOrTransports( transports ),
|
||
|
||
// Main method
|
||
ajax: function( url, options ) {
|
||
|
||
// If url is an object, simulate pre-1.5 signature
|
||
if ( typeof url === "object" ) {
|
||
options = url;
|
||
url = undefined;
|
||
}
|
||
|
||
// Force options to be an object
|
||
options = options || {};
|
||
|
||
var transport,
|
||
// URL without anti-cache param
|
||
cacheURL,
|
||
// Response headers
|
||
responseHeadersString,
|
||
responseHeaders,
|
||
// timeout handle
|
||
timeoutTimer,
|
||
// Cross-domain detection vars
|
||
parts,
|
||
// To know if global events are to be dispatched
|
||
fireGlobals,
|
||
// Loop variable
|
||
i,
|
||
// Create the final options object
|
||
s = jQuery.ajaxSetup( {}, options ),
|
||
// Callbacks context
|
||
callbackContext = s.context || s,
|
||
// Context for global events is callbackContext if it is a DOM node or jQuery collection
|
||
globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
|
||
jQuery( callbackContext ) :
|
||
jQuery.event,
|
||
// Deferreds
|
||
deferred = jQuery.Deferred(),
|
||
completeDeferred = jQuery.Callbacks("once memory"),
|
||
// Status-dependent callbacks
|
||
statusCode = s.statusCode || {},
|
||
// Headers (they are sent all at once)
|
||
requestHeaders = {},
|
||
requestHeadersNames = {},
|
||
// The jqXHR state
|
||
state = 0,
|
||
// Default abort message
|
||
strAbort = "canceled",
|
||
// Fake xhr
|
||
jqXHR = {
|
||
readyState: 0,
|
||
|
||
// Builds headers hashtable if needed
|
||
getResponseHeader: function( key ) {
|
||
var match;
|
||
if ( state === 2 ) {
|
||
if ( !responseHeaders ) {
|
||
responseHeaders = {};
|
||
while ( (match = rheaders.exec( responseHeadersString )) ) {
|
||
responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
|
||
}
|
||
}
|
||
match = responseHeaders[ key.toLowerCase() ];
|
||
}
|
||
return match == null ? null : match;
|
||
},
|
||
|
||
// Raw string
|
||
getAllResponseHeaders: function() {
|
||
return state === 2 ? responseHeadersString : null;
|
||
},
|
||
|
||
// Caches the header
|
||
setRequestHeader: function( name, value ) {
|
||
var lname = name.toLowerCase();
|
||
if ( !state ) {
|
||
name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
|
||
requestHeaders[ name ] = value;
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Overrides response content-type header
|
||
overrideMimeType: function( type ) {
|
||
if ( !state ) {
|
||
s.mimeType = type;
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Status-dependent callbacks
|
||
statusCode: function( map ) {
|
||
var code;
|
||
if ( map ) {
|
||
if ( state < 2 ) {
|
||
for ( code in map ) {
|
||
// Lazy-add the new callback in a way that preserves old ones
|
||
statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
|
||
}
|
||
} else {
|
||
// Execute the appropriate callbacks
|
||
jqXHR.always( map[ jqXHR.status ] );
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Cancel the request
|
||
abort: function( statusText ) {
|
||
var finalText = statusText || strAbort;
|
||
if ( transport ) {
|
||
transport.abort( finalText );
|
||
}
|
||
done( 0, finalText );
|
||
return this;
|
||
}
|
||
};
|
||
|
||
// Attach deferreds
|
||
deferred.promise( jqXHR ).complete = completeDeferred.add;
|
||
jqXHR.success = jqXHR.done;
|
||
jqXHR.error = jqXHR.fail;
|
||
|
||
// Remove hash character (#7531: and string promotion)
|
||
// Add protocol if not provided (prefilters might expect it)
|
||
// Handle falsy url in the settings object (#10093: consistency with old signature)
|
||
// We also use the url parameter if available
|
||
s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
|
||
.replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
|
||
|
||
// Alias method option to type as per ticket #12004
|
||
s.type = options.method || options.type || s.method || s.type;
|
||
|
||
// Extract dataTypes list
|
||
s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
|
||
|
||
// A cross-domain request is in order when we have a protocol:host:port mismatch
|
||
if ( s.crossDomain == null ) {
|
||
parts = rurl.exec( s.url.toLowerCase() );
|
||
s.crossDomain = !!( parts &&
|
||
( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
|
||
( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
|
||
( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
|
||
);
|
||
}
|
||
|
||
// Convert data if not already a string
|
||
if ( s.data && s.processData && typeof s.data !== "string" ) {
|
||
s.data = jQuery.param( s.data, s.traditional );
|
||
}
|
||
|
||
// Apply prefilters
|
||
inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
|
||
|
||
// If request was aborted inside a prefilter, stop there
|
||
if ( state === 2 ) {
|
||
return jqXHR;
|
||
}
|
||
|
||
// We can fire global events as of now if asked to
|
||
fireGlobals = s.global;
|
||
|
||
// Watch for a new set of requests
|
||
if ( fireGlobals && jQuery.active++ === 0 ) {
|
||
jQuery.event.trigger("ajaxStart");
|
||
}
|
||
|
||
// Uppercase the type
|
||
s.type = s.type.toUpperCase();
|
||
|
||
// Determine if request has content
|
||
s.hasContent = !rnoContent.test( s.type );
|
||
|
||
// Save the URL in case we're toying with the If-Modified-Since
|
||
// and/or If-None-Match header later on
|
||
cacheURL = s.url;
|
||
|
||
// More options handling for requests with no content
|
||
if ( !s.hasContent ) {
|
||
|
||
// If data is available, append data to url
|
||
if ( s.data ) {
|
||
cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
|
||
// #9682: remove data so that it's not used in an eventual retry
|
||
delete s.data;
|
||
}
|
||
|
||
// Add anti-cache in url if needed
|
||
if ( s.cache === false ) {
|
||
s.url = rts.test( cacheURL ) ?
|
||
|
||
// If there is already a '_' parameter, set its value
|
||
cacheURL.replace( rts, "$1_=" + nonce++ ) :
|
||
|
||
// Otherwise add one to the end
|
||
cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
|
||
}
|
||
}
|
||
|
||
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
||
if ( s.ifModified ) {
|
||
if ( jQuery.lastModified[ cacheURL ] ) {
|
||
jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
|
||
}
|
||
if ( jQuery.etag[ cacheURL ] ) {
|
||
jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
|
||
}
|
||
}
|
||
|
||
// Set the correct header, if data is being sent
|
||
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
|
||
jqXHR.setRequestHeader( "Content-Type", s.contentType );
|
||
}
|
||
|
||
// Set the Accepts header for the server, depending on the dataType
|
||
jqXHR.setRequestHeader(
|
||
"Accept",
|
||
s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
|
||
s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
|
||
s.accepts[ "*" ]
|
||
);
|
||
|
||
// Check for headers option
|
||
for ( i in s.headers ) {
|
||
jqXHR.setRequestHeader( i, s.headers[ i ] );
|
||
}
|
||
|
||
// Allow custom headers/mimetypes and early abort
|
||
if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
|
||
// Abort if not done already and return
|
||
return jqXHR.abort();
|
||
}
|
||
|
||
// aborting is no longer a cancellation
|
||
strAbort = "abort";
|
||
|
||
// Install callbacks on deferreds
|
||
for ( i in { success: 1, error: 1, complete: 1 } ) {
|
||
jqXHR[ i ]( s[ i ] );
|
||
}
|
||
|
||
// Get transport
|
||
transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
|
||
|
||
// If no transport, we auto-abort
|
||
if ( !transport ) {
|
||
done( -1, "No Transport" );
|
||
} else {
|
||
jqXHR.readyState = 1;
|
||
|
||
// Send global event
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
|
||
}
|
||
// Timeout
|
||
if ( s.async && s.timeout > 0 ) {
|
||
timeoutTimer = setTimeout(function() {
|
||
jqXHR.abort("timeout");
|
||
}, s.timeout );
|
||
}
|
||
|
||
try {
|
||
state = 1;
|
||
transport.send( requestHeaders, done );
|
||
} catch ( e ) {
|
||
// Propagate exception as error if not done
|
||
if ( state < 2 ) {
|
||
done( -1, e );
|
||
// Simply rethrow otherwise
|
||
} else {
|
||
throw e;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Callback for when everything is done
|
||
function done( status, nativeStatusText, responses, headers ) {
|
||
var isSuccess, success, error, response, modified,
|
||
statusText = nativeStatusText;
|
||
|
||
// Called once
|
||
if ( state === 2 ) {
|
||
return;
|
||
}
|
||
|
||
// State is "done" now
|
||
state = 2;
|
||
|
||
// Clear timeout if it exists
|
||
if ( timeoutTimer ) {
|
||
clearTimeout( timeoutTimer );
|
||
}
|
||
|
||
// Dereference transport for early garbage collection
|
||
// (no matter how long the jqXHR object will be used)
|
||
transport = undefined;
|
||
|
||
// Cache response headers
|
||
responseHeadersString = headers || "";
|
||
|
||
// Set readyState
|
||
jqXHR.readyState = status > 0 ? 4 : 0;
|
||
|
||
// Determine if successful
|
||
isSuccess = status >= 200 && status < 300 || status === 304;
|
||
|
||
// Get response data
|
||
if ( responses ) {
|
||
response = ajaxHandleResponses( s, jqXHR, responses );
|
||
}
|
||
|
||
// Convert no matter what (that way responseXXX fields are always set)
|
||
response = ajaxConvert( s, response, jqXHR, isSuccess );
|
||
|
||
// If successful, handle type chaining
|
||
if ( isSuccess ) {
|
||
|
||
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
||
if ( s.ifModified ) {
|
||
modified = jqXHR.getResponseHeader("Last-Modified");
|
||
if ( modified ) {
|
||
jQuery.lastModified[ cacheURL ] = modified;
|
||
}
|
||
modified = jqXHR.getResponseHeader("etag");
|
||
if ( modified ) {
|
||
jQuery.etag[ cacheURL ] = modified;
|
||
}
|
||
}
|
||
|
||
// if no content
|
||
if ( status === 204 || s.type === "HEAD" ) {
|
||
statusText = "nocontent";
|
||
|
||
// if not modified
|
||
} else if ( status === 304 ) {
|
||
statusText = "notmodified";
|
||
|
||
// If we have data, let's convert it
|
||
} else {
|
||
statusText = response.state;
|
||
success = response.data;
|
||
error = response.error;
|
||
isSuccess = !error;
|
||
}
|
||
} else {
|
||
// We extract error from statusText
|
||
// then normalize statusText and status for non-aborts
|
||
error = statusText;
|
||
if ( status || !statusText ) {
|
||
statusText = "error";
|
||
if ( status < 0 ) {
|
||
status = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Set data for the fake xhr object
|
||
jqXHR.status = status;
|
||
jqXHR.statusText = ( nativeStatusText || statusText ) + "";
|
||
|
||
// Success/Error
|
||
if ( isSuccess ) {
|
||
deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
|
||
} else {
|
||
deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
|
||
}
|
||
|
||
// Status-dependent callbacks
|
||
jqXHR.statusCode( statusCode );
|
||
statusCode = undefined;
|
||
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
|
||
[ jqXHR, s, isSuccess ? success : error ] );
|
||
}
|
||
|
||
// Complete
|
||
completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
|
||
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
|
||
// Handle the global AJAX counter
|
||
if ( !( --jQuery.active ) ) {
|
||
jQuery.event.trigger("ajaxStop");
|
||
}
|
||
}
|
||
}
|
||
|
||
return jqXHR;
|
||
},
|
||
|
||
getJSON: function( url, data, callback ) {
|
||
return jQuery.get( url, data, callback, "json" );
|
||
},
|
||
|
||
getScript: function( url, callback ) {
|
||
return jQuery.get( url, undefined, callback, "script" );
|
||
}
|
||
});
|
||
|
||
jQuery.each( [ "get", "post" ], function( i, method ) {
|
||
jQuery[ method ] = function( url, data, callback, type ) {
|
||
// shift arguments if data argument was omitted
|
||
if ( jQuery.isFunction( data ) ) {
|
||
type = type || callback;
|
||
callback = data;
|
||
data = undefined;
|
||
}
|
||
|
||
return jQuery.ajax({
|
||
url: url,
|
||
type: method,
|
||
dataType: type,
|
||
data: data,
|
||
success: callback
|
||
});
|
||
};
|
||
});
|
||
|
||
// Attach a bunch of functions for handling common AJAX events
|
||
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
|
||
jQuery.fn[ type ] = function( fn ) {
|
||
return this.on( type, fn );
|
||
};
|
||
});
|
||
|
||
|
||
jQuery._evalUrl = function( url ) {
|
||
return jQuery.ajax({
|
||
url: url,
|
||
type: "GET",
|
||
dataType: "script",
|
||
async: false,
|
||
global: false,
|
||
"throws": true
|
||
});
|
||
};
|
||
|
||
|
||
jQuery.fn.extend({
|
||
wrapAll: function( html ) {
|
||
var wrap;
|
||
|
||
if ( jQuery.isFunction( html ) ) {
|
||
return this.each(function( i ) {
|
||
jQuery( this ).wrapAll( html.call(this, i) );
|
||
});
|
||
}
|
||
|
||
if ( this[ 0 ] ) {
|
||
|
||
// The elements to wrap the target around
|
||
wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
|
||
|
||
if ( this[ 0 ].parentNode ) {
|
||
wrap.insertBefore( this[ 0 ] );
|
||
}
|
||
|
||
wrap.map(function() {
|
||
var elem = this;
|
||
|
||
while ( elem.firstElementChild ) {
|
||
elem = elem.firstElementChild;
|
||
}
|
||
|
||
return elem;
|
||
}).append( this );
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
wrapInner: function( html ) {
|
||
if ( jQuery.isFunction( html ) ) {
|
||
return this.each(function( i ) {
|
||
jQuery( this ).wrapInner( html.call(this, i) );
|
||
});
|
||
}
|
||
|
||
return this.each(function() {
|
||
var self = jQuery( this ),
|
||
contents = self.contents();
|
||
|
||
if ( contents.length ) {
|
||
contents.wrapAll( html );
|
||
|
||
} else {
|
||
self.append( html );
|
||
}
|
||
});
|
||
},
|
||
|
||
wrap: function( html ) {
|
||
var isFunction = jQuery.isFunction( html );
|
||
|
||
return this.each(function( i ) {
|
||
jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
|
||
});
|
||
},
|
||
|
||
unwrap: function() {
|
||
return this.parent().each(function() {
|
||
if ( !jQuery.nodeName( this, "body" ) ) {
|
||
jQuery( this ).replaceWith( this.childNodes );
|
||
}
|
||
}).end();
|
||
}
|
||
});
|
||
|
||
|
||
jQuery.expr.filters.hidden = function( elem ) {
|
||
// Support: Opera <= 12.12
|
||
// Opera reports offsetWidths and offsetHeights less than zero on some elements
|
||
return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
|
||
};
|
||
jQuery.expr.filters.visible = function( elem ) {
|
||
return !jQuery.expr.filters.hidden( elem );
|
||
};
|
||
|
||
|
||
|
||
|
||
var r20 = /%20/g,
|
||
rbracket = /\[\]$/,
|
||
rCRLF = /\r?\n/g,
|
||
rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
|
||
rsubmittable = /^(?:input|select|textarea|keygen)/i;
|
||
|
||
function buildParams( prefix, obj, traditional, add ) {
|
||
var name;
|
||
|
||
if ( jQuery.isArray( obj ) ) {
|
||
// Serialize array item.
|
||
jQuery.each( obj, function( i, v ) {
|
||
if ( traditional || rbracket.test( prefix ) ) {
|
||
// Treat each array item as a scalar.
|
||
add( prefix, v );
|
||
|
||
} else {
|
||
// Item is non-scalar (array or object), encode its numeric index.
|
||
buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
|
||
}
|
||
});
|
||
|
||
} else if ( !traditional && jQuery.type( obj ) === "object" ) {
|
||
// Serialize object item.
|
||
for ( name in obj ) {
|
||
buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
|
||
}
|
||
|
||
} else {
|
||
// Serialize scalar item.
|
||
add( prefix, obj );
|
||
}
|
||
}
|
||
|
||
// Serialize an array of form elements or a set of
|
||
// key/values into a query string
|
||
jQuery.param = function( a, traditional ) {
|
||
var prefix,
|
||
s = [],
|
||
add = function( key, value ) {
|
||
// If value is a function, invoke it and return its value
|
||
value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
|
||
s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
|
||
};
|
||
|
||
// Set traditional to true for jQuery <= 1.3.2 behavior.
|
||
if ( traditional === undefined ) {
|
||
traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
|
||
}
|
||
|
||
// If an array was passed in, assume that it is an array of form elements.
|
||
if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
|
||
// Serialize the form elements
|
||
jQuery.each( a, function() {
|
||
add( this.name, this.value );
|
||
});
|
||
|
||
} else {
|
||
// If traditional, encode the "old" way (the way 1.3.2 or older
|
||
// did it), otherwise encode params recursively.
|
||
for ( prefix in a ) {
|
||
buildParams( prefix, a[ prefix ], traditional, add );
|
||
}
|
||
}
|
||
|
||
// Return the resulting serialization
|
||
return s.join( "&" ).replace( r20, "+" );
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
serialize: function() {
|
||
return jQuery.param( this.serializeArray() );
|
||
},
|
||
serializeArray: function() {
|
||
return this.map(function() {
|
||
// Can add propHook for "elements" to filter or add form elements
|
||
var elements = jQuery.prop( this, "elements" );
|
||
return elements ? jQuery.makeArray( elements ) : this;
|
||
})
|
||
.filter(function() {
|
||
var type = this.type;
|
||
|
||
// Use .is( ":disabled" ) so that fieldset[disabled] works
|
||
return this.name && !jQuery( this ).is( ":disabled" ) &&
|
||
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
|
||
( this.checked || !rcheckableType.test( type ) );
|
||
})
|
||
.map(function( i, elem ) {
|
||
var val = jQuery( this ).val();
|
||
|
||
return val == null ?
|
||
null :
|
||
jQuery.isArray( val ) ?
|
||
jQuery.map( val, function( val ) {
|
||
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
|
||
}) :
|
||
{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
|
||
}).get();
|
||
}
|
||
});
|
||
|
||
|
||
jQuery.ajaxSettings.xhr = function() {
|
||
try {
|
||
return new XMLHttpRequest();
|
||
} catch( e ) {}
|
||
};
|
||
|
||
var xhrId = 0,
|
||
xhrCallbacks = {},
|
||
xhrSuccessStatus = {
|
||
// file protocol always yields status code 0, assume 200
|
||
0: 200,
|
||
// Support: IE9
|
||
// #1450: sometimes IE returns 1223 when it should be 204
|
||
1223: 204
|
||
},
|
||
xhrSupported = jQuery.ajaxSettings.xhr();
|
||
|
||
// Support: IE9
|
||
// Open requests must be manually aborted on unload (#5280)
|
||
if ( window.ActiveXObject ) {
|
||
jQuery( window ).on( "unload", function() {
|
||
for ( var key in xhrCallbacks ) {
|
||
xhrCallbacks[ key ]();
|
||
}
|
||
});
|
||
}
|
||
|
||
support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
|
||
support.ajax = xhrSupported = !!xhrSupported;
|
||
|
||
jQuery.ajaxTransport(function( options ) {
|
||
var callback;
|
||
|
||
// Cross domain only allowed if supported through XMLHttpRequest
|
||
if ( support.cors || xhrSupported && !options.crossDomain ) {
|
||
return {
|
||
send: function( headers, complete ) {
|
||
var i,
|
||
xhr = options.xhr(),
|
||
id = ++xhrId;
|
||
|
||
xhr.open( options.type, options.url, options.async, options.username, options.password );
|
||
|
||
// Apply custom fields if provided
|
||
if ( options.xhrFields ) {
|
||
for ( i in options.xhrFields ) {
|
||
xhr[ i ] = options.xhrFields[ i ];
|
||
}
|
||
}
|
||
|
||
// Override mime type if needed
|
||
if ( options.mimeType && xhr.overrideMimeType ) {
|
||
xhr.overrideMimeType( options.mimeType );
|
||
}
|
||
|
||
// X-Requested-With header
|
||
// For cross-domain requests, seeing as conditions for a preflight are
|
||
// akin to a jigsaw puzzle, we simply never set it to be sure.
|
||
// (it can always be set on a per-request basis or even using ajaxSetup)
|
||
// For same-domain requests, won't change header if already provided.
|
||
if ( !options.crossDomain && !headers["X-Requested-With"] ) {
|
||
headers["X-Requested-With"] = "XMLHttpRequest";
|
||
}
|
||
|
||
// Set headers
|
||
for ( i in headers ) {
|
||
xhr.setRequestHeader( i, headers[ i ] );
|
||
}
|
||
|
||
// Callback
|
||
callback = function( type ) {
|
||
return function() {
|
||
if ( callback ) {
|
||
delete xhrCallbacks[ id ];
|
||
callback = xhr.onload = xhr.onerror = null;
|
||
|
||
if ( type === "abort" ) {
|
||
xhr.abort();
|
||
} else if ( type === "error" ) {
|
||
complete(
|
||
// file: protocol always yields status 0; see #8605, #14207
|
||
xhr.status,
|
||
xhr.statusText
|
||
);
|
||
} else {
|
||
complete(
|
||
xhrSuccessStatus[ xhr.status ] || xhr.status,
|
||
xhr.statusText,
|
||
// Support: IE9
|
||
// Accessing binary-data responseText throws an exception
|
||
// (#11426)
|
||
typeof xhr.responseText === "string" ? {
|
||
text: xhr.responseText
|
||
} : undefined,
|
||
xhr.getAllResponseHeaders()
|
||
);
|
||
}
|
||
}
|
||
};
|
||
};
|
||
|
||
// Listen to events
|
||
xhr.onload = callback();
|
||
xhr.onerror = callback("error");
|
||
|
||
// Create the abort callback
|
||
callback = xhrCallbacks[ id ] = callback("abort");
|
||
|
||
try {
|
||
// Do send the request (this may raise an exception)
|
||
xhr.send( options.hasContent && options.data || null );
|
||
} catch ( e ) {
|
||
// #14683: Only rethrow if this hasn't been notified as an error yet
|
||
if ( callback ) {
|
||
throw e;
|
||
}
|
||
}
|
||
},
|
||
|
||
abort: function() {
|
||
if ( callback ) {
|
||
callback();
|
||
}
|
||
}
|
||
};
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
// Install script dataType
|
||
jQuery.ajaxSetup({
|
||
accepts: {
|
||
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
|
||
},
|
||
contents: {
|
||
script: /(?:java|ecma)script/
|
||
},
|
||
converters: {
|
||
"text script": function( text ) {
|
||
jQuery.globalEval( text );
|
||
return text;
|
||
}
|
||
}
|
||
});
|
||
|
||
// Handle cache's special case and crossDomain
|
||
jQuery.ajaxPrefilter( "script", function( s ) {
|
||
if ( s.cache === undefined ) {
|
||
s.cache = false;
|
||
}
|
||
if ( s.crossDomain ) {
|
||
s.type = "GET";
|
||
}
|
||
});
|
||
|
||
// Bind script tag hack transport
|
||
jQuery.ajaxTransport( "script", function( s ) {
|
||
// This transport only deals with cross domain requests
|
||
if ( s.crossDomain ) {
|
||
var script, callback;
|
||
return {
|
||
send: function( _, complete ) {
|
||
script = jQuery("<script>").prop({
|
||
async: true,
|
||
charset: s.scriptCharset,
|
||
src: s.url
|
||
}).on(
|
||
"load error",
|
||
callback = function( evt ) {
|
||
script.remove();
|
||
callback = null;
|
||
if ( evt ) {
|
||
complete( evt.type === "error" ? 404 : 200, evt.type );
|
||
}
|
||
}
|
||
);
|
||
document.head.appendChild( script[ 0 ] );
|
||
},
|
||
abort: function() {
|
||
if ( callback ) {
|
||
callback();
|
||
}
|
||
}
|
||
};
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
var oldCallbacks = [],
|
||
rjsonp = /(=)\?(?=&|$)|\?\?/;
|
||
|
||
// Default jsonp settings
|
||
jQuery.ajaxSetup({
|
||
jsonp: "callback",
|
||
jsonpCallback: function() {
|
||
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
|
||
this[ callback ] = true;
|
||
return callback;
|
||
}
|
||
});
|
||
|
||
// Detect, normalize options and install callbacks for jsonp requests
|
||
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
|
||
|
||
var callbackName, overwritten, responseContainer,
|
||
jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
|
||
"url" :
|
||
typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
|
||
);
|
||
|
||
// Handle iff the expected data type is "jsonp" or we have a parameter to set
|
||
if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
|
||
|
||
// Get callback name, remembering preexisting value associated with it
|
||
callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
|
||
s.jsonpCallback() :
|
||
s.jsonpCallback;
|
||
|
||
// Insert callback into url or form data
|
||
if ( jsonProp ) {
|
||
s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
|
||
} else if ( s.jsonp !== false ) {
|
||
s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
|
||
}
|
||
|
||
// Use data converter to retrieve json after script execution
|
||
s.converters["script json"] = function() {
|
||
if ( !responseContainer ) {
|
||
jQuery.error( callbackName + " was not called" );
|
||
}
|
||
return responseContainer[ 0 ];
|
||
};
|
||
|
||
// force json dataType
|
||
s.dataTypes[ 0 ] = "json";
|
||
|
||
// Install callback
|
||
overwritten = window[ callbackName ];
|
||
window[ callbackName ] = function() {
|
||
responseContainer = arguments;
|
||
};
|
||
|
||
// Clean-up function (fires after converters)
|
||
jqXHR.always(function() {
|
||
// Restore preexisting value
|
||
window[ callbackName ] = overwritten;
|
||
|
||
// Save back as free
|
||
if ( s[ callbackName ] ) {
|
||
// make sure that re-using the options doesn't screw things around
|
||
s.jsonpCallback = originalSettings.jsonpCallback;
|
||
|
||
// save the callback name for future use
|
||
oldCallbacks.push( callbackName );
|
||
}
|
||
|
||
// Call if it was a function and we have a response
|
||
if ( responseContainer && jQuery.isFunction( overwritten ) ) {
|
||
overwritten( responseContainer[ 0 ] );
|
||
}
|
||
|
||
responseContainer = overwritten = undefined;
|
||
});
|
||
|
||
// Delegate to script
|
||
return "script";
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
// data: string of html
|
||
// context (optional): If specified, the fragment will be created in this context, defaults to document
|
||
// keepScripts (optional): If true, will include scripts passed in the html string
|
||
jQuery.parseHTML = function( data, context, keepScripts ) {
|
||
if ( !data || typeof data !== "string" ) {
|
||
return null;
|
||
}
|
||
if ( typeof context === "boolean" ) {
|
||
keepScripts = context;
|
||
context = false;
|
||
}
|
||
context = context || document;
|
||
|
||
var parsed = rsingleTag.exec( data ),
|
||
scripts = !keepScripts && [];
|
||
|
||
// Single tag
|
||
if ( parsed ) {
|
||
return [ context.createElement( parsed[1] ) ];
|
||
}
|
||
|
||
parsed = jQuery.buildFragment( [ data ], context, scripts );
|
||
|
||
if ( scripts && scripts.length ) {
|
||
jQuery( scripts ).remove();
|
||
}
|
||
|
||
return jQuery.merge( [], parsed.childNodes );
|
||
};
|
||
|
||
|
||
// Keep a copy of the old load method
|
||
var _load = jQuery.fn.load;
|
||
|
||
/**
|
||
* Load a url into a page
|
||
*/
|
||
jQuery.fn.load = function( url, params, callback ) {
|
||
if ( typeof url !== "string" && _load ) {
|
||
return _load.apply( this, arguments );
|
||
}
|
||
|
||
var selector, type, response,
|
||
self = this,
|
||
off = url.indexOf(" ");
|
||
|
||
if ( off >= 0 ) {
|
||
selector = jQuery.trim( url.slice( off ) );
|
||
url = url.slice( 0, off );
|
||
}
|
||
|
||
// If it's a function
|
||
if ( jQuery.isFunction( params ) ) {
|
||
|
||
// We assume that it's the callback
|
||
callback = params;
|
||
params = undefined;
|
||
|
||
// Otherwise, build a param string
|
||
} else if ( params && typeof params === "object" ) {
|
||
type = "POST";
|
||
}
|
||
|
||
// If we have elements to modify, make the request
|
||
if ( self.length > 0 ) {
|
||
jQuery.ajax({
|
||
url: url,
|
||
|
||
// if "type" variable is undefined, then "GET" method will be used
|
||
type: type,
|
||
dataType: "html",
|
||
data: params
|
||
}).done(function( responseText ) {
|
||
|
||
// Save response for use in complete callback
|
||
response = arguments;
|
||
|
||
self.html( selector ?
|
||
|
||
// If a selector was specified, locate the right elements in a dummy div
|
||
// Exclude scripts to avoid IE 'Permission Denied' errors
|
||
jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
|
||
|
||
// Otherwise use the full result
|
||
responseText );
|
||
|
||
}).complete( callback && function( jqXHR, status ) {
|
||
self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
|
||
});
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
|
||
|
||
|
||
jQuery.expr.filters.animated = function( elem ) {
|
||
return jQuery.grep(jQuery.timers, function( fn ) {
|
||
return elem === fn.elem;
|
||
}).length;
|
||
};
|
||
|
||
|
||
|
||
|
||
var docElem = window.document.documentElement;
|
||
|
||
/**
|
||
* Gets a window from an element
|
||
*/
|
||
function getWindow( elem ) {
|
||
return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
|
||
}
|
||
|
||
jQuery.offset = {
|
||
setOffset: function( elem, options, i ) {
|
||
var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
|
||
position = jQuery.css( elem, "position" ),
|
||
curElem = jQuery( elem ),
|
||
props = {};
|
||
|
||
// Set position first, in-case top/left are set even on static elem
|
||
if ( position === "static" ) {
|
||
elem.style.position = "relative";
|
||
}
|
||
|
||
curOffset = curElem.offset();
|
||
curCSSTop = jQuery.css( elem, "top" );
|
||
curCSSLeft = jQuery.css( elem, "left" );
|
||
calculatePosition = ( position === "absolute" || position === "fixed" ) &&
|
||
( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
|
||
|
||
// Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
|
||
if ( calculatePosition ) {
|
||
curPosition = curElem.position();
|
||
curTop = curPosition.top;
|
||
curLeft = curPosition.left;
|
||
|
||
} else {
|
||
curTop = parseFloat( curCSSTop ) || 0;
|
||
curLeft = parseFloat( curCSSLeft ) || 0;
|
||
}
|
||
|
||
if ( jQuery.isFunction( options ) ) {
|
||
options = options.call( elem, i, curOffset );
|
||
}
|
||
|
||
if ( options.top != null ) {
|
||
props.top = ( options.top - curOffset.top ) + curTop;
|
||
}
|
||
if ( options.left != null ) {
|
||
props.left = ( options.left - curOffset.left ) + curLeft;
|
||
}
|
||
|
||
if ( "using" in options ) {
|
||
options.using.call( elem, props );
|
||
|
||
} else {
|
||
curElem.css( props );
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
offset: function( options ) {
|
||
if ( arguments.length ) {
|
||
return options === undefined ?
|
||
this :
|
||
this.each(function( i ) {
|
||
jQuery.offset.setOffset( this, options, i );
|
||
});
|
||
}
|
||
|
||
var docElem, win,
|
||
elem = this[ 0 ],
|
||
box = { top: 0, left: 0 },
|
||
doc = elem && elem.ownerDocument;
|
||
|
||
if ( !doc ) {
|
||
return;
|
||
}
|
||
|
||
docElem = doc.documentElement;
|
||
|
||
// Make sure it's not a disconnected DOM node
|
||
if ( !jQuery.contains( docElem, elem ) ) {
|
||
return box;
|
||
}
|
||
|
||
// If we don't have gBCR, just use 0,0 rather than error
|
||
// BlackBerry 5, iOS 3 (original iPhone)
|
||
if ( typeof elem.getBoundingClientRect !== strundefined ) {
|
||
box = elem.getBoundingClientRect();
|
||
}
|
||
win = getWindow( doc );
|
||
return {
|
||
top: box.top + win.pageYOffset - docElem.clientTop,
|
||
left: box.left + win.pageXOffset - docElem.clientLeft
|
||
};
|
||
},
|
||
|
||
position: function() {
|
||
if ( !this[ 0 ] ) {
|
||
return;
|
||
}
|
||
|
||
var offsetParent, offset,
|
||
elem = this[ 0 ],
|
||
parentOffset = { top: 0, left: 0 };
|
||
|
||
// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
|
||
if ( jQuery.css( elem, "position" ) === "fixed" ) {
|
||
// We assume that getBoundingClientRect is available when computed position is fixed
|
||
offset = elem.getBoundingClientRect();
|
||
|
||
} else {
|
||
// Get *real* offsetParent
|
||
offsetParent = this.offsetParent();
|
||
|
||
// Get correct offsets
|
||
offset = this.offset();
|
||
if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
|
||
parentOffset = offsetParent.offset();
|
||
}
|
||
|
||
// Add offsetParent borders
|
||
parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
|
||
parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
|
||
}
|
||
|
||
// Subtract parent offsets and element margins
|
||
return {
|
||
top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
|
||
left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
|
||
};
|
||
},
|
||
|
||
offsetParent: function() {
|
||
return this.map(function() {
|
||
var offsetParent = this.offsetParent || docElem;
|
||
|
||
while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
|
||
offsetParent = offsetParent.offsetParent;
|
||
}
|
||
|
||
return offsetParent || docElem;
|
||
});
|
||
}
|
||
});
|
||
|
||
// Create scrollLeft and scrollTop methods
|
||
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
|
||
var top = "pageYOffset" === prop;
|
||
|
||
jQuery.fn[ method ] = function( val ) {
|
||
return access( this, function( elem, method, val ) {
|
||
var win = getWindow( elem );
|
||
|
||
if ( val === undefined ) {
|
||
return win ? win[ prop ] : elem[ method ];
|
||
}
|
||
|
||
if ( win ) {
|
||
win.scrollTo(
|
||
!top ? val : window.pageXOffset,
|
||
top ? val : window.pageYOffset
|
||
);
|
||
|
||
} else {
|
||
elem[ method ] = val;
|
||
}
|
||
}, method, val, arguments.length, null );
|
||
};
|
||
});
|
||
|
||
// Add the top/left cssHooks using jQuery.fn.position
|
||
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
|
||
// getComputedStyle returns percent when specified for top/left/bottom/right
|
||
// rather than make the css module depend on the offset module, we just check for it here
|
||
jQuery.each( [ "top", "left" ], function( i, prop ) {
|
||
jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
|
||
function( elem, computed ) {
|
||
if ( computed ) {
|
||
computed = curCSS( elem, prop );
|
||
// if curCSS returns percentage, fallback to offset
|
||
return rnumnonpx.test( computed ) ?
|
||
jQuery( elem ).position()[ prop ] + "px" :
|
||
computed;
|
||
}
|
||
}
|
||
);
|
||
});
|
||
|
||
|
||
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
|
||
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
|
||
jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
|
||
// margin is only for outerHeight, outerWidth
|
||
jQuery.fn[ funcName ] = function( margin, value ) {
|
||
var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
|
||
extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
|
||
|
||
return access( this, function( elem, type, value ) {
|
||
var doc;
|
||
|
||
if ( jQuery.isWindow( elem ) ) {
|
||
// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
|
||
// isn't a whole lot we can do. See pull request at this URL for discussion:
|
||
// https://github.com/jquery/jquery/pull/764
|
||
return elem.document.documentElement[ "client" + name ];
|
||
}
|
||
|
||
// Get document width or height
|
||
if ( elem.nodeType === 9 ) {
|
||
doc = elem.documentElement;
|
||
|
||
// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
|
||
// whichever is greatest
|
||
return Math.max(
|
||
elem.body[ "scroll" + name ], doc[ "scroll" + name ],
|
||
elem.body[ "offset" + name ], doc[ "offset" + name ],
|
||
doc[ "client" + name ]
|
||
);
|
||
}
|
||
|
||
return value === undefined ?
|
||
// Get width or height on the element, requesting but not forcing parseFloat
|
||
jQuery.css( elem, type, extra ) :
|
||
|
||
// Set width or height on the element
|
||
jQuery.style( elem, type, value, extra );
|
||
}, type, chainable ? margin : undefined, chainable, null );
|
||
};
|
||
});
|
||
});
|
||
|
||
|
||
// The number of elements contained in the matched element set
|
||
jQuery.fn.size = function() {
|
||
return this.length;
|
||
};
|
||
|
||
jQuery.fn.andSelf = jQuery.fn.addBack;
|
||
|
||
|
||
|
||
|
||
// Register as a named AMD module, since jQuery can be concatenated with other
|
||
// files that may use define, but not via a proper concatenation script that
|
||
// understands anonymous AMD modules. A named AMD is safest and most robust
|
||
// way to register. Lowercase jquery is used because AMD module names are
|
||
// derived from file names, and jQuery is normally delivered in a lowercase
|
||
// file name. Do this after creating the global so that if an AMD module wants
|
||
// to call noConflict to hide this version of jQuery, it will work.
|
||
|
||
// Note that for maximum portability, libraries that are not jQuery should
|
||
// declare themselves as anonymous modules, and avoid setting a global if an
|
||
// AMD loader is present. jQuery is a special case. For more information, see
|
||
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
|
||
|
||
if ( typeof define === "function" && define.amd ) {
|
||
define( "jquery", [], function() {
|
||
return jQuery;
|
||
});
|
||
}
|
||
|
||
|
||
|
||
|
||
var
|
||
// Map over jQuery in case of overwrite
|
||
_jQuery = window.jQuery,
|
||
|
||
// Map over the $ in case of overwrite
|
||
_$ = window.$;
|
||
|
||
jQuery.noConflict = function( deep ) {
|
||
if ( window.$ === jQuery ) {
|
||
window.$ = _$;
|
||
}
|
||
|
||
if ( deep && window.jQuery === jQuery ) {
|
||
window.jQuery = _jQuery;
|
||
}
|
||
|
||
return jQuery;
|
||
};
|
||
|
||
// Expose jQuery and $ identifiers, even in
|
||
// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
|
||
// and CommonJS for browser emulators (#13566)
|
||
if ( typeof noGlobal === strundefined ) {
|
||
window.jQuery = window.$ = jQuery;
|
||
}
|
||
|
||
|
||
|
||
|
||
return jQuery;
|
||
|
||
}));
|
||
|
||
},{}],68:[function(require,module,exports){
|
||
(function (sinonChai) {
|
||
"use strict";
|
||
|
||
// Module systems magic dance.
|
||
|
||
if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
|
||
// NodeJS
|
||
module.exports = sinonChai;
|
||
} else if (typeof define === "function" && define.amd) {
|
||
// AMD
|
||
define(function () {
|
||
return sinonChai;
|
||
});
|
||
} else {
|
||
// Other environment (usually <script> tag): plug in to global chai instance directly.
|
||
chai.use(sinonChai);
|
||
}
|
||
}(function sinonChai(chai, utils) {
|
||
"use strict";
|
||
|
||
var slice = Array.prototype.slice;
|
||
|
||
function isSpy(putativeSpy) {
|
||
return typeof putativeSpy === "function" &&
|
||
typeof putativeSpy.getCall === "function" &&
|
||
typeof putativeSpy.calledWithExactly === "function";
|
||
}
|
||
|
||
function timesInWords(count) {
|
||
return count === 1 ? "once" :
|
||
count === 2 ? "twice" :
|
||
count === 3 ? "thrice" :
|
||
(count || 0) + " times";
|
||
}
|
||
|
||
function isCall(putativeCall) {
|
||
return putativeCall && isSpy(putativeCall.proxy);
|
||
}
|
||
|
||
function assertCanWorkWith(assertion) {
|
||
if (!isSpy(assertion._obj) && !isCall(assertion._obj)) {
|
||
throw new TypeError(utils.inspect(assertion._obj) + " is not a spy or a call to a spy!");
|
||
}
|
||
}
|
||
|
||
function getMessages(spy, action, nonNegatedSuffix, always, args) {
|
||
var verbPhrase = always ? "always have " : "have ";
|
||
nonNegatedSuffix = nonNegatedSuffix || "";
|
||
if (isSpy(spy.proxy)) {
|
||
spy = spy.proxy;
|
||
}
|
||
|
||
function printfArray(array) {
|
||
return spy.printf.apply(spy, array);
|
||
}
|
||
|
||
return {
|
||
affirmative: printfArray(["expected %n to " + verbPhrase + action + nonNegatedSuffix].concat(args)),
|
||
negative: printfArray(["expected %n to not " + verbPhrase + action].concat(args))
|
||
};
|
||
}
|
||
|
||
function sinonProperty(name, action, nonNegatedSuffix) {
|
||
utils.addProperty(chai.Assertion.prototype, name, function () {
|
||
assertCanWorkWith(this);
|
||
|
||
var messages = getMessages(this._obj, action, nonNegatedSuffix, false);
|
||
this.assert(this._obj[name], messages.affirmative, messages.negative);
|
||
});
|
||
}
|
||
|
||
function sinonPropertyAsBooleanMethod(name, action, nonNegatedSuffix) {
|
||
utils.addMethod(chai.Assertion.prototype, name, function (arg) {
|
||
assertCanWorkWith(this);
|
||
|
||
var messages = getMessages(this._obj, action, nonNegatedSuffix, false, [timesInWords(arg)]);
|
||
this.assert(this._obj[name] === arg, messages.affirmative, messages.negative);
|
||
});
|
||
}
|
||
|
||
function createSinonMethodHandler(sinonName, action, nonNegatedSuffix) {
|
||
return function () {
|
||
assertCanWorkWith(this);
|
||
|
||
var alwaysSinonMethod = "always" + sinonName[0].toUpperCase() + sinonName.substring(1);
|
||
var shouldBeAlways = utils.flag(this, "always") && typeof this._obj[alwaysSinonMethod] === "function";
|
||
var sinonMethod = shouldBeAlways ? alwaysSinonMethod : sinonName;
|
||
|
||
var messages = getMessages(this._obj, action, nonNegatedSuffix, shouldBeAlways, slice.call(arguments));
|
||
this.assert(this._obj[sinonMethod].apply(this._obj, arguments), messages.affirmative, messages.negative);
|
||
};
|
||
}
|
||
|
||
function sinonMethodAsProperty(name, action, nonNegatedSuffix) {
|
||
var handler = createSinonMethodHandler(name, action, nonNegatedSuffix);
|
||
utils.addProperty(chai.Assertion.prototype, name, handler);
|
||
}
|
||
|
||
function exceptionalSinonMethod(chaiName, sinonName, action, nonNegatedSuffix) {
|
||
var handler = createSinonMethodHandler(sinonName, action, nonNegatedSuffix);
|
||
utils.addMethod(chai.Assertion.prototype, chaiName, handler);
|
||
}
|
||
|
||
function sinonMethod(name, action, nonNegatedSuffix) {
|
||
exceptionalSinonMethod(name, name, action, nonNegatedSuffix);
|
||
}
|
||
|
||
utils.addProperty(chai.Assertion.prototype, "always", function () {
|
||
utils.flag(this, "always", true);
|
||
});
|
||
|
||
sinonProperty("called", "been called", " at least once, but it was never called");
|
||
sinonPropertyAsBooleanMethod("callCount", "been called exactly %1", ", but it was called %c%C");
|
||
sinonProperty("calledOnce", "been called exactly once", ", but it was called %c%C");
|
||
sinonProperty("calledTwice", "been called exactly twice", ", but it was called %c%C");
|
||
sinonProperty("calledThrice", "been called exactly thrice", ", but it was called %c%C");
|
||
sinonMethodAsProperty("calledWithNew", "been called with new");
|
||
sinonMethod("calledBefore", "been called before %1");
|
||
sinonMethod("calledAfter", "been called after %1");
|
||
sinonMethod("calledOn", "been called with %1 as this", ", but it was called with %t instead");
|
||
sinonMethod("calledWith", "been called with arguments %*", "%C");
|
||
sinonMethod("calledWithExactly", "been called with exact arguments %*", "%C");
|
||
sinonMethod("calledWithMatch", "been called with arguments matching %*", "%C");
|
||
sinonMethod("returned", "returned %1");
|
||
exceptionalSinonMethod("thrown", "threw", "thrown %1");
|
||
}));
|
||
|
||
},{}],69:[function(require,module,exports){
|
||
/*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
|
||
/*global module, require, __dirname, document*/
|
||
/**
|
||
* Sinon core utilities. For internal use only.
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
*/
|
||
"use strict";
|
||
|
||
var sinon = (function (formatio) {
|
||
var div = typeof document != "undefined" && document.createElement("div");
|
||
var hasOwn = Object.prototype.hasOwnProperty;
|
||
|
||
function isDOMNode(obj) {
|
||
var success = false;
|
||
|
||
try {
|
||
obj.appendChild(div);
|
||
success = div.parentNode == obj;
|
||
} catch (e) {
|
||
return false;
|
||
} finally {
|
||
try {
|
||
obj.removeChild(div);
|
||
} catch (e) {
|
||
// Remove failed, not much we can do about that
|
||
}
|
||
}
|
||
|
||
return success;
|
||
}
|
||
|
||
function isElement(obj) {
|
||
return div && obj && obj.nodeType === 1 && isDOMNode(obj);
|
||
}
|
||
|
||
function isFunction(obj) {
|
||
return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply);
|
||
}
|
||
|
||
function isReallyNaN(val) {
|
||
return typeof val === 'number' && isNaN(val);
|
||
}
|
||
|
||
function mirrorProperties(target, source) {
|
||
for (var prop in source) {
|
||
if (!hasOwn.call(target, prop)) {
|
||
target[prop] = source[prop];
|
||
}
|
||
}
|
||
}
|
||
|
||
function isRestorable (obj) {
|
||
return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
|
||
}
|
||
|
||
var sinon = {
|
||
wrapMethod: function wrapMethod(object, property, method) {
|
||
if (!object) {
|
||
throw new TypeError("Should wrap property of object");
|
||
}
|
||
|
||
if (typeof method != "function") {
|
||
throw new TypeError("Method wrapper should be function");
|
||
}
|
||
|
||
var wrappedMethod = object[property],
|
||
error;
|
||
|
||
if (!isFunction(wrappedMethod)) {
|
||
error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
|
||
property + " as function");
|
||
} else if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
|
||
error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
|
||
} else if (wrappedMethod.calledBefore) {
|
||
var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
|
||
error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
|
||
}
|
||
|
||
if (error) {
|
||
if (wrappedMethod && wrappedMethod._stack) {
|
||
error.stack += '\n--------------\n' + wrappedMethod._stack;
|
||
}
|
||
throw error;
|
||
}
|
||
|
||
// IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
|
||
// when using hasOwn.call on objects from other frames.
|
||
var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
|
||
object[property] = method;
|
||
method.displayName = property;
|
||
// Set up a stack trace which can be used later to find what line of
|
||
// code the original method was created on.
|
||
method._stack = (new Error('Stack Trace for original')).stack;
|
||
|
||
method.restore = function () {
|
||
// For prototype properties try to reset by delete first.
|
||
// If this fails (ex: localStorage on mobile safari) then force a reset
|
||
// via direct assignment.
|
||
if (!owned) {
|
||
delete object[property];
|
||
}
|
||
if (object[property] === method) {
|
||
object[property] = wrappedMethod;
|
||
}
|
||
};
|
||
|
||
method.restore.sinon = true;
|
||
mirrorProperties(method, wrappedMethod);
|
||
|
||
return method;
|
||
},
|
||
|
||
extend: function extend(target) {
|
||
for (var i = 1, l = arguments.length; i < l; i += 1) {
|
||
for (var prop in arguments[i]) {
|
||
if (arguments[i].hasOwnProperty(prop)) {
|
||
target[prop] = arguments[i][prop];
|
||
}
|
||
|
||
// DONT ENUM bug, only care about toString
|
||
if (arguments[i].hasOwnProperty("toString") &&
|
||
arguments[i].toString != target.toString) {
|
||
target.toString = arguments[i].toString;
|
||
}
|
||
}
|
||
}
|
||
|
||
return target;
|
||
},
|
||
|
||
create: function create(proto) {
|
||
var F = function () {};
|
||
F.prototype = proto;
|
||
return new F();
|
||
},
|
||
|
||
deepEqual: function deepEqual(a, b) {
|
||
if (sinon.match && sinon.match.isMatcher(a)) {
|
||
return a.test(b);
|
||
}
|
||
|
||
if (typeof a != 'object' || typeof b != 'object') {
|
||
if (isReallyNaN(a) && isReallyNaN(b)) {
|
||
return true;
|
||
} else {
|
||
return a === b;
|
||
}
|
||
}
|
||
|
||
if (isElement(a) || isElement(b)) {
|
||
return a === b;
|
||
}
|
||
|
||
if (a === b) {
|
||
return true;
|
||
}
|
||
|
||
if ((a === null && b !== null) || (a !== null && b === null)) {
|
||
return false;
|
||
}
|
||
|
||
if (a instanceof RegExp && b instanceof RegExp) {
|
||
return (a.source === b.source) && (a.global === b.global) &&
|
||
(a.ignoreCase === b.ignoreCase) && (a.multiline === b.multiline);
|
||
}
|
||
|
||
var aString = Object.prototype.toString.call(a);
|
||
if (aString != Object.prototype.toString.call(b)) {
|
||
return false;
|
||
}
|
||
|
||
if (aString == "[object Date]") {
|
||
return a.valueOf() === b.valueOf();
|
||
}
|
||
|
||
var prop, aLength = 0, bLength = 0;
|
||
|
||
if (aString == "[object Array]" && a.length !== b.length) {
|
||
return false;
|
||
}
|
||
|
||
for (prop in a) {
|
||
aLength += 1;
|
||
|
||
if (!(prop in b)) {
|
||
return false;
|
||
}
|
||
|
||
if (!deepEqual(a[prop], b[prop])) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
for (prop in b) {
|
||
bLength += 1;
|
||
}
|
||
|
||
return aLength == bLength;
|
||
},
|
||
|
||
functionName: function functionName(func) {
|
||
var name = func.displayName || func.name;
|
||
|
||
// Use function decomposition as a last resort to get function
|
||
// name. Does not rely on function decomposition to work - if it
|
||
// doesn't debugging will be slightly less informative
|
||
// (i.e. toString will say 'spy' rather than 'myFunc').
|
||
if (!name) {
|
||
var matches = func.toString().match(/function ([^\s\(]+)/);
|
||
name = matches && matches[1];
|
||
}
|
||
|
||
return name;
|
||
},
|
||
|
||
functionToString: function toString() {
|
||
if (this.getCall && this.callCount) {
|
||
var thisValue, prop, i = this.callCount;
|
||
|
||
while (i--) {
|
||
thisValue = this.getCall(i).thisValue;
|
||
|
||
for (prop in thisValue) {
|
||
if (thisValue[prop] === this) {
|
||
return prop;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return this.displayName || "sinon fake";
|
||
},
|
||
|
||
getConfig: function (custom) {
|
||
var config = {};
|
||
custom = custom || {};
|
||
var defaults = sinon.defaultConfig;
|
||
|
||
for (var prop in defaults) {
|
||
if (defaults.hasOwnProperty(prop)) {
|
||
config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
|
||
}
|
||
}
|
||
|
||
return config;
|
||
},
|
||
|
||
format: function (val) {
|
||
return "" + val;
|
||
},
|
||
|
||
defaultConfig: {
|
||
injectIntoThis: true,
|
||
injectInto: null,
|
||
properties: ["spy", "stub", "mock", "clock", "server", "requests"],
|
||
useFakeTimers: true,
|
||
useFakeServer: true
|
||
},
|
||
|
||
timesInWords: function timesInWords(count) {
|
||
return count == 1 && "once" ||
|
||
count == 2 && "twice" ||
|
||
count == 3 && "thrice" ||
|
||
(count || 0) + " times";
|
||
},
|
||
|
||
calledInOrder: function (spies) {
|
||
for (var i = 1, l = spies.length; i < l; i++) {
|
||
if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
},
|
||
|
||
orderByFirstCall: function (spies) {
|
||
return spies.sort(function (a, b) {
|
||
// uuid, won't ever be equal
|
||
var aCall = a.getCall(0);
|
||
var bCall = b.getCall(0);
|
||
var aId = aCall && aCall.callId || -1;
|
||
var bId = bCall && bCall.callId || -1;
|
||
|
||
return aId < bId ? -1 : 1;
|
||
});
|
||
},
|
||
|
||
log: function () {},
|
||
|
||
logError: function (label, err) {
|
||
var msg = label + " threw exception: ";
|
||
sinon.log(msg + "[" + err.name + "] " + err.message);
|
||
if (err.stack) { sinon.log(err.stack); }
|
||
|
||
setTimeout(function () {
|
||
err.message = msg + err.message;
|
||
throw err;
|
||
}, 0);
|
||
},
|
||
|
||
typeOf: function (value) {
|
||
if (value === null) {
|
||
return "null";
|
||
}
|
||
else if (value === undefined) {
|
||
return "undefined";
|
||
}
|
||
var string = Object.prototype.toString.call(value);
|
||
return string.substring(8, string.length - 1).toLowerCase();
|
||
},
|
||
|
||
createStubInstance: function (constructor) {
|
||
if (typeof constructor !== "function") {
|
||
throw new TypeError("The constructor should be a function.");
|
||
}
|
||
return sinon.stub(sinon.create(constructor.prototype));
|
||
},
|
||
|
||
restore: function (object) {
|
||
if (object !== null && typeof object === "object") {
|
||
for (var prop in object) {
|
||
if (isRestorable(object[prop])) {
|
||
object[prop].restore();
|
||
}
|
||
}
|
||
}
|
||
else if (isRestorable(object)) {
|
||
object.restore();
|
||
}
|
||
}
|
||
};
|
||
|
||
var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
|
||
var isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd;
|
||
|
||
function makePublicAPI(require, exports, module) {
|
||
module.exports = sinon;
|
||
sinon.spy = require("./sinon/spy");
|
||
sinon.spyCall = require("./sinon/call");
|
||
sinon.behavior = require("./sinon/behavior");
|
||
sinon.stub = require("./sinon/stub");
|
||
sinon.mock = require("./sinon/mock");
|
||
sinon.collection = require("./sinon/collection");
|
||
sinon.assert = require("./sinon/assert");
|
||
sinon.sandbox = require("./sinon/sandbox");
|
||
sinon.test = require("./sinon/test");
|
||
sinon.testCase = require("./sinon/test_case");
|
||
sinon.match = require("./sinon/match");
|
||
}
|
||
|
||
if (isAMD) {
|
||
define(makePublicAPI);
|
||
} else if (isNode) {
|
||
try {
|
||
formatio = require("formatio");
|
||
} catch (e) {}
|
||
makePublicAPI(require, exports, module);
|
||
}
|
||
|
||
if (formatio) {
|
||
var formatter = formatio.configure({ quoteStrings: false });
|
||
sinon.format = function () {
|
||
return formatter.ascii.apply(formatter, arguments);
|
||
};
|
||
} else if (isNode) {
|
||
try {
|
||
var util = require("util");
|
||
sinon.format = function (value) {
|
||
return typeof value == "object" && value.toString === Object.prototype.toString ? util.inspect(value) : value;
|
||
};
|
||
} catch (e) {
|
||
/* Node, but no util module - would be very old, but better safe than
|
||
sorry */
|
||
}
|
||
}
|
||
|
||
return sinon;
|
||
}(typeof formatio == "object" && formatio));
|
||
|
||
},{"./sinon/assert":70,"./sinon/behavior":71,"./sinon/call":72,"./sinon/collection":73,"./sinon/match":74,"./sinon/mock":75,"./sinon/sandbox":76,"./sinon/spy":77,"./sinon/stub":78,"./sinon/test":79,"./sinon/test_case":80,"formatio":82,"util":64}],70:[function(require,module,exports){
|
||
(function (global){
|
||
/**
|
||
* @depend ../sinon.js
|
||
* @depend stub.js
|
||
*/
|
||
/*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/
|
||
/*global module, require, sinon*/
|
||
/**
|
||
* Assertions matching the test spy retrieval interface.
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
*/
|
||
"use strict";
|
||
|
||
(function (sinon, global) {
|
||
var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
|
||
var slice = Array.prototype.slice;
|
||
var assert;
|
||
|
||
if (!sinon && commonJSModule) {
|
||
sinon = require("../sinon");
|
||
}
|
||
|
||
if (!sinon) {
|
||
return;
|
||
}
|
||
|
||
function verifyIsStub() {
|
||
var method;
|
||
|
||
for (var i = 0, l = arguments.length; i < l; ++i) {
|
||
method = arguments[i];
|
||
|
||
if (!method) {
|
||
assert.fail("fake is not a spy");
|
||
}
|
||
|
||
if (typeof method != "function") {
|
||
assert.fail(method + " is not a function");
|
||
}
|
||
|
||
if (typeof method.getCall != "function") {
|
||
assert.fail(method + " is not stubbed");
|
||
}
|
||
}
|
||
}
|
||
|
||
function failAssertion(object, msg) {
|
||
object = object || global;
|
||
var failMethod = object.fail || assert.fail;
|
||
failMethod.call(object, msg);
|
||
}
|
||
|
||
function mirrorPropAsAssertion(name, method, message) {
|
||
if (arguments.length == 2) {
|
||
message = method;
|
||
method = name;
|
||
}
|
||
|
||
assert[name] = function (fake) {
|
||
verifyIsStub(fake);
|
||
|
||
var args = slice.call(arguments, 1);
|
||
var failed = false;
|
||
|
||
if (typeof method == "function") {
|
||
failed = !method(fake);
|
||
} else {
|
||
failed = typeof fake[method] == "function" ?
|
||
!fake[method].apply(fake, args) : !fake[method];
|
||
}
|
||
|
||
if (failed) {
|
||
failAssertion(this, fake.printf.apply(fake, [message].concat(args)));
|
||
} else {
|
||
assert.pass(name);
|
||
}
|
||
};
|
||
}
|
||
|
||
function exposedName(prefix, prop) {
|
||
return !prefix || /^fail/.test(prop) ? prop :
|
||
prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
|
||
}
|
||
|
||
assert = {
|
||
failException: "AssertError",
|
||
|
||
fail: function fail(message) {
|
||
var error = new Error(message);
|
||
error.name = this.failException || assert.failException;
|
||
|
||
throw error;
|
||
},
|
||
|
||
pass: function pass(assertion) {},
|
||
|
||
callOrder: function assertCallOrder() {
|
||
verifyIsStub.apply(null, arguments);
|
||
var expected = "", actual = "";
|
||
|
||
if (!sinon.calledInOrder(arguments)) {
|
||
try {
|
||
expected = [].join.call(arguments, ", ");
|
||
var calls = slice.call(arguments);
|
||
var i = calls.length;
|
||
while (i) {
|
||
if (!calls[--i].called) {
|
||
calls.splice(i, 1);
|
||
}
|
||
}
|
||
actual = sinon.orderByFirstCall(calls).join(", ");
|
||
} catch (e) {
|
||
// If this fails, we'll just fall back to the blank string
|
||
}
|
||
|
||
failAssertion(this, "expected " + expected + " to be " +
|
||
"called in order but were called as " + actual);
|
||
} else {
|
||
assert.pass("callOrder");
|
||
}
|
||
},
|
||
|
||
callCount: function assertCallCount(method, count) {
|
||
verifyIsStub(method);
|
||
|
||
if (method.callCount != count) {
|
||
var msg = "expected %n to be called " + sinon.timesInWords(count) +
|
||
" but was called %c%C";
|
||
failAssertion(this, method.printf(msg));
|
||
} else {
|
||
assert.pass("callCount");
|
||
}
|
||
},
|
||
|
||
expose: function expose(target, options) {
|
||
if (!target) {
|
||
throw new TypeError("target is null or undefined");
|
||
}
|
||
|
||
var o = options || {};
|
||
var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
|
||
var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
|
||
|
||
for (var method in this) {
|
||
if (method != "export" && (includeFail || !/^(fail)/.test(method))) {
|
||
target[exposedName(prefix, method)] = this[method];
|
||
}
|
||
}
|
||
|
||
return target;
|
||
},
|
||
|
||
match: function match(actual, expectation) {
|
||
var matcher = sinon.match(expectation);
|
||
if (matcher.test(actual)) {
|
||
assert.pass("match");
|
||
} else {
|
||
var formatted = [
|
||
"expected value to match",
|
||
" expected = " + sinon.format(expectation),
|
||
" actual = " + sinon.format(actual)
|
||
]
|
||
failAssertion(this, formatted.join("\n"));
|
||
}
|
||
}
|
||
};
|
||
|
||
mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
|
||
mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
|
||
"expected %n to not have been called but was called %c%C");
|
||
mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
|
||
mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
|
||
mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
|
||
mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
|
||
mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
|
||
mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
|
||
mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
|
||
mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
|
||
mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
|
||
mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
|
||
mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
|
||
mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
|
||
mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
|
||
mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
|
||
mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
|
||
mirrorPropAsAssertion("threw", "%n did not throw exception%C");
|
||
mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
|
||
|
||
sinon.assert = assert;
|
||
|
||
if (typeof define === "function" && define.amd) {
|
||
define(["module"], function(module) { module.exports = assert; });
|
||
} else if (commonJSModule) {
|
||
module.exports = assert;
|
||
}
|
||
}(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
|
||
|
||
}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
},{"../sinon":69}],71:[function(require,module,exports){
|
||
(function (process){
|
||
/**
|
||
* @depend ../sinon.js
|
||
*/
|
||
/*jslint eqeqeq: false, onevar: false*/
|
||
/*global module, require, sinon, process, setImmediate, setTimeout*/
|
||
/**
|
||
* Stub behavior
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @author Tim Fischbach (mail@timfischbach.de)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
*/
|
||
"use strict";
|
||
|
||
(function (sinon) {
|
||
var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
|
||
|
||
if (!sinon && commonJSModule) {
|
||
sinon = require("../sinon");
|
||
}
|
||
|
||
if (!sinon) {
|
||
return;
|
||
}
|
||
|
||
var slice = Array.prototype.slice;
|
||
var join = Array.prototype.join;
|
||
var proto;
|
||
|
||
var nextTick = (function () {
|
||
if (typeof process === "object" && typeof process.nextTick === "function") {
|
||
return process.nextTick;
|
||
} else if (typeof setImmediate === "function") {
|
||
return setImmediate;
|
||
} else {
|
||
return function (callback) {
|
||
setTimeout(callback, 0);
|
||
};
|
||
}
|
||
})();
|
||
|
||
function throwsException(error, message) {
|
||
if (typeof error == "string") {
|
||
this.exception = new Error(message || "");
|
||
this.exception.name = error;
|
||
} else if (!error) {
|
||
this.exception = new Error("Error");
|
||
} else {
|
||
this.exception = error;
|
||
}
|
||
|
||
return this;
|
||
}
|
||
|
||
function getCallback(behavior, args) {
|
||
var callArgAt = behavior.callArgAt;
|
||
|
||
if (callArgAt < 0) {
|
||
var callArgProp = behavior.callArgProp;
|
||
|
||
for (var i = 0, l = args.length; i < l; ++i) {
|
||
if (!callArgProp && typeof args[i] == "function") {
|
||
return args[i];
|
||
}
|
||
|
||
if (callArgProp && args[i] &&
|
||
typeof args[i][callArgProp] == "function") {
|
||
return args[i][callArgProp];
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
return args[callArgAt];
|
||
}
|
||
|
||
function getCallbackError(behavior, func, args) {
|
||
if (behavior.callArgAt < 0) {
|
||
var msg;
|
||
|
||
if (behavior.callArgProp) {
|
||
msg = sinon.functionName(behavior.stub) +
|
||
" expected to yield to '" + behavior.callArgProp +
|
||
"', but no object with such a property was passed.";
|
||
} else {
|
||
msg = sinon.functionName(behavior.stub) +
|
||
" expected to yield, but no callback was passed.";
|
||
}
|
||
|
||
if (args.length > 0) {
|
||
msg += " Received [" + join.call(args, ", ") + "]";
|
||
}
|
||
|
||
return msg;
|
||
}
|
||
|
||
return "argument at index " + behavior.callArgAt + " is not a function: " + func;
|
||
}
|
||
|
||
function callCallback(behavior, args) {
|
||
if (typeof behavior.callArgAt == "number") {
|
||
var func = getCallback(behavior, args);
|
||
|
||
if (typeof func != "function") {
|
||
throw new TypeError(getCallbackError(behavior, func, args));
|
||
}
|
||
|
||
if (behavior.callbackAsync) {
|
||
nextTick(function() {
|
||
func.apply(behavior.callbackContext, behavior.callbackArguments);
|
||
});
|
||
} else {
|
||
func.apply(behavior.callbackContext, behavior.callbackArguments);
|
||
}
|
||
}
|
||
}
|
||
|
||
proto = {
|
||
create: function(stub) {
|
||
var behavior = sinon.extend({}, sinon.behavior);
|
||
delete behavior.create;
|
||
behavior.stub = stub;
|
||
|
||
return behavior;
|
||
},
|
||
|
||
isPresent: function() {
|
||
return (typeof this.callArgAt == 'number' ||
|
||
this.exception ||
|
||
typeof this.returnArgAt == 'number' ||
|
||
this.returnThis ||
|
||
this.returnValueDefined);
|
||
},
|
||
|
||
invoke: function(context, args) {
|
||
callCallback(this, args);
|
||
|
||
if (this.exception) {
|
||
throw this.exception;
|
||
} else if (typeof this.returnArgAt == 'number') {
|
||
return args[this.returnArgAt];
|
||
} else if (this.returnThis) {
|
||
return context;
|
||
}
|
||
|
||
return this.returnValue;
|
||
},
|
||
|
||
onCall: function(index) {
|
||
return this.stub.onCall(index);
|
||
},
|
||
|
||
onFirstCall: function() {
|
||
return this.stub.onFirstCall();
|
||
},
|
||
|
||
onSecondCall: function() {
|
||
return this.stub.onSecondCall();
|
||
},
|
||
|
||
onThirdCall: function() {
|
||
return this.stub.onThirdCall();
|
||
},
|
||
|
||
withArgs: function(/* arguments */) {
|
||
throw new Error('Defining a stub by invoking "stub.onCall(...).withArgs(...)" is not supported. ' +
|
||
'Use "stub.withArgs(...).onCall(...)" to define sequential behavior for calls with certain arguments.');
|
||
},
|
||
|
||
callsArg: function callsArg(pos) {
|
||
if (typeof pos != "number") {
|
||
throw new TypeError("argument index is not number");
|
||
}
|
||
|
||
this.callArgAt = pos;
|
||
this.callbackArguments = [];
|
||
this.callbackContext = undefined;
|
||
this.callArgProp = undefined;
|
||
this.callbackAsync = false;
|
||
|
||
return this;
|
||
},
|
||
|
||
callsArgOn: function callsArgOn(pos, context) {
|
||
if (typeof pos != "number") {
|
||
throw new TypeError("argument index is not number");
|
||
}
|
||
if (typeof context != "object") {
|
||
throw new TypeError("argument context is not an object");
|
||
}
|
||
|
||
this.callArgAt = pos;
|
||
this.callbackArguments = [];
|
||
this.callbackContext = context;
|
||
this.callArgProp = undefined;
|
||
this.callbackAsync = false;
|
||
|
||
return this;
|
||
},
|
||
|
||
callsArgWith: function callsArgWith(pos) {
|
||
if (typeof pos != "number") {
|
||
throw new TypeError("argument index is not number");
|
||
}
|
||
|
||
this.callArgAt = pos;
|
||
this.callbackArguments = slice.call(arguments, 1);
|
||
this.callbackContext = undefined;
|
||
this.callArgProp = undefined;
|
||
this.callbackAsync = false;
|
||
|
||
return this;
|
||
},
|
||
|
||
callsArgOnWith: function callsArgWith(pos, context) {
|
||
if (typeof pos != "number") {
|
||
throw new TypeError("argument index is not number");
|
||
}
|
||
if (typeof context != "object") {
|
||
throw new TypeError("argument context is not an object");
|
||
}
|
||
|
||
this.callArgAt = pos;
|
||
this.callbackArguments = slice.call(arguments, 2);
|
||
this.callbackContext = context;
|
||
this.callArgProp = undefined;
|
||
this.callbackAsync = false;
|
||
|
||
return this;
|
||
},
|
||
|
||
yields: function () {
|
||
this.callArgAt = -1;
|
||
this.callbackArguments = slice.call(arguments, 0);
|
||
this.callbackContext = undefined;
|
||
this.callArgProp = undefined;
|
||
this.callbackAsync = false;
|
||
|
||
return this;
|
||
},
|
||
|
||
yieldsOn: function (context) {
|
||
if (typeof context != "object") {
|
||
throw new TypeError("argument context is not an object");
|
||
}
|
||
|
||
this.callArgAt = -1;
|
||
this.callbackArguments = slice.call(arguments, 1);
|
||
this.callbackContext = context;
|
||
this.callArgProp = undefined;
|
||
this.callbackAsync = false;
|
||
|
||
return this;
|
||
},
|
||
|
||
yieldsTo: function (prop) {
|
||
this.callArgAt = -1;
|
||
this.callbackArguments = slice.call(arguments, 1);
|
||
this.callbackContext = undefined;
|
||
this.callArgProp = prop;
|
||
this.callbackAsync = false;
|
||
|
||
return this;
|
||
},
|
||
|
||
yieldsToOn: function (prop, context) {
|
||
if (typeof context != "object") {
|
||
throw new TypeError("argument context is not an object");
|
||
}
|
||
|
||
this.callArgAt = -1;
|
||
this.callbackArguments = slice.call(arguments, 2);
|
||
this.callbackContext = context;
|
||
this.callArgProp = prop;
|
||
this.callbackAsync = false;
|
||
|
||
return this;
|
||
},
|
||
|
||
|
||
"throws": throwsException,
|
||
throwsException: throwsException,
|
||
|
||
returns: function returns(value) {
|
||
this.returnValue = value;
|
||
this.returnValueDefined = true;
|
||
|
||
return this;
|
||
},
|
||
|
||
returnsArg: function returnsArg(pos) {
|
||
if (typeof pos != "number") {
|
||
throw new TypeError("argument index is not number");
|
||
}
|
||
|
||
this.returnArgAt = pos;
|
||
|
||
return this;
|
||
},
|
||
|
||
returnsThis: function returnsThis() {
|
||
this.returnThis = true;
|
||
|
||
return this;
|
||
}
|
||
};
|
||
|
||
// create asynchronous versions of callsArg* and yields* methods
|
||
for (var method in proto) {
|
||
// need to avoid creating anotherasync versions of the newly added async methods
|
||
if (proto.hasOwnProperty(method) &&
|
||
method.match(/^(callsArg|yields)/) &&
|
||
!method.match(/Async/)) {
|
||
proto[method + 'Async'] = (function (syncFnName) {
|
||
return function () {
|
||
var result = this[syncFnName].apply(this, arguments);
|
||
this.callbackAsync = true;
|
||
return result;
|
||
};
|
||
})(method);
|
||
}
|
||
}
|
||
|
||
sinon.behavior = proto;
|
||
|
||
if (typeof define === "function" && define.amd) {
|
||
define(["module"], function(module) { module.exports = proto; });
|
||
} else if (commonJSModule) {
|
||
module.exports = proto;
|
||
}
|
||
}(typeof sinon == "object" && sinon || null));
|
||
|
||
}).call(this,require("1YiZ5S"))
|
||
},{"../sinon":69,"1YiZ5S":62}],72:[function(require,module,exports){
|
||
/**
|
||
* @depend ../sinon.js
|
||
* @depend match.js
|
||
*/
|
||
/*jslint eqeqeq: false, onevar: false, plusplus: false*/
|
||
/*global module, require, sinon*/
|
||
/**
|
||
* Spy calls
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @author Maximilian Antoni (mail@maxantoni.de)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
* Copyright (c) 2013 Maximilian Antoni
|
||
*/
|
||
"use strict";
|
||
|
||
(function (sinon) {
|
||
var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
|
||
if (!sinon && commonJSModule) {
|
||
sinon = require("../sinon");
|
||
}
|
||
|
||
if (!sinon) {
|
||
return;
|
||
}
|
||
|
||
function throwYieldError(proxy, text, args) {
|
||
var msg = sinon.functionName(proxy) + text;
|
||
if (args.length) {
|
||
msg += " Received [" + slice.call(args).join(", ") + "]";
|
||
}
|
||
throw new Error(msg);
|
||
}
|
||
|
||
var slice = Array.prototype.slice;
|
||
|
||
var callProto = {
|
||
calledOn: function calledOn(thisValue) {
|
||
if (sinon.match && sinon.match.isMatcher(thisValue)) {
|
||
return thisValue.test(this.thisValue);
|
||
}
|
||
return this.thisValue === thisValue;
|
||
},
|
||
|
||
calledWith: function calledWith() {
|
||
for (var i = 0, l = arguments.length; i < l; i += 1) {
|
||
if (!sinon.deepEqual(arguments[i], this.args[i])) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
},
|
||
|
||
calledWithMatch: function calledWithMatch() {
|
||
for (var i = 0, l = arguments.length; i < l; i += 1) {
|
||
var actual = this.args[i];
|
||
var expectation = arguments[i];
|
||
if (!sinon.match || !sinon.match(expectation).test(actual)) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
},
|
||
|
||
calledWithExactly: function calledWithExactly() {
|
||
return arguments.length == this.args.length &&
|
||
this.calledWith.apply(this, arguments);
|
||
},
|
||
|
||
notCalledWith: function notCalledWith() {
|
||
return !this.calledWith.apply(this, arguments);
|
||
},
|
||
|
||
notCalledWithMatch: function notCalledWithMatch() {
|
||
return !this.calledWithMatch.apply(this, arguments);
|
||
},
|
||
|
||
returned: function returned(value) {
|
||
return sinon.deepEqual(value, this.returnValue);
|
||
},
|
||
|
||
threw: function threw(error) {
|
||
if (typeof error === "undefined" || !this.exception) {
|
||
return !!this.exception;
|
||
}
|
||
|
||
return this.exception === error || this.exception.name === error;
|
||
},
|
||
|
||
calledWithNew: function calledWithNew() {
|
||
return this.proxy.prototype && this.thisValue instanceof this.proxy;
|
||
},
|
||
|
||
calledBefore: function (other) {
|
||
return this.callId < other.callId;
|
||
},
|
||
|
||
calledAfter: function (other) {
|
||
return this.callId > other.callId;
|
||
},
|
||
|
||
callArg: function (pos) {
|
||
this.args[pos]();
|
||
},
|
||
|
||
callArgOn: function (pos, thisValue) {
|
||
this.args[pos].apply(thisValue);
|
||
},
|
||
|
||
callArgWith: function (pos) {
|
||
this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
|
||
},
|
||
|
||
callArgOnWith: function (pos, thisValue) {
|
||
var args = slice.call(arguments, 2);
|
||
this.args[pos].apply(thisValue, args);
|
||
},
|
||
|
||
"yield": function () {
|
||
this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
|
||
},
|
||
|
||
yieldOn: function (thisValue) {
|
||
var args = this.args;
|
||
for (var i = 0, l = args.length; i < l; ++i) {
|
||
if (typeof args[i] === "function") {
|
||
args[i].apply(thisValue, slice.call(arguments, 1));
|
||
return;
|
||
}
|
||
}
|
||
throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
|
||
},
|
||
|
||
yieldTo: function (prop) {
|
||
this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
|
||
},
|
||
|
||
yieldToOn: function (prop, thisValue) {
|
||
var args = this.args;
|
||
for (var i = 0, l = args.length; i < l; ++i) {
|
||
if (args[i] && typeof args[i][prop] === "function") {
|
||
args[i][prop].apply(thisValue, slice.call(arguments, 2));
|
||
return;
|
||
}
|
||
}
|
||
throwYieldError(this.proxy, " cannot yield to '" + prop +
|
||
"' since no callback was passed.", args);
|
||
},
|
||
|
||
toString: function () {
|
||
var callStr = this.proxy.toString() + "(";
|
||
var args = [];
|
||
|
||
for (var i = 0, l = this.args.length; i < l; ++i) {
|
||
args.push(sinon.format(this.args[i]));
|
||
}
|
||
|
||
callStr = callStr + args.join(", ") + ")";
|
||
|
||
if (typeof this.returnValue != "undefined") {
|
||
callStr += " => " + sinon.format(this.returnValue);
|
||
}
|
||
|
||
if (this.exception) {
|
||
callStr += " !" + this.exception.name;
|
||
|
||
if (this.exception.message) {
|
||
callStr += "(" + this.exception.message + ")";
|
||
}
|
||
}
|
||
|
||
return callStr;
|
||
}
|
||
};
|
||
|
||
callProto.invokeCallback = callProto.yield;
|
||
|
||
function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
|
||
if (typeof id !== "number") {
|
||
throw new TypeError("Call id is not a number");
|
||
}
|
||
var proxyCall = sinon.create(callProto);
|
||
proxyCall.proxy = spy;
|
||
proxyCall.thisValue = thisValue;
|
||
proxyCall.args = args;
|
||
proxyCall.returnValue = returnValue;
|
||
proxyCall.exception = exception;
|
||
proxyCall.callId = id;
|
||
|
||
return proxyCall;
|
||
}
|
||
createSpyCall.toString = callProto.toString; // used by mocks
|
||
|
||
sinon.spyCall = createSpyCall;
|
||
|
||
if (typeof define === "function" && define.amd) {
|
||
define(["module"], function(module) { module.exports = createSpyCall; });
|
||
} else if (commonJSModule) {
|
||
module.exports = createSpyCall;
|
||
}
|
||
}(typeof sinon == "object" && sinon || null));
|
||
|
||
|
||
},{"../sinon":69}],73:[function(require,module,exports){
|
||
/**
|
||
* @depend ../sinon.js
|
||
* @depend stub.js
|
||
* @depend mock.js
|
||
*/
|
||
/*jslint eqeqeq: false, onevar: false, forin: true*/
|
||
/*global module, require, sinon*/
|
||
/**
|
||
* Collections of stubs, spies and mocks.
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
*/
|
||
"use strict";
|
||
|
||
(function (sinon) {
|
||
var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
|
||
var push = [].push;
|
||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||
|
||
if (!sinon && commonJSModule) {
|
||
sinon = require("../sinon");
|
||
}
|
||
|
||
if (!sinon) {
|
||
return;
|
||
}
|
||
|
||
function getFakes(fakeCollection) {
|
||
if (!fakeCollection.fakes) {
|
||
fakeCollection.fakes = [];
|
||
}
|
||
|
||
return fakeCollection.fakes;
|
||
}
|
||
|
||
function each(fakeCollection, method) {
|
||
var fakes = getFakes(fakeCollection);
|
||
|
||
for (var i = 0, l = fakes.length; i < l; i += 1) {
|
||
if (typeof fakes[i][method] == "function") {
|
||
fakes[i][method]();
|
||
}
|
||
}
|
||
}
|
||
|
||
function compact(fakeCollection) {
|
||
var fakes = getFakes(fakeCollection);
|
||
var i = 0;
|
||
while (i < fakes.length) {
|
||
fakes.splice(i, 1);
|
||
}
|
||
}
|
||
|
||
var collection = {
|
||
verify: function resolve() {
|
||
each(this, "verify");
|
||
},
|
||
|
||
restore: function restore() {
|
||
each(this, "restore");
|
||
compact(this);
|
||
},
|
||
|
||
verifyAndRestore: function verifyAndRestore() {
|
||
var exception;
|
||
|
||
try {
|
||
this.verify();
|
||
} catch (e) {
|
||
exception = e;
|
||
}
|
||
|
||
this.restore();
|
||
|
||
if (exception) {
|
||
throw exception;
|
||
}
|
||
},
|
||
|
||
add: function add(fake) {
|
||
push.call(getFakes(this), fake);
|
||
return fake;
|
||
},
|
||
|
||
spy: function spy() {
|
||
return this.add(sinon.spy.apply(sinon, arguments));
|
||
},
|
||
|
||
stub: function stub(object, property, value) {
|
||
if (property) {
|
||
var original = object[property];
|
||
|
||
if (typeof original != "function") {
|
||
if (!hasOwnProperty.call(object, property)) {
|
||
throw new TypeError("Cannot stub non-existent own property " + property);
|
||
}
|
||
|
||
object[property] = value;
|
||
|
||
return this.add({
|
||
restore: function () {
|
||
object[property] = original;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
if (!property && !!object && typeof object == "object") {
|
||
var stubbedObj = sinon.stub.apply(sinon, arguments);
|
||
|
||
for (var prop in stubbedObj) {
|
||
if (typeof stubbedObj[prop] === "function") {
|
||
this.add(stubbedObj[prop]);
|
||
}
|
||
}
|
||
|
||
return stubbedObj;
|
||
}
|
||
|
||
return this.add(sinon.stub.apply(sinon, arguments));
|
||
},
|
||
|
||
mock: function mock() {
|
||
return this.add(sinon.mock.apply(sinon, arguments));
|
||
},
|
||
|
||
inject: function inject(obj) {
|
||
var col = this;
|
||
|
||
obj.spy = function () {
|
||
return col.spy.apply(col, arguments);
|
||
};
|
||
|
||
obj.stub = function () {
|
||
return col.stub.apply(col, arguments);
|
||
};
|
||
|
||
obj.mock = function () {
|
||
return col.mock.apply(col, arguments);
|
||
};
|
||
|
||
return obj;
|
||
}
|
||
};
|
||
|
||
sinon.collection = collection;
|
||
|
||
if (typeof define === "function" && define.amd) {
|
||
define(["module"], function(module) { module.exports = collection; });
|
||
} else if (commonJSModule) {
|
||
module.exports = collection;
|
||
}
|
||
}(typeof sinon == "object" && sinon || null));
|
||
|
||
},{"../sinon":69}],74:[function(require,module,exports){
|
||
/* @depend ../sinon.js */
|
||
/*jslint eqeqeq: false, onevar: false, plusplus: false*/
|
||
/*global module, require, sinon*/
|
||
/**
|
||
* Match functions
|
||
*
|
||
* @author Maximilian Antoni (mail@maxantoni.de)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2012 Maximilian Antoni
|
||
*/
|
||
"use strict";
|
||
|
||
(function (sinon) {
|
||
var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
|
||
|
||
if (!sinon && commonJSModule) {
|
||
sinon = require("../sinon");
|
||
}
|
||
|
||
if (!sinon) {
|
||
return;
|
||
}
|
||
|
||
function assertType(value, type, name) {
|
||
var actual = sinon.typeOf(value);
|
||
if (actual !== type) {
|
||
throw new TypeError("Expected type of " + name + " to be " +
|
||
type + ", but was " + actual);
|
||
}
|
||
}
|
||
|
||
var matcher = {
|
||
toString: function () {
|
||
return this.message;
|
||
}
|
||
};
|
||
|
||
function isMatcher(object) {
|
||
return matcher.isPrototypeOf(object);
|
||
}
|
||
|
||
function matchObject(expectation, actual) {
|
||
if (actual === null || actual === undefined) {
|
||
return false;
|
||
}
|
||
for (var key in expectation) {
|
||
if (expectation.hasOwnProperty(key)) {
|
||
var exp = expectation[key];
|
||
var act = actual[key];
|
||
if (match.isMatcher(exp)) {
|
||
if (!exp.test(act)) {
|
||
return false;
|
||
}
|
||
} else if (sinon.typeOf(exp) === "object") {
|
||
if (!matchObject(exp, act)) {
|
||
return false;
|
||
}
|
||
} else if (!sinon.deepEqual(exp, act)) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
matcher.or = function (m2) {
|
||
if (!arguments.length) {
|
||
throw new TypeError("Matcher expected");
|
||
} else if (!isMatcher(m2)) {
|
||
m2 = match(m2);
|
||
}
|
||
var m1 = this;
|
||
var or = sinon.create(matcher);
|
||
or.test = function (actual) {
|
||
return m1.test(actual) || m2.test(actual);
|
||
};
|
||
or.message = m1.message + ".or(" + m2.message + ")";
|
||
return or;
|
||
};
|
||
|
||
matcher.and = function (m2) {
|
||
if (!arguments.length) {
|
||
throw new TypeError("Matcher expected");
|
||
} else if (!isMatcher(m2)) {
|
||
m2 = match(m2);
|
||
}
|
||
var m1 = this;
|
||
var and = sinon.create(matcher);
|
||
and.test = function (actual) {
|
||
return m1.test(actual) && m2.test(actual);
|
||
};
|
||
and.message = m1.message + ".and(" + m2.message + ")";
|
||
return and;
|
||
};
|
||
|
||
var match = function (expectation, message) {
|
||
var m = sinon.create(matcher);
|
||
var type = sinon.typeOf(expectation);
|
||
switch (type) {
|
||
case "object":
|
||
if (typeof expectation.test === "function") {
|
||
m.test = function (actual) {
|
||
return expectation.test(actual) === true;
|
||
};
|
||
m.message = "match(" + sinon.functionName(expectation.test) + ")";
|
||
return m;
|
||
}
|
||
var str = [];
|
||
for (var key in expectation) {
|
||
if (expectation.hasOwnProperty(key)) {
|
||
str.push(key + ": " + expectation[key]);
|
||
}
|
||
}
|
||
m.test = function (actual) {
|
||
return matchObject(expectation, actual);
|
||
};
|
||
m.message = "match(" + str.join(", ") + ")";
|
||
break;
|
||
case "number":
|
||
m.test = function (actual) {
|
||
return expectation == actual;
|
||
};
|
||
break;
|
||
case "string":
|
||
m.test = function (actual) {
|
||
if (typeof actual !== "string") {
|
||
return false;
|
||
}
|
||
return actual.indexOf(expectation) !== -1;
|
||
};
|
||
m.message = "match(\"" + expectation + "\")";
|
||
break;
|
||
case "regexp":
|
||
m.test = function (actual) {
|
||
if (typeof actual !== "string") {
|
||
return false;
|
||
}
|
||
return expectation.test(actual);
|
||
};
|
||
break;
|
||
case "function":
|
||
m.test = expectation;
|
||
if (message) {
|
||
m.message = message;
|
||
} else {
|
||
m.message = "match(" + sinon.functionName(expectation) + ")";
|
||
}
|
||
break;
|
||
default:
|
||
m.test = function (actual) {
|
||
return sinon.deepEqual(expectation, actual);
|
||
};
|
||
}
|
||
if (!m.message) {
|
||
m.message = "match(" + expectation + ")";
|
||
}
|
||
return m;
|
||
};
|
||
|
||
match.isMatcher = isMatcher;
|
||
|
||
match.any = match(function () {
|
||
return true;
|
||
}, "any");
|
||
|
||
match.defined = match(function (actual) {
|
||
return actual !== null && actual !== undefined;
|
||
}, "defined");
|
||
|
||
match.truthy = match(function (actual) {
|
||
return !!actual;
|
||
}, "truthy");
|
||
|
||
match.falsy = match(function (actual) {
|
||
return !actual;
|
||
}, "falsy");
|
||
|
||
match.same = function (expectation) {
|
||
return match(function (actual) {
|
||
return expectation === actual;
|
||
}, "same(" + expectation + ")");
|
||
};
|
||
|
||
match.typeOf = function (type) {
|
||
assertType(type, "string", "type");
|
||
return match(function (actual) {
|
||
return sinon.typeOf(actual) === type;
|
||
}, "typeOf(\"" + type + "\")");
|
||
};
|
||
|
||
match.instanceOf = function (type) {
|
||
assertType(type, "function", "type");
|
||
return match(function (actual) {
|
||
return actual instanceof type;
|
||
}, "instanceOf(" + sinon.functionName(type) + ")");
|
||
};
|
||
|
||
function createPropertyMatcher(propertyTest, messagePrefix) {
|
||
return function (property, value) {
|
||
assertType(property, "string", "property");
|
||
var onlyProperty = arguments.length === 1;
|
||
var message = messagePrefix + "(\"" + property + "\"";
|
||
if (!onlyProperty) {
|
||
message += ", " + value;
|
||
}
|
||
message += ")";
|
||
return match(function (actual) {
|
||
if (actual === undefined || actual === null ||
|
||
!propertyTest(actual, property)) {
|
||
return false;
|
||
}
|
||
return onlyProperty || sinon.deepEqual(value, actual[property]);
|
||
}, message);
|
||
};
|
||
}
|
||
|
||
match.has = createPropertyMatcher(function (actual, property) {
|
||
if (typeof actual === "object") {
|
||
return property in actual;
|
||
}
|
||
return actual[property] !== undefined;
|
||
}, "has");
|
||
|
||
match.hasOwn = createPropertyMatcher(function (actual, property) {
|
||
return actual.hasOwnProperty(property);
|
||
}, "hasOwn");
|
||
|
||
match.bool = match.typeOf("boolean");
|
||
match.number = match.typeOf("number");
|
||
match.string = match.typeOf("string");
|
||
match.object = match.typeOf("object");
|
||
match.func = match.typeOf("function");
|
||
match.array = match.typeOf("array");
|
||
match.regexp = match.typeOf("regexp");
|
||
match.date = match.typeOf("date");
|
||
|
||
sinon.match = match;
|
||
|
||
if (typeof define === "function" && define.amd) {
|
||
define(["module"], function(module) { module.exports = match; });
|
||
} else if (commonJSModule) {
|
||
module.exports = match;
|
||
}
|
||
}(typeof sinon == "object" && sinon || null));
|
||
|
||
},{"../sinon":69}],75:[function(require,module,exports){
|
||
/**
|
||
* @depend ../sinon.js
|
||
* @depend stub.js
|
||
*/
|
||
/*jslint eqeqeq: false, onevar: false, nomen: false*/
|
||
/*global module, require, sinon*/
|
||
/**
|
||
* Mock functions.
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
*/
|
||
"use strict";
|
||
|
||
(function (sinon) {
|
||
var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
|
||
var push = [].push;
|
||
var match;
|
||
|
||
if (!sinon && commonJSModule) {
|
||
sinon = require("../sinon");
|
||
}
|
||
|
||
if (!sinon) {
|
||
return;
|
||
}
|
||
|
||
match = sinon.match;
|
||
|
||
if (!match && commonJSModule) {
|
||
match = require("./match");
|
||
}
|
||
|
||
function mock(object) {
|
||
if (!object) {
|
||
return sinon.expectation.create("Anonymous mock");
|
||
}
|
||
|
||
return mock.create(object);
|
||
}
|
||
|
||
sinon.mock = mock;
|
||
|
||
sinon.extend(mock, (function () {
|
||
function each(collection, callback) {
|
||
if (!collection) {
|
||
return;
|
||
}
|
||
|
||
for (var i = 0, l = collection.length; i < l; i += 1) {
|
||
callback(collection[i]);
|
||
}
|
||
}
|
||
|
||
return {
|
||
create: function create(object) {
|
||
if (!object) {
|
||
throw new TypeError("object is null");
|
||
}
|
||
|
||
var mockObject = sinon.extend({}, mock);
|
||
mockObject.object = object;
|
||
delete mockObject.create;
|
||
|
||
return mockObject;
|
||
},
|
||
|
||
expects: function expects(method) {
|
||
if (!method) {
|
||
throw new TypeError("method is falsy");
|
||
}
|
||
|
||
if (!this.expectations) {
|
||
this.expectations = {};
|
||
this.proxies = [];
|
||
}
|
||
|
||
if (!this.expectations[method]) {
|
||
this.expectations[method] = [];
|
||
var mockObject = this;
|
||
|
||
sinon.wrapMethod(this.object, method, function () {
|
||
return mockObject.invokeMethod(method, this, arguments);
|
||
});
|
||
|
||
push.call(this.proxies, method);
|
||
}
|
||
|
||
var expectation = sinon.expectation.create(method);
|
||
push.call(this.expectations[method], expectation);
|
||
|
||
return expectation;
|
||
},
|
||
|
||
restore: function restore() {
|
||
var object = this.object;
|
||
|
||
each(this.proxies, function (proxy) {
|
||
if (typeof object[proxy].restore == "function") {
|
||
object[proxy].restore();
|
||
}
|
||
});
|
||
},
|
||
|
||
verify: function verify() {
|
||
var expectations = this.expectations || {};
|
||
var messages = [], met = [];
|
||
|
||
each(this.proxies, function (proxy) {
|
||
each(expectations[proxy], function (expectation) {
|
||
if (!expectation.met()) {
|
||
push.call(messages, expectation.toString());
|
||
} else {
|
||
push.call(met, expectation.toString());
|
||
}
|
||
});
|
||
});
|
||
|
||
this.restore();
|
||
|
||
if (messages.length > 0) {
|
||
sinon.expectation.fail(messages.concat(met).join("\n"));
|
||
} else {
|
||
sinon.expectation.pass(messages.concat(met).join("\n"));
|
||
}
|
||
|
||
return true;
|
||
},
|
||
|
||
invokeMethod: function invokeMethod(method, thisValue, args) {
|
||
var expectations = this.expectations && this.expectations[method];
|
||
var length = expectations && expectations.length || 0, i;
|
||
|
||
for (i = 0; i < length; i += 1) {
|
||
if (!expectations[i].met() &&
|
||
expectations[i].allowsCall(thisValue, args)) {
|
||
return expectations[i].apply(thisValue, args);
|
||
}
|
||
}
|
||
|
||
var messages = [], available, exhausted = 0;
|
||
|
||
for (i = 0; i < length; i += 1) {
|
||
if (expectations[i].allowsCall(thisValue, args)) {
|
||
available = available || expectations[i];
|
||
} else {
|
||
exhausted += 1;
|
||
}
|
||
push.call(messages, " " + expectations[i].toString());
|
||
}
|
||
|
||
if (exhausted === 0) {
|
||
return available.apply(thisValue, args);
|
||
}
|
||
|
||
messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
|
||
proxy: method,
|
||
args: args
|
||
}));
|
||
|
||
sinon.expectation.fail(messages.join("\n"));
|
||
}
|
||
};
|
||
}()));
|
||
|
||
var times = sinon.timesInWords;
|
||
|
||
sinon.expectation = (function () {
|
||
var slice = Array.prototype.slice;
|
||
var _invoke = sinon.spy.invoke;
|
||
|
||
function callCountInWords(callCount) {
|
||
if (callCount == 0) {
|
||
return "never called";
|
||
} else {
|
||
return "called " + times(callCount);
|
||
}
|
||
}
|
||
|
||
function expectedCallCountInWords(expectation) {
|
||
var min = expectation.minCalls;
|
||
var max = expectation.maxCalls;
|
||
|
||
if (typeof min == "number" && typeof max == "number") {
|
||
var str = times(min);
|
||
|
||
if (min != max) {
|
||
str = "at least " + str + " and at most " + times(max);
|
||
}
|
||
|
||
return str;
|
||
}
|
||
|
||
if (typeof min == "number") {
|
||
return "at least " + times(min);
|
||
}
|
||
|
||
return "at most " + times(max);
|
||
}
|
||
|
||
function receivedMinCalls(expectation) {
|
||
var hasMinLimit = typeof expectation.minCalls == "number";
|
||
return !hasMinLimit || expectation.callCount >= expectation.minCalls;
|
||
}
|
||
|
||
function receivedMaxCalls(expectation) {
|
||
if (typeof expectation.maxCalls != "number") {
|
||
return false;
|
||
}
|
||
|
||
return expectation.callCount == expectation.maxCalls;
|
||
}
|
||
|
||
function verifyMatcher(possibleMatcher, arg){
|
||
if (match && match.isMatcher(possibleMatcher)) {
|
||
return possibleMatcher.test(arg);
|
||
} else {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return {
|
||
minCalls: 1,
|
||
maxCalls: 1,
|
||
|
||
create: function create(methodName) {
|
||
var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
|
||
delete expectation.create;
|
||
expectation.method = methodName;
|
||
|
||
return expectation;
|
||
},
|
||
|
||
invoke: function invoke(func, thisValue, args) {
|
||
this.verifyCallAllowed(thisValue, args);
|
||
|
||
return _invoke.apply(this, arguments);
|
||
},
|
||
|
||
atLeast: function atLeast(num) {
|
||
if (typeof num != "number") {
|
||
throw new TypeError("'" + num + "' is not number");
|
||
}
|
||
|
||
if (!this.limitsSet) {
|
||
this.maxCalls = null;
|
||
this.limitsSet = true;
|
||
}
|
||
|
||
this.minCalls = num;
|
||
|
||
return this;
|
||
},
|
||
|
||
atMost: function atMost(num) {
|
||
if (typeof num != "number") {
|
||
throw new TypeError("'" + num + "' is not number");
|
||
}
|
||
|
||
if (!this.limitsSet) {
|
||
this.minCalls = null;
|
||
this.limitsSet = true;
|
||
}
|
||
|
||
this.maxCalls = num;
|
||
|
||
return this;
|
||
},
|
||
|
||
never: function never() {
|
||
return this.exactly(0);
|
||
},
|
||
|
||
once: function once() {
|
||
return this.exactly(1);
|
||
},
|
||
|
||
twice: function twice() {
|
||
return this.exactly(2);
|
||
},
|
||
|
||
thrice: function thrice() {
|
||
return this.exactly(3);
|
||
},
|
||
|
||
exactly: function exactly(num) {
|
||
if (typeof num != "number") {
|
||
throw new TypeError("'" + num + "' is not a number");
|
||
}
|
||
|
||
this.atLeast(num);
|
||
return this.atMost(num);
|
||
},
|
||
|
||
met: function met() {
|
||
return !this.failed && receivedMinCalls(this);
|
||
},
|
||
|
||
verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
|
||
if (receivedMaxCalls(this)) {
|
||
this.failed = true;
|
||
sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
|
||
}
|
||
|
||
if ("expectedThis" in this && this.expectedThis !== thisValue) {
|
||
sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
|
||
this.expectedThis);
|
||
}
|
||
|
||
if (!("expectedArguments" in this)) {
|
||
return;
|
||
}
|
||
|
||
if (!args) {
|
||
sinon.expectation.fail(this.method + " received no arguments, expected " +
|
||
sinon.format(this.expectedArguments));
|
||
}
|
||
|
||
if (args.length < this.expectedArguments.length) {
|
||
sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
|
||
"), expected " + sinon.format(this.expectedArguments));
|
||
}
|
||
|
||
if (this.expectsExactArgCount &&
|
||
args.length != this.expectedArguments.length) {
|
||
sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
|
||
"), expected " + sinon.format(this.expectedArguments));
|
||
}
|
||
|
||
for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
|
||
|
||
if (!verifyMatcher(this.expectedArguments[i],args[i])) {
|
||
sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
|
||
", didn't match " + this.expectedArguments.toString());
|
||
}
|
||
|
||
if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
|
||
sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
|
||
", expected " + sinon.format(this.expectedArguments));
|
||
}
|
||
}
|
||
},
|
||
|
||
allowsCall: function allowsCall(thisValue, args) {
|
||
if (this.met() && receivedMaxCalls(this)) {
|
||
return false;
|
||
}
|
||
|
||
if ("expectedThis" in this && this.expectedThis !== thisValue) {
|
||
return false;
|
||
}
|
||
|
||
if (!("expectedArguments" in this)) {
|
||
return true;
|
||
}
|
||
|
||
args = args || [];
|
||
|
||
if (args.length < this.expectedArguments.length) {
|
||
return false;
|
||
}
|
||
|
||
if (this.expectsExactArgCount &&
|
||
args.length != this.expectedArguments.length) {
|
||
return false;
|
||
}
|
||
|
||
for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
|
||
if (!verifyMatcher(this.expectedArguments[i],args[i])) {
|
||
return false;
|
||
}
|
||
|
||
if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
},
|
||
|
||
withArgs: function withArgs() {
|
||
this.expectedArguments = slice.call(arguments);
|
||
return this;
|
||
},
|
||
|
||
withExactArgs: function withExactArgs() {
|
||
this.withArgs.apply(this, arguments);
|
||
this.expectsExactArgCount = true;
|
||
return this;
|
||
},
|
||
|
||
on: function on(thisValue) {
|
||
this.expectedThis = thisValue;
|
||
return this;
|
||
},
|
||
|
||
toString: function () {
|
||
var args = (this.expectedArguments || []).slice();
|
||
|
||
if (!this.expectsExactArgCount) {
|
||
push.call(args, "[...]");
|
||
}
|
||
|
||
var callStr = sinon.spyCall.toString.call({
|
||
proxy: this.method || "anonymous mock expectation",
|
||
args: args
|
||
});
|
||
|
||
var message = callStr.replace(", [...", "[, ...") + " " +
|
||
expectedCallCountInWords(this);
|
||
|
||
if (this.met()) {
|
||
return "Expectation met: " + message;
|
||
}
|
||
|
||
return "Expected " + message + " (" +
|
||
callCountInWords(this.callCount) + ")";
|
||
},
|
||
|
||
verify: function verify() {
|
||
if (!this.met()) {
|
||
sinon.expectation.fail(this.toString());
|
||
} else {
|
||
sinon.expectation.pass(this.toString());
|
||
}
|
||
|
||
return true;
|
||
},
|
||
|
||
pass: function(message) {
|
||
sinon.assert.pass(message);
|
||
},
|
||
fail: function (message) {
|
||
var exception = new Error(message);
|
||
exception.name = "ExpectationError";
|
||
|
||
throw exception;
|
||
}
|
||
};
|
||
}());
|
||
|
||
sinon.mock = mock;
|
||
|
||
if (typeof define === "function" && define.amd) {
|
||
define(["module"], function(module) { module.exports = mock; });
|
||
} else if (commonJSModule) {
|
||
module.exports = mock;
|
||
}
|
||
}(typeof sinon == "object" && sinon || null));
|
||
|
||
},{"../sinon":69,"./match":74}],76:[function(require,module,exports){
|
||
/**
|
||
* @depend ../sinon.js
|
||
* @depend collection.js
|
||
* @depend util/fake_timers.js
|
||
* @depend util/fake_server_with_clock.js
|
||
*/
|
||
/*jslint eqeqeq: false, onevar: false, plusplus: false*/
|
||
/*global require, module*/
|
||
/**
|
||
* Manages fake collections as well as fake utilities such as Sinon's
|
||
* timers and fake XHR implementation in one convenient object.
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
*/
|
||
"use strict";
|
||
|
||
if (typeof module !== "undefined" && module.exports && typeof require == "function") {
|
||
var sinon = require("../sinon");
|
||
sinon.extend(sinon, require("./util/fake_timers"));
|
||
}
|
||
|
||
(function () {
|
||
var push = [].push;
|
||
|
||
function exposeValue(sandbox, config, key, value) {
|
||
if (!value) {
|
||
return;
|
||
}
|
||
|
||
if (config.injectInto && !(key in config.injectInto)) {
|
||
config.injectInto[key] = value;
|
||
sandbox.injectedKeys.push(key);
|
||
} else {
|
||
push.call(sandbox.args, value);
|
||
}
|
||
}
|
||
|
||
function prepareSandboxFromConfig(config) {
|
||
var sandbox = sinon.create(sinon.sandbox);
|
||
|
||
if (config.useFakeServer) {
|
||
if (typeof config.useFakeServer == "object") {
|
||
sandbox.serverPrototype = config.useFakeServer;
|
||
}
|
||
|
||
sandbox.useFakeServer();
|
||
}
|
||
|
||
if (config.useFakeTimers) {
|
||
if (typeof config.useFakeTimers == "object") {
|
||
sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
|
||
} else {
|
||
sandbox.useFakeTimers();
|
||
}
|
||
}
|
||
|
||
return sandbox;
|
||
}
|
||
|
||
sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
|
||
useFakeTimers: function useFakeTimers() {
|
||
this.clock = sinon.useFakeTimers.apply(sinon, arguments);
|
||
|
||
return this.add(this.clock);
|
||
},
|
||
|
||
serverPrototype: sinon.fakeServer,
|
||
|
||
useFakeServer: function useFakeServer() {
|
||
var proto = this.serverPrototype || sinon.fakeServer;
|
||
|
||
if (!proto || !proto.create) {
|
||
return null;
|
||
}
|
||
|
||
this.server = proto.create();
|
||
return this.add(this.server);
|
||
},
|
||
|
||
inject: function (obj) {
|
||
sinon.collection.inject.call(this, obj);
|
||
|
||
if (this.clock) {
|
||
obj.clock = this.clock;
|
||
}
|
||
|
||
if (this.server) {
|
||
obj.server = this.server;
|
||
obj.requests = this.server.requests;
|
||
}
|
||
|
||
return obj;
|
||
},
|
||
|
||
restore: function () {
|
||
sinon.collection.restore.apply(this, arguments);
|
||
this.restoreContext();
|
||
},
|
||
|
||
restoreContext: function () {
|
||
if (this.injectedKeys) {
|
||
for (var i = 0, j = this.injectedKeys.length; i < j; i++) {
|
||
delete this.injectInto[this.injectedKeys[i]];
|
||
}
|
||
this.injectedKeys = [];
|
||
}
|
||
},
|
||
|
||
create: function (config) {
|
||
if (!config) {
|
||
return sinon.create(sinon.sandbox);
|
||
}
|
||
|
||
var sandbox = prepareSandboxFromConfig(config);
|
||
sandbox.args = sandbox.args || [];
|
||
sandbox.injectedKeys = [];
|
||
sandbox.injectInto = config.injectInto;
|
||
var prop, value, exposed = sandbox.inject({});
|
||
|
||
if (config.properties) {
|
||
for (var i = 0, l = config.properties.length; i < l; i++) {
|
||
prop = config.properties[i];
|
||
value = exposed[prop] || prop == "sandbox" && sandbox;
|
||
exposeValue(sandbox, config, prop, value);
|
||
}
|
||
} else {
|
||
exposeValue(sandbox, config, "sandbox", value);
|
||
}
|
||
|
||
return sandbox;
|
||
}
|
||
});
|
||
|
||
sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
|
||
|
||
if (typeof define === "function" && define.amd) {
|
||
define(["module"], function(module) { module.exports = sinon.sandbox; });
|
||
} else if (typeof module !== 'undefined' && module.exports) {
|
||
module.exports = sinon.sandbox;
|
||
}
|
||
}());
|
||
|
||
},{"../sinon":69,"./util/fake_timers":81}],77:[function(require,module,exports){
|
||
/**
|
||
* @depend ../sinon.js
|
||
* @depend call.js
|
||
*/
|
||
/*jslint eqeqeq: false, onevar: false, plusplus: false*/
|
||
/*global module, require, sinon*/
|
||
/**
|
||
* Spy functions
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
*/
|
||
"use strict";
|
||
|
||
(function (sinon) {
|
||
var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
|
||
var push = Array.prototype.push;
|
||
var slice = Array.prototype.slice;
|
||
var callId = 0;
|
||
|
||
if (!sinon && commonJSModule) {
|
||
sinon = require("../sinon");
|
||
}
|
||
|
||
if (!sinon) {
|
||
return;
|
||
}
|
||
|
||
function spy(object, property) {
|
||
if (!property && typeof object == "function") {
|
||
return spy.create(object);
|
||
}
|
||
|
||
if (!object && !property) {
|
||
return spy.create(function () { });
|
||
}
|
||
|
||
var method = object[property];
|
||
return sinon.wrapMethod(object, property, spy.create(method));
|
||
}
|
||
|
||
function matchingFake(fakes, args, strict) {
|
||
if (!fakes) {
|
||
return;
|
||
}
|
||
|
||
for (var i = 0, l = fakes.length; i < l; i++) {
|
||
if (fakes[i].matches(args, strict)) {
|
||
return fakes[i];
|
||
}
|
||
}
|
||
}
|
||
|
||
function incrementCallCount() {
|
||
this.called = true;
|
||
this.callCount += 1;
|
||
this.notCalled = false;
|
||
this.calledOnce = this.callCount == 1;
|
||
this.calledTwice = this.callCount == 2;
|
||
this.calledThrice = this.callCount == 3;
|
||
}
|
||
|
||
function createCallProperties() {
|
||
this.firstCall = this.getCall(0);
|
||
this.secondCall = this.getCall(1);
|
||
this.thirdCall = this.getCall(2);
|
||
this.lastCall = this.getCall(this.callCount - 1);
|
||
}
|
||
|
||
var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
|
||
function createProxy(func) {
|
||
// Retain the function length:
|
||
var p;
|
||
if (func.length) {
|
||
eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
|
||
") { return p.invoke(func, this, slice.call(arguments)); });");
|
||
}
|
||
else {
|
||
p = function proxy() {
|
||
return p.invoke(func, this, slice.call(arguments));
|
||
};
|
||
}
|
||
return p;
|
||
}
|
||
|
||
var uuid = 0;
|
||
|
||
// Public API
|
||
var spyApi = {
|
||
reset: function () {
|
||
this.called = false;
|
||
this.notCalled = true;
|
||
this.calledOnce = false;
|
||
this.calledTwice = false;
|
||
this.calledThrice = false;
|
||
this.callCount = 0;
|
||
this.firstCall = null;
|
||
this.secondCall = null;
|
||
this.thirdCall = null;
|
||
this.lastCall = null;
|
||
this.args = [];
|
||
this.returnValues = [];
|
||
this.thisValues = [];
|
||
this.exceptions = [];
|
||
this.callIds = [];
|
||
if (this.fakes) {
|
||
for (var i = 0; i < this.fakes.length; i++) {
|
||
this.fakes[i].reset();
|
||
}
|
||
}
|
||
},
|
||
|
||
create: function create(func) {
|
||
var name;
|
||
|
||
if (typeof func != "function") {
|
||
func = function () { };
|
||
} else {
|
||
name = sinon.functionName(func);
|
||
}
|
||
|
||
var proxy = createProxy(func);
|
||
|
||
sinon.extend(proxy, spy);
|
||
delete proxy.create;
|
||
sinon.extend(proxy, func);
|
||
|
||
proxy.reset();
|
||
proxy.prototype = func.prototype;
|
||
proxy.displayName = name || "spy";
|
||
proxy.toString = sinon.functionToString;
|
||
proxy._create = sinon.spy.create;
|
||
proxy.id = "spy#" + uuid++;
|
||
|
||
return proxy;
|
||
},
|
||
|
||
invoke: function invoke(func, thisValue, args) {
|
||
var matching = matchingFake(this.fakes, args);
|
||
var exception, returnValue;
|
||
|
||
incrementCallCount.call(this);
|
||
push.call(this.thisValues, thisValue);
|
||
push.call(this.args, args);
|
||
push.call(this.callIds, callId++);
|
||
|
||
// Make call properties available from within the spied function:
|
||
createCallProperties.call(this);
|
||
|
||
try {
|
||
if (matching) {
|
||
returnValue = matching.invoke(func, thisValue, args);
|
||
} else {
|
||
returnValue = (this.func || func).apply(thisValue, args);
|
||
}
|
||
|
||
var thisCall = this.getCall(this.callCount - 1);
|
||
if (thisCall.calledWithNew() && typeof returnValue !== 'object') {
|
||
returnValue = thisValue;
|
||
}
|
||
} catch (e) {
|
||
exception = e;
|
||
}
|
||
|
||
push.call(this.exceptions, exception);
|
||
push.call(this.returnValues, returnValue);
|
||
|
||
// Make return value and exception available in the calls:
|
||
createCallProperties.call(this);
|
||
|
||
if (exception !== undefined) {
|
||
throw exception;
|
||
}
|
||
|
||
return returnValue;
|
||
},
|
||
|
||
named: function named(name) {
|
||
this.displayName = name;
|
||
return this;
|
||
},
|
||
|
||
getCall: function getCall(i) {
|
||
if (i < 0 || i >= this.callCount) {
|
||
return null;
|
||
}
|
||
|
||
return sinon.spyCall(this, this.thisValues[i], this.args[i],
|
||
this.returnValues[i], this.exceptions[i],
|
||
this.callIds[i]);
|
||
},
|
||
|
||
getCalls: function () {
|
||
var calls = [];
|
||
var i;
|
||
|
||
for (i = 0; i < this.callCount; i++) {
|
||
calls.push(this.getCall(i));
|
||
}
|
||
|
||
return calls;
|
||
},
|
||
|
||
calledBefore: function calledBefore(spyFn) {
|
||
if (!this.called) {
|
||
return false;
|
||
}
|
||
|
||
if (!spyFn.called) {
|
||
return true;
|
||
}
|
||
|
||
return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
|
||
},
|
||
|
||
calledAfter: function calledAfter(spyFn) {
|
||
if (!this.called || !spyFn.called) {
|
||
return false;
|
||
}
|
||
|
||
return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
|
||
},
|
||
|
||
withArgs: function () {
|
||
var args = slice.call(arguments);
|
||
|
||
if (this.fakes) {
|
||
var match = matchingFake(this.fakes, args, true);
|
||
|
||
if (match) {
|
||
return match;
|
||
}
|
||
} else {
|
||
this.fakes = [];
|
||
}
|
||
|
||
var original = this;
|
||
var fake = this._create();
|
||
fake.matchingAguments = args;
|
||
fake.parent = this;
|
||
push.call(this.fakes, fake);
|
||
|
||
fake.withArgs = function () {
|
||
return original.withArgs.apply(original, arguments);
|
||
};
|
||
|
||
for (var i = 0; i < this.args.length; i++) {
|
||
if (fake.matches(this.args[i])) {
|
||
incrementCallCount.call(fake);
|
||
push.call(fake.thisValues, this.thisValues[i]);
|
||
push.call(fake.args, this.args[i]);
|
||
push.call(fake.returnValues, this.returnValues[i]);
|
||
push.call(fake.exceptions, this.exceptions[i]);
|
||
push.call(fake.callIds, this.callIds[i]);
|
||
}
|
||
}
|
||
createCallProperties.call(fake);
|
||
|
||
return fake;
|
||
},
|
||
|
||
matches: function (args, strict) {
|
||
var margs = this.matchingAguments;
|
||
|
||
if (margs.length <= args.length &&
|
||
sinon.deepEqual(margs, args.slice(0, margs.length))) {
|
||
return !strict || margs.length == args.length;
|
||
}
|
||
},
|
||
|
||
printf: function (format) {
|
||
var spy = this;
|
||
var args = slice.call(arguments, 1);
|
||
var formatter;
|
||
|
||
return (format || "").replace(/%(.)/g, function (match, specifyer) {
|
||
formatter = spyApi.formatters[specifyer];
|
||
|
||
if (typeof formatter == "function") {
|
||
return formatter.call(null, spy, args);
|
||
} else if (!isNaN(parseInt(specifyer, 10))) {
|
||
return sinon.format(args[specifyer - 1]);
|
||
}
|
||
|
||
return "%" + specifyer;
|
||
});
|
||
}
|
||
};
|
||
|
||
function delegateToCalls(method, matchAny, actual, notCalled) {
|
||
spyApi[method] = function () {
|
||
if (!this.called) {
|
||
if (notCalled) {
|
||
return notCalled.apply(this, arguments);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
var currentCall;
|
||
var matches = 0;
|
||
|
||
for (var i = 0, l = this.callCount; i < l; i += 1) {
|
||
currentCall = this.getCall(i);
|
||
|
||
if (currentCall[actual || method].apply(currentCall, arguments)) {
|
||
matches += 1;
|
||
|
||
if (matchAny) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
return matches === this.callCount;
|
||
};
|
||
}
|
||
|
||
delegateToCalls("calledOn", true);
|
||
delegateToCalls("alwaysCalledOn", false, "calledOn");
|
||
delegateToCalls("calledWith", true);
|
||
delegateToCalls("calledWithMatch", true);
|
||
delegateToCalls("alwaysCalledWith", false, "calledWith");
|
||
delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
|
||
delegateToCalls("calledWithExactly", true);
|
||
delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
|
||
delegateToCalls("neverCalledWith", false, "notCalledWith",
|
||
function () { return true; });
|
||
delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
|
||
function () { return true; });
|
||
delegateToCalls("threw", true);
|
||
delegateToCalls("alwaysThrew", false, "threw");
|
||
delegateToCalls("returned", true);
|
||
delegateToCalls("alwaysReturned", false, "returned");
|
||
delegateToCalls("calledWithNew", true);
|
||
delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
|
||
delegateToCalls("callArg", false, "callArgWith", function () {
|
||
throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
|
||
});
|
||
spyApi.callArgWith = spyApi.callArg;
|
||
delegateToCalls("callArgOn", false, "callArgOnWith", function () {
|
||
throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
|
||
});
|
||
spyApi.callArgOnWith = spyApi.callArgOn;
|
||
delegateToCalls("yield", false, "yield", function () {
|
||
throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
|
||
});
|
||
// "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
|
||
spyApi.invokeCallback = spyApi.yield;
|
||
delegateToCalls("yieldOn", false, "yieldOn", function () {
|
||
throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
|
||
});
|
||
delegateToCalls("yieldTo", false, "yieldTo", function (property) {
|
||
throw new Error(this.toString() + " cannot yield to '" + property +
|
||
"' since it was not yet invoked.");
|
||
});
|
||
delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
|
||
throw new Error(this.toString() + " cannot yield to '" + property +
|
||
"' since it was not yet invoked.");
|
||
});
|
||
|
||
spyApi.formatters = {
|
||
"c": function (spy) {
|
||
return sinon.timesInWords(spy.callCount);
|
||
},
|
||
|
||
"n": function (spy) {
|
||
return spy.toString();
|
||
},
|
||
|
||
"C": function (spy) {
|
||
var calls = [];
|
||
|
||
for (var i = 0, l = spy.callCount; i < l; ++i) {
|
||
var stringifiedCall = " " + spy.getCall(i).toString();
|
||
if (/\n/.test(calls[i - 1])) {
|
||
stringifiedCall = "\n" + stringifiedCall;
|
||
}
|
||
push.call(calls, stringifiedCall);
|
||
}
|
||
|
||
return calls.length > 0 ? "\n" + calls.join("\n") : "";
|
||
},
|
||
|
||
"t": function (spy) {
|
||
var objects = [];
|
||
|
||
for (var i = 0, l = spy.callCount; i < l; ++i) {
|
||
push.call(objects, sinon.format(spy.thisValues[i]));
|
||
}
|
||
|
||
return objects.join(", ");
|
||
},
|
||
|
||
"*": function (spy, args) {
|
||
var formatted = [];
|
||
|
||
for (var i = 0, l = args.length; i < l; ++i) {
|
||
push.call(formatted, sinon.format(args[i]));
|
||
}
|
||
|
||
return formatted.join(", ");
|
||
}
|
||
};
|
||
|
||
sinon.extend(spy, spyApi);
|
||
|
||
spy.spyCall = sinon.spyCall;
|
||
sinon.spy = spy;
|
||
|
||
if (typeof define === "function" && define.amd) {
|
||
define(["module"], function(module) { module.exports = spy; });
|
||
} else if (commonJSModule) {
|
||
module.exports = spy;
|
||
}
|
||
}(typeof sinon == "object" && sinon || null));
|
||
|
||
},{"../sinon":69}],78:[function(require,module,exports){
|
||
/**
|
||
* @depend ../sinon.js
|
||
* @depend spy.js
|
||
* @depend behavior.js
|
||
*/
|
||
/*jslint eqeqeq: false, onevar: false*/
|
||
/*global module, require, sinon*/
|
||
/**
|
||
* Stub functions
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
*/
|
||
"use strict";
|
||
|
||
(function (sinon) {
|
||
var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
|
||
|
||
if (!sinon && commonJSModule) {
|
||
sinon = require("../sinon");
|
||
}
|
||
|
||
if (!sinon) {
|
||
return;
|
||
}
|
||
|
||
function stub(object, property, func) {
|
||
if (!!func && typeof func != "function") {
|
||
throw new TypeError("Custom stub should be function");
|
||
}
|
||
|
||
var wrapper;
|
||
|
||
if (func) {
|
||
wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
|
||
} else {
|
||
wrapper = stub.create();
|
||
}
|
||
|
||
if (!object && typeof property === "undefined") {
|
||
return sinon.stub.create();
|
||
}
|
||
|
||
if (typeof property === "undefined" && typeof object == "object") {
|
||
for (var prop in object) {
|
||
if (typeof object[prop] === "function") {
|
||
stub(object, prop);
|
||
}
|
||
}
|
||
|
||
return object;
|
||
}
|
||
|
||
return sinon.wrapMethod(object, property, wrapper);
|
||
}
|
||
|
||
function getDefaultBehavior(stub) {
|
||
return stub.defaultBehavior || getParentBehaviour(stub) || sinon.behavior.create(stub);
|
||
}
|
||
|
||
function getParentBehaviour(stub) {
|
||
return (stub.parent && getCurrentBehavior(stub.parent));
|
||
}
|
||
|
||
function getCurrentBehavior(stub) {
|
||
var behavior = stub.behaviors[stub.callCount - 1];
|
||
return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stub);
|
||
}
|
||
|
||
var uuid = 0;
|
||
|
||
sinon.extend(stub, (function () {
|
||
var proto = {
|
||
create: function create() {
|
||
var functionStub = function () {
|
||
return getCurrentBehavior(functionStub).invoke(this, arguments);
|
||
};
|
||
|
||
functionStub.id = "stub#" + uuid++;
|
||
var orig = functionStub;
|
||
functionStub = sinon.spy.create(functionStub);
|
||
functionStub.func = orig;
|
||
|
||
sinon.extend(functionStub, stub);
|
||
functionStub._create = sinon.stub.create;
|
||
functionStub.displayName = "stub";
|
||
functionStub.toString = sinon.functionToString;
|
||
|
||
functionStub.defaultBehavior = null;
|
||
functionStub.behaviors = [];
|
||
|
||
return functionStub;
|
||
},
|
||
|
||
resetBehavior: function () {
|
||
var i;
|
||
|
||
this.defaultBehavior = null;
|
||
this.behaviors = [];
|
||
|
||
delete this.returnValue;
|
||
delete this.returnArgAt;
|
||
this.returnThis = false;
|
||
|
||
if (this.fakes) {
|
||
for (i = 0; i < this.fakes.length; i++) {
|
||
this.fakes[i].resetBehavior();
|
||
}
|
||
}
|
||
},
|
||
|
||
onCall: function(index) {
|
||
if (!this.behaviors[index]) {
|
||
this.behaviors[index] = sinon.behavior.create(this);
|
||
}
|
||
|
||
return this.behaviors[index];
|
||
},
|
||
|
||
onFirstCall: function() {
|
||
return this.onCall(0);
|
||
},
|
||
|
||
onSecondCall: function() {
|
||
return this.onCall(1);
|
||
},
|
||
|
||
onThirdCall: function() {
|
||
return this.onCall(2);
|
||
}
|
||
};
|
||
|
||
for (var method in sinon.behavior) {
|
||
if (sinon.behavior.hasOwnProperty(method) &&
|
||
!proto.hasOwnProperty(method) &&
|
||
method != 'create' &&
|
||
method != 'withArgs' &&
|
||
method != 'invoke') {
|
||
proto[method] = (function(behaviorMethod) {
|
||
return function() {
|
||
this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
|
||
this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
|
||
return this;
|
||
};
|
||
}(method));
|
||
}
|
||
}
|
||
|
||
return proto;
|
||
}()));
|
||
|
||
sinon.stub = stub;
|
||
|
||
if (typeof define === "function" && define.amd) {
|
||
define(["module"], function(module) { module.exports = stub; });
|
||
} else if (commonJSModule) {
|
||
module.exports = stub;
|
||
}
|
||
}(typeof sinon == "object" && sinon || null));
|
||
|
||
},{"../sinon":69}],79:[function(require,module,exports){
|
||
/**
|
||
* @depend ../sinon.js
|
||
* @depend stub.js
|
||
* @depend mock.js
|
||
* @depend sandbox.js
|
||
*/
|
||
/*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/
|
||
/*global module, require, sinon*/
|
||
/**
|
||
* Test function, sandboxes fakes
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
*/
|
||
"use strict";
|
||
|
||
(function (sinon) {
|
||
var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
|
||
|
||
if (!sinon && commonJSModule) {
|
||
sinon = require("../sinon");
|
||
}
|
||
|
||
if (!sinon) {
|
||
return;
|
||
}
|
||
|
||
function test(callback) {
|
||
var type = typeof callback;
|
||
|
||
if (type != "function") {
|
||
throw new TypeError("sinon.test needs to wrap a test function, got " + type);
|
||
}
|
||
|
||
function sinonSandboxedTest() {
|
||
var config = sinon.getConfig(sinon.config);
|
||
config.injectInto = config.injectIntoThis && this || config.injectInto;
|
||
var sandbox = sinon.sandbox.create(config);
|
||
var exception, result;
|
||
var args = Array.prototype.slice.call(arguments).concat(sandbox.args);
|
||
|
||
try {
|
||
result = callback.apply(this, args);
|
||
} catch (e) {
|
||
exception = e;
|
||
}
|
||
|
||
if (typeof exception !== "undefined") {
|
||
sandbox.restore();
|
||
throw exception;
|
||
}
|
||
else {
|
||
sandbox.verifyAndRestore();
|
||
}
|
||
|
||
return result;
|
||
};
|
||
|
||
if (callback.length) {
|
||
return function sinonAsyncSandboxedTest(callback) {
|
||
return sinonSandboxedTest.apply(this, arguments);
|
||
};
|
||
}
|
||
|
||
return sinonSandboxedTest;
|
||
}
|
||
|
||
test.config = {
|
||
injectIntoThis: true,
|
||
injectInto: null,
|
||
properties: ["spy", "stub", "mock", "clock", "server", "requests"],
|
||
useFakeTimers: true,
|
||
useFakeServer: true
|
||
};
|
||
|
||
sinon.test = test;
|
||
|
||
if (typeof define === "function" && define.amd) {
|
||
define(["module"], function(module) { module.exports = test; });
|
||
} else if (commonJSModule) {
|
||
module.exports = test;
|
||
}
|
||
}(typeof sinon == "object" && sinon || null));
|
||
|
||
},{"../sinon":69}],80:[function(require,module,exports){
|
||
/**
|
||
* @depend ../sinon.js
|
||
* @depend test.js
|
||
*/
|
||
/*jslint eqeqeq: false, onevar: false, eqeqeq: false*/
|
||
/*global module, require, sinon*/
|
||
/**
|
||
* Test case, sandboxes all test functions
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
*/
|
||
"use strict";
|
||
|
||
(function (sinon) {
|
||
var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
|
||
|
||
if (!sinon && commonJSModule) {
|
||
sinon = require("../sinon");
|
||
}
|
||
|
||
if (!sinon || !Object.prototype.hasOwnProperty) {
|
||
return;
|
||
}
|
||
|
||
function createTest(property, setUp, tearDown) {
|
||
return function () {
|
||
if (setUp) {
|
||
setUp.apply(this, arguments);
|
||
}
|
||
|
||
var exception, result;
|
||
|
||
try {
|
||
result = property.apply(this, arguments);
|
||
} catch (e) {
|
||
exception = e;
|
||
}
|
||
|
||
if (tearDown) {
|
||
tearDown.apply(this, arguments);
|
||
}
|
||
|
||
if (exception) {
|
||
throw exception;
|
||
}
|
||
|
||
return result;
|
||
};
|
||
}
|
||
|
||
function testCase(tests, prefix) {
|
||
/*jsl:ignore*/
|
||
if (!tests || typeof tests != "object") {
|
||
throw new TypeError("sinon.testCase needs an object with test functions");
|
||
}
|
||
/*jsl:end*/
|
||
|
||
prefix = prefix || "test";
|
||
var rPrefix = new RegExp("^" + prefix);
|
||
var methods = {}, testName, property, method;
|
||
var setUp = tests.setUp;
|
||
var tearDown = tests.tearDown;
|
||
|
||
for (testName in tests) {
|
||
if (tests.hasOwnProperty(testName)) {
|
||
property = tests[testName];
|
||
|
||
if (/^(setUp|tearDown)$/.test(testName)) {
|
||
continue;
|
||
}
|
||
|
||
if (typeof property == "function" && rPrefix.test(testName)) {
|
||
method = property;
|
||
|
||
if (setUp || tearDown) {
|
||
method = createTest(property, setUp, tearDown);
|
||
}
|
||
|
||
methods[testName] = sinon.test(method);
|
||
} else {
|
||
methods[testName] = tests[testName];
|
||
}
|
||
}
|
||
}
|
||
|
||
return methods;
|
||
}
|
||
|
||
sinon.testCase = testCase;
|
||
|
||
if (typeof define === "function" && define.amd) {
|
||
define(["module"], function(module) { module.exports = testCase; });
|
||
} else if (commonJSModule) {
|
||
module.exports = testCase;
|
||
}
|
||
}(typeof sinon == "object" && sinon || null));
|
||
|
||
},{"../sinon":69}],81:[function(require,module,exports){
|
||
(function (global){
|
||
/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
|
||
/*global module, require, window*/
|
||
/**
|
||
* Fake timer API
|
||
* setTimeout
|
||
* setInterval
|
||
* clearTimeout
|
||
* clearInterval
|
||
* tick
|
||
* reset
|
||
* Date
|
||
*
|
||
* Inspired by jsUnitMockTimeOut from JsUnit
|
||
*
|
||
* @author Christian Johansen (christian@cjohansen.no)
|
||
* @license BSD
|
||
*
|
||
* Copyright (c) 2010-2013 Christian Johansen
|
||
*/
|
||
"use strict";
|
||
|
||
if (typeof sinon == "undefined") {
|
||
var sinon = {};
|
||
}
|
||
|
||
(function (global) {
|
||
// node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref()
|
||
// browsers, a number.
|
||
// see https://github.com/cjohansen/Sinon.JS/pull/436
|
||
var timeoutResult = setTimeout(function() {}, 0);
|
||
var addTimerReturnsObject = typeof timeoutResult === 'object';
|
||
clearTimeout(timeoutResult);
|
||
|
||
var id = 1;
|
||
|
||
function addTimer(args, recurring) {
|
||
if (args.length === 0) {
|
||
throw new Error("Function requires at least 1 parameter");
|
||
}
|
||
|
||
if (typeof args[0] === "undefined") {
|
||
throw new Error("Callback must be provided to timer calls");
|
||
}
|
||
|
||
var toId = id++;
|
||
var delay = args[1] || 0;
|
||
|
||
if (!this.timeouts) {
|
||
this.timeouts = {};
|
||
}
|
||
|
||
this.timeouts[toId] = {
|
||
id: toId,
|
||
func: args[0],
|
||
callAt: this.now + delay,
|
||
invokeArgs: Array.prototype.slice.call(args, 2)
|
||
};
|
||
|
||
if (recurring === true) {
|
||
this.timeouts[toId].interval = delay;
|
||
}
|
||
|
||
if (addTimerReturnsObject) {
|
||
return {
|
||
id: toId,
|
||
ref: function() {},
|
||
unref: function() {}
|
||
};
|
||
}
|
||
else {
|
||
return toId;
|
||
}
|
||
}
|
||
|
||
function parseTime(str) {
|
||
if (!str) {
|
||
return 0;
|
||
}
|
||
|
||
var strings = str.split(":");
|
||
var l = strings.length, i = l;
|
||
var ms = 0, parsed;
|
||
|
||
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
|
||
throw new Error("tick only understands numbers and 'h:m:s'");
|
||
}
|
||
|
||
while (i--) {
|
||
parsed = parseInt(strings[i], 10);
|
||
|
||
if (parsed >= 60) {
|
||
throw new Error("Invalid time " + str);
|
||
}
|
||
|
||
ms += parsed * Math.pow(60, (l - i - 1));
|
||
}
|
||
|
||
return ms * 1000;
|
||
}
|
||
|
||
function createObject(object) {
|
||
var newObject;
|
||
|
||
if (Object.create) {
|
||
newObject = Object.create(object);
|
||
} else {
|
||
var F = function () {};
|
||
F.prototype = object;
|
||
newObject = new F();
|
||
}
|
||
|
||
newObject.Date.clock = newObject;
|
||
return newObject;
|
||
}
|
||
|
||
sinon.clock = {
|
||
now: 0,
|
||
|
||
create: function create(now) {
|
||
var clock = createObject(this);
|
||
|
||
if (typeof now == "number") {
|
||
clock.now = now;
|
||
}
|
||
|
||
if (!!now && typeof now == "object") {
|
||
throw new TypeError("now should be milliseconds since UNIX epoch");
|
||
}
|
||
|
||
return clock;
|
||
},
|
||
|
||
setTimeout: function setTimeout(callback, timeout) {
|
||
return addTimer.call(this, arguments, false);
|
||
},
|
||
|
||
clearTimeout: function clearTimeout(timerId) {
|
||
if (!timerId) {
|
||
// null appears to be allowed in most browsers, and appears to be relied upon by some libraries, like Bootstrap carousel
|
||
return;
|
||
}
|
||
if (!this.timeouts) {
|
||
this.timeouts = [];
|
||
}
|
||
// in Node, timerId is an object with .ref()/.unref(), and
|
||
// its .id field is the actual timer id.
|
||
if (typeof timerId === 'object') {
|
||
timerId = timerId.id
|
||
}
|
||
if (timerId in this.timeouts) {
|
||
delete this.timeouts[timerId];
|
||
}
|
||
},
|
||
|
||
setInterval: function setInterval(callback, timeout) {
|
||
return addTimer.call(this, arguments, true);
|
||
},
|
||
|
||
clearInterval: function clearInterval(timerId) {
|
||
this.clearTimeout(timerId);
|
||
},
|
||
|
||
setImmediate: function setImmediate(callback) {
|
||
var passThruArgs = Array.prototype.slice.call(arguments, 1);
|
||
|
||
return addTimer.call(this, [callback, 0].concat(passThruArgs), false);
|
||
},
|
||
|
||
clearImmediate: function clearImmediate(timerId) {
|
||
this.clearTimeout(timerId);
|
||
},
|
||
|
||
tick: function tick(ms) {
|
||
ms = typeof ms == "number" ? ms : parseTime(ms);
|
||
var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
|
||
var timer = this.firstTimerInRange(tickFrom, tickTo);
|
||
|
||
var firstException;
|
||
while (timer && tickFrom <= tickTo) {
|
||
if (this.timeouts[timer.id]) {
|
||
tickFrom = this.now = timer.callAt;
|
||
try {
|
||
this.callTimer(timer);
|
||
} catch (e) {
|
||
firstException = firstException || e;
|
||
}
|
||
}
|
||
|
||
timer = this.firstTimerInRange(previous, tickTo);
|
||
previous = tickFrom;
|
||
}
|
||
|
||
this.now = tickTo;
|
||
|
||
if (firstException) {
|
||
throw firstException;
|
||
}
|
||
|
||
return this.now;
|
||
},
|
||
|
||
firstTimerInRange: function (from, to) {
|
||
var timer, smallest = null, originalTimer;
|
||
|
||
for (var id in this.timeouts) {
|
||
if (this.timeouts.hasOwnProperty(id)) {
|
||
if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
|
||
continue;
|
||
}
|
||
|
||
if (smallest === null || this.timeouts[id].callAt < smallest) {
|
||
originalTimer = this.timeouts[id];
|
||
smallest = this.timeouts[id].callAt;
|
||
|
||
timer = {
|
||
func: this.timeouts[id].func,
|
||
callAt: this.timeouts[id].callAt,
|
||
interval: this.timeouts[id].interval,
|
||
id: this.timeouts[id].id,
|
||
invokeArgs: this.timeouts[id].invokeArgs
|
||
};
|
||
}
|
||
}
|
||
}
|
||
|
||
return timer || null;
|
||
},
|
||
|
||
callTimer: function (timer) {
|
||
if (typeof timer.interval == "number") {
|
||
this.timeouts[timer.id].callAt += timer.interval;
|
||
} else {
|
||
delete this.timeouts[timer.id];
|
||
}
|
||
|
||
try {
|
||
if (typeof timer.func == "function") {
|
||
timer.func.apply(null, timer.invokeArgs);
|
||
} else {
|
||
eval(timer.func);
|
||
}
|
||
} catch (e) {
|
||
var exception = e;
|
||
}
|
||
|
||
if (!this.timeouts[timer.id]) {
|
||
if (exception) {
|
||
throw exception;
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (exception) {
|
||
throw exception;
|
||
}
|
||
},
|
||
|
||
reset: function reset() {
|
||
this.timeouts = {};
|
||
},
|
||
|
||
Date: (function () {
|
||
var NativeDate = Date;
|
||
|
||
function ClockDate(year, month, date, hour, minute, second, ms) {
|
||
// Defensive and verbose to avoid potential harm in passing
|
||
// explicit undefined when user does not pass argument
|
||
switch (arguments.length) {
|
||
case 0:
|
||
return new NativeDate(ClockDate.clock.now);
|
||
case 1:
|
||
return new NativeDate(year);
|
||
case 2:
|
||
return new NativeDate(year, month);
|
||
case 3:
|
||
return new NativeDate(year, month, date);
|
||
case 4:
|
||
return new NativeDate(year, month, date, hour);
|
||
case 5:
|
||
return new NativeDate(year, month, date, hour, minute);
|
||
case 6:
|
||
return new NativeDate(year, month, date, hour, minute, second);
|
||
default:
|
||
return new NativeDate(year, month, date, hour, minute, second, ms);
|
||
}
|
||
}
|
||
|
||
return mirrorDateProperties(ClockDate, NativeDate);
|
||
}())
|
||
};
|
||
|
||
function mirrorDateProperties(target, source) {
|
||
if (source.now) {
|
||
target.now = function now() {
|
||
return target.clock.now;
|
||
};
|
||
} else {
|
||
delete target.now;
|
||
}
|
||
|
||
if (source.toSource) {
|
||
target.toSource = function toSource() {
|
||
return source.toSource();
|
||
};
|
||
} else {
|
||
delete target.toSource;
|
||
}
|
||
|
||
target.toString = function toString() {
|
||
return source.toString();
|
||
};
|
||
|
||
target.prototype = source.prototype;
|
||
target.parse = source.parse;
|
||
target.UTC = source.UTC;
|
||
target.prototype.toUTCString = source.prototype.toUTCString;
|
||
|
||
for (var prop in source) {
|
||
if (source.hasOwnProperty(prop)) {
|
||
target[prop] = source[prop];
|
||
}
|
||
}
|
||
|
||
return target;
|
||
}
|
||
|
||
var methods = ["Date", "setTimeout", "setInterval",
|
||
"clearTimeout", "clearInterval"];
|
||
|
||
if (typeof global.setImmediate !== "undefined") {
|
||
methods.push("setImmediate");
|
||
}
|
||
|
||
if (typeof global.clearImmediate !== "undefined") {
|
||
methods.push("clearImmediate");
|
||
}
|
||
|
||
function restore() {
|
||
var method;
|
||
|
||
for (var i = 0, l = this.methods.length; i < l; i++) {
|
||
method = this.methods[i];
|
||
|
||
if (global[method].hadOwnProperty) {
|
||
global[method] = this["_" + method];
|
||
} else {
|
||
try {
|
||
delete global[method];
|
||
} catch (e) {}
|
||
}
|
||
}
|
||
|
||
// Prevent multiple executions which will completely remove these props
|
||
this.methods = [];
|
||
}
|
||
|
||
function stubGlobal(method, clock) {
|
||
clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(global, method);
|
||
clock["_" + method] = global[method];
|
||
|
||
if (method == "Date") {
|
||
var date = mirrorDateProperties(clock[method], global[method]);
|
||
global[method] = date;
|
||
} else {
|
||
global[method] = function () {
|
||
return clock[method].apply(clock, arguments);
|
||
};
|
||
|
||
for (var prop in clock[method]) {
|
||
if (clock[method].hasOwnProperty(prop)) {
|
||
global[method][prop] = clock[method][prop];
|
||
}
|
||
}
|
||
}
|
||
|
||
global[method].clock = clock;
|
||
}
|
||
|
||
sinon.useFakeTimers = function useFakeTimers(now) {
|
||
var clock = sinon.clock.create(now);
|
||
clock.restore = restore;
|
||
clock.methods = Array.prototype.slice.call(arguments,
|
||
typeof now == "number" ? 1 : 0);
|
||
|
||
if (clock.methods.length === 0) {
|
||
clock.methods = methods;
|
||
}
|
||
|
||
for (var i = 0, l = clock.methods.length; i < l; i++) {
|
||
stubGlobal(clock.methods[i], clock);
|
||
}
|
||
|
||
return clock;
|
||
};
|
||
}(typeof global != "undefined" && typeof global !== "function" ? global : this));
|
||
|
||
sinon.timers = {
|
||
setTimeout: setTimeout,
|
||
clearTimeout: clearTimeout,
|
||
setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
|
||
clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
|
||
setInterval: setInterval,
|
||
clearInterval: clearInterval,
|
||
Date: Date
|
||
};
|
||
|
||
if (typeof module !== 'undefined' && module.exports) {
|
||
module.exports = sinon;
|
||
}
|
||
|
||
}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
},{}],82:[function(require,module,exports){
|
||
(function (global){
|
||
((typeof define === "function" && define.amd && function (m) {
|
||
define("formatio", ["samsam"], m);
|
||
}) || (typeof module === "object" && function (m) {
|
||
module.exports = m(require("samsam"));
|
||
}) || function (m) { this.formatio = m(this.samsam); }
|
||
)(function (samsam) {
|
||
"use strict";
|
||
|
||
var formatio = {
|
||
excludeConstructors: ["Object", /^.$/],
|
||
quoteStrings: true
|
||
};
|
||
|
||
var hasOwn = Object.prototype.hasOwnProperty;
|
||
|
||
var specialObjects = [];
|
||
if (typeof global !== "undefined") {
|
||
specialObjects.push({ object: global, value: "[object global]" });
|
||
}
|
||
if (typeof document !== "undefined") {
|
||
specialObjects.push({
|
||
object: document,
|
||
value: "[object HTMLDocument]"
|
||
});
|
||
}
|
||
if (typeof window !== "undefined") {
|
||
specialObjects.push({ object: window, value: "[object Window]" });
|
||
}
|
||
|
||
function functionName(func) {
|
||
if (!func) { return ""; }
|
||
if (func.displayName) { return func.displayName; }
|
||
if (func.name) { return func.name; }
|
||
var matches = func.toString().match(/function\s+([^\(]+)/m);
|
||
return (matches && matches[1]) || "";
|
||
}
|
||
|
||
function constructorName(f, object) {
|
||
var name = functionName(object && object.constructor);
|
||
var excludes = f.excludeConstructors ||
|
||
formatio.excludeConstructors || [];
|
||
|
||
var i, l;
|
||
for (i = 0, l = excludes.length; i < l; ++i) {
|
||
if (typeof excludes[i] === "string" && excludes[i] === name) {
|
||
return "";
|
||
} else if (excludes[i].test && excludes[i].test(name)) {
|
||
return "";
|
||
}
|
||
}
|
||
|
||
return name;
|
||
}
|
||
|
||
function isCircular(object, objects) {
|
||
if (typeof object !== "object") { return false; }
|
||
var i, l;
|
||
for (i = 0, l = objects.length; i < l; ++i) {
|
||
if (objects[i] === object) { return true; }
|
||
}
|
||
return false;
|
||
}
|
||
|
||
function ascii(f, object, processed, indent) {
|
||
if (typeof object === "string") {
|
||
var qs = f.quoteStrings;
|
||
var quote = typeof qs !== "boolean" || qs;
|
||
return processed || quote ? '"' + object + '"' : object;
|
||
}
|
||
|
||
if (typeof object === "function" && !(object instanceof RegExp)) {
|
||
return ascii.func(object);
|
||
}
|
||
|
||
processed = processed || [];
|
||
|
||
if (isCircular(object, processed)) { return "[Circular]"; }
|
||
|
||
if (Object.prototype.toString.call(object) === "[object Array]") {
|
||
return ascii.array.call(f, object, processed);
|
||
}
|
||
|
||
if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
|
||
if (samsam.isElement(object)) { return ascii.element(object); }
|
||
|
||
if (typeof object.toString === "function" &&
|
||
object.toString !== Object.prototype.toString) {
|
||
return object.toString();
|
||
}
|
||
|
||
var i, l;
|
||
for (i = 0, l = specialObjects.length; i < l; i++) {
|
||
if (object === specialObjects[i].object) {
|
||
return specialObjects[i].value;
|
||
}
|
||
}
|
||
|
||
return ascii.object.call(f, object, processed, indent);
|
||
}
|
||
|
||
ascii.func = function (func) {
|
||
return "function " + functionName(func) + "() {}";
|
||
};
|
||
|
||
ascii.array = function (array, processed) {
|
||
processed = processed || [];
|
||
processed.push(array);
|
||
var i, l, pieces = [];
|
||
for (i = 0, l = array.length; i < l; ++i) {
|
||
pieces.push(ascii(this, array[i], processed));
|
||
}
|
||
return "[" + pieces.join(", ") + "]";
|
||
};
|
||
|
||
ascii.object = function (object, processed, indent) {
|
||
processed = processed || [];
|
||
processed.push(object);
|
||
indent = indent || 0;
|
||
var pieces = [], properties = samsam.keys(object).sort();
|
||
var length = 3;
|
||
var prop, str, obj, i, l;
|
||
|
||
for (i = 0, l = properties.length; i < l; ++i) {
|
||
prop = properties[i];
|
||
obj = object[prop];
|
||
|
||
if (isCircular(obj, processed)) {
|
||
str = "[Circular]";
|
||
} else {
|
||
str = ascii(this, obj, processed, indent + 2);
|
||
}
|
||
|
||
str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
|
||
length += str.length;
|
||
pieces.push(str);
|
||
}
|
||
|
||
var cons = constructorName(this, object);
|
||
var prefix = cons ? "[" + cons + "] " : "";
|
||
var is = "";
|
||
for (i = 0, l = indent; i < l; ++i) { is += " "; }
|
||
|
||
if (length + indent > 80) {
|
||
return prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" +
|
||
is + "}";
|
||
}
|
||
return prefix + "{ " + pieces.join(", ") + " }";
|
||
};
|
||
|
||
ascii.element = function (element) {
|
||
var tagName = element.tagName.toLowerCase();
|
||
var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
|
||
|
||
for (i = 0, l = attrs.length; i < l; ++i) {
|
||
attr = attrs.item(i);
|
||
attrName = attr.nodeName.toLowerCase().replace("html:", "");
|
||
val = attr.nodeValue;
|
||
if (attrName !== "contenteditable" || val !== "inherit") {
|
||
if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
|
||
}
|
||
}
|
||
|
||
var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
|
||
var content = element.innerHTML;
|
||
|
||
if (content.length > 20) {
|
||
content = content.substr(0, 20) + "[...]";
|
||
}
|
||
|
||
var res = formatted + pairs.join(" ") + ">" + content +
|
||
"</" + tagName + ">";
|
||
|
||
return res.replace(/ contentEditable="inherit"/, "");
|
||
};
|
||
|
||
function Formatio(options) {
|
||
for (var opt in options) {
|
||
this[opt] = options[opt];
|
||
}
|
||
}
|
||
|
||
Formatio.prototype = {
|
||
functionName: functionName,
|
||
|
||
configure: function (options) {
|
||
return new Formatio(options);
|
||
},
|
||
|
||
constructorName: function (object) {
|
||
return constructorName(this, object);
|
||
},
|
||
|
||
ascii: function (object, processed, indent) {
|
||
return ascii(this, object, processed, indent);
|
||
}
|
||
};
|
||
|
||
return Formatio.prototype;
|
||
});
|
||
|
||
}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
},{"samsam":83}],83:[function(require,module,exports){
|
||
((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) ||
|
||
(typeof module === "object" &&
|
||
function (m) { module.exports = m(); }) || // Node
|
||
function (m) { this.samsam = m(); } // Browser globals
|
||
)(function () {
|
||
var o = Object.prototype;
|
||
var div = typeof document !== "undefined" && document.createElement("div");
|
||
|
||
function isNaN(value) {
|
||
// Unlike global isNaN, this avoids type coercion
|
||
// typeof check avoids IE host object issues, hat tip to
|
||
// lodash
|
||
var val = value; // JsLint thinks value !== value is "weird"
|
||
return typeof value === "number" && value !== val;
|
||
}
|
||
|
||
function getClass(value) {
|
||
// Returns the internal [[Class]] by calling Object.prototype.toString
|
||
// with the provided value as this. Return value is a string, naming the
|
||
// internal class, e.g. "Array"
|
||
return o.toString.call(value).split(/[ \]]/)[1];
|
||
}
|
||
|
||
/**
|
||
* @name samsam.isArguments
|
||
* @param Object object
|
||
*
|
||
* Returns ``true`` if ``object`` is an ``arguments`` object,
|
||
* ``false`` otherwise.
|
||
*/
|
||
function isArguments(object) {
|
||
if (getClass(object) === 'Arguments') { return true; }
|
||
if (typeof object !== "object" || typeof object.length !== "number" ||
|
||
getClass(object) === "Array") {
|
||
return false;
|
||
}
|
||
if (typeof object.callee == "function") { return true; }
|
||
try {
|
||
object[object.length] = 6;
|
||
delete object[object.length];
|
||
} catch (e) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* @name samsam.isElement
|
||
* @param Object object
|
||
*
|
||
* Returns ``true`` if ``object`` is a DOM element node. Unlike
|
||
* Underscore.js/lodash, this function will return ``false`` if ``object``
|
||
* is an *element-like* object, i.e. a regular object with a ``nodeType``
|
||
* property that holds the value ``1``.
|
||
*/
|
||
function isElement(object) {
|
||
if (!object || object.nodeType !== 1 || !div) { return false; }
|
||
try {
|
||
object.appendChild(div);
|
||
object.removeChild(div);
|
||
} catch (e) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* @name samsam.keys
|
||
* @param Object object
|
||
*
|
||
* Return an array of own property names.
|
||
*/
|
||
function keys(object) {
|
||
var ks = [], prop;
|
||
for (prop in object) {
|
||
if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
|
||
}
|
||
return ks;
|
||
}
|
||
|
||
/**
|
||
* @name samsam.isDate
|
||
* @param Object value
|
||
*
|
||
* Returns true if the object is a ``Date``, or *date-like*. Duck typing
|
||
* of date objects work by checking that the object has a ``getTime``
|
||
* function whose return value equals the return value from the object's
|
||
* ``valueOf``.
|
||
*/
|
||
function isDate(value) {
|
||
return typeof value.getTime == "function" &&
|
||
value.getTime() == value.valueOf();
|
||
}
|
||
|
||
/**
|
||
* @name samsam.isNegZero
|
||
* @param Object value
|
||
*
|
||
* Returns ``true`` if ``value`` is ``-0``.
|
||
*/
|
||
function isNegZero(value) {
|
||
return value === 0 && 1 / value === -Infinity;
|
||
}
|
||
|
||
/**
|
||
* @name samsam.equal
|
||
* @param Object obj1
|
||
* @param Object obj2
|
||
*
|
||
* Returns ``true`` if two objects are strictly equal. Compared to
|
||
* ``===`` there are two exceptions:
|
||
*
|
||
* - NaN is considered equal to NaN
|
||
* - -0 and +0 are not considered equal
|
||
*/
|
||
function identical(obj1, obj2) {
|
||
if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
|
||
return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @name samsam.deepEqual
|
||
* @param Object obj1
|
||
* @param Object obj2
|
||
*
|
||
* Deep equal comparison. Two values are "deep equal" if:
|
||
*
|
||
* - They are equal, according to samsam.identical
|
||
* - They are both date objects representing the same time
|
||
* - They are both arrays containing elements that are all deepEqual
|
||
* - They are objects with the same set of properties, and each property
|
||
* in ``obj1`` is deepEqual to the corresponding property in ``obj2``
|
||
*
|
||
* Supports cyclic objects.
|
||
*/
|
||
function deepEqualCyclic(obj1, obj2) {
|
||
|
||
// used for cyclic comparison
|
||
// contain already visited objects
|
||
var objects1 = [],
|
||
objects2 = [],
|
||
// contain pathes (position in the object structure)
|
||
// of the already visited objects
|
||
// indexes same as in objects arrays
|
||
paths1 = [],
|
||
paths2 = [],
|
||
// contains combinations of already compared objects
|
||
// in the manner: { "$1['ref']$2['ref']": true }
|
||
compared = {};
|
||
|
||
/**
|
||
* used to check, if the value of a property is an object
|
||
* (cyclic logic is only needed for objects)
|
||
* only needed for cyclic logic
|
||
*/
|
||
function isObject(value) {
|
||
|
||
if (typeof value === 'object' && value !== null &&
|
||
!(value instanceof Boolean) &&
|
||
!(value instanceof Date) &&
|
||
!(value instanceof Number) &&
|
||
!(value instanceof RegExp) &&
|
||
!(value instanceof String)) {
|
||
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* returns the index of the given object in the
|
||
* given objects array, -1 if not contained
|
||
* only needed for cyclic logic
|
||
*/
|
||
function getIndex(objects, obj) {
|
||
|
||
var i;
|
||
for (i = 0; i < objects.length; i++) {
|
||
if (objects[i] === obj) {
|
||
return i;
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
// does the recursion for the deep equal check
|
||
return (function deepEqual(obj1, obj2, path1, path2) {
|
||
var type1 = typeof obj1;
|
||
var type2 = typeof obj2;
|
||
|
||
// == null also matches undefined
|
||
if (obj1 === obj2 ||
|
||
isNaN(obj1) || isNaN(obj2) ||
|
||
obj1 == null || obj2 == null ||
|
||
type1 !== "object" || type2 !== "object") {
|
||
|
||
return identical(obj1, obj2);
|
||
}
|
||
|
||
// Elements are only equal if identical(expected, actual)
|
||
if (isElement(obj1) || isElement(obj2)) { return false; }
|
||
|
||
var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
|
||
if (isDate1 || isDate2) {
|
||
if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
|
||
if (obj1.toString() !== obj2.toString()) { return false; }
|
||
}
|
||
|
||
var class1 = getClass(obj1);
|
||
var class2 = getClass(obj2);
|
||
var keys1 = keys(obj1);
|
||
var keys2 = keys(obj2);
|
||
|
||
if (isArguments(obj1) || isArguments(obj2)) {
|
||
if (obj1.length !== obj2.length) { return false; }
|
||
} else {
|
||
if (type1 !== type2 || class1 !== class2 ||
|
||
keys1.length !== keys2.length) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
var key, i, l,
|
||
// following vars are used for the cyclic logic
|
||
value1, value2,
|
||
isObject1, isObject2,
|
||
index1, index2,
|
||
newPath1, newPath2;
|
||
|
||
for (i = 0, l = keys1.length; i < l; i++) {
|
||
key = keys1[i];
|
||
if (!o.hasOwnProperty.call(obj2, key)) {
|
||
return false;
|
||
}
|
||
|
||
// Start of the cyclic logic
|
||
|
||
value1 = obj1[key];
|
||
value2 = obj2[key];
|
||
|
||
isObject1 = isObject(value1);
|
||
isObject2 = isObject(value2);
|
||
|
||
// determine, if the objects were already visited
|
||
// (it's faster to check for isObject first, than to
|
||
// get -1 from getIndex for non objects)
|
||
index1 = isObject1 ? getIndex(objects1, value1) : -1;
|
||
index2 = isObject2 ? getIndex(objects2, value2) : -1;
|
||
|
||
// determine the new pathes of the objects
|
||
// - for non cyclic objects the current path will be extended
|
||
// by current property name
|
||
// - for cyclic objects the stored path is taken
|
||
newPath1 = index1 !== -1
|
||
? paths1[index1]
|
||
: path1 + '[' + JSON.stringify(key) + ']';
|
||
newPath2 = index2 !== -1
|
||
? paths2[index2]
|
||
: path2 + '[' + JSON.stringify(key) + ']';
|
||
|
||
// stop recursion if current objects are already compared
|
||
if (compared[newPath1 + newPath2]) {
|
||
return true;
|
||
}
|
||
|
||
// remember the current objects and their pathes
|
||
if (index1 === -1 && isObject1) {
|
||
objects1.push(value1);
|
||
paths1.push(newPath1);
|
||
}
|
||
if (index2 === -1 && isObject2) {
|
||
objects2.push(value2);
|
||
paths2.push(newPath2);
|
||
}
|
||
|
||
// remember that the current objects are already compared
|
||
if (isObject1 && isObject2) {
|
||
compared[newPath1 + newPath2] = true;
|
||
}
|
||
|
||
// End of cyclic logic
|
||
|
||
// neither value1 nor value2 is a cycle
|
||
// continue with next level
|
||
if (!deepEqual(value1, value2, newPath1, newPath2)) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
|
||
}(obj1, obj2, '$1', '$2'));
|
||
}
|
||
|
||
var match;
|
||
|
||
function arrayContains(array, subset) {
|
||
if (subset.length === 0) { return true; }
|
||
var i, l, j, k;
|
||
for (i = 0, l = array.length; i < l; ++i) {
|
||
if (match(array[i], subset[0])) {
|
||
for (j = 0, k = subset.length; j < k; ++j) {
|
||
if (!match(array[i + j], subset[j])) { return false; }
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* @name samsam.match
|
||
* @param Object object
|
||
* @param Object matcher
|
||
*
|
||
* Compare arbitrary value ``object`` with matcher.
|
||
*/
|
||
match = function match(object, matcher) {
|
||
if (matcher && typeof matcher.test === "function") {
|
||
return matcher.test(object);
|
||
}
|
||
|
||
if (typeof matcher === "function") {
|
||
return matcher(object) === true;
|
||
}
|
||
|
||
if (typeof matcher === "string") {
|
||
matcher = matcher.toLowerCase();
|
||
var notNull = typeof object === "string" || !!object;
|
||
return notNull &&
|
||
(String(object)).toLowerCase().indexOf(matcher) >= 0;
|
||
}
|
||
|
||
if (typeof matcher === "number") {
|
||
return matcher === object;
|
||
}
|
||
|
||
if (typeof matcher === "boolean") {
|
||
return matcher === object;
|
||
}
|
||
|
||
if (getClass(object) === "Array" && getClass(matcher) === "Array") {
|
||
return arrayContains(object, matcher);
|
||
}
|
||
|
||
if (matcher && typeof matcher === "object") {
|
||
var prop;
|
||
for (prop in matcher) {
|
||
var value = object[prop];
|
||
if (typeof value === "undefined" &&
|
||
typeof object.getAttribute === "function") {
|
||
value = object.getAttribute(prop);
|
||
}
|
||
if (typeof value === "undefined" || !match(value, matcher[prop])) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
throw new Error("Matcher was not a string, a number, a " +
|
||
"function, a boolean or an object");
|
||
};
|
||
|
||
return {
|
||
isArguments: isArguments,
|
||
isElement: isElement,
|
||
isDate: isDate,
|
||
isNegZero: isNegZero,
|
||
identical: identical,
|
||
deepEqual: deepEqualCyclic,
|
||
match: match,
|
||
keys: keys
|
||
};
|
||
});
|
||
|
||
},{}],84:[function(require,module,exports){
|
||
// Underscore.js 1.7.0
|
||
// http://underscorejs.org
|
||
// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||
// Underscore may be freely distributed under the MIT license.
|
||
|
||
(function() {
|
||
|
||
// Baseline setup
|
||
// --------------
|
||
|
||
// Establish the root object, `window` in the browser, or `exports` on the server.
|
||
var root = this;
|
||
|
||
// Save the previous value of the `_` variable.
|
||
var previousUnderscore = root._;
|
||
|
||
// Save bytes in the minified (but not gzipped) version:
|
||
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
|
||
|
||
// Create quick reference variables for speed access to core prototypes.
|
||
var
|
||
push = ArrayProto.push,
|
||
slice = ArrayProto.slice,
|
||
concat = ArrayProto.concat,
|
||
toString = ObjProto.toString,
|
||
hasOwnProperty = ObjProto.hasOwnProperty;
|
||
|
||
// All **ECMAScript 5** native function implementations that we hope to use
|
||
// are declared here.
|
||
var
|
||
nativeIsArray = Array.isArray,
|
||
nativeKeys = Object.keys,
|
||
nativeBind = FuncProto.bind;
|
||
|
||
// Create a safe reference to the Underscore object for use below.
|
||
var _ = function(obj) {
|
||
if (obj instanceof _) return obj;
|
||
if (!(this instanceof _)) return new _(obj);
|
||
this._wrapped = obj;
|
||
};
|
||
|
||
// Export the Underscore object for **Node.js**, with
|
||
// backwards-compatibility for the old `require()` API. If we're in
|
||
// the browser, add `_` as a global object.
|
||
if (typeof exports !== 'undefined') {
|
||
if (typeof module !== 'undefined' && module.exports) {
|
||
exports = module.exports = _;
|
||
}
|
||
exports._ = _;
|
||
} else {
|
||
root._ = _;
|
||
}
|
||
|
||
// Current version.
|
||
_.VERSION = '1.7.0';
|
||
|
||
// Internal function that returns an efficient (for current engines) version
|
||
// of the passed-in callback, to be repeatedly applied in other Underscore
|
||
// functions.
|
||
var createCallback = function(func, context, argCount) {
|
||
if (context === void 0) return func;
|
||
switch (argCount == null ? 3 : argCount) {
|
||
case 1: return function(value) {
|
||
return func.call(context, value);
|
||
};
|
||
case 2: return function(value, other) {
|
||
return func.call(context, value, other);
|
||
};
|
||
case 3: return function(value, index, collection) {
|
||
return func.call(context, value, index, collection);
|
||
};
|
||
case 4: return function(accumulator, value, index, collection) {
|
||
return func.call(context, accumulator, value, index, collection);
|
||
};
|
||
}
|
||
return function() {
|
||
return func.apply(context, arguments);
|
||
};
|
||
};
|
||
|
||
// A mostly-internal function to generate callbacks that can be applied
|
||
// to each element in a collection, returning the desired result — either
|
||
// identity, an arbitrary callback, a property matcher, or a property accessor.
|
||
_.iteratee = function(value, context, argCount) {
|
||
if (value == null) return _.identity;
|
||
if (_.isFunction(value)) return createCallback(value, context, argCount);
|
||
if (_.isObject(value)) return _.matches(value);
|
||
return _.property(value);
|
||
};
|
||
|
||
// Collection Functions
|
||
// --------------------
|
||
|
||
// The cornerstone, an `each` implementation, aka `forEach`.
|
||
// Handles raw objects in addition to array-likes. Treats all
|
||
// sparse array-likes as if they were dense.
|
||
_.each = _.forEach = function(obj, iteratee, context) {
|
||
if (obj == null) return obj;
|
||
iteratee = createCallback(iteratee, context);
|
||
var i, length = obj.length;
|
||
if (length === +length) {
|
||
for (i = 0; i < length; i++) {
|
||
iteratee(obj[i], i, obj);
|
||
}
|
||
} else {
|
||
var keys = _.keys(obj);
|
||
for (i = 0, length = keys.length; i < length; i++) {
|
||
iteratee(obj[keys[i]], keys[i], obj);
|
||
}
|
||
}
|
||
return obj;
|
||
};
|
||
|
||
// Return the results of applying the iteratee to each element.
|
||
_.map = _.collect = function(obj, iteratee, context) {
|
||
if (obj == null) return [];
|
||
iteratee = _.iteratee(iteratee, context);
|
||
var keys = obj.length !== +obj.length && _.keys(obj),
|
||
length = (keys || obj).length,
|
||
results = Array(length),
|
||
currentKey;
|
||
for (var index = 0; index < length; index++) {
|
||
currentKey = keys ? keys[index] : index;
|
||
results[index] = iteratee(obj[currentKey], currentKey, obj);
|
||
}
|
||
return results;
|
||
};
|
||
|
||
var reduceError = 'Reduce of empty array with no initial value';
|
||
|
||
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
||
// or `foldl`.
|
||
_.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) {
|
||
if (obj == null) obj = [];
|
||
iteratee = createCallback(iteratee, context, 4);
|
||
var keys = obj.length !== +obj.length && _.keys(obj),
|
||
length = (keys || obj).length,
|
||
index = 0, currentKey;
|
||
if (arguments.length < 3) {
|
||
if (!length) throw new TypeError(reduceError);
|
||
memo = obj[keys ? keys[index++] : index++];
|
||
}
|
||
for (; index < length; index++) {
|
||
currentKey = keys ? keys[index] : index;
|
||
memo = iteratee(memo, obj[currentKey], currentKey, obj);
|
||
}
|
||
return memo;
|
||
};
|
||
|
||
// The right-associative version of reduce, also known as `foldr`.
|
||
_.reduceRight = _.foldr = function(obj, iteratee, memo, context) {
|
||
if (obj == null) obj = [];
|
||
iteratee = createCallback(iteratee, context, 4);
|
||
var keys = obj.length !== + obj.length && _.keys(obj),
|
||
index = (keys || obj).length,
|
||
currentKey;
|
||
if (arguments.length < 3) {
|
||
if (!index) throw new TypeError(reduceError);
|
||
memo = obj[keys ? keys[--index] : --index];
|
||
}
|
||
while (index--) {
|
||
currentKey = keys ? keys[index] : index;
|
||
memo = iteratee(memo, obj[currentKey], currentKey, obj);
|
||
}
|
||
return memo;
|
||
};
|
||
|
||
// Return the first value which passes a truth test. Aliased as `detect`.
|
||
_.find = _.detect = function(obj, predicate, context) {
|
||
var result;
|
||
predicate = _.iteratee(predicate, context);
|
||
_.some(obj, function(value, index, list) {
|
||
if (predicate(value, index, list)) {
|
||
result = value;
|
||
return true;
|
||
}
|
||
});
|
||
return result;
|
||
};
|
||
|
||
// Return all the elements that pass a truth test.
|
||
// Aliased as `select`.
|
||
_.filter = _.select = function(obj, predicate, context) {
|
||
var results = [];
|
||
if (obj == null) return results;
|
||
predicate = _.iteratee(predicate, context);
|
||
_.each(obj, function(value, index, list) {
|
||
if (predicate(value, index, list)) results.push(value);
|
||
});
|
||
return results;
|
||
};
|
||
|
||
// Return all the elements for which a truth test fails.
|
||
_.reject = function(obj, predicate, context) {
|
||
return _.filter(obj, _.negate(_.iteratee(predicate)), context);
|
||
};
|
||
|
||
// Determine whether all of the elements match a truth test.
|
||
// Aliased as `all`.
|
||
_.every = _.all = function(obj, predicate, context) {
|
||
if (obj == null) return true;
|
||
predicate = _.iteratee(predicate, context);
|
||
var keys = obj.length !== +obj.length && _.keys(obj),
|
||
length = (keys || obj).length,
|
||
index, currentKey;
|
||
for (index = 0; index < length; index++) {
|
||
currentKey = keys ? keys[index] : index;
|
||
if (!predicate(obj[currentKey], currentKey, obj)) return false;
|
||
}
|
||
return true;
|
||
};
|
||
|
||
// Determine if at least one element in the object matches a truth test.
|
||
// Aliased as `any`.
|
||
_.some = _.any = function(obj, predicate, context) {
|
||
if (obj == null) return false;
|
||
predicate = _.iteratee(predicate, context);
|
||
var keys = obj.length !== +obj.length && _.keys(obj),
|
||
length = (keys || obj).length,
|
||
index, currentKey;
|
||
for (index = 0; index < length; index++) {
|
||
currentKey = keys ? keys[index] : index;
|
||
if (predicate(obj[currentKey], currentKey, obj)) return true;
|
||
}
|
||
return false;
|
||
};
|
||
|
||
// Determine if the array or object contains a given value (using `===`).
|
||
// Aliased as `include`.
|
||
_.contains = _.include = function(obj, target) {
|
||
if (obj == null) return false;
|
||
if (obj.length !== +obj.length) obj = _.values(obj);
|
||
return _.indexOf(obj, target) >= 0;
|
||
};
|
||
|
||
// Invoke a method (with arguments) on every item in a collection.
|
||
_.invoke = function(obj, method) {
|
||
var args = slice.call(arguments, 2);
|
||
var isFunc = _.isFunction(method);
|
||
return _.map(obj, function(value) {
|
||
return (isFunc ? method : value[method]).apply(value, args);
|
||
});
|
||
};
|
||
|
||
// Convenience version of a common use case of `map`: fetching a property.
|
||
_.pluck = function(obj, key) {
|
||
return _.map(obj, _.property(key));
|
||
};
|
||
|
||
// Convenience version of a common use case of `filter`: selecting only objects
|
||
// containing specific `key:value` pairs.
|
||
_.where = function(obj, attrs) {
|
||
return _.filter(obj, _.matches(attrs));
|
||
};
|
||
|
||
// Convenience version of a common use case of `find`: getting the first object
|
||
// containing specific `key:value` pairs.
|
||
_.findWhere = function(obj, attrs) {
|
||
return _.find(obj, _.matches(attrs));
|
||
};
|
||
|
||
// Return the maximum element (or element-based computation).
|
||
_.max = function(obj, iteratee, context) {
|
||
var result = -Infinity, lastComputed = -Infinity,
|
||
value, computed;
|
||
if (iteratee == null && obj != null) {
|
||
obj = obj.length === +obj.length ? obj : _.values(obj);
|
||
for (var i = 0, length = obj.length; i < length; i++) {
|
||
value = obj[i];
|
||
if (value > result) {
|
||
result = value;
|
||
}
|
||
}
|
||
} else {
|
||
iteratee = _.iteratee(iteratee, context);
|
||
_.each(obj, function(value, index, list) {
|
||
computed = iteratee(value, index, list);
|
||
if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
|
||
result = value;
|
||
lastComputed = computed;
|
||
}
|
||
});
|
||
}
|
||
return result;
|
||
};
|
||
|
||
// Return the minimum element (or element-based computation).
|
||
_.min = function(obj, iteratee, context) {
|
||
var result = Infinity, lastComputed = Infinity,
|
||
value, computed;
|
||
if (iteratee == null && obj != null) {
|
||
obj = obj.length === +obj.length ? obj : _.values(obj);
|
||
for (var i = 0, length = obj.length; i < length; i++) {
|
||
value = obj[i];
|
||
if (value < result) {
|
||
result = value;
|
||
}
|
||
}
|
||
} else {
|
||
iteratee = _.iteratee(iteratee, context);
|
||
_.each(obj, function(value, index, list) {
|
||
computed = iteratee(value, index, list);
|
||
if (computed < lastComputed || computed === Infinity && result === Infinity) {
|
||
result = value;
|
||
lastComputed = computed;
|
||
}
|
||
});
|
||
}
|
||
return result;
|
||
};
|
||
|
||
// Shuffle a collection, using the modern version of the
|
||
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
|
||
_.shuffle = function(obj) {
|
||
var set = obj && obj.length === +obj.length ? obj : _.values(obj);
|
||
var length = set.length;
|
||
var shuffled = Array(length);
|
||
for (var index = 0, rand; index < length; index++) {
|
||
rand = _.random(0, index);
|
||
if (rand !== index) shuffled[index] = shuffled[rand];
|
||
shuffled[rand] = set[index];
|
||
}
|
||
return shuffled;
|
||
};
|
||
|
||
// Sample **n** random values from a collection.
|
||
// If **n** is not specified, returns a single random element.
|
||
// The internal `guard` argument allows it to work with `map`.
|
||
_.sample = function(obj, n, guard) {
|
||
if (n == null || guard) {
|
||
if (obj.length !== +obj.length) obj = _.values(obj);
|
||
return obj[_.random(obj.length - 1)];
|
||
}
|
||
return _.shuffle(obj).slice(0, Math.max(0, n));
|
||
};
|
||
|
||
// Sort the object's values by a criterion produced by an iteratee.
|
||
_.sortBy = function(obj, iteratee, context) {
|
||
iteratee = _.iteratee(iteratee, context);
|
||
return _.pluck(_.map(obj, function(value, index, list) {
|
||
return {
|
||
value: value,
|
||
index: index,
|
||
criteria: iteratee(value, index, list)
|
||
};
|
||
}).sort(function(left, right) {
|
||
var a = left.criteria;
|
||
var b = right.criteria;
|
||
if (a !== b) {
|
||
if (a > b || a === void 0) return 1;
|
||
if (a < b || b === void 0) return -1;
|
||
}
|
||
return left.index - right.index;
|
||
}), 'value');
|
||
};
|
||
|
||
// An internal function used for aggregate "group by" operations.
|
||
var group = function(behavior) {
|
||
return function(obj, iteratee, context) {
|
||
var result = {};
|
||
iteratee = _.iteratee(iteratee, context);
|
||
_.each(obj, function(value, index) {
|
||
var key = iteratee(value, index, obj);
|
||
behavior(result, value, key);
|
||
});
|
||
return result;
|
||
};
|
||
};
|
||
|
||
// Groups the object's values by a criterion. Pass either a string attribute
|
||
// to group by, or a function that returns the criterion.
|
||
_.groupBy = group(function(result, value, key) {
|
||
if (_.has(result, key)) result[key].push(value); else result[key] = [value];
|
||
});
|
||
|
||
// Indexes the object's values by a criterion, similar to `groupBy`, but for
|
||
// when you know that your index values will be unique.
|
||
_.indexBy = group(function(result, value, key) {
|
||
result[key] = value;
|
||
});
|
||
|
||
// Counts instances of an object that group by a certain criterion. Pass
|
||
// either a string attribute to count by, or a function that returns the
|
||
// criterion.
|
||
_.countBy = group(function(result, value, key) {
|
||
if (_.has(result, key)) result[key]++; else result[key] = 1;
|
||
});
|
||
|
||
// Use a comparator function to figure out the smallest index at which
|
||
// an object should be inserted so as to maintain order. Uses binary search.
|
||
_.sortedIndex = function(array, obj, iteratee, context) {
|
||
iteratee = _.iteratee(iteratee, context, 1);
|
||
var value = iteratee(obj);
|
||
var low = 0, high = array.length;
|
||
while (low < high) {
|
||
var mid = low + high >>> 1;
|
||
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
|
||
}
|
||
return low;
|
||
};
|
||
|
||
// Safely create a real, live array from anything iterable.
|
||
_.toArray = function(obj) {
|
||
if (!obj) return [];
|
||
if (_.isArray(obj)) return slice.call(obj);
|
||
if (obj.length === +obj.length) return _.map(obj, _.identity);
|
||
return _.values(obj);
|
||
};
|
||
|
||
// Return the number of elements in an object.
|
||
_.size = function(obj) {
|
||
if (obj == null) return 0;
|
||
return obj.length === +obj.length ? obj.length : _.keys(obj).length;
|
||
};
|
||
|
||
// Split a collection into two arrays: one whose elements all satisfy the given
|
||
// predicate, and one whose elements all do not satisfy the predicate.
|
||
_.partition = function(obj, predicate, context) {
|
||
predicate = _.iteratee(predicate, context);
|
||
var pass = [], fail = [];
|
||
_.each(obj, function(value, key, obj) {
|
||
(predicate(value, key, obj) ? pass : fail).push(value);
|
||
});
|
||
return [pass, fail];
|
||
};
|
||
|
||
// Array Functions
|
||
// ---------------
|
||
|
||
// Get the first element of an array. Passing **n** will return the first N
|
||
// values in the array. Aliased as `head` and `take`. The **guard** check
|
||
// allows it to work with `_.map`.
|
||
_.first = _.head = _.take = function(array, n, guard) {
|
||
if (array == null) return void 0;
|
||
if (n == null || guard) return array[0];
|
||
if (n < 0) return [];
|
||
return slice.call(array, 0, n);
|
||
};
|
||
|
||
// Returns everything but the last entry of the array. Especially useful on
|
||
// the arguments object. Passing **n** will return all the values in
|
||
// the array, excluding the last N. The **guard** check allows it to work with
|
||
// `_.map`.
|
||
_.initial = function(array, n, guard) {
|
||
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
|
||
};
|
||
|
||
// Get the last element of an array. Passing **n** will return the last N
|
||
// values in the array. The **guard** check allows it to work with `_.map`.
|
||
_.last = function(array, n, guard) {
|
||
if (array == null) return void 0;
|
||
if (n == null || guard) return array[array.length - 1];
|
||
return slice.call(array, Math.max(array.length - n, 0));
|
||
};
|
||
|
||
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
|
||
// Especially useful on the arguments object. Passing an **n** will return
|
||
// the rest N values in the array. The **guard**
|
||
// check allows it to work with `_.map`.
|
||
_.rest = _.tail = _.drop = function(array, n, guard) {
|
||
return slice.call(array, n == null || guard ? 1 : n);
|
||
};
|
||
|
||
// Trim out all falsy values from an array.
|
||
_.compact = function(array) {
|
||
return _.filter(array, _.identity);
|
||
};
|
||
|
||
// Internal implementation of a recursive `flatten` function.
|
||
var flatten = function(input, shallow, strict, output) {
|
||
if (shallow && _.every(input, _.isArray)) {
|
||
return concat.apply(output, input);
|
||
}
|
||
for (var i = 0, length = input.length; i < length; i++) {
|
||
var value = input[i];
|
||
if (!_.isArray(value) && !_.isArguments(value)) {
|
||
if (!strict) output.push(value);
|
||
} else if (shallow) {
|
||
push.apply(output, value);
|
||
} else {
|
||
flatten(value, shallow, strict, output);
|
||
}
|
||
}
|
||
return output;
|
||
};
|
||
|
||
// Flatten out an array, either recursively (by default), or just one level.
|
||
_.flatten = function(array, shallow) {
|
||
return flatten(array, shallow, false, []);
|
||
};
|
||
|
||
// Return a version of the array that does not contain the specified value(s).
|
||
_.without = function(array) {
|
||
return _.difference(array, slice.call(arguments, 1));
|
||
};
|
||
|
||
// Produce a duplicate-free version of the array. If the array has already
|
||
// been sorted, you have the option of using a faster algorithm.
|
||
// Aliased as `unique`.
|
||
_.uniq = _.unique = function(array, isSorted, iteratee, context) {
|
||
if (array == null) return [];
|
||
if (!_.isBoolean(isSorted)) {
|
||
context = iteratee;
|
||
iteratee = isSorted;
|
||
isSorted = false;
|
||
}
|
||
if (iteratee != null) iteratee = _.iteratee(iteratee, context);
|
||
var result = [];
|
||
var seen = [];
|
||
for (var i = 0, length = array.length; i < length; i++) {
|
||
var value = array[i];
|
||
if (isSorted) {
|
||
if (!i || seen !== value) result.push(value);
|
||
seen = value;
|
||
} else if (iteratee) {
|
||
var computed = iteratee(value, i, array);
|
||
if (_.indexOf(seen, computed) < 0) {
|
||
seen.push(computed);
|
||
result.push(value);
|
||
}
|
||
} else if (_.indexOf(result, value) < 0) {
|
||
result.push(value);
|
||
}
|
||
}
|
||
return result;
|
||
};
|
||
|
||
// Produce an array that contains the union: each distinct element from all of
|
||
// the passed-in arrays.
|
||
_.union = function() {
|
||
return _.uniq(flatten(arguments, true, true, []));
|
||
};
|
||
|
||
// Produce an array that contains every item shared between all the
|
||
// passed-in arrays.
|
||
_.intersection = function(array) {
|
||
if (array == null) return [];
|
||
var result = [];
|
||
var argsLength = arguments.length;
|
||
for (var i = 0, length = array.length; i < length; i++) {
|
||
var item = array[i];
|
||
if (_.contains(result, item)) continue;
|
||
for (var j = 1; j < argsLength; j++) {
|
||
if (!_.contains(arguments[j], item)) break;
|
||
}
|
||
if (j === argsLength) result.push(item);
|
||
}
|
||
return result;
|
||
};
|
||
|
||
// Take the difference between one array and a number of other arrays.
|
||
// Only the elements present in just the first array will remain.
|
||
_.difference = function(array) {
|
||
var rest = flatten(slice.call(arguments, 1), true, true, []);
|
||
return _.filter(array, function(value){
|
||
return !_.contains(rest, value);
|
||
});
|
||
};
|
||
|
||
// Zip together multiple lists into a single array -- elements that share
|
||
// an index go together.
|
||
_.zip = function(array) {
|
||
if (array == null) return [];
|
||
var length = _.max(arguments, 'length').length;
|
||
var results = Array(length);
|
||
for (var i = 0; i < length; i++) {
|
||
results[i] = _.pluck(arguments, i);
|
||
}
|
||
return results;
|
||
};
|
||
|
||
// Converts lists into objects. Pass either a single array of `[key, value]`
|
||
// pairs, or two parallel arrays of the same length -- one of keys, and one of
|
||
// the corresponding values.
|
||
_.object = function(list, values) {
|
||
if (list == null) return {};
|
||
var result = {};
|
||
for (var i = 0, length = list.length; i < length; i++) {
|
||
if (values) {
|
||
result[list[i]] = values[i];
|
||
} else {
|
||
result[list[i][0]] = list[i][1];
|
||
}
|
||
}
|
||
return result;
|
||
};
|
||
|
||
// Return the position of the first occurrence of an item in an array,
|
||
// or -1 if the item is not included in the array.
|
||
// If the array is large and already in sort order, pass `true`
|
||
// for **isSorted** to use binary search.
|
||
_.indexOf = function(array, item, isSorted) {
|
||
if (array == null) return -1;
|
||
var i = 0, length = array.length;
|
||
if (isSorted) {
|
||
if (typeof isSorted == 'number') {
|
||
i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
|
||
} else {
|
||
i = _.sortedIndex(array, item);
|
||
return array[i] === item ? i : -1;
|
||
}
|
||
}
|
||
for (; i < length; i++) if (array[i] === item) return i;
|
||
return -1;
|
||
};
|
||
|
||
_.lastIndexOf = function(array, item, from) {
|
||
if (array == null) return -1;
|
||
var idx = array.length;
|
||
if (typeof from == 'number') {
|
||
idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
|
||
}
|
||
while (--idx >= 0) if (array[idx] === item) return idx;
|
||
return -1;
|
||
};
|
||
|
||
// Generate an integer Array containing an arithmetic progression. A port of
|
||
// the native Python `range()` function. See
|
||
// [the Python documentation](http://docs.python.org/library/functions.html#range).
|
||
_.range = function(start, stop, step) {
|
||
if (arguments.length <= 1) {
|
||
stop = start || 0;
|
||
start = 0;
|
||
}
|
||
step = step || 1;
|
||
|
||
var length = Math.max(Math.ceil((stop - start) / step), 0);
|
||
var range = Array(length);
|
||
|
||
for (var idx = 0; idx < length; idx++, start += step) {
|
||
range[idx] = start;
|
||
}
|
||
|
||
return range;
|
||
};
|
||
|
||
// Function (ahem) Functions
|
||
// ------------------
|
||
|
||
// Reusable constructor function for prototype setting.
|
||
var Ctor = function(){};
|
||
|
||
// Create a function bound to a given object (assigning `this`, and arguments,
|
||
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
|
||
// available.
|
||
_.bind = function(func, context) {
|
||
var args, bound;
|
||
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
||
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
|
||
args = slice.call(arguments, 2);
|
||
bound = function() {
|
||
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
|
||
Ctor.prototype = func.prototype;
|
||
var self = new Ctor;
|
||
Ctor.prototype = null;
|
||
var result = func.apply(self, args.concat(slice.call(arguments)));
|
||
if (_.isObject(result)) return result;
|
||
return self;
|
||
};
|
||
return bound;
|
||
};
|
||
|
||
// Partially apply a function by creating a version that has had some of its
|
||
// arguments pre-filled, without changing its dynamic `this` context. _ acts
|
||
// as a placeholder, allowing any combination of arguments to be pre-filled.
|
||
_.partial = function(func) {
|
||
var boundArgs = slice.call(arguments, 1);
|
||
return function() {
|
||
var position = 0;
|
||
var args = boundArgs.slice();
|
||
for (var i = 0, length = args.length; i < length; i++) {
|
||
if (args[i] === _) args[i] = arguments[position++];
|
||
}
|
||
while (position < arguments.length) args.push(arguments[position++]);
|
||
return func.apply(this, args);
|
||
};
|
||
};
|
||
|
||
// Bind a number of an object's methods to that object. Remaining arguments
|
||
// are the method names to be bound. Useful for ensuring that all callbacks
|
||
// defined on an object belong to it.
|
||
_.bindAll = function(obj) {
|
||
var i, length = arguments.length, key;
|
||
if (length <= 1) throw new Error('bindAll must be passed function names');
|
||
for (i = 1; i < length; i++) {
|
||
key = arguments[i];
|
||
obj[key] = _.bind(obj[key], obj);
|
||
}
|
||
return obj;
|
||
};
|
||
|
||
// Memoize an expensive function by storing its results.
|
||
_.memoize = function(func, hasher) {
|
||
var memoize = function(key) {
|
||
var cache = memoize.cache;
|
||
var address = hasher ? hasher.apply(this, arguments) : key;
|
||
if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
|
||
return cache[address];
|
||
};
|
||
memoize.cache = {};
|
||
return memoize;
|
||
};
|
||
|
||
// Delays a function for the given number of milliseconds, and then calls
|
||
// it with the arguments supplied.
|
||
_.delay = function(func, wait) {
|
||
var args = slice.call(arguments, 2);
|
||
return setTimeout(function(){
|
||
return func.apply(null, args);
|
||
}, wait);
|
||
};
|
||
|
||
// Defers a function, scheduling it to run after the current call stack has
|
||
// cleared.
|
||
_.defer = function(func) {
|
||
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
|
||
};
|
||
|
||
// Returns a function, that, when invoked, will only be triggered at most once
|
||
// during a given window of time. Normally, the throttled function will run
|
||
// as much as it can, without ever going more than once per `wait` duration;
|
||
// but if you'd like to disable the execution on the leading edge, pass
|
||
// `{leading: false}`. To disable execution on the trailing edge, ditto.
|
||
_.throttle = function(func, wait, options) {
|
||
var context, args, result;
|
||
var timeout = null;
|
||
var previous = 0;
|
||
if (!options) options = {};
|
||
var later = function() {
|
||
previous = options.leading === false ? 0 : _.now();
|
||
timeout = null;
|
||
result = func.apply(context, args);
|
||
if (!timeout) context = args = null;
|
||
};
|
||
return function() {
|
||
var now = _.now();
|
||
if (!previous && options.leading === false) previous = now;
|
||
var remaining = wait - (now - previous);
|
||
context = this;
|
||
args = arguments;
|
||
if (remaining <= 0 || remaining > wait) {
|
||
clearTimeout(timeout);
|
||
timeout = null;
|
||
previous = now;
|
||
result = func.apply(context, args);
|
||
if (!timeout) context = args = null;
|
||
} else if (!timeout && options.trailing !== false) {
|
||
timeout = setTimeout(later, remaining);
|
||
}
|
||
return result;
|
||
};
|
||
};
|
||
|
||
// Returns a function, that, as long as it continues to be invoked, will not
|
||
// be triggered. The function will be called after it stops being called for
|
||
// N milliseconds. If `immediate` is passed, trigger the function on the
|
||
// leading edge, instead of the trailing.
|
||
_.debounce = function(func, wait, immediate) {
|
||
var timeout, args, context, timestamp, result;
|
||
|
||
var later = function() {
|
||
var last = _.now() - timestamp;
|
||
|
||
if (last < wait && last > 0) {
|
||
timeout = setTimeout(later, wait - last);
|
||
} else {
|
||
timeout = null;
|
||
if (!immediate) {
|
||
result = func.apply(context, args);
|
||
if (!timeout) context = args = null;
|
||
}
|
||
}
|
||
};
|
||
|
||
return function() {
|
||
context = this;
|
||
args = arguments;
|
||
timestamp = _.now();
|
||
var callNow = immediate && !timeout;
|
||
if (!timeout) timeout = setTimeout(later, wait);
|
||
if (callNow) {
|
||
result = func.apply(context, args);
|
||
context = args = null;
|
||
}
|
||
|
||
return result;
|
||
};
|
||
};
|
||
|
||
// Returns the first function passed as an argument to the second,
|
||
// allowing you to adjust arguments, run code before and after, and
|
||
// conditionally execute the original function.
|
||
_.wrap = function(func, wrapper) {
|
||
return _.partial(wrapper, func);
|
||
};
|
||
|
||
// Returns a negated version of the passed-in predicate.
|
||
_.negate = function(predicate) {
|
||
return function() {
|
||
return !predicate.apply(this, arguments);
|
||
};
|
||
};
|
||
|
||
// Returns a function that is the composition of a list of functions, each
|
||
// consuming the return value of the function that follows.
|
||
_.compose = function() {
|
||
var args = arguments;
|
||
var start = args.length - 1;
|
||
return function() {
|
||
var i = start;
|
||
var result = args[start].apply(this, arguments);
|
||
while (i--) result = args[i].call(this, result);
|
||
return result;
|
||
};
|
||
};
|
||
|
||
// Returns a function that will only be executed after being called N times.
|
||
_.after = function(times, func) {
|
||
return function() {
|
||
if (--times < 1) {
|
||
return func.apply(this, arguments);
|
||
}
|
||
};
|
||
};
|
||
|
||
// Returns a function that will only be executed before being called N times.
|
||
_.before = function(times, func) {
|
||
var memo;
|
||
return function() {
|
||
if (--times > 0) {
|
||
memo = func.apply(this, arguments);
|
||
} else {
|
||
func = null;
|
||
}
|
||
return memo;
|
||
};
|
||
};
|
||
|
||
// Returns a function that will be executed at most one time, no matter how
|
||
// often you call it. Useful for lazy initialization.
|
||
_.once = _.partial(_.before, 2);
|
||
|
||
// Object Functions
|
||
// ----------------
|
||
|
||
// Retrieve the names of an object's properties.
|
||
// Delegates to **ECMAScript 5**'s native `Object.keys`
|
||
_.keys = function(obj) {
|
||
if (!_.isObject(obj)) return [];
|
||
if (nativeKeys) return nativeKeys(obj);
|
||
var keys = [];
|
||
for (var key in obj) if (_.has(obj, key)) keys.push(key);
|
||
return keys;
|
||
};
|
||
|
||
// Retrieve the values of an object's properties.
|
||
_.values = function(obj) {
|
||
var keys = _.keys(obj);
|
||
var length = keys.length;
|
||
var values = Array(length);
|
||
for (var i = 0; i < length; i++) {
|
||
values[i] = obj[keys[i]];
|
||
}
|
||
return values;
|
||
};
|
||
|
||
// Convert an object into a list of `[key, value]` pairs.
|
||
_.pairs = function(obj) {
|
||
var keys = _.keys(obj);
|
||
var length = keys.length;
|
||
var pairs = Array(length);
|
||
for (var i = 0; i < length; i++) {
|
||
pairs[i] = [keys[i], obj[keys[i]]];
|
||
}
|
||
return pairs;
|
||
};
|
||
|
||
// Invert the keys and values of an object. The values must be serializable.
|
||
_.invert = function(obj) {
|
||
var result = {};
|
||
var keys = _.keys(obj);
|
||
for (var i = 0, length = keys.length; i < length; i++) {
|
||
result[obj[keys[i]]] = keys[i];
|
||
}
|
||
return result;
|
||
};
|
||
|
||
// Return a sorted list of the function names available on the object.
|
||
// Aliased as `methods`
|
||
_.functions = _.methods = function(obj) {
|
||
var names = [];
|
||
for (var key in obj) {
|
||
if (_.isFunction(obj[key])) names.push(key);
|
||
}
|
||
return names.sort();
|
||
};
|
||
|
||
// Extend a given object with all the properties in passed-in object(s).
|
||
_.extend = function(obj) {
|
||
if (!_.isObject(obj)) return obj;
|
||
var source, prop;
|
||
for (var i = 1, length = arguments.length; i < length; i++) {
|
||
source = arguments[i];
|
||
for (prop in source) {
|
||
if (hasOwnProperty.call(source, prop)) {
|
||
obj[prop] = source[prop];
|
||
}
|
||
}
|
||
}
|
||
return obj;
|
||
};
|
||
|
||
// Return a copy of the object only containing the whitelisted properties.
|
||
_.pick = function(obj, iteratee, context) {
|
||
var result = {}, key;
|
||
if (obj == null) return result;
|
||
if (_.isFunction(iteratee)) {
|
||
iteratee = createCallback(iteratee, context);
|
||
for (key in obj) {
|
||
var value = obj[key];
|
||
if (iteratee(value, key, obj)) result[key] = value;
|
||
}
|
||
} else {
|
||
var keys = concat.apply([], slice.call(arguments, 1));
|
||
obj = new Object(obj);
|
||
for (var i = 0, length = keys.length; i < length; i++) {
|
||
key = keys[i];
|
||
if (key in obj) result[key] = obj[key];
|
||
}
|
||
}
|
||
return result;
|
||
};
|
||
|
||
// Return a copy of the object without the blacklisted properties.
|
||
_.omit = function(obj, iteratee, context) {
|
||
if (_.isFunction(iteratee)) {
|
||
iteratee = _.negate(iteratee);
|
||
} else {
|
||
var keys = _.map(concat.apply([], slice.call(arguments, 1)), String);
|
||
iteratee = function(value, key) {
|
||
return !_.contains(keys, key);
|
||
};
|
||
}
|
||
return _.pick(obj, iteratee, context);
|
||
};
|
||
|
||
// Fill in a given object with default properties.
|
||
_.defaults = function(obj) {
|
||
if (!_.isObject(obj)) return obj;
|
||
for (var i = 1, length = arguments.length; i < length; i++) {
|
||
var source = arguments[i];
|
||
for (var prop in source) {
|
||
if (obj[prop] === void 0) obj[prop] = source[prop];
|
||
}
|
||
}
|
||
return obj;
|
||
};
|
||
|
||
// Create a (shallow-cloned) duplicate of an object.
|
||
_.clone = function(obj) {
|
||
if (!_.isObject(obj)) return obj;
|
||
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
||
};
|
||
|
||
// Invokes interceptor with the obj, and then returns obj.
|
||
// The primary purpose of this method is to "tap into" a method chain, in
|
||
// order to perform operations on intermediate results within the chain.
|
||
_.tap = function(obj, interceptor) {
|
||
interceptor(obj);
|
||
return obj;
|
||
};
|
||
|
||
// Internal recursive comparison function for `isEqual`.
|
||
var eq = function(a, b, aStack, bStack) {
|
||
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
||
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
|
||
if (a === b) return a !== 0 || 1 / a === 1 / b;
|
||
// A strict comparison is necessary because `null == undefined`.
|
||
if (a == null || b == null) return a === b;
|
||
// Unwrap any wrapped objects.
|
||
if (a instanceof _) a = a._wrapped;
|
||
if (b instanceof _) b = b._wrapped;
|
||
// Compare `[[Class]]` names.
|
||
var className = toString.call(a);
|
||
if (className !== toString.call(b)) return false;
|
||
switch (className) {
|
||
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
|
||
case '[object RegExp]':
|
||
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
|
||
case '[object String]':
|
||
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
||
// equivalent to `new String("5")`.
|
||
return '' + a === '' + b;
|
||
case '[object Number]':
|
||
// `NaN`s are equivalent, but non-reflexive.
|
||
// Object(NaN) is equivalent to NaN
|
||
if (+a !== +a) return +b !== +b;
|
||
// An `egal` comparison is performed for other numeric values.
|
||
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
|
||
case '[object Date]':
|
||
case '[object Boolean]':
|
||
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
||
// millisecond representations. Note that invalid dates with millisecond representations
|
||
// of `NaN` are not equivalent.
|
||
return +a === +b;
|
||
}
|
||
if (typeof a != 'object' || typeof b != 'object') return false;
|
||
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
||
var length = aStack.length;
|
||
while (length--) {
|
||
// Linear search. Performance is inversely proportional to the number of
|
||
// unique nested structures.
|
||
if (aStack[length] === a) return bStack[length] === b;
|
||
}
|
||
// Objects with different constructors are not equivalent, but `Object`s
|
||
// from different frames are.
|
||
var aCtor = a.constructor, bCtor = b.constructor;
|
||
if (
|
||
aCtor !== bCtor &&
|
||
// Handle Object.create(x) cases
|
||
'constructor' in a && 'constructor' in b &&
|
||
!(_.isFunction(aCtor) && aCtor instanceof aCtor &&
|
||
_.isFunction(bCtor) && bCtor instanceof bCtor)
|
||
) {
|
||
return false;
|
||
}
|
||
// Add the first object to the stack of traversed objects.
|
||
aStack.push(a);
|
||
bStack.push(b);
|
||
var size, result;
|
||
// Recursively compare objects and arrays.
|
||
if (className === '[object Array]') {
|
||
// Compare array lengths to determine if a deep comparison is necessary.
|
||
size = a.length;
|
||
result = size === b.length;
|
||
if (result) {
|
||
// Deep compare the contents, ignoring non-numeric properties.
|
||
while (size--) {
|
||
if (!(result = eq(a[size], b[size], aStack, bStack))) break;
|
||
}
|
||
}
|
||
} else {
|
||
// Deep compare objects.
|
||
var keys = _.keys(a), key;
|
||
size = keys.length;
|
||
// Ensure that both objects contain the same number of properties before comparing deep equality.
|
||
result = _.keys(b).length === size;
|
||
if (result) {
|
||
while (size--) {
|
||
// Deep compare each member
|
||
key = keys[size];
|
||
if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
|
||
}
|
||
}
|
||
}
|
||
// Remove the first object from the stack of traversed objects.
|
||
aStack.pop();
|
||
bStack.pop();
|
||
return result;
|
||
};
|
||
|
||
// Perform a deep comparison to check if two objects are equal.
|
||
_.isEqual = function(a, b) {
|
||
return eq(a, b, [], []);
|
||
};
|
||
|
||
// Is a given array, string, or object empty?
|
||
// An "empty" object has no enumerable own-properties.
|
||
_.isEmpty = function(obj) {
|
||
if (obj == null) return true;
|
||
if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0;
|
||
for (var key in obj) if (_.has(obj, key)) return false;
|
||
return true;
|
||
};
|
||
|
||
// Is a given value a DOM element?
|
||
_.isElement = function(obj) {
|
||
return !!(obj && obj.nodeType === 1);
|
||
};
|
||
|
||
// Is a given value an array?
|
||
// Delegates to ECMA5's native Array.isArray
|
||
_.isArray = nativeIsArray || function(obj) {
|
||
return toString.call(obj) === '[object Array]';
|
||
};
|
||
|
||
// Is a given variable an object?
|
||
_.isObject = function(obj) {
|
||
var type = typeof obj;
|
||
return type === 'function' || type === 'object' && !!obj;
|
||
};
|
||
|
||
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
|
||
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
|
||
_['is' + name] = function(obj) {
|
||
return toString.call(obj) === '[object ' + name + ']';
|
||
};
|
||
});
|
||
|
||
// Define a fallback version of the method in browsers (ahem, IE), where
|
||
// there isn't any inspectable "Arguments" type.
|
||
if (!_.isArguments(arguments)) {
|
||
_.isArguments = function(obj) {
|
||
return _.has(obj, 'callee');
|
||
};
|
||
}
|
||
|
||
// Optimize `isFunction` if appropriate. Work around an IE 11 bug.
|
||
if (typeof /./ !== 'function') {
|
||
_.isFunction = function(obj) {
|
||
return typeof obj == 'function' || false;
|
||
};
|
||
}
|
||
|
||
// Is a given object a finite number?
|
||
_.isFinite = function(obj) {
|
||
return isFinite(obj) && !isNaN(parseFloat(obj));
|
||
};
|
||
|
||
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
|
||
_.isNaN = function(obj) {
|
||
return _.isNumber(obj) && obj !== +obj;
|
||
};
|
||
|
||
// Is a given value a boolean?
|
||
_.isBoolean = function(obj) {
|
||
return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
|
||
};
|
||
|
||
// Is a given value equal to null?
|
||
_.isNull = function(obj) {
|
||
return obj === null;
|
||
};
|
||
|
||
// Is a given variable undefined?
|
||
_.isUndefined = function(obj) {
|
||
return obj === void 0;
|
||
};
|
||
|
||
// Shortcut function for checking if an object has a given property directly
|
||
// on itself (in other words, not on a prototype).
|
||
_.has = function(obj, key) {
|
||
return obj != null && hasOwnProperty.call(obj, key);
|
||
};
|
||
|
||
// Utility Functions
|
||
// -----------------
|
||
|
||
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
|
||
// previous owner. Returns a reference to the Underscore object.
|
||
_.noConflict = function() {
|
||
root._ = previousUnderscore;
|
||
return this;
|
||
};
|
||
|
||
// Keep the identity function around for default iteratees.
|
||
_.identity = function(value) {
|
||
return value;
|
||
};
|
||
|
||
_.constant = function(value) {
|
||
return function() {
|
||
return value;
|
||
};
|
||
};
|
||
|
||
_.noop = function(){};
|
||
|
||
_.property = function(key) {
|
||
return function(obj) {
|
||
return obj[key];
|
||
};
|
||
};
|
||
|
||
// Returns a predicate for checking whether an object has a given set of `key:value` pairs.
|
||
_.matches = function(attrs) {
|
||
var pairs = _.pairs(attrs), length = pairs.length;
|
||
return function(obj) {
|
||
if (obj == null) return !length;
|
||
obj = new Object(obj);
|
||
for (var i = 0; i < length; i++) {
|
||
var pair = pairs[i], key = pair[0];
|
||
if (pair[1] !== obj[key] || !(key in obj)) return false;
|
||
}
|
||
return true;
|
||
};
|
||
};
|
||
|
||
// Run a function **n** times.
|
||
_.times = function(n, iteratee, context) {
|
||
var accum = Array(Math.max(0, n));
|
||
iteratee = createCallback(iteratee, context, 1);
|
||
for (var i = 0; i < n; i++) accum[i] = iteratee(i);
|
||
return accum;
|
||
};
|
||
|
||
// Return a random integer between min and max (inclusive).
|
||
_.random = function(min, max) {
|
||
if (max == null) {
|
||
max = min;
|
||
min = 0;
|
||
}
|
||
return min + Math.floor(Math.random() * (max - min + 1));
|
||
};
|
||
|
||
// A (possibly faster) way to get the current timestamp as an integer.
|
||
_.now = Date.now || function() {
|
||
return new Date().getTime();
|
||
};
|
||
|
||
// List of HTML entities for escaping.
|
||
var escapeMap = {
|
||
'&': '&',
|
||
'<': '<',
|
||
'>': '>',
|
||
'"': '"',
|
||
"'": ''',
|
||
'`': '`'
|
||
};
|
||
var unescapeMap = _.invert(escapeMap);
|
||
|
||
// Functions for escaping and unescaping strings to/from HTML interpolation.
|
||
var createEscaper = function(map) {
|
||
var escaper = function(match) {
|
||
return map[match];
|
||
};
|
||
// Regexes for identifying a key that needs to be escaped
|
||
var source = '(?:' + _.keys(map).join('|') + ')';
|
||
var testRegexp = RegExp(source);
|
||
var replaceRegexp = RegExp(source, 'g');
|
||
return function(string) {
|
||
string = string == null ? '' : '' + string;
|
||
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
|
||
};
|
||
};
|
||
_.escape = createEscaper(escapeMap);
|
||
_.unescape = createEscaper(unescapeMap);
|
||
|
||
// If the value of the named `property` is a function then invoke it with the
|
||
// `object` as context; otherwise, return it.
|
||
_.result = function(object, property) {
|
||
if (object == null) return void 0;
|
||
var value = object[property];
|
||
return _.isFunction(value) ? object[property]() : value;
|
||
};
|
||
|
||
// Generate a unique integer id (unique within the entire client session).
|
||
// Useful for temporary DOM ids.
|
||
var idCounter = 0;
|
||
_.uniqueId = function(prefix) {
|
||
var id = ++idCounter + '';
|
||
return prefix ? prefix + id : id;
|
||
};
|
||
|
||
// By default, Underscore uses ERB-style template delimiters, change the
|
||
// following template settings to use alternative delimiters.
|
||
_.templateSettings = {
|
||
evaluate : /<%([\s\S]+?)%>/g,
|
||
interpolate : /<%=([\s\S]+?)%>/g,
|
||
escape : /<%-([\s\S]+?)%>/g
|
||
};
|
||
|
||
// When customizing `templateSettings`, if you don't want to define an
|
||
// interpolation, evaluation or escaping regex, we need one that is
|
||
// guaranteed not to match.
|
||
var noMatch = /(.)^/;
|
||
|
||
// Certain characters need to be escaped so that they can be put into a
|
||
// string literal.
|
||
var escapes = {
|
||
"'": "'",
|
||
'\\': '\\',
|
||
'\r': 'r',
|
||
'\n': 'n',
|
||
'\u2028': 'u2028',
|
||
'\u2029': 'u2029'
|
||
};
|
||
|
||
var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
|
||
|
||
var escapeChar = function(match) {
|
||
return '\\' + escapes[match];
|
||
};
|
||
|
||
// JavaScript micro-templating, similar to John Resig's implementation.
|
||
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
||
// and correctly escapes quotes within interpolated code.
|
||
// NB: `oldSettings` only exists for backwards compatibility.
|
||
_.template = function(text, settings, oldSettings) {
|
||
if (!settings && oldSettings) settings = oldSettings;
|
||
settings = _.defaults({}, settings, _.templateSettings);
|
||
|
||
// Combine delimiters into one regular expression via alternation.
|
||
var matcher = RegExp([
|
||
(settings.escape || noMatch).source,
|
||
(settings.interpolate || noMatch).source,
|
||
(settings.evaluate || noMatch).source
|
||
].join('|') + '|$', 'g');
|
||
|
||
// Compile the template source, escaping string literals appropriately.
|
||
var index = 0;
|
||
var source = "__p+='";
|
||
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
|
||
source += text.slice(index, offset).replace(escaper, escapeChar);
|
||
index = offset + match.length;
|
||
|
||
if (escape) {
|
||
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
||
} else if (interpolate) {
|
||
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
||
} else if (evaluate) {
|
||
source += "';\n" + evaluate + "\n__p+='";
|
||
}
|
||
|
||
// Adobe VMs need the match returned to produce the correct offest.
|
||
return match;
|
||
});
|
||
source += "';\n";
|
||
|
||
// If a variable is not specified, place data values in local scope.
|
||
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
|
||
|
||
source = "var __t,__p='',__j=Array.prototype.join," +
|
||
"print=function(){__p+=__j.call(arguments,'');};\n" +
|
||
source + 'return __p;\n';
|
||
|
||
try {
|
||
var render = new Function(settings.variable || 'obj', '_', source);
|
||
} catch (e) {
|
||
e.source = source;
|
||
throw e;
|
||
}
|
||
|
||
var template = function(data) {
|
||
return render.call(this, data, _);
|
||
};
|
||
|
||
// Provide the compiled source as a convenience for precompilation.
|
||
var argument = settings.variable || 'obj';
|
||
template.source = 'function(' + argument + '){\n' + source + '}';
|
||
|
||
return template;
|
||
};
|
||
|
||
// Add a "chain" function. Start chaining a wrapped Underscore object.
|
||
_.chain = function(obj) {
|
||
var instance = _(obj);
|
||
instance._chain = true;
|
||
return instance;
|
||
};
|
||
|
||
// OOP
|
||
// ---------------
|
||
// If Underscore is called as a function, it returns a wrapped object that
|
||
// can be used OO-style. This wrapper holds altered versions of all the
|
||
// underscore functions. Wrapped objects may be chained.
|
||
|
||
// Helper function to continue chaining intermediate results.
|
||
var result = function(obj) {
|
||
return this._chain ? _(obj).chain() : obj;
|
||
};
|
||
|
||
// Add your own custom functions to the Underscore object.
|
||
_.mixin = function(obj) {
|
||
_.each(_.functions(obj), function(name) {
|
||
var func = _[name] = obj[name];
|
||
_.prototype[name] = function() {
|
||
var args = [this._wrapped];
|
||
push.apply(args, arguments);
|
||
return result.call(this, func.apply(_, args));
|
||
};
|
||
});
|
||
};
|
||
|
||
// Add all of the Underscore functions to the wrapper object.
|
||
_.mixin(_);
|
||
|
||
// Add all mutator Array functions to the wrapper.
|
||
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
|
||
var method = ArrayProto[name];
|
||
_.prototype[name] = function() {
|
||
var obj = this._wrapped;
|
||
method.apply(obj, arguments);
|
||
if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
|
||
return result.call(this, obj);
|
||
};
|
||
});
|
||
|
||
// Add all accessor Array functions to the wrapper.
|
||
_.each(['concat', 'join', 'slice'], function(name) {
|
||
var method = ArrayProto[name];
|
||
_.prototype[name] = function() {
|
||
return result.call(this, method.apply(this._wrapped, arguments));
|
||
};
|
||
});
|
||
|
||
// Extracts the result from a wrapped and chained object.
|
||
_.prototype.value = function() {
|
||
return this._wrapped;
|
||
};
|
||
|
||
// AMD registration happens at the end for compatibility with AMD loaders
|
||
// that may not enforce next-turn semantics on modules. Even though general
|
||
// practice for AMD registration is to be anonymous, underscore registers
|
||
// as a named module because, like jQuery, it is a base library that is
|
||
// popular enough to be bundled in a third party lib, but not be part of
|
||
// an AMD load request. Those cases could generate an error when an
|
||
// anonymous define() is called outside of a loader request.
|
||
if (typeof define === 'function' && define.amd) {
|
||
define('underscore', [], function() {
|
||
return _;
|
||
});
|
||
}
|
||
}.call(this));
|
||
|
||
},{}],85:[function(require,module,exports){
|
||
var Connector_uninitialized, Test, Y, chai, expect, should, sinon, sinonChai, _,
|
||
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
||
|
||
chai = require('chai');
|
||
|
||
expect = chai.expect;
|
||
|
||
should = chai.should();
|
||
|
||
sinon = require('sinon');
|
||
|
||
sinonChai = require('sinon-chai');
|
||
|
||
_ = require("underscore");
|
||
|
||
chai.use(sinonChai);
|
||
|
||
Y = require("../lib/index");
|
||
|
||
Connector_uninitialized = require("../lib/Connectors/TestConnector");
|
||
|
||
module.exports = Test = (function() {
|
||
function Test(name_suffix) {
|
||
this.name_suffix = name_suffix != null ? name_suffix : "";
|
||
this.applyRandomOp = __bind(this.applyRandomOp, this);
|
||
this.generateRandomOp = __bind(this.generateRandomOp, this);
|
||
this.getGeneratingFunctions = __bind(this.getGeneratingFunctions, this);
|
||
this.number_of_test_cases_multiplier = 1;
|
||
this.repeat_this = 1 * this.number_of_test_cases_multiplier;
|
||
this.doSomething_amount = 20 + this.number_of_test_cases_multiplier;
|
||
this.number_of_engines = 5 + this.number_of_test_cases_multiplier - 1;
|
||
this.time = 0;
|
||
this.ops = 0;
|
||
this.time_now = 0;
|
||
this.debug = false;
|
||
this.reinitialize();
|
||
}
|
||
|
||
Test.prototype.reinitialize = function() {
|
||
var i, u, _i, _ref;
|
||
this.users = [];
|
||
this.Connector = Connector_uninitialized(this.users);
|
||
for (i = _i = 0, _ref = this.number_of_engines; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
||
u = this.makeNewUser(i + this.name_suffix, this.Connector);
|
||
this.users.push(u);
|
||
}
|
||
return this.flushAll();
|
||
};
|
||
|
||
Test.prototype.makeNewUser = function(user) {
|
||
user.HB.setManualGarbageCollect();
|
||
return user;
|
||
};
|
||
|
||
Test.prototype.getSomeUser = function() {
|
||
var i;
|
||
i = _.random(0, this.users.length - 1);
|
||
return this.users[i];
|
||
};
|
||
|
||
Test.prototype.getRandomText = function(chars, min_length) {
|
||
var length, nextchar, text;
|
||
if (min_length == null) {
|
||
min_length = 0;
|
||
}
|
||
if (chars == null) {
|
||
chars = "abcdefghijklmnopqrstuvwxyz";
|
||
}
|
||
length = _.random(min_length, 10);
|
||
nextchar = chars[_.random(0, chars.length - 1)];
|
||
text = "";
|
||
_(length).times(function() {
|
||
return text += nextchar;
|
||
});
|
||
return text;
|
||
};
|
||
|
||
Test.prototype.getRandomObject = function() {
|
||
var key1, key2, result, val1, val2;
|
||
result = {};
|
||
key1 = this.getRandomKey();
|
||
key2 = this.getRandomKey();
|
||
val1 = this.getRandomText();
|
||
val2 = null;
|
||
if (_.random(0, 1) === 1) {
|
||
val2 = this.getRandomObject();
|
||
} else {
|
||
val2 = this.getRandomText();
|
||
}
|
||
result[key1] = val1;
|
||
result[key2] = val2;
|
||
return result;
|
||
};
|
||
|
||
Test.prototype.getRandomKey = function() {
|
||
return this.getRandomText([1, 2, 'x', 'y'], 1);
|
||
};
|
||
|
||
Test.prototype.getGeneratingFunctions = function(user_num) {
|
||
var types;
|
||
types = this.users[user_num].types;
|
||
return [
|
||
{
|
||
f: (function(_this) {
|
||
return function(y) {
|
||
y;
|
||
var pos;
|
||
pos = _.random(0, y.val().length - 1);
|
||
y.insertText(pos, _this.getRandomText());
|
||
return null;
|
||
};
|
||
})(this),
|
||
types: [types.WordType]
|
||
}, {
|
||
f: function(y) {
|
||
var length, ops1, pos;
|
||
if (y.val().length > 0) {
|
||
pos = _.random(0, y.val().length - 1);
|
||
length = _.random(0, y.val().length - pos);
|
||
ops1 = y.deleteText(pos, length);
|
||
}
|
||
return void 0;
|
||
},
|
||
types: [types.WordType]
|
||
}, {
|
||
f: (function(_this) {
|
||
return function(y) {
|
||
y.replaceText(_this.getRandomText());
|
||
return null;
|
||
};
|
||
})(this),
|
||
types: [types.WordType]
|
||
}
|
||
];
|
||
};
|
||
|
||
Test.prototype.getRandomRoot = function(user_num) {
|
||
throw new Error("overwrite me!");
|
||
};
|
||
|
||
Test.prototype.getContent = function(user_num) {
|
||
throw new Error("overwrite me!");
|
||
};
|
||
|
||
Test.prototype.generateRandomOp = function(user_num) {
|
||
var choices, i, y;
|
||
y = this.getRandomRoot(user_num);
|
||
choices = this.getGeneratingFunctions(user_num).filter(function(gf) {
|
||
return _.some(gf.types, function(type) {
|
||
return y instanceof type;
|
||
});
|
||
});
|
||
if (choices.length === 0) {
|
||
throw new Error("You forgot to specify a test generation methot for this Operation!");
|
||
}
|
||
i = _.random(0, choices.length - 1);
|
||
return choices[i].f(y);
|
||
};
|
||
|
||
Test.prototype.applyRandomOp = function(user_num) {
|
||
var user;
|
||
user = this.users[user_num];
|
||
return user.getConnector().flushOneRandom();
|
||
};
|
||
|
||
Test.prototype.doSomething = function() {
|
||
var choice, choices, user_num;
|
||
user_num = _.random(this.number_of_engines - 1);
|
||
choices = [this.applyRandomOp, this.generateRandomOp];
|
||
choice = _.random(choices.length - 1);
|
||
return choices[choice](user_num);
|
||
};
|
||
|
||
Test.prototype.flushAll = function(final) {
|
||
var ops, user, user_number, _i, _j, _len, _len1, _ref, _ref1, _results;
|
||
final = false;
|
||
if (this.users.length <= 1 || !final) {
|
||
_ref = this.users;
|
||
_results = [];
|
||
for (user_number = _i = 0, _len = _ref.length; _i < _len; user_number = ++_i) {
|
||
user = _ref[user_number];
|
||
_results.push(user.getConnector().flushAll());
|
||
}
|
||
return _results;
|
||
} else {
|
||
_ref1 = this.users.slice(1);
|
||
for (user_number = _j = 0, _len1 = _ref1.length; _j < _len1; user_number = ++_j) {
|
||
user = _ref1[user_number];
|
||
user.getConnector().flushAll();
|
||
}
|
||
ops = this.users[1].getHistoryBuffer()._encode(this.users[0].HB.getOperationCounter());
|
||
return this.users[0].engine.applyOpsCheckDouble(ops);
|
||
}
|
||
};
|
||
|
||
Test.prototype.compareAll = function(test_number) {
|
||
var i, j, number_of_created_operations, ops, ops_per_msek, printOpsInExecutionOrder, u, _i, _j, _k, _len, _ref, _ref1, _ref2, _results;
|
||
this.flushAll(true);
|
||
this.time += (new Date()).getTime() - this.time_now;
|
||
number_of_created_operations = 0;
|
||
for (i = _i = 0, _ref = this.users.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
||
number_of_created_operations += this.users[i].getConnector().getOpsInExecutionOrder().length;
|
||
}
|
||
this.ops += number_of_created_operations * this.users.length;
|
||
ops_per_msek = Math.floor(this.ops / this.time);
|
||
if (test_number != null) {
|
||
console.log(("" + test_number + "/" + this.repeat_this + ": " + number_of_created_operations + " were created and applied on (" + this.users.length + ") users ops in a different order.") + (" Over all we consumed " + this.ops + " operations in " + (this.time / 1000) + " seconds (" + ops_per_msek + " ops/msek)."));
|
||
}
|
||
_results = [];
|
||
for (i = _j = 0, _ref1 = this.users.length - 1; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
|
||
if (this.debug) {
|
||
if (!_.isEqual(this.getContent(i), this.getContent(i + 1))) {
|
||
printOpsInExecutionOrder = (function(_this) {
|
||
return function(otnumber, otherotnumber) {
|
||
var j, o, ops, s, _k, _l, _len, _len1;
|
||
ops = _.filter(_this.users[otnumber].getConnector().getOpsInExecutionOrder(), function(o) {
|
||
return typeof o.uid.op_name !== 'string' && o.uid.creator !== '_';
|
||
});
|
||
for (j = _k = 0, _len = ops.length; _k < _len; j = ++_k) {
|
||
s = ops[j];
|
||
console.log(("op" + j + " = ") + (JSON.stringify(s)));
|
||
}
|
||
console.log("");
|
||
s = "ops = [";
|
||
for (j = _l = 0, _len1 = ops.length; _l < _len1; j = ++_l) {
|
||
o = ops[j];
|
||
if (j !== 0) {
|
||
s += ", ";
|
||
}
|
||
s += "op" + j;
|
||
}
|
||
s += "]";
|
||
console.log(s);
|
||
console.log("@test_user.engine.applyOps ops");
|
||
console.log("expect(@test_user.val('name').val()).to.equal(\"" + (_this.users[otherotnumber].val('name').val()) + "\")");
|
||
return ops;
|
||
};
|
||
})(this);
|
||
console.log("");
|
||
console.log("Found an OT Puzzle!");
|
||
console.log("OT states:");
|
||
_ref2 = this.users;
|
||
for (j = _k = 0, _len = _ref2.length; _k < _len; j = ++_k) {
|
||
u = _ref2[j];
|
||
console.log(("OT" + j + ": ") + u.val('name').val());
|
||
}
|
||
console.log("\nOT execution order (" + i + "," + (i + 1) + "):");
|
||
printOpsInExecutionOrder(i, i + 1);
|
||
console.log("");
|
||
ops = printOpsInExecutionOrder(i + 1, i);
|
||
console.log("");
|
||
}
|
||
}
|
||
_results.push(expect(this.getContent(i)).to.deep.equal(this.getContent(i + 1)));
|
||
}
|
||
return _results;
|
||
};
|
||
|
||
Test.prototype.run = function() {
|
||
var i, times, u, _i, _j, _k, _l, _len, _ref, _ref1, _ref2, _ref3, _results;
|
||
if (this.debug) {
|
||
console.log('');
|
||
}
|
||
_results = [];
|
||
for (times = _i = 1, _ref = this.repeat_this; 1 <= _ref ? _i <= _ref : _i >= _ref; times = 1 <= _ref ? ++_i : --_i) {
|
||
this.time_now = (new Date).getTime();
|
||
for (i = _j = 1, _ref1 = Math.floor(this.doSomething_amount / 2); 1 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 1 <= _ref1 ? ++_j : --_j) {
|
||
this.doSomething();
|
||
}
|
||
this.flushAll(false);
|
||
_ref2 = this.users;
|
||
for (_k = 0, _len = _ref2.length; _k < _len; _k++) {
|
||
u = _ref2[_k];
|
||
u.HB.emptyGarbage();
|
||
}
|
||
for (i = _l = 1, _ref3 = Math.floor(this.doSomething_amount / 2); 1 <= _ref3 ? _l <= _ref3 : _l >= _ref3; i = 1 <= _ref3 ? ++_l : --_l) {
|
||
this.doSomething();
|
||
}
|
||
this.compareAll(times);
|
||
this.testHBencoding();
|
||
if (times !== this.repeat_this) {
|
||
_results.push(this.reinitialize());
|
||
} else {
|
||
_results.push(void 0);
|
||
}
|
||
}
|
||
return _results;
|
||
};
|
||
|
||
Test.prototype.testHBencoding = function() {
|
||
this.users[this.users.length] = this.makeNewUser(-1., Connector_uninitialized([]));
|
||
this.users[this.users.length - 1].engine.applyOps(this.users[0].HB._encode());
|
||
return expect(this.getContent(this.users.length - 1)).to.deep.equal(this.getContent(0));
|
||
};
|
||
|
||
return Test;
|
||
|
||
})();
|
||
|
||
|
||
},{"../lib/Connectors/TestConnector":2,"../lib/index":13,"chai":14,"sinon":69,"sinon-chai":68,"underscore":84}],86:[function(require,module,exports){
|
||
var $, Connector_uninitialized, Test, XmlTest, Y, chai, expect, should, sinon, sinonChai, _,
|
||
__hasProp = {}.hasOwnProperty,
|
||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
||
|
||
chai = require('chai');
|
||
|
||
expect = chai.expect;
|
||
|
||
should = chai.should();
|
||
|
||
sinon = require('sinon');
|
||
|
||
sinonChai = require('sinon-chai');
|
||
|
||
_ = require("underscore");
|
||
|
||
$ = require("jquery");
|
||
|
||
if (typeof document !== "undefined" && document !== null) {
|
||
document.$ = $;
|
||
}
|
||
|
||
require('coffee-errors');
|
||
|
||
chai.use(sinonChai);
|
||
|
||
Y = require("../lib/index");
|
||
|
||
Connector_uninitialized = require("../lib/Connectors/TestConnector");
|
||
|
||
Test = require("./TestSuite");
|
||
|
||
XmlTest = (function(_super) {
|
||
__extends(XmlTest, _super);
|
||
|
||
function XmlTest() {
|
||
return XmlTest.__super__.constructor.apply(this, arguments);
|
||
}
|
||
|
||
XmlTest.prototype.type = "XmlTest";
|
||
|
||
XmlTest.prototype.makeNewUser = function(user, conn) {
|
||
return XmlTest.__super__.makeNewUser.call(this, new Y.XmlFramework(user, conn));
|
||
};
|
||
|
||
XmlTest.prototype.getRandomRoot = function(user_num) {
|
||
return this.users[user_num].getSharedObject();
|
||
};
|
||
|
||
XmlTest.prototype.getContent = function(user_num) {
|
||
return this.users[user_num].val();
|
||
};
|
||
|
||
return XmlTest;
|
||
|
||
})(Test);
|
||
|
||
describe("XmlFramework", function() {
|
||
beforeEach(function(done) {
|
||
this.timeout(50000);
|
||
this.yTest = new XmlTest();
|
||
|
||
/*
|
||
|
||
@users = @yTest.users
|
||
*/
|
||
this.test_user = this.yTest.makeNewUser(0, Connector_uninitialized([]));
|
||
return done();
|
||
});
|
||
return it("can transform to a real Dom element", function() {
|
||
var dom, dom_;
|
||
dom = $("#test_dom")[0];
|
||
this.test_user.val(dom);
|
||
dom_ = this.test_user.val(true);
|
||
expect(dom_ !== dom).to.be["true"];
|
||
expect(dom_.outerHTML).to.equal(dom.outerHTML);
|
||
return console.log("dtrn");
|
||
});
|
||
});
|
||
|
||
|
||
},{"../lib/Connectors/TestConnector":2,"../lib/index":13,"./TestSuite":85,"chai":14,"coffee-errors":46,"jquery":67,"sinon":69,"sinon-chai":68,"underscore":84}]},{},[86])
|
||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbGliL0Nvbm5lY3RvcnMvSXdjQ29ubmVjdG9yLmNvZmZlZSIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9saWIvQ29ubmVjdG9ycy9UZXN0Q29ubmVjdG9yLmNvZmZlZSIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9saWIvRW5naW5lLmNvZmZlZSIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9saWIvRnJhbWV3b3Jrcy9Kc29uRnJhbWV3b3JrLmNvZmZlZSIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9saWIvRnJhbWV3b3Jrcy9UZXh0RnJhbWV3b3JrLmNvZmZlZSIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9saWIvRnJhbWV3b3Jrcy9YbWxGcmFtZXdvcmsuY29mZmVlIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL2xpYi9IaXN0b3J5QnVmZmVyLmNvZmZlZSIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9saWIvVHlwZXMvQmFzaWNUeXBlcy5jb2ZmZWUiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbGliL1R5cGVzL0pzb25UeXBlcy5jb2ZmZWUiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbGliL1R5cGVzL1N0cnVjdHVyZWRUeXBlcy5jb2ZmZWUiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbGliL1R5cGVzL1RleHRUeXBlcy5jb2ZmZWUiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbGliL1R5cGVzL1htbFR5cGVzLmNvZmZlZSIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9saWIvaW5kZXguY29mZmVlIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL2luZGV4LmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL2Fzc2VydGlvbi5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS9jb25maWcuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvY29yZS9hc3NlcnRpb25zLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL2ludGVyZmFjZS9hc3NlcnQuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvaW50ZXJmYWNlL2V4cGVjdC5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS9pbnRlcmZhY2Uvc2hvdWxkLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2FkZENoYWluYWJsZU1ldGhvZC5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9hZGRNZXRob2QuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvYWRkUHJvcGVydHkuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZmxhZy5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9nZXRBY3R1YWwuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0RW51bWVyYWJsZVByb3BlcnRpZXMuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0TWVzc2FnZS5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9nZXROYW1lLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2dldFBhdGhWYWx1ZS5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9nZXRQcm9wZXJ0aWVzLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2luZGV4LmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2luc3BlY3QuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvb2JqRGlzcGxheS5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvb3ZlcndyaXRlTWV0aG9kLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL292ZXJ3cml0ZVByb3BlcnR5LmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL3Rlc3QuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvdHJhbnNmZXJGbGFncy5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy90eXBlLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL25vZGVfbW9kdWxlcy9hc3NlcnRpb24tZXJyb3IvaW5kZXguanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NoYWkvbm9kZV9tb2R1bGVzL2RlZXAtZXFsL2luZGV4LmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL25vZGVfbW9kdWxlcy9kZWVwLWVxbC9saWIvZXFsLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jaGFpL25vZGVfbW9kdWxlcy9kZWVwLWVxbC9ub2RlX21vZHVsZXMvdHlwZS1kZXRlY3QvaW5kZXguanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NoYWkvbm9kZV9tb2R1bGVzL2RlZXAtZXFsL25vZGVfbW9kdWxlcy90eXBlLWRldGVjdC9saWIvdHlwZS5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY29mZmVlLWVycm9ycy9jb2ZmZWUtZXJyb3JzLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9jb2ZmZWUtc2NyaXB0L2xpYi9jb2ZmZWUtc2NyaXB0L2NvZmZlZS1zY3JpcHQuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NvZmZlZS1zY3JpcHQvbGliL2NvZmZlZS1zY3JpcHQvaGVscGVycy5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY29mZmVlLXNjcmlwdC9saWIvY29mZmVlLXNjcmlwdC9sZXhlci5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY29mZmVlLXNjcmlwdC9saWIvY29mZmVlLXNjcmlwdC9ub2Rlcy5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvY29mZmVlLXNjcmlwdC9saWIvY29mZmVlLXNjcmlwdC9wYXJzZXIuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NvZmZlZS1zY3JpcHQvbGliL2NvZmZlZS1zY3JpcHQvcmVnaXN0ZXIuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NvZmZlZS1zY3JpcHQvbGliL2NvZmZlZS1zY3JpcHQvcmV3cml0ZXIuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NvZmZlZS1zY3JpcHQvbGliL2NvZmZlZS1zY3JpcHQvc2NvcGUuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2NvZmZlZS1zY3JpcHQvbGliL2NvZmZlZS1zY3JpcHQvc291cmNlbWFwLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9ndWxwLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbGliL19lbXB0eS5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2d1bHAtYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnVmZmVyL25vZGVfbW9kdWxlcy9iYXNlNjQtanMvbGliL2I2NC5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2d1bHAtYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wYXRoLWJyb3dzZXJpZnkvaW5kZXguanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2d1bHAtYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9ndWxwLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3V0aWwvc3VwcG9ydC9pc0J1ZmZlckJyb3dzZXIuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2d1bHAtYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvdXRpbC91dGlsLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9ndWxwLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3ZtLWJyb3dzZXJpZnkvaW5kZXguanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL2d1bHAtYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvdm0tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvaW5kZXhvZi9pbmRleC5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvanF1ZXJ5L2Rpc3QvanF1ZXJ5LmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9zaW5vbi1jaGFpL2xpYi9zaW5vbi1jaGFpLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9zaW5vbi9saWIvc2lub24uanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL3Npbm9uL2xpYi9zaW5vbi9hc3NlcnQuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL3Npbm9uL2xpYi9zaW5vbi9iZWhhdmlvci5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvc2lub24vbGliL3Npbm9uL2NhbGwuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL3Npbm9uL2xpYi9zaW5vbi9jb2xsZWN0aW9uLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9zaW5vbi9saWIvc2lub24vbWF0Y2guanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL3Npbm9uL2xpYi9zaW5vbi9tb2NrLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9zaW5vbi9saWIvc2lub24vc2FuZGJveC5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvc2lub24vbGliL3Npbm9uL3NweS5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvc2lub24vbGliL3Npbm9uL3N0dWIuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbm9kZV9tb2R1bGVzL3Npbm9uL2xpYi9zaW5vbi90ZXN0LmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9zaW5vbi9saWIvc2lub24vdGVzdF9jYXNlLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL25vZGVfbW9kdWxlcy9zaW5vbi9saWIvc2lub24vdXRpbC9mYWtlX3RpbWVycy5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvc2lub24vbm9kZV9tb2R1bGVzL2Zvcm1hdGlvL2xpYi9mb3JtYXRpby5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvc2lub24vbm9kZV9tb2R1bGVzL2Zvcm1hdGlvL25vZGVfbW9kdWxlcy9zYW1zYW0vbGliL3NhbXNhbS5qcyIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvdW5kZXJzY29yZS91bmRlcnNjb3JlLmpzIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL3Rlc3QvVGVzdFN1aXRlLmNvZmZlZSIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS90ZXN0L1htbFlhdHRhX3Rlc3RfYnJvd3Nlci5jb2ZmZWUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNLQSxJQUFBLGtCQUFBOztBQUFBLGtCQUFBLEdBQXFCLFNBQUMsUUFBRCxFQUFXLE9BQVgsR0FBQTtBQUNuQixNQUFBLHNFQUFBO0FBQUEsRUFBQSxjQUFBLEdBQWlCLElBQWpCLENBQUE7QUFDQSxFQUFBLElBQUcsZUFBSDtBQUNFLElBQWEsaUJBQWtCLFFBQTlCLFVBQUQsQ0FERjtHQURBO0FBQUEsRUFJQSxVQUFBLEdBQWEsRUFKYixDQUFBO0FBQUEsRUFLQSxTQUFBLEdBQWdCLElBQUEsU0FBQSxDQUFBLENBTGhCLENBQUE7QUFBQSxFQU9BLFNBQVMsQ0FBQyxPQUFWLENBQWtCLFNBQUMsTUFBRCxHQUFBO0FBQ2hCLFFBQUEsSUFBQTs7VUFBeUIsQ0FBRSxHQUEzQixDQUErQixTQUFDLENBQUQsR0FBQTtlQUM3QixVQUFBLENBQVcsU0FBQSxHQUFBO2lCQUNULENBQUEsQ0FBRSxNQUFGLEVBRFM7UUFBQSxDQUFYLEVBRUUsQ0FGRixFQUQ2QjtNQUFBLENBQS9CO0tBQUE7QUFJQSxJQUFBLElBQUcsc0JBQUg7YUFDRSxjQUFBLENBQWUsTUFBZixFQURGO0tBTGdCO0VBQUEsQ0FBbEIsQ0FQQSxDQUFBO0FBQUEsRUFlQSxTQUFTLENBQUMsTUFBVixDQUFBLENBZkEsQ0FBQTtBQUFBLEVBaUJBLFdBQUEsR0FBYyxJQWpCZCxDQUFBO0FBQUEsRUEyQk07QUFRUyxJQUFBLHNCQUFFLE1BQUYsRUFBVyxFQUFYLEVBQWdCLGtCQUFoQixFQUFxQyxLQUFyQyxHQUFBO0FBQ1gsVUFBQSw2Q0FBQTtBQUFBLE1BRFksSUFBQyxDQUFBLFNBQUEsTUFDYixDQUFBO0FBQUEsTUFEcUIsSUFBQyxDQUFBLEtBQUEsRUFDdEIsQ0FBQTtBQUFBLE1BRDBCLElBQUMsQ0FBQSxxQkFBQSxrQkFDM0IsQ0FBQTtBQUFBLE1BRCtDLElBQUMsQ0FBQSxRQUFBLEtBQ2hELENBQUE7QUFBQSxNQUFBLElBQUMsQ0FBQSxTQUFELEdBQWEsU0FBYixDQUFBO0FBQUEsTUFDQSxJQUFDLENBQUEsVUFBRCxHQUFjLFVBRGQsQ0FBQTtBQUFBLE1BR0EsS0FBQSxHQUFRLENBQUEsU0FBQSxLQUFBLEdBQUE7ZUFBQSxTQUFDLENBQUQsR0FBQTtBQUNOLFVBQUEsSUFBRyxNQUFNLENBQUMsbUJBQVAsQ0FBMkIsS0FBQyxDQUFBLFdBQTVCLENBQXdDLENBQUMsTUFBekMsS0FBcUQsQ0FBeEQ7bUJBQ0UsS0FBQyxDQUFBLElBQUQsQ0FBTSxDQUFOLEVBREY7V0FETTtRQUFBLEVBQUE7TUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBSFIsQ0FBQTtBQUFBLE1BTUEsSUFBQyxDQUFBLGtCQUFrQixDQUFDLElBQXBCLENBQXlCLEtBQXpCLENBTkEsQ0FBQTtBQUFBLE1BUUEsSUFBQyxDQUFBLFdBQUQsR0FBZSxFQVJmLENBQUE7QUFBQSxNQVNBLFNBQUEsR0FBWSxDQUFBLFNBQUEsS0FBQSxHQUFBO2VBQUEsU0FBQyxJQUFELEdBQUE7QUFDVixjQUFBLEdBQUE7QUFBQSxVQUFBLEVBQUEsR0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQWpCLENBQUE7QUFBQSxVQUNBLEdBQUEsR0FBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBRGxCLENBQUE7QUFBQSxVQUVBLEtBQUksQ0FBQyxNQUFNLENBQUMsbUJBQVosQ0FBZ0MsRUFBaEMsQ0FGQSxDQUFBO2lCQUdBLEtBQUMsQ0FBQSxXQUFZLENBQUEsR0FBQSxDQUFiLEdBQW9CLEtBSlY7UUFBQSxFQUFBO01BQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQVRaLENBQUE7QUFBQSxNQWNBLFVBQVcsQ0FBQSx1QkFBQSxDQUFYLEdBQXNDLENBQUMsU0FBRCxDQWR0QyxDQUFBO0FBQUEsTUFnQkEsSUFBQyxDQUFBLGFBQUQsQ0FBZSxzQkFBZixFQUF1QyxJQUFDLENBQUEsRUFBRSxDQUFDLG1CQUFKLENBQUEsQ0FBdkMsQ0FoQkEsQ0FBQTtBQUFBLE1Ba0JBLFFBQUEsR0FBVyxDQUFBLFNBQUEsS0FBQSxHQUFBO2VBQUEsU0FBQyxNQUFELEdBQUE7QUFDVCxjQUFBLENBQUE7QUFBQSxVQUFBLENBQUEsR0FBSSxNQUFNLENBQUMsTUFBWCxDQUFBO0FBQ0EsVUFBQSxJQUFHLHdDQUFIO21CQUNFLEtBQUMsQ0FBQSxPQUFELENBQVMsQ0FBVCxFQURGO1dBRlM7UUFBQSxFQUFBO01BQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQWxCWCxDQUFBO0FBQUEsTUF1QkEsSUFBQyxDQUFBLFVBQVcsQ0FBQSxxQkFBQSxDQUFaLEdBQXFDLENBQUMsUUFBRCxDQXZCckMsQ0FBQTtBQXlCQSxNQUFBLElBQUcsbUJBQUg7QUFDRSxRQUFBLElBQUMsQ0FBQSxNQUFNLENBQUMsbUJBQVIsQ0FBNEIsV0FBNUIsQ0FBQSxDQURGO09BekJBO0FBQUEsTUE0QkEsaUJBQUEsR0FBb0IsQ0FBQSxTQUFBLEtBQUEsR0FBQTtlQUFBLFNBQUMsTUFBRCxHQUFBO0FBQ2xCLGNBQUEsa0JBQUE7QUFBQSxVQUFBLFlBQUEsR0FBZSxNQUFNLENBQUMsTUFBdEIsQ0FBQTtBQUFBLFVBQ0EsT0FBTyxDQUFDLEdBQVIsQ0FBWSxZQUFaLENBREEsQ0FBQTtBQUFBLFVBRUEsSUFBQSxHQUNFO0FBQUEsWUFBQSxFQUFBLEVBQUssS0FBQyxDQUFBLEtBQUssQ0FBQyxnQkFBUCxDQUFBLENBQXlCLENBQUMsT0FBMUIsQ0FBa0MsWUFBbEMsQ0FBTDtBQUFBLFlBQ0EsSUFBQSxFQUFPLEtBQUMsQ0FBQSxLQUFLLENBQUMsU0FBUCxDQUFBLENBRFA7V0FIRixDQUFBO2lCQUtBLEtBQUMsQ0FBQSxhQUFELENBQWUsdUJBQWYsRUFBd0MsSUFBeEMsRUFOa0I7UUFBQSxFQUFBO01BQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQTVCcEIsQ0FBQTtBQUFBLE1BbUNBLElBQUMsQ0FBQSxVQUFXLENBQUEsc0JBQUEsQ0FBWixHQUFzQyxDQUFDLGlCQUFELENBbkN0QyxDQURXO0lBQUEsQ0FBYjs7QUFBQSwyQkEwQ0EsYUFBQSxHQUFlLFNBQUMsQ0FBRCxHQUFBO2FBQ2IsY0FBQSxHQUFpQixFQURKO0lBQUEsQ0ExQ2YsQ0FBQTs7QUFBQSwyQkFxREEsYUFBQSxHQUFlLFNBQUMsV0FBRCxFQUFjLE9BQWQsR0FBQTtBQUNiLFVBQUEsTUFBQTtBQUFBLE1BQUEsTUFBQSxHQUFTLElBQVQsQ0FBQTtBQUNBLE1BQUEsSUFBRyxTQUFTLENBQUMsTUFBVixJQUFvQixDQUF2QjtBQUNFLFFBQUMsMEJBQUQsRUFBYyxzQkFBZCxDQUFBO0FBQUEsUUFDQSxNQUFBLEdBQ0U7QUFBQSxVQUFBLE1BQUEsRUFBUSxXQUFSO0FBQUEsVUFDQSxTQUFBLEVBQVcsRUFEWDtBQUFBLFVBRUEsSUFBQSxFQUFNLEVBRk47QUFBQSxVQUdBLFFBQUEsRUFBVSxFQUhWO0FBQUEsVUFJQSxLQUFBLEVBQU8sQ0FBQyxnQkFBRCxDQUpQO0FBQUEsVUFLQSxNQUFBLEVBQVEsT0FMUjtTQUZGLENBREY7T0FBQSxNQUFBO0FBVUUsUUFBQSxNQUFBLEdBQVMsU0FBVSxDQUFBLENBQUEsQ0FBbkIsQ0FWRjtPQURBO2FBYUEsSUFBQyxDQUFBLFNBQVMsQ0FBQyxVQUFYLENBQXNCLE1BQXRCLEVBZGE7SUFBQSxDQXJEZixDQUFBOztBQUFBLDJCQTBFQSxJQUFBLEdBQU0sU0FBQyxDQUFELEdBQUE7QUFDSixNQUFBLElBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFOLEtBQWlCLElBQUMsQ0FBQSxFQUFFLENBQUMsU0FBSixDQUFBLENBQWpCLElBQXFDLENBQUMsTUFBQSxDQUFBLENBQVEsQ0FBQyxHQUFHLENBQUMsU0FBYixLQUE0QixRQUE3QixDQUF4QztlQUNFLElBQUMsQ0FBQSxhQUFELENBQWUscUJBQWYsRUFBc0MsQ0FBdEMsRUFERjtPQURJO0lBQUEsQ0ExRU4sQ0FBQTs7QUFBQSwyQkFtRkEsT0FBQSxHQUFTLFNBQUMsQ0FBRCxHQUFBO0FBQ1AsTUFBQSxJQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTixLQUFtQixJQUFDLENBQUEsRUFBRSxDQUFDLFNBQUosQ0FBQSxDQUF0QjtlQUNFLElBQUMsQ0FBQSxNQUFNLENBQUMsT0FBUixDQUFnQixDQUFoQixFQURGO09BRE87SUFBQSxDQW5GVCxDQUFBOzt3QkFBQTs7TUFuQ0YsQ0FBQTtBQUFBLEVBMkhBLElBQUEsR0FBTyxTQUFBLEdBQUE7QUFFTCxRQUFBLGdCQUFBO0FBQUEsSUFBQSxnQkFBQSxHQUFtQixJQUFJLENBQUMsS0FBTCxDQUFXLElBQUksQ0FBQyxNQUFMLENBQUEsQ0FBQSxHQUFjLE9BQXpCLENBQW5CLENBQUE7V0FDQSxRQUFBLENBQVMsWUFBVCxFQUF1QixnQkFBdkIsRUFISztFQUFBLENBM0hQLENBQUE7QUFBQSxFQWdJQSxVQUFBLENBQVcsSUFBWCxFQUFpQixJQUFqQixDQWhJQSxDQUFBO1NBa0lBLE9BbkltQjtBQUFBLENBQXJCLENBQUE7O0FBQUEsTUFzSU0sQ0FBQyxPQUFQLEdBQWlCLGtCQXRJakIsQ0FBQTs7QUF1SUEsSUFBRyxnREFBSDtBQUNFLEVBQUEsSUFBTyxnQkFBUDtBQUNFLElBQUEsTUFBTSxDQUFDLENBQVAsR0FBVyxFQUFYLENBREY7R0FBQTtBQUFBLEVBRUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxrQkFBVCxHQUE4QixrQkFGOUIsQ0FERjtDQXZJQTs7OztBQ0pBLElBQUEsQ0FBQTs7QUFBQSxDQUFBLEdBQUksT0FBQSxDQUFRLFlBQVIsQ0FBSixDQUFBOztBQUFBLE1BRU0sQ0FBQyxPQUFQLEdBQWlCLFNBQUMsU0FBRCxHQUFBO0FBTWYsTUFBQSxhQUFBO1NBQU07QUFRUyxJQUFBLHVCQUFFLE1BQUYsRUFBVyxFQUFYLEVBQWdCLGtCQUFoQixHQUFBO0FBQ1gsVUFBQSxnQ0FBQTtBQUFBLE1BRFksSUFBQyxDQUFBLFNBQUEsTUFDYixDQUFBO0FBQUEsTUFEcUIsSUFBQyxDQUFBLEtBQUEsRUFDdEIsQ0FBQTtBQUFBLE1BRDBCLElBQUMsQ0FBQSxxQkFBQSxrQkFDM0IsQ0FBQTtBQUFBLE1BQUEsS0FBQSxHQUFRLENBQUEsU0FBQSxLQUFBLEdBQUE7ZUFBQSxTQUFDLENBQUQsR0FBQTtpQkFDTixLQUFDLENBQUEsSUFBRCxDQUFNLENBQU4sRUFETTtRQUFBLEVBQUE7TUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBQVIsQ0FBQTtBQUFBLE1BRUEsSUFBQyxDQUFBLGtCQUFrQixDQUFDLElBQXBCLENBQXlCLEtBQXpCLENBRkEsQ0FBQTtBQUFBLE1BSUEsSUFBQyxDQUFBLGtCQUFELEdBQXNCLEVBSnRCLENBQUE7QUFBQSxNQUtBLHlCQUFBLEdBQTRCLENBQUEsU0FBQSxLQUFBLEdBQUE7ZUFBQSxTQUFDLENBQUQsR0FBQTtpQkFDMUIsS0FBQyxDQUFBLGtCQUFrQixDQUFDLElBQXBCLENBQXlCLENBQXpCLEVBRDBCO1FBQUEsRUFBQTtNQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FMNUIsQ0FBQTtBQUFBLE1BT0EsSUFBQyxDQUFBLGtCQUFrQixDQUFDLElBQXBCLENBQXlCLHlCQUF6QixDQVBBLENBQUE7QUFRQSxNQUFBLElBQUcsQ0FBQSxzQkFBSyxTQUFTLENBQUUsZ0JBQVgsS0FBcUIsQ0FBdEIsQ0FBUDtBQUNFLFFBQUEsSUFBQyxDQUFBLE1BQU0sQ0FBQyxRQUFSLENBQWlCLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxnQkFBYixDQUFBLENBQStCLENBQUMsT0FBaEMsQ0FBQSxDQUFqQixDQUFBLENBREY7T0FSQTtBQUFBLE1BV0EsSUFBQyxDQUFBLEVBQUUsQ0FBQyx1QkFBSixDQUFBLENBWEEsQ0FBQTtBQUFBLE1BWUEsSUFBQyxDQUFBLFVBQUQsR0FBYyxFQVpkLENBRFc7SUFBQSxDQUFiOztBQUFBLDRCQW1CQSxzQkFBQSxHQUF3QixTQUFBLEdBQUE7YUFDdEIsSUFBQyxDQUFBLG1CQURxQjtJQUFBLENBbkJ4QixDQUFBOztBQUFBLDRCQTBCQSxJQUFBLEdBQU0sU0FBQyxDQUFELEdBQUE7QUFDSixVQUFBLHdCQUFBO0FBQUEsTUFBQSxJQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFOLEtBQWlCLElBQUMsQ0FBQSxFQUFFLENBQUMsU0FBSixDQUFBLENBQWxCLENBQUEsSUFBdUMsQ0FBQyxNQUFBLENBQUEsQ0FBUSxDQUFDLEdBQUcsQ0FBQyxTQUFiLEtBQTRCLFFBQTdCLENBQTFDO0FBQ0U7YUFBQSxnREFBQTsrQkFBQTtBQUNFLFVBQUEsSUFBRyxJQUFJLENBQUMsU0FBTCxDQUFBLENBQUEsS0FBc0IsSUFBQyxDQUFBLEVBQUUsQ0FBQyxTQUFKLENBQUEsQ0FBekI7MEJBQ0UsSUFBSSxDQUFDLFlBQUwsQ0FBQSxDQUFtQixDQUFDLE9BQXBCLENBQTRCLENBQTVCLEdBREY7V0FBQSxNQUFBO2tDQUFBO1dBREY7QUFBQTt3QkFERjtPQURJO0lBQUEsQ0ExQk4sQ0FBQTs7QUFBQSw0QkFvQ0EsT0FBQSxHQUFTLFNBQUMsQ0FBRCxHQUFBO0FBQ1AsVUFBQSxZQUFBOzt1QkFBOEI7T0FBOUI7YUFDQSxJQUFDLENBQUEsVUFBVyxDQUFBLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTixDQUFjLENBQUMsSUFBM0IsQ0FBZ0MsQ0FBaEMsRUFGTztJQUFBLENBcENULENBQUE7O0FBQUEsNEJBMkNBLFFBQUEsR0FBVSxTQUFDLElBQUQsR0FBQTtBQUNSLFVBQUEsSUFBQTtBQUFBLE1BQUEsa0RBQW9CLENBQUUsZ0JBQW5CLEdBQTRCLENBQS9CO2VBQ0UsSUFBQyxDQUFBLE1BQU0sQ0FBQyxPQUFSLENBQWdCLElBQUMsQ0FBQSxVQUFXLENBQUEsSUFBQSxDQUFLLENBQUMsS0FBbEIsQ0FBQSxDQUFoQixFQURGO09BRFE7SUFBQSxDQTNDVixDQUFBOztBQUFBLDRCQWtEQSxjQUFBLEdBQWdCLFNBQUEsR0FBQTthQUNkLElBQUMsQ0FBQSxRQUFELENBQVcsQ0FBQyxDQUFDLE1BQUYsQ0FBUyxDQUFULEVBQWEsU0FBUyxDQUFDLE1BQVYsR0FBaUIsQ0FBOUIsQ0FBWCxFQURjO0lBQUEsQ0FsRGhCLENBQUE7O0FBQUEsNEJBd0RBLFFBQUEsR0FBVSxTQUFBLEdBQUE7QUFDUixVQUFBLFlBQUE7QUFBQTtBQUFBLFdBQUEsU0FBQTtzQkFBQTtBQUNFLFFBQUEsSUFBQyxDQUFBLE1BQU0sQ0FBQyxRQUFSLENBQWlCLEdBQWpCLENBQUEsQ0FERjtBQUFBLE9BQUE7YUFFQSxJQUFDLENBQUEsVUFBRCxHQUFjLEdBSE47SUFBQSxDQXhEVixDQUFBOzt5QkFBQTs7T0FkYTtBQUFBLENBRmpCLENBQUE7Ozs7QUNJQSxJQUFBLE1BQUE7O0FBQUE7QUFNZSxFQUFBLGdCQUFFLEVBQUYsRUFBTyxNQUFQLEdBQUE7QUFDWCxJQURZLElBQUMsQ0FBQSxLQUFBLEVBQ2IsQ0FBQTtBQUFBLElBRGlCLElBQUMsQ0FBQSxTQUFBLE1BQ2xCLENBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxlQUFELEdBQW1CLEVBQW5CLENBRFc7RUFBQSxDQUFiOztBQUFBLG1CQU1BLGNBQUEsR0FBZ0IsU0FBQyxJQUFELEdBQUE7QUFDZCxRQUFBLFVBQUE7QUFBQSxJQUFBLFVBQUEsR0FBYSxJQUFDLENBQUEsTUFBTyxDQUFBLElBQUksQ0FBQyxJQUFMLENBQXJCLENBQUE7QUFDQSxJQUFBLElBQUcsa0JBQUg7YUFDRSxVQUFBLENBQVcsSUFBWCxFQURGO0tBQUEsTUFBQTtBQUdFLFlBQVUsSUFBQSxLQUFBLENBQU8sMENBQUEsR0FBeUMsSUFBSSxDQUFDLElBQTlDLEdBQW9ELG1CQUFwRCxHQUFzRSxDQUFBLElBQUksQ0FBQyxTQUFMLENBQWUsSUFBZixDQUFBLENBQXRFLEdBQTJGLEdBQWxHLENBQVYsQ0FIRjtLQUZjO0VBQUEsQ0FOaEIsQ0FBQTs7QUFBQSxtQkFpQkEsY0FBQSxHQUFnQixTQUFDLFFBQUQsR0FBQTtBQUNkLFFBQUEsc0NBQUE7QUFBQSxJQUFBLEdBQUEsR0FBTSxFQUFOLENBQUE7QUFDQSxTQUFBLCtDQUFBO3VCQUFBO0FBQ0UsTUFBQSxHQUFHLENBQUMsSUFBSixDQUFTLElBQUMsQ0FBQSxjQUFELENBQWdCLENBQWhCLENBQVQsQ0FBQSxDQURGO0FBQUEsS0FEQTtBQUdBLFNBQUEsNENBQUE7a0JBQUE7QUFDRSxNQUFBLElBQUMsQ0FBQSxFQUFFLENBQUMsWUFBSixDQUFpQixDQUFqQixDQUFBLENBREY7QUFBQSxLQUhBO0FBS0EsU0FBQSw0Q0FBQTtrQkFBQTtBQUNFLE1BQUEsSUFBRyxDQUFBLENBQUssQ0FBQyxPQUFGLENBQUEsQ0FBUDtBQUNFLFFBQUEsSUFBQyxDQUFBLGVBQWUsQ0FBQyxJQUFqQixDQUFzQixDQUF0QixDQUFBLENBREY7T0FERjtBQUFBLEtBTEE7V0FRQSxJQUFDLENBQUEsY0FBRCxDQUFBLEVBVGM7RUFBQSxDQWpCaEIsQ0FBQTs7QUFBQSxtQkFnQ0EsbUJBQUEsR0FBcUIsU0FBQyxRQUFELEdBQUE7QUFDbkIsUUFBQSxxQkFBQTtBQUFBO1NBQUEsK0NBQUE7dUJBQUE7QUFDRSxNQUFBLElBQU8sbUNBQVA7c0JBQ0UsSUFBQyxDQUFBLE9BQUQsQ0FBUyxDQUFULEdBREY7T0FBQSxNQUFBOzhCQUFBO09BREY7QUFBQTtvQkFEbUI7RUFBQSxDQWhDckIsQ0FBQTs7QUFBQSxtQkF3Q0EsUUFBQSxHQUFVLFNBQUMsUUFBRCxHQUFBO0FBQ1IsUUFBQSxxQkFBQTtBQUFBO1NBQUEsK0NBQUE7dUJBQUE7QUFDRSxvQkFBQSxJQUFDLENBQUEsT0FBRCxDQUFTLENBQVQsRUFBQSxDQURGO0FBQUE7b0JBRFE7RUFBQSxDQXhDVixDQUFBOztBQUFBLG1CQStDQSxPQUFBLEdBQVMsU0FBQyxPQUFELEdBQUE7QUFFUCxRQUFBLENBQUE7QUFBQSxJQUFBLENBQUEsR0FBSSxJQUFDLENBQUEsY0FBRCxDQUFnQixPQUFoQixDQUFKLENBQUE7QUFBQSxJQUNBLElBQUMsQ0FBQSxFQUFFLENBQUMsWUFBSixDQUFpQixDQUFqQixDQURBLENBQUE7QUFHQSxJQUFBLElBQUcsK0JBQUg7QUFBQTtLQUFBLE1BQ0ssSUFBRyxDQUFBLENBQUssQ0FBQyxPQUFGLENBQUEsQ0FBUDtBQUNILE1BQUEsSUFBQyxDQUFBLGVBQWUsQ0FBQyxJQUFqQixDQUFzQixDQUF0QixDQUFBLENBREc7S0FBQSxNQUFBO0FBR0gsTUFBQSxJQUFDLENBQUEsRUFBRSxDQUFDLFlBQUosQ0FBaUIsQ0FBakIsQ0FBQSxDQUhHO0tBSkw7V0FRQSxJQUFDLENBQUEsY0FBRCxDQUFBLEVBVk87RUFBQSxDQS9DVCxDQUFBOztBQUFBLG1CQStEQSxjQUFBLEdBQWdCLFNBQUEsR0FBQTtBQUNkLFFBQUEscURBQUE7QUFBQTtXQUFNLElBQU4sR0FBQTtBQUNFLE1BQUEsVUFBQSxHQUFhLElBQUMsQ0FBQSxlQUFlLENBQUMsTUFBOUIsQ0FBQTtBQUFBLE1BQ0EsV0FBQSxHQUFjLEVBRGQsQ0FBQTtBQUVBO0FBQUEsV0FBQSwyQ0FBQTtzQkFBQTtBQUNFLFFBQUEsSUFBRyxnQ0FBSDtBQUFBO1NBQUEsTUFDSyxJQUFHLENBQUEsRUFBTSxDQUFDLE9BQUgsQ0FBQSxDQUFQO0FBQ0gsVUFBQSxXQUFXLENBQUMsSUFBWixDQUFpQixFQUFqQixDQUFBLENBREc7U0FBQSxNQUFBO0FBR0gsVUFBQSxJQUFDLENBQUEsRUFBRSxDQUFDLFlBQUosQ0FBaUIsRUFBakIsQ0FBQSxDQUhHO1NBRlA7QUFBQSxPQUZBO0FBQUEsTUFRQSxJQUFDLENBQUEsZUFBRCxHQUFtQixXQVJuQixDQUFBO0FBU0EsTUFBQSxJQUFHLElBQUMsQ0FBQSxlQUFlLENBQUMsTUFBakIsS0FBMkIsVUFBOUI7QUFDRSxjQURGO09BQUEsTUFBQTs4QkFBQTtPQVZGO0lBQUEsQ0FBQTtvQkFEYztFQUFBLENBL0RoQixDQUFBOztnQkFBQTs7SUFORixDQUFBOztBQUFBLE1Bc0ZNLENBQUMsT0FBUCxHQUFpQixNQXRGakIsQ0FBQTs7OztBQ0pBLElBQUEsOERBQUE7O0FBQUEsd0JBQUEsR0FBMkIsT0FBQSxDQUFRLG9CQUFSLENBQTNCLENBQUE7O0FBQUEsYUFDQSxHQUFnQixPQUFBLENBQVEsa0JBQVIsQ0FEaEIsQ0FBQTs7QUFBQSxNQUVBLEdBQVMsT0FBQSxDQUFRLFdBQVIsQ0FGVCxDQUFBOztBQUFBO0FBaUJlLEVBQUEsdUJBQUMsT0FBRCxFQUFVLFNBQVYsR0FBQTtBQUNYLFFBQUEsb0RBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxFQUFELEdBQVUsSUFBQSxhQUFBLENBQWMsT0FBZCxDQUFWLENBQUE7QUFBQSxJQUNBLFlBQUEsR0FBZSx3QkFBQSxDQUF5QixJQUFDLENBQUEsRUFBMUIsQ0FEZixDQUFBO0FBQUEsSUFFQSxJQUFDLENBQUEsS0FBRCxHQUFTLFlBQVksQ0FBQyxLQUZ0QixDQUFBO0FBQUEsSUFHQSxJQUFDLENBQUEsTUFBRCxHQUFjLElBQUEsTUFBQSxDQUFPLElBQUMsQ0FBQSxFQUFSLEVBQVksWUFBWSxDQUFDLE1BQXpCLENBSGQsQ0FBQTtBQUFBLElBSUEsSUFBQyxDQUFBLEVBQUUsQ0FBQyxNQUFKLEdBQWEsSUFBQyxDQUFBLE1BSmQsQ0FBQTtBQUFBLElBS0EsSUFBQyxDQUFBLFNBQUQsR0FBaUIsSUFBQSxTQUFBLENBQVUsSUFBQyxDQUFBLE1BQVgsRUFBbUIsSUFBQyxDQUFBLEVBQXBCLEVBQXdCLFlBQVksQ0FBQyxrQkFBckMsRUFBeUQsSUFBekQsQ0FMakIsQ0FBQTtBQUFBLElBTUEsVUFBQSxHQUFpQixJQUFBLElBQUMsQ0FBQSxLQUFLLENBQUMsUUFBUCxDQUFnQixJQUFDLENBQUEsRUFBRSxDQUFDLDJCQUFKLENBQUEsQ0FBaEIsQ0FOakIsQ0FBQTtBQUFBLElBT0EsSUFBQyxDQUFBLEVBQUUsQ0FBQyxZQUFKLENBQWlCLFVBQWpCLENBQTRCLENBQUMsT0FBN0IsQ0FBQSxDQVBBLENBQUE7QUFBQSxJQVNBLE9BQUEsR0FBVSxJQUFDLENBQUEsRUFBRSxDQUFDLDJCQUFKLENBQUEsQ0FUVixDQUFBO0FBQUEsSUFVQSxPQUFBLEdBQVUsSUFBQyxDQUFBLEVBQUUsQ0FBQywyQkFBSixDQUFBLENBVlYsQ0FBQTtBQUFBLElBV0EsR0FBQSxHQUFNLElBQUMsQ0FBQSxFQUFFLENBQUMsWUFBSixDQUFxQixJQUFBLElBQUMsQ0FBQSxLQUFLLENBQUMsU0FBUCxDQUFpQixPQUFqQixFQUEwQixNQUExQixFQUFxQyxPQUFyQyxDQUFyQixDQUFrRSxDQUFDLE9BQW5FLENBQUEsQ0FYTixDQUFBO0FBQUEsSUFZQSxHQUFBLEdBQU0sSUFBQyxDQUFBLEVBQUUsQ0FBQyxZQUFKLENBQXFCLElBQUEsSUFBQyxDQUFBLEtBQUssQ0FBQyxTQUFQLENBQWlCLE9BQWpCLEVBQTBCLEdBQTFCLEVBQStCLE1BQS9CLENBQXJCLENBQThELENBQUMsT0FBL0QsQ0FBQSxDQVpOLENBQUE7QUFBQSxJQWNBLElBQUMsQ0FBQSxZQUFELEdBQW9CLElBQUEsSUFBQyxDQUFBLEtBQUssQ0FBQyxjQUFQLENBQXNCLE1BQXRCLEVBQWlDLElBQUMsQ0FBQSxFQUFFLENBQUMsMkJBQUosQ0FBQSxDQUFqQyxFQUFvRSxHQUFwRSxFQUF5RSxHQUF6RSxDQWRwQixDQUFBO0FBQUEsSUFlQSxJQUFDLENBQUEsRUFBRSxDQUFDLFlBQUosQ0FBaUIsSUFBQyxDQUFBLFlBQWxCLENBQStCLENBQUMsT0FBaEMsQ0FBQSxDQWZBLENBQUE7QUFBQSxJQWdCQSxJQUFDLENBQUEsWUFBWSxDQUFDLE9BQWQsQ0FBc0IsVUFBdEIsRUFBa0MsSUFBQyxDQUFBLEVBQUUsQ0FBQywyQkFBSixDQUFBLENBQWxDLENBaEJBLENBRFc7RUFBQSxDQUFiOztBQUFBLDBCQXNCQSxlQUFBLEdBQWlCLFNBQUEsR0FBQTtXQUNmLElBQUMsQ0FBQSxZQUFZLENBQUMsR0FBZCxDQUFBLEVBRGU7RUFBQSxDQXRCakIsQ0FBQTs7QUFBQSwwQkE0QkEsWUFBQSxHQUFjLFNBQUEsR0FBQTtXQUNaLElBQUMsQ0FBQSxVQURXO0VBQUEsQ0E1QmQsQ0FBQTs7QUFBQSwwQkFrQ0EsZ0JBQUEsR0FBa0IsU0FBQSxHQUFBO1dBQ2hCLElBQUMsQ0FBQSxHQURlO0VBQUEsQ0FsQ2xCLENBQUE7O0FBQUEsMEJBd0NBLGlCQUFBLEdBQW1CLFNBQUMsT0FBRCxHQUFBO1dBQ2pCLElBQUMsQ0FBQSxlQUFELENBQUEsQ0FBa0IsQ0FBQyxpQkFBbkIsQ0FBcUMsT0FBckMsRUFEaUI7RUFBQSxDQXhDbkIsQ0FBQTs7QUFBQSwwQkFnREEsU0FBQSxHQUFXLFNBQUEsR0FBQTtXQUNULElBQUMsQ0FBQSxFQUFFLENBQUMsU0FBSixDQUFBLEVBRFM7RUFBQSxDQWhEWCxDQUFBOztBQUFBLDBCQXNEQSxNQUFBLEdBQVMsU0FBQSxHQUFBO1dBQ1AsSUFBQyxDQUFBLGVBQUQsQ0FBQSxDQUFrQixDQUFDLE1BQW5CLENBQUEsRUFETztFQUFBLENBdERULENBQUE7O0FBQUEsMEJBNERBLEdBQUEsR0FBTSxTQUFDLElBQUQsRUFBTyxPQUFQLEVBQWdCLE9BQWhCLEdBQUE7V0FDSixJQUFDLENBQUEsZUFBRCxDQUFBLENBQWtCLENBQUMsR0FBbkIsQ0FBdUIsSUFBdkIsRUFBNkIsT0FBN0IsRUFBc0MsT0FBdEMsRUFESTtFQUFBLENBNUROLENBQUE7O0FBQUEsMEJBa0VBLEVBQUEsR0FBSSxTQUFBLEdBQUE7QUFDRixRQUFBLElBQUE7V0FBQSxRQUFBLElBQUMsQ0FBQSxlQUFELENBQUEsQ0FBQSxDQUFrQixDQUFDLEVBQW5CLGFBQXNCLFNBQXRCLEVBREU7RUFBQSxDQWxFSixDQUFBOztBQUFBLDBCQXdFQSxjQUFBLEdBQWdCLFNBQUEsR0FBQTtBQUNkLFFBQUEsSUFBQTtXQUFBLFFBQUEsSUFBQyxDQUFBLGVBQUQsQ0FBQSxDQUFBLENBQWtCLENBQUMsY0FBbkIsYUFBa0MsU0FBbEMsRUFEYztFQUFBLENBeEVoQixDQUFBOztBQUFBLEVBOEVBLE1BQU0sQ0FBQyxjQUFQLENBQXNCLGFBQWEsQ0FBQyxTQUFwQyxFQUErQyxPQUEvQyxFQUNFO0FBQUEsSUFBQSxHQUFBLEVBQU0sU0FBQSxHQUFBO2FBQUcsSUFBQyxDQUFBLGVBQUQsQ0FBQSxDQUFrQixDQUFDLE1BQXRCO0lBQUEsQ0FBTjtBQUFBLElBQ0EsR0FBQSxFQUFNLFNBQUMsQ0FBRCxHQUFBO0FBQ0osVUFBQSx1QkFBQTtBQUFBLE1BQUEsSUFBRyxDQUFDLENBQUMsV0FBRixLQUFpQixFQUFFLENBQUMsV0FBdkI7QUFDRTthQUFBLFdBQUE7NEJBQUE7QUFDRSx3QkFBQSxJQUFDLENBQUEsR0FBRCxDQUFLLE1BQUwsRUFBYSxLQUFiLEVBQW9CLFdBQXBCLEVBQUEsQ0FERjtBQUFBO3dCQURGO09BQUEsTUFBQTtBQUlFLGNBQVUsSUFBQSxLQUFBLENBQU0sa0NBQU4sQ0FBVixDQUpGO09BREk7SUFBQSxDQUROO0dBREYsQ0E5RUEsQ0FBQTs7dUJBQUE7O0lBakJGLENBQUE7O0FBQUEsTUF3R00sQ0FBQyxPQUFQLEdBQWlCLGFBeEdqQixDQUFBOztBQXlHQSxJQUFHLGdEQUFIO0FBQ0UsRUFBQSxJQUFPLGdCQUFQO0FBQ0UsSUFBQSxNQUFNLENBQUMsQ0FBUCxHQUFXLEVBQVgsQ0FERjtHQUFBO0FBQUEsRUFFQSxNQUFNLENBQUMsQ0FBQyxDQUFDLGFBQVQsR0FBeUIsYUFGekIsQ0FERjtDQXpHQTs7OztBQ0FBLElBQUEsOERBQUE7O0FBQUEsd0JBQUEsR0FBMkIsT0FBQSxDQUFRLG9CQUFSLENBQTNCLENBQUE7O0FBQUEsYUFDQSxHQUFnQixPQUFBLENBQVEsa0JBQVIsQ0FEaEIsQ0FBQTs7QUFBQSxNQUVBLEdBQVMsT0FBQSxDQUFRLFdBQVIsQ0FGVCxDQUFBOztBQUFBO0FBYWUsRUFBQSx1QkFBQyxPQUFELEVBQVUsU0FBVixHQUFBO0FBQ1gsUUFBQSxvRUFBQTtBQUFBLElBQUEsSUFBQyxDQUFBLEVBQUQsR0FBVSxJQUFBLGFBQUEsQ0FBYyxPQUFkLENBQVYsQ0FBQTtBQUFBLElBQ0EsVUFBQSxHQUFhLHdCQUFBLENBQXlCLElBQUMsQ0FBQSxFQUExQixDQURiLENBQUE7QUFBQSxJQUVBLElBQUMsQ0FBQSxLQUFELEdBQVMsVUFBVSxDQUFDLEtBRnBCLENBQUE7QUFBQSxJQUdBLElBQUMsQ0FBQSxNQUFELEdBQWMsSUFBQSxNQUFBLENBQU8sSUFBQyxDQUFBLEVBQVIsRUFBWSxVQUFVLENBQUMsTUFBdkIsQ0FIZCxDQUFBO0FBQUEsSUFJQSxJQUFDLENBQUEsU0FBRCxHQUFpQixJQUFBLFNBQUEsQ0FBVSxJQUFDLENBQUEsTUFBWCxFQUFtQixJQUFDLENBQUEsRUFBcEIsRUFBd0IsVUFBVSxDQUFDLGtCQUFuQyxFQUF1RCxJQUF2RCxDQUpqQixDQUFBO0FBQUEsSUFNQSxTQUFBLEdBQVksSUFBQyxDQUFBLEVBQUUsQ0FBQyxZQUFKLENBQXFCLElBQUEsSUFBQyxDQUFBLEtBQUssQ0FBQyxTQUFQLENBQWlCO0FBQUEsTUFBQyxPQUFBLEVBQVMsR0FBVjtBQUFBLE1BQWUsU0FBQSxFQUFXLFlBQTFCO0tBQWpCLEVBQTJELE1BQTNELEVBQXNFLE1BQXRFLENBQXJCLENBTlosQ0FBQTtBQUFBLElBT0EsR0FBQSxHQUFZLElBQUMsQ0FBQSxFQUFFLENBQUMsWUFBSixDQUFxQixJQUFBLElBQUMsQ0FBQSxLQUFLLENBQUMsU0FBUCxDQUFpQjtBQUFBLE1BQUMsT0FBQSxFQUFTLEdBQVY7QUFBQSxNQUFlLFNBQUEsRUFBVyxNQUExQjtLQUFqQixFQUEyRCxTQUEzRCxFQUFzRSxNQUF0RSxDQUFyQixDQVBaLENBQUE7QUFBQSxJQVFBLFNBQVMsQ0FBQyxPQUFWLEdBQW9CLEdBUnBCLENBQUE7QUFBQSxJQVNBLFNBQVMsQ0FBQyxPQUFWLENBQUEsQ0FUQSxDQUFBO0FBQUEsSUFVQSxHQUFHLENBQUMsT0FBSixDQUFBLENBVkEsQ0FBQTtBQUFBLElBV0EsVUFBQSxHQUFpQixJQUFBLElBQUMsQ0FBQSxLQUFLLENBQUMsUUFBUCxDQUFnQjtBQUFBLE1BQUMsT0FBQSxFQUFTLEdBQVY7QUFBQSxNQUFlLFNBQUEsRUFBVyxHQUExQjtLQUFoQixFQUFnRCxTQUFoRCxFQUEyRCxHQUEzRCxDQVhqQixDQUFBO0FBQUEsSUFZQSxJQUFDLENBQUEsRUFBRSxDQUFDLFlBQUosQ0FBaUIsVUFBakIsQ0FBNEIsQ0FBQyxPQUE3QixDQUFBLENBWkEsQ0FBQTtBQUFBLElBY0EsS0FBQSxHQUFRO0FBQUEsTUFBRSxPQUFBLEVBQVMsR0FBWDtBQUFBLE1BQWdCLFNBQUEsRUFBVyxJQUEzQjtLQWRSLENBQUE7QUFBQSxJQWVBLE9BQUEsR0FBVTtBQUFBLE1BQUUsT0FBQSxFQUFTLEdBQVg7QUFBQSxNQUFnQixTQUFBLEVBQVcsZUFBM0I7S0FmVixDQUFBO0FBQUEsSUFnQkEsT0FBQSxHQUFVO0FBQUEsTUFBRSxPQUFBLEVBQVMsR0FBWDtBQUFBLE1BQWdCLFNBQUEsRUFBVyxTQUEzQjtLQWhCVixDQUFBO0FBQUEsSUFpQkEsR0FBQSxHQUFNLElBQUMsQ0FBQSxFQUFFLENBQUMsWUFBSixDQUFxQixJQUFBLElBQUMsQ0FBQSxLQUFLLENBQUMsU0FBUCxDQUFpQixPQUFqQixFQUEwQixNQUExQixFQUFxQyxPQUFyQyxDQUFyQixDQUFrRSxDQUFDLE9BQW5FLENBQUEsQ0FqQk4sQ0FBQTtBQUFBLElBa0JBLEdBQUEsR0FBTSxJQUFDLENBQUEsRUFBRSxDQUFDLFlBQUosQ0FBcUIsSUFBQSxJQUFDLENBQUEsS0FBSyxDQUFDLFNBQVAsQ0FBaUIsT0FBakIsRUFBMEIsR0FBMUIsRUFBK0IsTUFBL0IsQ0FBckIsQ0FBOEQsQ0FBQyxPQUEvRCxDQUFBLENBbEJOLENBQUE7QUFBQSxJQW1CQSxJQUFDLENBQUEsWUFBRCxHQUFnQixJQUFDLENBQUEsRUFBRSxDQUFDLFlBQUosQ0FBcUIsSUFBQSxJQUFDLENBQUEsS0FBSyxDQUFDLGNBQVAsQ0FBc0IsTUFBdEIsRUFBaUMsS0FBakMsRUFBd0MsR0FBeEMsRUFBNkMsR0FBN0MsQ0FBckIsQ0FBc0UsQ0FBQyxPQUF2RSxDQUFBLENBbkJoQixDQUFBO0FBQUEsSUFvQkEsSUFBQyxDQUFBLFlBQVksQ0FBQyxPQUFkLENBQXNCLFVBQXRCLEVBQWtDO0FBQUEsTUFBRSxPQUFBLEVBQVMsR0FBWDtBQUFBLE1BQWdCLFNBQUEsRUFBVyxhQUEzQjtLQUFsQyxDQXBCQSxDQURXO0VBQUEsQ0FBYjs7QUFBQSwwQkEyQkEsZUFBQSxHQUFpQixTQUFBLEdBQUE7V0FDZixJQUFDLENBQUEsWUFBWSxDQUFDLEdBQWQsQ0FBQSxFQURlO0VBQUEsQ0EzQmpCLENBQUE7O0FBQUEsMEJBaUNBLFlBQUEsR0FBYyxTQUFBLEdBQUE7V0FDWixJQUFDLENBQUEsVUFEVztFQUFBLENBakNkLENBQUE7O0FBQUEsMEJBdUNBLGdCQUFBLEdBQWtCLFNBQUEsR0FBQTtXQUNoQixJQUFDLENBQUEsR0FEZTtFQUFBLENBdkNsQixDQUFBOztBQUFBLDBCQStDQSxTQUFBLEdBQVcsU0FBQSxHQUFBO1dBQ1QsSUFBQyxDQUFBLEVBQUUsQ0FBQyxTQUFKLENBQUEsRUFEUztFQUFBLENBL0NYLENBQUE7O0FBQUEsMEJBcURBLEdBQUEsR0FBSyxTQUFBLEdBQUE7V0FDSCxJQUFDLENBQUEsZUFBRCxDQUFBLENBQWtCLENBQUMsR0FBbkIsQ0FBQSxFQURHO0VBQUEsQ0FyREwsQ0FBQTs7QUFBQSwwQkEyREEsVUFBQSxHQUFZLFNBQUMsR0FBRCxFQUFNLE9BQU4sR0FBQTtXQUNWLElBQUMsQ0FBQSxlQUFELENBQUEsQ0FBa0IsQ0FBQyxVQUFuQixDQUE4QixHQUE5QixFQUFtQyxPQUFuQyxFQURVO0VBQUEsQ0EzRFosQ0FBQTs7QUFBQSwwQkFpRUEsVUFBQSxHQUFZLFNBQUMsR0FBRCxFQUFNLE1BQU4sR0FBQTtXQUNWLElBQUMsQ0FBQSxlQUFELENBQUEsQ0FBa0IsQ0FBQyxVQUFuQixDQUE4QixHQUE5QixFQUFtQyxNQUFuQyxFQURVO0VBQUEsQ0FqRVosQ0FBQTs7QUFBQSwwQkF1RUEsSUFBQSxHQUFNLFNBQUMsUUFBRCxHQUFBO1dBQ0osSUFBQyxDQUFBLGVBQUQsQ0FBQSxDQUFrQixDQUFDLElBQW5CLENBQXdCLFFBQXhCLEVBREk7RUFBQSxDQXZFTixDQUFBOztBQUFBLDBCQTZFQSxXQUFBLEdBQWEsU0FBQyxJQUFELEdBQUE7V0FDWCxJQUFDLENBQUEsZUFBRCxDQUFBLENBQWtCLENBQUMsV0FBbkIsQ0FBK0IsSUFBL0IsRUFEVztFQUFBLENBN0ViLENBQUE7O0FBQUEsMEJBbUZBLEVBQUEsR0FBSSxTQUFBLEdBQUE7QUFDRixRQUFBLElBQUE7V0FBQSxRQUFBLElBQUMsQ0FBQSxZQUFELENBQWEsQ0FBQyxFQUFkLGFBQWlCLFNBQWpCLEVBREU7RUFBQSxDQW5GSixDQUFBOzt1QkFBQTs7SUFiRixDQUFBOztBQUFBLE1Bb0dNLENBQUMsT0FBUCxHQUFpQixhQXBHakIsQ0FBQTs7QUFxR0EsSUFBRyxnREFBSDtBQUNFLEVBQUEsSUFBTyxnQkFBUDtBQUNFLElBQUEsTUFBTSxDQUFDLENBQVAsR0FBVyxFQUFYLENBREY7R0FBQTtBQUFBLEVBRUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxhQUFULEdBQXlCLGFBRnpCLENBREY7Q0FyR0E7Ozs7QUNBQSxJQUFBLDZEQUFBOztBQUFBLHdCQUFBLEdBQTJCLE9BQUEsQ0FBUSxtQkFBUixDQUEzQixDQUFBOztBQUFBLGFBQ0EsR0FBZ0IsT0FBQSxDQUFRLGtCQUFSLENBRGhCLENBQUE7O0FBQUEsTUFFQSxHQUFTLE9BQUEsQ0FBUSxXQUFSLENBRlQsQ0FBQTs7QUFBQTtBQWNlLEVBQUEsc0JBQUMsT0FBRCxFQUFVLFNBQVYsR0FBQTtBQUNYLFFBQUEsd0NBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxFQUFELEdBQVUsSUFBQSxhQUFBLENBQWMsT0FBZCxDQUFWLENBQUE7QUFBQSxJQUNBLFlBQUEsR0FBZSx3QkFBQSxDQUF5QixJQUFDLENBQUEsRUFBMUIsQ0FEZixDQUFBO0FBQUEsSUFFQSxJQUFDLENBQUEsS0FBRCxHQUFTLFlBQVksQ0FBQyxLQUZ0QixDQUFBO0FBQUEsSUFHQSxJQUFDLENBQUEsTUFBRCxHQUFjLElBQUEsTUFBQSxDQUFPLElBQUMsQ0FBQSxFQUFSLEVBQVksWUFBWSxDQUFDLE1BQXpCLENBSGQsQ0FBQTtBQUFBLElBSUEsSUFBQyxDQUFBLEVBQUUsQ0FBQyxNQUFKLEdBQWEsSUFBQyxDQUFBLE1BSmQsQ0FBQTtBQUFBLElBS0EsSUFBQyxDQUFBLFNBQUQsR0FBaUIsSUFBQSxTQUFBLENBQVUsSUFBQyxDQUFBLE1BQVgsRUFBbUIsSUFBQyxDQUFBLEVBQXBCLEVBQXdCLFlBQVksQ0FBQyxrQkFBckMsRUFBeUQsSUFBekQsQ0FMakIsQ0FBQTtBQUFBLElBU0EsT0FBQSxHQUFVLElBQUMsQ0FBQSxFQUFFLENBQUMsMkJBQUosQ0FBQSxDQVRWLENBQUE7QUFBQSxJQVVBLE9BQUEsR0FBVSxJQUFDLENBQUEsRUFBRSxDQUFDLDJCQUFKLENBQUEsQ0FWVixDQUFBO0FBQUEsSUFXQSxHQUFBLEdBQU0sSUFBQyxDQUFBLEVBQUUsQ0FBQyxZQUFKLENBQXFCLElBQUEsSUFBQyxDQUFBLEtBQUssQ0FBQyxTQUFQLENBQWlCLE9BQWpCLEVBQTBCLE1BQTFCLEVBQXFDLE9BQXJDLENBQXJCLENBQWtFLENBQUMsT0FBbkUsQ0FBQSxDQVhOLENBQUE7QUFBQSxJQVlBLEdBQUEsR0FBTSxJQUFDLENBQUEsRUFBRSxDQUFDLFlBQUosQ0FBcUIsSUFBQSxJQUFDLENBQUEsS0FBSyxDQUFDLFNBQVAsQ0FBaUIsT0FBakIsRUFBMEIsR0FBMUIsRUFBK0IsTUFBL0IsQ0FBckIsQ0FBOEQsQ0FBQyxPQUEvRCxDQUFBLENBWk4sQ0FBQTtBQUFBLElBY0EsSUFBQyxDQUFBLFlBQUQsR0FBb0IsSUFBQSxJQUFDLENBQUEsS0FBSyxDQUFDLGNBQVAsQ0FBc0IsTUFBdEIsRUFBaUMsSUFBQyxDQUFBLEVBQUUsQ0FBQywyQkFBSixDQUFBLENBQWpDLEVBQW9FLEdBQXBFLEVBQXlFLEdBQXpFLENBZHBCLENBQUE7QUFBQSxJQWVBLElBQUMsQ0FBQSxFQUFFLENBQUMsWUFBSixDQUFpQixJQUFDLENBQUEsWUFBbEIsQ0FBK0IsQ0FBQyxPQUFoQyxDQUFBLENBZkEsQ0FEVztFQUFBLENBQWI7O0FBQUEseUJBc0JBLGVBQUEsR0FBaUIsU0FBQSxHQUFBO1dBQ2YsSUFBQyxDQUFBLFlBQVksQ0FBQyxHQUFkLENBQUEsRUFEZTtFQUFBLENBdEJqQixDQUFBOztBQUFBLHlCQTRCQSxZQUFBLEdBQWMsU0FBQSxHQUFBO1dBQ1osSUFBQyxDQUFBLFVBRFc7RUFBQSxDQTVCZCxDQUFBOztBQUFBLHlCQWtDQSxnQkFBQSxHQUFrQixTQUFBLEdBQUE7V0FDaEIsSUFBQyxDQUFBLEdBRGU7RUFBQSxDQWxDbEIsQ0FBQTs7QUFBQSx5QkF3Q0EsaUJBQUEsR0FBbUIsU0FBQyxPQUFELEdBQUE7V0FDakIsSUFBQyxDQUFBLGVBQUQsQ0FBQSxDQUFrQixDQUFDLGlCQUFuQixDQUFxQyxPQUFyQyxFQURpQjtFQUFBLENBeENuQixDQUFBOztBQUFBLHlCQWdEQSxTQUFBLEdBQVcsU0FBQSxHQUFBO1dBQ1QsSUFBQyxDQUFBLEVBQUUsQ0FBQyxTQUFKLENBQUEsRUFEUztFQUFBLENBaERYLENBQUE7O0FBQUEseUJBc0RBLE1BQUEsR0FBUyxTQUFBLEdBQUE7V0FDUCxJQUFDLENBQUEsZUFBRCxDQUFBLENBQWtCLENBQUMsTUFBbkIsQ0FBQSxFQURPO0VBQUEsQ0F0RFQsQ0FBQTs7QUFBQSx5QkE0REEsR0FBQSxHQUFNLFNBQUEsR0FBQTtBQUNKLFFBQUEsTUFBQTtBQUFBLElBQUEsSUFBRyxDQUFDLFNBQVMsQ0FBQyxNQUFWLEtBQW9CLENBQXJCLENBQUEsSUFBMkIsQ0FBQyxNQUFBLENBQUEsU0FBaUIsQ0FBQSxDQUFBLENBQWpCLEtBQXVCLFNBQXhCLENBQTlCO2FBQ0UsSUFBQyxDQUFBLGVBQUQsQ0FBQSxDQUFrQixDQUFDLEdBQW5CLENBQXVCLFNBQVUsQ0FBQSxDQUFBLENBQWpDLEVBREY7S0FBQSxNQUVLLElBQUcsU0FBUyxDQUFDLE1BQVYsS0FBb0IsQ0FBdkI7QUFDSCxNQUFBLE1BQUEsR0FBYSxJQUFBLElBQUMsQ0FBQSxLQUFLLENBQUMsT0FBUCxDQUFlLE1BQWYsRUFBMEIsTUFBMUIsRUFBcUMsTUFBckMsRUFBZ0QsTUFBaEQsRUFBMkQsU0FBVSxDQUFBLENBQUEsQ0FBckUsQ0FBYixDQUFBO0FBQUEsTUFDQSxJQUFDLENBQUEsRUFBRSxDQUFDLFlBQUosQ0FBaUIsTUFBakIsQ0FBd0IsQ0FBQyxPQUF6QixDQUFBLENBREEsQ0FBQTtBQUFBLE1BRUEsSUFBQyxDQUFBLFlBQVksQ0FBQyxPQUFkLENBQXNCLE1BQXRCLENBRkEsQ0FBQTthQUdBLE9BSkc7S0FBQSxNQUFBO0FBTUgsWUFBVSxJQUFBLEtBQUEsQ0FBTSxtQ0FBTixDQUFWLENBTkc7S0FIRDtFQUFBLENBNUROLENBQUE7O0FBQUEseUJBMkVBLEVBQUEsR0FBSSxTQUFBLEdBQUE7QUFDRixRQUFBLElBQUE7V0FBQSxRQUFBLElBQUMsQ0FBQSxlQUFELENBQUEsQ0FBQSxDQUFrQixDQUFDLEVBQW5CLGFBQXNCLFNBQXRCLEVBREU7RUFBQSxDQTNFSixDQUFBOztzQkFBQTs7SUFkRixDQUFBOztBQUFBLE1BOEZNLENBQUMsT0FBUCxHQUFpQixZQTlGakIsQ0FBQTs7QUErRkEsSUFBRyxnREFBSDtBQUNFLEVBQUEsSUFBTyxnQkFBUDtBQUNFLElBQUEsTUFBTSxDQUFDLENBQVAsR0FBVyxFQUFYLENBREY7R0FBQTtBQUFBLEVBRUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxZQUFULEdBQXdCLFlBRnhCLENBREY7Q0EvRkE7Ozs7QUNNQSxJQUFBLGFBQUE7RUFBQSxrRkFBQTs7QUFBQTtBQVFlLEVBQUEsdUJBQUUsT0FBRixHQUFBO0FBQ1gsSUFEWSxJQUFDLENBQUEsVUFBQSxPQUNiLENBQUE7QUFBQSx1REFBQSxDQUFBO0FBQUEsSUFBQSxJQUFDLENBQUEsaUJBQUQsR0FBcUIsRUFBckIsQ0FBQTtBQUFBLElBQ0EsSUFBQyxDQUFBLE1BQUQsR0FBVSxFQURWLENBQUE7QUFBQSxJQUVBLElBQUMsQ0FBQSxnQkFBRCxHQUFvQixFQUZwQixDQUFBO0FBQUEsSUFHQSxJQUFDLENBQUEsT0FBRCxHQUFXLEVBSFgsQ0FBQTtBQUFBLElBSUEsSUFBQyxDQUFBLEtBQUQsR0FBUyxFQUpULENBQUE7QUFBQSxJQUtBLElBQUMsQ0FBQSx3QkFBRCxHQUE0QixJQUw1QixDQUFBO0FBQUEsSUFNQSxJQUFDLENBQUEscUJBQUQsR0FBeUIsSUFOekIsQ0FBQTtBQUFBLElBT0EsSUFBQyxDQUFBLDJCQUFELEdBQStCLENBUC9CLENBQUE7QUFBQSxJQVFBLFVBQUEsQ0FBVyxJQUFDLENBQUEsWUFBWixFQUEwQixJQUFDLENBQUEscUJBQTNCLENBUkEsQ0FEVztFQUFBLENBQWI7O0FBQUEsMEJBV0EsWUFBQSxHQUFjLFNBQUEsR0FBQTtBQUNaLFFBQUEsaUJBQUE7QUFBQTtBQUFBLFNBQUEsMkNBQUE7bUJBQUE7O1FBRUUsQ0FBQyxDQUFDO09BRko7QUFBQSxLQUFBO0FBQUEsSUFJQSxJQUFDLENBQUEsT0FBRCxHQUFXLElBQUMsQ0FBQSxLQUpaLENBQUE7QUFBQSxJQUtBLElBQUMsQ0FBQSxLQUFELEdBQVMsRUFMVCxDQUFBO0FBTUEsSUFBQSxJQUFHLElBQUMsQ0FBQSxxQkFBRCxLQUE0QixDQUFBLENBQS9CO0FBQ0UsTUFBQSxJQUFDLENBQUEsdUJBQUQsR0FBMkIsVUFBQSxDQUFXLElBQUMsQ0FBQSxZQUFaLEVBQTBCLElBQUMsQ0FBQSxxQkFBM0IsQ0FBM0IsQ0FERjtLQU5BO1dBUUEsT0FUWTtFQUFBLENBWGQsQ0FBQTs7QUFBQSwwQkF5QkEsU0FBQSxHQUFXLFNBQUEsR0FBQTtXQUNULElBQUMsQ0FBQSxRQURRO0VBQUEsQ0F6QlgsQ0FBQTs7QUFBQSwwQkE0QkEscUJBQUEsR0FBdUIsU0FBQSxHQUFBO0FBQ3JCLFFBQUEscUJBQUE7QUFBQSxJQUFBLElBQUcsSUFBQyxDQUFBLHdCQUFKO0FBQ0U7V0FBQSxnREFBQTswQkFBQTtBQUNFLFFBQUEsSUFBRyxTQUFIO3dCQUNFLElBQUMsQ0FBQSxPQUFPLENBQUMsSUFBVCxDQUFjLENBQWQsR0FERjtTQUFBLE1BQUE7Z0NBQUE7U0FERjtBQUFBO3NCQURGO0tBRHFCO0VBQUEsQ0E1QnZCLENBQUE7O0FBQUEsMEJBa0NBLHFCQUFBLEdBQXVCLFNBQUEsR0FBQTtBQUNyQixJQUFBLElBQUMsQ0FBQSx3QkFBRCxHQUE0QixLQUE1QixDQUFBO0FBQUEsSUFDQSxJQUFDLENBQUEsdUJBQUQsQ0FBQSxDQURBLENBQUE7QUFBQSxJQUVBLElBQUMsQ0FBQSxPQUFELEdBQVcsRUFGWCxDQUFBO1dBR0EsSUFBQyxDQUFBLEtBQUQsR0FBUyxHQUpZO0VBQUEsQ0FsQ3ZCLENBQUE7O0FBQUEsMEJBd0NBLHVCQUFBLEdBQXlCLFNBQUEsR0FBQTtBQUN2QixJQUFBLElBQUMsQ0FBQSxxQkFBRCxHQUF5QixDQUFBLENBQXpCLENBQUE7QUFBQSxJQUNBLFlBQUEsQ0FBYSxJQUFDLENBQUEsdUJBQWQsQ0FEQSxDQUFBO1dBRUEsSUFBQyxDQUFBLHVCQUFELEdBQTJCLE9BSEo7RUFBQSxDQXhDekIsQ0FBQTs7QUFBQSwwQkE2Q0Esd0JBQUEsR0FBMEIsU0FBRSxxQkFBRixHQUFBO0FBQXlCLElBQXhCLElBQUMsQ0FBQSx3QkFBQSxxQkFBdUIsQ0FBekI7RUFBQSxDQTdDMUIsQ0FBQTs7QUFBQSwwQkFvREEsMkJBQUEsR0FBNkIsU0FBQSxHQUFBO1dBQzNCO0FBQUEsTUFDRSxPQUFBLEVBQVUsR0FEWjtBQUFBLE1BRUUsU0FBQSxFQUFhLEdBQUEsR0FBRSxDQUFBLElBQUMsQ0FBQSwyQkFBRCxFQUFBLENBRmpCO0FBQUEsTUFHRSxNQUFBLEVBQVEsS0FIVjtNQUQyQjtFQUFBLENBcEQ3QixDQUFBOztBQUFBLDBCQThEQSxtQkFBQSxHQUFxQixTQUFDLE9BQUQsR0FBQTtBQUNuQixRQUFBLG9CQUFBO0FBQUEsSUFBQSxJQUFPLGVBQVA7QUFDRSxNQUFBLEdBQUEsR0FBTSxFQUFOLENBQUE7QUFDQTtBQUFBLFdBQUEsWUFBQTt5QkFBQTtBQUNFLFFBQUEsR0FBSSxDQUFBLElBQUEsQ0FBSixHQUFZLEdBQVosQ0FERjtBQUFBLE9BREE7YUFHQSxJQUpGO0tBQUEsTUFBQTthQU1FLElBQUMsQ0FBQSxpQkFBa0IsQ0FBQSxPQUFBLEVBTnJCO0tBRG1CO0VBQUEsQ0E5RHJCLENBQUE7O0FBQUEsMEJBMkVBLE9BQUEsR0FBUyxTQUFDLFlBQUQsR0FBQTtBQUNQLFFBQUEsc0VBQUE7O01BRFEsZUFBYTtLQUNyQjtBQUFBLElBQUEsSUFBQSxHQUFPLEVBQVAsQ0FBQTtBQUFBLElBQ0EsT0FBQSxHQUFVLFNBQUMsSUFBRCxFQUFPLFFBQVAsR0FBQTtBQUNSLE1BQUEsSUFBRyxDQUFLLFlBQUwsQ0FBQSxJQUFlLENBQUssZ0JBQUwsQ0FBbEI7QUFDRSxjQUFVLElBQUEsS0FBQSxDQUFNLE1BQU4sQ0FBVixDQURGO09BQUE7YUFFSSw0QkFBSixJQUEyQixZQUFhLENBQUEsSUFBQSxDQUFiLElBQXNCLFNBSHpDO0lBQUEsQ0FEVixDQUFBO0FBTUE7QUFBQSxTQUFBLGNBQUE7MEJBQUE7QUFDRSxXQUFBLGdCQUFBOzJCQUFBO0FBQ0UsUUFBQSxJQUFHLENBQUMsQ0FBQyxNQUFGLElBQWEsT0FBQSxDQUFRLE1BQVIsRUFBZ0IsUUFBaEIsQ0FBaEI7QUFFRSxVQUFBLE1BQUEsR0FBUyxDQUFDLENBQUMsT0FBRixDQUFBLENBQVQsQ0FBQTtBQUNBLFVBQUEsSUFBRyxpQkFBSDtBQUVFLFlBQUEsTUFBQSxHQUFTLENBQUMsQ0FBQyxPQUFYLENBQUE7QUFDQSxtQkFBTSx3QkFBQSxJQUFvQixPQUFBLENBQVEsTUFBTSxDQUFDLE9BQWYsRUFBd0IsTUFBTSxDQUFDLFNBQS9CLENBQTFCLEdBQUE7QUFDRSxjQUFBLE1BQUEsR0FBUyxNQUFNLENBQUMsT0FBaEIsQ0FERjtZQUFBLENBREE7QUFBQSxZQUdBLE1BQU0sQ0FBQyxJQUFQLEdBQWMsTUFBTSxDQUFDLE1BQVAsQ0FBQSxDQUhkLENBRkY7V0FBQSxNQU1LLElBQUcsaUJBQUg7QUFFSCxZQUFBLE1BQUEsR0FBUyxDQUFDLENBQUMsT0FBWCxDQUFBO0FBQ0EsbUJBQU0sd0JBQUEsSUFBb0IsT0FBQSxDQUFRLE1BQU0sQ0FBQyxPQUFmLEVBQXdCLE1BQU0sQ0FBQyxTQUEvQixDQUExQixHQUFBO0FBQ0UsY0FBQSxNQUFBLEdBQVMsTUFBTSxDQUFDLE9BQWhCLENBREY7WUFBQSxDQURBO0FBQUEsWUFHQSxNQUFNLENBQUMsSUFBUCxHQUFjLE1BQU0sQ0FBQyxNQUFQLENBQUEsQ0FIZCxDQUZHO1dBUEw7QUFBQSxVQWFBLElBQUksQ0FBQyxJQUFMLENBQVUsTUFBVixDQWJBLENBRkY7U0FERjtBQUFBLE9BREY7QUFBQSxLQU5BO1dBeUJBLEtBMUJPO0VBQUEsQ0EzRVQsQ0FBQTs7QUFBQSwwQkE0R0EsMEJBQUEsR0FBNEIsU0FBQyxPQUFELEdBQUE7QUFDMUIsUUFBQSxHQUFBO0FBQUEsSUFBQSxJQUFPLGVBQVA7QUFDRSxNQUFBLE9BQUEsR0FBVSxJQUFDLENBQUEsT0FBWCxDQURGO0tBQUE7QUFFQSxJQUFBLElBQU8sdUNBQVA7QUFDRSxNQUFBLElBQUMsQ0FBQSxpQkFBa0IsQ0FBQSxPQUFBLENBQW5CLEdBQThCLENBQTlCLENBREY7S0FGQTtBQUFBLElBSUEsR0FBQSxHQUNFO0FBQUEsTUFBQSxTQUFBLEVBQVksT0FBWjtBQUFBLE1BQ0EsV0FBQSxFQUFjLElBQUMsQ0FBQSxpQkFBa0IsQ0FBQSxPQUFBLENBRGpDO0tBTEYsQ0FBQTtBQUFBLElBT0EsSUFBQyxDQUFBLGlCQUFrQixDQUFBLE9BQUEsQ0FBbkIsRUFQQSxDQUFBO1dBUUEsSUFUMEI7RUFBQSxDQTVHNUIsQ0FBQTs7QUFBQSwwQkEwSEEsWUFBQSxHQUFjLFNBQUMsR0FBRCxHQUFBO0FBQ1osUUFBQSxJQUFBO0FBQUEsSUFBQSxJQUFHLEdBQUEsWUFBZSxNQUFsQjs2REFDd0IsQ0FBQSxHQUFHLENBQUMsU0FBSixXQUR4QjtLQUFBLE1BRUssSUFBTyxXQUFQO0FBQUE7S0FBQSxNQUFBO0FBRUgsWUFBVSxJQUFBLEtBQUEsQ0FBTSxrQ0FBTixDQUFWLENBRkc7S0FITztFQUFBLENBMUhkLENBQUE7O0FBQUEsMEJBb0lBLFlBQUEsR0FBYyxTQUFDLENBQUQsR0FBQTtBQUNaLElBQUEsSUFBTyw4QkFBUDtBQUNFLE1BQUEsSUFBQyxDQUFBLE1BQU8sQ0FBQSxDQUFDLENBQUMsT0FBRixDQUFSLEdBQXFCLEVBQXJCLENBREY7S0FBQTtBQUVBLElBQUEsSUFBRywyQ0FBSDtBQUNFLFlBQVUsSUFBQSxLQUFBLENBQU0sb0NBQU4sQ0FBVixDQURGO0tBRkE7QUFBQSxJQUlBLElBQUMsQ0FBQSxNQUFPLENBQUEsQ0FBQyxDQUFDLE9BQUYsQ0FBVyxDQUFBLENBQUMsQ0FBQyxTQUFGLENBQW5CLEdBQWtDLENBSmxDLENBQUE7V0FLQSxFQU5ZO0VBQUEsQ0FwSWQsQ0FBQTs7QUFBQSwwQkE0SUEsZUFBQSxHQUFpQixTQUFDLENBQUQsR0FBQTtBQUNmLFFBQUEsSUFBQTtxREFBQSxNQUFBLENBQUEsSUFBMkIsQ0FBQSxDQUFDLENBQUMsU0FBRixXQURaO0VBQUEsQ0E1SWpCLENBQUE7O0FBQUEsMEJBa0pBLFlBQUEsR0FBYyxTQUFDLENBQUQsR0FBQTtBQUNaLFFBQUEsUUFBQTtBQUFBLElBQUEsSUFBTyx5Q0FBUDtBQUNFLE1BQUEsSUFBQyxDQUFBLGlCQUFrQixDQUFBLENBQUMsQ0FBQyxPQUFGLENBQW5CLEdBQWdDLENBQWhDLENBREY7S0FBQTtBQUVBLElBQUEsSUFBRyxNQUFBLENBQUEsQ0FBUSxDQUFDLFNBQVQsS0FBc0IsUUFBdEIsSUFBbUMsQ0FBQyxDQUFDLE9BQUYsS0FBZSxJQUFDLENBQUEsU0FBRCxDQUFBLENBQXJEO0FBSUUsTUFBQSxJQUFHLENBQUMsQ0FBQyxTQUFGLEtBQWUsSUFBQyxDQUFBLGlCQUFrQixDQUFBLENBQUMsQ0FBQyxPQUFGLENBQXJDO0FBQ0UsUUFBQSxJQUFDLENBQUEsaUJBQWtCLENBQUEsQ0FBQyxDQUFDLE9BQUYsQ0FBbkIsRUFBQSxDQUFBO0FBQ0E7ZUFBTTs7O29CQUFOLEdBQUE7QUFDRSx3QkFBQSxJQUFDLENBQUEsaUJBQWtCLENBQUEsQ0FBQyxDQUFDLE9BQUYsQ0FBbkIsR0FBQSxDQURGO1FBQUEsQ0FBQTt3QkFGRjtPQUpGO0tBSFk7RUFBQSxDQWxKZCxDQUFBOzt1QkFBQTs7SUFSRixDQUFBOztBQUFBLE1BMktNLENBQUMsT0FBUCxHQUFpQixhQTNLakIsQ0FBQTs7OztBQ1BBLElBQUE7O2lTQUFBOztBQUFBLE1BQU0sQ0FBQyxPQUFQLEdBQWlCLFNBQUMsRUFBRCxHQUFBO0FBRWYsTUFBQSxpRkFBQTtBQUFBLEVBQUEsTUFBQSxHQUFTLEVBQVQsQ0FBQTtBQUFBLEVBQ0Esa0JBQUEsR0FBcUIsRUFEckIsQ0FBQTtBQUFBLEVBZ0JNO0FBTVMsSUFBQSxtQkFBQyxHQUFELEdBQUE7QUFDWCxNQUFBLElBQUMsQ0FBQSxVQUFELEdBQWMsS0FBZCxDQUFBO0FBQUEsTUFDQSxJQUFDLENBQUEsTUFBRCxHQUFVLElBRFYsQ0FBQTtBQUFBLE1BRUEsSUFBQyxDQUFBLGlCQUFELEdBQXFCLEtBRnJCLENBQUE7QUFHQSxNQUFBLElBQU8sV0FBUDtBQUNFLFFBQUEsR0FBQSxHQUFNLEVBQUUsQ0FBQywwQkFBSCxDQUFBLENBQU4sQ0FERjtPQUhBO0FBS0EsTUFBQSxJQUFPLGtCQUFQO0FBQ0UsUUFBQSxHQUFHLENBQUMsTUFBSixHQUFhLENBQUEsS0FBSSxDQUFNLFFBQUEsQ0FBUyxHQUFHLENBQUMsU0FBYixDQUFOLENBQWpCLENBREY7T0FMQTtBQUFBLE1BUWEsSUFBQyxDQUFBLGNBQVosVUFERixFQUVnQixJQUFDLENBQUEsZ0JBQWYsWUFGRixFQUdhLElBQUMsQ0FBQSxhQUFaLFNBVkYsQ0FEVztJQUFBLENBQWI7O0FBQUEsd0JBY0EsSUFBQSxHQUFNLFFBZE4sQ0FBQTs7QUFBQSx3QkFxQkEsRUFBQSxHQUFJLFNBQUMsTUFBRCxFQUFTLENBQVQsR0FBQTtBQUNGLFVBQUEsNEJBQUE7O1FBQUEsSUFBQyxDQUFBLGtCQUFtQjtPQUFwQjtBQUNBLE1BQUEsSUFBRyxNQUFNLENBQUMsV0FBUCxLQUF3QixFQUFFLENBQUMsV0FBOUI7QUFDRSxRQUFBLE1BQUEsR0FBUyxDQUFDLE1BQUQsQ0FBVCxDQURGO09BREE7QUFHQTtXQUFBLDZDQUFBO3VCQUFBOztlQUNtQixDQUFBLENBQUEsSUFBTTtTQUF2QjtBQUFBLHNCQUNBLElBQUMsQ0FBQSxlQUFnQixDQUFBLENBQUEsQ0FBRSxDQUFDLElBQXBCLENBQXlCLENBQXpCLEVBREEsQ0FERjtBQUFBO3NCQUpFO0lBQUEsQ0FyQkosQ0FBQTs7QUFBQSx3QkF1Q0EsY0FBQSxHQUFnQixTQUFDLE1BQUQsRUFBUyxDQUFULEdBQUE7QUFDZCxVQUFBLDJCQUFBO0FBQUEsTUFBQSxJQUFHLE1BQU0sQ0FBQyxXQUFQLEtBQXdCLEVBQUUsQ0FBQyxXQUE5QjtBQUNFLFFBQUEsTUFBQSxHQUFTLENBQUMsTUFBRCxDQUFULENBREY7T0FBQTtBQUVBO1dBQUEsNkNBQUE7dUJBQUE7QUFDRSxRQUFBLElBQUcsa0VBQUg7d0JBQ0UsSUFBQyxDQUFBLGVBQWdCLENBQUEsQ0FBQSxDQUFqQixHQUFzQixJQUFDLENBQUEsZUFBZ0IsQ0FBQSxDQUFBLENBQUUsQ0FBQyxNQUFwQixDQUEyQixTQUFDLENBQUQsR0FBQTttQkFDL0MsQ0FBQSxLQUFPLEVBRHdDO1VBQUEsQ0FBM0IsR0FEeEI7U0FBQSxNQUFBO2dDQUFBO1NBREY7QUFBQTtzQkFIYztJQUFBLENBdkNoQixDQUFBOztBQUFBLHdCQW1EQSxTQUFBLEdBQVcsU0FBQSxHQUFBO2FBQ1QsSUFBQyxDQUFBLFlBQUQsYUFBYyxDQUFBLElBQUcsU0FBQSxhQUFBLFNBQUEsQ0FBQSxDQUFqQixFQURTO0lBQUEsQ0FuRFgsQ0FBQTs7QUFBQSx3QkF5REEsWUFBQSxHQUFjLFNBQUEsR0FBQTtBQUNaLFVBQUEsbURBQUE7QUFBQSxNQURhLG1CQUFJLHNCQUFPLDhEQUN4QixDQUFBO0FBQUEsTUFBQSxJQUFHLHNFQUFIO0FBQ0U7QUFBQTthQUFBLDRDQUFBO3dCQUFBO0FBQ0Usd0JBQUEsQ0FBQyxDQUFDLElBQUYsVUFBTyxDQUFBLEVBQUEsRUFBSSxLQUFPLFNBQUEsYUFBQSxJQUFBLENBQUEsQ0FBbEIsRUFBQSxDQURGO0FBQUE7d0JBREY7T0FEWTtJQUFBLENBekRkLENBQUE7O0FBQUEsd0JBOERBLFNBQUEsR0FBVyxTQUFBLEdBQUE7YUFDVCxJQUFDLENBQUEsV0FEUTtJQUFBLENBOURYLENBQUE7O0FBQUEsd0JBaUVBLFdBQUEsR0FBYSxTQUFDLGNBQUQsR0FBQTs7UUFBQyxpQkFBaUI7T0FDN0I7QUFBQSxNQUFBLElBQUcsQ0FBQSxJQUFLLENBQUEsaUJBQVI7QUFFRSxRQUFBLElBQUMsQ0FBQSxVQUFELEdBQWMsSUFBZCxDQUFBO0FBQ0EsUUFBQSxJQUFHLGNBQUg7QUFDRSxVQUFBLElBQUMsQ0FBQSxpQkFBRCxHQUFxQixJQUFyQixDQUFBO2lCQUNBLEVBQUUsQ0FBQyxxQkFBSCxDQUF5QixJQUF6QixFQUZGO1NBSEY7T0FEVztJQUFBLENBakViLENBQUE7O0FBQUEsd0JBeUVBLE9BQUEsR0FBUyxTQUFBLEdBQUE7YUFFUCxFQUFFLENBQUMsZUFBSCxDQUFtQixJQUFuQixFQUZPO0lBQUEsQ0F6RVQsQ0FBQTs7QUFBQSx3QkFnRkEsU0FBQSxHQUFXLFNBQUUsTUFBRixHQUFBO0FBQVUsTUFBVCxJQUFDLENBQUEsU0FBQSxNQUFRLENBQVY7SUFBQSxDQWhGWCxDQUFBOztBQUFBLHdCQXFGQSxTQUFBLEdBQVcsU0FBQSxHQUFBO2FBQ1QsSUFBQyxDQUFBLE9BRFE7SUFBQSxDQXJGWCxDQUFBOztBQUFBLHdCQTJGQSxNQUFBLEdBQVEsU0FBQSxHQUFBO2FBQ047QUFBQSxRQUFFLFNBQUEsRUFBVyxJQUFDLENBQUEsT0FBZDtBQUFBLFFBQXVCLFdBQUEsRUFBYSxJQUFDLENBQUEsU0FBckM7QUFBQSxRQUFpRCxNQUFBLEVBQVEsSUFBQyxDQUFBLE1BQTFEO1FBRE07SUFBQSxDQTNGUixDQUFBOztBQUFBLHdCQThGQSxRQUFBLEdBQVUsU0FBQSxHQUFBO2FBQ1IsSUFBQyxDQUFBLE1BQUQsR0FBVSxNQURGO0lBQUEsQ0E5RlYsQ0FBQTs7QUFBQSx3QkFxR0EsT0FBQSxHQUFTLFNBQUEsR0FBQTtBQUNQLFVBQUEsV0FBQTtBQUFBLE1BQUEsSUFBQyxDQUFBLFdBQUQsR0FBZSxJQUFmLENBQUE7QUFDQSxXQUFBLHlEQUFBO21DQUFBO0FBQ0UsUUFBQSxDQUFBLENBQUUsSUFBQyxDQUFBLE9BQUQsQ0FBQSxDQUFGLENBQUEsQ0FERjtBQUFBLE9BREE7YUFHQSxLQUpPO0lBQUEsQ0FyR1QsQ0FBQTs7QUFBQSx3QkE2SEEsYUFBQSxHQUFlLFNBQUMsSUFBRCxFQUFPLEVBQVAsR0FBQTtBQU9iLE1BQUEsSUFBRywwQ0FBSDtlQUVFLElBQUUsQ0FBQSxJQUFBLENBQUYsR0FBVSxHQUZaO09BQUEsTUFHSyxJQUFHLFVBQUg7O1VBRUgsSUFBQyxDQUFBLFlBQWE7U0FBZDtlQUNBLElBQUMsQ0FBQSxTQUFVLENBQUEsSUFBQSxDQUFYLEdBQW1CLEdBSGhCO09BVlE7SUFBQSxDQTdIZixDQUFBOztBQUFBLHdCQW1KQSx1QkFBQSxHQUF5QixTQUFBLEdBQUE7QUFDdkIsVUFBQSwrQ0FBQTtBQUFBLE1BQUEsY0FBQSxHQUFpQixFQUFqQixDQUFBO0FBQUEsTUFDQSxPQUFBLEdBQVUsSUFEVixDQUFBO0FBRUE7QUFBQSxXQUFBLFlBQUE7NEJBQUE7QUFDRSxRQUFBLEVBQUEsR0FBSyxFQUFFLENBQUMsWUFBSCxDQUFnQixNQUFoQixDQUFMLENBQUE7QUFDQSxRQUFBLElBQUcsRUFBSDtBQUNFLFVBQUEsSUFBRSxDQUFBLElBQUEsQ0FBRixHQUFVLEVBQVYsQ0FERjtTQUFBLE1BQUE7QUFHRSxVQUFBLGNBQWUsQ0FBQSxJQUFBLENBQWYsR0FBdUIsTUFBdkIsQ0FBQTtBQUFBLFVBQ0EsT0FBQSxHQUFVLEtBRFYsQ0FIRjtTQUZGO0FBQUEsT0FGQTtBQUFBLE1BU0EsTUFBQSxDQUFBLElBQVEsQ0FBQSxTQVRSLENBQUE7QUFVQSxNQUFBLElBQUcsQ0FBQSxPQUFIO0FBQ0UsUUFBQSxJQUFDLENBQUEsU0FBRCxHQUFhLGNBQWIsQ0FERjtPQVZBO2FBWUEsUUFidUI7SUFBQSxDQW5KekIsQ0FBQTs7cUJBQUE7O01BdEJGLENBQUE7QUFBQSxFQThMTTtBQU1KLDZCQUFBLENBQUE7O0FBQWEsSUFBQSxnQkFBQyxHQUFELEVBQU0sT0FBTixHQUFBO0FBQ1gsTUFBQSxJQUFDLENBQUEsYUFBRCxDQUFlLFNBQWYsRUFBMEIsT0FBMUIsQ0FBQSxDQUFBO0FBQUEsTUFDQSx3Q0FBTSxHQUFOLENBREEsQ0FEVztJQUFBLENBQWI7O0FBQUEscUJBSUEsSUFBQSxHQUFNLFFBSk4sQ0FBQTs7QUFBQSxxQkFXQSxPQUFBLEdBQVMsU0FBQSxHQUFBO2FBQ1A7QUFBQSxRQUNFLE1BQUEsRUFBUSxRQURWO0FBQUEsUUFFRSxLQUFBLEVBQU8sSUFBQyxDQUFBLE1BQUQsQ0FBQSxDQUZUO0FBQUEsUUFHRSxTQUFBLEVBQVcsSUFBQyxDQUFBLE9BQU8sQ0FBQyxNQUFULENBQUEsQ0FIYjtRQURPO0lBQUEsQ0FYVCxDQUFBOztBQUFBLHFCQXNCQSxPQUFBLEdBQVMsU0FBQSxHQUFBO0FBQ1AsTUFBQSxJQUFHLElBQUMsQ0FBQSx1QkFBRCxDQUFBLENBQUg7QUFDRSxRQUFBLElBQUMsQ0FBQSxPQUFPLENBQUMsV0FBVCxDQUFxQixJQUFyQixDQUFBLENBQUE7ZUFDQSxxQ0FBQSxTQUFBLEVBRkY7T0FBQSxNQUFBO2VBSUUsTUFKRjtPQURPO0lBQUEsQ0F0QlQsQ0FBQTs7a0JBQUE7O0tBTm1CLFVBOUxyQixDQUFBO0FBQUEsRUFvT0EsTUFBTyxDQUFBLFFBQUEsQ0FBUCxHQUFtQixTQUFDLENBQUQsR0FBQTtBQUNqQixRQUFBLGdCQUFBO0FBQUEsSUFDVSxRQUFSLE1BREYsRUFFYSxnQkFBWCxVQUZGLENBQUE7V0FJSSxJQUFBLE1BQUEsQ0FBTyxHQUFQLEVBQVksV0FBWixFQUxhO0VBQUEsQ0FwT25CLENBQUE7QUFBQSxFQXFQTTtBQVNKLDZCQUFBLENBQUE7O0FBQWEsSUFBQSxnQkFBQyxHQUFELEVBQU0sT0FBTixFQUFlLE9BQWYsRUFBd0IsTUFBeEIsR0FBQTtBQUNYLE1BQUEsSUFBQyxDQUFBLGFBQUQsQ0FBZSxTQUFmLEVBQTBCLE9BQTFCLENBQUEsQ0FBQTtBQUFBLE1BQ0EsSUFBQyxDQUFBLGFBQUQsQ0FBZSxTQUFmLEVBQTBCLE9BQTFCLENBREEsQ0FBQTtBQUVBLE1BQUEsSUFBRyxjQUFIO0FBQ0UsUUFBQSxJQUFDLENBQUEsYUFBRCxDQUFlLFFBQWYsRUFBeUIsTUFBekIsQ0FBQSxDQURGO09BQUEsTUFBQTtBQUdFLFFBQUEsSUFBQyxDQUFBLGFBQUQsQ0FBZSxRQUFmLEVBQXlCLE9BQXpCLENBQUEsQ0FIRjtPQUZBO0FBQUEsTUFNQSx3Q0FBTSxHQUFOLENBTkEsQ0FEVztJQUFBLENBQWI7O0FBQUEscUJBU0EsSUFBQSxHQUFNLFFBVE4sQ0FBQTs7QUFBQSxxQkFlQSxXQUFBLEdBQWEsU0FBQyxDQUFELEdBQUE7QUFDWCxVQUFBLG9CQUFBOztRQUFBLElBQUMsQ0FBQSxhQUFjO09BQWY7QUFDQSxNQUFBLElBQUcscUJBQUEsSUFBYSxDQUFBLElBQUssQ0FBQSxTQUFELENBQUEsQ0FBcEI7QUFFRSxRQUFBLElBQUMsQ0FBQSxNQUFNLENBQUMsU0FBUixDQUFrQixRQUFsQixFQUE0QixJQUE1QixFQUErQixDQUEvQixDQUFBLENBRkY7T0FEQTtBQUlBLE1BQUEsSUFBRyxTQUFIO0FBQ0UsUUFBQSxJQUFDLENBQUEsVUFBVSxDQUFDLElBQVosQ0FBaUIsQ0FBakIsQ0FBQSxDQURGO09BSkE7QUFBQSxNQU1BLGNBQUEsR0FBaUIsS0FOakIsQ0FBQTtBQU9BLE1BQUEsSUFBRyxDQUFBLENBQUssc0JBQUEsSUFBYyxzQkFBZixDQUFKLElBQWlDLElBQUMsQ0FBQSxPQUFPLENBQUMsU0FBVCxDQUFBLENBQXBDO0FBQ0UsUUFBQSxjQUFBLEdBQWlCLElBQWpCLENBREY7T0FQQTtBQUFBLE1BU0Esd0NBQU0sY0FBTixDQVRBLENBQUE7QUFVQSxNQUFBLHdDQUFXLENBQUUsU0FBVixDQUFBLFVBQUg7ZUFFRSxJQUFDLENBQUEsT0FBTyxDQUFDLFdBQVQsQ0FBQSxFQUZGO09BWFc7SUFBQSxDQWZiLENBQUE7O0FBQUEscUJBOEJBLE9BQUEsR0FBUyxTQUFBLEdBQUE7QUFFUCxVQUFBLDJCQUFBO0FBQUEsTUFBQSx3Q0FBVyxDQUFFLFNBQVYsQ0FBQSxVQUFIO0FBRUU7QUFBQSxhQUFBLDRDQUFBO3dCQUFBO0FBQ0UsVUFBQSxDQUFDLENBQUMsT0FBRixDQUFBLENBQUEsQ0FERjtBQUFBLFNBQUE7QUFBQSxRQUtBLENBQUEsR0FBSSxJQUFDLENBQUEsT0FMTCxDQUFBO0FBTUEsZUFBTSxDQUFDLENBQUMsSUFBRixLQUFZLFdBQWxCLEdBQUE7QUFDRSxVQUFBLElBQUcsQ0FBQyxDQUFDLE1BQUYsS0FBWSxJQUFmO0FBQ0UsWUFBQSxDQUFDLENBQUMsTUFBRixHQUFXLElBQUMsQ0FBQSxPQUFaLENBREY7V0FBQTtBQUFBLFVBRUEsQ0FBQSxHQUFJLENBQUMsQ0FBQyxPQUZOLENBREY7UUFBQSxDQU5BO0FBQUEsUUFXQSxJQUFDLENBQUEsT0FBTyxDQUFDLE9BQVQsR0FBbUIsSUFBQyxDQUFBLE9BWHBCLENBQUE7QUFBQSxRQVlBLElBQUMsQ0FBQSxPQUFPLENBQUMsT0FBVCxHQUFtQixJQUFDLENBQUEsT0FacEIsQ0FBQTtlQWFBLHFDQUFBLFNBQUEsRUFmRjtPQUZPO0lBQUEsQ0E5QlQsQ0FBQTs7QUFBQSxxQkFzREEsbUJBQUEsR0FBcUIsU0FBQSxHQUFBO0FBQ25CLFVBQUEsSUFBQTtBQUFBLE1BQUEsQ0FBQSxHQUFJLENBQUosQ0FBQTtBQUFBLE1BQ0EsQ0FBQSxHQUFJLElBQUMsQ0FBQSxPQURMLENBQUE7QUFFQSxhQUFNLElBQU4sR0FBQTtBQUNFLFFBQUEsSUFBRyxJQUFDLENBQUEsTUFBRCxLQUFXLENBQWQ7QUFDRSxnQkFERjtTQUFBO0FBQUEsUUFFQSxDQUFBLEVBRkEsQ0FBQTtBQUFBLFFBR0EsQ0FBQSxHQUFJLENBQUMsQ0FBQyxPQUhOLENBREY7TUFBQSxDQUZBO2FBT0EsRUFSbUI7SUFBQSxDQXREckIsQ0FBQTs7QUFBQSxxQkFvRUEsT0FBQSxHQUFTLFNBQUMsVUFBRCxHQUFBO0FBQ1AsVUFBQSxzQ0FBQTs7UUFEUSxhQUFhO09BQ3JCO0FBQUEsTUFBQSxJQUFHLENBQUEsSUFBSyxDQUFBLHVCQUFELENBQUEsQ0FBUDtBQUNFLGVBQU8sS0FBUCxDQURGO09BQUEsTUFBQTtBQUdFLFFBQUEsSUFBRyxvQkFBSDtBQUNFLFVBQUEsa0JBQUEsR0FBcUIsSUFBQyxDQUFBLG1CQUFELENBQUEsQ0FBckIsQ0FBQTtBQUFBLFVBQ0EsQ0FBQSxHQUFJLElBQUMsQ0FBQSxPQUFPLENBQUMsT0FEYixDQUFBO0FBQUEsVUFFQSxDQUFBLEdBQUksa0JBRkosQ0FBQTtBQWdCQSxpQkFBTSxJQUFOLEdBQUE7QUFDRSxZQUFBLElBQUcsQ0FBQSxLQUFPLElBQUMsQ0FBQSxPQUFYO0FBRUUsY0FBQSxJQUFHLENBQUMsQ0FBQyxtQkFBRixDQUFBLENBQUEsS0FBMkIsQ0FBOUI7QUFFRSxnQkFBQSxJQUFHLENBQUMsQ0FBQyxPQUFGLEdBQVksSUFBQyxDQUFBLE9BQWhCO0FBQ0Usa0JBQUEsSUFBQyxDQUFBLE9BQUQsR0FBVyxDQUFYLENBQUE7QUFBQSxrQkFDQSxrQkFBQSxHQUFxQixDQUFBLEdBQUksQ0FEekIsQ0FERjtpQkFBQSxNQUFBO0FBQUE7aUJBRkY7ZUFBQSxNQU9LLElBQUcsQ0FBQyxDQUFDLG1CQUFGLENBQUEsQ0FBQSxHQUEwQixDQUE3QjtBQUVILGdCQUFBLElBQUcsQ0FBQSxHQUFJLGtCQUFKLElBQTBCLENBQUMsQ0FBQyxtQkFBRixDQUFBLENBQTdCO0FBQ0Usa0JBQUEsSUFBQyxDQUFBLE9BQUQsR0FBVyxDQUFYLENBQUE7QUFBQSxrQkFDQSxrQkFBQSxHQUFxQixDQUFBLEdBQUksQ0FEekIsQ0FERjtpQkFBQSxNQUFBO0FBQUE7aUJBRkc7ZUFBQSxNQUFBO0FBU0gsc0JBVEc7ZUFQTDtBQUFBLGNBaUJBLENBQUEsRUFqQkEsQ0FBQTtBQUFBLGNBa0JBLENBQUEsR0FBSSxDQUFDLENBQUMsT0FsQk4sQ0FGRjthQUFBLE1BQUE7QUF1QkUsb0JBdkJGO2FBREY7VUFBQSxDQWhCQTtBQUFBLFVBMENBLElBQUMsQ0FBQSxPQUFELEdBQVcsSUFBQyxDQUFBLE9BQU8sQ0FBQyxPQTFDcEIsQ0FBQTtBQUFBLFVBMkNBLElBQUMsQ0FBQSxPQUFPLENBQUMsT0FBVCxHQUFtQixJQTNDbkIsQ0FBQTtBQUFBLFVBNENBLElBQUMsQ0FBQSxPQUFPLENBQUMsT0FBVCxHQUFtQixJQTVDbkIsQ0FERjtTQUFBO0FBQUEsUUErQ0EsTUFBQSx1Q0FBaUIsQ0FBRSxTQUFWLENBQUEsVUEvQ1QsQ0FBQTtBQWdEQSxRQUFBLElBQUcsZ0JBQUEsSUFBWSxVQUFmO0FBQ0UsVUFBQSxJQUFDLENBQUEsU0FBRCxDQUFXLE1BQVgsQ0FBQSxDQUFBO0FBQUEsVUFDQSxJQUFDLENBQUEsTUFBTSxDQUFDLFNBQVIsQ0FBa0IsUUFBbEIsRUFBNEIsSUFBNUIsQ0FEQSxDQURGO1NBaERBO2VBbURBLHFDQUFBLFNBQUEsRUF0REY7T0FETztJQUFBLENBcEVULENBQUE7O0FBQUEscUJBZ0lBLFdBQUEsR0FBYSxTQUFBLEdBQUE7QUFDWCxVQUFBLGNBQUE7QUFBQSxNQUFBLFFBQUEsR0FBVyxDQUFYLENBQUE7QUFBQSxNQUNBLElBQUEsR0FBTyxJQUFDLENBQUEsT0FEUixDQUFBO0FBRUEsYUFBTSxJQUFOLEdBQUE7QUFDRSxRQUFBLElBQUcsSUFBQSxZQUFnQixTQUFuQjtBQUNFLGdCQURGO1NBQUE7QUFFQSxRQUFBLElBQUcsQ0FBQSxJQUFRLENBQUMsU0FBTCxDQUFBLENBQVA7QUFDRSxVQUFBLFFBQUEsRUFBQSxDQURGO1NBRkE7QUFBQSxRQUlBLElBQUEsR0FBTyxJQUFJLENBQUMsT0FKWixDQURGO01BQUEsQ0FGQTthQVFBLFNBVFc7SUFBQSxDQWhJYixDQUFBOztrQkFBQTs7S0FUbUIsVUFyUHJCLENBQUE7QUFBQSxFQTZZTTtBQU1KLHNDQUFBLENBQUE7O0FBQWEsSUFBQSx5QkFBQyxHQUFELEVBQU8sT0FBUCxFQUFnQixJQUFoQixFQUFzQixJQUF0QixFQUE0QixNQUE1QixHQUFBO0FBQ1gsTUFEaUIsSUFBQyxDQUFBLFVBQUEsT0FDbEIsQ0FBQTtBQUFBLE1BQUEsaURBQU0sR0FBTixFQUFXLElBQVgsRUFBaUIsSUFBakIsRUFBdUIsTUFBdkIsQ0FBQSxDQURXO0lBQUEsQ0FBYjs7QUFBQSw4QkFHQSxJQUFBLEdBQU0saUJBSE4sQ0FBQTs7QUFBQSw4QkFRQSxHQUFBLEdBQU0sU0FBQSxHQUFBO2FBQ0osSUFBQyxDQUFBLFFBREc7SUFBQSxDQVJOLENBQUE7O0FBQUEsOEJBY0EsT0FBQSxHQUFTLFNBQUEsR0FBQTtBQUNQLFVBQUEsSUFBQTtBQUFBLE1BQUEsSUFBQSxHQUFPO0FBQUEsUUFDTCxNQUFBLEVBQVEsaUJBREg7QUFBQSxRQUVMLEtBQUEsRUFBUSxJQUFDLENBQUEsTUFBRCxDQUFBLENBRkg7QUFBQSxRQUdMLFNBQUEsRUFBWSxJQUFDLENBQUEsT0FIUjtPQUFQLENBQUE7QUFLQSxNQUFBLElBQUcsb0JBQUg7QUFDRSxRQUFBLElBQUssQ0FBQSxNQUFBLENBQUwsR0FBZSxJQUFDLENBQUEsT0FBTyxDQUFDLE1BQVQsQ0FBQSxDQUFmLENBREY7T0FMQTtBQU9BLE1BQUEsSUFBRyxvQkFBSDtBQUNFLFFBQUEsSUFBSyxDQUFBLE1BQUEsQ0FBTCxHQUFlLElBQUMsQ0FBQSxPQUFPLENBQUMsTUFBVCxDQUFBLENBQWYsQ0FERjtPQVBBO0FBU0EsTUFBQSxJQUFHLG1CQUFIO0FBQ0UsUUFBQSxJQUFLLENBQUEsUUFBQSxDQUFMLEdBQWlCLElBQUMsQ0FBQSxNQUFELENBQUEsQ0FBUyxDQUFDLE1BQVYsQ0FBQSxDQUFqQixDQURGO09BVEE7YUFXQSxLQVpPO0lBQUEsQ0FkVCxDQUFBOzsyQkFBQTs7S0FONEIsVUE3WTlCLENBQUE7QUFBQSxFQSthQSxNQUFPLENBQUEsaUJBQUEsQ0FBUCxHQUE0QixTQUFDLElBQUQsR0FBQTtBQUMxQixRQUFBLGdDQUFBO0FBQUEsSUFDVSxXQUFSLE1BREYsRUFFYyxlQUFaLFVBRkYsRUFHVSxZQUFSLE9BSEYsRUFJVSxZQUFSLE9BSkYsRUFLYSxjQUFYLFNBTEYsQ0FBQTtXQU9JLElBQUEsZUFBQSxDQUFnQixHQUFoQixFQUFxQixPQUFyQixFQUE4QixJQUE5QixFQUFvQyxJQUFwQyxFQUEwQyxNQUExQyxFQVJzQjtFQUFBLENBL2E1QixDQUFBO0FBQUEsRUErYk07QUFRSixnQ0FBQSxDQUFBOztBQUFhLElBQUEsbUJBQUMsR0FBRCxFQUFNLE9BQU4sRUFBZSxPQUFmLEVBQXdCLE1BQXhCLEdBQUE7QUFDWCxNQUFBLElBQUMsQ0FBQSxhQUFELENBQWUsU0FBZixFQUEwQixPQUExQixDQUFBLENBQUE7QUFBQSxNQUNBLElBQUMsQ0FBQSxhQUFELENBQWUsU0FBZixFQUEwQixPQUExQixDQURBLENBQUE7QUFBQSxNQUVBLElBQUMsQ0FBQSxhQUFELENBQWUsUUFBZixFQUF5QixPQUF6QixDQUZBLENBQUE7QUFBQSxNQUdBLDJDQUFNLEdBQU4sQ0FIQSxDQURXO0lBQUEsQ0FBYjs7QUFBQSx3QkFNQSxJQUFBLEdBQU0sV0FOTixDQUFBOztBQUFBLHdCQVFBLFdBQUEsR0FBYSxTQUFBLEdBQUE7QUFDWCxVQUFBLENBQUE7QUFBQSxNQUFBLHlDQUFBLENBQUEsQ0FBQTtBQUFBLE1BQ0EsQ0FBQSxHQUFJLElBQUMsQ0FBQSxPQURMLENBQUE7QUFFQSxhQUFNLFNBQU4sR0FBQTtBQUNFLFFBQUEsQ0FBQyxDQUFDLFdBQUYsQ0FBQSxDQUFBLENBQUE7QUFBQSxRQUNBLENBQUEsR0FBSSxDQUFDLENBQUMsT0FETixDQURGO01BQUEsQ0FGQTthQUtBLE9BTlc7SUFBQSxDQVJiLENBQUE7O0FBQUEsd0JBZ0JBLE9BQUEsR0FBUyxTQUFBLEdBQUE7YUFDUCxxQ0FBQSxFQURPO0lBQUEsQ0FoQlQsQ0FBQTs7QUFBQSx3QkFzQkEsT0FBQSxHQUFTLFNBQUEsR0FBQTtBQUNQLFVBQUEsV0FBQTtBQUFBLE1BQUEsSUFBRyxvRUFBSDtlQUNFLHdDQUFBLFNBQUEsRUFERjtPQUFBLE1BRUssNENBQWUsQ0FBQSxTQUFBLFVBQWY7QUFDSCxRQUFBLElBQUcsSUFBQyxDQUFBLHVCQUFELENBQUEsQ0FBSDtBQUNFLFVBQUEsSUFBRyw0QkFBSDtBQUNFLGtCQUFVLElBQUEsS0FBQSxDQUFNLGdDQUFOLENBQVYsQ0FERjtXQUFBO0FBQUEsVUFFQSxJQUFDLENBQUEsT0FBTyxDQUFDLE9BQVQsR0FBbUIsSUFGbkIsQ0FBQTtBQUFBLFVBR0EsTUFBQSxDQUFBLElBQVEsQ0FBQSxPQUFPLENBQUMsU0FBUyxDQUFDLE9BSDFCLENBQUE7aUJBSUEsd0NBQUEsU0FBQSxFQUxGO1NBQUEsTUFBQTtpQkFPRSxNQVBGO1NBREc7T0FBQSxNQVNBLElBQUcsc0JBQUEsSUFBa0IsOEJBQXJCO0FBQ0gsUUFBQSxNQUFBLENBQUEsSUFBUSxDQUFBLE9BQU8sQ0FBQyxTQUFTLENBQUMsT0FBMUIsQ0FBQTtlQUNBLElBQUMsQ0FBQSxPQUFPLENBQUMsT0FBVCxHQUFtQixLQUZoQjtPQUFBLE1BR0EsSUFBRyxzQkFBQSxJQUFhLHNCQUFoQjtlQUNILHdDQUFBLFNBQUEsRUFERztPQUFBLE1BQUE7QUFHSCxjQUFVLElBQUEsS0FBQSxDQUFNLG9DQUFOLENBQVYsQ0FIRztPQWZFO0lBQUEsQ0F0QlQsQ0FBQTs7QUFBQSx3QkE2Q0EsT0FBQSxHQUFTLFNBQUEsR0FBQTtBQUNQLFVBQUEsV0FBQTthQUFBO0FBQUEsUUFDRSxNQUFBLEVBQVMsV0FEWDtBQUFBLFFBRUUsS0FBQSxFQUFRLElBQUMsQ0FBQSxNQUFELENBQUEsQ0FGVjtBQUFBLFFBR0UsTUFBQSxzQ0FBaUIsQ0FBRSxNQUFWLENBQUEsVUFIWDtBQUFBLFFBSUUsTUFBQSx3Q0FBaUIsQ0FBRSxNQUFWLENBQUEsVUFKWDtRQURPO0lBQUEsQ0E3Q1QsQ0FBQTs7cUJBQUE7O0tBUnNCLFVBL2J4QixDQUFBO0FBQUEsRUE0ZkEsTUFBTyxDQUFBLFdBQUEsQ0FBUCxHQUFzQixTQUFDLElBQUQsR0FBQTtBQUNwQixRQUFBLGVBQUE7QUFBQSxJQUNRLFdBQVIsTUFEQSxFQUVTLFlBQVQsT0FGQSxFQUdTLFlBQVQsT0FIQSxDQUFBO1dBS0ksSUFBQSxTQUFBLENBQVUsR0FBVixFQUFlLElBQWYsRUFBcUIsSUFBckIsRUFOZ0I7RUFBQSxDQTVmdEIsQ0FBQTtTQXFnQkE7QUFBQSxJQUNFLE9BQUEsRUFDRTtBQUFBLE1BQUEsUUFBQSxFQUFXLE1BQVg7QUFBQSxNQUNBLFFBQUEsRUFBVyxNQURYO0FBQUEsTUFFQSxXQUFBLEVBQWEsU0FGYjtBQUFBLE1BR0EsV0FBQSxFQUFhLFNBSGI7QUFBQSxNQUlBLGlCQUFBLEVBQW9CLGVBSnBCO0tBRko7QUFBQSxJQU9FLFFBQUEsRUFBVyxNQVBiO0FBQUEsSUFRRSxvQkFBQSxFQUF1QixrQkFSekI7SUF2Z0JlO0FBQUEsQ0FBakIsQ0FBQTs7OztBQ0FBLElBQUEsd0JBQUE7RUFBQTs7b0JBQUE7O0FBQUEsd0JBQUEsR0FBMkIsT0FBQSxDQUFRLGFBQVIsQ0FBM0IsQ0FBQTs7QUFBQSxNQUVNLENBQUMsT0FBUCxHQUFpQixTQUFDLEVBQUQsR0FBQTtBQUNmLE1BQUEsMERBQUE7QUFBQSxFQUFBLFVBQUEsR0FBYSx3QkFBQSxDQUF5QixFQUF6QixDQUFiLENBQUE7QUFBQSxFQUNBLEtBQUEsR0FBUSxVQUFVLENBQUMsS0FEbkIsQ0FBQTtBQUFBLEVBRUEsTUFBQSxHQUFTLFVBQVUsQ0FBQyxNQUZwQixDQUFBO0FBQUEsRUFJQSxxQkFBQSxHQUF3QixTQUFDLFNBQUQsR0FBQTtBQTREdEIsUUFBQSxlQUFBO0FBQUEsSUFBTTtBQUtTLE1BQUEseUJBQUMsUUFBRCxHQUFBO0FBQ1gsWUFBQSxvQkFBQTtBQUFBO0FBQUEsY0FDSyxTQUFDLElBQUQsRUFBTyxHQUFQLEdBQUE7aUJBQ0QsTUFBTSxDQUFDLGNBQVAsQ0FBc0IsZUFBZSxDQUFDLFNBQXRDLEVBQWlELElBQWpELEVBQ0U7QUFBQSxZQUFBLEdBQUEsRUFBTSxTQUFBLEdBQUE7QUFDSixrQkFBQSxDQUFBO0FBQUEsY0FBQSxDQUFBLEdBQUksR0FBRyxDQUFDLEdBQUosQ0FBQSxDQUFKLENBQUE7QUFDQSxjQUFBLElBQUcsQ0FBQSxZQUFhLFFBQWhCO3VCQUNFLHFCQUFBLENBQXNCLENBQXRCLEVBREY7ZUFBQSxNQUVLLElBQUcsQ0FBQSxZQUFhLEtBQUssQ0FBQyxlQUF0Qjt1QkFDSCxDQUFDLENBQUMsR0FBRixDQUFBLEVBREc7ZUFBQSxNQUFBO3VCQUdILEVBSEc7ZUFKRDtZQUFBLENBQU47QUFBQSxZQVFBLEdBQUEsRUFBTSxTQUFDLENBQUQsR0FBQTtBQUNKLGtCQUFBLGtDQUFBO0FBQUEsY0FBQSxTQUFBLEdBQVksUUFBUSxDQUFDLEdBQVQsQ0FBYSxJQUFiLENBQVosQ0FBQTtBQUNBLGNBQUEsSUFBRyxDQUFDLENBQUMsV0FBRixLQUFpQixFQUFFLENBQUMsV0FBcEIsSUFBb0MsU0FBQSxZQUFxQixLQUFLLENBQUMsU0FBbEU7QUFDRTtxQkFBQSxXQUFBO29DQUFBO0FBQ0UsZ0NBQUEsU0FBUyxDQUFDLEdBQVYsQ0FBYyxNQUFkLEVBQXNCLEtBQXRCLEVBQTZCLFdBQTdCLEVBQUEsQ0FERjtBQUFBO2dDQURGO2VBQUEsTUFBQTt1QkFJRSxRQUFRLENBQUMsR0FBVCxDQUFhLElBQWIsRUFBbUIsQ0FBbkIsRUFBc0IsV0FBdEIsRUFKRjtlQUZJO1lBQUEsQ0FSTjtBQUFBLFlBZUEsVUFBQSxFQUFZLElBZlo7QUFBQSxZQWdCQSxZQUFBLEVBQWMsS0FoQmQ7V0FERixFQURDO1FBQUEsQ0FETDtBQUFBLGFBQUEsWUFBQTsyQkFBQTtBQUNFLGNBQUksTUFBTSxJQUFWLENBREY7QUFBQSxTQURXO01BQUEsQ0FBYjs7NkJBQUE7O1FBTEYsQ0FBQTtXQTBCSSxJQUFBLGVBQUEsQ0FBZ0IsU0FBaEIsRUF0RmtCO0VBQUEsQ0FKeEIsQ0FBQTtBQUFBLEVBK0ZNO0FBT0osK0JBQUEsQ0FBQTs7QUFBYSxJQUFBLGtCQUFDLEdBQUQsRUFBTSxhQUFOLEVBQXFCLE9BQXJCLEdBQUE7QUFDWCxVQUFBLE9BQUE7QUFBQSxNQUFBLDBDQUFNLEdBQU4sQ0FBQSxDQUFBO0FBQ0EsTUFBQSxJQUFHLHFCQUFIO0FBQ0UsUUFBQSxJQUFHLE1BQUEsQ0FBQSxhQUFBLEtBQTBCLFFBQTdCO0FBQ0UsZ0JBQVUsSUFBQSxLQUFBLENBQU8sd0VBQUEsR0FBdUUsQ0FBQSxNQUFBLENBQUEsYUFBQSxDQUF2RSxHQUE2RixHQUFwRyxDQUFWLENBREY7U0FBQTtBQUVBLGFBQUEscUJBQUE7a0NBQUE7QUFDRSxVQUFBLElBQUMsQ0FBQSxHQUFELENBQUssSUFBTCxFQUFXLENBQVgsRUFBYyxPQUFkLENBQUEsQ0FERjtBQUFBLFNBSEY7T0FGVztJQUFBLENBQWI7O0FBQUEsdUJBa0JBLElBQUEsR0FBTSxVQWxCTixDQUFBOztBQUFBLHVCQW9CQSxXQUFBLEdBQWEsU0FBQSxHQUFBO2FBQ1gsd0NBQUEsRUFEVztJQUFBLENBcEJiLENBQUE7O0FBQUEsdUJBdUJBLE9BQUEsR0FBUyxTQUFBLEdBQUE7YUFDUCxvQ0FBQSxFQURPO0lBQUEsQ0F2QlQsQ0FBQTs7QUFBQSx1QkE2QkEsTUFBQSxHQUFRLFNBQUEsR0FBQTtBQUNOLFVBQUEsa0JBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxJQUFDLENBQUEsR0FBRCxDQUFBLENBQU4sQ0FBQTtBQUFBLE1BQ0EsSUFBQSxHQUFPLEVBRFAsQ0FBQTtBQUVBLFdBQUEsV0FBQTtzQkFBQTtBQUNFLFFBQUEsSUFBRyxDQUFBLEtBQUssSUFBUjtBQUNFLFVBQUEsSUFBSyxDQUFBLElBQUEsQ0FBTCxHQUFhLENBQWIsQ0FERjtTQUFBLE1BRUssSUFBRyxDQUFDLENBQUMsV0FBRixLQUFpQixFQUFFLENBQUMsV0FBdkI7QUFDSCxVQUFBLElBQUssQ0FBQSxJQUFBLENBQUwsR0FBYSxJQUFDLENBQUEsR0FBRCxDQUFLLElBQUwsQ0FBVSxDQUFDLE1BQVgsQ0FBQSxDQUFiLENBREc7U0FBQSxNQUVBLElBQUcsQ0FBQSxZQUFhLEtBQUssQ0FBQyxTQUF0QjtBQUNILGlCQUFNLENBQUEsWUFBYSxLQUFLLENBQUMsU0FBekIsR0FBQTtBQUNFLFlBQUEsQ0FBQSxHQUFJLENBQUMsQ0FBQyxHQUFGLENBQUEsQ0FBSixDQURGO1VBQUEsQ0FBQTtBQUFBLFVBRUEsSUFBSyxDQUFBLElBQUEsQ0FBTCxHQUFhLENBRmIsQ0FERztTQUFBLE1BQUE7QUFLSCxVQUFBLElBQUssQ0FBQSxJQUFBLENBQUwsR0FBYSxDQUFiLENBTEc7U0FMUDtBQUFBLE9BRkE7YUFhQSxLQWRNO0lBQUEsQ0E3QlIsQ0FBQTs7QUFBQSx1QkFpREEsaUJBQUEsR0FBbUIsU0FBQyxlQUFELEdBQUE7QUFDakIsTUFBQSxJQUFDLENBQUEsZUFBRCxHQUFtQixlQUFuQixDQUFBO2FBQ0EsSUFBQyxDQUFBLEVBQUQsQ0FBSSxDQUFDLFFBQUQsRUFBVSxhQUFWLENBQUosRUFBOEIsU0FBQSxHQUFBO0FBQzVCLFlBQUEsSUFBQTtBQUFBLFFBQUEsSUFBRyw4QkFBSDtpQkFDRSxRQUFBLGVBQWUsQ0FBQyxNQUFoQixDQUFzQixDQUFDLFlBQXZCLGFBQW9DLENBQUEsSUFBTSxTQUFBLGFBQUEsU0FBQSxDQUFBLENBQTFDLEVBREY7U0FENEI7TUFBQSxDQUE5QixFQUZpQjtJQUFBLENBakRuQixDQUFBOztBQUFBLHVCQTJEQSxTQUFBLEdBQVcsU0FBQSxHQUFBO2FBQ1QsSUFBQyxDQUFBLGVBQWUsQ0FBQyxPQURSO0lBQUEsQ0EzRFgsQ0FBQTs7QUFBQSx1QkFpRUEsZUFBQSxHQUNFLElBbEVGLENBQUE7O0FBQUEsdUJBdUVBLGlCQUFBLEdBQW1CLFNBQUMsT0FBRCxHQUFBO0FBQ2pCLE1BQUEsSUFBRyxPQUFBLEtBQVcsSUFBWCxJQUFtQixPQUFBLEtBQVcsU0FBakM7QUFDRSxRQUFBLFFBQVEsQ0FBQyxTQUFTLENBQUMsZUFBbkIsR0FBcUMsSUFBckMsQ0FERjtPQUFBLE1BRUssSUFBRyxPQUFBLEtBQVcsS0FBWCxJQUFvQixPQUFBLEtBQVcsV0FBbEM7QUFDSCxRQUFBLFFBQVEsQ0FBQyxTQUFTLENBQUMsZUFBbkIsR0FBcUMsS0FBckMsQ0FERztPQUFBLE1BQUE7QUFHSCxjQUFVLElBQUEsS0FBQSxDQUFNLDhDQUFOLENBQVYsQ0FIRztPQUZMO2FBTUEsS0FQaUI7SUFBQSxDQXZFbkIsQ0FBQTs7QUFBQSx1QkFnR0EsR0FBQSxHQUFLLFNBQUMsSUFBRCxFQUFPLE9BQVAsRUFBZ0IsT0FBaEIsR0FBQTtBQUNILFVBQUEsZUFBQTtBQUFBLE1BQUEsSUFBRyxNQUFBLENBQUEsSUFBQSxLQUFlLFFBQWxCO0FBR0UsUUFBQSxJQUFBLEdBQVcsSUFBQSxRQUFBLENBQVMsTUFBVCxFQUFvQixJQUFwQixFQUEwQixPQUExQixDQUFYLENBQUE7QUFBQSxRQUNBLEVBQUUsQ0FBQyxZQUFILENBQWdCLElBQWhCLENBQXFCLENBQUMsT0FBdEIsQ0FBQSxDQURBLENBQUE7QUFBQSxRQUVBLElBQUMsQ0FBQSxlQUFlLENBQUMsT0FBakIsQ0FBeUIsSUFBekIsQ0FGQSxDQUFBO2VBR0EsS0FORjtPQUFBLE1BT0ssSUFBRyxjQUFBLElBQVUsQ0FBQyxpQkFBQSxJQUFZLE9BQUEsS0FBVyxJQUF4QixDQUFiO0FBQ0gsUUFBQSxJQUFHLGVBQUg7QUFDRSxVQUFBLElBQUcsT0FBQSxLQUFXLElBQVgsSUFBbUIsT0FBQSxLQUFXLFNBQWpDO0FBQ0UsWUFBQSxPQUFBLEdBQVUsSUFBVixDQURGO1dBQUEsTUFBQTtBQUdFLFlBQUEsT0FBQSxHQUFVLEtBQVYsQ0FIRjtXQURGO1NBQUEsTUFBQTtBQU1FLFVBQUEsT0FBQSxHQUFVLElBQUMsQ0FBQSxlQUFYLENBTkY7U0FBQTtBQU9BLFFBQUEsSUFBRyxNQUFBLENBQUEsT0FBQSxLQUFrQixVQUFyQjtpQkFDRSxLQURGO1NBQUEsTUFFSyxJQUFHLE9BQUEsS0FBVyxJQUFYLElBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUEsT0FBRCxDQUFBLElBQWlCLE1BQUEsQ0FBQSxPQUFBLEtBQWtCLFFBQXBDLENBQUEsSUFBa0QsT0FBTyxDQUFDLFdBQVIsS0FBeUIsTUFBNUUsQ0FBdEI7QUFDSCxVQUFBLEdBQUEsR0FBTSxFQUFFLENBQUMsWUFBSCxDQUFvQixJQUFBLEtBQUssQ0FBQyxlQUFOLENBQXNCLE1BQXRCLEVBQWlDLE9BQWpDLENBQXBCLENBQTZELENBQUMsT0FBOUQsQ0FBQSxDQUFOLENBQUE7aUJBQ0Esa0NBQU0sSUFBTixFQUFZLEdBQVosRUFGRztTQUFBLE1BQUE7QUFJSCxVQUFBLElBQUcsTUFBQSxDQUFBLE9BQUEsS0FBa0IsUUFBckI7QUFDRSxZQUFBLElBQUEsR0FBTyxFQUFFLENBQUMsWUFBSCxDQUFvQixJQUFBLEtBQUssQ0FBQyxRQUFOLENBQWUsTUFBZixDQUFwQixDQUE2QyxDQUFDLE9BQTlDLENBQUEsQ0FBUCxDQUFBO0FBQUEsWUFDQSxJQUFJLENBQUMsVUFBTCxDQUFnQixDQUFoQixFQUFtQixPQUFuQixDQURBLENBQUE7bUJBRUEsa0NBQU0sSUFBTixFQUFZLElBQVosRUFIRjtXQUFBLE1BSUssSUFBRyxPQUFPLENBQUMsV0FBUixLQUF1QixNQUExQjtBQUNILFlBQUEsSUFBQSxHQUFPLEVBQUUsQ0FBQyxZQUFILENBQW9CLElBQUEsUUFBQSxDQUFTLE1BQVQsRUFBb0IsT0FBcEIsRUFBNkIsT0FBN0IsQ0FBcEIsQ0FBeUQsQ0FBQyxPQUExRCxDQUFBLENBQVAsQ0FBQTttQkFDQSxrQ0FBTSxJQUFOLEVBQVksSUFBWixFQUZHO1dBQUEsTUFBQTtBQUlILGtCQUFVLElBQUEsS0FBQSxDQUFPLG1CQUFBLEdBQWtCLENBQUEsTUFBQSxDQUFBLE9BQUEsQ0FBbEIsR0FBa0MsdUNBQXpDLENBQVYsQ0FKRztXQVJGO1NBVkY7T0FBQSxNQUFBO2VBd0JILGtDQUFNLElBQU4sRUFBWSxPQUFaLEVBeEJHO09BUkY7SUFBQSxDQWhHTCxDQUFBOztBQUFBLElBa0lBLE1BQU0sQ0FBQyxjQUFQLENBQXNCLFFBQVEsQ0FBQyxTQUEvQixFQUEwQyxPQUExQyxFQUNFO0FBQUEsTUFBQSxHQUFBLEVBQU0sU0FBQSxHQUFBO2VBQUcscUJBQUEsQ0FBc0IsSUFBdEIsRUFBSDtNQUFBLENBQU47QUFBQSxNQUNBLEdBQUEsRUFBTSxTQUFDLENBQUQsR0FBQTtBQUNKLFlBQUEsdUJBQUE7QUFBQSxRQUFBLElBQUcsQ0FBQyxDQUFDLFdBQUYsS0FBaUIsRUFBRSxDQUFDLFdBQXZCO0FBQ0U7ZUFBQSxXQUFBOzhCQUFBO0FBQ0UsMEJBQUEsSUFBQyxDQUFBLEdBQUQsQ0FBSyxNQUFMLEVBQWEsS0FBYixFQUFvQixXQUFwQixFQUFBLENBREY7QUFBQTswQkFERjtTQUFBLE1BQUE7QUFJRSxnQkFBVSxJQUFBLEtBQUEsQ0FBTSxrQ0FBTixDQUFWLENBSkY7U0FESTtNQUFBLENBRE47S0FERixDQWxJQSxDQUFBOztBQUFBLHVCQThJQSxPQUFBLEdBQVMsU0FBQSxHQUFBO2FBQ1A7QUFBQSxRQUNFLE1BQUEsRUFBUyxVQURYO0FBQUEsUUFFRSxLQUFBLEVBQVEsSUFBQyxDQUFBLE1BQUQsQ0FBQSxDQUZWO1FBRE87SUFBQSxDQTlJVCxDQUFBOztvQkFBQTs7S0FQcUIsS0FBSyxDQUFDLFdBL0Y3QixDQUFBO0FBQUEsRUEwUEEsTUFBTyxDQUFBLFVBQUEsQ0FBUCxHQUFxQixTQUFDLElBQUQsR0FBQTtBQUNuQixRQUFBLEdBQUE7QUFBQSxJQUNVLE1BQ04sS0FERixNQURGLENBQUE7V0FHSSxJQUFBLFFBQUEsQ0FBUyxHQUFULEVBSmU7RUFBQSxDQTFQckIsQ0FBQTtBQUFBLEVBbVFBLEtBQU0sQ0FBQSxVQUFBLENBQU4sR0FBb0IsUUFuUXBCLENBQUE7U0FxUUEsV0F0UWU7QUFBQSxDQUZqQixDQUFBOzs7O0FDQUEsSUFBQSx5QkFBQTtFQUFBO2lTQUFBOztBQUFBLHlCQUFBLEdBQTRCLE9BQUEsQ0FBUSxjQUFSLENBQTVCLENBQUE7O0FBQUEsTUFFTSxDQUFDLE9BQVAsR0FBaUIsU0FBQyxFQUFELEdBQUE7QUFDZixNQUFBLHlGQUFBO0FBQUEsRUFBQSxXQUFBLEdBQWMseUJBQUEsQ0FBMEIsRUFBMUIsQ0FBZCxDQUFBO0FBQUEsRUFDQSxLQUFBLEdBQVEsV0FBVyxDQUFDLEtBRHBCLENBQUE7QUFBQSxFQUVBLE1BQUEsR0FBUyxXQUFXLENBQUMsTUFGckIsQ0FBQTtBQUFBLEVBUU07QUFLSixpQ0FBQSxDQUFBOztBQUFhLElBQUEsb0JBQUMsR0FBRCxHQUFBO0FBQ1gsTUFBQSxJQUFDLENBQUEsR0FBRCxHQUFPLEVBQVAsQ0FBQTtBQUFBLE1BQ0EsNENBQU0sR0FBTixDQURBLENBRFc7SUFBQSxDQUFiOztBQUFBLHlCQUlBLElBQUEsR0FBTSxZQUpOLENBQUE7O0FBQUEseUJBTUEsV0FBQSxHQUFhLFNBQUEsR0FBQTtBQUNYLFVBQUEsYUFBQTtBQUFBO0FBQUEsV0FBQSxZQUFBO3VCQUFBO0FBQ0UsUUFBQSxDQUFDLENBQUMsV0FBRixDQUFBLENBQUEsQ0FERjtBQUFBLE9BQUE7YUFFQSwwQ0FBQSxFQUhXO0lBQUEsQ0FOYixDQUFBOztBQUFBLHlCQVdBLE9BQUEsR0FBUyxTQUFBLEdBQUE7YUFDUCxzQ0FBQSxFQURPO0lBQUEsQ0FYVCxDQUFBOztBQUFBLHlCQWlCQSxHQUFBLEdBQUssU0FBQyxJQUFELEVBQU8sT0FBUCxHQUFBO0FBQ0gsVUFBQSwyQkFBQTtBQUFBLE1BQUEsSUFBRyxlQUFIO0FBQ0UsUUFBQSxJQUFPLHNCQUFQO0FBQ0UsVUFBQSxFQUFFLENBQUMsWUFBSCxDQUFvQixJQUFBLE9BQUEsQ0FBUSxNQUFSLEVBQW1CLElBQW5CLEVBQXNCLElBQXRCLENBQXBCLENBQStDLENBQUMsT0FBaEQsQ0FBQSxDQUFBLENBREY7U0FBQTtBQUFBLFFBRUEsSUFBQyxDQUFBLEdBQUksQ0FBQSxJQUFBLENBQUssQ0FBQyxPQUFYLENBQW1CLE9BQW5CLENBRkEsQ0FBQTtlQUdBLEtBSkY7T0FBQSxNQUtLLElBQUcsWUFBSDtBQUNILFFBQUEsR0FBQSx5Q0FBZ0IsQ0FBRSxHQUFaLENBQUEsVUFBTixDQUFBO0FBQ0EsUUFBQSxJQUFHLEdBQUEsWUFBZSxLQUFLLENBQUMsZUFBeEI7aUJBQ0UsR0FBRyxDQUFDLEdBQUosQ0FBQSxFQURGO1NBQUEsTUFBQTtpQkFHRSxJQUhGO1NBRkc7T0FBQSxNQUFBO0FBT0gsUUFBQSxNQUFBLEdBQVMsRUFBVCxDQUFBO0FBQ0E7QUFBQSxhQUFBLGFBQUE7MEJBQUE7QUFDRSxVQUFBLEdBQUEsR0FBTSxDQUFDLENBQUMsR0FBRixDQUFBLENBQU4sQ0FBQTtBQUNBLFVBQUEsSUFBRyxHQUFBLFlBQWUsS0FBSyxDQUFDLGVBQXJCLElBQXdDLEdBQUEsWUFBZSxVQUExRDtBQUNFLFlBQUEsR0FBQSxHQUFNLEdBQUcsQ0FBQyxHQUFKLENBQUEsQ0FBTixDQURGO1dBREE7QUFBQSxVQUdBLE1BQU8sQ0FBQSxJQUFBLENBQVAsR0FBZSxHQUhmLENBREY7QUFBQSxTQURBO2VBTUEsT0FiRztPQU5GO0lBQUEsQ0FqQkwsQ0FBQTs7c0JBQUE7O0tBTHVCLEtBQUssQ0FBQyxVQVIvQixDQUFBO0FBQUEsRUEwRE07QUFPSiw4QkFBQSxDQUFBOztBQUFhLElBQUEsaUJBQUMsR0FBRCxFQUFNLFdBQU4sRUFBb0IsSUFBcEIsR0FBQTtBQUNYLE1BRDhCLElBQUMsQ0FBQSxPQUFBLElBQy9CLENBQUE7QUFBQSxNQUFBLElBQUMsQ0FBQSxhQUFELENBQWUsYUFBZixFQUE4QixXQUE5QixDQUFBLENBQUE7QUFBQSxNQUNBLHlDQUFNLEdBQU4sQ0FEQSxDQURXO0lBQUEsQ0FBYjs7QUFBQSxzQkFJQSxJQUFBLEdBQU0sU0FKTixDQUFBOztBQUFBLHNCQU1BLFdBQUEsR0FBYSxTQUFBLEdBQUE7YUFDWCx1Q0FBQSxFQURXO0lBQUEsQ0FOYixDQUFBOztBQUFBLHNCQVNBLE9BQUEsR0FBUyxTQUFBLEdBQUE7YUFDUCxtQ0FBQSxFQURPO0lBQUEsQ0FUVCxDQUFBOztBQUFBLHNCQWtCQSxPQUFBLEdBQVMsU0FBQSxHQUFBO0FBQ1AsVUFBQSx3Q0FBQTtBQUFBLE1BQUEsSUFBRyxDQUFBLElBQUssQ0FBQSx1QkFBRCxDQUFBLENBQVA7QUFDRSxlQUFPLEtBQVAsQ0FERjtPQUFBLE1BQUE7QUFHRSxRQUFBLEtBQUEsR0FBUSxJQUFDLENBQUEsV0FBVyxDQUFDLE1BQWIsQ0FBQSxDQUFSLENBQUE7QUFBQSxRQUNBLEtBQUssQ0FBQyxTQUFOLEdBQW1CLEdBQUEsR0FBRSxLQUFLLENBQUMsU0FBUixHQUFtQixNQUFuQixHQUF3QixJQUFDLENBQUEsSUFENUMsQ0FBQTtBQUVBLFFBQUEsSUFBTyw4QkFBUDtBQUNFLFVBQUEsT0FBQSxHQUFVLElBQUMsQ0FBQSxXQUFXLENBQUMsTUFBYixDQUFBLENBQVYsQ0FBQTtBQUFBLFVBQ0EsT0FBTyxDQUFDLFNBQVIsR0FBcUIsR0FBQSxHQUFFLE9BQU8sQ0FBQyxTQUFWLEdBQXFCLE1BQXJCLEdBQTBCLElBQUMsQ0FBQSxJQUEzQixHQUFpQyxZQUR0RCxDQUFBO0FBQUEsVUFFQSxPQUFBLEdBQVUsSUFBQyxDQUFBLFdBQVcsQ0FBQyxNQUFiLENBQUEsQ0FGVixDQUFBO0FBQUEsVUFHQSxPQUFPLENBQUMsU0FBUixHQUFxQixHQUFBLEdBQUUsT0FBTyxDQUFDLFNBQVYsR0FBcUIsTUFBckIsR0FBMEIsSUFBQyxDQUFBLElBQTNCLEdBQWlDLE1BSHRELENBQUE7QUFBQSxVQUlBLEdBQUEsR0FBTSxFQUFFLENBQUMsWUFBSCxDQUFvQixJQUFBLEtBQUssQ0FBQyxTQUFOLENBQWdCLE9BQWhCLEVBQXlCLE1BQXpCLEVBQW9DLE9BQXBDLENBQXBCLENBQWdFLENBQUMsT0FBakUsQ0FBQSxDQUpOLENBQUE7QUFBQSxVQUtBLEdBQUEsR0FBTSxFQUFFLENBQUMsWUFBSCxDQUFvQixJQUFBLEtBQUssQ0FBQyxTQUFOLENBQWdCLE9BQWhCLEVBQXlCLEdBQXpCLEVBQThCLE1BQTlCLENBQXBCLENBQTRELENBQUMsT0FBN0QsQ0FBQSxDQUxOLENBQUE7QUFBQSxVQU1BLElBQUMsQ0FBQSxXQUFXLENBQUMsR0FBSSxDQUFBLElBQUMsQ0FBQSxJQUFELENBQWpCLEdBQTBCLEVBQUUsQ0FBQyxZQUFILENBQW9CLElBQUEsY0FBQSxDQUFlLE1BQWYsRUFBMEIsS0FBMUIsRUFBaUMsR0FBakMsRUFBc0MsR0FBdEMsQ0FBcEIsQ0FOMUIsQ0FBQTtBQUFBLFVBT0EsSUFBQyxDQUFBLFdBQVcsQ0FBQyxHQUFJLENBQUEsSUFBQyxDQUFBLElBQUQsQ0FBTSxDQUFDLFNBQXhCLENBQWtDLElBQUMsQ0FBQSxXQUFuQyxFQUFnRCxJQUFDLENBQUEsSUFBakQsQ0FQQSxDQUFBO0FBQUEsVUFRQSx1RUFBd0IsQ0FBQyxvQkFBRCxDQUFDLGVBQWdCLEVBQXpDLENBQTRDLENBQUMsSUFBN0MsQ0FBa0QsSUFBbEQsQ0FSQSxDQUFBO0FBQUEsVUFTQSxJQUFDLENBQUEsV0FBVyxDQUFDLEdBQUksQ0FBQSxJQUFDLENBQUEsSUFBRCxDQUFNLENBQUMsT0FBeEIsQ0FBQSxDQVRBLENBREY7U0FGQTtlQWFBLHNDQUFBLFNBQUEsRUFoQkY7T0FETztJQUFBLENBbEJULENBQUE7O0FBQUEsc0JBd0NBLE9BQUEsR0FBUyxTQUFBLEdBQUE7YUFDUDtBQUFBLFFBQ0UsTUFBQSxFQUFTLFNBRFg7QUFBQSxRQUVFLEtBQUEsRUFBUSxJQUFDLENBQUEsTUFBRCxDQUFBLENBRlY7QUFBQSxRQUdFLGFBQUEsRUFBZ0IsSUFBQyxDQUFBLFdBQVcsQ0FBQyxNQUFiLENBQUEsQ0FIbEI7QUFBQSxRQUlFLE1BQUEsRUFBUyxJQUFDLENBQUEsSUFKWjtRQURPO0lBQUEsQ0F4Q1QsQ0FBQTs7bUJBQUE7O0tBUG9CLEtBQUssQ0FBQyxVQTFENUIsQ0FBQTtBQUFBLEVBaUhBLE1BQU8sQ0FBQSxTQUFBLENBQVAsR0FBb0IsU0FBQyxJQUFELEdBQUE7QUFDbEIsUUFBQSxzQkFBQTtBQUFBLElBQ2tCLG1CQUFoQixjQURGLEVBRVUsV0FBUixNQUZGLEVBR1csWUFBVCxPQUhGLENBQUE7V0FLSSxJQUFBLE9BQUEsQ0FBUSxHQUFSLEVBQWEsV0FBYixFQUEwQixJQUExQixFQU5jO0VBQUEsQ0FqSHBCLENBQUE7QUFBQSxFQTZITTtBQU9KLGtDQUFBLENBQUE7O0FBQWEsSUFBQSxxQkFBQyxHQUFELEVBQU0sU0FBTixFQUFpQixHQUFqQixFQUFzQixJQUF0QixFQUE0QixJQUE1QixFQUFrQyxNQUFsQyxHQUFBO0FBQ1gsTUFBQSxJQUFHLG1CQUFBLElBQWUsYUFBbEI7QUFDRSxRQUFBLElBQUMsQ0FBQSxhQUFELENBQWUsV0FBZixFQUE0QixTQUE1QixDQUFBLENBQUE7QUFBQSxRQUNBLElBQUMsQ0FBQSxhQUFELENBQWUsS0FBZixFQUFzQixHQUF0QixDQURBLENBREY7T0FBQSxNQUFBO0FBSUUsUUFBQSxJQUFDLENBQUEsU0FBRCxHQUFhLEVBQUUsQ0FBQyxZQUFILENBQW9CLElBQUEsS0FBSyxDQUFDLFNBQU4sQ0FBZ0IsTUFBaEIsRUFBMkIsTUFBM0IsRUFBc0MsTUFBdEMsQ0FBcEIsQ0FBYixDQUFBO0FBQUEsUUFDQSxJQUFDLENBQUEsR0FBRCxHQUFhLEVBQUUsQ0FBQyxZQUFILENBQW9CLElBQUEsS0FBSyxDQUFDLFNBQU4sQ0FBZ0IsTUFBaEIsRUFBMkIsSUFBQyxDQUFBLFNBQTVCLEVBQXVDLE1BQXZDLENBQXBCLENBRGIsQ0FBQTtBQUFBLFFBRUEsSUFBQyxDQUFBLFNBQVMsQ0FBQyxPQUFYLEdBQXFCLElBQUMsQ0FBQSxHQUZ0QixDQUFBO0FBQUEsUUFHQSxJQUFDLENBQUEsU0FBUyxDQUFDLE9BQVgsQ0FBQSxDQUhBLENBQUE7QUFBQSxRQUlBLElBQUMsQ0FBQSxHQUFHLENBQUMsT0FBTCxDQUFBLENBSkEsQ0FKRjtPQUFBO0FBQUEsTUFTQSw2Q0FBTSxHQUFOLEVBQVcsSUFBWCxFQUFpQixJQUFqQixFQUF1QixNQUF2QixDQVRBLENBRFc7SUFBQSxDQUFiOztBQUFBLDBCQVlBLElBQUEsR0FBTSxhQVpOLENBQUE7O0FBQUEsMEJBa0JBLE9BQUEsR0FBUyxTQUFBLEdBQUE7QUFDUCxNQUFBLElBQUcsSUFBQyxDQUFBLHVCQUFELENBQUEsQ0FBSDtBQUNFLFFBQUEsSUFBQyxDQUFBLFNBQVMsQ0FBQyxTQUFYLENBQXFCLElBQXJCLENBQUEsQ0FBQTtBQUFBLFFBQ0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxTQUFMLENBQWUsSUFBZixDQURBLENBQUE7ZUFFQSwwQ0FBQSxTQUFBLEVBSEY7T0FBQSxNQUFBO2VBS0UsTUFMRjtPQURPO0lBQUEsQ0FsQlQsQ0FBQTs7QUFBQSwwQkEyQkEsZ0JBQUEsR0FBa0IsU0FBQSxHQUFBO2FBQ2hCLElBQUMsQ0FBQSxHQUFHLENBQUMsUUFEVztJQUFBLENBM0JsQixDQUFBOztBQUFBLDBCQStCQSxpQkFBQSxHQUFtQixTQUFBLEdBQUE7YUFDakIsSUFBQyxDQUFBLFNBQVMsQ0FBQyxRQURNO0lBQUEsQ0EvQm5CLENBQUE7O0FBQUEsMEJBb0NBLE9BQUEsR0FBUyxTQUFBLEdBQUE7QUFDUCxVQUFBLFNBQUE7QUFBQSxNQUFBLENBQUEsR0FBSSxJQUFDLENBQUEsU0FBUyxDQUFDLE9BQWYsQ0FBQTtBQUFBLE1BQ0EsTUFBQSxHQUFTLEVBRFQsQ0FBQTtBQUVBLGFBQU0sQ0FBQSxLQUFPLElBQUMsQ0FBQSxHQUFkLEdBQUE7QUFDRSxRQUFBLE1BQU0sQ0FBQyxJQUFQLENBQVksQ0FBWixDQUFBLENBQUE7QUFBQSxRQUNBLENBQUEsR0FBSSxDQUFDLENBQUMsT0FETixDQURGO01BQUEsQ0FGQTthQUtBLE9BTk87SUFBQSxDQXBDVCxDQUFBOztBQUFBLDBCQStDQSxzQkFBQSxHQUF3QixTQUFDLFFBQUQsR0FBQTtBQUN0QixVQUFBLENBQUE7QUFBQSxNQUFBLENBQUEsR0FBSSxJQUFDLENBQUEsU0FBUyxDQUFDLE9BQWYsQ0FBQTtBQUNBLE1BQUEsSUFBRyxDQUFDLFFBQUEsR0FBVyxDQUFYLElBQWdCLENBQUMsQ0FBQyxTQUFGLENBQUEsQ0FBakIsQ0FBQSxJQUFvQyxDQUFBLENBQUssQ0FBQSxZQUFhLEtBQUssQ0FBQyxTQUFwQixDQUEzQztBQUNFLGVBQU0sQ0FBQyxDQUFDLFNBQUYsQ0FBQSxDQUFBLElBQWtCLENBQUEsQ0FBSyxDQUFBLFlBQWEsS0FBSyxDQUFDLFNBQXBCLENBQTVCLEdBQUE7QUFFRSxVQUFBLENBQUEsR0FBSSxDQUFDLENBQUMsT0FBTixDQUZGO1FBQUEsQ0FBQTtBQUdBLGVBQU0sSUFBTixHQUFBO0FBRUUsVUFBQSxJQUFHLENBQUEsWUFBYSxLQUFLLENBQUMsU0FBdEI7QUFDRSxrQkFERjtXQUFBO0FBRUEsVUFBQSxJQUFHLFFBQUEsSUFBWSxDQUFaLElBQWtCLENBQUEsQ0FBSyxDQUFDLFNBQUYsQ0FBQSxDQUF6QjtBQUNFLGtCQURGO1dBRkE7QUFBQSxVQUlBLENBQUEsR0FBSSxDQUFDLENBQUMsT0FKTixDQUFBO0FBS0EsVUFBQSxJQUFHLENBQUEsQ0FBSyxDQUFDLFNBQUYsQ0FBQSxDQUFQO0FBQ0UsWUFBQSxRQUFBLElBQVksQ0FBWixDQURGO1dBUEY7UUFBQSxDQUpGO09BREE7YUFjQSxFQWZzQjtJQUFBLENBL0N4QixDQUFBOzt1QkFBQTs7S0FQd0IsS0FBSyxDQUFDLFVBN0hoQyxDQUFBO0FBQUEsRUE0TU07QUFNSixxQ0FBQSxDQUFBOztBQUFhLElBQUEsd0JBQUMsZUFBRCxFQUFrQixHQUFsQixFQUF1QixTQUF2QixFQUFrQyxHQUFsQyxFQUF1QyxJQUF2QyxFQUE2QyxJQUE3QyxFQUFtRCxNQUFuRCxHQUFBO0FBQ1gsTUFBQSxnREFBTSxHQUFOLEVBQVcsU0FBWCxFQUFzQixHQUF0QixFQUEyQixJQUEzQixFQUFpQyxJQUFqQyxFQUF1QyxNQUF2QyxDQUFBLENBQUE7QUFDQSxNQUFBLElBQUcsdUJBQUg7QUFDRSxRQUFBLElBQUMsQ0FBQSxPQUFELENBQVMsZUFBVCxDQUFBLENBREY7T0FGVztJQUFBLENBQWI7O0FBQUEsNkJBS0EsSUFBQSxHQUFNLGdCQUxOLENBQUE7O0FBQUEsNkJBT0EsV0FBQSxHQUFhLFNBQUEsR0FBQTtBQUNYLFVBQUEsaUJBQUE7QUFBQSxNQUFBLENBQUEsR0FBSSxJQUFDLENBQUEsU0FBTCxDQUFBO0FBQ0EsYUFBTSxTQUFOLEdBQUE7QUFDRSxRQUFBLENBQUMsQ0FBQyxXQUFGLENBQUEsQ0FBQSxDQUFBO0FBQUEsUUFDQSxDQUFBLEdBQUksQ0FBQyxDQUFDLE9BRE4sQ0FERjtNQUFBLENBREE7QUFLQSxNQUFBLElBQUcseUJBQUg7QUFDRTtBQUFBLGFBQUEsMkNBQUE7dUJBQUE7QUFDRSxVQUFBLENBQUMsQ0FBQyxXQUFGLENBQUEsQ0FBQSxDQURGO0FBQUEsU0FERjtPQUxBO2FBUUEsOENBQUEsRUFUVztJQUFBLENBUGIsQ0FBQTs7QUFBQSw2QkFrQkEsT0FBQSxHQUFTLFNBQUEsR0FBQTthQUNQLDBDQUFBLEVBRE87SUFBQSxDQWxCVCxDQUFBOztBQUFBLDZCQTJCQSxPQUFBLEdBQVMsU0FBQyxPQUFELEVBQVUsZUFBVixHQUFBO0FBQ1AsVUFBQSxLQUFBO0FBQUEsTUFBQSxDQUFBLEdBQUksSUFBQyxDQUFBLGdCQUFELENBQUEsQ0FBSixDQUFBO0FBQUEsTUFDQSxFQUFBLEdBQVMsSUFBQSxXQUFBLENBQVksT0FBWixFQUFxQixJQUFyQixFQUF3QixlQUF4QixFQUF5QyxDQUF6QyxFQUE0QyxDQUFDLENBQUMsT0FBOUMsQ0FEVCxDQUFBO0FBQUEsTUFFQSxFQUFFLENBQUMsWUFBSCxDQUFnQixFQUFoQixDQUFtQixDQUFDLE9BQXBCLENBQUEsQ0FGQSxDQUFBO2FBR0EsT0FKTztJQUFBLENBM0JULENBQUE7O0FBQUEsNkJBb0NBLFNBQUEsR0FBVyxTQUFDLE1BQUQsRUFBUyxhQUFULEdBQUE7QUFDVCxVQUFBLGlDQUFBO0FBQUEsTUFBQSxZQUFBLEdBQWUsSUFBZixDQUFBO0FBQUEsTUFDQSxJQUFDLENBQUEsRUFBRCxDQUFJLFFBQUosRUFBYyxTQUFDLEtBQUQsRUFBUSxFQUFSLEdBQUE7QUFDWixRQUFBLElBQUcsRUFBRSxDQUFDLE9BQUgsWUFBc0IsS0FBSyxDQUFDLFNBQS9CO2lCQUNFLFlBQVksQ0FBQyxNQUFNLENBQUMsU0FBcEIsQ0FBOEIsUUFBOUIsRUFBd0MsYUFBeEMsRUFBdUQsRUFBdkQsRUFERjtTQURZO01BQUEsQ0FBZCxDQURBLENBQUE7QUFBQSxNQUlBLElBQUMsQ0FBQSxFQUFELENBQUksUUFBSixFQUFjLFNBQUMsS0FBRCxFQUFRLEVBQVIsR0FBQTtBQUNaLFFBQUEsSUFBRyxZQUFBLEtBQWtCLElBQXJCO2lCQUNFLFlBQVksQ0FBQyxNQUFNLENBQUMsU0FBcEIsQ0FBOEIsUUFBOUIsRUFBd0MsYUFBeEMsRUFBdUQsRUFBdkQsRUFERjtTQURZO01BQUEsQ0FBZCxDQUpBLENBQUE7QUFBQSxNQVFBLG1CQUFBLEdBQXNCLFNBQUMsS0FBRCxFQUFRLEVBQVIsR0FBQTtBQUNwQixRQUFBLFlBQVksQ0FBQyxjQUFiLENBQTRCLGFBQTVCLEVBQTJDLG1CQUEzQyxDQUFBLENBQUE7ZUFDQSxZQUFZLENBQUMsTUFBTSxDQUFDLFNBQXBCLENBQThCLGFBQTlCLEVBQTZDLGFBQTdDLEVBQTRELEVBQTVELEVBRm9CO01BQUEsQ0FSdEIsQ0FBQTtBQUFBLE1BV0EsSUFBQyxDQUFBLEVBQUQsQ0FBSSxRQUFKLEVBQWMsbUJBQWQsQ0FYQSxDQUFBO2FBWUEsOENBQU0sTUFBTixFQWJTO0lBQUEsQ0FwQ1gsQ0FBQTs7QUFBQSw2QkF1REEsR0FBQSxHQUFLLFNBQUEsR0FBQTtBQUNILFVBQUEsQ0FBQTtBQUFBLE1BQUEsQ0FBQSxHQUFJLElBQUMsQ0FBQSxnQkFBRCxDQUFBLENBQUosQ0FBQTsyQ0FHQSxDQUFDLENBQUMsZUFKQztJQUFBLENBdkRMLENBQUE7O0FBQUEsNkJBZ0VBLE9BQUEsR0FBUyxTQUFBLEdBQUE7QUFDUCxVQUFBLElBQUE7QUFBQSxNQUFBLElBQUEsR0FDRTtBQUFBLFFBQ0UsTUFBQSxFQUFRLGdCQURWO0FBQUEsUUFFRSxLQUFBLEVBQVEsSUFBQyxDQUFBLE1BQUQsQ0FBQSxDQUZWO0FBQUEsUUFHRSxXQUFBLEVBQWMsSUFBQyxDQUFBLFNBQVMsQ0FBQyxNQUFYLENBQUEsQ0FIaEI7QUFBQSxRQUlFLEtBQUEsRUFBUSxJQUFDLENBQUEsR0FBRyxDQUFDLE1BQUwsQ0FBQSxDQUpWO09BREYsQ0FBQTtBQU9BLE1BQUEsSUFBRyxzQkFBQSxJQUFjLHNCQUFqQjtBQUNFLFFBQUEsSUFBSyxDQUFBLE1BQUEsQ0FBTCxHQUFlLElBQUMsQ0FBQSxPQUFPLENBQUMsTUFBVCxDQUFBLENBQWYsQ0FBQTtBQUFBLFFBQ0EsSUFBSyxDQUFBLE1BQUEsQ0FBTCxHQUFlLElBQUMsQ0FBQSxPQUFPLENBQUMsTUFBVCxDQUFBLENBRGYsQ0FERjtPQVBBO0FBVUEsTUFBQSxJQUFHLG1CQUFIO0FBQ0UsUUFBQSxJQUFLLENBQUEsUUFBQSxDQUFMLEdBQWlCLElBQUMsQ0FBQSxNQUFELENBQUEsQ0FBUyxDQUFDLE1BQVYsQ0FBQSxDQUFqQixDQURGO09BVkE7YUFZQSxLQWJPO0lBQUEsQ0FoRVQsQ0FBQTs7MEJBQUE7O0tBTjJCLFlBNU03QixDQUFBO0FBQUEsRUFpU0EsTUFBTyxDQUFBLGdCQUFBLENBQVAsR0FBMkIsU0FBQyxJQUFELEdBQUE7QUFDekIsUUFBQSxnREFBQTtBQUFBLElBQ2MsZUFBWixVQURGLEVBRVUsV0FBUixNQUZGLEVBR1UsWUFBUixPQUhGLEVBSVUsWUFBUixPQUpGLEVBS2EsY0FBWCxTQUxGLEVBTWdCLGlCQUFkLFlBTkYsRUFPVSxXQUFSLE1BUEYsQ0FBQTtXQVNJLElBQUEsY0FBQSxDQUFlLE9BQWYsRUFBd0IsR0FBeEIsRUFBNkIsU0FBN0IsRUFBd0MsR0FBeEMsRUFBNkMsSUFBN0MsRUFBbUQsSUFBbkQsRUFBeUQsTUFBekQsRUFWcUI7RUFBQSxDQWpTM0IsQ0FBQTtBQUFBLEVBbVRNO0FBT0osa0NBQUEsQ0FBQTs7QUFBYSxJQUFBLHFCQUFDLE9BQUQsRUFBVSxNQUFWLEVBQWtCLEdBQWxCLEVBQXVCLElBQXZCLEVBQTZCLElBQTdCLEVBQW1DLE1BQW5DLEdBQUE7QUFDWCxNQUFBLElBQUMsQ0FBQSxhQUFELENBQWUsU0FBZixFQUEwQixPQUExQixDQUFBLENBQUE7QUFBQSxNQUNBLElBQUMsQ0FBQSxhQUFELENBQWUsUUFBZixFQUF5QixNQUF6QixDQURBLENBQUE7QUFFQSxNQUFBLElBQUcsQ0FBQSxDQUFLLGNBQUEsSUFBVSxjQUFYLENBQVA7QUFDRSxjQUFVLElBQUEsS0FBQSxDQUFNLHVEQUFOLENBQVYsQ0FERjtPQUZBO0FBQUEsTUFJQSw2Q0FBTSxHQUFOLEVBQVcsSUFBWCxFQUFpQixJQUFqQixFQUF1QixNQUF2QixDQUpBLENBRFc7SUFBQSxDQUFiOztBQUFBLDBCQU9BLElBQUEsR0FBTSxhQVBOLENBQUE7O0FBQUEsMEJBWUEsR0FBQSxHQUFLLFNBQUEsR0FBQTthQUNILElBQUMsQ0FBQSxRQURFO0lBQUEsQ0FaTCxDQUFBOztBQUFBLDBCQWtCQSxPQUFBLEdBQVMsU0FBQyxPQUFELEdBQUE7YUFDUCxJQUFDLENBQUEsTUFBTSxDQUFDLE9BQVIsQ0FBZ0IsT0FBaEIsRUFETztJQUFBLENBbEJULENBQUE7O0FBQUEsMEJBcUJBLFdBQUEsR0FBYSxTQUFBLEdBQUE7QUFDWCxNQUFBLElBQUcsb0JBQUg7QUFDRSxRQUFBLElBQUMsQ0FBQSxPQUFPLENBQUMsV0FBVCxDQUFBLENBQUEsQ0FBQTtBQUFBLFFBQ0EsSUFBQyxDQUFBLE9BQU8sQ0FBQyxRQUFULENBQUEsQ0FEQSxDQURGO09BQUE7QUFBQSxNQUdBLElBQUMsQ0FBQSxPQUFELEdBQVcsSUFIWCxDQUFBO2FBSUEsOENBQUEsU0FBQSxFQUxXO0lBQUEsQ0FyQmIsQ0FBQTs7QUFBQSwwQkE0QkEsT0FBQSxHQUFTLFNBQUEsR0FBQTthQUNQLDBDQUFBLFNBQUEsRUFETztJQUFBLENBNUJULENBQUE7O0FBQUEsMEJBbUNBLE9BQUEsR0FBUyxTQUFBLEdBQUE7QUFDUCxVQUFBLGdCQUFBO0FBQUEsTUFBQSxJQUFHLENBQUEsSUFBSyxDQUFBLHVCQUFELENBQUEsQ0FBUDtBQUNFLGVBQU8sS0FBUCxDQURGO09BQUEsTUFBQTs7O2dCQUdVLENBQUUsa0JBQW1CLElBQUMsQ0FBQTs7U0FBOUI7QUFBQSxRQUlBLFVBQUEsR0FBYSx5Q0FBTSxvQkFBTixDQUpiLENBQUE7QUFLQSxRQUFBLElBQUcsVUFBSDtBQUNFLFVBQUEsSUFBRyxJQUFDLENBQUEsT0FBTyxDQUFDLElBQVQsS0FBaUIsV0FBakIsSUFBaUMsSUFBQyxDQUFBLE9BQU8sQ0FBQyxJQUFULEtBQW1CLFdBQXZEO0FBQ0UsWUFBQSxJQUFDLENBQUEsT0FBTyxDQUFDLFdBQVQsQ0FBQSxDQUFBLENBREY7V0FBQSxNQUVLLElBQUcsSUFBQyxDQUFBLE9BQU8sQ0FBQyxJQUFULEtBQW1CLFdBQXRCO0FBQ0gsWUFBQSxJQUFDLENBQUEsV0FBRCxDQUFBLENBQUEsQ0FERztXQUhQO1NBTEE7QUFXQSxlQUFPLFVBQVAsQ0FkRjtPQURPO0lBQUEsQ0FuQ1QsQ0FBQTs7QUFBQSwwQkF1REEsT0FBQSxHQUFTLFNBQUEsR0FBQTtBQUNQLFVBQUEsVUFBQTtBQUFBLE1BQUEsSUFBQSxHQUNFO0FBQUEsUUFDRSxNQUFBLEVBQVEsYUFEVjtBQUFBLFFBRUUsU0FBQSxzQ0FBbUIsQ0FBRSxNQUFWLENBQUEsVUFGYjtBQUFBLFFBR0UsZ0JBQUEsRUFBbUIsSUFBQyxDQUFBLE1BQU0sQ0FBQyxNQUFSLENBQUEsQ0FIckI7QUFBQSxRQUlFLE1BQUEsRUFBUSxJQUFDLENBQUEsT0FBTyxDQUFDLE1BQVQsQ0FBQSxDQUpWO0FBQUEsUUFLRSxNQUFBLEVBQVEsSUFBQyxDQUFBLE9BQU8sQ0FBQyxNQUFULENBQUEsQ0FMVjtBQUFBLFFBTUUsS0FBQSxFQUFRLElBQUMsQ0FBQSxNQUFELENBQUEsQ0FOVjtPQURGLENBQUE7QUFTQSxNQUFBLElBQUcscUJBQUEsSUFBYSxJQUFDLENBQUEsTUFBRCxLQUFhLElBQUMsQ0FBQSxPQUE5QjtBQUNFLFFBQUEsSUFBSyxDQUFBLFFBQUEsQ0FBTCxHQUFpQixJQUFDLENBQUEsTUFBTSxDQUFDLE1BQVIsQ0FBQSxDQUFqQixDQURGO09BVEE7YUFXQSxLQVpPO0lBQUEsQ0F2RFQsQ0FBQTs7dUJBQUE7O0tBUHdCLEtBQUssQ0FBQyxPQW5UaEMsQ0FBQTtBQUFBLEVBK1hBLE1BQU8sQ0FBQSxhQUFBLENBQVAsR0FBd0IsU0FBQyxJQUFELEdBQUE7QUFDdEIsUUFBQSx3Q0FBQTtBQUFBLElBQ2MsZUFBWixVQURGLEVBRXFCLGNBQW5CLGlCQUZGLEVBR1UsV0FBUixNQUhGLEVBSVUsWUFBUixPQUpGLEVBS1UsWUFBUixPQUxGLEVBTWEsY0FBWCxTQU5GLENBQUE7V0FRSSxJQUFBLFdBQUEsQ0FBWSxPQUFaLEVBQXFCLE1BQXJCLEVBQTZCLEdBQTdCLEVBQWtDLElBQWxDLEVBQXdDLElBQXhDLEVBQThDLE1BQTlDLEVBVGtCO0VBQUEsQ0EvWHhCLENBQUE7QUFBQSxFQTRZQSxLQUFNLENBQUEsYUFBQSxDQUFOLEdBQXVCLFdBNVl2QixDQUFBO0FBQUEsRUE2WUEsS0FBTSxDQUFBLFlBQUEsQ0FBTixHQUFzQixVQTdZdEIsQ0FBQTtBQUFBLEVBOFlBLEtBQU0sQ0FBQSxnQkFBQSxDQUFOLEdBQTBCLGNBOVkxQixDQUFBO0FBQUEsRUErWUEsS0FBTSxDQUFBLGFBQUEsQ0FBTixHQUF1QixXQS9ZdkIsQ0FBQTtTQWlaQSxZQWxaZTtBQUFBLENBRmpCLENBQUE7Ozs7QUNBQSxJQUFBLDhCQUFBO0VBQUE7aVNBQUE7O0FBQUEsOEJBQUEsR0FBaUMsT0FBQSxDQUFRLG1CQUFSLENBQWpDLENBQUE7O0FBQUEsTUFFTSxDQUFDLE9BQVAsR0FBaUIsU0FBQyxFQUFELEdBQUE7QUFDZixNQUFBLGlFQUFBO0FBQUEsRUFBQSxnQkFBQSxHQUFtQiw4QkFBQSxDQUErQixFQUEvQixDQUFuQixDQUFBO0FBQUEsRUFDQSxLQUFBLEdBQVEsZ0JBQWdCLENBQUMsS0FEekIsQ0FBQTtBQUFBLEVBRUEsTUFBQSxHQUFTLGdCQUFnQixDQUFDLE1BRjFCLENBQUE7QUFBQSxFQVNNO0FBQU4saUNBQUEsQ0FBQTs7OztLQUFBOztzQkFBQTs7S0FBeUIsS0FBSyxDQUFDLE9BVC9CLENBQUE7QUFBQSxFQVVBLE1BQU8sQ0FBQSxZQUFBLENBQVAsR0FBdUIsTUFBTyxDQUFBLFFBQUEsQ0FWOUIsQ0FBQTtBQUFBLEVBZ0JNO0FBS0osaUNBQUEsQ0FBQTs7QUFBYSxJQUFBLG9CQUFFLE9BQUYsRUFBVyxHQUFYLEVBQWdCLElBQWhCLEVBQXNCLElBQXRCLEVBQTRCLE1BQTVCLEdBQUE7QUFDWCxNQURZLElBQUMsQ0FBQSxVQUFBLE9BQ2IsQ0FBQTtBQUFBLE1BQUEsSUFBRyxDQUFBLENBQUssY0FBQSxJQUFVLGNBQVgsQ0FBUDtBQUNFLGNBQVUsSUFBQSxLQUFBLENBQU0sc0RBQU4sQ0FBVixDQURGO09BQUE7QUFBQSxNQUVBLDRDQUFNLEdBQU4sRUFBVyxJQUFYLEVBQWlCLElBQWpCLEVBQXVCLE1BQXZCLENBRkEsQ0FEVztJQUFBLENBQWI7O0FBQUEseUJBS0EsSUFBQSxHQUFNLFlBTE4sQ0FBQTs7QUFBQSx5QkFVQSxTQUFBLEdBQVcsU0FBQSxHQUFBO0FBQ1QsTUFBQSxJQUFHLElBQUMsQ0FBQSxTQUFELENBQUEsQ0FBSDtlQUNFLEVBREY7T0FBQSxNQUFBO2VBR0UsSUFBQyxDQUFBLE9BQU8sQ0FBQyxPQUhYO09BRFM7SUFBQSxDQVZYLENBQUE7O0FBQUEseUJBZ0JBLFdBQUEsR0FBYSxTQUFBLEdBQUE7QUFDWCxNQUFBLElBQUMsQ0FBQSxPQUFELEdBQVcsSUFBWCxDQUFBO2FBQ0EsNkNBQUEsU0FBQSxFQUZXO0lBQUEsQ0FoQmIsQ0FBQTs7QUFBQSx5QkF5QkEsR0FBQSxHQUFLLFNBQUMsZ0JBQUQsR0FBQTtBQUNILE1BQUEsSUFBRyxJQUFDLENBQUEsU0FBRCxDQUFBLENBQUEsSUFBb0Isc0JBQXZCO2VBQ0UsR0FERjtPQUFBLE1BQUE7ZUFHRSxJQUFDLENBQUEsUUFISDtPQURHO0lBQUEsQ0F6QkwsQ0FBQTs7QUFBQSx5QkFtQ0EsT0FBQSxHQUFTLFNBQUEsR0FBQTtBQUNQLFVBQUEsSUFBQTtBQUFBLE1BQUEsSUFBQSxHQUNFO0FBQUEsUUFDRSxNQUFBLEVBQVEsWUFEVjtBQUFBLFFBRUUsU0FBQSxFQUFXLElBQUMsQ0FBQSxPQUZkO0FBQUEsUUFHRSxLQUFBLEVBQVEsSUFBQyxDQUFBLE1BQUQsQ0FBQSxDQUhWO0FBQUEsUUFJRSxNQUFBLEVBQVEsSUFBQyxDQUFBLE9BQU8sQ0FBQyxNQUFULENBQUEsQ0FKVjtBQUFBLFFBS0UsTUFBQSxFQUFRLElBQUMsQ0FBQSxPQUFPLENBQUMsTUFBVCxDQUFBLENBTFY7T0FERixDQUFBO0FBUUEsTUFBQSxJQUFHLElBQUMsQ0FBQSxNQUFELEtBQWEsSUFBQyxDQUFBLE9BQWpCO0FBQ0UsUUFBQSxJQUFLLENBQUEsUUFBQSxDQUFMLEdBQWlCLElBQUMsQ0FBQSxNQUFNLENBQUMsTUFBUixDQUFBLENBQWpCLENBREY7T0FSQTthQVVBLEtBWE87SUFBQSxDQW5DVCxDQUFBOztzQkFBQTs7S0FMdUIsS0FBSyxDQUFDLE9BaEIvQixDQUFBO0FBQUEsRUFxRUEsTUFBTyxDQUFBLFlBQUEsQ0FBUCxHQUF1QixTQUFDLElBQUQsR0FBQTtBQUNyQixRQUFBLGdDQUFBO0FBQUEsSUFDYyxlQUFaLFVBREYsRUFFVSxXQUFSLE1BRkYsRUFHVSxZQUFSLE9BSEYsRUFJVSxZQUFSLE9BSkYsRUFLYSxjQUFYLFNBTEYsQ0FBQTtXQU9JLElBQUEsVUFBQSxDQUFXLE9BQVgsRUFBb0IsR0FBcEIsRUFBeUIsSUFBekIsRUFBK0IsSUFBL0IsRUFBcUMsTUFBckMsRUFSaUI7RUFBQSxDQXJFdkIsQ0FBQTtBQUFBLEVBbUZNO0FBTUosK0JBQUEsQ0FBQTs7QUFBYSxJQUFBLGtCQUFDLEdBQUQsRUFBTSxTQUFOLEVBQWlCLEdBQWpCLEVBQXNCLElBQXRCLEVBQTRCLElBQTVCLEVBQWtDLE1BQWxDLEdBQUE7QUFDWCxNQUFBLDBDQUFNLEdBQU4sRUFBVyxTQUFYLEVBQXNCLEdBQXRCLEVBQTJCLElBQTNCLEVBQWlDLElBQWpDLEVBQXVDLE1BQXZDLENBQUEsQ0FEVztJQUFBLENBQWI7O0FBQUEsdUJBYUEsSUFBQSxHQUFNLFVBYk4sQ0FBQTs7QUFBQSx1QkFlQSxXQUFBLEdBQWEsU0FBQSxHQUFBO0FBQ1gsVUFBQSxDQUFBO0FBQUEsTUFBQSxDQUFBLEdBQUksSUFBQyxDQUFBLFNBQUwsQ0FBQTtBQUNBLGFBQU0sU0FBTixHQUFBO0FBQ0UsUUFBQSxDQUFDLENBQUMsV0FBRixDQUFBLENBQUEsQ0FBQTtBQUFBLFFBQ0EsQ0FBQSxHQUFJLENBQUMsQ0FBQyxPQUROLENBREY7TUFBQSxDQURBO2FBSUEsd0NBQUEsRUFMVztJQUFBLENBZmIsQ0FBQTs7QUFBQSx1QkFzQkEsT0FBQSxHQUFTLFNBQUEsR0FBQTthQUNQLG9DQUFBLEVBRE87SUFBQSxDQXRCVCxDQUFBOztBQUFBLHVCQXlCQSxJQUFBLEdBQU0sU0FBQyxPQUFELEdBQUE7YUFDSixJQUFDLENBQUEsV0FBRCxDQUFhLElBQUMsQ0FBQSxHQUFHLENBQUMsT0FBbEIsRUFBMkIsT0FBM0IsRUFESTtJQUFBLENBekJOLENBQUE7O0FBQUEsdUJBNEJBLFdBQUEsR0FBYSxTQUFDLElBQUQsRUFBTyxPQUFQLEdBQUE7QUFDWCxVQUFBLHNCQUFBO0FBQUEsYUFBTSxJQUFJLENBQUMsU0FBTCxDQUFBLENBQU4sR0FBQTtBQUNFLFFBQUEsSUFBQSxHQUFPLElBQUksQ0FBQyxPQUFaLENBREY7TUFBQSxDQUFBO0FBQUEsTUFFQSxLQUFBLEdBQVEsSUFBSSxDQUFDLE9BRmIsQ0FBQTtBQUdBLE1BQUEsSUFBRyxvQkFBSDtBQUNFLFFBQUEsRUFBQSxHQUFTLElBQUEsVUFBQSxDQUFXLE9BQVgsRUFBb0IsTUFBcEIsRUFBK0IsSUFBL0IsRUFBcUMsS0FBckMsQ0FBVCxDQUFBO0FBQUEsUUFDQSxFQUFFLENBQUMsWUFBSCxDQUFnQixFQUFoQixDQUFtQixDQUFDLE9BQXBCLENBQUEsQ0FEQSxDQURGO09BQUEsTUFBQTtBQUlFLGFBQUEsOENBQUE7MEJBQUE7QUFDRSxVQUFBLEVBQUEsR0FBUyxJQUFBLFVBQUEsQ0FBVyxDQUFYLEVBQWMsTUFBZCxFQUF5QixJQUF6QixFQUErQixLQUEvQixDQUFULENBQUE7QUFBQSxVQUNBLEVBQUUsQ0FBQyxZQUFILENBQWdCLEVBQWhCLENBQW1CLENBQUMsT0FBcEIsQ0FBQSxDQURBLENBQUE7QUFBQSxVQUVBLElBQUEsR0FBTyxFQUZQLENBREY7QUFBQSxTQUpGO09BSEE7YUFXQSxLQVpXO0lBQUEsQ0E1QmIsQ0FBQTs7QUFBQSx1QkE4Q0EsVUFBQSxHQUFZLFNBQUMsUUFBRCxFQUFXLE9BQVgsR0FBQTtBQUVWLFVBQUEsU0FBQTtBQUFBLE1BQUEsR0FBQSxHQUFNLElBQUMsQ0FBQSxzQkFBRCxDQUF3QixRQUF4QixDQUFOLENBQUE7QUFBQSxNQUNBLElBQUEsR0FBTyxHQUFHLENBQUMsT0FEWCxDQUFBO2FBRUEsSUFBQyxDQUFBLFdBQUQsQ0FBYSxJQUFiLEVBQW1CLE9BQW5CLEVBSlU7SUFBQSxDQTlDWixDQUFBOztBQUFBLHVCQXlEQSxVQUFBLEdBQVksU0FBQyxRQUFELEVBQVcsTUFBWCxHQUFBO0FBQ1YsVUFBQSx1QkFBQTtBQUFBLE1BQUEsQ0FBQSxHQUFJLElBQUMsQ0FBQSxzQkFBRCxDQUF3QixRQUF4QixDQUFKLENBQUE7QUFBQSxNQUVBLFVBQUEsR0FBYSxFQUZiLENBQUE7QUFHQSxXQUFTLGtGQUFULEdBQUE7QUFDRSxRQUFBLElBQUcsQ0FBQSxZQUFhLEtBQUssQ0FBQyxTQUF0QjtBQUNFLGdCQURGO1NBQUE7QUFBQSxRQUVBLENBQUEsR0FBSSxFQUFFLENBQUMsWUFBSCxDQUFvQixJQUFBLFVBQUEsQ0FBVyxNQUFYLEVBQXNCLENBQXRCLENBQXBCLENBQTRDLENBQUMsT0FBN0MsQ0FBQSxDQUZKLENBQUE7QUFBQSxRQUdBLENBQUEsR0FBSSxDQUFDLENBQUMsT0FITixDQUFBO0FBSUEsZUFBTSxDQUFBLENBQUssQ0FBQSxZQUFhLEtBQUssQ0FBQyxTQUFwQixDQUFKLElBQXVDLENBQUMsQ0FBQyxTQUFGLENBQUEsQ0FBN0MsR0FBQTtBQUNFLFVBQUEsQ0FBQSxHQUFJLENBQUMsQ0FBQyxPQUFOLENBREY7UUFBQSxDQUpBO0FBQUEsUUFNQSxVQUFVLENBQUMsSUFBWCxDQUFnQixDQUFDLENBQUMsT0FBRixDQUFBLENBQWhCLENBTkEsQ0FERjtBQUFBLE9BSEE7YUFXQSxLQVpVO0lBQUEsQ0F6RFosQ0FBQTs7QUFBQSx1QkE2RUEsV0FBQSxHQUFhLFNBQUMsSUFBRCxHQUFBO0FBR1gsVUFBQSxJQUFBO0FBQUEsTUFBQSxJQUFHLDRCQUFIO0FBQ0UsUUFBQSxJQUFBLEdBQU8sRUFBRSxDQUFDLFlBQUgsQ0FBb0IsSUFBQSxRQUFBLENBQVMsTUFBVCxDQUFwQixDQUF1QyxDQUFDLE9BQXhDLENBQUEsQ0FBUCxDQUFBO0FBQUEsUUFDQSxJQUFJLENBQUMsVUFBTCxDQUFnQixDQUFoQixFQUFtQixJQUFuQixDQURBLENBQUE7QUFBQSxRQUVBLElBQUMsQ0FBQSxlQUFlLENBQUMsT0FBakIsQ0FBeUIsSUFBekIsQ0FGQSxDQUFBO2VBR0EsS0FKRjtPQUFBLE1BQUE7QUFNRSxjQUFVLElBQUEsS0FBQSxDQUFNLDREQUFOLENBQVYsQ0FORjtPQUhXO0lBQUEsQ0E3RWIsQ0FBQTs7QUFBQSx1QkE0RkEsR0FBQSxHQUFLLFNBQUEsR0FBQTtBQUNILFVBQUEsSUFBQTtBQUFBLE1BQUEsQ0FBQTs7QUFBSTtBQUFBO2FBQUEsMkNBQUE7dUJBQUE7QUFDRixVQUFBLElBQUcsYUFBSDswQkFDRSxDQUFDLENBQUMsR0FBRixDQUFBLEdBREY7V0FBQSxNQUFBOzBCQUdFLElBSEY7V0FERTtBQUFBOzttQkFBSixDQUFBO2FBS0EsQ0FBQyxDQUFDLElBQUYsQ0FBTyxFQUFQLEVBTkc7SUFBQSxDQTVGTCxDQUFBOztBQUFBLHVCQXdHQSxRQUFBLEdBQVUsU0FBQSxHQUFBO2FBQ1IsSUFBQyxDQUFBLEdBQUQsQ0FBQSxFQURRO0lBQUEsQ0F4R1YsQ0FBQTs7QUFBQSx1QkFnSEEsaUJBQUEsR0FBbUIsU0FBQyxFQUFELEdBQUE7QUFDakIsTUFBQSxJQUFDLENBQUEsYUFBRCxDQUFlLGlCQUFmLEVBQWtDLEVBQWxDLENBQUEsQ0FBQTtBQUFBLE1BQ0EsSUFBQyxDQUFBLHVCQUFELENBQUEsQ0FEQSxDQUFBO0FBQUEsTUFFQSxJQUFDLENBQUEsRUFBRCxDQUFJLFFBQUosRUFBYyxDQUFBLFNBQUEsS0FBQSxHQUFBO2VBQUEsU0FBQyxLQUFELEVBQVEsR0FBUixHQUFBO0FBQ1osY0FBQSxJQUFBOzhEQUFnQixDQUFFLFlBQWxCLENBQStCLEtBQS9CLEVBQWtDLFFBQWxDLEVBQTRDLEdBQTVDLFdBRFk7UUFBQSxFQUFBO01BQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQUFkLENBRkEsQ0FBQTthQUlBLElBQUMsQ0FBQSxFQUFELENBQUksUUFBSixFQUFjLENBQUEsU0FBQSxLQUFBLEdBQUE7ZUFBQSxTQUFDLEtBQUQsRUFBUSxHQUFSLEVBQWEsR0FBYixHQUFBO0FBQ1osY0FBQSxJQUFBOzhEQUFnQixDQUFFLFlBQWxCLENBQStCLEtBQS9CLEVBQWtDLFFBQWxDLEVBQTRDLEdBQTVDLFdBRFk7UUFBQSxFQUFBO01BQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQUFkLEVBTGlCO0lBQUEsQ0FoSG5CLENBQUE7O0FBQUEsdUJBOEhBLElBQUEsR0FBTSxTQUFDLFNBQUQsR0FBQTtBQUNKLFVBQUEsSUFBQTtBQUFBLE1BQUEsSUFBQSxHQUFPLElBQVAsQ0FBQTtBQUFBLE1BQ0EsU0FBUyxDQUFDLEtBQVYsR0FBa0IsSUFBQyxDQUFBLEdBQUQsQ0FBQSxDQURsQixDQUFBO0FBQUEsTUFHQSxJQUFDLENBQUEsRUFBRCxDQUFJLFFBQUosRUFBYyxTQUFDLEtBQUQsRUFBUSxFQUFSLEdBQUE7QUFDWixZQUFBLHVCQUFBO0FBQUEsUUFBQSxLQUFBLEdBQVEsRUFBRSxDQUFDLFdBQUgsQ0FBQSxDQUFSLENBQUE7QUFBQSxRQUNBLEdBQUEsR0FBTSxTQUFDLE1BQUQsR0FBQTtBQUNKLFVBQUEsSUFBRyxNQUFBLElBQVUsS0FBYjttQkFDRSxPQURGO1dBQUEsTUFBQTtBQUdFLFlBQUEsTUFBQSxJQUFVLENBQVYsQ0FBQTttQkFDQSxPQUpGO1dBREk7UUFBQSxDQUROLENBQUE7QUFBQSxRQU9BLElBQUEsR0FBTyxHQUFBLENBQUksU0FBUyxDQUFDLGNBQWQsQ0FQUCxDQUFBO0FBQUEsUUFRQSxLQUFBLEdBQVEsR0FBQSxDQUFJLFNBQVMsQ0FBQyxZQUFkLENBUlIsQ0FBQTtBQUFBLFFBVUEsU0FBUyxDQUFDLEtBQVYsR0FBa0IsSUFBSSxDQUFDLEdBQUwsQ0FBQSxDQVZsQixDQUFBO2VBV0EsU0FBUyxDQUFDLGlCQUFWLENBQTRCLElBQTVCLEVBQWtDLEtBQWxDLEVBWlk7TUFBQSxDQUFkLENBSEEsQ0FBQTtBQUFBLE1Ba0JBLElBQUMsQ0FBQSxFQUFELENBQUksUUFBSixFQUFjLFNBQUMsS0FBRCxFQUFRLEVBQVIsR0FBQTtBQUNaLFlBQUEsdUJBQUE7QUFBQSxRQUFBLEtBQUEsR0FBUSxFQUFFLENBQUMsV0FBSCxDQUFBLENBQVIsQ0FBQTtBQUFBLFFBQ0EsR0FBQSxHQUFNLFNBQUMsTUFBRCxHQUFBO0FBQ0osVUFBQSxJQUFHLE1BQUEsR0FBUyxLQUFaO21CQUNFLE9BREY7V0FBQSxNQUFBO0FBR0UsWUFBQSxNQUFBLElBQVUsQ0FBVixDQUFBO21CQUNBLE9BSkY7V0FESTtRQUFBLENBRE4sQ0FBQTtBQUFBLFFBT0EsSUFBQSxHQUFPLEdBQUEsQ0FBSSxTQUFTLENBQUMsY0FBZCxDQVBQLENBQUE7QUFBQSxRQVFBLEtBQUEsR0FBUSxHQUFBLENBQUksU0FBUyxDQUFDLFlBQWQsQ0FSUixDQUFBO0FBQUEsUUFVQSxTQUFTLENBQUMsS0FBVixHQUFrQixJQUFJLENBQUMsR0FBTCxDQUFBLENBVmxCLENBQUE7ZUFXQSxTQUFTLENBQUMsaUJBQVYsQ0FBNEIsSUFBNUIsRUFBa0MsS0FBbEMsRUFaWTtNQUFBLENBQWQsQ0FsQkEsQ0FBQTtBQUFBLE1BaUNBLFNBQVMsQ0FBQyxVQUFWLEdBQXVCLFNBQUMsS0FBRCxHQUFBO0FBQ3JCLFlBQUEsd0JBQUE7QUFBQSxRQUFBLElBQUEsR0FBTyxJQUFQLENBQUE7QUFDQSxRQUFBLElBQUcsaUJBQUg7QUFDRSxVQUFBLElBQUcsS0FBSyxDQUFDLFFBQU4sS0FBa0IsRUFBckI7QUFDRSxZQUFBLElBQUEsR0FBTyxHQUFQLENBREY7V0FBQSxNQUVLLElBQUcsS0FBSyxDQUFDLE9BQU4sS0FBaUIsRUFBcEI7QUFDSCxZQUFBLElBQUEsR0FBTyxJQUFQLENBREc7V0FBQSxNQUFBO0FBR0gsWUFBQSxJQUFBLEdBQU8sS0FBSyxDQUFDLEdBQWIsQ0FIRztXQUhQO1NBQUEsTUFBQTtBQVFFLFVBQUEsSUFBQSxHQUFPLE1BQU0sQ0FBQyxZQUFQLENBQW9CLEtBQUssQ0FBQyxPQUExQixDQUFQLENBUkY7U0FEQTtBQVVBLFFBQUEsSUFBRyxJQUFJLENBQUMsTUFBTCxHQUFjLENBQWpCO0FBQ0UsVUFBQSxHQUFBLEdBQU0sSUFBSSxDQUFDLEdBQUwsQ0FBUyxTQUFTLENBQUMsY0FBbkIsRUFBbUMsU0FBUyxDQUFDLFlBQTdDLENBQU4sQ0FBQTtBQUFBLFVBQ0EsSUFBQSxHQUFPLElBQUksQ0FBQyxHQUFMLENBQVMsU0FBUyxDQUFDLFlBQVYsR0FBeUIsU0FBUyxDQUFDLGNBQTVDLENBRFAsQ0FBQTtBQUFBLFVBRUEsSUFBSSxDQUFDLFVBQUwsQ0FBaUIsR0FBakIsRUFBdUIsSUFBdkIsQ0FGQSxDQUFBO0FBQUEsVUFHQSxJQUFJLENBQUMsVUFBTCxDQUFnQixHQUFoQixFQUFxQixJQUFyQixDQUhBLENBQUE7QUFBQSxVQUlBLE9BQUEsR0FBVSxHQUFBLEdBQU0sSUFBSSxDQUFDLE1BSnJCLENBQUE7QUFBQSxVQUtBLFNBQVMsQ0FBQyxpQkFBVixDQUE0QixPQUE1QixFQUFxQyxPQUFyQyxDQUxBLENBQUE7aUJBTUEsS0FBSyxDQUFDLGNBQU4sQ0FBQSxFQVBGO1NBQUEsTUFBQTtpQkFTRSxLQUFLLENBQUMsY0FBTixDQUFBLEVBVEY7U0FYcUI7TUFBQSxDQWpDdkIsQ0FBQTtBQUFBLE1BdURBLFNBQVMsQ0FBQyxPQUFWLEdBQW9CLFNBQUMsS0FBRCxHQUFBO2VBQ2xCLEtBQUssQ0FBQyxjQUFOLENBQUEsRUFEa0I7TUFBQSxDQXZEcEIsQ0FBQTtBQUFBLE1BeURBLFNBQVMsQ0FBQyxLQUFWLEdBQWtCLFNBQUMsS0FBRCxHQUFBO2VBQ2hCLEtBQUssQ0FBQyxjQUFOLENBQUEsRUFEZ0I7TUFBQSxDQXpEbEIsQ0FBQTthQW1FQSxTQUFTLENBQUMsU0FBVixHQUFzQixTQUFDLEtBQUQsR0FBQTtBQUNwQixZQUFBLG1DQUFBO0FBQUEsUUFBQSxHQUFBLEdBQU0sSUFBSSxDQUFDLEdBQUwsQ0FBUyxTQUFTLENBQUMsY0FBbkIsRUFBbUMsU0FBUyxDQUFDLFlBQTdDLENBQU4sQ0FBQTtBQUFBLFFBQ0EsSUFBQSxHQUFPLElBQUksQ0FBQyxHQUFMLENBQVMsU0FBUyxDQUFDLFlBQVYsR0FBeUIsU0FBUyxDQUFDLGNBQTVDLENBRFAsQ0FBQTtBQUVBLFFBQUEsSUFBRyx1QkFBQSxJQUFtQixLQUFLLENBQUMsT0FBTixLQUFpQixDQUF2QztBQUNFLFVBQUEsSUFBRyxJQUFBLEdBQU8sQ0FBVjtBQUNFLFlBQUEsSUFBSSxDQUFDLFVBQUwsQ0FBZ0IsR0FBaEIsRUFBcUIsSUFBckIsQ0FBQSxDQUFBO0FBQUEsWUFDQSxTQUFTLENBQUMsaUJBQVYsQ0FBNEIsR0FBNUIsRUFBaUMsR0FBakMsQ0FEQSxDQURGO1dBQUEsTUFBQTtBQUlFLFlBQUEsSUFBRyx1QkFBQSxJQUFtQixLQUFLLENBQUMsT0FBNUI7QUFDRSxjQUFBLEdBQUEsR0FBTSxTQUFTLENBQUMsS0FBaEIsQ0FBQTtBQUFBLGNBQ0EsT0FBQSxHQUFVLEdBRFYsQ0FBQTtBQUFBLGNBRUEsVUFBQSxHQUFhLENBRmIsQ0FBQTtBQUdBLGNBQUEsSUFBRyxHQUFBLEdBQU0sQ0FBVDtBQUNFLGdCQUFBLE9BQUEsRUFBQSxDQUFBO0FBQUEsZ0JBQ0EsVUFBQSxFQURBLENBREY7ZUFIQTtBQU1BLHFCQUFNLE9BQUEsR0FBVSxDQUFWLElBQWdCLEdBQUksQ0FBQSxPQUFBLENBQUosS0FBa0IsR0FBbEMsSUFBMEMsR0FBSSxDQUFBLE9BQUEsQ0FBSixLQUFrQixJQUFsRSxHQUFBO0FBQ0UsZ0JBQUEsT0FBQSxFQUFBLENBQUE7QUFBQSxnQkFDQSxVQUFBLEVBREEsQ0FERjtjQUFBLENBTkE7QUFBQSxjQVNBLElBQUksQ0FBQyxVQUFMLENBQWdCLE9BQWhCLEVBQTBCLEdBQUEsR0FBSSxPQUE5QixDQVRBLENBQUE7QUFBQSxjQVVBLFNBQVMsQ0FBQyxpQkFBVixDQUE0QixPQUE1QixFQUFxQyxPQUFyQyxDQVZBLENBREY7YUFBQSxNQUFBO0FBYUUsY0FBQSxJQUFJLENBQUMsVUFBTCxDQUFpQixHQUFBLEdBQUksQ0FBckIsRUFBeUIsQ0FBekIsQ0FBQSxDQWJGO2FBSkY7V0FBQTtpQkFrQkEsS0FBSyxDQUFDLGNBQU4sQ0FBQSxFQW5CRjtTQUFBLE1Bb0JLLElBQUcsdUJBQUEsSUFBbUIsS0FBSyxDQUFDLE9BQU4sS0FBaUIsRUFBdkM7QUFDSCxVQUFBLElBQUcsSUFBQSxHQUFPLENBQVY7QUFDRSxZQUFBLElBQUksQ0FBQyxVQUFMLENBQWdCLEdBQWhCLEVBQXFCLElBQXJCLENBQUEsQ0FBQTtBQUFBLFlBQ0EsU0FBUyxDQUFDLGlCQUFWLENBQTRCLEdBQTVCLEVBQWlDLEdBQWpDLENBREEsQ0FERjtXQUFBLE1BQUE7QUFJRSxZQUFBLElBQUksQ0FBQyxVQUFMLENBQWdCLEdBQWhCLEVBQXFCLENBQXJCLENBQUEsQ0FBQTtBQUFBLFlBQ0EsU0FBUyxDQUFDLGlCQUFWLENBQTRCLEdBQTVCLEVBQWlDLEdBQWpDLENBREEsQ0FKRjtXQUFBO2lCQU1BLEtBQUssQ0FBQyxjQUFOLENBQUEsRUFQRztTQXZCZTtNQUFBLEVBcEVsQjtJQUFBLENBOUhOLENBQUE7O0FBQUEsdUJBd09BLE9BQUEsR0FBUyxTQUFBLEdBQUE7QUFDUCxVQUFBLElBQUE7QUFBQSxNQUFBLElBQUEsR0FBTztBQUFBLFFBQ0wsTUFBQSxFQUFRLFVBREg7QUFBQSxRQUVMLEtBQUEsRUFBUSxJQUFDLENBQUEsTUFBRCxDQUFBLENBRkg7QUFBQSxRQUdMLFdBQUEsRUFBYyxJQUFDLENBQUEsU0FBUyxDQUFDLE1BQVgsQ0FBQSxDQUhUO0FBQUEsUUFJTCxLQUFBLEVBQVEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxNQUFMLENBQUEsQ0FKSDtPQUFQLENBQUE7QUFNQSxNQUFBLElBQUcsb0JBQUg7QUFDRSxRQUFBLElBQUssQ0FBQSxNQUFBLENBQUwsR0FBZSxJQUFDLENBQUEsT0FBTyxDQUFDLE1BQVQsQ0FBQSxDQUFmLENBREY7T0FOQTtBQVFBLE1BQUEsSUFBRyxvQkFBSDtBQUNFLFFBQUEsSUFBSyxDQUFBLE1BQUEsQ0FBTCxHQUFlLElBQUMsQ0FBQSxPQUFPLENBQUMsTUFBVCxDQUFBLENBQWYsQ0FERjtPQVJBO0FBVUEsTUFBQSxJQUFHLG1CQUFIO0FBQ0UsUUFBQSxJQUFLLENBQUEsUUFBQSxDQUFMLEdBQWlCLElBQUMsQ0FBQSxNQUFELENBQUEsQ0FBUyxDQUFDLE1BQVYsQ0FBQSxDQUFqQixDQURGO09BVkE7YUFZQSxLQWJPO0lBQUEsQ0F4T1QsQ0FBQTs7b0JBQUE7O0tBTnFCLEtBQUssQ0FBQyxZQW5GN0IsQ0FBQTtBQUFBLEVBZ1ZBLE1BQU8sQ0FBQSxVQUFBLENBQVAsR0FBcUIsU0FBQyxJQUFELEdBQUE7QUFDbkIsUUFBQSx1Q0FBQTtBQUFBLElBQ1UsV0FBUixNQURGLEVBRWdCLGlCQUFkLFlBRkYsRUFHVSxXQUFSLE1BSEYsRUFJVSxZQUFSLE9BSkYsRUFLVSxZQUFSLE9BTEYsRUFNYSxjQUFYLFNBTkYsQ0FBQTtXQVFJLElBQUEsUUFBQSxDQUFTLEdBQVQsRUFBYyxTQUFkLEVBQXlCLEdBQXpCLEVBQThCLElBQTlCLEVBQW9DLElBQXBDLEVBQTBDLE1BQTFDLEVBVGU7RUFBQSxDQWhWckIsQ0FBQTtBQUFBLEVBMlZBLEtBQU0sQ0FBQSxZQUFBLENBQU4sR0FBc0IsVUEzVnRCLENBQUE7QUFBQSxFQTRWQSxLQUFNLENBQUEsWUFBQSxDQUFOLEdBQXNCLFVBNVZ0QixDQUFBO0FBQUEsRUE2VkEsS0FBTSxDQUFBLFVBQUEsQ0FBTixHQUFvQixRQTdWcEIsQ0FBQTtTQThWQSxpQkEvVmU7QUFBQSxDQUZqQixDQUFBOzs7O0FDQ0EsSUFBQSx3QkFBQTtFQUFBO2lTQUFBOztBQUFBLHdCQUFBLEdBQTJCLE9BQUEsQ0FBUSxhQUFSLENBQTNCLENBQUE7OztFQUVBLE9BQU8sQ0FBRSxTQUFTLENBQUMsTUFBbkIsR0FBNEIsU0FBQyxNQUFELEVBQVMsQ0FBVCxHQUFBO0FBQzFCLFFBQUEsS0FBQTtBQUFBLElBQUEsS0FBQSxHQUFRLElBQUUsQ0FBQSxNQUFBLENBQVYsQ0FBQTtBQUNBLElBQUEsSUFBRyxhQUFIO2FBQ0UsSUFBRSxDQUFBLE1BQUEsQ0FBRixHQUFZLFNBQUEsR0FBQTtBQUNWLFFBQUEsQ0FBQyxDQUFDLEtBQUYsQ0FBUSxJQUFSLEVBQWMsU0FBZCxDQUFBLENBQUE7ZUFDQSxLQUFLLENBQUMsS0FBTixDQUFZLElBQVosRUFBa0IsU0FBbEIsRUFGVTtNQUFBLEVBRGQ7S0FBQSxNQUFBO2FBS0UsSUFBRSxDQUFBLE1BQUEsQ0FBRixHQUFZLEVBTGQ7S0FGMEI7RUFBQTtDQUY1Qjs7QUFBQSxNQVlNLENBQUMsT0FBUCxHQUFpQixTQUFDLEVBQUQsR0FBQTtBQUNmLE1BQUEsa0NBQUE7QUFBQSxFQUFBLFVBQUEsR0FBYSx3QkFBQSxDQUF5QixFQUF6QixDQUFiLENBQUE7QUFBQSxFQUNBLEtBQUEsR0FBUSxVQUFVLENBQUMsS0FEbkIsQ0FBQTtBQUFBLEVBRUEsTUFBQSxHQUFTLFVBQVUsQ0FBQyxNQUZwQixDQUFBO0FBQUEsRUFPTTtBQUVKLDhCQUFBLENBQUE7O0FBQWEsSUFBQSxpQkFBQyxHQUFELEVBQU8sT0FBUCxFQUFnQixVQUFoQixFQUE0QixRQUE1QixFQUF1QyxHQUF2QyxHQUFBO0FBQ1gsVUFBQSxvREFBQTtBQUFBLE1BRGlCLElBQUMsQ0FBQSxVQUFBLE9BQ2xCLENBQUE7QUFBQSxNQURpRCxJQUFDLENBQUEsTUFBQSxHQUNsRCxDQUFBO0FBQUE7QUFBQTs7Ozs7Ozs7U0FBQTtBQUFBLE1BVUEsdUNBQUEsQ0FWQSxDQUFBO0FBWUEsTUFBQSxJQUFHLG9CQUFBLElBQWdCLGtCQUFuQjtBQUNFLFFBQUEsSUFBQyxDQUFBLGFBQUQsQ0FBZSxZQUFmLEVBQTZCLFVBQTdCLENBQUEsQ0FBQTtBQUFBLFFBQ0EsSUFBQyxDQUFBLGFBQUQsQ0FBZSxVQUFmLEVBQTJCLFFBQTNCLENBREEsQ0FERjtPQUFBLE1BR0ssSUFBRyxDQUFLLGtCQUFMLENBQUEsSUFBc0IsQ0FBSyxnQkFBTCxDQUF6QjtBQUNILFFBQUEsSUFBQyxDQUFBLFVBQUQsR0FBa0IsSUFBQSxLQUFLLENBQUMsUUFBTixDQUFBLENBQWxCLENBQUE7QUFBQSxRQUNBLEVBQUUsQ0FBQyxZQUFILENBQWdCLElBQUMsQ0FBQSxVQUFqQixDQUE0QixDQUFDLE9BQTdCLENBQUEsQ0FEQSxDQUFBO0FBQUEsUUFFQSxJQUFDLENBQUEsUUFBRCxHQUFnQixJQUFBLEtBQUssQ0FBQyxRQUFOLENBQUEsQ0FGaEIsQ0FBQTtBQUFBLFFBR0EsSUFBQyxDQUFBLFFBQVEsQ0FBQyxNQUFWLEdBQW1CLElBSG5CLENBQUE7QUFBQSxRQUlBLEVBQUUsQ0FBQyxZQUFILENBQWdCLElBQUMsQ0FBQSxRQUFqQixDQUEwQixDQUFDLE9BQTNCLENBQUEsQ0FKQSxDQURHO09BQUEsTUFBQTtBQU9ILGNBQVUsSUFBQSxLQUFBLENBQU0sNERBQU4sQ0FBVixDQVBHO09BZkw7QUF3QkEsTUFBQSxJQUFHLGdCQUFIO0FBQ0UsUUFBQSxJQUFDLENBQUEsT0FBRCxHQUFXLElBQUMsQ0FBQSxHQUFHLENBQUMsT0FBaEIsQ0FBQTtBQUNBLGFBQVMsNkdBQVQsR0FBQTtBQUNFLFVBQUEsSUFBQSxHQUFPLEdBQUcsQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUF0QixDQUFBO0FBQUEsVUFDQSxJQUFDLENBQUEsVUFBVSxDQUFDLEdBQVosQ0FBZ0IsSUFBSSxDQUFDLElBQXJCLEVBQTJCLElBQUksQ0FBQyxLQUFoQyxDQURBLENBREY7QUFBQSxTQURBO0FBSUE7QUFBQSxhQUFBLDRDQUFBO3dCQUFBO0FBQ0UsVUFBQSxJQUFHLENBQUMsQ0FBQyxRQUFGLEtBQWMsQ0FBQyxDQUFDLFNBQW5CO0FBQ0UsWUFBQSxJQUFBLEdBQVcsSUFBQSxLQUFLLENBQUMsUUFBTixDQUFBLENBQVgsQ0FBQTtBQUFBLFlBQ0EsRUFBRSxDQUFDLFlBQUgsQ0FBZ0IsSUFBaEIsQ0FBcUIsQ0FBQyxPQUF0QixDQUFBLENBREEsQ0FBQTtBQUFBLFlBRUEsSUFBSSxDQUFDLElBQUwsQ0FBVSxDQUFDLENBQUMsV0FBWixDQUZBLENBQUE7QUFBQSxZQUdBLElBQUMsQ0FBQSxRQUFRLENBQUMsSUFBVixDQUFlLElBQWYsQ0FIQSxDQURGO1dBQUEsTUFLSyxJQUFHLENBQUMsQ0FBQyxRQUFGLEtBQWMsQ0FBQyxDQUFDLFlBQW5CO0FBQ0gsWUFBQSxPQUFBLEdBQWMsSUFBQSxPQUFBLENBQVEsTUFBUixFQUFtQixNQUFuQixFQUE4QixNQUE5QixFQUF5QyxNQUF6QyxFQUFvRCxDQUFwRCxDQUFkLENBQUE7QUFBQSxZQUNBLEVBQUUsQ0FBQyxZQUFILENBQWdCLE9BQWhCLENBQXdCLENBQUMsT0FBekIsQ0FBQSxDQURBLENBQUE7QUFBQSxZQUVBLElBQUMsQ0FBQSxRQUFRLENBQUMsSUFBVixDQUFlLE9BQWYsQ0FGQSxDQURHO1dBQUEsTUFBQTtBQUtILGtCQUFVLElBQUEsS0FBQSxDQUFPLHlCQUFBLEdBQXdCLENBQUMsQ0FBQyxRQUExQixHQUFvQyxJQUEzQyxDQUFWLENBTEc7V0FOUDtBQUFBLFNBSkE7QUFBQSxRQWdCQSxJQUFDLENBQUEsV0FBRCxDQUFBLENBaEJBLENBREY7T0F4QkE7QUFBQSxNQTBDQSxNQTFDQSxDQURXO0lBQUEsQ0FBYjs7QUFBQSxzQkFpREEsSUFBQSxHQUFNLFNBakROLENBQUE7O0FBQUEsc0JBbURBLFdBQUEsR0FBYSxTQUFBLEdBQUE7QUFDWCxNQUFBLElBQUMsQ0FBQSxVQUFVLENBQUMsV0FBWixDQUFBLENBQUEsQ0FBQTtBQUFBLE1BQ0EsSUFBQyxDQUFBLFFBQVEsQ0FBQyxXQUFWLENBQUEsQ0FEQSxDQUFBO2FBRUEsdUNBQUEsRUFIVztJQUFBLENBbkRiLENBQUE7O0FBQUEsc0JBd0RBLE9BQUEsR0FBUyxTQUFBLEdBQUE7YUFDUCxtQ0FBQSxFQURPO0lBQUEsQ0F4RFQsQ0FBQTs7QUFBQSxzQkEyREEsV0FBQSxHQUFhLFNBQUEsR0FBQTtBQUNYLE1BQUEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxNQUFMLEdBQWMsSUFBZCxDQUFBO2FBQ0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxNQUFMLENBQVksY0FBWixFQUE0QixTQUFDLFlBQUQsRUFBZSxZQUFmLEdBQUE7QUFDMUIsWUFBQSxtQkFBQTtBQUFBLFFBQUEsSUFBQSwwQkFBTyxZQUFZLENBQUUsZUFBckIsQ0FBQTtBQUFBLFFBQ0EsSUFBQSxHQUFPLElBRFAsQ0FBQTtBQUVBLFFBQUEsSUFBRyxZQUFIO0FBQ0UsVUFBQSxJQUFBLEdBQU8sSUFBSSxDQUFDLE9BQVosQ0FERjtTQUFBLE1BQUE7QUFHRSxVQUFBLElBQUEsR0FBTyxJQUFDLENBQUEsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsT0FBNUIsQ0FIRjtTQUZBO0FBQUEsUUFNQSxPQUFBLEdBQWMsSUFBQSxPQUFBLENBQVEsTUFBUixFQUFtQixNQUFuQixFQUE4QixNQUE5QixFQUF5QyxNQUF6QyxDQU5kLENBQUE7QUFBQSxRQU9BLEVBQUUsQ0FBQyxZQUFILENBQWdCLE9BQWhCLENBQXdCLENBQUMsT0FBekIsQ0FBQSxDQVBBLENBQUE7ZUFRQSxJQUFDLENBQUEsUUFBUSxDQUFDLFdBQVYsQ0FBc0IsSUFBdEIsRUFBNEIsT0FBNUIsRUFUMEI7TUFBQSxDQUE1QixFQUZXO0lBQUEsQ0EzRGIsQ0FBQTs7QUFBQSxzQkF3RUEsR0FBQSxHQUFLLFNBQUMsT0FBRCxHQUFBO0FBQ0gsVUFBQSwwQ0FBQTs7UUFESSxVQUFVO09BQ2Q7QUFBQSxNQUFBLElBQUcsb0RBQUg7QUFDRSxRQUFBLElBQUcsQ0FBSyxnQkFBTCxDQUFBLElBQWUsT0FBbEI7QUFDRSxVQUFBLElBQUMsQ0FBQSxHQUFELEdBQU8sUUFBUSxDQUFDLGFBQVQsQ0FBdUIsSUFBQyxDQUFBLE9BQXhCLENBQVAsQ0FBQTtBQUFBLFVBRUEsSUFBQSxHQUFPLElBQUMsQ0FBQSxVQUFVLENBQUMsR0FBWixDQUFBLENBRlAsQ0FBQTtBQUdBLGVBQUEsaUJBQUE7b0NBQUE7QUFDRSxZQUFBLENBQUEsR0FBSSxRQUFRLENBQUMsZUFBVCxDQUF5QixTQUF6QixDQUFKLENBQUE7QUFBQSxZQUNBLENBQUMsQ0FBQyxLQUFGLEdBQVUsS0FEVixDQUFBO0FBQUEsWUFFQSxJQUFDLENBQUEsR0FBRyxDQUFDLGdCQUFMLENBQXNCLENBQXRCLENBRkEsQ0FERjtBQUFBLFdBSEE7QUFBQSxVQVFBLENBQUEsR0FBSSxJQUFDLENBQUEsUUFBUSxDQUFDLFNBQVMsQ0FBQyxPQVJ4QixDQUFBO0FBU0EsaUJBQU0sQ0FBQyxDQUFDLElBQUYsS0FBWSxXQUFsQixHQUFBO0FBQ0UsWUFBQSxDQUFBLEdBQUksQ0FBQyxDQUFDLE9BQU4sQ0FBQTtBQUNBLFlBQUEsSUFBRyxDQUFBLENBQUssQ0FBQyxTQUFGLENBQUEsQ0FBUDtBQUNFLGNBQUEsSUFBRyxDQUFDLENBQUMsSUFBRixLQUFVLFNBQWI7QUFDRSxnQkFBQSxJQUFDLENBQUEsR0FBRyxDQUFDLFdBQUwsQ0FBaUIsQ0FBQyxDQUFDLEdBQUYsQ0FBTSxPQUFOLENBQWpCLENBQUEsQ0FERjtlQUFBLE1BRUssSUFBRyxDQUFDLENBQUMsSUFBRixLQUFVLFVBQWI7QUFDSCxnQkFBQSxTQUFBLEdBQVksUUFBUSxDQUFDLGNBQVQsQ0FBd0IsQ0FBQyxDQUFDLEdBQUYsQ0FBQSxDQUF4QixDQUFaLENBQUE7QUFBQSxnQkFDQSxJQUFDLENBQUEsR0FBRyxDQUFDLFdBQUwsQ0FBaUIsU0FBakIsQ0FEQSxDQURHO2VBQUEsTUFBQTtBQUlILHNCQUFVLElBQUEsS0FBQSxDQUFNLGlEQUFOLENBQVYsQ0FKRztlQUhQO2FBREE7QUFBQSxZQVNBLENBQUEsR0FBSSxDQUFDLENBQUMsT0FUTixDQURGO1VBQUEsQ0FWRjtTQUFBO0FBQUEsUUFxQkEsSUFBQyxDQUFBLFdBQUQsQ0FBQSxDQXJCQSxDQUFBO2VBc0JBLElBQUMsQ0FBQSxJQXZCSDtPQURHO0lBQUEsQ0F4RUwsQ0FBQTs7QUFBQSxzQkF3R0EsT0FBQSxHQUFTLFNBQUEsR0FBQTthQUNQLHNDQUFBLFNBQUEsRUFETztJQUFBLENBeEdULENBQUE7O0FBMEdBO0FBQUE7Ozs7OztPQTFHQTs7QUFBQSxzQkFzSEEsU0FBQSxHQUFXLFNBQUEsR0FBQTthQUNULElBQUMsQ0FBQSxPQURRO0lBQUEsQ0F0SFgsQ0FBQTs7QUFBQSxzQkErSEEsT0FBQSxHQUFTLFNBQUEsR0FBQTtBQUNQLFVBQUEsSUFBQTtBQUFBLE1BQUEsSUFBQSxHQUNFO0FBQUEsUUFDRSxNQUFBLEVBQVMsSUFBQyxDQUFBLElBRFo7QUFBQSxRQUVFLFlBQUEsRUFBZSxJQUFDLENBQUEsVUFBVSxDQUFDLE1BQVosQ0FBQSxDQUZqQjtBQUFBLFFBR0UsVUFBQSxFQUFhLElBQUMsQ0FBQSxRQUFRLENBQUMsTUFBVixDQUFBLENBSGY7QUFBQSxRQUlFLFNBQUEsRUFBWSxJQUFDLENBQUEsT0FKZjtBQUFBLFFBS0UsS0FBQSxFQUFRLElBQUMsQ0FBQSxNQUFELENBQUEsQ0FMVjtPQURGLENBQUE7YUFTQSxLQVZPO0lBQUEsQ0EvSFQsQ0FBQTs7bUJBQUE7O0tBRm9CLEtBQUssQ0FBQyxPQVA1QixDQUFBO0FBQUEsRUFvSkEsTUFBTyxDQUFBLFNBQUEsQ0FBUCxHQUFvQixTQUFDLElBQUQsR0FBQTtBQUNsQixRQUFBLGtDQUFBO0FBQUEsSUFDVSxXQUFSLE1BREYsRUFFaUIsa0JBQWYsYUFGRixFQUdlLGdCQUFiLFdBSEYsRUFJYyxlQUFaLFVBSkYsQ0FBQTtXQU9JLElBQUEsT0FBQSxDQUFRLEdBQVIsRUFBYSxPQUFiLEVBQXNCLFVBQXRCLEVBQWtDLFFBQWxDLEVBQTRDLE1BQTVDLEVBUmM7RUFBQSxDQXBKcEIsQ0FBQTtBQUFBLEVBK0pBLEtBQU0sQ0FBQSxTQUFBLENBQU4sR0FBbUIsT0EvSm5CLENBQUE7U0FpS0EsV0FsS2U7QUFBQSxDQVpqQixDQUFBOzs7O0FDQ0EsT0FBUSxDQUFBLGNBQUEsQ0FBUixHQUNFLE9BQUEsQ0FBUSwyQkFBUixDQURGLENBQUE7O0FBQUEsT0FFUSxDQUFBLGVBQUEsQ0FBUixHQUNFLE9BQUEsQ0FBUSw0QkFBUixDQUhGLENBQUE7O0FBQUEsT0FJUSxDQUFBLGVBQUEsQ0FBUixHQUNFLE9BQUEsQ0FBUSw0QkFBUixDQUxGLENBQUE7O0FBQUEsT0FNUSxDQUFBLGVBQUEsQ0FBUixHQUNFLE9BQUEsQ0FBUSw0QkFBUixDQVBGLENBQUE7O0FBQUEsT0FRUSxDQUFBLGNBQUEsQ0FBUixHQUNFLE9BQUEsQ0FBUSwyQkFBUixDQVRGLENBQUE7Ozs7QUNGQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2x5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaGlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlHQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqUUE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3VkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3Q2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcGxHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcnRCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaktBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNybENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVrQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdCtSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9YQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN01BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25jQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDamFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2NENBLElBQUEsMkVBQUE7RUFBQSxrRkFBQTs7QUFBQSxJQUFBLEdBQVksT0FBQSxDQUFRLE1BQVIsQ0FBWixDQUFBOztBQUFBLE1BQ0EsR0FBWSxJQUFJLENBQUMsTUFEakIsQ0FBQTs7QUFBQSxNQUVBLEdBQVksSUFBSSxDQUFDLE1BQUwsQ0FBQSxDQUZaLENBQUE7O0FBQUEsS0FHQSxHQUFZLE9BQUEsQ0FBUSxPQUFSLENBSFosQ0FBQTs7QUFBQSxTQUlBLEdBQVksT0FBQSxDQUFRLFlBQVIsQ0FKWixDQUFBOztBQUFBLENBS0EsR0FBWSxPQUFBLENBQVEsWUFBUixDQUxaLENBQUE7O0FBQUEsSUFPSSxDQUFDLEdBQUwsQ0FBUyxTQUFULENBUEEsQ0FBQTs7QUFBQSxDQVNBLEdBQUksT0FBQSxDQUFRLGNBQVIsQ0FUSixDQUFBOztBQUFBLHVCQVVBLEdBQTBCLE9BQUEsQ0FBUSxpQ0FBUixDQVYxQixDQUFBOztBQUFBLE1BWU0sQ0FBQyxPQUFQLEdBQXVCO0FBQ1IsRUFBQSxjQUFFLFdBQUYsR0FBQTtBQUNYLElBRFksSUFBQyxDQUFBLG9DQUFBLGNBQWMsRUFDM0IsQ0FBQTtBQUFBLHlEQUFBLENBQUE7QUFBQSwrREFBQSxDQUFBO0FBQUEsMkVBQUEsQ0FBQTtBQUFBLElBQUEsSUFBQyxDQUFBLCtCQUFELEdBQW1DLENBQW5DLENBQUE7QUFBQSxJQUNBLElBQUMsQ0FBQSxXQUFELEdBQWUsQ0FBQSxHQUFJLElBQUMsQ0FBQSwrQkFEcEIsQ0FBQTtBQUFBLElBRUEsSUFBQyxDQUFBLGtCQUFELEdBQXNCLEVBQUEsR0FBSyxJQUFDLENBQUEsK0JBRjVCLENBQUE7QUFBQSxJQUdBLElBQUMsQ0FBQSxpQkFBRCxHQUFxQixDQUFBLEdBQUksSUFBQyxDQUFBLCtCQUFMLEdBQXVDLENBSDVELENBQUE7QUFBQSxJQUtBLElBQUMsQ0FBQSxJQUFELEdBQVEsQ0FMUixDQUFBO0FBQUEsSUFNQSxJQUFDLENBQUEsR0FBRCxHQUFPLENBTlAsQ0FBQTtBQUFBLElBT0EsSUFBQyxDQUFBLFFBQUQsR0FBWSxDQVBaLENBQUE7QUFBQSxJQVNBLElBQUMsQ0FBQSxLQUFELEdBQVMsS0FUVCxDQUFBO0FBQUEsSUFXQSxJQUFDLENBQUEsWUFBRCxDQUFBLENBWEEsQ0FEVztFQUFBLENBQWI7O0FBQUEsaUJBY0EsWUFBQSxHQUFjLFNBQUEsR0FBQTtBQUNaLFFBQUEsY0FBQTtBQUFBLElBQUEsSUFBQyxDQUFBLEtBQUQsR0FBUyxFQUFULENBQUE7QUFBQSxJQUNBLElBQUMsQ0FBQSxTQUFELEdBQWEsdUJBQUEsQ0FBd0IsSUFBQyxDQUFBLEtBQXpCLENBRGIsQ0FBQTtBQUVBLFNBQVMseUdBQVQsR0FBQTtBQUNFLE1BQUEsQ0FBQSxHQUFJLElBQUMsQ0FBQSxXQUFELENBQWMsQ0FBQSxHQUFFLElBQUMsQ0FBQSxXQUFqQixFQUErQixJQUFDLENBQUEsU0FBaEMsQ0FBSixDQUFBO0FBQUEsTUFDQSxJQUFDLENBQUEsS0FBSyxDQUFDLElBQVAsQ0FBWSxDQUFaLENBREEsQ0FERjtBQUFBLEtBRkE7V0FNQSxJQUFDLENBQUEsUUFBRCxDQUFBLEVBUFk7RUFBQSxDQWRkLENBQUE7O0FBQUEsaUJBdUJBLFdBQUEsR0FBYSxTQUFDLElBQUQsR0FBQTtBQUNYLElBQUEsSUFBSSxDQUFDLEVBQUUsQ0FBQyx1QkFBUixDQUFBLENBQUEsQ0FBQTtXQUNBLEtBRlc7RUFBQSxDQXZCYixDQUFBOztBQUFBLGlCQTJCQSxXQUFBLEdBQWEsU0FBQSxHQUFBO0FBQ1gsUUFBQSxDQUFBO0FBQUEsSUFBQSxDQUFBLEdBQUksQ0FBQyxDQUFDLE1BQUYsQ0FBUyxDQUFULEVBQWEsSUFBQyxDQUFBLEtBQUssQ0FBQyxNQUFQLEdBQWMsQ0FBM0IsQ0FBSixDQUFBO1dBQ0EsSUFBQyxDQUFBLEtBQU0sQ0FBQSxDQUFBLEVBRkk7RUFBQSxDQTNCYixDQUFBOztBQUFBLGlCQStCQSxhQUFBLEdBQWUsU0FBQyxLQUFELEVBQVEsVUFBUixHQUFBO0FBQ2IsUUFBQSxzQkFBQTs7TUFEcUIsYUFBYTtLQUNsQzs7TUFBQSxRQUFTO0tBQVQ7QUFBQSxJQUNBLE1BQUEsR0FBUyxDQUFDLENBQUMsTUFBRixDQUFTLFVBQVQsRUFBcUIsRUFBckIsQ0FEVCxDQUFBO0FBQUEsSUFHQSxRQUFBLEdBQVcsS0FBTSxDQUFDLENBQUMsQ0FBQyxNQUFGLENBQVMsQ0FBVCxFQUFhLEtBQUssQ0FBQyxNQUFOLEdBQWEsQ0FBMUIsQ0FBRCxDQUhqQixDQUFBO0FBQUEsSUFJQSxJQUFBLEdBQU8sRUFKUCxDQUFBO0FBQUEsSUFLQSxDQUFBLENBQUUsTUFBRixDQUFTLENBQUMsS0FBVixDQUFnQixTQUFBLEdBQUE7YUFBSyxJQUFBLElBQVEsU0FBYjtJQUFBLENBQWhCLENBTEEsQ0FBQTtXQU1BLEtBUGE7RUFBQSxDQS9CZixDQUFBOztBQUFBLGlCQXdDQSxlQUFBLEdBQWlCLFNBQUEsR0FBQTtBQUNmLFFBQUEsOEJBQUE7QUFBQSxJQUFBLE1BQUEsR0FBUyxFQUFULENBQUE7QUFBQSxJQUNBLElBQUEsR0FBTyxJQUFDLENBQUEsWUFBRCxDQUFBLENBRFAsQ0FBQTtBQUFBLElBRUEsSUFBQSxHQUFPLElBQUMsQ0FBQSxZQUFELENBQUEsQ0FGUCxDQUFBO0FBQUEsSUFHQSxJQUFBLEdBQU8sSUFBQyxDQUFBLGFBQUQsQ0FBQSxDQUhQLENBQUE7QUFBQSxJQUlBLElBQUEsR0FBTyxJQUpQLENBQUE7QUFLQSxJQUFBLElBQUcsQ0FBQyxDQUFDLE1BQUYsQ0FBUyxDQUFULEVBQVcsQ0FBWCxDQUFBLEtBQWlCLENBQXBCO0FBQ0UsTUFBQSxJQUFBLEdBQU8sSUFBQyxDQUFBLGVBQUQsQ0FBQSxDQUFQLENBREY7S0FBQSxNQUFBO0FBR0UsTUFBQSxJQUFBLEdBQU8sSUFBQyxDQUFBLGFBQUQsQ0FBQSxDQUFQLENBSEY7S0FMQTtBQUFBLElBU0EsTUFBTyxDQUFBLElBQUEsQ0FBUCxHQUFlLElBVGYsQ0FBQTtBQUFBLElBVUEsTUFBTyxDQUFBLElBQUEsQ0FBUCxHQUFlLElBVmYsQ0FBQTtXQVdBLE9BWmU7RUFBQSxDQXhDakIsQ0FBQTs7QUFBQSxpQkFzREEsWUFBQSxHQUFjLFNBQUEsR0FBQTtXQUNaLElBQUMsQ0FBQSxhQUFELENBQWUsQ0FBQyxDQUFELEVBQUcsQ0FBSCxFQUFLLEdBQUwsRUFBUyxHQUFULENBQWYsRUFBOEIsQ0FBOUIsRUFEWTtFQUFBLENBdERkLENBQUE7O0FBQUEsaUJBeURBLHNCQUFBLEdBQXdCLFNBQUMsUUFBRCxHQUFBO0FBQ3RCLFFBQUEsS0FBQTtBQUFBLElBQUEsS0FBQSxHQUFRLElBQUMsQ0FBQSxLQUFNLENBQUEsUUFBQSxDQUFTLENBQUMsS0FBekIsQ0FBQTtXQUNBO01BQ0k7QUFBQSxRQUFBLENBQUEsRUFBSSxDQUFBLFNBQUEsS0FBQSxHQUFBO2lCQUFBLFNBQUMsQ0FBRCxHQUFBO0FBQ0YsWUFBQSxDQUFBLENBQUE7QUFBQSxnQkFBQSxHQUFBO0FBQUEsWUFDQSxHQUFBLEdBQU0sQ0FBQyxDQUFDLE1BQUYsQ0FBUyxDQUFULEVBQWEsQ0FBQyxDQUFDLEdBQUYsQ0FBQSxDQUFPLENBQUMsTUFBUixHQUFlLENBQTVCLENBRE4sQ0FBQTtBQUFBLFlBRUEsQ0FBQyxDQUFDLFVBQUYsQ0FBYSxHQUFiLEVBQWtCLEtBQUMsQ0FBQSxhQUFELENBQUEsQ0FBbEIsQ0FGQSxDQUFBO21CQUdBLEtBSkU7VUFBQSxFQUFBO1FBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQUFKO0FBQUEsUUFLQSxLQUFBLEVBQU8sQ0FBQyxLQUFLLENBQUMsUUFBUCxDQUxQO09BREosRUFRSTtBQUFBLFFBQUEsQ0FBQSxFQUFJLFNBQUMsQ0FBRCxHQUFBO0FBQ0YsY0FBQSxpQkFBQTtBQUFBLFVBQUEsSUFBRyxDQUFDLENBQUMsR0FBRixDQUFBLENBQU8sQ0FBQyxNQUFSLEdBQWlCLENBQXBCO0FBQ0UsWUFBQSxHQUFBLEdBQU0sQ0FBQyxDQUFDLE1BQUYsQ0FBUyxDQUFULEVBQWEsQ0FBQyxDQUFDLEdBQUYsQ0FBQSxDQUFPLENBQUMsTUFBUixHQUFlLENBQTVCLENBQU4sQ0FBQTtBQUFBLFlBQ0EsTUFBQSxHQUFTLENBQUMsQ0FBQyxNQUFGLENBQVMsQ0FBVCxFQUFhLENBQUMsQ0FBQyxHQUFGLENBQUEsQ0FBTyxDQUFDLE1BQVIsR0FBaUIsR0FBOUIsQ0FEVCxDQUFBO0FBQUEsWUFFQSxJQUFBLEdBQU8sQ0FBQyxDQUFDLFVBQUYsQ0FBYSxHQUFiLEVBQWtCLE1BQWxCLENBRlAsQ0FERjtXQUFBO2lCQUlBLE9BTEU7UUFBQSxDQUFKO0FBQUEsUUFNQSxLQUFBLEVBQVEsQ0FBQyxLQUFLLENBQUMsUUFBUCxDQU5SO09BUkosRUFnQkk7QUFBQSxRQUFBLENBQUEsRUFBSSxDQUFBLFNBQUEsS0FBQSxHQUFBO2lCQUFBLFNBQUMsQ0FBRCxHQUFBO0FBQ0YsWUFBQSxDQUFDLENBQUMsV0FBRixDQUFjLEtBQUMsQ0FBQSxhQUFELENBQUEsQ0FBZCxDQUFBLENBQUE7bUJBQ0EsS0FGRTtVQUFBLEVBQUE7UUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBQUo7QUFBQSxRQUdBLEtBQUEsRUFBTyxDQUFDLEtBQUssQ0FBQyxRQUFQLENBSFA7T0FoQko7TUFGc0I7RUFBQSxDQXpEeEIsQ0FBQTs7QUFBQSxpQkFnRkEsYUFBQSxHQUFlLFNBQUMsUUFBRCxHQUFBO0FBQ2IsVUFBVSxJQUFBLEtBQUEsQ0FBTSxlQUFOLENBQVYsQ0FEYTtFQUFBLENBaEZmLENBQUE7O0FBQUEsaUJBbUZBLFVBQUEsR0FBWSxTQUFDLFFBQUQsR0FBQTtBQUNWLFVBQVUsSUFBQSxLQUFBLENBQU0sZUFBTixDQUFWLENBRFU7RUFBQSxDQW5GWixDQUFBOztBQUFBLGlCQXNGQSxnQkFBQSxHQUFrQixTQUFDLFFBQUQsR0FBQTtBQUNoQixRQUFBLGFBQUE7QUFBQSxJQUFBLENBQUEsR0FBSSxJQUFDLENBQUEsYUFBRCxDQUFlLFFBQWYsQ0FBSixDQUFBO0FBQUEsSUFDQSxPQUFBLEdBQVUsSUFBQyxDQUFBLHNCQUFELENBQXdCLFFBQXhCLENBQWlDLENBQUMsTUFBbEMsQ0FBeUMsU0FBQyxFQUFELEdBQUE7YUFDakQsQ0FBQyxDQUFDLElBQUYsQ0FBTyxFQUFFLENBQUMsS0FBVixFQUFpQixTQUFDLElBQUQsR0FBQTtlQUNmLENBQUEsWUFBYSxLQURFO01BQUEsQ0FBakIsRUFEaUQ7SUFBQSxDQUF6QyxDQURWLENBQUE7QUFLQSxJQUFBLElBQUcsT0FBTyxDQUFDLE1BQVIsS0FBa0IsQ0FBckI7QUFDRSxZQUFVLElBQUEsS0FBQSxDQUFNLG9FQUFOLENBQVYsQ0FERjtLQUxBO0FBQUEsSUFPQSxDQUFBLEdBQUksQ0FBQyxDQUFDLE1BQUYsQ0FBUyxDQUFULEVBQWEsT0FBTyxDQUFDLE1BQVIsR0FBZSxDQUE1QixDQVBKLENBQUE7V0FRQSxPQUFRLENBQUEsQ0FBQSxDQUFFLENBQUMsQ0FBWCxDQUFhLENBQWIsRUFUZ0I7RUFBQSxDQXRGbEIsQ0FBQTs7QUFBQSxpQkFpR0EsYUFBQSxHQUFlLFNBQUMsUUFBRCxHQUFBO0FBQ2IsUUFBQSxJQUFBO0FBQUEsSUFBQSxJQUFBLEdBQU8sSUFBQyxDQUFBLEtBQU0sQ0FBQSxRQUFBLENBQWQsQ0FBQTtXQUNBLElBQUksQ0FBQyxZQUFMLENBQUEsQ0FBbUIsQ0FBQyxjQUFwQixDQUFBLEVBRmE7RUFBQSxDQWpHZixDQUFBOztBQUFBLGlCQXFHQSxXQUFBLEdBQWEsU0FBQSxHQUFBO0FBQ1gsUUFBQSx5QkFBQTtBQUFBLElBQUEsUUFBQSxHQUFXLENBQUMsQ0FBQyxNQUFGLENBQVUsSUFBQyxDQUFBLGlCQUFELEdBQW1CLENBQTdCLENBQVgsQ0FBQTtBQUFBLElBQ0EsT0FBQSxHQUFVLENBQUMsSUFBQyxDQUFBLGFBQUYsRUFBaUIsSUFBQyxDQUFBLGdCQUFsQixDQURWLENBQUE7QUFBQSxJQUVBLE1BQUEsR0FBUyxDQUFDLENBQUMsTUFBRixDQUFVLE9BQU8sQ0FBQyxNQUFSLEdBQWUsQ0FBekIsQ0FGVCxDQUFBO1dBR0EsT0FBUSxDQUFBLE1BQUEsQ0FBUixDQUFnQixRQUFoQixFQUpXO0VBQUEsQ0FyR2IsQ0FBQTs7QUFBQSxpQkEyR0EsUUFBQSxHQUFVLFNBQUMsS0FBRCxHQUFBO0FBRVIsUUFBQSxrRUFBQTtBQUFBLElBQUEsS0FBQSxHQUFRLEtBQVIsQ0FBQTtBQUNBLElBQUEsSUFBRyxJQUFDLENBQUEsS0FBSyxDQUFDLE1BQVAsSUFBaUIsQ0FBakIsSUFBc0IsQ0FBQSxLQUF6QjtBQUNFO0FBQUE7V0FBQSx1RUFBQTtpQ0FBQTtBQUNFLHNCQUFBLElBQUksQ0FBQyxZQUFMLENBQUEsQ0FBbUIsQ0FBQyxRQUFwQixDQUFBLEVBQUEsQ0FERjtBQUFBO3NCQURGO0tBQUEsTUFBQTtBQUlFO0FBQUEsV0FBQSwwRUFBQTtrQ0FBQTtBQUNFLFFBQUEsSUFBSSxDQUFDLFlBQUwsQ0FBQSxDQUFtQixDQUFDLFFBQXBCLENBQUEsQ0FBQSxDQURGO0FBQUEsT0FBQTtBQUFBLE1BRUEsR0FBQSxHQUFNLElBQUMsQ0FBQSxLQUFNLENBQUEsQ0FBQSxDQUFFLENBQUMsZ0JBQVYsQ0FBQSxDQUE0QixDQUFDLE9BQTdCLENBQXFDLElBQUMsQ0FBQSxLQUFNLENBQUEsQ0FBQSxDQUFFLENBQUMsRUFBRSxDQUFDLG1CQUFiLENBQUEsQ0FBckMsQ0FGTixDQUFBO2FBR0EsSUFBQyxDQUFBLEtBQU0sQ0FBQSxDQUFBLENBQUUsQ0FBQyxNQUFNLENBQUMsbUJBQWpCLENBQXFDLEdBQXJDLEVBUEY7S0FIUTtFQUFBLENBM0dWLENBQUE7O0FBQUEsaUJBeUhBLFVBQUEsR0FBWSxTQUFDLFdBQUQsR0FBQTtBQUNWLFFBQUEsa0lBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxRQUFELENBQVUsSUFBVixDQUFBLENBQUE7QUFBQSxJQUVBLElBQUMsQ0FBQSxJQUFELElBQVMsQ0FBSyxJQUFBLElBQUEsQ0FBQSxDQUFMLENBQVksQ0FBQyxPQUFiLENBQUEsQ0FBQSxHQUF5QixJQUFDLENBQUEsUUFGbkMsQ0FBQTtBQUFBLElBSUEsNEJBQUEsR0FBK0IsQ0FKL0IsQ0FBQTtBQUtBLFNBQVMsb0dBQVQsR0FBQTtBQUNFLE1BQUEsNEJBQUEsSUFBZ0MsSUFBQyxDQUFBLEtBQU0sQ0FBQSxDQUFBLENBQUUsQ0FBQyxZQUFWLENBQUEsQ0FBd0IsQ0FBQyxzQkFBekIsQ0FBQSxDQUFpRCxDQUFDLE1BQWxGLENBREY7QUFBQSxLQUxBO0FBQUEsSUFPQSxJQUFDLENBQUEsR0FBRCxJQUFRLDRCQUFBLEdBQTZCLElBQUMsQ0FBQSxLQUFLLENBQUMsTUFQNUMsQ0FBQTtBQUFBLElBU0EsWUFBQSxHQUFlLElBQUksQ0FBQyxLQUFMLENBQVcsSUFBQyxDQUFBLEdBQUQsR0FBSyxJQUFDLENBQUEsSUFBakIsQ0FUZixDQUFBO0FBVUEsSUFBQSxJQUFHLG1CQUFIO0FBQ0UsTUFBQSxPQUFPLENBQUMsR0FBUixDQUFZLENBQUEsRUFBQSxHQUFFLFdBQUYsR0FBZSxHQUFmLEdBQWlCLElBQUMsQ0FBQSxXQUFsQixHQUErQixJQUEvQixHQUFrQyw0QkFBbEMsR0FBZ0UsZ0NBQWhFLEdBQStGLElBQUMsQ0FBQSxLQUFLLENBQUMsTUFBdEcsR0FBOEcsbUNBQTlHLENBQUEsR0FBbUosQ0FBQyx3QkFBQSxHQUF1QixJQUFDLENBQUEsR0FBeEIsR0FBNkIsaUJBQTdCLEdBQTZDLENBQUEsSUFBQyxDQUFBLElBQUQsR0FBTSxJQUFOLENBQTdDLEdBQXlELFlBQXpELEdBQW9FLFlBQXBFLEdBQWtGLGFBQW5GLENBQS9KLENBQUEsQ0FERjtLQVZBO0FBYUE7U0FBUyw2R0FBVCxHQUFBO0FBQ0UsTUFBQSxJQUFHLElBQUMsQ0FBQSxLQUFKO0FBQ0UsUUFBQSxJQUFHLENBQUEsQ0FBSyxDQUFDLE9BQUYsQ0FBVSxJQUFDLENBQUEsVUFBRCxDQUFZLENBQVosQ0FBVixFQUEwQixJQUFDLENBQUEsVUFBRCxDQUFZLENBQUEsR0FBRSxDQUFkLENBQTFCLENBQVA7QUFDRSxVQUFBLHdCQUFBLEdBQTJCLENBQUEsU0FBQSxLQUFBLEdBQUE7bUJBQUEsU0FBQyxRQUFELEVBQVcsYUFBWCxHQUFBO0FBQ3pCLGtCQUFBLGlDQUFBO0FBQUEsY0FBQSxHQUFBLEdBQU0sQ0FBQyxDQUFDLE1BQUYsQ0FBUyxLQUFDLENBQUEsS0FBTSxDQUFBLFFBQUEsQ0FBUyxDQUFDLFlBQWpCLENBQUEsQ0FBK0IsQ0FBQyxzQkFBaEMsQ0FBQSxDQUFULEVBQW1FLFNBQUMsQ0FBRCxHQUFBO3VCQUN2RSxNQUFBLENBQUEsQ0FBUSxDQUFDLEdBQUcsQ0FBQyxPQUFiLEtBQTBCLFFBQTFCLElBQXVDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTixLQUFtQixJQURhO2NBQUEsQ0FBbkUsQ0FBTixDQUFBO0FBRUEsbUJBQUEsa0RBQUE7MkJBQUE7QUFDRSxnQkFBQSxPQUFPLENBQUMsR0FBUixDQUFZLENBQUMsSUFBQSxHQUFHLENBQUgsR0FBTSxLQUFQLENBQUEsR0FBYyxDQUFDLElBQUksQ0FBQyxTQUFMLENBQWUsQ0FBZixDQUFELENBQTFCLENBQUEsQ0FERjtBQUFBLGVBRkE7QUFBQSxjQUlBLE9BQU8sQ0FBQyxHQUFSLENBQVksRUFBWixDQUpBLENBQUE7QUFBQSxjQUtBLENBQUEsR0FBSSxTQUxKLENBQUE7QUFNQSxtQkFBQSxvREFBQTsyQkFBQTtBQUNFLGdCQUFBLElBQUcsQ0FBQSxLQUFPLENBQVY7QUFDRSxrQkFBQSxDQUFBLElBQUssSUFBTCxDQURGO2lCQUFBO0FBQUEsZ0JBRUEsQ0FBQSxJQUFNLElBQUEsR0FBRyxDQUZULENBREY7QUFBQSxlQU5BO0FBQUEsY0FVQSxDQUFBLElBQUssR0FWTCxDQUFBO0FBQUEsY0FXQSxPQUFPLENBQUMsR0FBUixDQUFZLENBQVosQ0FYQSxDQUFBO0FBQUEsY0FZQSxPQUFPLENBQUMsR0FBUixDQUFZLGdDQUFaLENBWkEsQ0FBQTtBQUFBLGNBYUEsT0FBTyxDQUFDLEdBQVIsQ0FBYSxrREFBQSxHQUFpRCxDQUFBLEtBQUMsQ0FBQSxLQUFNLENBQUEsYUFBQSxDQUFjLENBQUMsR0FBdEIsQ0FBMEIsTUFBMUIsQ0FBaUMsQ0FBQyxHQUFsQyxDQUFBLENBQUEsQ0FBakQsR0FBMEYsS0FBdkcsQ0FiQSxDQUFBO3FCQWNBLElBZnlCO1lBQUEsRUFBQTtVQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FBM0IsQ0FBQTtBQUFBLFVBZ0JBLE9BQU8sQ0FBQyxHQUFSLENBQVksRUFBWixDQWhCQSxDQUFBO0FBQUEsVUFpQkEsT0FBTyxDQUFDLEdBQVIsQ0FBWSxxQkFBWixDQWpCQSxDQUFBO0FBQUEsVUFrQkEsT0FBTyxDQUFDLEdBQVIsQ0FBWSxZQUFaLENBbEJBLENBQUE7QUFtQkE7QUFBQSxlQUFBLG9EQUFBO3lCQUFBO0FBQ0UsWUFBQSxPQUFPLENBQUMsR0FBUixDQUFZLENBQUMsSUFBQSxHQUFHLENBQUgsR0FBTSxJQUFQLENBQUEsR0FBVyxDQUFDLENBQUMsR0FBRixDQUFNLE1BQU4sQ0FBYSxDQUFDLEdBQWQsQ0FBQSxDQUF2QixDQUFBLENBREY7QUFBQSxXQW5CQTtBQUFBLFVBcUJBLE9BQU8sQ0FBQyxHQUFSLENBQWEsd0JBQUEsR0FBdUIsQ0FBdkIsR0FBMEIsR0FBMUIsR0FBNEIsQ0FBQSxDQUFBLEdBQUUsQ0FBRixDQUE1QixHQUFpQyxJQUE5QyxDQXJCQSxDQUFBO0FBQUEsVUFzQkEsd0JBQUEsQ0FBeUIsQ0FBekIsRUFBNEIsQ0FBQSxHQUFFLENBQTlCLENBdEJBLENBQUE7QUFBQSxVQXVCQSxPQUFPLENBQUMsR0FBUixDQUFZLEVBQVosQ0F2QkEsQ0FBQTtBQUFBLFVBd0JBLEdBQUEsR0FBTSx3QkFBQSxDQUF5QixDQUFBLEdBQUUsQ0FBM0IsRUFBOEIsQ0FBOUIsQ0F4Qk4sQ0FBQTtBQUFBLFVBMEJBLE9BQU8sQ0FBQyxHQUFSLENBQVksRUFBWixDQTFCQSxDQURGO1NBREY7T0FBQTtBQUFBLG9CQTZCQSxNQUFBLENBQU8sSUFBQyxDQUFBLFVBQUQsQ0FBWSxDQUFaLENBQVAsQ0FBc0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQS9CLENBQXFDLElBQUMsQ0FBQSxVQUFELENBQVksQ0FBQSxHQUFFLENBQWQsQ0FBckMsRUE3QkEsQ0FERjtBQUFBO29CQWRVO0VBQUEsQ0F6SFosQ0FBQTs7QUFBQSxpQkF1S0EsR0FBQSxHQUFLLFNBQUEsR0FBQTtBQUNILFFBQUEsc0VBQUE7QUFBQSxJQUFBLElBQUcsSUFBQyxDQUFBLEtBQUo7QUFDRSxNQUFBLE9BQU8sQ0FBQyxHQUFSLENBQVksRUFBWixDQUFBLENBREY7S0FBQTtBQUVBO1NBQWEsNkdBQWIsR0FBQTtBQUNFLE1BQUEsSUFBQyxDQUFBLFFBQUQsR0FBWSxDQUFDLEdBQUEsQ0FBQSxJQUFELENBQVUsQ0FBQyxPQUFYLENBQUEsQ0FBWixDQUFBO0FBQ0EsV0FBUyxpSUFBVCxHQUFBO0FBQ0UsUUFBQSxJQUFDLENBQUEsV0FBRCxDQUFBLENBQUEsQ0FERjtBQUFBLE9BREE7QUFBQSxNQUdBLElBQUMsQ0FBQSxRQUFELENBQVUsS0FBVixDQUhBLENBQUE7QUFJQTtBQUFBLFdBQUEsNENBQUE7c0JBQUE7QUFDRSxRQUFBLENBQUMsQ0FBQyxFQUFFLENBQUMsWUFBTCxDQUFBLENBQUEsQ0FERjtBQUFBLE9BSkE7QUFNQSxXQUFTLGlJQUFULEdBQUE7QUFDRSxRQUFBLElBQUMsQ0FBQSxXQUFELENBQUEsQ0FBQSxDQURGO0FBQUEsT0FOQTtBQUFBLE1BU0EsSUFBQyxDQUFBLFVBQUQsQ0FBWSxLQUFaLENBVEEsQ0FBQTtBQUFBLE1BVUEsSUFBQyxDQUFBLGNBQUQsQ0FBQSxDQVZBLENBQUE7QUFXQSxNQUFBLElBQUcsS0FBQSxLQUFXLElBQUMsQ0FBQSxXQUFmO3NCQUNFLElBQUMsQ0FBQSxZQUFELENBQUEsR0FERjtPQUFBLE1BQUE7OEJBQUE7T0FaRjtBQUFBO29CQUhHO0VBQUEsQ0F2S0wsQ0FBQTs7QUFBQSxpQkF5TEEsY0FBQSxHQUFnQixTQUFBLEdBQUE7QUFFZCxJQUFBLElBQUMsQ0FBQSxLQUFNLENBQUEsSUFBQyxDQUFBLEtBQUssQ0FBQyxNQUFQLENBQVAsR0FBd0IsSUFBQyxDQUFBLFdBQUQsQ0FBYyxDQUFBLENBQUQsQ0FBYixFQUFvQix1QkFBQSxDQUF3QixFQUF4QixDQUFwQixDQUF4QixDQUFBO0FBQUEsSUFDQSxJQUFDLENBQUEsS0FBTSxDQUFBLElBQUMsQ0FBQSxLQUFLLENBQUMsTUFBUCxHQUFjLENBQWQsQ0FBZ0IsQ0FBQyxNQUFNLENBQUMsUUFBL0IsQ0FBd0MsSUFBQyxDQUFBLEtBQU0sQ0FBQSxDQUFBLENBQUUsQ0FBQyxFQUFFLENBQUMsT0FBYixDQUFBLENBQXhDLENBREEsQ0FBQTtXQU9BLE1BQUEsQ0FBTyxJQUFDLENBQUEsVUFBRCxDQUFZLElBQUMsQ0FBQSxLQUFLLENBQUMsTUFBUCxHQUFjLENBQTFCLENBQVAsQ0FBb0MsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQTdDLENBQW1ELElBQUMsQ0FBQSxVQUFELENBQVksQ0FBWixDQUFuRCxFQVRjO0VBQUEsQ0F6TGhCLENBQUE7O2NBQUE7O0lBYkYsQ0FBQTs7OztBQ0FBLElBQUEsdUZBQUE7RUFBQTtpU0FBQTs7QUFBQSxJQUFBLEdBQVksT0FBQSxDQUFRLE1BQVIsQ0FBWixDQUFBOztBQUFBLE1BQ0EsR0FBWSxJQUFJLENBQUMsTUFEakIsQ0FBQTs7QUFBQSxNQUVBLEdBQVksSUFBSSxDQUFDLE1BQUwsQ0FBQSxDQUZaLENBQUE7O0FBQUEsS0FHQSxHQUFZLE9BQUEsQ0FBUSxPQUFSLENBSFosQ0FBQTs7QUFBQSxTQUlBLEdBQVksT0FBQSxDQUFRLFlBQVIsQ0FKWixDQUFBOztBQUFBLENBS0EsR0FBWSxPQUFBLENBQVEsWUFBUixDQUxaLENBQUE7O0FBQUEsQ0FNQSxHQUFZLE9BQUEsQ0FBUSxRQUFSLENBTlosQ0FBQTs7O0VBT0EsUUFBUSxDQUFFLENBQVYsR0FBYztDQVBkOztBQUFBLE9BUUEsQ0FBUSxlQUFSLENBUkEsQ0FBQTs7QUFBQSxJQVVJLENBQUMsR0FBTCxDQUFTLFNBQVQsQ0FWQSxDQUFBOztBQUFBLENBWUEsR0FBSSxPQUFBLENBQVEsY0FBUixDQVpKLENBQUE7O0FBQUEsdUJBYUEsR0FBMEIsT0FBQSxDQUFRLGlDQUFSLENBYjFCLENBQUE7O0FBQUEsSUFlQSxHQUFPLE9BQUEsQ0FBUSxhQUFSLENBZlAsQ0FBQTs7QUFBQTtBQWtCRSw0QkFBQSxDQUFBOzs7O0dBQUE7O0FBQUEsb0JBQUEsSUFBQSxHQUFNLFNBQU4sQ0FBQTs7QUFBQSxvQkFFQSxXQUFBLEdBQWEsU0FBQyxJQUFELEVBQU8sSUFBUCxHQUFBO1dBQ1gseUNBQVUsSUFBQSxDQUFDLENBQUMsWUFBRixDQUFlLElBQWYsRUFBcUIsSUFBckIsQ0FBVixFQURXO0VBQUEsQ0FGYixDQUFBOztBQUFBLG9CQUtBLGFBQUEsR0FBZSxTQUFDLFFBQUQsR0FBQTtXQUNiLElBQUMsQ0FBQSxLQUFNLENBQUEsUUFBQSxDQUFTLENBQUMsZUFBakIsQ0FBQSxFQURhO0VBQUEsQ0FMZixDQUFBOztBQUFBLG9CQVFBLFVBQUEsR0FBWSxTQUFDLFFBQUQsR0FBQTtXQUNWLElBQUMsQ0FBQSxLQUFNLENBQUEsUUFBQSxDQUFTLENBQUMsR0FBakIsQ0FBQSxFQURVO0VBQUEsQ0FSWixDQUFBOztpQkFBQTs7R0FGb0IsS0FoQnRCLENBQUE7O0FBQUEsUUE4QkEsQ0FBUyxjQUFULEVBQXlCLFNBQUEsR0FBQTtBQUN2QixFQUFBLFVBQUEsQ0FBVyxTQUFDLElBQUQsR0FBQTtBQUNULElBQUEsSUFBQyxDQUFBLE9BQUQsQ0FBUyxLQUFULENBQUEsQ0FBQTtBQUFBLElBQ0EsSUFBQyxDQUFBLEtBQUQsR0FBYSxJQUFBLE9BQUEsQ0FBQSxDQURiLENBQUE7QUFFQTtBQUFBOzs7T0FGQTtBQUFBLElBTUEsSUFBQyxDQUFBLFNBQUQsR0FBYSxJQUFDLENBQUEsS0FBSyxDQUFDLFdBQVAsQ0FBbUIsQ0FBbkIsRUFBdUIsdUJBQUEsQ0FBd0IsRUFBeEIsQ0FBdkIsQ0FOYixDQUFBO1dBT0EsSUFBQSxDQUFBLEVBUlM7RUFBQSxDQUFYLENBQUEsQ0FBQTtTQVVBLEVBQUEsQ0FBRyxxQ0FBSCxFQUEwQyxTQUFBLEdBQUE7QUFDeEMsUUFBQSxTQUFBO0FBQUEsSUFBQSxHQUFBLEdBQU0sQ0FBQSxDQUFFLFdBQUYsQ0FBZSxDQUFBLENBQUEsQ0FBckIsQ0FBQTtBQUFBLElBQ0EsSUFBQyxDQUFBLFNBQVMsQ0FBQyxHQUFYLENBQWUsR0FBZixDQURBLENBQUE7QUFBQSxJQUVBLElBQUEsR0FBTyxJQUFDLENBQUEsU0FBUyxDQUFDLEdBQVgsQ0FBZSxJQUFmLENBRlAsQ0FBQTtBQUFBLElBR0EsTUFBQSxDQUFPLElBQUEsS0FBVSxHQUFqQixDQUFxQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQUgzQixDQUFBO0FBQUEsSUFJQSxNQUFBLENBQU8sSUFBSSxDQUFDLFNBQVosQ0FBc0IsQ0FBQyxFQUFFLENBQUMsS0FBMUIsQ0FBZ0MsR0FBRyxDQUFDLFNBQXBDLENBSkEsQ0FBQTtXQUtBLE9BQU8sQ0FBQyxHQUFSLENBQVksTUFBWixFQU53QztFQUFBLENBQTFDLEVBWHVCO0FBQUEsQ0FBekIsQ0E5QkEsQ0FBQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpfXZhciBmPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChmLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGYsZi5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJcbiNcbiMgQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIGlzIGNhbGxlZCB3aGVuIHRoZSBjb25uZWN0b3IgaXMgaW5pdGlhbGl6ZWQuXG4jIEBwYXJhbSB7U3RyaW5nfSBpbml0aWFsX3VzZXJfaWQgT3B0aW9uYWwuIFlvdSBjYW4gc2V0IHlvdSBvd24gdXNlcl9pZCAoc2luY2UgdGhlIGlkcyBvZiBkdWljbGllbnQgYXJlIG5vdCBhbHdheXMgdW5pcXVlKVxuI1xuY3JlYXRlSXdjQ29ubmVjdG9yID0gKGNhbGxiYWNrLCBvcHRpb25zKS0+XG4gIHVzZXJJd2NIYW5kbGVyID0gbnVsbFxuICBpZiBvcHRpb25zP1xuICAgIHtpd2NIYW5kbGVyOiB1c2VySXdjSGFuZGxlcn0gPSBvcHRpb25zXG5cbiAgaXdjSGFuZGxlciA9IHt9XG4gIGR1aUNsaWVudCA9IG5ldyBEVUlDbGllbnQoKVxuICAjQGR1aUNsaWVudCA9IG5ldyBpd2MuQ2xpZW50KClcbiAgZHVpQ2xpZW50LmNvbm5lY3QgKGludGVudCktPlxuICAgIGl3Y0hhbmRsZXJbaW50ZW50LmFjdGlvbl0/Lm1hcCAoZiktPlxuICAgICAgc2V0VGltZW91dCAoKS0+XG4gICAgICAgIGYgaW50ZW50XG4gICAgICAsIDBcbiAgICBpZiB1c2VySXdjSGFuZGxlcj9cbiAgICAgIHVzZXJJd2NIYW5kbGVyIGludGVudFxuXG4gIGR1aUNsaWVudC5pbml0T0soKVxuXG4gIHJlY2VpdmVkX0hCID0gbnVsbFxuXG4gICNcbiAgIyBUaGUgSXdjIENvbm5lY3RvciBhZGRzIHN1cHBvcnQgZm9yIHRoZSBJbnRlci1XaWRnZXQtQ29tbXVuaWNhdGlvbiBwcm90b2NvbCB0aGF0IGlzIHVzZWQgaW4gdGhlIFJvbGUtU0RLLlxuICAjXG4gICMgWW91IG11c3Qgbm90IHVzZSB5b3VyIG93biBJV0MgY2xpZW50IHdoZW4gdXNpbmcgdGhpcyBjb25uZWN0b3IhIVxuICAjXG4gICMgQHNlZSBodHRwOi8vZGJpcy5yd3RoLWFhY2hlbi5kZS9jbXMvcHJvamVjdHMvdGhlLXhtcHAtZXhwZXJpZW5jZSNpbnRlcndpZGdldC1jb21tdW5pY2F0aW9uXG4gICMgQHNlZSBodHRwOi8vZGJpcy5yd3RoLWFhY2hlbi5kZS9jbXMvcHJvamVjdHMvUk9MRVxuICAjXG4gIGNsYXNzIEl3Y0Nvbm5lY3RvclxuXG4gICAgI1xuICAgICMgQHBhcmFtIHtFbmdpbmV9IGVuZ2luZSBUaGUgdHJhbnNmb3JtYXRpb24gZW5naW5lXG4gICAgIyBAcGFyYW0ge0hpc3RvcnlCdWZmZXJ9IEhCXG4gICAgIyBAcGFyYW0ge0FycmF5PEZ1bmN0aW9uPn0gZXhlY3V0aW9uX2xpc3RlbmVyIFlvdSBtdXN0IGVuc3VyZSB0aGF0IHdoZW5ldmVyIGFuIG9wZXJhdGlvbiBpcyBleGVjdXRlZCwgZXZlcnkgZnVuY3Rpb24gaW4gdGhpcyBBcnJheSBpcyBjYWxsZWQuXG4gICAgIyBAcGFyYW0ge1lhdHRhRnJhbWV3b3JrfSB5YXR0YSBUaGUgWWF0dGEgZnJhbWV3b3JrLlxuICAgICNcbiAgICBjb25zdHJ1Y3RvcjogKEBlbmdpbmUsIEBIQiwgQGV4ZWN1dGlvbl9saXN0ZW5lciwgQHlhdHRhKS0+XG4gICAgICBAZHVpQ2xpZW50ID0gZHVpQ2xpZW50XG4gICAgICBAaXdjSGFuZGxlciA9IGl3Y0hhbmRsZXJcblxuICAgICAgc2VuZF8gPSAobyk9PlxuICAgICAgICBpZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhAaW5pdGlhbGl6ZWQpLmxlbmd0aCBpc250IDBcbiAgICAgICAgICBAc2VuZCBvXG4gICAgICBAZXhlY3V0aW9uX2xpc3RlbmVyLnB1c2ggc2VuZF9cblxuICAgICAgQGluaXRpYWxpemVkID0ge31cbiAgICAgIHJlY2VpdmVIQiA9IChqc29uKT0+XG4gICAgICAgIEhCID0ganNvbi5leHRyYXMuSEJcbiAgICAgICAgaGltID0ganNvbi5leHRyYXMudXNlclxuICAgICAgICB0aGlzLmVuZ2luZS5hcHBseU9wc0NoZWNrRG91YmxlIEhCXG4gICAgICAgIEBpbml0aWFsaXplZFtoaW1dID0gdHJ1ZVxuICAgICAgaXdjSGFuZGxlcltcIllhdHRhX3B1c2hfSEJfZWxlbWVudFwiXSA9IFtyZWNlaXZlSEJdXG5cbiAgICAgIEBzZW5kSXdjSW50ZW50IFwiWWF0dGFfZ2V0X0hCX2VsZW1lbnRcIiwgQEhCLmdldE9wZXJhdGlvbkNvdW50ZXIoKVxuXG4gICAgICByZWNlaXZlXyA9IChpbnRlbnQpPT5cbiAgICAgICAgbyA9IGludGVudC5leHRyYXNcbiAgICAgICAgaWYgQGluaXRpYWxpemVkW28udWlkLmNyZWF0b3JdPyAjIGluaXRpYWxpemUgZmlyc3RcbiAgICAgICAgICBAcmVjZWl2ZSBvXG5cbiAgICAgIEBpd2NIYW5kbGVyW1wiWWF0dGFfbmV3X29wZXJhdGlvblwiXSA9IFtyZWNlaXZlX11cblxuICAgICAgaWYgcmVjZWl2ZWRfSEI/XG4gICAgICAgIEBlbmdpbmUuYXBwbHlPcHNDaGVja0RvdWJsZSByZWNlaXZlZF9IQlxuXG4gICAgICBzZW5kSGlzdG9yeUJ1ZmZlciA9IChpbnRlbnQpPT5cbiAgICAgICAgc3RhdGVfdmVjdG9yID0gaW50ZW50LmV4dHJhc1xuICAgICAgICBjb25zb2xlLmxvZyBzdGF0ZV92ZWN0b3JcbiAgICAgICAganNvbiA9XG4gICAgICAgICAgSEIgOiBAeWF0dGEuZ2V0SGlzdG9yeUJ1ZmZlcigpLl9lbmNvZGUoc3RhdGVfdmVjdG9yKVxuICAgICAgICAgIHVzZXIgOiBAeWF0dGEuZ2V0VXNlcklkKClcbiAgICAgICAgQHNlbmRJd2NJbnRlbnQgXCJZYXR0YV9wdXNoX0hCX2VsZW1lbnRcIiwganNvblxuICAgICAgQGl3Y0hhbmRsZXJbXCJZYXR0YV9nZXRfSEJfZWxlbWVudFwiXSA9IFtzZW5kSGlzdG9yeUJ1ZmZlcl1cblxuICAgICNcbiAgICAjIFNldCB5b3VyIG93biBJV0MgaGFuZGxlci4gSXQgd2lsbCBiZSBjYWxsZWQgYWZ0ZXIgWWF0dGEgY29uc3VtZWQgdGhlXG4gICAgIyBkYXRhIGZyb20gdGhlIHJlY2VpdmVkIGludGVudC5cbiAgICAjXG4gICAgc2V0SXdjSGFuZGxlcjogKGYpLT5cbiAgICAgIHVzZXJJd2NIYW5kbGVyID0gZlxuXG4gICAgI1xuICAgICMgSGVscGVyIGZvciBzZW5kaW5nIGl3YyBpbnRlbnRzLlxuICAgICMgQG92ZXJsb2FkIHNlbmRJd2NJbnRlbnQgaW50ZW50XG4gICAgIyAgIEBwYXJhbSB7T2JqZWN0fSBpbnRlbnQgVGhlIGludGVudCBvYmplY3QuXG4gICAgIyBAb3ZlcmxvYWQgc2VuZEl3Y0ludGVudCBhY3Rpb25fbmFtZSwgY29udGVudFxuICAgICMgICBAcGFyYW0ge1N0cmluZ30gYWN0aW9uX25hbWUgVGhlIG5hbWUgb2YgdGhlIGFjdGlvbiB0aGF0IGlzIGdvaW5nIHRvIGJlIHNlbmQuXG4gICAgIyAgIEBwYXJhbSB7U3RyaW5nfSBjb250ZW50IFRoZSBjb250ZW50IHRoYXQgaXMgYXR0ZWNoZWQgdG8gdGhlIGludGVudC5cbiAgICAjXG4gICAgc2VuZEl3Y0ludGVudDogKGFjdGlvbl9uYW1lLCBjb250ZW50KS0+XG4gICAgICBpbnRlbnQgPSBudWxsXG4gICAgICBpZiBhcmd1bWVudHMubGVuZ3RoID49IDJcbiAgICAgICAgW2FjdGlvbl9uYW1lLCBjb250ZW50XSA9IGFyZ3VtZW50c1xuICAgICAgICBpbnRlbnQgPVxuICAgICAgICAgIGFjdGlvbjogYWN0aW9uX25hbWVcbiAgICAgICAgICBjb21wb25lbnQ6IFwiXCJcbiAgICAgICAgICBkYXRhOiBcIlwiXG4gICAgICAgICAgZGF0YVR5cGU6IFwiXCJcbiAgICAgICAgICBmbGFnczogW1wiUFVCTElTSF9HTE9CQUxcIl1cbiAgICAgICAgICBleHRyYXM6IGNvbnRlbnRcbiAgICAgIGVsc2VcbiAgICAgICAgaW50ZW50ID0gYXJndW1lbnRzWzBdXG5cbiAgICAgIEBkdWlDbGllbnQuc2VuZEludGVudChpbnRlbnQpXG5cbiAgICAjXG4gICAgIyBAcHJpdmF0ZVxuICAgICMgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgd2hlbmV2ZXIgYW4gb3BlcmF0aW9uIHdhcyBleGVjdXRlZC5cbiAgICAjIEBwYXJhbSB7T3BlcmF0aW9ufSBvIFRoZSBvcGVyYXRpb24gdGhhdCB3YXMgZXhlY3V0ZWQuXG4gICAgI1xuICAgIHNlbmQ6IChvKS0+XG4gICAgICBpZiBvLnVpZC5jcmVhdG9yIGlzIEBIQi5nZXRVc2VySWQoKSBhbmQgKHR5cGVvZiBvLnVpZC5vcF9udW1iZXIgaXNudCBcInN0cmluZ1wiKVxuICAgICAgICBAc2VuZEl3Y0ludGVudCBcIllhdHRhX25ld19vcGVyYXRpb25cIiwgb1xuXG4gICAgI1xuICAgICMgQHByaXZhdGVcbiAgICAjIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW5ldmVyIGFuIG9wZXJhdGlvbiB3YXMgcmVjZWl2ZWQgZnJvbSBhbm90aGVyIHBlZXIuXG4gICAgIyBAcGFyYW0ge09wZXJhdGlvbn0gbyBUaGUgb3BlcmF0aW9uIHRoYXQgd2FzIHJlY2VpdmVkLlxuICAgICNcbiAgICByZWNlaXZlOiAobyktPlxuICAgICAgaWYgby51aWQuY3JlYXRvciBpc250IEBIQi5nZXRVc2VySWQoKVxuICAgICAgICBAZW5naW5lLmFwcGx5T3Agb1xuXG5cbiAgaW5pdCA9ICgpLT5cbiAgICAjIHByb3Bvc2VkX3VzZXJfaWQgPSBkdWlDbGllbnQuZ2V0SXdjQ2xpZW50KCkuX2NvbXBvbmVudE5hbWUgI1RPRE86IFRoaXMgaXMgc3R1cGlkISB3aHkgY2FuJ3QgaSB1c2UgdGhpcz9cbiAgICBwcm9wb3NlZF91c2VyX2lkID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKjEwMDAwMDApXG4gICAgY2FsbGJhY2sgSXdjQ29ubmVjdG9yLCBwcm9wb3NlZF91c2VyX2lkXG5cbiAgc2V0VGltZW91dCBpbml0LCA1MDAwXG5cbiAgdW5kZWZpbmVkXG5cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVJd2NDb25uZWN0b3JcbmlmIHdpbmRvdz9cbiAgaWYgbm90IHdpbmRvdy5ZP1xuICAgIHdpbmRvdy5ZID0ge31cbiAgd2luZG93LlkuY3JlYXRlSXdjQ29ubmVjdG9yID0gY3JlYXRlSXdjQ29ubmVjdG9yXG5cbiIsIlxuXyA9IHJlcXVpcmUgXCJ1bmRlcnNjb3JlXCJcblxubW9kdWxlLmV4cG9ydHMgPSAodXNlcl9saXN0KS0+XG5cbiAgI1xuICAjIEBub2RvY1xuICAjIEEgdHJpdmlhbCBDb25uZWN0b3IgdGhhdCBzaW11bGF0ZXMgbmV0d29yayBkZWxheS5cbiAgI1xuICBjbGFzcyBUZXN0Q29ubmVjdG9yXG5cbiAgICAjXG4gICAgIyBAcGFyYW0ge0VuZ2luZX0gZW5naW5lIFRoZSB0cmFuc2Zvcm1hdGlvbiBlbmdpbmVcbiAgICAjIEBwYXJhbSB7SGlzdG9yeUJ1ZmZlcn0gSEJcbiAgICAjIEBwYXJhbSB7QXJyYXk8RnVuY3Rpb24+fSBleGVjdXRpb25fbGlzdGVuZXIgWW91IG11c3QgZW5zdXJlIHRoYXQgd2hlbmV2ZXIgYW4gb3BlcmF0aW9uIGlzIGV4ZWN1dGVkLCBldmVyeSBmdW5jdGlvbiBpbiB0aGlzIEFycmF5IGlzIGNhbGxlZC5cbiAgICAjIEBwYXJhbSB7WWF0dGF9IHlhdHRhIFRoZSBZYXR0YSBmcmFtZXdvcmsuXG4gICAgI1xuICAgIGNvbnN0cnVjdG9yOiAoQGVuZ2luZSwgQEhCLCBAZXhlY3V0aW9uX2xpc3RlbmVyKS0+XG4gICAgICBzZW5kXyA9IChvKT0+XG4gICAgICAgIEBzZW5kIG9cbiAgICAgIEBleGVjdXRpb25fbGlzdGVuZXIucHVzaCBzZW5kX1xuXG4gICAgICBAYXBwbGllZF9vcGVyYXRpb25zID0gW11cbiAgICAgIGFwcGxpZWRPcGVyYXRpb25zTGlzdGVuZXIgPSAobyk9PlxuICAgICAgICBAYXBwbGllZF9vcGVyYXRpb25zLnB1c2ggb1xuICAgICAgQGV4ZWN1dGlvbl9saXN0ZW5lci5wdXNoIGFwcGxpZWRPcGVyYXRpb25zTGlzdGVuZXJcbiAgICAgIGlmIG5vdCAodXNlcl9saXN0Py5sZW5ndGggaXMgMClcbiAgICAgICAgQGVuZ2luZS5hcHBseU9wcyB1c2VyX2xpc3RbMF0uZ2V0SGlzdG9yeUJ1ZmZlcigpLl9lbmNvZGUoKVxuXG4gICAgICBASEIuc2V0TWFudWFsR2FyYmFnZUNvbGxlY3QoKVxuICAgICAgQHVuZXhlY3V0ZWQgPSB7fVxuXG4gICAgI1xuICAgICMgVGhpcyBlbmdpbmUgYXBwbGllZCBvcGVyYXRpb25zIGluIGEgc3BlY2lmaWMgb3JkZXIuXG4gICAgIyBHZXQgdGhlIG9wcyBpbiB0aGUgcmlnaHQgb3JkZXIuXG4gICAgI1xuICAgIGdldE9wc0luRXhlY3V0aW9uT3JkZXI6ICgpLT5cbiAgICAgIEBhcHBsaWVkX29wZXJhdGlvbnNcblxuICAgICNcbiAgICAjIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW5ldmVyIGFuIG9wZXJhdGlvbiB3YXMgZXhlY3V0ZWQuXG4gICAgIyBAcGFyYW0ge09wZXJhdGlvbn0gbyBUaGUgb3BlcmF0aW9uIHRoYXQgd2FzIGV4ZWN1dGVkLlxuICAgICNcbiAgICBzZW5kOiAobyktPlxuICAgICAgaWYgKG8udWlkLmNyZWF0b3IgaXMgQEhCLmdldFVzZXJJZCgpKSBhbmQgKHR5cGVvZiBvLnVpZC5vcF9udW1iZXIgaXNudCBcInN0cmluZ1wiKVxuICAgICAgICBmb3IgdXNlciBpbiB1c2VyX2xpc3RcbiAgICAgICAgICBpZiB1c2VyLmdldFVzZXJJZCgpIGlzbnQgQEhCLmdldFVzZXJJZCgpXG4gICAgICAgICAgICB1c2VyLmdldENvbm5lY3RvcigpLnJlY2VpdmUobylcblxuICAgICNcbiAgICAjIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW5ldmVyIGFuIG9wZXJhdGlvbiB3YXMgcmVjZWl2ZWQgZnJvbSBhbm90aGVyIHBlZXIuXG4gICAgIyBAcGFyYW0ge09wZXJhdGlvbn0gbyBUaGUgb3BlcmF0aW9uIHRoYXQgd2FzIHJlY2VpdmVkLlxuICAgICNcbiAgICByZWNlaXZlOiAobyktPlxuICAgICAgQHVuZXhlY3V0ZWRbby51aWQuY3JlYXRvcl0gPz0gW11cbiAgICAgIEB1bmV4ZWN1dGVkW28udWlkLmNyZWF0b3JdLnB1c2ggb1xuXG4gICAgI1xuICAgICMgRmx1c2ggb25lIG9wZXJhdGlvbiBmcm9tIHRoZSBsaW5lIG9mIGEgc3BlY2lmaWMgdXNlci5cbiAgICAjXG4gICAgZmx1c2hPbmU6ICh1c2VyKS0+XG4gICAgICBpZiBAdW5leGVjdXRlZFt1c2VyXT8ubGVuZ3RoID4gMFxuICAgICAgICBAZW5naW5lLmFwcGx5T3AgQHVuZXhlY3V0ZWRbdXNlcl0uc2hpZnQoKVxuXG4gICAgI1xuICAgICMgRmx1c2ggb25lIG9wZXJhdGlvbiBvbiBhIHJhbmRvbSBsaW5lLlxuICAgICNcbiAgICBmbHVzaE9uZVJhbmRvbTogKCktPlxuICAgICAgQGZsdXNoT25lIChfLnJhbmRvbSAwLCAodXNlcl9saXN0Lmxlbmd0aC0xKSlcblxuICAgICNcbiAgICAjIEZsdXNoIGFsbCBvcGVyYXRpb25zIG9uIGV2ZXJ5IGxpbmUuXG4gICAgI1xuICAgIGZsdXNoQWxsOiAoKS0+XG4gICAgICBmb3IgbixvcHMgb2YgQHVuZXhlY3V0ZWRcbiAgICAgICAgQGVuZ2luZS5hcHBseU9wcyBvcHNcbiAgICAgIEB1bmV4ZWN1dGVkID0ge31cblxuIiwiXHJcbiNcclxuIyBAbm9kb2NcclxuIyBUaGUgRW5naW5lIGhhbmRsZXMgaG93IGFuZCBpbiB3aGljaCBvcmRlciB0byBleGVjdXRlIG9wZXJhdGlvbnMgYW5kIGFkZCBvcGVyYXRpb25zIHRvIHRoZSBIaXN0b3J5QnVmZmVyLlxyXG4jXHJcbmNsYXNzIEVuZ2luZVxyXG5cclxuICAjXHJcbiAgIyBAcGFyYW0ge0hpc3RvcnlCdWZmZXJ9IEhCXHJcbiAgIyBAcGFyYW0ge0FycmF5fSBwYXJzZXIgRGVmaW5lcyBob3cgdG8gcGFyc2UgZW5jb2RlZCBtZXNzYWdlcy5cclxuICAjXHJcbiAgY29uc3RydWN0b3I6IChASEIsIEBwYXJzZXIpLT5cclxuICAgIEB1bnByb2Nlc3NlZF9vcHMgPSBbXVxyXG5cclxuICAjXHJcbiAgIyBQYXJzZXMgYW4gb3BlcmF0aW8gZnJvbSB0aGUganNvbiBmb3JtYXQuIEl0IHVzZXMgdGhlIHNwZWNpZmllZCBwYXJzZXIgaW4geW91ciBPcGVyYXRpb25UeXBlIG1vZHVsZS5cclxuICAjXHJcbiAgcGFyc2VPcGVyYXRpb246IChqc29uKS0+XHJcbiAgICB0eXBlUGFyc2VyID0gQHBhcnNlcltqc29uLnR5cGVdXHJcbiAgICBpZiB0eXBlUGFyc2VyP1xyXG4gICAgICB0eXBlUGFyc2VyIGpzb25cclxuICAgIGVsc2VcclxuICAgICAgdGhyb3cgbmV3IEVycm9yIFwiWW91IGZvcmdvdCB0byBzcGVjaWZ5IGEgcGFyc2VyIGZvciB0eXBlICN7anNvbi50eXBlfS4gVGhlIG1lc3NhZ2UgaXMgI3tKU09OLnN0cmluZ2lmeSBqc29ufS5cIlxyXG5cclxuICAjXHJcbiAgIyBBcHBseSBhIHNldCBvZiBvcGVyYXRpb25zLiBFLmcuIHRoZSBvcGVyYXRpb25zIHlvdSByZWNlaXZlZCBmcm9tIGFub3RoZXIgdXNlcnMgSEIuX2VuY29kZSgpLlxyXG4gICMgQG5vdGUgWW91IG11c3Qgbm90IHVzZSB0aGlzIG1ldGhvZCB3aGVuIHlvdSBhbHJlYWR5IGhhdmUgb3BzIGluIHlvdXIgSEIhXHJcbiAgI1xyXG4gIGFwcGx5T3BzQnVuZGxlOiAob3BzX2pzb24pLT5cclxuICAgIG9wcyA9IFtdXHJcbiAgICBmb3IgbyBpbiBvcHNfanNvblxyXG4gICAgICBvcHMucHVzaCBAcGFyc2VPcGVyYXRpb24gb1xyXG4gICAgZm9yIG8gaW4gb3BzXHJcbiAgICAgIEBIQi5hZGRPcGVyYXRpb24gb1xyXG4gICAgZm9yIG8gaW4gb3BzXHJcbiAgICAgIGlmIG5vdCBvLmV4ZWN1dGUoKVxyXG4gICAgICAgIEB1bnByb2Nlc3NlZF9vcHMucHVzaCBvXHJcbiAgICBAdHJ5VW5wcm9jZXNzZWQoKVxyXG5cclxuICAjXHJcbiAgIyBTYW1lIGFzIGFwcGx5T3BzIGJ1dCBvcGVyYXRpb25zIHRoYXQgYXJlIGFscmVhZHkgaW4gdGhlIEhCIGFyZSBub3QgYXBwbGllZC5cclxuICAjIEBzZWUgRW5naW5lLmFwcGx5T3BzXHJcbiAgI1xyXG4gIGFwcGx5T3BzQ2hlY2tEb3VibGU6IChvcHNfanNvbiktPlxyXG4gICAgZm9yIG8gaW4gb3BzX2pzb25cclxuICAgICAgaWYgbm90IEBIQi5nZXRPcGVyYXRpb24oby51aWQpP1xyXG4gICAgICAgIEBhcHBseU9wIG9cclxuXHJcbiAgI1xyXG4gICMgQXBwbHkgYSBzZXQgb2Ygb3BlcmF0aW9ucy4gKEhlbHBlciBmb3IgdXNpbmcgYXBwbHlPcCBvbiBBcnJheXMpXHJcbiAgIyBAc2VlIEVuZ2luZS5hcHBseU9wXHJcbiAgYXBwbHlPcHM6IChvcHNfanNvbiktPlxyXG4gICAgZm9yIG8gaW4gb3BzX2pzb25cclxuICAgICAgQGFwcGx5T3Agb1xyXG5cclxuICAjXHJcbiAgIyBBcHBseSBhbiBvcGVyYXRpb24gdGhhdCB5b3UgcmVjZWl2ZWQgZnJvbSBhbm90aGVyIHBlZXIuXHJcbiAgI1xyXG4gIGFwcGx5T3A6IChvcF9qc29uKS0+XHJcbiAgICAjICRwYXJzZV9hbmRfZXhlY3V0ZSB3aWxsIHJldHVybiBmYWxzZSBpZiAkb19qc29uIHdhcyBwYXJzZWQgYW5kIGV4ZWN1dGVkLCBvdGhlcndpc2UgdGhlIHBhcnNlZCBvcGVyYWRpb25cclxuICAgIG8gPSBAcGFyc2VPcGVyYXRpb24gb3BfanNvblxyXG4gICAgQEhCLmFkZFRvQ291bnRlciBvXHJcbiAgICAjIEBIQi5hZGRPcGVyYXRpb24gb1xyXG4gICAgaWYgQEhCLmdldE9wZXJhdGlvbihvKT9cclxuICAgIGVsc2UgaWYgbm90IG8uZXhlY3V0ZSgpXHJcbiAgICAgIEB1bnByb2Nlc3NlZF9vcHMucHVzaCBvXHJcbiAgICBlbHNlXHJcbiAgICAgIEBIQi5hZGRPcGVyYXRpb24gb1xyXG4gICAgQHRyeVVucHJvY2Vzc2VkKClcclxuXHJcbiAgI1xyXG4gICMgQ2FsbCB0aGlzIG1ldGhvZCB3aGVuIHlvdSBhcHBsaWVkIGEgbmV3IG9wZXJhdGlvbi5cclxuICAjIEl0IGNoZWNrcyBpZiBvcGVyYXRpb25zIHRoYXQgd2VyZSBwcmV2aW91c2x5IG5vdCBleGVjdXRhYmxlIGFyZSBub3cgZXhlY3V0YWJsZS5cclxuICAjXHJcbiAgdHJ5VW5wcm9jZXNzZWQ6ICgpLT5cclxuICAgIHdoaWxlIHRydWVcclxuICAgICAgb2xkX2xlbmd0aCA9IEB1bnByb2Nlc3NlZF9vcHMubGVuZ3RoXHJcbiAgICAgIHVucHJvY2Vzc2VkID0gW11cclxuICAgICAgZm9yIG9wIGluIEB1bnByb2Nlc3NlZF9vcHNcclxuICAgICAgICBpZiBASEIuZ2V0T3BlcmF0aW9uKG9wKT9cclxuICAgICAgICBlbHNlIGlmIG5vdCBvcC5leGVjdXRlKClcclxuICAgICAgICAgIHVucHJvY2Vzc2VkLnB1c2ggb3BcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICBASEIuYWRkT3BlcmF0aW9uIG9wXHJcbiAgICAgIEB1bnByb2Nlc3NlZF9vcHMgPSB1bnByb2Nlc3NlZFxyXG4gICAgICBpZiBAdW5wcm9jZXNzZWRfb3BzLmxlbmd0aCBpcyBvbGRfbGVuZ3RoXHJcbiAgICAgICAgYnJlYWtcclxuXHJcblxyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gRW5naW5lXHJcblxyXG5cclxuXHJcblxyXG5cclxuXHJcblxyXG5cclxuXHJcblxyXG5cclxuXHJcbiIsIlxuanNvbl90eXBlc191bmluaXRpYWxpemVkID0gcmVxdWlyZSBcIi4uL1R5cGVzL0pzb25UeXBlc1wiXG5IaXN0b3J5QnVmZmVyID0gcmVxdWlyZSBcIi4uL0hpc3RvcnlCdWZmZXJcIlxuRW5naW5lID0gcmVxdWlyZSBcIi4uL0VuZ2luZVwiXG5cbiNcbiMgRnJhbWV3b3JrIGZvciBKc29uIGRhdGEtc3RydWN0dXJlcy5cbiMgS25vd24gdmFsdWVzIHRoYXQgYXJlIHN1cHBvcnRlZDpcbiMgKiBTdHJpbmdcbiMgKiBJbnRlZ2VyXG4jICogQXJyYXlcbiNcbmNsYXNzIEpzb25GcmFtZXdvcmtcblxuICAjXG4gICMgQHBhcmFtIHtTdHJpbmd9IHVzZXJfaWQgVW5pcXVlIGlkIG9mIHRoZSBwZWVyLlxuICAjIEBwYXJhbSB7Q29ubmVjdG9yfSBDb25uZWN0b3IgdGhlIGNvbm5lY3RvciBjbGFzcy5cbiAgI1xuICBjb25zdHJ1Y3RvcjogKHVzZXJfaWQsIENvbm5lY3RvciktPlxuICAgIEBIQiA9IG5ldyBIaXN0b3J5QnVmZmVyIHVzZXJfaWRcbiAgICB0eXBlX21hbmFnZXIgPSBqc29uX3R5cGVzX3VuaW5pdGlhbGl6ZWQgQEhCXG4gICAgQHR5cGVzID0gdHlwZV9tYW5hZ2VyLnR5cGVzXG4gICAgQGVuZ2luZSA9IG5ldyBFbmdpbmUgQEhCLCB0eXBlX21hbmFnZXIucGFyc2VyXG4gICAgQEhCLmVuZ2luZSA9IEBlbmdpbmUgIyBUT0RPOiAhISBvbmx5IGZvciBkZWJ1Z2dpbmdcbiAgICBAY29ubmVjdG9yID0gbmV3IENvbm5lY3RvciBAZW5naW5lLCBASEIsIHR5cGVfbWFuYWdlci5leGVjdXRpb25fbGlzdGVuZXIsIEBcbiAgICBmaXJzdF93b3JkID0gbmV3IEB0eXBlcy5Kc29uVHlwZShASEIuZ2V0UmVzZXJ2ZWRVbmlxdWVJZGVudGlmaWVyKCkpXG4gICAgQEhCLmFkZE9wZXJhdGlvbihmaXJzdF93b3JkKS5leGVjdXRlKClcblxuICAgIHVpZF9iZWcgPSBASEIuZ2V0UmVzZXJ2ZWRVbmlxdWVJZGVudGlmaWVyKClcbiAgICB1aWRfZW5kID0gQEhCLmdldFJlc2VydmVkVW5pcXVlSWRlbnRpZmllcigpXG4gICAgYmVnID0gQEhCLmFkZE9wZXJhdGlvbihuZXcgQHR5cGVzLkRlbGltaXRlciB1aWRfYmVnLCB1bmRlZmluZWQsIHVpZF9lbmQpLmV4ZWN1dGUoKVxuICAgIGVuZCA9IEBIQi5hZGRPcGVyYXRpb24obmV3IEB0eXBlcy5EZWxpbWl0ZXIgdWlkX2VuZCwgYmVnLCB1bmRlZmluZWQpLmV4ZWN1dGUoKVxuXG4gICAgQHJvb3RfZWxlbWVudCA9IG5ldyBAdHlwZXMuUmVwbGFjZU1hbmFnZXIgdW5kZWZpbmVkLCBASEIuZ2V0UmVzZXJ2ZWRVbmlxdWVJZGVudGlmaWVyKCksIGJlZywgZW5kXG4gICAgQEhCLmFkZE9wZXJhdGlvbihAcm9vdF9lbGVtZW50KS5leGVjdXRlKClcbiAgICBAcm9vdF9lbGVtZW50LnJlcGxhY2UgZmlyc3Rfd29yZCwgQEhCLmdldFJlc2VydmVkVW5pcXVlSWRlbnRpZmllcigpXG5cbiAgI1xuICAjIEByZXR1cm4gSnNvblR5cGVcbiAgI1xuICBnZXRTaGFyZWRPYmplY3Q6ICgpLT5cbiAgICBAcm9vdF9lbGVtZW50LnZhbCgpXG5cbiAgI1xuICAjIEdldCB0aGUgaW5pdGlhbGl6ZWQgY29ubmVjdG9yLlxuICAjXG4gIGdldENvbm5lY3RvcjogKCktPlxuICAgIEBjb25uZWN0b3JcblxuICAjXG4gICMgQHNlZSBIaXN0b3J5QnVmZmVyXG4gICNcbiAgZ2V0SGlzdG9yeUJ1ZmZlcjogKCktPlxuICAgIEBIQlxuXG4gICNcbiAgIyBAc2VlIEpzb25UeXBlLnNldE11dGFibGVEZWZhdWx0XG4gICNcbiAgc2V0TXV0YWJsZURlZmF1bHQ6IChtdXRhYmxlKS0+XG4gICAgQGdldFNoYXJlZE9iamVjdCgpLnNldE11dGFibGVEZWZhdWx0KG11dGFibGUpXG5cbiAgI1xuICAjIEdldCB0aGUgVXNlcklkIGZyb20gdGhlIEhpc3RvcnlCdWZmZXIgb2JqZWN0LlxuICAjIEluIG1vc3QgY2FzZXMgdGhpcyB3aWxsIGJlIHRoZSBzYW1lIGFzIHRoZSB1c2VyX2lkIHZhbHVlIHdpdGggd2hpY2hcbiAgIyBKc29uRnJhbWV3b3JrIHdhcyBpbml0aWFsaXplZCAoRGVwZW5kaW5nIG9uIHRoZSBIaXN0b3J5QnVmZmVyIGltcGxlbWVudGF0aW9uKS5cbiAgI1xuICBnZXRVc2VySWQ6ICgpLT5cbiAgICBASEIuZ2V0VXNlcklkKClcblxuICAjXG4gICMgQHNlZSBKc29uVHlwZS50b0pzb25cbiAgI1xuICB0b0pzb24gOiAoKS0+XG4gICAgQGdldFNoYXJlZE9iamVjdCgpLnRvSnNvbigpXG5cbiAgI1xuICAjIEBzZWUgSnNvblR5cGUudmFsXG4gICNcbiAgdmFsIDogKG5hbWUsIGNvbnRlbnQsIG11dGFibGUpLT5cbiAgICBAZ2V0U2hhcmVkT2JqZWN0KCkudmFsKG5hbWUsIGNvbnRlbnQsIG11dGFibGUpXG5cbiAgI1xuICAjIEBzZWUgT3BlcmF0aW9uLm9uXG4gICNcbiAgb246ICgpLT5cbiAgICBAZ2V0U2hhcmVkT2JqZWN0KCkub24gYXJndW1lbnRzLi4uXG5cbiAgI1xuICAjIEBzZWUgT3BlcmF0aW9uLmRlbGV0ZUxpc3RlbmVyXG4gICNcbiAgZGVsZXRlTGlzdGVuZXI6ICgpLT5cbiAgICBAZ2V0U2hhcmVkT2JqZWN0KCkuZGVsZXRlTGlzdGVuZXIgYXJndW1lbnRzLi4uXG5cbiAgI1xuICAjIEBzZWUgSnNvblR5cGUudmFsdWVcbiAgI1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkgSnNvbkZyYW1ld29yay5wcm90b3R5cGUsICd2YWx1ZScsXG4gICAgZ2V0IDogLT4gQGdldFNoYXJlZE9iamVjdCgpLnZhbHVlXG4gICAgc2V0IDogKG8pLT5cbiAgICAgIGlmIG8uY29uc3RydWN0b3IgaXMge30uY29uc3RydWN0b3JcbiAgICAgICAgZm9yIG9fbmFtZSxvX29iaiBvZiBvXG4gICAgICAgICAgQHZhbChvX25hbWUsIG9fb2JqLCAnaW1tdXRhYmxlJylcbiAgICAgIGVsc2VcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yIFwiWW91IG11c3Qgb25seSBzZXQgT2JqZWN0IHZhbHVlcyFcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IEpzb25GcmFtZXdvcmtcbmlmIHdpbmRvdz9cbiAgaWYgbm90IHdpbmRvdy5ZP1xuICAgIHdpbmRvdy5ZID0ge31cbiAgd2luZG93LlkuSnNvbkZyYW1ld29yayA9IEpzb25GcmFtZXdvcmtcbiIsIlxudGV4dF90eXBlc191bmluaXRpYWxpemVkID0gcmVxdWlyZSBcIi4uL1R5cGVzL1RleHRUeXBlc1wiXG5IaXN0b3J5QnVmZmVyID0gcmVxdWlyZSBcIi4uL0hpc3RvcnlCdWZmZXJcIlxuRW5naW5lID0gcmVxdWlyZSBcIi4uL0VuZ2luZVwiXG5cbiNcbiMgRnJhbWV3b3JrIGZvciBUZXh0IERhdGFzdHJ1Y3R1cmVzLlxuI1xuY2xhc3MgVGV4dEZyYW1ld29ya1xuXG4gICNcbiAgIyBAcGFyYW0ge1N0cmluZ30gdXNlcl9pZCBVbmlxZSB1c2VyIGlkIHRoYXQgZGVmaW5lcyB0aGlzIHBlZXIuXG4gICMgQHBhcmFtIHtDb25uZWN0b3J9IENvbm5lY3RvciBUaGUgY29ubmVjdG9yIGRlZmluZXMgaG93IHlvdSBjb25uZWN0IHRvIHRoZSBvdGhlciBwZWVycy5cbiAgI1xuICBjb25zdHJ1Y3RvcjogKHVzZXJfaWQsIENvbm5lY3RvciktPlxuICAgIEBIQiA9IG5ldyBIaXN0b3J5QnVmZmVyIHVzZXJfaWRcbiAgICB0ZXh0X3R5cGVzID0gdGV4dF90eXBlc191bmluaXRpYWxpemVkIEBIQlxuICAgIEB0eXBlcyA9IHRleHRfdHlwZXMudHlwZXNcbiAgICBAZW5naW5lID0gbmV3IEVuZ2luZSBASEIsIHRleHRfdHlwZXMucGFyc2VyXG4gICAgQGNvbm5lY3RvciA9IG5ldyBDb25uZWN0b3IgQGVuZ2luZSwgQEhCLCB0ZXh0X3R5cGVzLmV4ZWN1dGlvbl9saXN0ZW5lciwgQFxuXG4gICAgYmVnaW5uaW5nID0gQEhCLmFkZE9wZXJhdGlvbiBuZXcgQHR5cGVzLkRlbGltaXRlciB7Y3JlYXRvcjogJ18nLCBvcF9udW1iZXI6ICdfYmVnaW5uaW5nJ30gLCB1bmRlZmluZWQsIHVuZGVmaW5lZFxuICAgIGVuZCA9ICAgICAgIEBIQi5hZGRPcGVyYXRpb24gbmV3IEB0eXBlcy5EZWxpbWl0ZXIge2NyZWF0b3I6ICdfJywgb3BfbnVtYmVyOiAnX2VuZCd9ICAgICAgICwgYmVnaW5uaW5nLCB1bmRlZmluZWRcbiAgICBiZWdpbm5pbmcubmV4dF9jbCA9IGVuZFxuICAgIGJlZ2lubmluZy5leGVjdXRlKClcbiAgICBlbmQuZXhlY3V0ZSgpXG4gICAgZmlyc3Rfd29yZCA9IG5ldyBAdHlwZXMuV29yZFR5cGUge2NyZWF0b3I6ICdfJywgb3BfbnVtYmVyOiAnXyd9LCBiZWdpbm5pbmcsIGVuZFxuICAgIEBIQi5hZGRPcGVyYXRpb24oZmlyc3Rfd29yZCkuZXhlY3V0ZSgpXG5cbiAgICB1aWRfciA9IHsgY3JlYXRvcjogJ18nLCBvcF9udW1iZXI6IFwiUk1cIiB9XG4gICAgdWlkX2JlZyA9IHsgY3JlYXRvcjogJ18nLCBvcF9udW1iZXI6IFwiX1JNX2JlZ2lubmluZ1wiIH1cbiAgICB1aWRfZW5kID0geyBjcmVhdG9yOiAnXycsIG9wX251bWJlcjogXCJfUk1fZW5kXCIgfVxuICAgIGJlZyA9IEBIQi5hZGRPcGVyYXRpb24obmV3IEB0eXBlcy5EZWxpbWl0ZXIgdWlkX2JlZywgdW5kZWZpbmVkLCB1aWRfZW5kKS5leGVjdXRlKClcbiAgICBlbmQgPSBASEIuYWRkT3BlcmF0aW9uKG5ldyBAdHlwZXMuRGVsaW1pdGVyIHVpZF9lbmQsIGJlZywgdW5kZWZpbmVkKS5leGVjdXRlKClcbiAgICBAcm9vdF9lbGVtZW50ID0gQEhCLmFkZE9wZXJhdGlvbihuZXcgQHR5cGVzLlJlcGxhY2VNYW5hZ2VyIHVuZGVmaW5lZCwgdWlkX3IsIGJlZywgZW5kKS5leGVjdXRlKClcbiAgICBAcm9vdF9lbGVtZW50LnJlcGxhY2UgZmlyc3Rfd29yZCwgeyBjcmVhdG9yOiAnXycsIG9wX251bWJlcjogJ1JlcGxhY2VhYmxlJ31cblxuXG4gICNcbiAgIyBAcmV0dXJuIFdvcmRUeXBlXG4gICNcbiAgZ2V0U2hhcmVkT2JqZWN0OiAoKS0+XG4gICAgQHJvb3RfZWxlbWVudC52YWwoKVxuXG4gICNcbiAgIyBHZXQgdGhlIGluaXRpYWxpemVkIGNvbm5lY3Rvci5cbiAgI1xuICBnZXRDb25uZWN0b3I6ICgpLT5cbiAgICBAY29ubmVjdG9yXG5cbiAgI1xuICAjIEBzZWUgSGlzdG9yeUJ1ZmZlclxuICAjXG4gIGdldEhpc3RvcnlCdWZmZXI6ICgpLT5cbiAgICBASEJcblxuICAjXG4gICMgR2V0IHRoZSBVc2VySWQgZnJvbSB0aGUgSGlzdG9yeUJ1ZmZlciBvYmplY3QuXG4gICMgSW4gbW9zdCBjYXNlcyB0aGlzIHdpbGwgYmUgdGhlIHNhbWUgYXMgdGhlIHVzZXJfaWQgdmFsdWUgd2l0aCB3aGljaFxuICAjIEpzb25GcmFtZXdvcmsgd2FzIGluaXRpYWxpemVkIChEZXBlbmRpbmcgb24gdGhlIEhpc3RvcnlCdWZmZXIgaW1wbGVtZW50YXRpb24pLlxuICAjXG4gIGdldFVzZXJJZDogKCktPlxuICAgIEBIQi5nZXRVc2VySWQoKVxuXG4gICNcbiAgIyBAc2VlIEpzb25UeXBlLnZhbFxuICAjXG4gIHZhbDogKCktPlxuICAgIEBnZXRTaGFyZWRPYmplY3QoKS52YWwoKVxuXG4gICNcbiAgIyBAc2VlIFdvcmRUeXBlLmluc2VydFRleHRcbiAgI1xuICBpbnNlcnRUZXh0OiAocG9zLCBjb250ZW50KS0+XG4gICAgQGdldFNoYXJlZE9iamVjdCgpLmluc2VydFRleHQgcG9zLCBjb250ZW50XG5cbiAgI1xuICAjIEBzZWUgV29yZFR5cGUuZGVsZXRlVGV4dFxuICAjXG4gIGRlbGV0ZVRleHQ6IChwb3MsIGxlbmd0aCktPlxuICAgIEBnZXRTaGFyZWRPYmplY3QoKS5kZWxldGVUZXh0IHBvcywgbGVuZ3RoXG5cbiAgI1xuICAjIEBzZWUgV29yZFR5cGUuYmluZFxuICAjXG4gIGJpbmQ6ICh0ZXh0YXJlYSktPlxuICAgIEBnZXRTaGFyZWRPYmplY3QoKS5iaW5kIHRleHRhcmVhXG5cbiAgI1xuICAjIEBzZWUgV29yZFR5cGUucmVwbGFjZVRleHRcbiAgI1xuICByZXBsYWNlVGV4dDogKHRleHQpLT5cbiAgICBAZ2V0U2hhcmVkT2JqZWN0KCkucmVwbGFjZVRleHQgdGV4dFxuXG4gICNcbiAgIyBAc2VlIE9wZXJhdGlvbi5vblxuICAjXG4gIG9uOiAoKS0+XG4gICAgQHJvb3RfZWxlbWVudC5vbiBhcmd1bWVudHMuLi5cblxuXG5tb2R1bGUuZXhwb3J0cyA9IFRleHRGcmFtZXdvcmtcbmlmIHdpbmRvdz9cbiAgaWYgbm90IHdpbmRvdy5ZP1xuICAgIHdpbmRvdy5ZID0ge31cbiAgd2luZG93LlkuVGV4dEZyYW1ld29yayA9IFRleHRGcmFtZXdvcmtcbiIsIlxuanNvbl90eXBlc191bmluaXRpYWxpemVkID0gcmVxdWlyZSBcIi4uL1R5cGVzL1htbFR5cGVzXCJcbkhpc3RvcnlCdWZmZXIgPSByZXF1aXJlIFwiLi4vSGlzdG9yeUJ1ZmZlclwiXG5FbmdpbmUgPSByZXF1aXJlIFwiLi4vRW5naW5lXCJcblxuI1xuIyBGcmFtZXdvcmsgZm9yIFhtbC1saWtlIGRhdGEtc3RydWN0dXJlcy5cbiMgS25vd24gdmFsdWVzIHRoYXQgYXJlIHN1cHBvcnRlZDpcbiNcbmNsYXNzIFhtbEZyYW1ld29ya1xuXG4gICNcbiAgIyBAcGFyYW0ge1N0cmluZ30gdXNlcl9pZCBVbmlxdWUgaWQgb2YgdGhlIHBlZXIuXG4gICMgQHBhcmFtIHtDb25uZWN0b3J9IENvbm5lY3RvciB0aGUgY29ubmVjdG9yIGNsYXNzLlxuICAjXG4gIGNvbnN0cnVjdG9yOiAodXNlcl9pZCwgQ29ubmVjdG9yKS0+XG4gICAgQEhCID0gbmV3IEhpc3RvcnlCdWZmZXIgdXNlcl9pZFxuICAgIHR5cGVfbWFuYWdlciA9IGpzb25fdHlwZXNfdW5pbml0aWFsaXplZCBASEJcbiAgICBAdHlwZXMgPSB0eXBlX21hbmFnZXIudHlwZXNcbiAgICBAZW5naW5lID0gbmV3IEVuZ2luZSBASEIsIHR5cGVfbWFuYWdlci5wYXJzZXJcbiAgICBASEIuZW5naW5lID0gQGVuZ2luZSAjIFRPRE86ICEhIG9ubHkgZm9yIGRlYnVnZ2luZ1xuICAgIEBjb25uZWN0b3IgPSBuZXcgQ29ubmVjdG9yIEBlbmdpbmUsIEBIQiwgdHlwZV9tYW5hZ2VyLmV4ZWN1dGlvbl9saXN0ZW5lciwgQFxuICAgICNmaXJzdF93b3JkID0gbmV3IEB0eXBlcy5YbWxUeXBlKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNoYXJlZFwiKSlcbiAgICAjQEhCLmFkZE9wZXJhdGlvbihmaXJzdF93b3JkKS5leGVjdXRlKClcblxuICAgIHVpZF9iZWcgPSBASEIuZ2V0UmVzZXJ2ZWRVbmlxdWVJZGVudGlmaWVyKClcbiAgICB1aWRfZW5kID0gQEhCLmdldFJlc2VydmVkVW5pcXVlSWRlbnRpZmllcigpXG4gICAgYmVnID0gQEhCLmFkZE9wZXJhdGlvbihuZXcgQHR5cGVzLkRlbGltaXRlciB1aWRfYmVnLCB1bmRlZmluZWQsIHVpZF9lbmQpLmV4ZWN1dGUoKVxuICAgIGVuZCA9IEBIQi5hZGRPcGVyYXRpb24obmV3IEB0eXBlcy5EZWxpbWl0ZXIgdWlkX2VuZCwgYmVnLCB1bmRlZmluZWQpLmV4ZWN1dGUoKVxuXG4gICAgQHJvb3RfZWxlbWVudCA9IG5ldyBAdHlwZXMuUmVwbGFjZU1hbmFnZXIgdW5kZWZpbmVkLCBASEIuZ2V0UmVzZXJ2ZWRVbmlxdWVJZGVudGlmaWVyKCksIGJlZywgZW5kXG4gICAgQEhCLmFkZE9wZXJhdGlvbihAcm9vdF9lbGVtZW50KS5leGVjdXRlKClcbiAgICAjQHJvb3RfZWxlbWVudC5yZXBsYWNlIGZpcnN0X3dvcmRcblxuICAjXG4gICMgQHJldHVybiBKc29uVHlwZVxuICAjXG4gIGdldFNoYXJlZE9iamVjdDogKCktPlxuICAgIEByb290X2VsZW1lbnQudmFsKClcblxuICAjXG4gICMgR2V0IHRoZSBpbml0aWFsaXplZCBjb25uZWN0b3IuXG4gICNcbiAgZ2V0Q29ubmVjdG9yOiAoKS0+XG4gICAgQGNvbm5lY3RvclxuXG4gICNcbiAgIyBAc2VlIEhpc3RvcnlCdWZmZXJcbiAgI1xuICBnZXRIaXN0b3J5QnVmZmVyOiAoKS0+XG4gICAgQEhCXG5cbiAgI1xuICAjIEBzZWUgSnNvblR5cGUuc2V0TXV0YWJsZURlZmF1bHRcbiAgI1xuICBzZXRNdXRhYmxlRGVmYXVsdDogKG11dGFibGUpLT5cbiAgICBAZ2V0U2hhcmVkT2JqZWN0KCkuc2V0TXV0YWJsZURlZmF1bHQobXV0YWJsZSlcblxuICAjXG4gICMgR2V0IHRoZSBVc2VySWQgZnJvbSB0aGUgSGlzdG9yeUJ1ZmZlciBvYmplY3QuXG4gICMgSW4gbW9zdCBjYXNlcyB0aGlzIHdpbGwgYmUgdGhlIHNhbWUgYXMgdGhlIHVzZXJfaWQgdmFsdWUgd2l0aCB3aGljaFxuICAjIEpzb25GcmFtZXdvcmsgd2FzIGluaXRpYWxpemVkIChEZXBlbmRpbmcgb24gdGhlIEhpc3RvcnlCdWZmZXIgaW1wbGVtZW50YXRpb24pLlxuICAjXG4gIGdldFVzZXJJZDogKCktPlxuICAgIEBIQi5nZXRVc2VySWQoKVxuXG4gICNcbiAgIyBAc2VlIEpzb25UeXBlLnRvSnNvblxuICAjXG4gIHRvSnNvbiA6ICgpLT5cbiAgICBAZ2V0U2hhcmVkT2JqZWN0KCkudG9Kc29uKClcblxuICAjXG4gICMgQHNlZSBKc29uVHlwZS52YWxcbiAgI1xuICB2YWwgOiAoKS0+XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggaXMgMCkgb3IgKHR5cGVvZiBhcmd1bWVudHNbMF0gaXMgXCJib29sZWFuXCIpXG4gICAgICBAZ2V0U2hhcmVkT2JqZWN0KCkudmFsKGFyZ3VtZW50c1swXSlcbiAgICBlbHNlIGlmIGFyZ3VtZW50cy5sZW5ndGggaXMgMVxuICAgICAgbmV3WG1sID0gbmV3IEB0eXBlcy5YbWxUeXBlKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgYXJndW1lbnRzWzBdKVxuICAgICAgQEhCLmFkZE9wZXJhdGlvbihuZXdYbWwpLmV4ZWN1dGUoKVxuICAgICAgQHJvb3RfZWxlbWVudC5yZXBsYWNlIG5ld1htbFxuICAgICAgbmV3WG1sXG4gICAgZWxzZVxuICAgICAgdGhyb3cgbmV3IEVycm9yIFwiY2FuIG9ubHkgcGFyc2UgMCwgb3IgMSBwYXJhbWV0ZXIhXCJcblxuXG4gICNcbiAgIyBAc2VlIE9wZXJhdGlvbi5vblxuICAjXG4gIG9uOiAoKS0+XG4gICAgQGdldFNoYXJlZE9iamVjdCgpLm9uIGFyZ3VtZW50cy4uLlxuXG5cblxubW9kdWxlLmV4cG9ydHMgPSBYbWxGcmFtZXdvcmtcbmlmIHdpbmRvdz9cbiAgaWYgbm90IHdpbmRvdy5ZP1xuICAgIHdpbmRvdy5ZID0ge31cbiAgd2luZG93LlkuWG1sRnJhbWV3b3JrID0gWG1sRnJhbWV3b3JrXG4iLCJcbiNcbiMgQG5vZG9jXG4jIEFuIG9iamVjdCB0aGF0IGhvbGRzIGFsbCBhcHBsaWVkIG9wZXJhdGlvbnMuXG4jXG4jIEBub3RlIFRoZSBIaXN0b3J5QnVmZmVyIGlzIGNvbW1vbmx5IGFiYnJldmlhdGVkIHRvIEhCLlxuI1xuY2xhc3MgSGlzdG9yeUJ1ZmZlclxuXG5cblxuICAjXG4gICMgQ3JlYXRlcyBhbiBlbXB0eSBIQi5cbiAgIyBAcGFyYW0ge09iamVjdH0gdXNlcl9pZCBDcmVhdG9yIG9mIHRoZSBIQi5cbiAgI1xuICBjb25zdHJ1Y3RvcjogKEB1c2VyX2lkKS0+XG4gICAgQG9wZXJhdGlvbl9jb3VudGVyID0ge31cbiAgICBAYnVmZmVyID0ge31cbiAgICBAY2hhbmdlX2xpc3RlbmVycyA9IFtdXG4gICAgQGdhcmJhZ2UgPSBbXSAjIFdpbGwgYmUgY2xlYW5lZCBvbiBuZXh0IGNhbGwgb2YgZ2FyYmFnZUNvbGxlY3RvclxuICAgIEB0cmFzaCA9IFtdICMgSXMgZGVsZXRlZC4gV2FpdCB1bnRpbCBpdCBpcyBub3QgdXNlZCBhbnltb3JlLlxuICAgIEBwZXJmb3JtR2FyYmFnZUNvbGxlY3Rpb24gPSB0cnVlXG4gICAgQGdhcmJhZ2VDb2xsZWN0VGltZW91dCA9IDEwMDBcbiAgICBAcmVzZXJ2ZWRfaWRlbnRpZmllcl9jb3VudGVyID0gMFxuICAgIHNldFRpbWVvdXQgQGVtcHR5R2FyYmFnZSwgQGdhcmJhZ2VDb2xsZWN0VGltZW91dFxuXG4gIGVtcHR5R2FyYmFnZTogKCk9PlxuICAgIGZvciBvIGluIEBnYXJiYWdlXG4gICAgICAjaWYgQGdldE9wZXJhdGlvbkNvdW50ZXIoby5jcmVhdG9yKSA+IG8ub3BfbnVtYmVyXG4gICAgICBvLmNsZWFudXA/KClcblxuICAgIEBnYXJiYWdlID0gQHRyYXNoXG4gICAgQHRyYXNoID0gW11cbiAgICBpZiBAZ2FyYmFnZUNvbGxlY3RUaW1lb3V0IGlzbnQgLTFcbiAgICAgIEBnYXJiYWdlQ29sbGVjdFRpbWVvdXRJZCA9IHNldFRpbWVvdXQgQGVtcHR5R2FyYmFnZSwgQGdhcmJhZ2VDb2xsZWN0VGltZW91dFxuICAgIHVuZGVmaW5lZFxuXG4gICNcbiAgIyBHZXQgdGhlIHVzZXIgaWQgd2l0aCB3aWNoIHRoZSBIaXN0b3J5IEJ1ZmZlciB3YXMgaW5pdGlhbGl6ZWQuXG4gICNcbiAgZ2V0VXNlcklkOiAoKS0+XG4gICAgQHVzZXJfaWRcblxuICBhZGRUb0dhcmJhZ2VDb2xsZWN0b3I6ICgpLT5cbiAgICBpZiBAcGVyZm9ybUdhcmJhZ2VDb2xsZWN0aW9uXG4gICAgICBmb3IgbyBpbiBhcmd1bWVudHNcbiAgICAgICAgaWYgbz9cbiAgICAgICAgICBAZ2FyYmFnZS5wdXNoIG9cblxuICBzdG9wR2FyYmFnZUNvbGxlY3Rpb246ICgpLT5cbiAgICBAcGVyZm9ybUdhcmJhZ2VDb2xsZWN0aW9uID0gZmFsc2VcbiAgICBAc2V0TWFudWFsR2FyYmFnZUNvbGxlY3QoKVxuICAgIEBnYXJiYWdlID0gW11cbiAgICBAdHJhc2ggPSBbXVxuXG4gIHNldE1hbnVhbEdhcmJhZ2VDb2xsZWN0OiAoKS0+XG4gICAgQGdhcmJhZ2VDb2xsZWN0VGltZW91dCA9IC0xXG4gICAgY2xlYXJUaW1lb3V0IEBnYXJiYWdlQ29sbGVjdFRpbWVvdXRJZFxuICAgIEBnYXJiYWdlQ29sbGVjdFRpbWVvdXRJZCA9IHVuZGVmaW5lZFxuXG4gIHNldEdhcmJhZ2VDb2xsZWN0VGltZW91dDogKEBnYXJiYWdlQ29sbGVjdFRpbWVvdXQpLT5cblxuICAjXG4gICMgSSBwcm9wb3NlIHRvIHVzZSBpdCBpbiB5b3VyIEZyYW1ld29yaywgdG8gY3JlYXRlIHNvbWV0aGluZyBsaWtlIGEgcm9vdCBlbGVtZW50LlxuICAjIEFuIG9wZXJhdGlvbiB3aXRoIHRoaXMgaWRlbnRpZmllciBpcyBub3QgcHJvcGFnYXRlZCB0byBvdGhlciBjbGllbnRzLlxuICAjIFRoaXMgaXMgd2h5IGV2ZXJ5Ym9kZSBtdXN0IGNyZWF0ZSB0aGUgc2FtZSBvcGVyYXRpb24gd2l0aCB0aGlzIHVpZC5cbiAgI1xuICBnZXRSZXNlcnZlZFVuaXF1ZUlkZW50aWZpZXI6ICgpLT5cbiAgICB7XG4gICAgICBjcmVhdG9yIDogJ18nXG4gICAgICBvcF9udW1iZXIgOiBcIl8je0ByZXNlcnZlZF9pZGVudGlmaWVyX2NvdW50ZXIrK31cIlxuICAgICAgZG9TeW5jOiBmYWxzZVxuICAgIH1cblxuICAjXG4gICMgR2V0IHRoZSBvcGVyYXRpb24gY291bnRlciB0aGF0IGRlc2NyaWJlcyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgZG9jdW1lbnQuXG4gICNcbiAgZ2V0T3BlcmF0aW9uQ291bnRlcjogKHVzZXJfaWQpLT5cbiAgICBpZiBub3QgdXNlcl9pZD9cbiAgICAgIHJlcyA9IHt9XG4gICAgICBmb3IgdXNlcixjdG4gb2YgQG9wZXJhdGlvbl9jb3VudGVyXG4gICAgICAgIHJlc1t1c2VyXSA9IGN0blxuICAgICAgcmVzXG4gICAgZWxzZVxuICAgICAgQG9wZXJhdGlvbl9jb3VudGVyW3VzZXJfaWRdXG5cblxuICAjXG4gICMgRW5jb2RlIHRoaXMgb3BlcmF0aW9uIGluIHN1Y2ggYSB3YXkgdGhhdCBpdCBjYW4gYmUgcGFyc2VkIGJ5IHJlbW90ZSBwZWVycy5cbiAgIyBUT0RPOiBNYWtlIHRoaXMgbW9yZSBlZmZpY2llbnQhXG4gIF9lbmNvZGU6IChzdGF0ZV92ZWN0b3I9e30pLT5cbiAgICBqc29uID0gW11cbiAgICB1bmtub3duID0gKHVzZXIsIG9fbnVtYmVyKS0+XG4gICAgICBpZiAobm90IHVzZXI/KSBvciAobm90IG9fbnVtYmVyPylcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yIFwiZGFoIVwiXG4gICAgICBub3Qgc3RhdGVfdmVjdG9yW3VzZXJdPyBvciBzdGF0ZV92ZWN0b3JbdXNlcl0gPD0gb19udW1iZXJcblxuICAgIGZvciB1X25hbWUsdXNlciBvZiBAYnVmZmVyXG4gICAgICBmb3Igb19udW1iZXIsbyBvZiB1c2VyXG4gICAgICAgIGlmIG8uZG9TeW5jIGFuZCB1bmtub3duKHVfbmFtZSwgb19udW1iZXIpXG4gICAgICAgICAgIyBpdHMgbmVjZXNzYXJ5IHRvIHNlbmQgaXQsIGFuZCBub3Qga25vd24gaW4gc3RhdGVfdmVjdG9yXG4gICAgICAgICAgb19qc29uID0gby5fZW5jb2RlKClcbiAgICAgICAgICBpZiBvLm5leHRfY2w/ICMgYXBwbGllcyBmb3IgYWxsIG9wcyBidXQgdGhlIG1vc3QgcmlnaHQgZGVsaW1pdGVyIVxuICAgICAgICAgICAgIyBzZWFyY2ggZm9yIHRoZSBuZXh0IF9rbm93bl8gb3BlcmF0aW9uLiAoV2hlbiBzdGF0ZV92ZWN0b3IgaXMge30gdGhlbiB0aGlzIGlzIHRoZSBEZWxpbWl0ZXIpXG4gICAgICAgICAgICBvX25leHQgPSBvLm5leHRfY2xcbiAgICAgICAgICAgIHdoaWxlIG9fbmV4dC5uZXh0X2NsPyBhbmQgdW5rbm93bihvX25leHQuY3JlYXRvciwgb19uZXh0Lm9wX251bWJlcilcbiAgICAgICAgICAgICAgb19uZXh0ID0gb19uZXh0Lm5leHRfY2xcbiAgICAgICAgICAgIG9fanNvbi5uZXh0ID0gb19uZXh0LmdldFVpZCgpXG4gICAgICAgICAgZWxzZSBpZiBvLnByZXZfY2w/ICMgbW9zdCByaWdodCBkZWxpbWl0ZXIgb25seSFcbiAgICAgICAgICAgICMgc2FtZSBhcyB0aGUgYWJvdmUgd2l0aCBwcmV2LlxuICAgICAgICAgICAgb19wcmV2ID0gby5wcmV2X2NsXG4gICAgICAgICAgICB3aGlsZSBvX3ByZXYucHJldl9jbD8gYW5kIHVua25vd24ob19wcmV2LmNyZWF0b3IsIG9fcHJldi5vcF9udW1iZXIpXG4gICAgICAgICAgICAgIG9fcHJldiA9IG9fcHJldi5wcmV2X2NsXG4gICAgICAgICAgICBvX2pzb24ucHJldiA9IG9fcHJldi5nZXRVaWQoKVxuICAgICAgICAgIGpzb24ucHVzaCBvX2pzb25cblxuICAgIGpzb25cblxuICAjXG4gICMgR2V0IHRoZSBudW1iZXIgb2Ygb3BlcmF0aW9ucyB0aGF0IHdlcmUgY3JlYXRlZCBieSBhIHVzZXIuXG4gICMgQWNjb3JkaW5nbHkgeW91IHdpbGwgZ2V0IHRoZSBuZXh0IG9wZXJhdGlvbiBudW1iZXIgdGhhdCBpcyBleHBlY3RlZCBmcm9tIHRoYXQgdXNlci5cbiAgIyBUaGlzIHdpbGwgaW5jcmVtZW50IHRoZSBvcGVyYXRpb24gY291bnRlci5cbiAgI1xuICBnZXROZXh0T3BlcmF0aW9uSWRlbnRpZmllcjogKHVzZXJfaWQpLT5cbiAgICBpZiBub3QgdXNlcl9pZD9cbiAgICAgIHVzZXJfaWQgPSBAdXNlcl9pZFxuICAgIGlmIG5vdCBAb3BlcmF0aW9uX2NvdW50ZXJbdXNlcl9pZF0/XG4gICAgICBAb3BlcmF0aW9uX2NvdW50ZXJbdXNlcl9pZF0gPSAwXG4gICAgdWlkID1cbiAgICAgICdjcmVhdG9yJyA6IHVzZXJfaWRcbiAgICAgICdvcF9udW1iZXInIDogQG9wZXJhdGlvbl9jb3VudGVyW3VzZXJfaWRdXG4gICAgQG9wZXJhdGlvbl9jb3VudGVyW3VzZXJfaWRdKytcbiAgICB1aWRcblxuICAjXG4gICMgUmV0cmlldmUgYW4gb3BlcmF0aW9uIGZyb20gYSB1bmlxdWUgaWQuXG4gICNcbiAgZ2V0T3BlcmF0aW9uOiAodWlkKS0+XG4gICAgaWYgdWlkIGluc3RhbmNlb2YgT2JqZWN0XG4gICAgICBAYnVmZmVyW3VpZC5jcmVhdG9yXT9bdWlkLm9wX251bWJlcl1cbiAgICBlbHNlIGlmIG5vdCB1aWQ/XG4gICAgZWxzZVxuICAgICAgdGhyb3cgbmV3IEVycm9yIFwiVGhpcyB0eXBlIG9mIHVpZCBpcyBub3QgZGVmaW5lZCFcIlxuICAjXG4gICMgQWRkIGFuIG9wZXJhdGlvbiB0byB0aGUgSEIuIE5vdGUgdGhhdCB0aGlzIHdpbGwgbm90IGxpbmsgaXQgYWdhaW5zdFxuICAjIG90aGVyIG9wZXJhdGlvbnMgKGl0IHdvbnQgZXhlY3V0ZWQpXG4gICNcbiAgYWRkT3BlcmF0aW9uOiAobyktPlxuICAgIGlmIG5vdCBAYnVmZmVyW28uY3JlYXRvcl0/XG4gICAgICBAYnVmZmVyW28uY3JlYXRvcl0gPSB7fVxuICAgIGlmIEBidWZmZXJbby5jcmVhdG9yXVtvLm9wX251bWJlcl0/XG4gICAgICB0aHJvdyBuZXcgRXJyb3IgXCJZb3UgbXVzdCBub3Qgb3ZlcndyaXRlIG9wZXJhdGlvbnMhXCJcbiAgICBAYnVmZmVyW28uY3JlYXRvcl1bby5vcF9udW1iZXJdID0gb1xuICAgIG9cblxuICByZW1vdmVPcGVyYXRpb246IChvKS0+XG4gICAgZGVsZXRlIEBidWZmZXJbby5jcmVhdG9yXT9bby5vcF9udW1iZXJdXG5cbiAgI1xuICAjIEluY3JlbWVudCB0aGUgb3BlcmF0aW9uX2NvdW50ZXIgdGhhdCBkZWZpbmVzIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBFbmdpbmUuXG4gICNcbiAgYWRkVG9Db3VudGVyOiAobyktPlxuICAgIGlmIG5vdCBAb3BlcmF0aW9uX2NvdW50ZXJbby5jcmVhdG9yXT9cbiAgICAgIEBvcGVyYXRpb25fY291bnRlcltvLmNyZWF0b3JdID0gMFxuICAgIGlmIHR5cGVvZiBvLm9wX251bWJlciBpcyAnbnVtYmVyJyBhbmQgby5jcmVhdG9yIGlzbnQgQGdldFVzZXJJZCgpXG4gICAgICAjIFRPRE86IGZpeCB0aGlzIGlzc3VlIGJldHRlci5cbiAgICAgICMgT3BlcmF0aW9ucyBzaG91bGQgaW5jb21lIGluIG9yZGVyXG4gICAgICAjIFRoZW4geW91IGRvbid0IGhhdmUgdG8gZG8gdGhpcy4uXG4gICAgICBpZiBvLm9wX251bWJlciBpcyBAb3BlcmF0aW9uX2NvdW50ZXJbby5jcmVhdG9yXVxuICAgICAgICBAb3BlcmF0aW9uX2NvdW50ZXJbby5jcmVhdG9yXSsrXG4gICAgICAgIHdoaWxlIEBnZXRPcGVyYXRpb24oe2NyZWF0b3I6by5jcmVhdG9yLCBvcF9udW1iZXI6IEBvcGVyYXRpb25fY291bnRlcltvLmNyZWF0b3JdfSk/XG4gICAgICAgICAgQG9wZXJhdGlvbl9jb3VudGVyW28uY3JlYXRvcl0rK1xuXG4gICAgI2lmIEBvcGVyYXRpb25fY291bnRlcltvLmNyZWF0b3JdIGlzbnQgKG8ub3BfbnVtYmVyICsgMSlcbiAgICAgICNjb25zb2xlLmxvZyAoQG9wZXJhdGlvbl9jb3VudGVyW28uY3JlYXRvcl0gLSAoby5vcF9udW1iZXIgKyAxKSlcbiAgICAgICNjb25zb2xlLmxvZyBvXG4gICAgICAjdGhyb3cgbmV3IEVycm9yIFwiWW91IGRvbid0IHJlY2VpdmUgb3BlcmF0aW9ucyBpbiB0aGUgcHJvcGVyIG9yZGVyLiBUcnkgY291bnRpbmcgbGlrZSB0aGlzIDAsMSwyLDMsNCwuLiA7KVwiXG5cbm1vZHVsZS5leHBvcnRzID0gSGlzdG9yeUJ1ZmZlclxuIiwibW9kdWxlLmV4cG9ydHMgPSAoSEIpLT5cbiAgIyBAc2VlIEVuZ2luZS5wYXJzZVxuICBwYXJzZXIgPSB7fVxuICBleGVjdXRpb25fbGlzdGVuZXIgPSBbXVxuXG4gICNcbiAgIyBAcHJpdmF0ZVxuICAjIEBhYnN0cmFjdFxuICAjIEBub2RvY1xuICAjIEEgZ2VuZXJpYyBpbnRlcmZhY2UgdG8gb3BlcmF0aW9ucy5cbiAgI1xuICAjIEFuIG9wZXJhdGlvbiBoYXMgdGhlIGZvbGxvd2luZyBtZXRob2RzOlxuICAjICogX2VuY29kZTogZW5jb2RlcyBhbiBvcGVyYXRpb24gKG5lZWRlZCBvbmx5IGlmIGluc3RhbmNlIG9mIHRoaXMgb3BlcmF0aW9uIGlzIHNlbnQpLlxuICAjICogZXhlY3V0ZTogZXhlY3V0ZSB0aGUgZWZmZWN0cyBvZiB0aGlzIG9wZXJhdGlvbnMuIEdvb2QgZXhhbXBsZXMgYXJlIEluc2VydC10eXBlIGFuZCBBZGROYW1lLXR5cGVcbiAgIyAqIHZhbDogaW4gdGhlIGNhc2UgdGhhdCB0aGUgb3BlcmF0aW9uIGhvbGRzIGEgdmFsdWVcbiAgI1xuICAjIEZ1cnRoZXJtb3JlIGFuIGVuY29kYWJsZSBvcGVyYXRpb24gaGFzIGEgcGFyc2VyLiBXZSBleHRlbmQgdGhlIHBhcnNlciBvYmplY3QgaW4gb3JkZXIgdG8gcGFyc2UgZW5jb2RlZCBvcGVyYXRpb25zLlxuICAjXG4gIGNsYXNzIE9wZXJhdGlvblxuXG4gICAgI1xuICAgICMgQHBhcmFtIHtPYmplY3R9IHVpZCBBIHVuaXF1ZSBpZGVudGlmaWVyLiBJZiB1aWQgaXMgdW5kZWZpbmVkLCBhIG5ldyB1aWQgd2lsbCBiZSBjcmVhdGVkLlxuICAgICMgQHNlZSBIaXN0b3J5QnVmZmVyLmdldE5leHRPcGVyYXRpb25JZGVudGlmaWVyXG4gICAgI1xuICAgIGNvbnN0cnVjdG9yOiAodWlkKS0+XG4gICAgICBAaXNfZGVsZXRlZCA9IGZhbHNlXG4gICAgICBAZG9TeW5jID0gdHJ1ZVxuICAgICAgQGdhcmJhZ2VfY29sbGVjdGVkID0gZmFsc2VcbiAgICAgIGlmIG5vdCB1aWQ/XG4gICAgICAgIHVpZCA9IEhCLmdldE5leHRPcGVyYXRpb25JZGVudGlmaWVyKClcbiAgICAgIGlmIG5vdCB1aWQuZG9TeW5jP1xuICAgICAgICB1aWQuZG9TeW5jID0gbm90IGlzTmFOKHBhcnNlSW50KHVpZC5vcF9udW1iZXIpKVxuICAgICAge1xuICAgICAgICAnY3JlYXRvcic6IEBjcmVhdG9yXG4gICAgICAgICdvcF9udW1iZXInIDogQG9wX251bWJlclxuICAgICAgICAnZG9TeW5jJyA6IEBkb1N5bmNcbiAgICAgIH0gPSB1aWRcblxuICAgIHR5cGU6IFwiSW5zZXJ0XCJcblxuICAgICNcbiAgICAjIEFkZCBhbiBldmVudCBsaXN0ZW5lci4gSXQgZGVwZW5kcyBvbiB0aGUgb3BlcmF0aW9uIHdoaWNoIGV2ZW50cyBhcmUgc3VwcG9ydGVkLlxuICAgICMgQHBhcmFtIHtTdHJpbmd9IGV2ZW50IE5hbWUgb2YgdGhlIGV2ZW50LlxuICAgICMgQHBhcmFtIHtGdW5jdGlvbn0gZiBmIGlzIGV4ZWN1dGVkIGluIGNhc2UgdGhlIGV2ZW50IGZpcmVzLlxuICAgICNcbiAgICBvbjogKGV2ZW50cywgZiktPlxuICAgICAgQGV2ZW50X2xpc3RlbmVycyA/PSB7fVxuICAgICAgaWYgZXZlbnRzLmNvbnN0cnVjdG9yIGlzbnQgW10uY29uc3RydWN0b3JcbiAgICAgICAgZXZlbnRzID0gW2V2ZW50c11cbiAgICAgIGZvciBlIGluIGV2ZW50c1xuICAgICAgICBAZXZlbnRfbGlzdGVuZXJzW2VdID89IFtdXG4gICAgICAgIEBldmVudF9saXN0ZW5lcnNbZV0ucHVzaCBmXG5cbiAgICAjXG4gICAgIyBEZWxldGVzIGEgZnVuY3Rpb24gZnJvbSBhbiBldmVudCAvIGxpc3Qgb2YgZXZlbnRzLlxuICAgICMgQHNlZSBPcGVyYXRpb24ub25cbiAgICAjXG4gICAgIyBAb3ZlcmxvYWQgZGVsZXRlTGlzdGVuZXIoZXZlbnQsIGYpXG4gICAgIyAgIEBwYXJhbSBldmVudCB7U3RyaW5nfSBBbiBldmVudCBuYW1lXG4gICAgIyAgIEBwYXJhbSBmICAgICB7RnVuY3Rpb259IFRoZSBmdW5jdGlvbiB0aGF0IHlvdSB3YW50IHRvIGRlbGV0ZSBmcm9tIHRoZXNlIGV2ZW50c1xuICAgICMgQG92ZXJsb2FkIGRlbGV0ZUxpc3RlbmVyKGV2ZW50cywgZilcbiAgICAjICAgQHBhcmFtIGV2ZW50cyB7QXJyYXk8U3RyaW5nPn0gQSBsaXN0IG9mIGV2ZW50IG5hbWVzXG4gICAgIyAgIEBwYXJhbSBmICAgICAge0Z1bmN0aW9ufSBUaGUgZnVuY3Rpb24gdGhhdCB5b3Ugd2FudCB0byBkZWxldGUgZnJvbSB0aGVzZSBldmVudHMuXG4gICAgZGVsZXRlTGlzdGVuZXI6IChldmVudHMsIGYpLT5cbiAgICAgIGlmIGV2ZW50cy5jb25zdHJ1Y3RvciBpc250IFtdLmNvbnN0cnVjdG9yXG4gICAgICAgIGV2ZW50cyA9IFtldmVudHNdXG4gICAgICBmb3IgZSBpbiBldmVudHNcbiAgICAgICAgaWYgQGV2ZW50X2xpc3RlbmVycz9bZV0/XG4gICAgICAgICAgQGV2ZW50X2xpc3RlbmVyc1tlXSA9IEBldmVudF9saXN0ZW5lcnNbZV0uZmlsdGVyIChnKS0+XG4gICAgICAgICAgICBmIGlzbnQgZ1xuXG4gICAgI1xuICAgICMgRmlyZSBhbiBldmVudC5cbiAgICAjIFRPRE86IERvIHNvbWV0aGluZyB3aXRoIHRpbWVvdXRzLiBZb3UgZG9uJ3Qgd2FudCB0aGlzIHRvIGZpcmUgZm9yIGV2ZXJ5IG9wZXJhdGlvbiAoZS5nLiBpbnNlcnQpLlxuICAgICNcbiAgICBjYWxsRXZlbnQ6ICgpLT5cbiAgICAgIEBmb3J3YXJkRXZlbnQgQCwgYXJndW1lbnRzLi4uXG5cbiAgICAjXG4gICAgIyBGaXJlIGFuIGV2ZW50IGFuZCBzcGVjaWZ5IGluIHdoaWNoIGNvbnRleHQgdGhlIGxpc3RlbmVyIGlzIGNhbGxlZCAoc2V0ICd0aGlzJykuXG4gICAgI1xuICAgIGZvcndhcmRFdmVudDogKG9wLCBldmVudCwgYXJncy4uLiktPlxuICAgICAgaWYgQGV2ZW50X2xpc3RlbmVycz9bZXZlbnRdP1xuICAgICAgICBmb3IgZiBpbiBAZXZlbnRfbGlzdGVuZXJzW2V2ZW50XVxuICAgICAgICAgIGYuY2FsbCBvcCwgZXZlbnQsIGFyZ3MuLi5cblxuICAgIGlzRGVsZXRlZDogKCktPlxuICAgICAgQGlzX2RlbGV0ZWRcblxuICAgIGFwcGx5RGVsZXRlOiAoZ2FyYmFnZWNvbGxlY3QgPSB0cnVlKS0+XG4gICAgICBpZiBub3QgQGdhcmJhZ2VfY29sbGVjdGVkXG4gICAgICAgICNjb25zb2xlLmxvZyBcImFwcGx5RGVsZXRlOiAje0B0eXBlfVwiXG4gICAgICAgIEBpc19kZWxldGVkID0gdHJ1ZVxuICAgICAgICBpZiBnYXJiYWdlY29sbGVjdFxuICAgICAgICAgIEBnYXJiYWdlX2NvbGxlY3RlZCA9IHRydWVcbiAgICAgICAgICBIQi5hZGRUb0dhcmJhZ2VDb2xsZWN0b3IgQFxuXG4gICAgY2xlYW51cDogKCktPlxuICAgICAgI2NvbnNvbGUubG9nIFwiY2xlYW51cDogI3tAdHlwZX1cIlxuICAgICAgSEIucmVtb3ZlT3BlcmF0aW9uIEBcblxuICAgICNcbiAgICAjIFNldCB0aGUgcGFyZW50IG9mIHRoaXMgb3BlcmF0aW9uLlxuICAgICNcbiAgICBzZXRQYXJlbnQ6IChAcGFyZW50KS0+XG5cbiAgICAjXG4gICAgIyBHZXQgdGhlIHBhcmVudCBvZiB0aGlzIG9wZXJhdGlvbi5cbiAgICAjXG4gICAgZ2V0UGFyZW50OiAoKS0+XG4gICAgICBAcGFyZW50XG5cbiAgICAjXG4gICAgIyBDb21wdXRlcyBhIHVuaXF1ZSBpZGVudGlmaWVyICh1aWQpIHRoYXQgaWRlbnRpZmllcyB0aGlzIG9wZXJhdGlvbi5cbiAgICAjXG4gICAgZ2V0VWlkOiAoKS0+XG4gICAgICB7ICdjcmVhdG9yJzogQGNyZWF0b3IsICdvcF9udW1iZXInOiBAb3BfbnVtYmVyICwgJ3N5bmMnOiBAZG9TeW5jfVxuXG4gICAgZG9udFN5bmM6ICgpLT5cbiAgICAgIEBkb1N5bmMgPSBmYWxzZVxuXG4gICAgI1xuICAgICMgQHByaXZhdGVcbiAgICAjIE5vdGlmeSB0aGUgYWxsIHRoZSBsaXN0ZW5lcnMuXG4gICAgI1xuICAgIGV4ZWN1dGU6ICgpLT5cbiAgICAgIEBpc19leGVjdXRlZCA9IHRydWVcbiAgICAgIGZvciBsIGluIGV4ZWN1dGlvbl9saXN0ZW5lclxuICAgICAgICBsIEBfZW5jb2RlKClcbiAgICAgIEBcblxuICAgICNcbiAgICAjIEBwcml2YXRlXG4gICAgIyBPcGVyYXRpb25zIG1heSBkZXBlbmQgb24gb3RoZXIgb3BlcmF0aW9ucyAobGlua2VkIGxpc3RzLCBldGMuKS5cbiAgICAjIFRoZSBzYXZlT3BlcmF0aW9uIGFuZCB2YWxpZGF0ZVNhdmVkT3BlcmF0aW9ucyBtZXRob2RzIHByb3ZpZGVcbiAgICAjIGFuIGVhc3kgd2F5IHRvIHJlZmVyIHRvIHRoZXNlIG9wZXJhdGlvbnMgdmlhIGFuIHVpZCBvciBvYmplY3QgcmVmZXJlbmNlLlxuICAgICNcbiAgICAjIEZvciBleGFtcGxlOiBXZSBjYW4gY3JlYXRlIGEgbmV3IERlbGV0ZSBvcGVyYXRpb24gdGhhdCBkZWxldGVzIHRoZSBvcGVyYXRpb24gJG8gbGlrZSB0aGlzXG4gICAgIyAgICAgLSB2YXIgZCA9IG5ldyBEZWxldGUodWlkLCAkbyk7ICAgb3JcbiAgICAjICAgICAtIHZhciBkID0gbmV3IERlbGV0ZSh1aWQsICRvLmdldFVpZCgpKTtcbiAgICAjIEVpdGhlciB3YXkgd2Ugd2FudCB0byBhY2Nlc3MgJG8gdmlhIGQuZGVsZXRlcy4gSW4gdGhlIHNlY29uZCBjYXNlIHZhbGlkYXRlU2F2ZWRPcGVyYXRpb25zIG11c3QgYmUgY2FsbGVkIGZpcnN0LlxuICAgICNcbiAgICAjIEBvdmVybG9hZCBzYXZlT3BlcmF0aW9uKG5hbWUsIG9wX3VpZClcbiAgICAjICAgQHBhcmFtIHtTdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGlvbi4gQWZ0ZXIgdmFsaWRhdGluZyAod2l0aCB2YWxpZGF0ZVNhdmVkT3BlcmF0aW9ucykgdGhlIGluc3RhbnRpYXRlZCBvcGVyYXRpb24gd2lsbCBiZSBhY2Nlc3NpYmxlIHZpYSB0aGlzW25hbWVdLlxuICAgICMgICBAcGFyYW0ge09iamVjdH0gb3BfdWlkIEEgdWlkIHRoYXQgcmVmZXJzIHRvIGFuIG9wZXJhdGlvblxuICAgICMgQG92ZXJsb2FkIHNhdmVPcGVyYXRpb24obmFtZSwgb3ApXG4gICAgIyAgIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBvcGVyYXRpb24uIEFmdGVyIGNhbGxpbmcgdGhpcyBmdW5jdGlvbiBvcCBpcyBhY2Nlc3NpYmxlIHZpYSB0aGlzW25hbWVdLlxuICAgICMgICBAcGFyYW0ge09wZXJhdGlvbn0gb3AgQW4gT3BlcmF0aW9uIG9iamVjdFxuICAgICNcbiAgICBzYXZlT3BlcmF0aW9uOiAobmFtZSwgb3ApLT5cblxuICAgICAgI1xuICAgICAgIyBFdmVyeSBpbnN0YW5jZSBvZiAkT3BlcmF0aW9uIG11c3QgaGF2ZSBhbiAkZXhlY3V0ZSBmdW5jdGlvbi5cbiAgICAgICMgV2UgdXNlIGR1Y2stdHlwaW5nIHRvIGNoZWNrIGlmIG9wIGlzIGluc3RhbnRpYXRlZCBzaW5jZSB0aGVyZVxuICAgICAgIyBjb3VsZCBleGlzdCBtdWx0aXBsZSBjbGFzc2VzIG9mICRPcGVyYXRpb25cbiAgICAgICNcbiAgICAgIGlmIG9wPy5leGVjdXRlP1xuICAgICAgICAjIGlzIGluc3RhbnRpYXRlZFxuICAgICAgICBAW25hbWVdID0gb3BcbiAgICAgIGVsc2UgaWYgb3A/XG4gICAgICAgICMgbm90IGluaXRpYWxpemVkLiBEbyBpdCB3aGVuIGNhbGxpbmcgJHZhbGlkYXRlU2F2ZWRPcGVyYXRpb25zKClcbiAgICAgICAgQHVuY2hlY2tlZCA/PSB7fVxuICAgICAgICBAdW5jaGVja2VkW25hbWVdID0gb3BcblxuICAgICNcbiAgICAjIEBwcml2YXRlXG4gICAgIyBBZnRlciBjYWxsaW5nIHRoaXMgZnVuY3Rpb24gYWxsIG5vdCBpbnN0YW50aWF0ZWQgb3BlcmF0aW9ucyB3aWxsIGJlIGFjY2Vzc2libGUuXG4gICAgIyBAc2VlIE9wZXJhdGlvbi5zYXZlT3BlcmF0aW9uXG4gICAgI1xuICAgICMgQHJldHVybiBbQm9vbGVhbl0gV2hldGhlciBpdCB3YXMgcG9zc2libGUgdG8gaW5zdGFudGlhdGUgYWxsIG9wZXJhdGlvbnMuXG4gICAgI1xuICAgIHZhbGlkYXRlU2F2ZWRPcGVyYXRpb25zOiAoKS0+XG4gICAgICB1bmluc3RhbnRpYXRlZCA9IHt9XG4gICAgICBzdWNjZXNzID0gQFxuICAgICAgZm9yIG5hbWUsIG9wX3VpZCBvZiBAdW5jaGVja2VkXG4gICAgICAgIG9wID0gSEIuZ2V0T3BlcmF0aW9uIG9wX3VpZFxuICAgICAgICBpZiBvcFxuICAgICAgICAgIEBbbmFtZV0gPSBvcFxuICAgICAgICBlbHNlXG4gICAgICAgICAgdW5pbnN0YW50aWF0ZWRbbmFtZV0gPSBvcF91aWRcbiAgICAgICAgICBzdWNjZXNzID0gZmFsc2VcbiAgICAgIGRlbGV0ZSBAdW5jaGVja2VkXG4gICAgICBpZiBub3Qgc3VjY2Vzc1xuICAgICAgICBAdW5jaGVja2VkID0gdW5pbnN0YW50aWF0ZWRcbiAgICAgIHN1Y2Nlc3NcblxuXG5cbiAgI1xuICAjIEBub2RvY1xuICAjIEEgc2ltcGxlIERlbGV0ZS10eXBlIG9wZXJhdGlvbiB0aGF0IGRlbGV0ZXMgYW4gb3BlcmF0aW9uLlxuICAjXG4gIGNsYXNzIERlbGV0ZSBleHRlbmRzIE9wZXJhdGlvblxuXG4gICAgI1xuICAgICMgQHBhcmFtIHtPYmplY3R9IHVpZCBBIHVuaXF1ZSBpZGVudGlmaWVyLiBJZiB1aWQgaXMgdW5kZWZpbmVkLCBhIG5ldyB1aWQgd2lsbCBiZSBjcmVhdGVkLlxuICAgICMgQHBhcmFtIHtPYmplY3R9IGRlbGV0ZXMgVUlEIG9yIHJlZmVyZW5jZSBvZiB0aGUgb3BlcmF0aW9uIHRoYXQgdGhpcyB0byBiZSBkZWxldGVkLlxuICAgICNcbiAgICBjb25zdHJ1Y3RvcjogKHVpZCwgZGVsZXRlcyktPlxuICAgICAgQHNhdmVPcGVyYXRpb24gJ2RlbGV0ZXMnLCBkZWxldGVzXG4gICAgICBzdXBlciB1aWRcblxuICAgIHR5cGU6IFwiRGVsZXRlXCJcblxuICAgICNcbiAgICAjIEBwcml2YXRlXG4gICAgIyBDb252ZXJ0IGFsbCByZWxldmFudCBpbmZvcm1hdGlvbiBvZiB0aGlzIG9wZXJhdGlvbiB0byB0aGUganNvbi1mb3JtYXQuXG4gICAgIyBUaGlzIHJlc3VsdCBjYW4gYmUgc2VudCB0byBvdGhlciBjbGllbnRzLlxuICAgICNcbiAgICBfZW5jb2RlOiAoKS0+XG4gICAgICB7XG4gICAgICAgICd0eXBlJzogXCJEZWxldGVcIlxuICAgICAgICAndWlkJzogQGdldFVpZCgpXG4gICAgICAgICdkZWxldGVzJzogQGRlbGV0ZXMuZ2V0VWlkKClcbiAgICAgIH1cblxuICAgICNcbiAgICAjIEBwcml2YXRlXG4gICAgIyBBcHBseSB0aGUgZGVsZXRpb24uXG4gICAgI1xuICAgIGV4ZWN1dGU6ICgpLT5cbiAgICAgIGlmIEB2YWxpZGF0ZVNhdmVkT3BlcmF0aW9ucygpXG4gICAgICAgIEBkZWxldGVzLmFwcGx5RGVsZXRlIEBcbiAgICAgICAgc3VwZXJcbiAgICAgIGVsc2VcbiAgICAgICAgZmFsc2VcblxuICAjXG4gICMgRGVmaW5lIGhvdyB0byBwYXJzZSBEZWxldGUgb3BlcmF0aW9ucy5cbiAgI1xuICBwYXJzZXJbJ0RlbGV0ZSddID0gKG8pLT5cbiAgICB7XG4gICAgICAndWlkJyA6IHVpZFxuICAgICAgJ2RlbGV0ZXMnOiBkZWxldGVzX3VpZFxuICAgIH0gPSBvXG4gICAgbmV3IERlbGV0ZSB1aWQsIGRlbGV0ZXNfdWlkXG5cbiAgI1xuICAjIEBub2RvY1xuICAjIEEgc2ltcGxlIGluc2VydC10eXBlIG9wZXJhdGlvbi5cbiAgI1xuICAjIEFuIGluc2VydCBvcGVyYXRpb24gaXMgYWx3YXlzIHBvc2l0aW9uZWQgYmV0d2VlbiB0d28gb3RoZXIgaW5zZXJ0IG9wZXJhdGlvbnMuXG4gICMgSW50ZXJuYWxseSB0aGlzIGlzIHJlYWxpemVkIGFzIGFzc29jaWF0aXZlIGxpc3RzLCB3aGVyZWJ5IGVhY2ggaW5zZXJ0IG9wZXJhdGlvbiBoYXMgYSBwcmVkZWNlc3NvciBhbmQgYSBzdWNjZXNzb3IuXG4gICMgRm9yIHRoZSBzYWtlIG9mIGVmZmljaWVuY3kgd2UgbWFpbnRhaW4gdHdvIGxpc3RzOlxuICAjICAgLSBUaGUgc2hvcnQtbGlzdCAoYWJicmV2LiBzbCkgbWFpbnRhaW5zIG9ubHkgdGhlIG9wZXJhdGlvbnMgdGhhdCBhcmUgbm90IGRlbGV0ZWRcbiAgIyAgIC0gVGhlIGNvbXBsZXRlLWxpc3QgKGFiYnJldi4gY2wpIG1haW50YWlucyBhbGwgb3BlcmF0aW9uc1xuICAjXG4gIGNsYXNzIEluc2VydCBleHRlbmRzIE9wZXJhdGlvblxuXG4gICAgI1xuICAgICMgQHBhcmFtIHtPYmplY3R9IHVpZCBBIHVuaXF1ZSBpZGVudGlmaWVyLiBJZiB1aWQgaXMgdW5kZWZpbmVkLCBhIG5ldyB1aWQgd2lsbCBiZSBjcmVhdGVkLlxuICAgICMgQHBhcmFtIHtPcGVyYXRpb259IHByZXZfY2wgVGhlIHByZWRlY2Vzc29yIG9mIHRoaXMgb3BlcmF0aW9uIGluIHRoZSBjb21wbGV0ZS1saXN0IChjbClcbiAgICAjIEBwYXJhbSB7T3BlcmF0aW9ufSBuZXh0X2NsIFRoZSBzdWNjZXNzb3Igb2YgdGhpcyBvcGVyYXRpb24gaW4gdGhlIGNvbXBsZXRlLWxpc3QgKGNsKVxuICAgICNcbiAgICAjIEBzZWUgSGlzdG9yeUJ1ZmZlci5nZXROZXh0T3BlcmF0aW9uSWRlbnRpZmllclxuICAgICNcbiAgICBjb25zdHJ1Y3RvcjogKHVpZCwgcHJldl9jbCwgbmV4dF9jbCwgb3JpZ2luKS0+XG4gICAgICBAc2F2ZU9wZXJhdGlvbiAncHJldl9jbCcsIHByZXZfY2xcbiAgICAgIEBzYXZlT3BlcmF0aW9uICduZXh0X2NsJywgbmV4dF9jbFxuICAgICAgaWYgb3JpZ2luP1xuICAgICAgICBAc2F2ZU9wZXJhdGlvbiAnb3JpZ2luJywgb3JpZ2luXG4gICAgICBlbHNlXG4gICAgICAgIEBzYXZlT3BlcmF0aW9uICdvcmlnaW4nLCBwcmV2X2NsXG4gICAgICBzdXBlciB1aWRcblxuICAgIHR5cGU6IFwiSW5zZXJ0XCJcblxuICAgICNcbiAgICAjIHNldCBjb250ZW50IHRvIG51bGwgYW5kIG90aGVyIHN0dWZmXG4gICAgIyBAcHJpdmF0ZVxuICAgICNcbiAgICBhcHBseURlbGV0ZTogKG8pLT5cbiAgICAgIEBkZWxldGVkX2J5ID89IFtdXG4gICAgICBpZiBAcGFyZW50PyBhbmQgbm90IEBpc0RlbGV0ZWQoKVxuICAgICAgICAjIGNhbGwgaWZmIHdhc24ndCBkZWxldGVkIGVhcmx5ZXJcbiAgICAgICAgQHBhcmVudC5jYWxsRXZlbnQgXCJkZWxldGVcIiwgQCwgb1xuICAgICAgaWYgbz9cbiAgICAgICAgQGRlbGV0ZWRfYnkucHVzaCBvXG4gICAgICBnYXJiYWdlY29sbGVjdCA9IGZhbHNlXG4gICAgICBpZiBub3QgKEBwcmV2X2NsPyBhbmQgQG5leHRfY2w/KSBvciBAcHJldl9jbC5pc0RlbGV0ZWQoKVxuICAgICAgICBnYXJiYWdlY29sbGVjdCA9IHRydWVcbiAgICAgIHN1cGVyIGdhcmJhZ2Vjb2xsZWN0XG4gICAgICBpZiBAbmV4dF9jbD8uaXNEZWxldGVkKClcbiAgICAgICAgIyBnYXJiYWdlIGNvbGxlY3QgbmV4dF9jbFxuICAgICAgICBAbmV4dF9jbC5hcHBseURlbGV0ZSgpXG5cbiAgICBjbGVhbnVwOiAoKS0+XG4gICAgICAjIFRPRE86IERlYnVnZ2luZ1xuICAgICAgaWYgQHByZXZfY2w/LmlzRGVsZXRlZCgpXG4gICAgICAgICMgZGVsZXRlIGFsbCBvcHMgdGhhdCBkZWxldGUgdGhpcyBpbnNlcnRpb25cbiAgICAgICAgZm9yIGQgaW4gQGRlbGV0ZWRfYnlcbiAgICAgICAgICBkLmNsZWFudXAoKVxuXG4gICAgICAgICMgdGhyb3cgbmV3IEVycm9yIFwibGVmdCBpcyBub3QgZGVsZXRlZC4gaW5jb25zaXN0ZW5jeSEsIHdyYXJhcmFyXCJcbiAgICAgICAgIyBkZWxldGUgb3JpZ2luIHJlZmVyZW5jZXMgdG8gdGhlIHJpZ2h0XG4gICAgICAgIG8gPSBAbmV4dF9jbFxuICAgICAgICB3aGlsZSBvLnR5cGUgaXNudCBcIkRlbGltaXRlclwiXG4gICAgICAgICAgaWYgby5vcmlnaW4gaXMgQFxuICAgICAgICAgICAgby5vcmlnaW4gPSBAcHJldl9jbFxuICAgICAgICAgIG8gPSBvLm5leHRfY2xcbiAgICAgICAgIyByZWNvbm5lY3QgbGVmdC9yaWdodFxuICAgICAgICBAcHJldl9jbC5uZXh0X2NsID0gQG5leHRfY2xcbiAgICAgICAgQG5leHRfY2wucHJldl9jbCA9IEBwcmV2X2NsXG4gICAgICAgIHN1cGVyXG5cblxuICAgICNcbiAgICAjIEBwcml2YXRlXG4gICAgIyBUaGUgYW1vdW50IG9mIHBvc2l0aW9ucyB0aGF0ICR0aGlzIG9wZXJhdGlvbiB3YXMgbW92ZWQgdG8gdGhlIHJpZ2h0LlxuICAgICNcbiAgICBnZXREaXN0YW5jZVRvT3JpZ2luOiAoKS0+XG4gICAgICBkID0gMFxuICAgICAgbyA9IEBwcmV2X2NsXG4gICAgICB3aGlsZSB0cnVlXG4gICAgICAgIGlmIEBvcmlnaW4gaXMgb1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGQrK1xuICAgICAgICBvID0gby5wcmV2X2NsXG4gICAgICBkXG5cbiAgICAjXG4gICAgIyBAcHJpdmF0ZVxuICAgICMgSW5jbHVkZSB0aGlzIG9wZXJhdGlvbiBpbiB0aGUgYXNzb2NpYXRpdmUgbGlzdHMuXG4gICAgIyBAcGFyYW0gZmlyZV9ldmVudCB7Ym9vbGVhbn0gV2hldGhlciB0byBmaXJlIHRoZSBpbnNlcnQtZXZlbnQuXG4gICAgZXhlY3V0ZTogKGZpcmVfZXZlbnQgPSB0cnVlKS0+XG4gICAgICBpZiBub3QgQHZhbGlkYXRlU2F2ZWRPcGVyYXRpb25zKClcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICBlbHNlXG4gICAgICAgIGlmIEBwcmV2X2NsP1xuICAgICAgICAgIGRpc3RhbmNlX3RvX29yaWdpbiA9IEBnZXREaXN0YW5jZVRvT3JpZ2luKCkgIyBtb3N0IGNhc2VzOiAwXG4gICAgICAgICAgbyA9IEBwcmV2X2NsLm5leHRfY2xcbiAgICAgICAgICBpID0gZGlzdGFuY2VfdG9fb3JpZ2luICMgbG9vcCBjb3VudGVyXG5cbiAgICAgICAgICAjICR0aGlzIGhhcyB0byBmaW5kIGEgdW5pcXVlIHBvc2l0aW9uIGJldHdlZW4gb3JpZ2luIGFuZCB0aGUgbmV4dCBrbm93biBjaGFyYWN0ZXJcbiAgICAgICAgICAjIGNhc2UgMTogJG9yaWdpbiBlcXVhbHMgJG8ub3JpZ2luOiB0aGUgJGNyZWF0b3IgcGFyYW1ldGVyIGRlY2lkZXMgaWYgbGVmdCBvciByaWdodFxuICAgICAgICAgICMgICAgICAgICBsZXQgJE9MPSBbbzEsbzIsbzMsbzRdLCB3aGVyZWJ5ICR0aGlzIGlzIHRvIGJlIGluc2VydGVkIGJldHdlZW4gbzEgYW5kIG80XG4gICAgICAgICAgIyAgICAgICAgIG8yLG8zIGFuZCBvNCBvcmlnaW4gaXMgMSAodGhlIHBvc2l0aW9uIG9mIG8yKVxuICAgICAgICAgICMgICAgICAgICB0aGVyZSBpcyB0aGUgY2FzZSB0aGF0ICR0aGlzLmNyZWF0b3IgPCBvMi5jcmVhdG9yLCBidXQgbzMuY3JlYXRvciA8ICR0aGlzLmNyZWF0b3JcbiAgICAgICAgICAjICAgICAgICAgdGhlbiBvMiBrbm93cyBvMy4gU2luY2Ugb24gYW5vdGhlciBjbGllbnQgJE9MIGNvdWxkIGJlIFtvMSxvMyxvNF0gdGhlIHByb2JsZW0gaXMgY29tcGxleFxuICAgICAgICAgICMgICAgICAgICB0aGVyZWZvcmUgJHRoaXMgd291bGQgYmUgYWx3YXlzIHRvIHRoZSByaWdodCBvZiBvM1xuICAgICAgICAgICMgY2FzZSAyOiAkb3JpZ2luIDwgJG8ub3JpZ2luXG4gICAgICAgICAgIyAgICAgICAgIGlmIGN1cnJlbnQgJHRoaXMgaW5zZXJ0X3Bvc2l0aW9uID4gJG8gb3JpZ2luOiAkdGhpcyBpbnNcbiAgICAgICAgICAjICAgICAgICAgZWxzZSAkaW5zZXJ0X3Bvc2l0aW9uIHdpbGwgbm90IGNoYW5nZSAobWF5YmUgd2UgZW5jb3VudGVyIGNhc2UgMSBsYXRlciwgdGhlbiB0aGlzIHdpbGwgYmUgdG8gdGhlIHJpZ2h0IG9mICRvKVxuICAgICAgICAgICMgY2FzZSAzOiAkb3JpZ2luID4gJG8ub3JpZ2luXG4gICAgICAgICAgIyAgICAgICAgICR0aGlzIGluc2VydF9wb3NpdGlvbiBpcyB0byB0aGUgbGVmdCBvZiAkbyAoZm9yZXZlciEpXG4gICAgICAgICAgd2hpbGUgdHJ1ZVxuICAgICAgICAgICAgaWYgbyBpc250IEBuZXh0X2NsXG4gICAgICAgICAgICAgICMgJG8gaGFwcGVuZWQgY29uY3VycmVudGx5XG4gICAgICAgICAgICAgIGlmIG8uZ2V0RGlzdGFuY2VUb09yaWdpbigpIGlzIGlcbiAgICAgICAgICAgICAgICAjIGNhc2UgMVxuICAgICAgICAgICAgICAgIGlmIG8uY3JlYXRvciA8IEBjcmVhdG9yXG4gICAgICAgICAgICAgICAgICBAcHJldl9jbCA9IG9cbiAgICAgICAgICAgICAgICAgIGRpc3RhbmNlX3RvX29yaWdpbiA9IGkgKyAxXG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgIyBub3BcbiAgICAgICAgICAgICAgZWxzZSBpZiBvLmdldERpc3RhbmNlVG9PcmlnaW4oKSA8IGlcbiAgICAgICAgICAgICAgICAjIGNhc2UgMlxuICAgICAgICAgICAgICAgIGlmIGkgLSBkaXN0YW5jZV90b19vcmlnaW4gPD0gby5nZXREaXN0YW5jZVRvT3JpZ2luKClcbiAgICAgICAgICAgICAgICAgIEBwcmV2X2NsID0gb1xuICAgICAgICAgICAgICAgICAgZGlzdGFuY2VfdG9fb3JpZ2luID0gaSArIDFcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAjbm9wXG4gICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAjIGNhc2UgM1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIGkrK1xuICAgICAgICAgICAgICBvID0gby5uZXh0X2NsXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICMgJHRoaXMga25vd3MgdGhhdCAkbyBleGlzdHMsXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgIyBub3cgcmVjb25uZWN0IGV2ZXJ5dGhpbmdcbiAgICAgICAgICBAbmV4dF9jbCA9IEBwcmV2X2NsLm5leHRfY2xcbiAgICAgICAgICBAcHJldl9jbC5uZXh0X2NsID0gQFxuICAgICAgICAgIEBuZXh0X2NsLnByZXZfY2wgPSBAXG5cbiAgICAgICAgcGFyZW50ID0gQHByZXZfY2w/LmdldFBhcmVudCgpXG4gICAgICAgIGlmIHBhcmVudD8gYW5kIGZpcmVfZXZlbnRcbiAgICAgICAgICBAc2V0UGFyZW50IHBhcmVudFxuICAgICAgICAgIEBwYXJlbnQuY2FsbEV2ZW50IFwiaW5zZXJ0XCIsIEBcbiAgICAgICAgc3VwZXIgIyBub3RpZnkgdGhlIGV4ZWN1dGlvbl9saXN0ZW5lcnNcblxuICAgICNcbiAgICAjIENvbXB1dGUgdGhlIHBvc2l0aW9uIG9mIHRoaXMgb3BlcmF0aW9uLlxuICAgICNcbiAgICBnZXRQb3NpdGlvbjogKCktPlxuICAgICAgcG9zaXRpb24gPSAwXG4gICAgICBwcmV2ID0gQHByZXZfY2xcbiAgICAgIHdoaWxlIHRydWVcbiAgICAgICAgaWYgcHJldiBpbnN0YW5jZW9mIERlbGltaXRlclxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGlmIG5vdCBwcmV2LmlzRGVsZXRlZCgpXG4gICAgICAgICAgcG9zaXRpb24rK1xuICAgICAgICBwcmV2ID0gcHJldi5wcmV2X2NsXG4gICAgICBwb3NpdGlvblxuXG4gICNcbiAgIyBAbm9kb2NcbiAgIyBEZWZpbmVzIGFuIG9iamVjdCB0aGF0IGlzIGNhbm5vdCBiZSBjaGFuZ2VkLiBZb3UgY2FuIHVzZSB0aGlzIHRvIHNldCBhbiBpbW11dGFibGUgc3RyaW5nLCBvciBhIG51bWJlci5cbiAgI1xuICBjbGFzcyBJbW11dGFibGVPYmplY3QgZXh0ZW5kcyBPcGVyYXRpb25cblxuICAgICNcbiAgICAjIEBwYXJhbSB7T2JqZWN0fSB1aWQgQSB1bmlxdWUgaWRlbnRpZmllci4gSWYgdWlkIGlzIHVuZGVmaW5lZCwgYSBuZXcgdWlkIHdpbGwgYmUgY3JlYXRlZC5cbiAgICAjIEBwYXJhbSB7T2JqZWN0fSBjb250ZW50XG4gICAgI1xuICAgIGNvbnN0cnVjdG9yOiAodWlkLCBAY29udGVudCwgcHJldiwgbmV4dCwgb3JpZ2luKS0+XG4gICAgICBzdXBlciB1aWQsIHByZXYsIG5leHQsIG9yaWdpblxuXG4gICAgdHlwZTogXCJJbW11dGFibGVPYmplY3RcIlxuXG4gICAgI1xuICAgICMgQHJldHVybiBbU3RyaW5nXSBUaGUgY29udGVudCBvZiB0aGlzIG9wZXJhdGlvbi5cbiAgICAjXG4gICAgdmFsIDogKCktPlxuICAgICAgQGNvbnRlbnRcblxuICAgICNcbiAgICAjIEVuY29kZSB0aGlzIG9wZXJhdGlvbiBpbiBzdWNoIGEgd2F5IHRoYXQgaXQgY2FuIGJlIHBhcnNlZCBieSByZW1vdGUgcGVlcnMuXG4gICAgI1xuICAgIF9lbmNvZGU6ICgpLT5cbiAgICAgIGpzb24gPSB7XG4gICAgICAgICd0eXBlJzogXCJJbW11dGFibGVPYmplY3RcIlxuICAgICAgICAndWlkJyA6IEBnZXRVaWQoKVxuICAgICAgICAnY29udGVudCcgOiBAY29udGVudFxuICAgICAgfVxuICAgICAgaWYgQHByZXZfY2w/XG4gICAgICAgIGpzb25bJ3ByZXYnXSA9IEBwcmV2X2NsLmdldFVpZCgpXG4gICAgICBpZiBAbmV4dF9jbD9cbiAgICAgICAganNvblsnbmV4dCddID0gQG5leHRfY2wuZ2V0VWlkKClcbiAgICAgIGlmIEBvcmlnaW4/ICMgYW5kIEBvcmlnaW4gaXNudCBAcHJldl9jbFxuICAgICAgICBqc29uW1wib3JpZ2luXCJdID0gQG9yaWdpbigpLmdldFVpZCgpXG4gICAgICBqc29uXG5cbiAgcGFyc2VyWydJbW11dGFibGVPYmplY3QnXSA9IChqc29uKS0+XG4gICAge1xuICAgICAgJ3VpZCcgOiB1aWRcbiAgICAgICdjb250ZW50JyA6IGNvbnRlbnRcbiAgICAgICdwcmV2JzogcHJldlxuICAgICAgJ25leHQnOiBuZXh0XG4gICAgICAnb3JpZ2luJyA6IG9yaWdpblxuICAgIH0gPSBqc29uXG4gICAgbmV3IEltbXV0YWJsZU9iamVjdCB1aWQsIGNvbnRlbnQsIHByZXYsIG5leHQsIG9yaWdpblxuXG4gICNcbiAgIyBAbm9kb2NcbiAgIyBBIGRlbGltaXRlciBpcyBwbGFjZWQgYXQgdGhlIGVuZCBhbmQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgYXNzb2NpYXRpdmUgbGlzdHMuXG4gICMgVGhpcyBpcyBuZWNlc3NhcnkgaW4gb3JkZXIgdG8gaGF2ZSBhIGJlZ2lubmluZyBhbmQgYW4gZW5kIGV2ZW4gaWYgdGhlIGNvbnRlbnRcbiAgIyBvZiB0aGUgRW5naW5lIGlzIGVtcHR5LlxuICAjXG4gIGNsYXNzIERlbGltaXRlciBleHRlbmRzIE9wZXJhdGlvblxuICAgICNcbiAgICAjIEBwYXJhbSB7T2JqZWN0fSB1aWQgQSB1bmlxdWUgaWRlbnRpZmllci4gSWYgdWlkIGlzIHVuZGVmaW5lZCwgYSBuZXcgdWlkIHdpbGwgYmUgY3JlYXRlZC5cbiAgICAjIEBwYXJhbSB7T3BlcmF0aW9ufSBwcmV2X2NsIFRoZSBwcmVkZWNlc3NvciBvZiB0aGlzIG9wZXJhdGlvbiBpbiB0aGUgY29tcGxldGUtbGlzdCAoY2wpXG4gICAgIyBAcGFyYW0ge09wZXJhdGlvbn0gbmV4dF9jbCBUaGUgc3VjY2Vzc29yIG9mIHRoaXMgb3BlcmF0aW9uIGluIHRoZSBjb21wbGV0ZS1saXN0IChjbClcbiAgICAjXG4gICAgIyBAc2VlIEhpc3RvcnlCdWZmZXIuZ2V0TmV4dE9wZXJhdGlvbklkZW50aWZpZXJcbiAgICAjXG4gICAgY29uc3RydWN0b3I6ICh1aWQsIHByZXZfY2wsIG5leHRfY2wsIG9yaWdpbiktPlxuICAgICAgQHNhdmVPcGVyYXRpb24gJ3ByZXZfY2wnLCBwcmV2X2NsXG4gICAgICBAc2F2ZU9wZXJhdGlvbiAnbmV4dF9jbCcsIG5leHRfY2xcbiAgICAgIEBzYXZlT3BlcmF0aW9uICdvcmlnaW4nLCBwcmV2X2NsXG4gICAgICBzdXBlciB1aWRcblxuICAgIHR5cGU6IFwiRGVsaW1pdGVyXCJcblxuICAgIGFwcGx5RGVsZXRlOiAoKS0+XG4gICAgICBzdXBlcigpXG4gICAgICBvID0gQG5leHRfY2xcbiAgICAgIHdoaWxlIG8/XG4gICAgICAgIG8uYXBwbHlEZWxldGUoKVxuICAgICAgICBvID0gby5uZXh0X2NsXG4gICAgICB1bmRlZmluZWRcblxuICAgIGNsZWFudXA6ICgpLT5cbiAgICAgIHN1cGVyKClcblxuICAgICNcbiAgICAjIEBwcml2YXRlXG4gICAgI1xuICAgIGV4ZWN1dGU6ICgpLT5cbiAgICAgIGlmIEB1bmNoZWNrZWQ/WyduZXh0X2NsJ10/XG4gICAgICAgIHN1cGVyXG4gICAgICBlbHNlIGlmIEB1bmNoZWNrZWQ/WydwcmV2X2NsJ11cbiAgICAgICAgaWYgQHZhbGlkYXRlU2F2ZWRPcGVyYXRpb25zKClcbiAgICAgICAgICBpZiBAcHJldl9jbC5uZXh0X2NsP1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yIFwiUHJvYmFibHkgZHVwbGljYXRlZCBvcGVyYXRpb25zXCJcbiAgICAgICAgICBAcHJldl9jbC5uZXh0X2NsID0gQFxuICAgICAgICAgIGRlbGV0ZSBAcHJldl9jbC51bmNoZWNrZWQubmV4dF9jbFxuICAgICAgICAgIHN1cGVyXG4gICAgICAgIGVsc2VcbiAgICAgICAgICBmYWxzZVxuICAgICAgZWxzZSBpZiBAcHJldl9jbD8gYW5kIG5vdCBAcHJldl9jbC5uZXh0X2NsP1xuICAgICAgICBkZWxldGUgQHByZXZfY2wudW5jaGVja2VkLm5leHRfY2xcbiAgICAgICAgQHByZXZfY2wubmV4dF9jbCA9IEBcbiAgICAgIGVsc2UgaWYgQHByZXZfY2w/IG9yIEBuZXh0X2NsP1xuICAgICAgICBzdXBlclxuICAgICAgZWxzZVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IgXCJEZWxpbWl0ZXIgaXMgdW5zdWZmaWNpZW50IGRlZmluZWQhXCJcblxuICAgICNcbiAgICAjIEBwcml2YXRlXG4gICAgI1xuICAgIF9lbmNvZGU6ICgpLT5cbiAgICAgIHtcbiAgICAgICAgJ3R5cGUnIDogXCJEZWxpbWl0ZXJcIlxuICAgICAgICAndWlkJyA6IEBnZXRVaWQoKVxuICAgICAgICAncHJldicgOiBAcHJldl9jbD8uZ2V0VWlkKClcbiAgICAgICAgJ25leHQnIDogQG5leHRfY2w/LmdldFVpZCgpXG4gICAgICB9XG5cbiAgcGFyc2VyWydEZWxpbWl0ZXInXSA9IChqc29uKS0+XG4gICAge1xuICAgICd1aWQnIDogdWlkXG4gICAgJ3ByZXYnIDogcHJldlxuICAgICduZXh0JyA6IG5leHRcbiAgICB9ID0ganNvblxuICAgIG5ldyBEZWxpbWl0ZXIgdWlkLCBwcmV2LCBuZXh0XG5cbiAgIyBUaGlzIGlzIHdoYXQgdGhpcyBtb2R1bGUgZXhwb3J0cyBhZnRlciBpbml0aWFsaXppbmcgaXQgd2l0aCB0aGUgSGlzdG9yeUJ1ZmZlclxuICB7XG4gICAgJ3R5cGVzJyA6XG4gICAgICAnRGVsZXRlJyA6IERlbGV0ZVxuICAgICAgJ0luc2VydCcgOiBJbnNlcnRcbiAgICAgICdEZWxpbWl0ZXInOiBEZWxpbWl0ZXJcbiAgICAgICdPcGVyYXRpb24nOiBPcGVyYXRpb25cbiAgICAgICdJbW11dGFibGVPYmplY3QnIDogSW1tdXRhYmxlT2JqZWN0XG4gICAgJ3BhcnNlcicgOiBwYXJzZXJcbiAgICAnZXhlY3V0aW9uX2xpc3RlbmVyJyA6IGV4ZWN1dGlvbl9saXN0ZW5lclxuICB9XG5cblxuXG5cbiIsInRleHRfdHlwZXNfdW5pbml0aWFsaXplZCA9IHJlcXVpcmUgXCIuL1RleHRUeXBlc1wiXG5cbm1vZHVsZS5leHBvcnRzID0gKEhCKS0+XG4gIHRleHRfdHlwZXMgPSB0ZXh0X3R5cGVzX3VuaW5pdGlhbGl6ZWQgSEJcbiAgdHlwZXMgPSB0ZXh0X3R5cGVzLnR5cGVzXG4gIHBhcnNlciA9IHRleHRfdHlwZXMucGFyc2VyXG5cbiAgY3JlYXRlSnNvblR5cGVXcmFwcGVyID0gKF9qc29uVHlwZSktPlxuXG4gICAgI1xuICAgICMgQG5vdGUgRVhQRVJJTUVOVEFMXG4gICAgI1xuICAgICMgQSBKc29uVHlwZVdyYXBwZXIgd2FzIGludGVuZGVkIHRvIGJlIGEgY29udmVuaWVudCB3cmFwcGVyIGZvciB0aGUgSnNvblR5cGUuXG4gICAgIyBCdXQgaXQgY2FuIG1ha2UgdGhpbmdzIG1vcmUgZGlmZmljdWx0IHRoYW4gdGhleSBhcmUuXG4gICAgIyBAc2VlIEpzb25UeXBlXG4gICAgI1xuICAgICMgQGV4YW1wbGUgY3JlYXRlIGEgSnNvblR5cGVXcmFwcGVyXG4gICAgIyAgICMgWW91IGdldCBhIEpzb25UeXBlV3JhcHBlciBmcm9tIGEgSnNvblR5cGUgYnkgY2FsbGluZ1xuICAgICMgICB3ID0geWF0dGEudmFsdWVcbiAgICAjXG4gICAgIyBJdCBjcmVhdGVzIEphdmFzY3JpcHRzIC1nZXR0ZXIgYW5kIC1zZXR0ZXIgbWV0aG9kcyBmb3IgZWFjaCBwcm9wZXJ0eSB0aGF0IEpzb25UeXBlIG1haW50YWlucy5cbiAgICAjIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2RlZmluZVByb3BlcnR5XG4gICAgI1xuICAgICMgQGV4YW1wbGUgR2V0dGVyIEV4YW1wbGVcbiAgICAjICAgIyB5b3UgY2FuIGFjY2VzcyB0aGUgeCBwcm9wZXJ0eSBvZiB5YXR0YSBieSBjYWxsaW5nXG4gICAgIyAgIHcueFxuICAgICMgICAjIGluc3RlYWQgb2ZcbiAgICAjICAgeWF0dGEudmFsKCd4JylcbiAgICAjXG4gICAgIyBAbm90ZSBZb3UgY2FuIG9ubHkgb3ZlcndyaXRlIGV4aXN0aW5nIHZhbHVlcyEgU2V0dGluZyBhIG5ldyBwcm9wZXJ0eSB3b24ndCBoYXZlIGFueSBlZmZlY3QhXG4gICAgI1xuICAgICMgQGV4YW1wbGUgU2V0dGVyIEV4YW1wbGVcbiAgICAjICAgIyB5b3UgY2FuIHNldCBhbiBleGlzdGluZyB4IHByb3BlcnR5IG9mIHlhdHRhIGJ5IGNhbGxpbmdcbiAgICAjICAgdy54ID0gXCJ0ZXh0XCJcbiAgICAjICAgIyBpbnN0ZWFkIG9mXG4gICAgIyAgIHlhdHRhLnZhbCgneCcsIFwidGV4dFwiKVxuICAgICNcbiAgICAjIEluIG9yZGVyIHRvIHNldCBhIG5ldyBwcm9wZXJ0eSB5b3UgaGF2ZSB0byBvdmVyd3JpdGUgYW4gZXhpc3RpbmcgcHJvcGVydHkuXG4gICAgIyBUaGVyZWZvcmUgdGhlIEpzb25UeXBlV3JhcHBlciBzdXBwb3J0cyBhIHNwZWNpYWwgZmVhdHVyZSB0aGF0IHNob3VsZCBtYWtlIHRoaW5ncyBtb3JlIGNvbnZlbmllbnRcbiAgICAjICh3ZSBjYW4gYXJndWUgYWJvdXQgdGhhdCwgdXNlIHRoZSBKc29uVHlwZSBpZiB5b3UgZG9uJ3QgbGlrZSBpdCA7KS5cbiAgICAjIElmIHlvdSBvdmVyd3JpdGUgYW4gb2JqZWN0IHByb3BlcnR5IG9mIHRoZSBKc29uVHlwZVdyYXBwZXIgd2l0aCBhIG5ldyBvYmplY3QsIGl0IHdpbGwgcmVzdWx0IGluIGEgbWVyZ2VkIHZlcnNpb24gb2YgdGhlIG9iamVjdHMuXG4gICAgIyBMZXQgYHlhdHRhLnZhbHVlLnBgIHRoZSBwcm9wZXJ0eSB0aGF0IGlzIHRvIGJlIG92ZXJ3cml0dGVuIGFuZCBvIHRoZSBuZXcgdmFsdWUuIEUuZy4gYHlhdHRhLnZhbHVlLnAgPSBvYFxuICAgICMgKiBUaGUgcmVzdWx0IGhhcyBhbGwgcHJvcGVydGllcyBvZiBvXG4gICAgIyAqIFRoZSByZXN1bHQgaGFzIGFsbCBwcm9wZXJ0aWVzIG9mIHcucCBpZiB0aGV5IGRvbid0IG9jY3VyIHVuZGVyIHRoZSBzYW1lIHByb3BlcnR5LW5hbWUgaW4gby5cbiAgICAjXG4gICAgIyBAZXhhbXBsZSBDb25mbGljdCBFeGFtcGxlXG4gICAgIyAgIHlhdHRhLnZhbHVlID0ge2EgOiBcInN0cmluZ1wifVxuICAgICMgICB3ID0geWF0dGEudmFsdWVcbiAgICAjICAgY29uc29sZS5sb2codykgIyB7YSA6IFwic3RyaW5nXCJ9XG4gICAgIyAgIHcuYSA9IHthIDoge2IgOiBcInN0cmluZ1wifX1cbiAgICAjICAgY29uc29sZS5sb2codykgIyB7YSA6IHtiIDogXCJTdHJpbmdcIn19XG4gICAgIyAgIHcuYSA9IHthIDoge2MgOiA0fX1cbiAgICAjICAgY29uc29sZS5sb2codykgIyB7YSA6IHtiIDogXCJTdHJpbmdcIiwgYyA6IDR9fVxuICAgICNcbiAgICAjIEBleGFtcGxlIENvbW1vbiBQaXRmYWxsc1xuICAgICMgICB3ID0geWF0dGEudmFsdWVcbiAgICAjICAgIyBTZXR0aW5nIGEgbmV3IHByb3BlcnR5XG4gICAgIyAgIHcubmV3UHJvcGVydHkgPSBcIkF3ZXNvbWVcIlxuICAgICMgICBjb25zb2xlLmxvZyh3Lm5ld1Byb3BlcnR5ID09IFwiQXdlc29tZVwiKSAjIGZhbHNlLCB3Lm5ld1Byb3BlcnR5IGlzIHVuZGVmaW5lZFxuICAgICMgICAjIG92ZXJ3cml0ZSB0aGUgdyBvYmplY3RcbiAgICAjICAgdyA9IHtuZXdQcm9wZXJ0eSA6IFwiQXdlc29tZVwifVxuICAgICMgICBjb25zb2xlLmxvZyh3Lm5ld1Byb3BlcnR5ID09IFwiQXdlc29tZVwiKSAjIHRydWUhLCBidXQgLi5cbiAgICAjICAgY29uc29sZS5sb2coeWF0dGEudmFsdWUubmV3UHJvcGVydHkgPT0gXCJBd2Vzb21lXCIpICMgZmFsc2UsIHlvdSBhcmUgb25seSBhbGxvd2VkIHRvIHNldCBwcm9wZXJ0aWVzIVxuICAgICMgICAjIFRoZSBzb2x1dGlvblxuICAgICMgICB5YXR0YS52YWx1ZSA9IHtuZXdQcm9wZXJ0eSA6IFwiQXdlc29tZVwifVxuICAgICMgICBjb25zb2xlLmxvZyh3Lm5ld1Byb3BlcnR5ID09IFwiQXdlc29tZVwiKSAjIHRydWUhXG4gICAgI1xuICAgIGNsYXNzIEpzb25UeXBlV3JhcHBlclxuXG4gICAgICAjXG4gICAgICAjIEBwYXJhbSB7SnNvblR5cGV9IGpzb25UeXBlIEluc3RhbmNlIG9mIHRoZSBKc29uVHlwZSB0aGF0IHRoaXMgY2xhc3Mgd3JhcHBlcy5cbiAgICAgICNcbiAgICAgIGNvbnN0cnVjdG9yOiAoanNvblR5cGUpLT5cbiAgICAgICAgZm9yIG5hbWUsIG9iaiBvZiBqc29uVHlwZS5tYXBcbiAgICAgICAgICBkbyAobmFtZSwgb2JqKS0+XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkgSnNvblR5cGVXcmFwcGVyLnByb3RvdHlwZSwgbmFtZSxcbiAgICAgICAgICAgICAgZ2V0IDogLT5cbiAgICAgICAgICAgICAgICB4ID0gb2JqLnZhbCgpXG4gICAgICAgICAgICAgICAgaWYgeCBpbnN0YW5jZW9mIEpzb25UeXBlXG4gICAgICAgICAgICAgICAgICBjcmVhdGVKc29uVHlwZVdyYXBwZXIgeFxuICAgICAgICAgICAgICAgIGVsc2UgaWYgeCBpbnN0YW5jZW9mIHR5cGVzLkltbXV0YWJsZU9iamVjdFxuICAgICAgICAgICAgICAgICAgeC52YWwoKVxuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgIHhcbiAgICAgICAgICAgICAgc2V0IDogKG8pLT5cbiAgICAgICAgICAgICAgICBvdmVyd3JpdGUgPSBqc29uVHlwZS52YWwobmFtZSlcbiAgICAgICAgICAgICAgICBpZiBvLmNvbnN0cnVjdG9yIGlzIHt9LmNvbnN0cnVjdG9yIGFuZCBvdmVyd3JpdGUgaW5zdGFuY2VvZiB0eXBlcy5PcGVyYXRpb25cbiAgICAgICAgICAgICAgICAgIGZvciBvX25hbWUsb19vYmogb2Ygb1xuICAgICAgICAgICAgICAgICAgICBvdmVyd3JpdGUudmFsKG9fbmFtZSwgb19vYmosICdpbW11dGFibGUnKVxuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgIGpzb25UeXBlLnZhbChuYW1lLCBvLCAnaW1tdXRhYmxlJylcbiAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZVxuICAgICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlXG4gICAgbmV3IEpzb25UeXBlV3JhcHBlciBfanNvblR5cGVcblxuICAjXG4gICMgTWFuYWdlcyBPYmplY3QtbGlrZSB2YWx1ZXMuXG4gICNcbiAgY2xhc3MgSnNvblR5cGUgZXh0ZW5kcyB0eXBlcy5NYXBNYW5hZ2VyXG5cbiAgICAjXG4gICAgIyBAcGFyYW0ge09iamVjdH0gdWlkIEEgdW5pcXVlIGlkZW50aWZpZXIuIElmIHVpZCBpcyB1bmRlZmluZWQsIGEgbmV3IHVpZCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAgIyBAcGFyYW0ge09iamVjdH0gaW5pdGlhbF92YWx1ZSBDcmVhdGUgdGhpcyBvcGVyYXRpb24gd2l0aCBhbiBpbml0aWFsIHZhbHVlLlxuICAgICMgQHBhcmFtIHtTdHJpbmd8Qm9vbGVhbn0gV2hldGhlciB0aGUgaW5pdGlhbF92YWx1ZSBzaG91bGQgYmUgY3JlYXRlZCBhcyBtdXRhYmxlLiAoT3B0aW9uYWwgLSBzZWUgc2V0TXV0YWJsZURlZmF1bHQpXG4gICAgI1xuICAgIGNvbnN0cnVjdG9yOiAodWlkLCBpbml0aWFsX3ZhbHVlLCBtdXRhYmxlKS0+XG4gICAgICBzdXBlciB1aWRcbiAgICAgIGlmIGluaXRpYWxfdmFsdWU/XG4gICAgICAgIGlmIHR5cGVvZiBpbml0aWFsX3ZhbHVlIGlzbnQgXCJvYmplY3RcIlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvciBcIlRoZSBpbml0aWFsIHZhbHVlIG9mIEpzb25UeXBlcyBtdXN0IGJlIG9mIHR5cGUgT2JqZWN0ISAoY3VycmVudCB0eXBlOiAje3R5cGVvZiBpbml0aWFsX3ZhbHVlfSlcIlxuICAgICAgICBmb3IgbmFtZSxvIG9mIGluaXRpYWxfdmFsdWVcbiAgICAgICAgICBAdmFsIG5hbWUsIG8sIG11dGFibGVcblxuICAgICNcbiAgICAjIElkZW50aWZpZXMgdGhpcyBjbGFzcy5cbiAgICAjIFVzZSBpdCB0byBjaGVjayB3aGV0aGVyIHRoaXMgaXMgYSBqc29uLXR5cGUgb3Igc29tZXRoaW5nIGVsc2UuXG4gICAgI1xuICAgICMgQGV4YW1wbGVcbiAgICAjICAgdmFyIHggPSB5YXR0YS52YWwoJ3Vua25vd24nKVxuICAgICMgICBpZiAoeC50eXBlID09PSBcIkpzb25UeXBlXCIpIHtcbiAgICAjICAgICBjb25zb2xlLmxvZyBKU09OLnN0cmluZ2lmeSh4LnRvSnNvbigpKVxuICAgICMgICB9XG4gICAgI1xuICAgIHR5cGU6IFwiSnNvblR5cGVcIlxuXG4gICAgYXBwbHlEZWxldGU6ICgpLT5cbiAgICAgIHN1cGVyKClcblxuICAgIGNsZWFudXA6ICgpLT5cbiAgICAgIHN1cGVyKClcbiAgICAjXG4gICAgIyBUcmFuc2Zvcm0gdGhpcyB0byBhIEpzb24gYW5kIGxvb3NlIGFsbCB0aGUgc2hhcmluZy1hYmlsaXRpZXMgKHRoZSBuZXcgb2JqZWN0IHdpbGwgYmUgYSBkZWVwIGNsb25lKSFcbiAgICAjIEByZXR1cm4ge0pzb259XG4gICAgI1xuICAgIHRvSnNvbjogKCktPlxuICAgICAgdmFsID0gQHZhbCgpXG4gICAgICBqc29uID0ge31cbiAgICAgIGZvciBuYW1lLCBvIG9mIHZhbFxuICAgICAgICBpZiBvIGlzIG51bGxcbiAgICAgICAgICBqc29uW25hbWVdID0gb1xuICAgICAgICBlbHNlIGlmIG8uY29uc3RydWN0b3IgaXMge30uY29uc3RydWN0b3JcbiAgICAgICAgICBqc29uW25hbWVdID0gQHZhbChuYW1lKS50b0pzb24oKVxuICAgICAgICBlbHNlIGlmIG8gaW5zdGFuY2VvZiB0eXBlcy5PcGVyYXRpb25cbiAgICAgICAgICB3aGlsZSBvIGluc3RhbmNlb2YgdHlwZXMuT3BlcmF0aW9uXG4gICAgICAgICAgICBvID0gby52YWwoKVxuICAgICAgICAgIGpzb25bbmFtZV0gPSBvXG4gICAgICAgIGVsc2VcbiAgICAgICAgICBqc29uW25hbWVdID0gb1xuICAgICAganNvblxuXG4gICAgI1xuICAgICMgQHNlZSBXb3JkVHlwZS5zZXRSZXBsYWNlTWFuYWdlclxuICAgICMgU2V0cyB0aGUgcGFyZW50IG9mIHRoaXMgSnNvblR5cGUgb2JqZWN0LlxuICAgICNcbiAgICBzZXRSZXBsYWNlTWFuYWdlcjogKHJlcGxhY2VfbWFuYWdlciktPlxuICAgICAgQHJlcGxhY2VfbWFuYWdlciA9IHJlcGxhY2VfbWFuYWdlclxuICAgICAgQG9uIFsnY2hhbmdlJywnYWRkUHJvcGVydHknXSwgKCktPlxuICAgICAgICBpZiByZXBsYWNlX21hbmFnZXIucGFyZW50P1xuICAgICAgICAgIHJlcGxhY2VfbWFuYWdlci5wYXJlbnQuZm9yd2FyZEV2ZW50IHRoaXMsIGFyZ3VtZW50cy4uLlxuXG4gICAgI1xuICAgICMgR2V0IHRoZSBwYXJlbnQgb2YgdGhpcyBKc29uVHlwZS5cbiAgICAjIEByZXR1cm4ge0pzb25UeXBlfVxuICAgICNcbiAgICBnZXRQYXJlbnQ6ICgpLT5cbiAgICAgIEByZXBsYWNlX21hbmFnZXIucGFyZW50XG5cbiAgICAjXG4gICAgIyBXaGV0aGVyIHRoZSBkZWZhdWx0IGlzICdtdXRhYmxlJyAodHJ1ZSkgb3IgJ2ltbXV0YWJsZScgKGZhbHNlKVxuICAgICNcbiAgICBtdXRhYmxlX2RlZmF1bHQ6XG4gICAgICB0cnVlXG5cbiAgICAjXG4gICAgIyBTZXQgaWYgdGhlIGRlZmF1bHQgaXMgJ211dGFibGUnIG9yICdpbW11dGFibGUnXG4gICAgIyBAcGFyYW0ge1N0cmluZ3xCb29sZWFufSBtdXRhYmxlIFNldCBlaXRoZXIgJ211dGFibGUnIC8gdHJ1ZSBvciAnaW1tdXRhYmxlJyAvIGZhbHNlXG4gICAgc2V0TXV0YWJsZURlZmF1bHQ6IChtdXRhYmxlKS0+XG4gICAgICBpZiBtdXRhYmxlIGlzIHRydWUgb3IgbXV0YWJsZSBpcyAnbXV0YWJsZSdcbiAgICAgICAgSnNvblR5cGUucHJvdG90eXBlLm11dGFibGVfZGVmYXVsdCA9IHRydWVcbiAgICAgIGVsc2UgaWYgbXV0YWJsZSBpcyBmYWxzZSBvciBtdXRhYmxlIGlzICdpbW11dGFibGUnXG4gICAgICAgIEpzb25UeXBlLnByb3RvdHlwZS5tdXRhYmxlX2RlZmF1bHQgPSBmYWxzZVxuICAgICAgZWxzZVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IgJ1NldCBtdXRhYmxlIGVpdGhlciBcIm11dGFibGVcIiBvciBcImltbXV0YWJsZVwiISdcbiAgICAgICdPSydcblxuICAgICNcbiAgICAjIEBvdmVybG9hZCB2YWwoKVxuICAgICMgICBHZXQgdGhpcyBhcyBhIEpzb24gb2JqZWN0LlxuICAgICMgICBAcmV0dXJuIFtKc29uXVxuICAgICNcbiAgICAjIEBvdmVybG9hZCB2YWwobmFtZSlcbiAgICAjICAgR2V0IHZhbHVlIG9mIGEgcHJvcGVydHkuXG4gICAgIyAgIEBwYXJhbSB7U3RyaW5nfSBuYW1lIE5hbWUgb2YgdGhlIG9iamVjdCBwcm9wZXJ0eS5cbiAgICAjICAgQHJldHVybiBbSnNvblR5cGV8V29yZFR5cGV8U3RyaW5nfE9iamVjdF0gRGVwZW5kaW5nIG9uIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuIElmIG11dGFibGUgaXQgd2lsbCByZXR1cm4gYSBPcGVyYXRpb24tdHlwZSBvYmplY3QsIGlmIGltbXV0YWJsZSBpdCB3aWxsIHJldHVybiBTdHJpbmcvT2JqZWN0LlxuICAgICNcbiAgICAjIEBvdmVybG9hZCB2YWwobmFtZSwgY29udGVudClcbiAgICAjICAgU2V0IGEgbmV3IHByb3BlcnR5LlxuICAgICMgICBAcGFyYW0ge1N0cmluZ30gbmFtZSBOYW1lIG9mIHRoZSBvYmplY3QgcHJvcGVydHkuXG4gICAgIyAgIEBwYXJhbSB7T2JqZWN0fFN0cmluZ30gY29udGVudCBDb250ZW50IG9mIHRoZSBvYmplY3QgcHJvcGVydHkuXG4gICAgIyAgIEByZXR1cm4gW0pzb25UeXBlXSBUaGlzIG9iamVjdC4gKHN1cHBvcnRzIGNoYWluaW5nKVxuICAgICNcbiAgICB2YWw6IChuYW1lLCBjb250ZW50LCBtdXRhYmxlKS0+XG4gICAgICBpZiB0eXBlb2YgbmFtZSBpcyAnb2JqZWN0J1xuICAgICAgICAjIFNwZWNpYWwgY2FzZS4gRmlyc3QgYXJndW1lbnQgaXMgYW4gb2JqZWN0LiBUaGVuIHRoZSBzZWNvbmQgYXJnIGlzIG11dGFibGUuXG4gICAgICAgICMgS2VlcCB0aGF0IGluIG1pbmQgd2hlbiByZWFkaW5nIHRoZSBmb2xsb3dpbmcuLlxuICAgICAgICBqc29uID0gbmV3IEpzb25UeXBlIHVuZGVmaW5lZCwgbmFtZSwgY29udGVudFxuICAgICAgICBIQi5hZGRPcGVyYXRpb24oanNvbikuZXhlY3V0ZSgpXG4gICAgICAgIEByZXBsYWNlX21hbmFnZXIucmVwbGFjZSBqc29uXG4gICAgICAgIEBcbiAgICAgIGVsc2UgaWYgbmFtZT8gYW5kIChjb250ZW50PyBvciBjb250ZW50IGlzIG51bGwpXG4gICAgICAgIGlmIG11dGFibGU/XG4gICAgICAgICAgaWYgbXV0YWJsZSBpcyB0cnVlIG9yIG11dGFibGUgaXMgJ211dGFibGUnXG4gICAgICAgICAgICBtdXRhYmxlID0gdHJ1ZVxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIG11dGFibGUgPSBmYWxzZVxuICAgICAgICBlbHNlXG4gICAgICAgICAgbXV0YWJsZSA9IEBtdXRhYmxlX2RlZmF1bHRcbiAgICAgICAgaWYgdHlwZW9mIGNvbnRlbnQgaXMgJ2Z1bmN0aW9uJ1xuICAgICAgICAgIEAgIyBKdXN0IGRvIG5vdGhpbmdcbiAgICAgICAgZWxzZSBpZiBjb250ZW50IGlzIG51bGwgb3IgKCgobm90IG11dGFibGUpIG9yIHR5cGVvZiBjb250ZW50IGlzICdudW1iZXInKSBhbmQgY29udGVudC5jb25zdHJ1Y3RvciBpc250IE9iamVjdClcbiAgICAgICAgICBvYmogPSBIQi5hZGRPcGVyYXRpb24obmV3IHR5cGVzLkltbXV0YWJsZU9iamVjdCB1bmRlZmluZWQsIGNvbnRlbnQpLmV4ZWN1dGUoKVxuICAgICAgICAgIHN1cGVyIG5hbWUsIG9ialxuICAgICAgICBlbHNlXG4gICAgICAgICAgaWYgdHlwZW9mIGNvbnRlbnQgaXMgJ3N0cmluZydcbiAgICAgICAgICAgIHdvcmQgPSBIQi5hZGRPcGVyYXRpb24obmV3IHR5cGVzLldvcmRUeXBlIHVuZGVmaW5lZCkuZXhlY3V0ZSgpXG4gICAgICAgICAgICB3b3JkLmluc2VydFRleHQgMCwgY29udGVudFxuICAgICAgICAgICAgc3VwZXIgbmFtZSwgd29yZFxuICAgICAgICAgIGVsc2UgaWYgY29udGVudC5jb25zdHJ1Y3RvciBpcyBPYmplY3RcbiAgICAgICAgICAgIGpzb24gPSBIQi5hZGRPcGVyYXRpb24obmV3IEpzb25UeXBlIHVuZGVmaW5lZCwgY29udGVudCwgbXV0YWJsZSkuZXhlY3V0ZSgpXG4gICAgICAgICAgICBzdXBlciBuYW1lLCBqc29uXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yIFwiWW91IG11c3Qgbm90IHNldCAje3R5cGVvZiBjb250ZW50fS10eXBlcyBpbiBjb2xsYWJvcmF0aXZlIEpzb24tb2JqZWN0cyFcIlxuICAgICAgZWxzZVxuICAgICAgICBzdXBlciBuYW1lLCBjb250ZW50XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkgSnNvblR5cGUucHJvdG90eXBlLCAndmFsdWUnLFxuICAgICAgZ2V0IDogLT4gY3JlYXRlSnNvblR5cGVXcmFwcGVyIEBcbiAgICAgIHNldCA6IChvKS0+XG4gICAgICAgIGlmIG8uY29uc3RydWN0b3IgaXMge30uY29uc3RydWN0b3JcbiAgICAgICAgICBmb3Igb19uYW1lLG9fb2JqIG9mIG9cbiAgICAgICAgICAgIEB2YWwob19uYW1lLCBvX29iaiwgJ2ltbXV0YWJsZScpXG4gICAgICAgIGVsc2VcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IgXCJZb3UgbXVzdCBvbmx5IHNldCBPYmplY3QgdmFsdWVzIVwiXG5cbiAgICAjXG4gICAgIyBAcHJpdmF0ZVxuICAgICNcbiAgICBfZW5jb2RlOiAoKS0+XG4gICAgICB7XG4gICAgICAgICd0eXBlJyA6IFwiSnNvblR5cGVcIlxuICAgICAgICAndWlkJyA6IEBnZXRVaWQoKVxuICAgICAgfVxuXG4gIHBhcnNlclsnSnNvblR5cGUnXSA9IChqc29uKS0+XG4gICAge1xuICAgICAgJ3VpZCcgOiB1aWRcbiAgICB9ID0ganNvblxuICAgIG5ldyBKc29uVHlwZSB1aWRcblxuXG5cblxuICB0eXBlc1snSnNvblR5cGUnXSA9IEpzb25UeXBlXG5cbiAgdGV4dF90eXBlc1xuXG5cbiIsImJhc2ljX3R5cGVzX3VuaW5pdGlhbGl6ZWQgPSByZXF1aXJlIFwiLi9CYXNpY1R5cGVzXCJcblxubW9kdWxlLmV4cG9ydHMgPSAoSEIpLT5cbiAgYmFzaWNfdHlwZXMgPSBiYXNpY190eXBlc191bmluaXRpYWxpemVkIEhCXG4gIHR5cGVzID0gYmFzaWNfdHlwZXMudHlwZXNcbiAgcGFyc2VyID0gYmFzaWNfdHlwZXMucGFyc2VyXG5cbiAgI1xuICAjIEBub2RvY1xuICAjIE1hbmFnZXMgbWFwIGxpa2Ugb2JqZWN0cy4gRS5nLiBKc29uLVR5cGUgYW5kIFhNTCBhdHRyaWJ1dGVzLlxuICAjXG4gIGNsYXNzIE1hcE1hbmFnZXIgZXh0ZW5kcyB0eXBlcy5PcGVyYXRpb25cblxuICAgICNcbiAgICAjIEBwYXJhbSB7T2JqZWN0fSB1aWQgQSB1bmlxdWUgaWRlbnRpZmllci4gSWYgdWlkIGlzIHVuZGVmaW5lZCwgYSBuZXcgdWlkIHdpbGwgYmUgY3JlYXRlZC5cbiAgICAjXG4gICAgY29uc3RydWN0b3I6ICh1aWQpLT5cbiAgICAgIEBtYXAgPSB7fVxuICAgICAgc3VwZXIgdWlkXG5cbiAgICB0eXBlOiBcIk1hcE1hbmFnZXJcIlxuXG4gICAgYXBwbHlEZWxldGU6ICgpLT5cbiAgICAgIGZvciBuYW1lLHAgb2YgQG1hcFxuICAgICAgICBwLmFwcGx5RGVsZXRlKClcbiAgICAgIHN1cGVyKClcblxuICAgIGNsZWFudXA6ICgpLT5cbiAgICAgIHN1cGVyKClcblxuICAgICNcbiAgICAjIEBzZWUgSnNvblR5cGVzLnZhbFxuICAgICNcbiAgICB2YWw6IChuYW1lLCBjb250ZW50KS0+XG4gICAgICBpZiBjb250ZW50P1xuICAgICAgICBpZiBub3QgQG1hcFtuYW1lXT9cbiAgICAgICAgICBIQi5hZGRPcGVyYXRpb24obmV3IEFkZE5hbWUgdW5kZWZpbmVkLCBALCBuYW1lKS5leGVjdXRlKClcbiAgICAgICAgQG1hcFtuYW1lXS5yZXBsYWNlIGNvbnRlbnRcbiAgICAgICAgQFxuICAgICAgZWxzZSBpZiBuYW1lP1xuICAgICAgICBvYmogPSBAbWFwW25hbWVdPy52YWwoKVxuICAgICAgICBpZiBvYmogaW5zdGFuY2VvZiB0eXBlcy5JbW11dGFibGVPYmplY3RcbiAgICAgICAgICBvYmoudmFsKClcbiAgICAgICAgZWxzZVxuICAgICAgICAgIG9ialxuICAgICAgZWxzZVxuICAgICAgICByZXN1bHQgPSB7fVxuICAgICAgICBmb3IgbmFtZSxvIG9mIEBtYXBcbiAgICAgICAgICBvYmogPSBvLnZhbCgpXG4gICAgICAgICAgaWYgb2JqIGluc3RhbmNlb2YgdHlwZXMuSW1tdXRhYmxlT2JqZWN0IG9yIG9iaiBpbnN0YW5jZW9mIE1hcE1hbmFnZXJcbiAgICAgICAgICAgIG9iaiA9IG9iai52YWwoKVxuICAgICAgICAgIHJlc3VsdFtuYW1lXSA9IG9ialxuICAgICAgICByZXN1bHRcblxuICAjXG4gICMgQG5vZG9jXG4gICMgV2hlbiBhIG5ldyBwcm9wZXJ0eSBpbiBhIG1hcCBtYW5hZ2VyIGlzIGNyZWF0ZWQsIHRoZW4gdGhlIHVpZHMgb2YgdGhlIGluc2VydGVkIE9wZXJhdGlvbnNcbiAgIyBtdXN0IGJlIHVuaXF1ZSAodGhpbmsgYWJvdXQgY29uY3VycmVudCBvcGVyYXRpb25zKS4gVGhlcmVmb3JlIG9ubHkgYW4gQWRkTmFtZSBvcGVyYXRpb24gaXMgYWxsb3dlZCB0b1xuICAjIGFkZCBhIHByb3BlcnR5IGluIGEgTWFwTWFuYWdlci4gSWYgdHdvIEFkZE5hbWUgb3BlcmF0aW9ucyBvbiB0aGUgc2FtZSBNYXBNYW5hZ2VyIG5hbWUgaGFwcGVuIGNvbmN1cnJlbnRseVxuICAjIG9ubHkgb25lIHdpbGwgQWRkTmFtZSBvcGVyYXRpb24gd2lsbCBiZSBleGVjdXRlZC5cbiAgI1xuICBjbGFzcyBBZGROYW1lIGV4dGVuZHMgdHlwZXMuT3BlcmF0aW9uXG5cbiAgICAjXG4gICAgIyBAcGFyYW0ge09iamVjdH0gdWlkIEEgdW5pcXVlIGlkZW50aWZpZXIuIElmIHVpZCBpcyB1bmRlZmluZWQsIGEgbmV3IHVpZCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAgIyBAcGFyYW0ge09iamVjdH0gbWFwX21hbmFnZXIgVWlkIG9yIHJlZmVyZW5jZSB0byB0aGUgTWFwTWFuYWdlci5cbiAgICAjIEBwYXJhbSB7U3RyaW5nfSBuYW1lIE5hbWUgb2YgdGhlIHByb3BlcnR5IHRoYXQgd2lsbCBiZSBhZGRlZC5cbiAgICAjXG4gICAgY29uc3RydWN0b3I6ICh1aWQsIG1hcF9tYW5hZ2VyLCBAbmFtZSktPlxuICAgICAgQHNhdmVPcGVyYXRpb24gJ21hcF9tYW5hZ2VyJywgbWFwX21hbmFnZXJcbiAgICAgIHN1cGVyIHVpZFxuXG4gICAgdHlwZTogXCJBZGROYW1lXCJcblxuICAgIGFwcGx5RGVsZXRlOiAoKS0+XG4gICAgICBzdXBlcigpXG5cbiAgICBjbGVhbnVwOiAoKS0+XG4gICAgICBzdXBlcigpXG5cbiAgICAjXG4gICAgIyBJZiBtYXBfbWFuYWdlciBkb2Vzbid0IGhhdmUgdGhlIHByb3BlcnR5IG5hbWUsIHRoZW4gYWRkIGl0LlxuICAgICMgVGhlIFJlcGxhY2VNYW5hZ2VyIHRoYXQgaXMgYmVpbmcgd3JpdHRlbiBvbiB0aGUgcHJvcGVydHkgaXMgdW5pcXVlXG4gICAgIyBpbiBzdWNoIGEgd2F5IHRoYXQgaWYgQWRkTmFtZSBpcyBleGVjdXRlZCAoZnJvbSBhbm90aGVyIHBlZXIpIGl0IHdpbGxcbiAgICAjIGFsd2F5cyBoYXZlIHRoZSBzYW1lIHJlc3VsdCAoUmVwbGFjZU1hbmFnZXIsIGFuZCBpdHMgYmVnaW5uaW5nIGFuZCBlbmQgYXJlIHRoZSBzYW1lKVxuICAgICNcbiAgICBleGVjdXRlOiAoKS0+XG4gICAgICBpZiBub3QgQHZhbGlkYXRlU2F2ZWRPcGVyYXRpb25zKClcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICBlbHNlXG4gICAgICAgIHVpZF9yID0gQG1hcF9tYW5hZ2VyLmdldFVpZCgpXG4gICAgICAgIHVpZF9yLm9wX251bWJlciA9IFwiXyN7dWlkX3Iub3BfbnVtYmVyfV9STV8je0BuYW1lfVwiXG4gICAgICAgIGlmIG5vdCBIQi5nZXRPcGVyYXRpb24odWlkX3IpP1xuICAgICAgICAgIHVpZF9iZWcgPSBAbWFwX21hbmFnZXIuZ2V0VWlkKClcbiAgICAgICAgICB1aWRfYmVnLm9wX251bWJlciA9IFwiXyN7dWlkX2JlZy5vcF9udW1iZXJ9X1JNXyN7QG5hbWV9X2JlZ2lubmluZ1wiXG4gICAgICAgICAgdWlkX2VuZCA9IEBtYXBfbWFuYWdlci5nZXRVaWQoKVxuICAgICAgICAgIHVpZF9lbmQub3BfbnVtYmVyID0gXCJfI3t1aWRfZW5kLm9wX251bWJlcn1fUk1fI3tAbmFtZX1fZW5kXCJcbiAgICAgICAgICBiZWcgPSBIQi5hZGRPcGVyYXRpb24obmV3IHR5cGVzLkRlbGltaXRlciB1aWRfYmVnLCB1bmRlZmluZWQsIHVpZF9lbmQpLmV4ZWN1dGUoKVxuICAgICAgICAgIGVuZCA9IEhCLmFkZE9wZXJhdGlvbihuZXcgdHlwZXMuRGVsaW1pdGVyIHVpZF9lbmQsIGJlZywgdW5kZWZpbmVkKS5leGVjdXRlKClcbiAgICAgICAgICBAbWFwX21hbmFnZXIubWFwW0BuYW1lXSA9IEhCLmFkZE9wZXJhdGlvbihuZXcgUmVwbGFjZU1hbmFnZXIgdW5kZWZpbmVkLCB1aWRfciwgYmVnLCBlbmQpXG4gICAgICAgICAgQG1hcF9tYW5hZ2VyLm1hcFtAbmFtZV0uc2V0UGFyZW50IEBtYXBfbWFuYWdlciwgQG5hbWVcbiAgICAgICAgICAoQG1hcF9tYW5hZ2VyLm1hcFtAbmFtZV0uYWRkX25hbWVfb3BzID89IFtdKS5wdXNoIEBcbiAgICAgICAgICBAbWFwX21hbmFnZXIubWFwW0BuYW1lXS5leGVjdXRlKClcbiAgICAgICAgc3VwZXJcblxuICAgICNcbiAgICAjIEVuY29kZSB0aGlzIG9wZXJhdGlvbiBpbiBzdWNoIGEgd2F5IHRoYXQgaXQgY2FuIGJlIHBhcnNlZCBieSByZW1vdGUgcGVlcnMuXG4gICAgI1xuICAgIF9lbmNvZGU6ICgpLT5cbiAgICAgIHtcbiAgICAgICAgJ3R5cGUnIDogXCJBZGROYW1lXCJcbiAgICAgICAgJ3VpZCcgOiBAZ2V0VWlkKClcbiAgICAgICAgJ21hcF9tYW5hZ2VyJyA6IEBtYXBfbWFuYWdlci5nZXRVaWQoKVxuICAgICAgICAnbmFtZScgOiBAbmFtZVxuICAgICAgfVxuXG4gIHBhcnNlclsnQWRkTmFtZSddID0gKGpzb24pLT5cbiAgICB7XG4gICAgICAnbWFwX21hbmFnZXInIDogbWFwX21hbmFnZXJcbiAgICAgICd1aWQnIDogdWlkXG4gICAgICAnbmFtZScgOiBuYW1lXG4gICAgfSA9IGpzb25cbiAgICBuZXcgQWRkTmFtZSB1aWQsIG1hcF9tYW5hZ2VyLCBuYW1lXG5cbiAgI1xuICAjIEBub2RvY1xuICAjIE1hbmFnZXMgYSBsaXN0IG9mIEluc2VydC10eXBlIG9wZXJhdGlvbnMuXG4gICNcbiAgY2xhc3MgTGlzdE1hbmFnZXIgZXh0ZW5kcyB0eXBlcy5PcGVyYXRpb25cblxuICAgICNcbiAgICAjIEEgTGlzdE1hbmFnZXIgbWFpbnRhaW5zIGEgbm9uLWVtcHR5IGxpc3QgdGhhdCBoYXMgYSBiZWdpbm5pbmcgYW5kIGFuIGVuZCAoYm90aCBEZWxpbWl0ZXJzISlcbiAgICAjIEBwYXJhbSB7T2JqZWN0fSB1aWQgQSB1bmlxdWUgaWRlbnRpZmllci4gSWYgdWlkIGlzIHVuZGVmaW5lZCwgYSBuZXcgdWlkIHdpbGwgYmUgY3JlYXRlZC5cbiAgICAjIEBwYXJhbSB7RGVsaW1pdGVyfSBiZWdpbm5pbmcgUmVmZXJlbmNlIG9yIE9iamVjdC5cbiAgICAjIEBwYXJhbSB7RGVsaW1pdGVyfSBlbmQgUmVmZXJlbmNlIG9yIE9iamVjdC5cbiAgICBjb25zdHJ1Y3RvcjogKHVpZCwgYmVnaW5uaW5nLCBlbmQsIHByZXYsIG5leHQsIG9yaWdpbiktPlxuICAgICAgaWYgYmVnaW5uaW5nPyBhbmQgZW5kP1xuICAgICAgICBAc2F2ZU9wZXJhdGlvbiAnYmVnaW5uaW5nJywgYmVnaW5uaW5nXG4gICAgICAgIEBzYXZlT3BlcmF0aW9uICdlbmQnLCBlbmRcbiAgICAgIGVsc2VcbiAgICAgICAgQGJlZ2lubmluZyA9IEhCLmFkZE9wZXJhdGlvbiBuZXcgdHlwZXMuRGVsaW1pdGVyIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWRcbiAgICAgICAgQGVuZCA9ICAgICAgIEhCLmFkZE9wZXJhdGlvbiBuZXcgdHlwZXMuRGVsaW1pdGVyIHVuZGVmaW5lZCwgQGJlZ2lubmluZywgdW5kZWZpbmVkXG4gICAgICAgIEBiZWdpbm5pbmcubmV4dF9jbCA9IEBlbmRcbiAgICAgICAgQGJlZ2lubmluZy5leGVjdXRlKClcbiAgICAgICAgQGVuZC5leGVjdXRlKClcbiAgICAgIHN1cGVyIHVpZCwgcHJldiwgbmV4dCwgb3JpZ2luXG5cbiAgICB0eXBlOiBcIkxpc3RNYW5hZ2VyXCJcblxuICAgICNcbiAgICAjIEBwcml2YXRlXG4gICAgIyBAc2VlIE9wZXJhdGlvbi5leGVjdXRlXG4gICAgI1xuICAgIGV4ZWN1dGU6ICgpLT5cbiAgICAgIGlmIEB2YWxpZGF0ZVNhdmVkT3BlcmF0aW9ucygpXG4gICAgICAgIEBiZWdpbm5pbmcuc2V0UGFyZW50IEBcbiAgICAgICAgQGVuZC5zZXRQYXJlbnQgQFxuICAgICAgICBzdXBlclxuICAgICAgZWxzZVxuICAgICAgICBmYWxzZVxuXG4gICAgIyBHZXQgdGhlIGVsZW1lbnQgcHJldmlvdXMgdG8gdGhlIGRlbGVtaXRlciBhdCB0aGUgZW5kXG4gICAgZ2V0TGFzdE9wZXJhdGlvbjogKCktPlxuICAgICAgQGVuZC5wcmV2X2NsXG5cbiAgICAjIHNpbWlsYXIgdG8gdGhlIGFib3ZlXG4gICAgZ2V0Rmlyc3RPcGVyYXRpb246ICgpLT5cbiAgICAgIEBiZWdpbm5pbmcubmV4dF9jbFxuXG4gICAgIyBUcmFuc2Zvcm1zIHRoZSB0aGUgbGlzdCB0byBhbiBhcnJheVxuICAgICMgRG9lc24ndCByZXR1cm4gbGVmdC1yaWdodCBkZWxpbWl0ZXIuXG4gICAgdG9BcnJheTogKCktPlxuICAgICAgbyA9IEBiZWdpbm5pbmcubmV4dF9jbFxuICAgICAgcmVzdWx0ID0gW11cbiAgICAgIHdoaWxlIG8gaXNudCBAZW5kXG4gICAgICAgIHJlc3VsdC5wdXNoIG9cbiAgICAgICAgbyA9IG8ubmV4dF9jbFxuICAgICAgcmVzdWx0XG5cbiAgICAjXG4gICAgIyBSZXRyaWV2ZXMgdGhlIHgtdGggbm90IGRlbGV0ZWQgZWxlbWVudC5cbiAgICAjXG4gICAgZ2V0T3BlcmF0aW9uQnlQb3NpdGlvbjogKHBvc2l0aW9uKS0+XG4gICAgICBvID0gQGJlZ2lubmluZy5uZXh0X2NsXG4gICAgICBpZiAocG9zaXRpb24gPiAwIG9yIG8uaXNEZWxldGVkKCkpIGFuZCBub3QgKG8gaW5zdGFuY2VvZiB0eXBlcy5EZWxpbWl0ZXIpXG4gICAgICAgIHdoaWxlIG8uaXNEZWxldGVkKCkgYW5kIG5vdCAobyBpbnN0YW5jZW9mIHR5cGVzLkRlbGltaXRlcilcbiAgICAgICAgICAjIGZpbmQgZmlyc3Qgbm9uIGRlbGV0ZWQgb3BcbiAgICAgICAgICBvID0gby5uZXh0X2NsXG4gICAgICAgIHdoaWxlIHRydWVcbiAgICAgICAgICAjIGZpbmQgdGhlIGktdGggb3BcbiAgICAgICAgICBpZiBvIGluc3RhbmNlb2YgdHlwZXMuRGVsaW1pdGVyXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIGlmIHBvc2l0aW9uIDw9IDAgYW5kIG5vdCBvLmlzRGVsZXRlZCgpXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIG8gPSBvLm5leHRfY2xcbiAgICAgICAgICBpZiBub3Qgby5pc0RlbGV0ZWQoKVxuICAgICAgICAgICAgcG9zaXRpb24gLT0gMVxuICAgICAgb1xuXG4gICNcbiAgIyBAbm9kb2NcbiAgIyBBZGRzIHN1cHBvcnQgZm9yIHJlcGxhY2UuIFRoZSBSZXBsYWNlTWFuYWdlciBtYW5hZ2VzIFJlcGxhY2VhYmxlIG9wZXJhdGlvbnMuXG4gICMgRWFjaCBSZXBsYWNlYWJsZSBob2xkcyBhIHZhbHVlIHRoYXQgaXMgbm93IHJlcGxhY2VhYmxlLlxuICAjXG4gICMgVGhlIFdvcmRUeXBlLXR5cGUgaGFzIGltcGxlbWVudGVkIHN1cHBvcnQgZm9yIHJlcGxhY2VcbiAgIyBAc2VlIFdvcmRUeXBlXG4gICNcbiAgY2xhc3MgUmVwbGFjZU1hbmFnZXIgZXh0ZW5kcyBMaXN0TWFuYWdlclxuICAgICNcbiAgICAjIEBwYXJhbSB7T3BlcmF0aW9ufSBpbml0aWFsX2NvbnRlbnQgSW5pdGlhbGl6ZSB0aGlzIHdpdGggYSBSZXBsYWNlYWJsZSB0aGF0IGhvbGRzIHRoZSBpbml0aWFsX2NvbnRlbnQuXG4gICAgIyBAcGFyYW0ge09iamVjdH0gdWlkIEEgdW5pcXVlIGlkZW50aWZpZXIuIElmIHVpZCBpcyB1bmRlZmluZWQsIGEgbmV3IHVpZCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAgIyBAcGFyYW0ge0RlbGltaXRlcn0gYmVnaW5uaW5nIFJlZmVyZW5jZSBvciBPYmplY3QuXG4gICAgIyBAcGFyYW0ge0RlbGltaXRlcn0gZW5kIFJlZmVyZW5jZSBvciBPYmplY3QuXG4gICAgY29uc3RydWN0b3I6IChpbml0aWFsX2NvbnRlbnQsIHVpZCwgYmVnaW5uaW5nLCBlbmQsIHByZXYsIG5leHQsIG9yaWdpbiktPlxuICAgICAgc3VwZXIgdWlkLCBiZWdpbm5pbmcsIGVuZCwgcHJldiwgbmV4dCwgb3JpZ2luXG4gICAgICBpZiBpbml0aWFsX2NvbnRlbnQ/XG4gICAgICAgIEByZXBsYWNlIGluaXRpYWxfY29udGVudFxuXG4gICAgdHlwZTogXCJSZXBsYWNlTWFuYWdlclwiXG5cbiAgICBhcHBseURlbGV0ZTogKCktPlxuICAgICAgbyA9IEBiZWdpbm5pbmdcbiAgICAgIHdoaWxlIG8/XG4gICAgICAgIG8uYXBwbHlEZWxldGUoKVxuICAgICAgICBvID0gby5uZXh0X2NsXG4gICAgICAjIGlmIHRoaXMgd2FzIGNyZWF0ZWQgYnkgYW4gQWRkTmFtZSBvcGVyYXRpb24sIGRlbGV0ZSBpdCB0b29cbiAgICAgIGlmIEBhZGRfbmFtZV9vcHM/XG4gICAgICAgIGZvciBvIGluIEBhZGRfbmFtZV9vcHNcbiAgICAgICAgICBvLmFwcGx5RGVsZXRlKClcbiAgICAgIHN1cGVyKClcblxuICAgIGNsZWFudXA6ICgpLT5cbiAgICAgIHN1cGVyKClcblxuICAgICNcbiAgICAjIFJlcGxhY2UgdGhlIGV4aXN0aW5nIHdvcmQgd2l0aCBhIG5ldyB3b3JkLlxuICAgICNcbiAgICAjIEBwYXJhbSBjb250ZW50IHtPcGVyYXRpb259IFRoZSBuZXcgdmFsdWUgb2YgdGhpcyBSZXBsYWNlTWFuYWdlci5cbiAgICAjIEBwYXJhbSByZXBsYWNlYWJsZV91aWQge1VJRH0gT3B0aW9uYWw6IFVuaXF1ZSBpZCBvZiB0aGUgUmVwbGFjZWFibGUgdGhhdCBpcyBjcmVhdGVkXG4gICAgI1xuICAgIHJlcGxhY2U6IChjb250ZW50LCByZXBsYWNlYWJsZV91aWQpLT5cbiAgICAgIG8gPSBAZ2V0TGFzdE9wZXJhdGlvbigpXG4gICAgICBvcCA9IG5ldyBSZXBsYWNlYWJsZSBjb250ZW50LCBALCByZXBsYWNlYWJsZV91aWQsIG8sIG8ubmV4dF9jbFxuICAgICAgSEIuYWRkT3BlcmF0aW9uKG9wKS5leGVjdXRlKClcbiAgICAgIHVuZGVmaW5lZFxuXG4gICAgI1xuICAgICMgQWRkIGNoYW5nZSBsaXN0ZW5lcnMgZm9yIHBhcmVudC5cbiAgICAjXG4gICAgc2V0UGFyZW50OiAocGFyZW50LCBwcm9wZXJ0eV9uYW1lKS0+XG4gICAgICByZXBsX21hbmFnZXIgPSB0aGlzXG4gICAgICBAb24gJ2luc2VydCcsIChldmVudCwgb3ApLT5cbiAgICAgICAgaWYgb3AubmV4dF9jbCBpbnN0YW5jZW9mIHR5cGVzLkRlbGltaXRlclxuICAgICAgICAgIHJlcGxfbWFuYWdlci5wYXJlbnQuY2FsbEV2ZW50ICdjaGFuZ2UnLCBwcm9wZXJ0eV9uYW1lLCBvcFxuICAgICAgQG9uICdjaGFuZ2UnLCAoZXZlbnQsIG9wKS0+XG4gICAgICAgIGlmIHJlcGxfbWFuYWdlciBpc250IHRoaXNcbiAgICAgICAgICByZXBsX21hbmFnZXIucGFyZW50LmNhbGxFdmVudCAnY2hhbmdlJywgcHJvcGVydHlfbmFtZSwgb3BcbiAgICAgICMgQ2FsbCB0aGlzLCB3aGVuIHRoZSBmaXJzdCBlbGVtZW50IGlzIGluc2VydGVkLiBUaGVuIGRlbGV0ZSB0aGUgbGlzdGVuZXIuXG4gICAgICBhZGRQcm9wZXJ0eUxpc3RlbmVyID0gKGV2ZW50LCBvcCktPlxuICAgICAgICByZXBsX21hbmFnZXIuZGVsZXRlTGlzdGVuZXIgJ2FkZFByb3BlcnR5JywgYWRkUHJvcGVydHlMaXN0ZW5lclxuICAgICAgICByZXBsX21hbmFnZXIucGFyZW50LmNhbGxFdmVudCAnYWRkUHJvcGVydHknLCBwcm9wZXJ0eV9uYW1lLCBvcFxuICAgICAgQG9uICdpbnNlcnQnLCBhZGRQcm9wZXJ0eUxpc3RlbmVyXG4gICAgICBzdXBlciBwYXJlbnRcblxuICAgICNcbiAgICAjIEdldCB0aGUgdmFsdWUgb2YgdGhpcyBXb3JkVHlwZVxuICAgICMgQHJldHVybiB7U3RyaW5nfVxuICAgICNcbiAgICB2YWw6ICgpLT5cbiAgICAgIG8gPSBAZ2V0TGFzdE9wZXJhdGlvbigpXG4gICAgICAjaWYgbyBpbnN0YW5jZW9mIHR5cGVzLkRlbGltaXRlclxuICAgICAgICAjIHRocm93IG5ldyBFcnJvciBcIlJlcGxhY2UgTWFuYWdlciBkb2Vzbid0IGNvbnRhaW4gYW55dGhpbmcuXCJcbiAgICAgIG8udmFsPygpICMgPyAtIGZvciB0aGUgY2FzZSB0aGF0IChjdXJyZW50bHkpIHRoZSBSTSBkb2VzIG5vdCBjb250YWluIGFueXRoaW5nICh0aGVuIG8gaXMgYSBEZWxpbWl0ZXIpXG5cbiAgICAjXG4gICAgIyBFbmNvZGUgdGhpcyBvcGVyYXRpb24gaW4gc3VjaCBhIHdheSB0aGF0IGl0IGNhbiBiZSBwYXJzZWQgYnkgcmVtb3RlIHBlZXJzLlxuICAgICNcbiAgICBfZW5jb2RlOiAoKS0+XG4gICAgICBqc29uID1cbiAgICAgICAge1xuICAgICAgICAgICd0eXBlJzogXCJSZXBsYWNlTWFuYWdlclwiXG4gICAgICAgICAgJ3VpZCcgOiBAZ2V0VWlkKClcbiAgICAgICAgICAnYmVnaW5uaW5nJyA6IEBiZWdpbm5pbmcuZ2V0VWlkKClcbiAgICAgICAgICAnZW5kJyA6IEBlbmQuZ2V0VWlkKClcbiAgICAgICAgfVxuICAgICAgaWYgQHByZXZfY2w/IGFuZCBAbmV4dF9jbD9cbiAgICAgICAganNvblsncHJldiddID0gQHByZXZfY2wuZ2V0VWlkKClcbiAgICAgICAganNvblsnbmV4dCddID0gQG5leHRfY2wuZ2V0VWlkKClcbiAgICAgIGlmIEBvcmlnaW4/ICMgYW5kIEBvcmlnaW4gaXNudCBAcHJldl9jbFxuICAgICAgICBqc29uW1wib3JpZ2luXCJdID0gQG9yaWdpbigpLmdldFVpZCgpXG4gICAgICBqc29uXG5cbiAgcGFyc2VyW1wiUmVwbGFjZU1hbmFnZXJcIl0gPSAoanNvbiktPlxuICAgIHtcbiAgICAgICdjb250ZW50JyA6IGNvbnRlbnRcbiAgICAgICd1aWQnIDogdWlkXG4gICAgICAncHJldic6IHByZXZcbiAgICAgICduZXh0JzogbmV4dFxuICAgICAgJ29yaWdpbicgOiBvcmlnaW5cbiAgICAgICdiZWdpbm5pbmcnIDogYmVnaW5uaW5nXG4gICAgICAnZW5kJyA6IGVuZFxuICAgIH0gPSBqc29uXG4gICAgbmV3IFJlcGxhY2VNYW5hZ2VyIGNvbnRlbnQsIHVpZCwgYmVnaW5uaW5nLCBlbmQsIHByZXYsIG5leHQsIG9yaWdpblxuXG5cbiAgI1xuICAjIEBub2RvY1xuICAjIFRoZSBSZXBsYWNlTWFuYWdlciBtYW5hZ2VzIFJlcGxhY2VhYmxlcy5cbiAgIyBAc2VlIFJlcGxhY2VNYW5hZ2VyXG4gICNcbiAgY2xhc3MgUmVwbGFjZWFibGUgZXh0ZW5kcyB0eXBlcy5JbnNlcnRcblxuICAgICNcbiAgICAjIEBwYXJhbSB7T3BlcmF0aW9ufSBjb250ZW50IFRoZSB2YWx1ZSB0aGF0IHRoaXMgUmVwbGFjZWFibGUgaG9sZHMuXG4gICAgIyBAcGFyYW0ge1JlcGxhY2VNYW5hZ2VyfSBwYXJlbnQgVXNlZCB0byByZXBsYWNlIHRoaXMgUmVwbGFjZWFibGUgd2l0aCBhbm90aGVyIG9uZS5cbiAgICAjIEBwYXJhbSB7T2JqZWN0fSB1aWQgQSB1bmlxdWUgaWRlbnRpZmllci4gSWYgdWlkIGlzIHVuZGVmaW5lZCwgYSBuZXcgdWlkIHdpbGwgYmUgY3JlYXRlZC5cbiAgICAjXG4gICAgY29uc3RydWN0b3I6IChjb250ZW50LCBwYXJlbnQsIHVpZCwgcHJldiwgbmV4dCwgb3JpZ2luKS0+XG4gICAgICBAc2F2ZU9wZXJhdGlvbiAnY29udGVudCcsIGNvbnRlbnRcbiAgICAgIEBzYXZlT3BlcmF0aW9uICdwYXJlbnQnLCBwYXJlbnRcbiAgICAgIGlmIG5vdCAocHJldj8gYW5kIG5leHQ/KVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IgXCJZb3UgbXVzdCBkZWZpbmUgcHJldiwgYW5kIG5leHQgZm9yIFJlcGxhY2VhYmxlLXR5cGVzIVwiXG4gICAgICBzdXBlciB1aWQsIHByZXYsIG5leHQsIG9yaWdpblxuXG4gICAgdHlwZTogXCJSZXBsYWNlYWJsZVwiXG5cbiAgICAjXG4gICAgIyBSZXR1cm4gdGhlIGNvbnRlbnQgdGhhdCB0aGlzIG9wZXJhdGlvbiBob2xkcy5cbiAgICAjXG4gICAgdmFsOiAoKS0+XG4gICAgICBAY29udGVudFxuXG4gICAgI1xuICAgICMgUmVwbGFjZSB0aGUgY29udGVudCBvZiB0aGlzIHJlcGxhY2VhYmxlIHdpdGggbmV3IGNvbnRlbnQuXG4gICAgI1xuICAgIHJlcGxhY2U6IChjb250ZW50KS0+XG4gICAgICBAcGFyZW50LnJlcGxhY2UgY29udGVudFxuXG4gICAgYXBwbHlEZWxldGU6ICgpLT5cbiAgICAgIGlmIEBjb250ZW50P1xuICAgICAgICBAY29udGVudC5hcHBseURlbGV0ZSgpXG4gICAgICAgIEBjb250ZW50LmRvbnRTeW5jKClcbiAgICAgIEBjb250ZW50ID0gbnVsbFxuICAgICAgc3VwZXJcblxuICAgIGNsZWFudXA6ICgpLT5cbiAgICAgIHN1cGVyXG5cbiAgICAjXG4gICAgIyBJZiBwb3NzaWJsZSBzZXQgdGhlIHJlcGxhY2UgbWFuYWdlciBpbiB0aGUgY29udGVudC5cbiAgICAjIEBzZWUgV29yZFR5cGUuc2V0UmVwbGFjZU1hbmFnZXJcbiAgICAjXG4gICAgZXhlY3V0ZTogKCktPlxuICAgICAgaWYgbm90IEB2YWxpZGF0ZVNhdmVkT3BlcmF0aW9ucygpXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgZWxzZVxuICAgICAgICBAY29udGVudD8uc2V0UmVwbGFjZU1hbmFnZXI/KEBwYXJlbnQpXG4gICAgICAgICMgb25seSBmaXJlICdpbnNlcnQtZXZlbnQnICh3aGljaCB3aWxsIHJlc3VsdCBpbiBhZGRQcm9wZXJ0eSBhbmQgY2hhbmdlIGV2ZW50cyksXG4gICAgICAgICMgd2hlbiBjb250ZW50IGlzIGFkZGVkLiBJbiBjYXNlIG9mIEpzb24sIGVtcHR5IGNvbnRlbnQgbWVhbnMgdGhhdCB0aGlzIGlzIG5vdCB0aGUgbGFzdCB1cGRhdGUsXG4gICAgICAgICMgc2luY2UgY29udGVudCBpcyBkZWxldGVkIHdoZW4gJ2FwcGx5RGVsZXRlJyB3YXMgZXhlY3R1dGVkLlxuICAgICAgICBpbnNfcmVzdWx0ID0gc3VwZXIoQGNvbnRlbnQ/KSAjIEBjb250ZW50PyB3aGV0aGVyIHRvIGZpcmUgb3Igbm90XG4gICAgICAgIGlmIGluc19yZXN1bHRcbiAgICAgICAgICBpZiBAbmV4dF9jbC50eXBlIGlzIFwiRGVsaW1pdGVyXCIgYW5kIEBwcmV2X2NsLnR5cGUgaXNudCBcIkRlbGltaXRlclwiXG4gICAgICAgICAgICBAcHJldl9jbC5hcHBseURlbGV0ZSgpXG4gICAgICAgICAgZWxzZSBpZiBAbmV4dF9jbC50eXBlIGlzbnQgXCJEZWxpbWl0ZXJcIlxuICAgICAgICAgICAgQGFwcGx5RGVsZXRlKClcblxuICAgICAgICByZXR1cm4gaW5zX3Jlc3VsdFxuXG4gICAgI1xuICAgICMgRW5jb2RlIHRoaXMgb3BlcmF0aW9uIGluIHN1Y2ggYSB3YXkgdGhhdCBpdCBjYW4gYmUgcGFyc2VkIGJ5IHJlbW90ZSBwZWVycy5cbiAgICAjXG4gICAgX2VuY29kZTogKCktPlxuICAgICAganNvbiA9XG4gICAgICAgIHtcbiAgICAgICAgICAndHlwZSc6IFwiUmVwbGFjZWFibGVcIlxuICAgICAgICAgICdjb250ZW50JzogQGNvbnRlbnQ/LmdldFVpZCgpXG4gICAgICAgICAgJ1JlcGxhY2VNYW5hZ2VyJyA6IEBwYXJlbnQuZ2V0VWlkKClcbiAgICAgICAgICAncHJldic6IEBwcmV2X2NsLmdldFVpZCgpXG4gICAgICAgICAgJ25leHQnOiBAbmV4dF9jbC5nZXRVaWQoKVxuICAgICAgICAgICd1aWQnIDogQGdldFVpZCgpXG4gICAgICAgIH1cbiAgICAgIGlmIEBvcmlnaW4/IGFuZCBAb3JpZ2luIGlzbnQgQHByZXZfY2xcbiAgICAgICAganNvbltcIm9yaWdpblwiXSA9IEBvcmlnaW4uZ2V0VWlkKClcbiAgICAgIGpzb25cblxuICBwYXJzZXJbXCJSZXBsYWNlYWJsZVwiXSA9IChqc29uKS0+XG4gICAge1xuICAgICAgJ2NvbnRlbnQnIDogY29udGVudFxuICAgICAgJ1JlcGxhY2VNYW5hZ2VyJyA6IHBhcmVudFxuICAgICAgJ3VpZCcgOiB1aWRcbiAgICAgICdwcmV2JzogcHJldlxuICAgICAgJ25leHQnOiBuZXh0XG4gICAgICAnb3JpZ2luJyA6IG9yaWdpblxuICAgIH0gPSBqc29uXG4gICAgbmV3IFJlcGxhY2VhYmxlIGNvbnRlbnQsIHBhcmVudCwgdWlkLCBwcmV2LCBuZXh0LCBvcmlnaW5cblxuXG5cbiAgdHlwZXNbJ0xpc3RNYW5hZ2VyJ10gPSBMaXN0TWFuYWdlclxuICB0eXBlc1snTWFwTWFuYWdlciddID0gTWFwTWFuYWdlclxuICB0eXBlc1snUmVwbGFjZU1hbmFnZXInXSA9IFJlcGxhY2VNYW5hZ2VyXG4gIHR5cGVzWydSZXBsYWNlYWJsZSddID0gUmVwbGFjZWFibGVcblxuICBiYXNpY190eXBlc1xuXG5cblxuXG5cblxuIiwic3RydWN0dXJlZF90eXBlc191bmluaXRpYWxpemVkID0gcmVxdWlyZSBcIi4vU3RydWN0dXJlZFR5cGVzXCJcblxubW9kdWxlLmV4cG9ydHMgPSAoSEIpLT5cbiAgc3RydWN0dXJlZF90eXBlcyA9IHN0cnVjdHVyZWRfdHlwZXNfdW5pbml0aWFsaXplZCBIQlxuICB0eXBlcyA9IHN0cnVjdHVyZWRfdHlwZXMudHlwZXNcbiAgcGFyc2VyID0gc3RydWN0dXJlZF90eXBlcy5wYXJzZXJcblxuICAjXG4gICMgQG5vZG9jXG4gICMgQXQgdGhlIG1vbWVudCBUZXh0RGVsZXRlIHR5cGUgZXF1YWxzIHRoZSBEZWxldGUgdHlwZSBpbiBCYXNpY1R5cGVzLlxuICAjIEBzZWUgQmFzaWNUeXBlcy5EZWxldGVcbiAgI1xuICBjbGFzcyBUZXh0RGVsZXRlIGV4dGVuZHMgdHlwZXMuRGVsZXRlXG4gIHBhcnNlcltcIlRleHREZWxldGVcIl0gPSBwYXJzZXJbXCJEZWxldGVcIl1cblxuICAjXG4gICMgQG5vZG9jXG4gICMgRXh0ZW5kcyB0aGUgYmFzaWMgSW5zZXJ0IHR5cGUgdG8gYW4gb3BlcmF0aW9uIHRoYXQgaG9sZHMgYSB0ZXh0IHZhbHVlXG4gICNcbiAgY2xhc3MgVGV4dEluc2VydCBleHRlbmRzIHR5cGVzLkluc2VydFxuICAgICNcbiAgICAjIEBwYXJhbSB7U3RyaW5nfSBjb250ZW50IFRoZSBjb250ZW50IG9mIHRoaXMgSW5zZXJ0LXR5cGUgT3BlcmF0aW9uLiBVc3VhbGx5IHlvdSByZXN0cmljdCB0aGUgbGVuZ3RoIG9mIGNvbnRlbnQgdG8gc2l6ZSAxXG4gICAgIyBAcGFyYW0ge09iamVjdH0gdWlkIEEgdW5pcXVlIGlkZW50aWZpZXIuIElmIHVpZCBpcyB1bmRlZmluZWQsIGEgbmV3IHVpZCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAgI1xuICAgIGNvbnN0cnVjdG9yOiAoQGNvbnRlbnQsIHVpZCwgcHJldiwgbmV4dCwgb3JpZ2luKS0+XG4gICAgICBpZiBub3QgKHByZXY/IGFuZCBuZXh0PylcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yIFwiWW91IG11c3QgZGVmaW5lIHByZXYsIGFuZCBuZXh0IGZvciBUZXh0SW5zZXJ0LXR5cGVzIVwiXG4gICAgICBzdXBlciB1aWQsIHByZXYsIG5leHQsIG9yaWdpblxuXG4gICAgdHlwZTogXCJUZXh0SW5zZXJ0XCJcblxuICAgICNcbiAgICAjIFJldHJpZXZlIHRoZSBlZmZlY3RpdmUgbGVuZ3RoIG9mIHRoZSAkY29udGVudCBvZiB0aGlzIG9wZXJhdGlvbi5cbiAgICAjXG4gICAgZ2V0TGVuZ3RoOiAoKS0+XG4gICAgICBpZiBAaXNEZWxldGVkKClcbiAgICAgICAgMFxuICAgICAgZWxzZVxuICAgICAgICBAY29udGVudC5sZW5ndGhcblxuICAgIGFwcGx5RGVsZXRlOiAoKS0+XG4gICAgICBAY29udGVudCA9IG51bGxcbiAgICAgIHN1cGVyXG5cbiAgICAjXG4gICAgIyBUaGUgcmVzdWx0IHdpbGwgYmUgY29uY2F0ZW5hdGVkIHdpdGggdGhlIHJlc3VsdHMgZnJvbSB0aGUgb3RoZXIgaW5zZXJ0IG9wZXJhdGlvbnNcbiAgICAjIGluIG9yZGVyIHRvIHJldHJpZXZlIHRoZSBjb250ZW50IG9mIHRoZSBlbmdpbmUuXG4gICAgIyBAc2VlIEhpc3RvcnlCdWZmZXIudG9FeGVjdXRlZEFycmF5XG4gICAgI1xuICAgIHZhbDogKGN1cnJlbnRfcG9zaXRpb24pLT5cbiAgICAgIGlmIEBpc0RlbGV0ZWQoKSBvciBub3QgQGNvbnRlbnQ/XG4gICAgICAgIFwiXCJcbiAgICAgIGVsc2VcbiAgICAgICAgQGNvbnRlbnRcblxuICAgICNcbiAgICAjIENvbnZlcnQgYWxsIHJlbGV2YW50IGluZm9ybWF0aW9uIG9mIHRoaXMgb3BlcmF0aW9uIHRvIHRoZSBqc29uLWZvcm1hdC5cbiAgICAjIFRoaXMgcmVzdWx0IGNhbiBiZSBzZW5kIHRvIG90aGVyIGNsaWVudHMuXG4gICAgI1xuICAgIF9lbmNvZGU6ICgpLT5cbiAgICAgIGpzb24gPVxuICAgICAgICB7XG4gICAgICAgICAgJ3R5cGUnOiBcIlRleHRJbnNlcnRcIlxuICAgICAgICAgICdjb250ZW50JzogQGNvbnRlbnRcbiAgICAgICAgICAndWlkJyA6IEBnZXRVaWQoKVxuICAgICAgICAgICdwcmV2JzogQHByZXZfY2wuZ2V0VWlkKClcbiAgICAgICAgICAnbmV4dCc6IEBuZXh0X2NsLmdldFVpZCgpXG4gICAgICAgIH1cbiAgICAgIGlmIEBvcmlnaW4gaXNudCBAcHJldl9jbFxuICAgICAgICBqc29uW1wib3JpZ2luXCJdID0gQG9yaWdpbi5nZXRVaWQoKVxuICAgICAganNvblxuXG4gIHBhcnNlcltcIlRleHRJbnNlcnRcIl0gPSAoanNvbiktPlxuICAgIHtcbiAgICAgICdjb250ZW50JyA6IGNvbnRlbnRcbiAgICAgICd1aWQnIDogdWlkXG4gICAgICAncHJldic6IHByZXZcbiAgICAgICduZXh0JzogbmV4dFxuICAgICAgJ29yaWdpbicgOiBvcmlnaW5cbiAgICB9ID0ganNvblxuICAgIG5ldyBUZXh0SW5zZXJ0IGNvbnRlbnQsIHVpZCwgcHJldiwgbmV4dCwgb3JpZ2luXG5cbiAgI1xuICAjIEhhbmRsZXMgYSBXb3JkVHlwZS1saWtlIGRhdGEgc3RydWN0dXJlcyB3aXRoIHN1cHBvcnQgZm9yIGluc2VydFRleHQvZGVsZXRlVGV4dCBhdCBhIHdvcmQtcG9zaXRpb24uXG4gICMgQG5vdGUgQ3VycmVudGx5LCBvbmx5IFRleHQgaXMgc3VwcG9ydGVkIVxuICAjXG4gIGNsYXNzIFdvcmRUeXBlIGV4dGVuZHMgdHlwZXMuTGlzdE1hbmFnZXJcblxuICAgICNcbiAgICAjIEBwcml2YXRlXG4gICAgIyBAcGFyYW0ge09iamVjdH0gdWlkIEEgdW5pcXVlIGlkZW50aWZpZXIuIElmIHVpZCBpcyB1bmRlZmluZWQsIGEgbmV3IHVpZCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAgI1xuICAgIGNvbnN0cnVjdG9yOiAodWlkLCBiZWdpbm5pbmcsIGVuZCwgcHJldiwgbmV4dCwgb3JpZ2luKS0+XG4gICAgICBzdXBlciB1aWQsIGJlZ2lubmluZywgZW5kLCBwcmV2LCBuZXh0LCBvcmlnaW5cblxuICAgICNcbiAgICAjIElkZW50aWZpZXMgdGhpcyBjbGFzcy5cbiAgICAjIFVzZSBpdCB0byBjaGVjayB3aGV0aGVyIHRoaXMgaXMgYSB3b3JkLXR5cGUgb3Igc29tZXRoaW5nIGVsc2UuXG4gICAgI1xuICAgICMgQGV4YW1wbGVcbiAgICAjICAgdmFyIHggPSB5YXR0YS52YWwoJ3Vua25vd24nKVxuICAgICMgICBpZiAoeC50eXBlID09PSBcIldvcmRUeXBlXCIpIHtcbiAgICAjICAgICBjb25zb2xlLmxvZyBKU09OLnN0cmluZ2lmeSh4LnRvSnNvbigpKVxuICAgICMgICB9XG4gICAgI1xuICAgIHR5cGU6IFwiV29yZFR5cGVcIlxuXG4gICAgYXBwbHlEZWxldGU6ICgpLT5cbiAgICAgIG8gPSBAYmVnaW5uaW5nXG4gICAgICB3aGlsZSBvP1xuICAgICAgICBvLmFwcGx5RGVsZXRlKClcbiAgICAgICAgbyA9IG8ubmV4dF9jbFxuICAgICAgc3VwZXIoKVxuXG4gICAgY2xlYW51cDogKCktPlxuICAgICAgc3VwZXIoKVxuXG4gICAgcHVzaDogKGNvbnRlbnQpLT5cbiAgICAgIEBpbnNlcnRBZnRlciBAZW5kLnByZXZfY2wsIGNvbnRlbnRcblxuICAgIGluc2VydEFmdGVyOiAobGVmdCwgY29udGVudCktPlxuICAgICAgd2hpbGUgbGVmdC5pc0RlbGV0ZWQoKVxuICAgICAgICBsZWZ0ID0gbGVmdC5wcmV2X2NsICMgZmluZCB0aGUgZmlyc3QgY2hhcmFjdGVyIHRvIHRoZSBsZWZ0LCB0aGF0IGlzIG5vdCBkZWxldGVkLiBDYXNlIHBvc2l0aW9uIGlzIDAsIGl0cyB0aGUgRGVsaW1pdGVyLlxuICAgICAgcmlnaHQgPSBsZWZ0Lm5leHRfY2xcbiAgICAgIGlmIGNvbnRlbnQudHlwZT9cbiAgICAgICAgb3AgPSBuZXcgVGV4dEluc2VydCBjb250ZW50LCB1bmRlZmluZWQsIGxlZnQsIHJpZ2h0XG4gICAgICAgIEhCLmFkZE9wZXJhdGlvbihvcCkuZXhlY3V0ZSgpXG4gICAgICBlbHNlXG4gICAgICAgIGZvciBjIGluIGNvbnRlbnRcbiAgICAgICAgICBvcCA9IG5ldyBUZXh0SW5zZXJ0IGMsIHVuZGVmaW5lZCwgbGVmdCwgcmlnaHRcbiAgICAgICAgICBIQi5hZGRPcGVyYXRpb24ob3ApLmV4ZWN1dGUoKVxuICAgICAgICAgIGxlZnQgPSBvcFxuICAgICAgQFxuICAgICNcbiAgICAjIEluc2VydHMgYSBzdHJpbmcgaW50byB0aGUgd29yZC5cbiAgICAjXG4gICAgIyBAcmV0dXJuIHtXb3JkVHlwZX0gVGhpcyBXb3JkVHlwZSBvYmplY3QuXG4gICAgI1xuICAgIGluc2VydFRleHQ6IChwb3NpdGlvbiwgY29udGVudCktPlxuICAgICAgIyBUT0RPOiBnZXRPcGVyYXRpb25CeVBvc2l0aW9uIHNob3VsZCByZXR1cm4gXCIoaS0yKXRoXCIgY2hhcmFjdGVyXG4gICAgICBpdGggPSBAZ2V0T3BlcmF0aW9uQnlQb3NpdGlvbiBwb3NpdGlvbiAjIHRoZSAoaS0xKXRoIGNoYXJhY3Rlci4gZS5nLiBcImFiY1wiIGEgaXMgdGhlIDB0aCBjaGFyYWN0ZXJcbiAgICAgIGxlZnQgPSBpdGgucHJldl9jbCAjIGxlZnQgaXMgdGhlIG5vbi1kZWxldGVkIGNoYXJhdGhlciB0byB0aGUgbGVmdCBvZiBpdGhcbiAgICAgIEBpbnNlcnRBZnRlciBsZWZ0LCBjb250ZW50XG5cbiAgICAjXG4gICAgIyBEZWxldGVzIGEgcGFydCBvZiB0aGUgd29yZC5cbiAgICAjXG4gICAgIyBAcmV0dXJuIHtXb3JkVHlwZX0gVGhpcyBXb3JkVHlwZSBvYmplY3RcbiAgICAjXG4gICAgZGVsZXRlVGV4dDogKHBvc2l0aW9uLCBsZW5ndGgpLT5cbiAgICAgIG8gPSBAZ2V0T3BlcmF0aW9uQnlQb3NpdGlvbiBwb3NpdGlvblxuXG4gICAgICBkZWxldGVfb3BzID0gW11cbiAgICAgIGZvciBpIGluIFswLi4ubGVuZ3RoXVxuICAgICAgICBpZiBvIGluc3RhbmNlb2YgdHlwZXMuRGVsaW1pdGVyXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgZCA9IEhCLmFkZE9wZXJhdGlvbihuZXcgVGV4dERlbGV0ZSB1bmRlZmluZWQsIG8pLmV4ZWN1dGUoKVxuICAgICAgICBvID0gby5uZXh0X2NsXG4gICAgICAgIHdoaWxlIG5vdCAobyBpbnN0YW5jZW9mIHR5cGVzLkRlbGltaXRlcikgYW5kIG8uaXNEZWxldGVkKClcbiAgICAgICAgICBvID0gby5uZXh0X2NsXG4gICAgICAgIGRlbGV0ZV9vcHMucHVzaCBkLl9lbmNvZGUoKVxuICAgICAgQFxuXG4gICAgI1xuICAgICMgUmVwbGFjZSB0aGUgY29udGVudCBvZiB0aGlzIHdvcmQgd2l0aCBhbm90aGVyIG9uZS4gQ29uY3VycmVudCByZXBsYWNlbWVudHMgYXJlIG5vdCBtZXJnZWQhXG4gICAgIyBPbmx5IG9uZSBvZiB0aGUgcmVwbGFjZW1lbnRzIHdpbGwgYmUgdXNlZC5cbiAgICAjXG4gICAgIyBAcmV0dXJuIHtXb3JkVHlwZX0gUmV0dXJucyB0aGUgbmV3IFdvcmRUeXBlIG9iamVjdC5cbiAgICAjXG4gICAgcmVwbGFjZVRleHQ6ICh0ZXh0KS0+XG4gICAgICAjIENhbiBvbmx5IGJlIHVzZWQgaWYgdGhlIFJlcGxhY2VNYW5hZ2VyIHdhcyBzZXQhXG4gICAgICAjIEBzZWUgV29yZFR5cGUuc2V0UmVwbGFjZU1hbmFnZXJcbiAgICAgIGlmIEByZXBsYWNlX21hbmFnZXI/XG4gICAgICAgIHdvcmQgPSBIQi5hZGRPcGVyYXRpb24obmV3IFdvcmRUeXBlIHVuZGVmaW5lZCkuZXhlY3V0ZSgpXG4gICAgICAgIHdvcmQuaW5zZXJ0VGV4dCAwLCB0ZXh0XG4gICAgICAgIEByZXBsYWNlX21hbmFnZXIucmVwbGFjZSh3b3JkKVxuICAgICAgICB3b3JkXG4gICAgICBlbHNlXG4gICAgICAgIHRocm93IG5ldyBFcnJvciBcIlRoaXMgdHlwZSBpcyBjdXJyZW50bHkgbm90IG1haW50YWluZWQgYnkgYSBSZXBsYWNlTWFuYWdlciFcIlxuXG4gICAgI1xuICAgICMgR2V0IHRoZSBTdHJpbmctcmVwcmVzZW50YXRpb24gb2YgdGhpcyB3b3JkLlxuICAgICMgQHJldHVybiB7U3RyaW5nfSBUaGUgU3RyaW5nLXJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LlxuICAgICNcbiAgICB2YWw6ICgpLT5cbiAgICAgIGMgPSBmb3IgbyBpbiBAdG9BcnJheSgpXG4gICAgICAgIGlmIG8udmFsP1xuICAgICAgICAgIG8udmFsKClcbiAgICAgICAgZWxzZVxuICAgICAgICAgIFwiXCJcbiAgICAgIGMuam9pbignJylcblxuICAgICNcbiAgICAjIFNhbWUgYXMgV29yZFR5cGUudmFsXG4gICAgIyBAc2VlIFdvcmRUeXBlLnZhbFxuICAgICNcbiAgICB0b1N0cmluZzogKCktPlxuICAgICAgQHZhbCgpXG5cbiAgICAjXG4gICAgIyBAcHJpdmF0ZVxuICAgICMgSW4gbW9zdCBjYXNlcyB5b3Ugd291bGQgZW1iZWQgYSBXb3JkVHlwZSBpbiBhIFJlcGxhY2VhYmxlLCB3aWNoIGlzIGhhbmRsZWQgYnkgdGhlIFJlcGxhY2VNYW5hZ2VyIGluIG9yZGVyXG4gICAgIyB0byBwcm92aWRlIHJlcGxhY2UgZnVuY3Rpb25hbGl0eS5cbiAgICAjXG4gICAgc2V0UmVwbGFjZU1hbmFnZXI6IChvcCktPlxuICAgICAgQHNhdmVPcGVyYXRpb24gJ3JlcGxhY2VfbWFuYWdlcicsIG9wXG4gICAgICBAdmFsaWRhdGVTYXZlZE9wZXJhdGlvbnMoKVxuICAgICAgQG9uICdpbnNlcnQnLCAoZXZlbnQsIGlucyk9PlxuICAgICAgICBAcmVwbGFjZV9tYW5hZ2VyPy5mb3J3YXJkRXZlbnQgQCwgJ2NoYW5nZScsIGluc1xuICAgICAgQG9uICdkZWxldGUnLCAoZXZlbnQsIGlucywgZGVsKT0+XG4gICAgICAgIEByZXBsYWNlX21hbmFnZXI/LmZvcndhcmRFdmVudCBALCAnY2hhbmdlJywgZGVsXG4gICAgI1xuICAgICMgQmluZCB0aGlzIFdvcmRUeXBlIHRvIGEgdGV4dGZpZWxkIG9yIGlucHV0IGZpZWxkLlxuICAgICNcbiAgICAjIEBleGFtcGxlXG4gICAgIyAgIHZhciB0ZXh0Ym94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJ0ZXh0ZmllbGRcIik7XG4gICAgIyAgIHlhdHRhLmJpbmQodGV4dGJveCk7XG4gICAgI1xuICAgIGJpbmQ6ICh0ZXh0ZmllbGQpLT5cbiAgICAgIHdvcmQgPSBAXG4gICAgICB0ZXh0ZmllbGQudmFsdWUgPSBAdmFsKClcblxuICAgICAgQG9uIFwiaW5zZXJ0XCIsIChldmVudCwgb3ApLT5cbiAgICAgICAgb19wb3MgPSBvcC5nZXRQb3NpdGlvbigpXG4gICAgICAgIGZpeCA9IChjdXJzb3IpLT5cbiAgICAgICAgICBpZiBjdXJzb3IgPD0gb19wb3NcbiAgICAgICAgICAgIGN1cnNvclxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGN1cnNvciArPSAxXG4gICAgICAgICAgICBjdXJzb3JcbiAgICAgICAgbGVmdCA9IGZpeCB0ZXh0ZmllbGQuc2VsZWN0aW9uU3RhcnRcbiAgICAgICAgcmlnaHQgPSBmaXggdGV4dGZpZWxkLnNlbGVjdGlvbkVuZFxuXG4gICAgICAgIHRleHRmaWVsZC52YWx1ZSA9IHdvcmQudmFsKClcbiAgICAgICAgdGV4dGZpZWxkLnNldFNlbGVjdGlvblJhbmdlIGxlZnQsIHJpZ2h0XG5cblxuICAgICAgQG9uIFwiZGVsZXRlXCIsIChldmVudCwgb3ApLT5cbiAgICAgICAgb19wb3MgPSBvcC5nZXRQb3NpdGlvbigpXG4gICAgICAgIGZpeCA9IChjdXJzb3IpLT5cbiAgICAgICAgICBpZiBjdXJzb3IgPCBvX3Bvc1xuICAgICAgICAgICAgY3Vyc29yXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgY3Vyc29yIC09IDFcbiAgICAgICAgICAgIGN1cnNvclxuICAgICAgICBsZWZ0ID0gZml4IHRleHRmaWVsZC5zZWxlY3Rpb25TdGFydFxuICAgICAgICByaWdodCA9IGZpeCB0ZXh0ZmllbGQuc2VsZWN0aW9uRW5kXG5cbiAgICAgICAgdGV4dGZpZWxkLnZhbHVlID0gd29yZC52YWwoKVxuICAgICAgICB0ZXh0ZmllbGQuc2V0U2VsZWN0aW9uUmFuZ2UgbGVmdCwgcmlnaHRcblxuICAgICAgIyBjb25zdW1lIGFsbCB0ZXh0LWluc2VydCBjaGFuZ2VzLlxuICAgICAgdGV4dGZpZWxkLm9ua2V5cHJlc3MgPSAoZXZlbnQpLT5cbiAgICAgICAgY2hhciA9IG51bGxcbiAgICAgICAgaWYgZXZlbnQua2V5P1xuICAgICAgICAgIGlmIGV2ZW50LmNoYXJDb2RlIGlzIDMyXG4gICAgICAgICAgICBjaGFyID0gXCIgXCJcbiAgICAgICAgICBlbHNlIGlmIGV2ZW50LmtleUNvZGUgaXMgMTNcbiAgICAgICAgICAgIGNoYXIgPSAnXFxuJ1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGNoYXIgPSBldmVudC5rZXlcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGNoYXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlIGV2ZW50LmtleUNvZGVcbiAgICAgICAgaWYgY2hhci5sZW5ndGggPiAwXG4gICAgICAgICAgcG9zID0gTWF0aC5taW4gdGV4dGZpZWxkLnNlbGVjdGlvblN0YXJ0LCB0ZXh0ZmllbGQuc2VsZWN0aW9uRW5kXG4gICAgICAgICAgZGlmZiA9IE1hdGguYWJzKHRleHRmaWVsZC5zZWxlY3Rpb25FbmQgLSB0ZXh0ZmllbGQuc2VsZWN0aW9uU3RhcnQpXG4gICAgICAgICAgd29yZC5kZWxldGVUZXh0IChwb3MpLCBkaWZmXG4gICAgICAgICAgd29yZC5pbnNlcnRUZXh0IHBvcywgY2hhclxuICAgICAgICAgIG5ld19wb3MgPSBwb3MgKyBjaGFyLmxlbmd0aFxuICAgICAgICAgIHRleHRmaWVsZC5zZXRTZWxlY3Rpb25SYW5nZSBuZXdfcG9zLCBuZXdfcG9zXG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgICAgICBlbHNlXG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuXG4gICAgICB0ZXh0ZmllbGQub25wYXN0ZSA9IChldmVudCktPlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICB0ZXh0ZmllbGQub25jdXQgPSAoZXZlbnQpLT5cbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuXG4gICAgICAjXG4gICAgICAjIGNvbnN1bWUgZGVsZXRlcy4gTm90ZSB0aGF0XG4gICAgICAjICAgY2hyb21lOiB3b24ndCBjb25zdW1lIGRlbGV0aW9ucyBvbiBrZXlwcmVzcyBldmVudC5cbiAgICAgICMgICBrZXlDb2RlIGlzIGRlcHJlY2F0ZWQuIEJVVDogSSBkb24ndCBzZWUgYW5vdGhlciB3YXkuXG4gICAgICAjICAgICBzaW5jZSBldmVudC5rZXkgaXMgbm90IGltcGxlbWVudGVkIGluIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgY2hyb21lLlxuICAgICAgIyAgICAgRXZlcnkgYnJvd3NlciBzdXBwb3J0cyBrZXlDb2RlLiBMZXQncyBzdGljayB3aXRoIGl0IGZvciBub3cuLlxuICAgICAgI1xuICAgICAgdGV4dGZpZWxkLm9ua2V5ZG93biA9IChldmVudCktPlxuICAgICAgICBwb3MgPSBNYXRoLm1pbiB0ZXh0ZmllbGQuc2VsZWN0aW9uU3RhcnQsIHRleHRmaWVsZC5zZWxlY3Rpb25FbmRcbiAgICAgICAgZGlmZiA9IE1hdGguYWJzKHRleHRmaWVsZC5zZWxlY3Rpb25FbmQgLSB0ZXh0ZmllbGQuc2VsZWN0aW9uU3RhcnQpXG4gICAgICAgIGlmIGV2ZW50LmtleUNvZGU/IGFuZCBldmVudC5rZXlDb2RlIGlzIDggIyBCYWNrc3BhY2VcbiAgICAgICAgICBpZiBkaWZmID4gMFxuICAgICAgICAgICAgd29yZC5kZWxldGVUZXh0IHBvcywgZGlmZlxuICAgICAgICAgICAgdGV4dGZpZWxkLnNldFNlbGVjdGlvblJhbmdlIHBvcywgcG9zXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgaWYgZXZlbnQuY3RybEtleT8gYW5kIGV2ZW50LmN0cmxLZXlcbiAgICAgICAgICAgICAgdmFsID0gdGV4dGZpZWxkLnZhbHVlXG4gICAgICAgICAgICAgIG5ld19wb3MgPSBwb3NcbiAgICAgICAgICAgICAgZGVsX2xlbmd0aCA9IDBcbiAgICAgICAgICAgICAgaWYgcG9zID4gMFxuICAgICAgICAgICAgICAgIG5ld19wb3MtLVxuICAgICAgICAgICAgICAgIGRlbF9sZW5ndGgrK1xuICAgICAgICAgICAgICB3aGlsZSBuZXdfcG9zID4gMCBhbmQgdmFsW25ld19wb3NdIGlzbnQgXCIgXCIgYW5kIHZhbFtuZXdfcG9zXSBpc250ICdcXG4nXG4gICAgICAgICAgICAgICAgbmV3X3Bvcy0tXG4gICAgICAgICAgICAgICAgZGVsX2xlbmd0aCsrXG4gICAgICAgICAgICAgIHdvcmQuZGVsZXRlVGV4dCBuZXdfcG9zLCAocG9zLW5ld19wb3MpXG4gICAgICAgICAgICAgIHRleHRmaWVsZC5zZXRTZWxlY3Rpb25SYW5nZSBuZXdfcG9zLCBuZXdfcG9zXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgIHdvcmQuZGVsZXRlVGV4dCAocG9zLTEpLCAxXG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgICAgICBlbHNlIGlmIGV2ZW50LmtleUNvZGU/IGFuZCBldmVudC5rZXlDb2RlIGlzIDQ2ICMgRGVsZXRlXG4gICAgICAgICAgaWYgZGlmZiA+IDBcbiAgICAgICAgICAgIHdvcmQuZGVsZXRlVGV4dCBwb3MsIGRpZmZcbiAgICAgICAgICAgIHRleHRmaWVsZC5zZXRTZWxlY3Rpb25SYW5nZSBwb3MsIHBvc1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHdvcmQuZGVsZXRlVGV4dCBwb3MsIDFcbiAgICAgICAgICAgIHRleHRmaWVsZC5zZXRTZWxlY3Rpb25SYW5nZSBwb3MsIHBvc1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcblxuXG5cbiAgICAjXG4gICAgIyBAcHJpdmF0ZVxuICAgICMgRW5jb2RlIHRoaXMgb3BlcmF0aW9uIGluIHN1Y2ggYSB3YXkgdGhhdCBpdCBjYW4gYmUgcGFyc2VkIGJ5IHJlbW90ZSBwZWVycy5cbiAgICAjXG4gICAgX2VuY29kZTogKCktPlxuICAgICAganNvbiA9IHtcbiAgICAgICAgJ3R5cGUnOiBcIldvcmRUeXBlXCJcbiAgICAgICAgJ3VpZCcgOiBAZ2V0VWlkKClcbiAgICAgICAgJ2JlZ2lubmluZycgOiBAYmVnaW5uaW5nLmdldFVpZCgpXG4gICAgICAgICdlbmQnIDogQGVuZC5nZXRVaWQoKVxuICAgICAgfVxuICAgICAgaWYgQHByZXZfY2w/XG4gICAgICAgIGpzb25bJ3ByZXYnXSA9IEBwcmV2X2NsLmdldFVpZCgpXG4gICAgICBpZiBAbmV4dF9jbD9cbiAgICAgICAganNvblsnbmV4dCddID0gQG5leHRfY2wuZ2V0VWlkKClcbiAgICAgIGlmIEBvcmlnaW4/ICMgYW5kIEBvcmlnaW4gaXNudCBAcHJldl9jbFxuICAgICAgICBqc29uW1wib3JpZ2luXCJdID0gQG9yaWdpbigpLmdldFVpZCgpXG4gICAgICBqc29uXG5cbiAgcGFyc2VyWydXb3JkVHlwZSddID0gKGpzb24pLT5cbiAgICB7XG4gICAgICAndWlkJyA6IHVpZFxuICAgICAgJ2JlZ2lubmluZycgOiBiZWdpbm5pbmdcbiAgICAgICdlbmQnIDogZW5kXG4gICAgICAncHJldic6IHByZXZcbiAgICAgICduZXh0JzogbmV4dFxuICAgICAgJ29yaWdpbicgOiBvcmlnaW5cbiAgICB9ID0ganNvblxuICAgIG5ldyBXb3JkVHlwZSB1aWQsIGJlZ2lubmluZywgZW5kLCBwcmV2LCBuZXh0LCBvcmlnaW5cblxuICB0eXBlc1snVGV4dEluc2VydCddID0gVGV4dEluc2VydFxuICB0eXBlc1snVGV4dERlbGV0ZSddID0gVGV4dERlbGV0ZVxuICB0eXBlc1snV29yZFR5cGUnXSA9IFdvcmRUeXBlXG4gIHN0cnVjdHVyZWRfdHlwZXNcblxuXG4iLCJcbmpzb25fdHlwZXNfdW5pbml0aWFsaXplZCA9IHJlcXVpcmUgXCIuL0pzb25UeXBlc1wiXG5cbkVsZW1lbnQ/LnByb3RvdHlwZS5fcHJveHkgPSAoZl9uYW1lLCBmKS0+XG4gIG9sZF9mID0gQFtmX25hbWVdXG4gIGlmIG9sZF9mP1xuICAgIEBbZl9uYW1lXSA9ICgpLT5cbiAgICAgIGYuYXBwbHkgdGhpcywgYXJndW1lbnRzXG4gICAgICBvbGRfZi5hcHBseSB0aGlzLCBhcmd1bWVudHNcbiAgZWxzZVxuICAgIEBbZl9uYW1lXSA9IGZcblxuXG5tb2R1bGUuZXhwb3J0cyA9IChIQiktPlxuICBqc29uX3R5cGVzID0ganNvbl90eXBlc191bmluaXRpYWxpemVkIEhCXG4gIHR5cGVzID0ganNvbl90eXBlcy50eXBlc1xuICBwYXJzZXIgPSBqc29uX3R5cGVzLnBhcnNlclxuXG4gICNcbiAgIyBNYW5hZ2VzIFhNTCB0eXBlc1xuICAjXG4gIGNsYXNzIFhtbFR5cGUgZXh0ZW5kcyB0eXBlcy5JbnNlcnRcblxuICAgIGNvbnN0cnVjdG9yOiAodWlkLCBAdGFnbmFtZSwgYXR0cmlidXRlcywgZWxlbWVudHMsIEB4bWwpLT5cbiAgICAgICMjIyBJbiBjYXNlIHlvdSBtYWtlIHRoaXMgaW5zdGFuY2VvZiBJbnNlcnQgYWdhaW5cbiAgICAgIGlmIHByZXY/IGFuZCAobm90IG5leHQ/KSBhbmQgcHJldi50eXBlP1xuICAgICAgICAjIGFkanVzdCB3aGF0IHlvdSBhY3R1YWxseSBtZWFuLiB5b3Ugd2FudCB0byBpbnNlcnQgYWZ0ZXIgcHJldiwgdGhlblxuICAgICAgICAjIG5leHQgaXMgbm90IGRlZmluZWQuIGJ1dCB3ZSBvbmx5IGluc2VydCBhZnRlciBub24tZGVsZXRlZCBlbGVtZW50cy5cbiAgICAgICAgIyBUaGlzIGlzIGFsc28gaGFuZGxlZCBpbiBUZXh0SW5zZXJ0LlxuICAgICAgICB3aGlsZSBwcmV2LmlzRGVsZXRlZCgpXG4gICAgICAgICAgcHJldiA9IHByZXYucHJldl9jbFxuICAgICAgICBuZXh0ID0gcHJldi5uZXh0X2NsXG4gICAgICAjIyNcblxuICAgICAgc3VwZXIoKVxuXG4gICAgICBpZiBhdHRyaWJ1dGVzPyBhbmQgZWxlbWVudHM/XG4gICAgICAgIEBzYXZlT3BlcmF0aW9uICdhdHRyaWJ1dGVzJywgYXR0cmlidXRlc1xuICAgICAgICBAc2F2ZU9wZXJhdGlvbiAnZWxlbWVudHMnLCBlbGVtZW50c1xuICAgICAgZWxzZSBpZiAobm90IGF0dHJpYnV0ZXM/KSBhbmQgKG5vdCBlbGVtZW50cz8pXG4gICAgICAgIEBhdHRyaWJ1dGVzID0gbmV3IHR5cGVzLkpzb25UeXBlKClcbiAgICAgICAgSEIuYWRkT3BlcmF0aW9uKEBhdHRyaWJ1dGVzKS5leGVjdXRlKClcbiAgICAgICAgQGVsZW1lbnRzID0gbmV3IHR5cGVzLldvcmRUeXBlKClcbiAgICAgICAgQGVsZW1lbnRzLnBhcmVudCA9IEBcbiAgICAgICAgSEIuYWRkT3BlcmF0aW9uKEBlbGVtZW50cykuZXhlY3V0ZSgpXG4gICAgICBlbHNlXG4gICAgICAgIHRocm93IG5ldyBFcnJvciBcIkVpdGhlciBkZWZpbmUgYXR0cmlidXRlIGFuZCBlbGVtZW50cyBib3RoLCBvciBub25lIG9mIHRoZW1cIlxuXG4gICAgICBpZiBAeG1sP1xuICAgICAgICBAdGFnbmFtZSA9IEB4bWwudGFnTmFtZVxuICAgICAgICBmb3IgaSBpbiBbMC4uLkB4bWwuYXR0cmlidXRlcy5sZW5ndGhdXG4gICAgICAgICAgYXR0ciA9IHhtbC5hdHRyaWJ1dGVzW2ldXG4gICAgICAgICAgQGF0dHJpYnV0ZXMudmFsKGF0dHIubmFtZSwgYXR0ci52YWx1ZSlcbiAgICAgICAgZm9yIG4gaW4gQHhtbC5jaGlsZE5vZGVzXG4gICAgICAgICAgaWYgbi5ub2RlVHlwZSBpcyBuLlRFWFRfTk9ERVxuICAgICAgICAgICAgd29yZCA9IG5ldyB0eXBlcy5Xb3JkVHlwZSgpXG4gICAgICAgICAgICBIQi5hZGRPcGVyYXRpb24od29yZCkuZXhlY3V0ZSgpXG4gICAgICAgICAgICB3b3JkLnB1c2ggbi50ZXh0Q29udGVudFxuICAgICAgICAgICAgQGVsZW1lbnRzLnB1c2ggd29yZFxuICAgICAgICAgIGVsc2UgaWYgbi5ub2RlVHlwZSBpcyBuLkVMRU1FTlRfTk9ERVxuICAgICAgICAgICAgZWxlbWVudCA9IG5ldyBYbWxUeXBlIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgblxuICAgICAgICAgICAgSEIuYWRkT3BlcmF0aW9uKGVsZW1lbnQpLmV4ZWN1dGUoKVxuICAgICAgICAgICAgQGVsZW1lbnRzLnB1c2ggZWxlbWVudFxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvciBcIkkgZG9uJ3Qga25vdyBOb2RlLXR5cGUgI3tuLm5vZGVUeXBlfSEhXCJcbiAgICAgICAgQHNldFhtbFByb3h5KClcbiAgICAgIHVuZGVmaW5lZFxuXG4gICAgI1xuICAgICMgSWRlbnRpZmllcyB0aGlzIGNsYXNzLlxuICAgICMgVXNlIGl0IGluIG9yZGVyIHRvIGNoZWNrIHdoZXRoZXIgdGhpcyBpcyBhbiB4bWwtdHlwZSBvciBzb21ldGhpbmcgZWxzZS5cbiAgICAjXG4gICAgdHlwZTogXCJYbWxUeXBlXCJcblxuICAgIGFwcGx5RGVsZXRlOiAoKS0+XG4gICAgICBAYXR0cmlidXRlcy5hcHBseURlbGV0ZSgpXG4gICAgICBAZWxlbWVudHMuYXBwbHlEZWxldGUoKVxuICAgICAgc3VwZXIoKVxuXG4gICAgY2xlYW51cDogKCktPlxuICAgICAgc3VwZXIoKVxuXG4gICAgc2V0WG1sUHJveHk6ICgpLT5cbiAgICAgIEB4bWwuX3lhdHRhID0gQFxuICAgICAgQHhtbC5fcHJveHkgJ2luc2VydEJlZm9yZScsIChpbnNlcnRlZE5vZGUsIGFkamFjZW50Tm9kZSktPlxuICAgICAgICBuZXh0ID0gYWRqYWNlbnROb2RlPy5feWF0dGFcbiAgICAgICAgcHJldiA9IG51bGxcbiAgICAgICAgaWYgbmV4dD9cbiAgICAgICAgICBwcmV2ID0gbmV4dC5wcmV2X2NsXG4gICAgICAgIGVsc2VcbiAgICAgICAgICBwcmV2ID0gQF95YXR0YS5lbGVtZW50cy5lbmQucHJldl9jbFxuICAgICAgICBlbGVtZW50ID0gbmV3IFhtbFR5cGUgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkXG4gICAgICAgIEhCLmFkZE9wZXJhdGlvbihlbGVtZW50KS5leGVjdXRlKClcbiAgICAgICAgQGVsZW1lbnRzLmluc2VydEFmdGVyIHByZXYsIGVsZW1lbnRcblxuICAgIHZhbDogKGVuZm9yY2UgPSBmYWxzZSktPlxuICAgICAgaWYgZG9jdW1lbnQ/XG4gICAgICAgIGlmIChub3QgQHhtbD8pIG9yIGVuZm9yY2VcbiAgICAgICAgICBAeG1sID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBAdGFnbmFtZVxuXG4gICAgICAgICAgYXR0ciA9IEBhdHRyaWJ1dGVzLnZhbCgpXG4gICAgICAgICAgZm9yIGF0dHJfbmFtZSwgdmFsdWUgb2YgYXR0clxuICAgICAgICAgICAgYSA9IGRvY3VtZW50LmNyZWF0ZUF0dHJpYnV0ZSBhdHRyX25hbWVcbiAgICAgICAgICAgIGEudmFsdWUgPSB2YWx1ZVxuICAgICAgICAgICAgQHhtbC5zZXRBdHRyaWJ1dGVOb2RlIGFcblxuICAgICAgICAgIGUgPSBAZWxlbWVudHMuYmVnaW5uaW5nLm5leHRfY2xcbiAgICAgICAgICB3aGlsZSBlLnR5cGUgaXNudCBcIkRlbGltaXRlclwiXG4gICAgICAgICAgICBuID0gZS5jb250ZW50XG4gICAgICAgICAgICBpZiBub3Qgbi5pc0RlbGV0ZWQoKVxuICAgICAgICAgICAgICBpZiBuLnR5cGUgaXMgXCJYbWxUeXBlXCJcbiAgICAgICAgICAgICAgICBAeG1sLmFwcGVuZENoaWxkIG4udmFsKGVuZm9yY2UpXG4gICAgICAgICAgICAgIGVsc2UgaWYgbi50eXBlIGlzIFwiV29yZFR5cGVcIlxuICAgICAgICAgICAgICAgIHRleHRfbm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlIG4udmFsKClcbiAgICAgICAgICAgICAgICBAeG1sLmFwcGVuZENoaWxkIHRleHRfbm9kZVxuICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yIFwiSW50ZXJuYWwgc3RydWN0dXJlIGNhbm5vdCBiZSB0cmFuc2Zvcm1lZCB0byBkb21cIlxuICAgICAgICAgICAgZSA9IGUubmV4dF9jbFxuICAgICAgICBAc2V0WG1sUHJveHkoKVxuICAgICAgICBAeG1sXG5cblxuXG4gICAgI1xuICAgICMgSWYgcG9zc2libGUgc2V0IHRoZSByZXBsYWNlIG1hbmFnZXIgaW4gdGhlIGNvbnRlbnQuXG4gICAgIyBAc2VlIFdvcmRUeXBlLnNldFJlcGxhY2VNYW5hZ2VyXG4gICAgI1xuICAgIGV4ZWN1dGU6ICgpLT5cbiAgICAgIHN1cGVyXG4gICAgIyMjXG4gICAgICBpZiBub3QgQHZhbGlkYXRlU2F2ZWRPcGVyYXRpb25zKClcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICBlbHNlXG5cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAjIyNcblxuICAgICNcbiAgICAjIEdldCB0aGUgcGFyZW50IG9mIHRoaXMgSnNvblR5cGUuXG4gICAgIyBAcmV0dXJuIHtYbWxUeXBlfVxuICAgICNcbiAgICBnZXRQYXJlbnQ6ICgpLT5cbiAgICAgIEBwYXJlbnRcblxuICAgICNcbiAgICAjIEBwcml2YXRlXG4gICAgI1xuICAgICMgQ29udmVydCBhbGwgcmVsZXZhbnQgaW5mb3JtYXRpb24gb2YgdGhpcyBvcGVyYXRpb24gdG8gdGhlIGpzb24tZm9ybWF0LlxuICAgICMgVGhpcyByZXN1bHQgY2FuIGJlIHNlbmQgdG8gb3RoZXIgY2xpZW50cy5cbiAgICAjXG4gICAgX2VuY29kZTogKCktPlxuICAgICAganNvbiA9XG4gICAgICAgIHtcbiAgICAgICAgICAndHlwZScgOiBAdHlwZVxuICAgICAgICAgICdhdHRyaWJ1dGVzJyA6IEBhdHRyaWJ1dGVzLmdldFVpZCgpXG4gICAgICAgICAgJ2VsZW1lbnRzJyA6IEBlbGVtZW50cy5nZXRVaWQoKVxuICAgICAgICAgICd0YWduYW1lJyA6IEB0YWduYW1lXG4gICAgICAgICAgJ3VpZCcgOiBAZ2V0VWlkKClcblxuICAgICAgICB9XG4gICAgICBqc29uXG5cbiAgcGFyc2VyWydYbWxUeXBlJ10gPSAoanNvbiktPlxuICAgIHtcbiAgICAgICd1aWQnIDogdWlkXG4gICAgICAnYXR0cmlidXRlcycgOiBhdHRyaWJ1dGVzXG4gICAgICAnZWxlbWVudHMnIDogZWxlbWVudHNcbiAgICAgICd0YWduYW1lJyA6IHRhZ25hbWVcbiAgICB9ID0ganNvblxuXG4gICAgbmV3IFhtbFR5cGUgdWlkLCB0YWduYW1lLCBhdHRyaWJ1dGVzLCBlbGVtZW50cywgdW5kZWZpbmVkXG5cblxuICB0eXBlc1snWG1sVHlwZSddID0gWG1sVHlwZVxuXG4gIGpzb25fdHlwZXNcbiIsIlxuXG5leHBvcnRzWydJd2NDb25uZWN0b3InXSA9XG4gIHJlcXVpcmUgJy4vQ29ubmVjdG9ycy9Jd2NDb25uZWN0b3InXG5leHBvcnRzWydUZXN0Q29ubmVjdG9yJ10gPVxuICByZXF1aXJlICcuL0Nvbm5lY3RvcnMvVGVzdENvbm5lY3RvcidcbmV4cG9ydHNbJ0pzb25GcmFtZXdvcmsnXSA9XG4gIHJlcXVpcmUgJy4vRnJhbWV3b3Jrcy9Kc29uRnJhbWV3b3JrJ1xuZXhwb3J0c1snVGV4dEZyYW1ld29yayddID1cbiAgcmVxdWlyZSAnLi9GcmFtZXdvcmtzL1RleHRGcmFtZXdvcmsnXG5leHBvcnRzWydYbWxGcmFtZXdvcmsnXSA9XG4gIHJlcXVpcmUgJy4vRnJhbWV3b3Jrcy9YbWxGcmFtZXdvcmsnXG5cbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvY2hhaScpO1xuIiwiLyohXG4gKiBjaGFpXG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIHVzZWQgPSBbXVxuICAsIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vKiFcbiAqIENoYWkgdmVyc2lvblxuICovXG5cbmV4cG9ydHMudmVyc2lvbiA9ICcxLjkuMSc7XG5cbi8qIVxuICogQXNzZXJ0aW9uIEVycm9yXG4gKi9cblxuZXhwb3J0cy5Bc3NlcnRpb25FcnJvciA9IHJlcXVpcmUoJ2Fzc2VydGlvbi1lcnJvcicpO1xuXG4vKiFcbiAqIFV0aWxzIGZvciBwbHVnaW5zIChub3QgZXhwb3J0ZWQpXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuL2NoYWkvdXRpbHMnKTtcblxuLyoqXG4gKiAjIC51c2UoZnVuY3Rpb24pXG4gKlxuICogUHJvdmlkZXMgYSB3YXkgdG8gZXh0ZW5kIHRoZSBpbnRlcm5hbHMgb2YgQ2hhaVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259XG4gKiBAcmV0dXJucyB7dGhpc30gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMudXNlID0gZnVuY3Rpb24gKGZuKSB7XG4gIGlmICghfnVzZWQuaW5kZXhPZihmbikpIHtcbiAgICBmbih0aGlzLCB1dGlsKTtcbiAgICB1c2VkLnB1c2goZm4pO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKiFcbiAqIENvbmZpZ3VyYXRpb25cbiAqL1xuXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi9jaGFpL2NvbmZpZycpO1xuZXhwb3J0cy5jb25maWcgPSBjb25maWc7XG5cbi8qIVxuICogUHJpbWFyeSBgQXNzZXJ0aW9uYCBwcm90b3R5cGVcbiAqL1xuXG52YXIgYXNzZXJ0aW9uID0gcmVxdWlyZSgnLi9jaGFpL2Fzc2VydGlvbicpO1xuZXhwb3J0cy51c2UoYXNzZXJ0aW9uKTtcblxuLyohXG4gKiBDb3JlIEFzc2VydGlvbnNcbiAqL1xuXG52YXIgY29yZSA9IHJlcXVpcmUoJy4vY2hhaS9jb3JlL2Fzc2VydGlvbnMnKTtcbmV4cG9ydHMudXNlKGNvcmUpO1xuXG4vKiFcbiAqIEV4cGVjdCBpbnRlcmZhY2VcbiAqL1xuXG52YXIgZXhwZWN0ID0gcmVxdWlyZSgnLi9jaGFpL2ludGVyZmFjZS9leHBlY3QnKTtcbmV4cG9ydHMudXNlKGV4cGVjdCk7XG5cbi8qIVxuICogU2hvdWxkIGludGVyZmFjZVxuICovXG5cbnZhciBzaG91bGQgPSByZXF1aXJlKCcuL2NoYWkvaW50ZXJmYWNlL3Nob3VsZCcpO1xuZXhwb3J0cy51c2Uoc2hvdWxkKTtcblxuLyohXG4gKiBBc3NlcnQgaW50ZXJmYWNlXG4gKi9cblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJy4vY2hhaS9pbnRlcmZhY2UvYXNzZXJ0Jyk7XG5leHBvcnRzLnVzZShhc3NlcnQpO1xuIiwiLyohXG4gKiBjaGFpXG4gKiBodHRwOi8vY2hhaWpzLmNvbVxuICogQ29weXJpZ2h0KGMpIDIwMTEtMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChfY2hhaSwgdXRpbCkge1xuICAvKiFcbiAgICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAgICovXG5cbiAgdmFyIEFzc2VydGlvbkVycm9yID0gX2NoYWkuQXNzZXJ0aW9uRXJyb3JcbiAgICAsIGZsYWcgPSB1dGlsLmZsYWc7XG5cbiAgLyohXG4gICAqIE1vZHVsZSBleHBvcnQuXG4gICAqL1xuXG4gIF9jaGFpLkFzc2VydGlvbiA9IEFzc2VydGlvbjtcblxuICAvKiFcbiAgICogQXNzZXJ0aW9uIENvbnN0cnVjdG9yXG4gICAqXG4gICAqIENyZWF0ZXMgb2JqZWN0IGZvciBjaGFpbmluZy5cbiAgICpcbiAgICogQGFwaSBwcml2YXRlXG4gICAqL1xuXG4gIGZ1bmN0aW9uIEFzc2VydGlvbiAob2JqLCBtc2csIHN0YWNrKSB7XG4gICAgZmxhZyh0aGlzLCAnc3NmaScsIHN0YWNrIHx8IGFyZ3VtZW50cy5jYWxsZWUpO1xuICAgIGZsYWcodGhpcywgJ29iamVjdCcsIG9iaik7XG4gICAgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gIH1cblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQXNzZXJ0aW9uLCAnaW5jbHVkZVN0YWNrJywge1xuICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ0Fzc2VydGlvbi5pbmNsdWRlU3RhY2sgaXMgZGVwcmVjYXRlZCwgdXNlIGNoYWkuY29uZmlnLmluY2x1ZGVTdGFjayBpbnN0ZWFkLicpO1xuICAgICAgcmV0dXJuIGNvbmZpZy5pbmNsdWRlU3RhY2s7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ0Fzc2VydGlvbi5pbmNsdWRlU3RhY2sgaXMgZGVwcmVjYXRlZCwgdXNlIGNoYWkuY29uZmlnLmluY2x1ZGVTdGFjayBpbnN0ZWFkLicpO1xuICAgICAgY29uZmlnLmluY2x1ZGVTdGFjayA9IHZhbHVlO1xuICAgIH1cbiAgfSk7XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFzc2VydGlvbiwgJ3Nob3dEaWZmJywge1xuICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ0Fzc2VydGlvbi5zaG93RGlmZiBpcyBkZXByZWNhdGVkLCB1c2UgY2hhaS5jb25maWcuc2hvd0RpZmYgaW5zdGVhZC4nKTtcbiAgICAgIHJldHVybiBjb25maWcuc2hvd0RpZmY7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ0Fzc2VydGlvbi5zaG93RGlmZiBpcyBkZXByZWNhdGVkLCB1c2UgY2hhaS5jb25maWcuc2hvd0RpZmYgaW5zdGVhZC4nKTtcbiAgICAgIGNvbmZpZy5zaG93RGlmZiA9IHZhbHVlO1xuICAgIH1cbiAgfSk7XG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5ID0gZnVuY3Rpb24gKG5hbWUsIGZuKSB7XG4gICAgdXRpbC5hZGRQcm9wZXJ0eSh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4pO1xuICB9O1xuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QgPSBmdW5jdGlvbiAobmFtZSwgZm4pIHtcbiAgICB1dGlsLmFkZE1ldGhvZCh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4pO1xuICB9O1xuXG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QgPSBmdW5jdGlvbiAobmFtZSwgZm4sIGNoYWluaW5nQmVoYXZpb3IpIHtcbiAgICB1dGlsLmFkZENoYWluYWJsZU1ldGhvZCh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4sIGNoYWluaW5nQmVoYXZpb3IpO1xuICB9O1xuXG4gIEFzc2VydGlvbi5vdmVyd3JpdGVQcm9wZXJ0eSA9IGZ1bmN0aW9uIChuYW1lLCBmbikge1xuICAgIHV0aWwub3ZlcndyaXRlUHJvcGVydHkodGhpcy5wcm90b3R5cGUsIG5hbWUsIGZuKTtcbiAgfTtcblxuICBBc3NlcnRpb24ub3ZlcndyaXRlTWV0aG9kID0gZnVuY3Rpb24gKG5hbWUsIGZuKSB7XG4gICAgdXRpbC5vdmVyd3JpdGVNZXRob2QodGhpcy5wcm90b3R5cGUsIG5hbWUsIGZuKTtcbiAgfTtcblxuICBBc3NlcnRpb24ub3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kID0gZnVuY3Rpb24gKG5hbWUsIGZuLCBjaGFpbmluZ0JlaGF2aW9yKSB7XG4gICAgdXRpbC5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QodGhpcy5wcm90b3R5cGUsIG5hbWUsIGZuLCBjaGFpbmluZ0JlaGF2aW9yKTtcbiAgfTtcblxuICAvKiFcbiAgICogIyMjIC5hc3NlcnQoZXhwcmVzc2lvbiwgbWVzc2FnZSwgbmVnYXRlTWVzc2FnZSwgZXhwZWN0ZWQsIGFjdHVhbClcbiAgICpcbiAgICogRXhlY3V0ZXMgYW4gZXhwcmVzc2lvbiBhbmQgY2hlY2sgZXhwZWN0YXRpb25zLiBUaHJvd3MgQXNzZXJ0aW9uRXJyb3IgZm9yIHJlcG9ydGluZyBpZiB0ZXN0IGRvZXNuJ3QgcGFzcy5cbiAgICpcbiAgICogQG5hbWUgYXNzZXJ0XG4gICAqIEBwYXJhbSB7UGhpbG9zb3BoaWNhbH0gZXhwcmVzc2lvbiB0byBiZSB0ZXN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgdG8gZGlzcGxheSBpZiBmYWlsc1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbmVnYXRlZE1lc3NhZ2UgdG8gZGlzcGxheSBpZiBuZWdhdGVkIGV4cHJlc3Npb24gZmFpbHNcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWQgdmFsdWUgKHJlbWVtYmVyIHRvIGNoZWNrIGZvciBuZWdhdGlvbilcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsIChvcHRpb25hbCkgd2lsbCBkZWZhdWx0IHRvIGB0aGlzLm9iamBcbiAgICogQGFwaSBwcml2YXRlXG4gICAqL1xuXG4gIEFzc2VydGlvbi5wcm90b3R5cGUuYXNzZXJ0ID0gZnVuY3Rpb24gKGV4cHIsIG1zZywgbmVnYXRlTXNnLCBleHBlY3RlZCwgX2FjdHVhbCwgc2hvd0RpZmYpIHtcbiAgICB2YXIgb2sgPSB1dGlsLnRlc3QodGhpcywgYXJndW1lbnRzKTtcbiAgICBpZiAodHJ1ZSAhPT0gc2hvd0RpZmYpIHNob3dEaWZmID0gZmFsc2U7XG4gICAgaWYgKHRydWUgIT09IGNvbmZpZy5zaG93RGlmZikgc2hvd0RpZmYgPSBmYWxzZTtcblxuICAgIGlmICghb2spIHtcbiAgICAgIHZhciBtc2cgPSB1dGlsLmdldE1lc3NhZ2UodGhpcywgYXJndW1lbnRzKVxuICAgICAgICAsIGFjdHVhbCA9IHV0aWwuZ2V0QWN0dWFsKHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobXNnLCB7XG4gICAgICAgICAgYWN0dWFsOiBhY3R1YWxcbiAgICAgICAgLCBleHBlY3RlZDogZXhwZWN0ZWRcbiAgICAgICAgLCBzaG93RGlmZjogc2hvd0RpZmZcbiAgICAgIH0sIChjb25maWcuaW5jbHVkZVN0YWNrKSA/IHRoaXMuYXNzZXJ0IDogZmxhZyh0aGlzLCAnc3NmaScpKTtcbiAgICB9XG4gIH07XG5cbiAgLyohXG4gICAqICMjIyAuX29ialxuICAgKlxuICAgKiBRdWljayByZWZlcmVuY2UgdG8gc3RvcmVkIGBhY3R1YWxgIHZhbHVlIGZvciBwbHVnaW4gZGV2ZWxvcGVycy5cbiAgICpcbiAgICogQGFwaSBwcml2YXRlXG4gICAqL1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBc3NlcnRpb24ucHJvdG90eXBlLCAnX29iaicsXG4gICAgeyBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgICAgfVxuICAgICwgc2V0OiBmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcsIHZhbCk7XG4gICAgICB9XG4gIH0pO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIC8qKlxuICAgKiAjIyMgY29uZmlnLmluY2x1ZGVTdGFja1xuICAgKlxuICAgKiBVc2VyIGNvbmZpZ3VyYWJsZSBwcm9wZXJ0eSwgaW5mbHVlbmNlcyB3aGV0aGVyIHN0YWNrIHRyYWNlXG4gICAqIGlzIGluY2x1ZGVkIGluIEFzc2VydGlvbiBlcnJvciBtZXNzYWdlLiBEZWZhdWx0IG9mIGZhbHNlXG4gICAqIHN1cHByZXNzZXMgc3RhY2sgdHJhY2UgaW4gdGhlIGVycm9yIG1lc3NhZ2UuXG4gICAqXG4gICAqICAgICBjaGFpLmNvbmZpZy5pbmNsdWRlU3RhY2sgPSB0cnVlOyAgLy8gZW5hYmxlIHN0YWNrIG9uIGVycm9yXG4gICAqXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn1cbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgIGluY2x1ZGVTdGFjazogZmFsc2UsXG5cbiAgLyoqXG4gICAqICMjIyBjb25maWcuc2hvd0RpZmZcbiAgICpcbiAgICogVXNlciBjb25maWd1cmFibGUgcHJvcGVydHksIGluZmx1ZW5jZXMgd2hldGhlciBvciBub3RcbiAgICogdGhlIGBzaG93RGlmZmAgZmxhZyBzaG91bGQgYmUgaW5jbHVkZWQgaW4gdGhlIHRocm93blxuICAgKiBBc3NlcnRpb25FcnJvcnMuIGBmYWxzZWAgd2lsbCBhbHdheXMgYmUgYGZhbHNlYDsgYHRydWVgXG4gICAqIHdpbGwgYmUgdHJ1ZSB3aGVuIHRoZSBhc3NlcnRpb24gaGFzIHJlcXVlc3RlZCBhIGRpZmZcbiAgICogYmUgc2hvd24uXG4gICAqXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn1cbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgc2hvd0RpZmY6IHRydWUsXG5cbiAgLyoqXG4gICAqICMjIyBjb25maWcudHJ1bmNhdGVUaHJlc2hvbGRcbiAgICpcbiAgICogVXNlciBjb25maWd1cmFibGUgcHJvcGVydHksIHNldHMgbGVuZ3RoIHRocmVzaG9sZCBmb3IgYWN0dWFsIGFuZFxuICAgKiBleHBlY3RlZCB2YWx1ZXMgaW4gYXNzZXJ0aW9uIGVycm9ycy4gSWYgdGhpcyB0aHJlc2hvbGQgaXMgZXhjZWVkZWQsXG4gICAqIHRoZSB2YWx1ZSBpcyB0cnVuY2F0ZWQuXG4gICAqXG4gICAqIFNldCBpdCB0byB6ZXJvIGlmIHlvdSB3YW50IHRvIGRpc2FibGUgdHJ1bmNhdGluZyBhbHRvZ2V0aGVyLlxuICAgKlxuICAgKiAgICAgY2hhaS5jb25maWcudHJ1bmNhdGVUaHJlc2hvbGQgPSAwOyAgLy8gZGlzYWJsZSB0cnVuY2F0aW5nXG4gICAqXG4gICAqIEBwYXJhbSB7TnVtYmVyfVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICB0cnVuY2F0ZVRocmVzaG9sZDogNDBcblxufTtcbiIsIi8qIVxuICogY2hhaVxuICogaHR0cDovL2NoYWlqcy5jb21cbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCBfKSB7XG4gIHZhciBBc3NlcnRpb24gPSBjaGFpLkFzc2VydGlvblxuICAgICwgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG4gICAgLCBmbGFnID0gXy5mbGFnO1xuXG4gIC8qKlxuICAgKiAjIyMgTGFuZ3VhZ2UgQ2hhaW5zXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgYXJlIHByb3ZpZGVkIGFzIGNoYWluYWJsZSBnZXR0ZXJzIHRvXG4gICAqIGltcHJvdmUgdGhlIHJlYWRhYmlsaXR5IG9mIHlvdXIgYXNzZXJ0aW9ucy4gVGhleVxuICAgKiBkbyBub3QgcHJvdmlkZSB0ZXN0aW5nIGNhcGFiaWxpdGllcyB1bmxlc3MgdGhleVxuICAgKiBoYXZlIGJlZW4gb3ZlcndyaXR0ZW4gYnkgYSBwbHVnaW4uXG4gICAqXG4gICAqICoqQ2hhaW5zKipcbiAgICpcbiAgICogLSB0b1xuICAgKiAtIGJlXG4gICAqIC0gYmVlblxuICAgKiAtIGlzXG4gICAqIC0gdGhhdFxuICAgKiAtIGFuZFxuICAgKiAtIGhhc1xuICAgKiAtIGhhdmVcbiAgICogLSB3aXRoXG4gICAqIC0gYXRcbiAgICogLSBvZlxuICAgKiAtIHNhbWVcbiAgICpcbiAgICogQG5hbWUgbGFuZ3VhZ2UgY2hhaW5zXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIFsgJ3RvJywgJ2JlJywgJ2JlZW4nXG4gICwgJ2lzJywgJ2FuZCcsICdoYXMnLCAnaGF2ZSdcbiAgLCAnd2l0aCcsICd0aGF0JywgJ2F0J1xuICAsICdvZicsICdzYW1lJyBdLmZvckVhY2goZnVuY3Rpb24gKGNoYWluKSB7XG4gICAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KGNoYWluLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9KTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAubm90XG4gICAqXG4gICAqIE5lZ2F0ZXMgYW55IG9mIGFzc2VydGlvbnMgZm9sbG93aW5nIGluIHRoZSBjaGFpbi5cbiAgICpcbiAgICogICAgIGV4cGVjdChmb28pLnRvLm5vdC5lcXVhbCgnYmFyJyk7XG4gICAqICAgICBleHBlY3QoZ29vZEZuKS50by5ub3QudGhyb3coRXJyb3IpO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmF6JyB9KS50by5oYXZlLnByb3BlcnR5KCdmb28nKVxuICAgKiAgICAgICAuYW5kLm5vdC5lcXVhbCgnYmFyJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ25vdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBmbGFnKHRoaXMsICduZWdhdGUnLCB0cnVlKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuZGVlcFxuICAgKlxuICAgKiBTZXRzIHRoZSBgZGVlcGAgZmxhZywgbGF0ZXIgdXNlZCBieSB0aGUgYGVxdWFsYCBhbmRcbiAgICogYHByb3BlcnR5YCBhc3NlcnRpb25zLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZvbykudG8uZGVlcC5lcXVhbCh7IGJhcjogJ2JheicgfSk7XG4gICAqICAgICBleHBlY3QoeyBmb286IHsgYmFyOiB7IGJhejogJ3F1dXgnIH0gfSB9KVxuICAgKiAgICAgICAudG8uaGF2ZS5kZWVwLnByb3BlcnR5KCdmb28uYmFyLmJheicsICdxdXV4Jyk7XG4gICAqXG4gICAqIEBuYW1lIGRlZXBcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdkZWVwJywgZnVuY3Rpb24gKCkge1xuICAgIGZsYWcodGhpcywgJ2RlZXAnLCB0cnVlKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuYSh0eXBlKVxuICAgKlxuICAgKiBUaGUgYGFgIGFuZCBgYW5gIGFzc2VydGlvbnMgYXJlIGFsaWFzZXMgdGhhdCBjYW4gYmVcbiAgICogdXNlZCBlaXRoZXIgYXMgbGFuZ3VhZ2UgY2hhaW5zIG9yIHRvIGFzc2VydCBhIHZhbHVlJ3NcbiAgICogdHlwZS5cbiAgICpcbiAgICogICAgIC8vIHR5cGVvZlxuICAgKiAgICAgZXhwZWN0KCd0ZXN0JykudG8uYmUuYSgnc3RyaW5nJyk7XG4gICAqICAgICBleHBlY3QoeyBmb286ICdiYXInIH0pLnRvLmJlLmFuKCdvYmplY3QnKTtcbiAgICogICAgIGV4cGVjdChudWxsKS50by5iZS5hKCdudWxsJyk7XG4gICAqICAgICBleHBlY3QodW5kZWZpbmVkKS50by5iZS5hbigndW5kZWZpbmVkJyk7XG4gICAqXG4gICAqICAgICAvLyBsYW5ndWFnZSBjaGFpblxuICAgKiAgICAgZXhwZWN0KGZvbykudG8uYmUuYW4uaW5zdGFuY2VvZihGb28pO1xuICAgKlxuICAgKiBAbmFtZSBhXG4gICAqIEBhbGlhcyBhblxuICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFuICh0eXBlLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB0eXBlID0gdHlwZS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBhcnRpY2xlID0gflsgJ2EnLCAnZScsICdpJywgJ28nLCAndScgXS5pbmRleE9mKHR5cGUuY2hhckF0KDApKSA/ICdhbiAnIDogJ2EgJztcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB0eXBlID09PSBfLnR5cGUob2JqKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSAnICsgYXJ0aWNsZSArIHR5cGVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlICcgKyBhcnRpY2xlICsgdHlwZVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdhbicsIGFuKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnYScsIGFuKTtcblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlKHZhbHVlKVxuICAgKlxuICAgKiBUaGUgYGluY2x1ZGVgIGFuZCBgY29udGFpbmAgYXNzZXJ0aW9ucyBjYW4gYmUgdXNlZCBhcyBlaXRoZXIgcHJvcGVydHlcbiAgICogYmFzZWQgbGFuZ3VhZ2UgY2hhaW5zIG9yIGFzIG1ldGhvZHMgdG8gYXNzZXJ0IHRoZSBpbmNsdXNpb24gb2YgYW4gb2JqZWN0XG4gICAqIGluIGFuIGFycmF5IG9yIGEgc3Vic3RyaW5nIGluIGEgc3RyaW5nLiBXaGVuIHVzZWQgYXMgbGFuZ3VhZ2UgY2hhaW5zLFxuICAgKiB0aGV5IHRvZ2dsZSB0aGUgYGNvbnRhaW5gIGZsYWcgZm9yIHRoZSBga2V5c2AgYXNzZXJ0aW9uLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFsxLDIsM10pLnRvLmluY2x1ZGUoMik7XG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicpLnRvLmNvbnRhaW4oJ2ZvbycpO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJywgaGVsbG86ICd1bml2ZXJzZScgfSkudG8uaW5jbHVkZS5rZXlzKCdmb28nKTtcbiAgICpcbiAgICogQG5hbWUgaW5jbHVkZVxuICAgKiBAYWxpYXMgY29udGFpblxuICAgKiBAcGFyYW0ge09iamVjdHxTdHJpbmd8TnVtYmVyfSBvYmpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBpbmNsdWRlQ2hhaW5pbmdCZWhhdmlvciAoKSB7XG4gICAgZmxhZyh0aGlzLCAnY29udGFpbnMnLCB0cnVlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluY2x1ZGUgKHZhbCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIHZhciBleHBlY3RlZCA9IGZhbHNlO1xuICAgIGlmIChfLnR5cGUob2JqKSA9PT0gJ2FycmF5JyAmJiBfLnR5cGUodmFsKSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGZvciAodmFyIGkgaW4gb2JqKSB7XG4gICAgICAgIGlmIChfLmVxbChvYmpbaV0sIHZhbCkpIHtcbiAgICAgICAgICBleHBlY3RlZCA9IHRydWU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKF8udHlwZSh2YWwpID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKCFmbGFnKHRoaXMsICduZWdhdGUnKSkge1xuICAgICAgICBmb3IgKHZhciBrIGluIHZhbCkgbmV3IEFzc2VydGlvbihvYmopLnByb3BlcnR5KGssIHZhbFtrXSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciBzdWJzZXQgPSB7fVxuICAgICAgZm9yICh2YXIgayBpbiB2YWwpIHN1YnNldFtrXSA9IG9ialtrXVxuICAgICAgZXhwZWN0ZWQgPSBfLmVxbChzdWJzZXQsIHZhbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cGVjdGVkID0gb2JqICYmIH5vYmouaW5kZXhPZih2YWwpXG4gICAgfVxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBleHBlY3RlZFxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBpbmNsdWRlICcgKyBfLmluc3BlY3QodmFsKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaW5jbHVkZSAnICsgXy5pbnNwZWN0KHZhbCkpO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnaW5jbHVkZScsIGluY2x1ZGUsIGluY2x1ZGVDaGFpbmluZ0JlaGF2aW9yKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnY29udGFpbicsIGluY2x1ZGUsIGluY2x1ZGVDaGFpbmluZ0JlaGF2aW9yKTtcblxuICAvKipcbiAgICogIyMjIC5va1xuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyB0cnV0aHkuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2V2ZXJ0aGluZycpLnRvLmJlLm9rO1xuICAgKiAgICAgZXhwZWN0KDEpLnRvLmJlLm9rO1xuICAgKiAgICAgZXhwZWN0KGZhbHNlKS50by5ub3QuYmUub2s7XG4gICAqICAgICBleHBlY3QodW5kZWZpbmVkKS50by5ub3QuYmUub2s7XG4gICAqICAgICBleHBlY3QobnVsbCkudG8ubm90LmJlLm9rO1xuICAgKlxuICAgKiBAbmFtZSBva1xuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ29rJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB0cnV0aHknXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGZhbHN5Jyk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLnRydWVcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgYHRydWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHRydWUpLnRvLmJlLnRydWU7XG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LmJlLnRydWU7XG4gICAqXG4gICAqIEBuYW1lIHRydWVcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCd0cnVlJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB0cnVlID09PSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB0cnVlJ1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBmYWxzZSdcbiAgICAgICwgdGhpcy5uZWdhdGUgPyBmYWxzZSA6IHRydWVcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5mYWxzZVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBgZmFsc2VgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZhbHNlKS50by5iZS5mYWxzZTtcbiAgICogICAgIGV4cGVjdCgwKS50by5ub3QuYmUuZmFsc2U7XG4gICAqXG4gICAqIEBuYW1lIGZhbHNlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZmFsc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIGZhbHNlID09PSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBmYWxzZSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgdHJ1ZSdcbiAgICAgICwgdGhpcy5uZWdhdGUgPyB0cnVlIDogZmFsc2VcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5udWxsXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGBudWxsYC5cbiAgICpcbiAgICogICAgIGV4cGVjdChudWxsKS50by5iZS5udWxsO1xuICAgKiAgICAgZXhwZWN0KHVuZGVmaW5lZCkubm90LnRvLmJlLm51bGw7XG4gICAqXG4gICAqIEBuYW1lIG51bGxcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdudWxsJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBudWxsID09PSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBudWxsJ1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgbnVsbCdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC51bmRlZmluZWRcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqICAgICBleHBlY3QodW5kZWZpbmVkKS50by5iZS51bmRlZmluZWQ7XG4gICAqICAgICBleHBlY3QobnVsbCkudG8ubm90LmJlLnVuZGVmaW5lZDtcbiAgICpcbiAgICogQG5hbWUgdW5kZWZpbmVkXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgndW5kZWZpbmVkJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB1bmRlZmluZWQgPT09IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHVuZGVmaW5lZCdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlIHVuZGVmaW5lZCdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5leGlzdFxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBuZWl0aGVyIGBudWxsYCBub3IgYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqICAgICB2YXIgZm9vID0gJ2hpJ1xuICAgKiAgICAgICAsIGJhciA9IG51bGxcbiAgICogICAgICAgLCBiYXo7XG4gICAqXG4gICAqICAgICBleHBlY3QoZm9vKS50by5leGlzdDtcbiAgICogICAgIGV4cGVjdChiYXIpLnRvLm5vdC5leGlzdDtcbiAgICogICAgIGV4cGVjdChiYXopLnRvLm5vdC5leGlzdDtcbiAgICpcbiAgICogQG5hbWUgZXhpc3RcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdleGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgbnVsbCAhPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBleGlzdCdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGV4aXN0J1xuICAgICk7XG4gIH0pO1xuXG5cbiAgLyoqXG4gICAqICMjIyAuZW1wdHlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQncyBsZW5ndGggaXMgYDBgLiBGb3IgYXJyYXlzLCBpdCBjaGVja3NcbiAgICogdGhlIGBsZW5ndGhgIHByb3BlcnR5LiBGb3Igb2JqZWN0cywgaXQgZ2V0cyB0aGUgY291bnQgb2ZcbiAgICogZW51bWVyYWJsZSBrZXlzLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFtdKS50by5iZS5lbXB0eTtcbiAgICogICAgIGV4cGVjdCgnJykudG8uYmUuZW1wdHk7XG4gICAqICAgICBleHBlY3Qoe30pLnRvLmJlLmVtcHR5O1xuICAgKlxuICAgKiBAbmFtZSBlbXB0eVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2VtcHR5JywgZnVuY3Rpb24gKCkge1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBleHBlY3RlZCA9IG9iajtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikgfHwgJ3N0cmluZycgPT09IHR5cGVvZiBvYmplY3QpIHtcbiAgICAgIGV4cGVjdGVkID0gb2JqLmxlbmd0aDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnKSB7XG4gICAgICBleHBlY3RlZCA9IE9iamVjdC5rZXlzKG9iaikubGVuZ3RoO1xuICAgIH1cblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAhZXhwZWN0ZWRcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgZW1wdHknXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSBlbXB0eSdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5hcmd1bWVudHNcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgYW4gYXJndW1lbnRzIG9iamVjdC5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIHRlc3QgKCkge1xuICAgKiAgICAgICBleHBlY3QoYXJndW1lbnRzKS50by5iZS5hcmd1bWVudHM7XG4gICAqICAgICB9XG4gICAqXG4gICAqIEBuYW1lIGFyZ3VtZW50c1xuICAgKiBAYWxpYXMgQXJndW1lbnRzXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGNoZWNrQXJndW1lbnRzICgpIHtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgdHlwZSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAnW29iamVjdCBBcmd1bWVudHNdJyA9PT0gdHlwZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhcmd1bWVudHMgYnV0IGdvdCAnICsgdHlwZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgYXJndW1lbnRzJ1xuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2FyZ3VtZW50cycsIGNoZWNrQXJndW1lbnRzKTtcbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdBcmd1bWVudHMnLCBjaGVja0FyZ3VtZW50cyk7XG5cbiAgLyoqXG4gICAqICMjIyAuZXF1YWwodmFsdWUpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIHN0cmljdGx5IGVxdWFsIChgPT09YCkgdG8gYHZhbHVlYC5cbiAgICogQWx0ZXJuYXRlbHksIGlmIHRoZSBgZGVlcGAgZmxhZyBpcyBzZXQsIGFzc2VydHMgdGhhdFxuICAgKiB0aGUgdGFyZ2V0IGlzIGRlZXBseSBlcXVhbCB0byBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdoZWxsbycpLnRvLmVxdWFsKCdoZWxsbycpO1xuICAgKiAgICAgZXhwZWN0KDQyKS50by5lcXVhbCg0Mik7XG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LmVxdWFsKHRydWUpO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJyB9KS50by5ub3QuZXF1YWwoeyBmb286ICdiYXInIH0pO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJyB9KS50by5kZWVwLmVxdWFsKHsgZm9vOiAnYmFyJyB9KTtcbiAgICpcbiAgICogQG5hbWUgZXF1YWxcbiAgICogQGFsaWFzIGVxdWFsc1xuICAgKiBAYWxpYXMgZXFcbiAgICogQGFsaWFzIGRlZXAuZXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRFcXVhbCAodmFsLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgaWYgKGZsYWcodGhpcywgJ2RlZXAnKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZXFsKHZhbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIHZhbCA9PT0gb2JqXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gZXF1YWwgI3tleHB9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBlcXVhbCAje2V4cH0nXG4gICAgICAgICwgdmFsXG4gICAgICAgICwgdGhpcy5fb2JqXG4gICAgICAgICwgdHJ1ZVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcXVhbCcsIGFzc2VydEVxdWFsKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZXF1YWxzJywgYXNzZXJ0RXF1YWwpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcScsIGFzc2VydEVxdWFsKTtcblxuICAvKipcbiAgICogIyMjIC5lcWwodmFsdWUpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGRlZXBseSBlcXVhbCB0byBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJyB9KS50by5lcWwoeyBmb286ICdiYXInIH0pO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5lcWwoWyAxLCAyLCAzIF0pO1xuICAgKlxuICAgKiBAbmFtZSBlcWxcbiAgICogQGFsaWFzIGVxbHNcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRFcWwob2JqLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgXy5lcWwob2JqLCBmbGFnKHRoaXMsICdvYmplY3QnKSlcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gZGVlcGx5IGVxdWFsICN7ZXhwfSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGRlZXBseSBlcXVhbCAje2V4cH0nXG4gICAgICAsIG9ialxuICAgICAgLCB0aGlzLl9vYmpcbiAgICAgICwgdHJ1ZVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcWwnLCBhc3NlcnRFcWwpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcWxzJywgYXNzZXJ0RXFsKTtcblxuICAvKipcbiAgICogIyMjIC5hYm92ZSh2YWx1ZSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgZ3JlYXRlciB0aGFuIGB2YWx1ZWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMTApLnRvLmJlLmFib3ZlKDUpO1xuICAgKlxuICAgKiBDYW4gYWxzbyBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggYGxlbmd0aGAgdG9cbiAgICogYXNzZXJ0IGEgbWluaW11bSBsZW5ndGguIFRoZSBiZW5lZml0IGJlaW5nIGFcbiAgICogbW9yZSBpbmZvcm1hdGl2ZSBlcnJvciBtZXNzYWdlIHRoYW4gaWYgdGhlIGxlbmd0aFxuICAgKiB3YXMgc3VwcGxpZWQgZGlyZWN0bHkuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoLmFib3ZlKDIpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5oYXZlLmxlbmd0aC5hYm92ZSgyKTtcbiAgICpcbiAgICogQG5hbWUgYWJvdmVcbiAgICogQGFsaWFzIGd0XG4gICAqIEBhbGlhcyBncmVhdGVyVGhhblxuICAgKiBAcGFyYW0ge051bWJlcn0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRBYm92ZSAobiwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIGlmIChmbGFnKHRoaXMsICdkb0xlbmd0aCcpKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICAgIHZhciBsZW4gPSBvYmoubGVuZ3RoO1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgbGVuID4gblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYWJvdmUgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIGEgbGVuZ3RoIGFib3ZlICN7ZXhwfSdcbiAgICAgICAgLCBuXG4gICAgICAgICwgbGVuXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBvYmogPiBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYWJvdmUgJyArIG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhdCBtb3N0ICcgKyBuXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2Fib3ZlJywgYXNzZXJ0QWJvdmUpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdndCcsIGFzc2VydEFib3ZlKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZ3JlYXRlclRoYW4nLCBhc3NlcnRBYm92ZSk7XG5cbiAgLyoqXG4gICAqICMjIyAubGVhc3QodmFsdWUpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEwKS50by5iZS5hdC5sZWFzdCgxMCk7XG4gICAqXG4gICAqIENhbiBhbHNvIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBgbGVuZ3RoYCB0b1xuICAgKiBhc3NlcnQgYSBtaW5pbXVtIGxlbmd0aC4gVGhlIGJlbmVmaXQgYmVpbmcgYVxuICAgKiBtb3JlIGluZm9ybWF0aXZlIGVycm9yIG1lc3NhZ2UgdGhhbiBpZiB0aGUgbGVuZ3RoXG4gICAqIHdhcyBzdXBwbGllZCBkaXJlY3RseS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGgub2YuYXQubGVhc3QoMik7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLm9mLmF0LmxlYXN0KDMpO1xuICAgKlxuICAgKiBAbmFtZSBsZWFzdFxuICAgKiBAYWxpYXMgZ3RlXG4gICAqIEBwYXJhbSB7TnVtYmVyfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydExlYXN0IChuLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgaWYgKGZsYWcodGhpcywgJ2RvTGVuZ3RoJykpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLmhhdmUucHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgICAgdmFyIGxlbiA9IG9iai5sZW5ndGg7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBsZW4gPj0gblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYXQgbGVhc3QgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYmVsb3cgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICAgLCBsZW5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA+PSBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYXQgbGVhc3QgJyArIG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBiZWxvdyAnICsgblxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdsZWFzdCcsIGFzc2VydExlYXN0KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZ3RlJywgYXNzZXJ0TGVhc3QpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmJlbG93KHZhbHVlKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBsZXNzIHRoYW4gYHZhbHVlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCg1KS50by5iZS5iZWxvdygxMCk7XG4gICAqXG4gICAqIENhbiBhbHNvIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBgbGVuZ3RoYCB0b1xuICAgKiBhc3NlcnQgYSBtYXhpbXVtIGxlbmd0aC4gVGhlIGJlbmVmaXQgYmVpbmcgYVxuICAgKiBtb3JlIGluZm9ybWF0aXZlIGVycm9yIG1lc3NhZ2UgdGhhbiBpZiB0aGUgbGVuZ3RoXG4gICAqIHdhcyBzdXBwbGllZCBkaXJlY3RseS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGguYmVsb3coNCk7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLmJlbG93KDQpO1xuICAgKlxuICAgKiBAbmFtZSBiZWxvd1xuICAgKiBAYWxpYXMgbHRcbiAgICogQGFsaWFzIGxlc3NUaGFuXG4gICAqIEBwYXJhbSB7TnVtYmVyfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEJlbG93IChuLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgaWYgKGZsYWcodGhpcywgJ2RvTGVuZ3RoJykpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLmhhdmUucHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgICAgdmFyIGxlbiA9IG9iai5sZW5ndGg7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBsZW4gPCBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBhIGxlbmd0aCBiZWxvdyAje2V4cH0gYnV0IGdvdCAje2FjdH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgYSBsZW5ndGggYmVsb3cgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICAgLCBsZW5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA8IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBiZWxvdyAnICsgblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGF0IGxlYXN0ICcgKyBuXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2JlbG93JywgYXNzZXJ0QmVsb3cpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdsdCcsIGFzc2VydEJlbG93KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbGVzc1RoYW4nLCBhc3NlcnRCZWxvdyk7XG5cbiAgLyoqXG4gICAqICMjIyAubW9zdCh2YWx1ZSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGB2YWx1ZWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoNSkudG8uYmUuYXQubW9zdCg1KTtcbiAgICpcbiAgICogQ2FuIGFsc28gYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGBsZW5ndGhgIHRvXG4gICAqIGFzc2VydCBhIG1heGltdW0gbGVuZ3RoLiBUaGUgYmVuZWZpdCBiZWluZyBhXG4gICAqIG1vcmUgaW5mb3JtYXRpdmUgZXJyb3IgbWVzc2FnZSB0aGFuIGlmIHRoZSBsZW5ndGhcbiAgICogd2FzIHN1cHBsaWVkIGRpcmVjdGx5LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aC5vZi5hdC5tb3N0KDQpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5oYXZlLmxlbmd0aC5vZi5hdC5tb3N0KDMpO1xuICAgKlxuICAgKiBAbmFtZSBtb3N0XG4gICAqIEBhbGlhcyBsdGVcbiAgICogQHBhcmFtIHtOdW1iZXJ9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0TW9zdCAobiwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIGlmIChmbGFnKHRoaXMsICdkb0xlbmd0aCcpKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICAgIHZhciBsZW4gPSBvYmoubGVuZ3RoO1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgbGVuIDw9IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgbGVuZ3RoIGF0IG1vc3QgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYWJvdmUgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICAgLCBsZW5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA8PSBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYXQgbW9zdCAnICsgblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGFib3ZlICcgKyBuXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ21vc3QnLCBhc3NlcnRNb3N0KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbHRlJywgYXNzZXJ0TW9zdCk7XG5cbiAgLyoqXG4gICAqICMjIyAud2l0aGluKHN0YXJ0LCBmaW5pc2gpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIHdpdGhpbiBhIHJhbmdlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDcpLnRvLmJlLndpdGhpbig1LDEwKTtcbiAgICpcbiAgICogQ2FuIGFsc28gYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGBsZW5ndGhgIHRvXG4gICAqIGFzc2VydCBhIGxlbmd0aCByYW5nZS4gVGhlIGJlbmVmaXQgYmVpbmcgYVxuICAgKiBtb3JlIGluZm9ybWF0aXZlIGVycm9yIG1lc3NhZ2UgdGhhbiBpZiB0aGUgbGVuZ3RoXG4gICAqIHdhcyBzdXBwbGllZCBkaXJlY3RseS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGgud2l0aGluKDIsNCk7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLndpdGhpbigyLDQpO1xuICAgKlxuICAgKiBAbmFtZSB3aXRoaW5cbiAgICogQHBhcmFtIHtOdW1iZXJ9IHN0YXJ0IGxvd2VyYm91bmQgaW5jbHVzaXZlXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBmaW5pc2ggdXBwZXJib3VuZCBpbmNsdXNpdmVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCd3aXRoaW4nLCBmdW5jdGlvbiAoc3RhcnQsIGZpbmlzaCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIHJhbmdlID0gc3RhcnQgKyAnLi4nICsgZmluaXNoO1xuICAgIGlmIChmbGFnKHRoaXMsICdkb0xlbmd0aCcpKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICAgIHZhciBsZW4gPSBvYmoubGVuZ3RoO1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgbGVuID49IHN0YXJ0ICYmIGxlbiA8PSBmaW5pc2hcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgbGVuZ3RoIHdpdGhpbiAnICsgcmFuZ2VcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSBhIGxlbmd0aCB3aXRoaW4gJyArIHJhbmdlXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBvYmogPj0gc3RhcnQgJiYgb2JqIDw9IGZpbmlzaFxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHdpdGhpbiAnICsgcmFuZ2VcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgd2l0aGluICcgKyByYW5nZVxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmluc3RhbmNlb2YoY29uc3RydWN0b3IpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGFuIGluc3RhbmNlIG9mIGBjb25zdHJ1Y3RvcmAuXG4gICAqXG4gICAqICAgICB2YXIgVGVhID0gZnVuY3Rpb24gKG5hbWUpIHsgdGhpcy5uYW1lID0gbmFtZTsgfVxuICAgKiAgICAgICAsIENoYWkgPSBuZXcgVGVhKCdjaGFpJyk7XG4gICAqXG4gICAqICAgICBleHBlY3QoQ2hhaSkudG8uYmUuYW4uaW5zdGFuY2VvZihUZWEpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5iZS5pbnN0YW5jZW9mKEFycmF5KTtcbiAgICpcbiAgICogQG5hbWUgaW5zdGFuY2VvZlxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yfSBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBhbGlhcyBpbnN0YW5jZU9mXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEluc3RhbmNlT2YgKGNvbnN0cnVjdG9yLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgbmFtZSA9IF8uZ2V0TmFtZShjb25zdHJ1Y3Rvcik7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcpIGluc3RhbmNlb2YgY29uc3RydWN0b3JcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYW4gaW5zdGFuY2Ugb2YgJyArIG5hbWVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGFuIGluc3RhbmNlIG9mICcgKyBuYW1lXG4gICAgKTtcbiAgfTtcblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdpbnN0YW5jZW9mJywgYXNzZXJ0SW5zdGFuY2VPZik7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2luc3RhbmNlT2YnLCBhc3NlcnRJbnN0YW5jZU9mKTtcblxuICAvKipcbiAgICogIyMjIC5wcm9wZXJ0eShuYW1lLCBbdmFsdWVdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBoYXMgYSBwcm9wZXJ0eSBgbmFtZWAsIG9wdGlvbmFsbHkgYXNzZXJ0aW5nIHRoYXRcbiAgICogdGhlIHZhbHVlIG9mIHRoYXQgcHJvcGVydHkgaXMgc3RyaWN0bHkgZXF1YWwgdG8gIGB2YWx1ZWAuXG4gICAqIElmIHRoZSBgZGVlcGAgZmxhZyBpcyBzZXQsIHlvdSBjYW4gdXNlIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gZm9yIGRlZXBcbiAgICogcmVmZXJlbmNlcyBpbnRvIG9iamVjdHMgYW5kIGFycmF5cy5cbiAgICpcbiAgICogICAgIC8vIHNpbXBsZSByZWZlcmVuY2luZ1xuICAgKiAgICAgdmFyIG9iaiA9IHsgZm9vOiAnYmFyJyB9O1xuICAgKiAgICAgZXhwZWN0KG9iaikudG8uaGF2ZS5wcm9wZXJ0eSgnZm9vJyk7XG4gICAqICAgICBleHBlY3Qob2JqKS50by5oYXZlLnByb3BlcnR5KCdmb28nLCAnYmFyJyk7XG4gICAqXG4gICAqICAgICAvLyBkZWVwIHJlZmVyZW5jaW5nXG4gICAqICAgICB2YXIgZGVlcE9iaiA9IHtcbiAgICogICAgICAgICBncmVlbjogeyB0ZWE6ICdtYXRjaGEnIH1cbiAgICogICAgICAgLCB0ZWFzOiBbICdjaGFpJywgJ21hdGNoYScsIHsgdGVhOiAna29uYWNoYScgfSBdXG4gICAqICAgICB9O1xuXG4gICAqICAgICBleHBlY3QoZGVlcE9iaikudG8uaGF2ZS5kZWVwLnByb3BlcnR5KCdncmVlbi50ZWEnLCAnbWF0Y2hhJyk7XG4gICAqICAgICBleHBlY3QoZGVlcE9iaikudG8uaGF2ZS5kZWVwLnByb3BlcnR5KCd0ZWFzWzFdJywgJ21hdGNoYScpO1xuICAgKiAgICAgZXhwZWN0KGRlZXBPYmopLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eSgndGVhc1syXS50ZWEnLCAna29uYWNoYScpO1xuICAgKlxuICAgKiBZb3UgY2FuIGFsc28gdXNlIGFuIGFycmF5IGFzIHRoZSBzdGFydGluZyBwb2ludCBvZiBhIGBkZWVwLnByb3BlcnR5YFxuICAgKiBhc3NlcnRpb24sIG9yIHRyYXZlcnNlIG5lc3RlZCBhcnJheXMuXG4gICAqXG4gICAqICAgICB2YXIgYXJyID0gW1xuICAgKiAgICAgICAgIFsgJ2NoYWknLCAnbWF0Y2hhJywgJ2tvbmFjaGEnIF1cbiAgICogICAgICAgLCBbIHsgdGVhOiAnY2hhaScgfVxuICAgKiAgICAgICAgICwgeyB0ZWE6ICdtYXRjaGEnIH1cbiAgICogICAgICAgICAsIHsgdGVhOiAna29uYWNoYScgfSBdXG4gICAqICAgICBdO1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGFycikudG8uaGF2ZS5kZWVwLnByb3BlcnR5KCdbMF1bMV0nLCAnbWF0Y2hhJyk7XG4gICAqICAgICBleHBlY3QoYXJyKS50by5oYXZlLmRlZXAucHJvcGVydHkoJ1sxXVsyXS50ZWEnLCAna29uYWNoYScpO1xuICAgKlxuICAgKiBGdXJ0aGVybW9yZSwgYHByb3BlcnR5YCBjaGFuZ2VzIHRoZSBzdWJqZWN0IG9mIHRoZSBhc3NlcnRpb25cbiAgICogdG8gYmUgdGhlIHZhbHVlIG9mIHRoYXQgcHJvcGVydHkgZnJvbSB0aGUgb3JpZ2luYWwgb2JqZWN0LiBUaGlzXG4gICAqIHBlcm1pdHMgZm9yIGZ1cnRoZXIgY2hhaW5hYmxlIGFzc2VydGlvbnMgb24gdGhhdCBwcm9wZXJ0eS5cbiAgICpcbiAgICogICAgIGV4cGVjdChvYmopLnRvLmhhdmUucHJvcGVydHkoJ2ZvbycpXG4gICAqICAgICAgIC50aGF0LmlzLmEoJ3N0cmluZycpO1xuICAgKiAgICAgZXhwZWN0KGRlZXBPYmopLnRvLmhhdmUucHJvcGVydHkoJ2dyZWVuJylcbiAgICogICAgICAgLnRoYXQuaXMuYW4oJ29iamVjdCcpXG4gICAqICAgICAgIC50aGF0LmRlZXAuZXF1YWxzKHsgdGVhOiAnbWF0Y2hhJyB9KTtcbiAgICogICAgIGV4cGVjdChkZWVwT2JqKS50by5oYXZlLnByb3BlcnR5KCd0ZWFzJylcbiAgICogICAgICAgLnRoYXQuaXMuYW4oJ2FycmF5JylcbiAgICogICAgICAgLndpdGguZGVlcC5wcm9wZXJ0eSgnWzJdJylcbiAgICogICAgICAgICAudGhhdC5kZWVwLmVxdWFscyh7IHRlYTogJ2tvbmFjaGEnIH0pO1xuICAgKlxuICAgKiBAbmFtZSBwcm9wZXJ0eVxuICAgKiBAYWxpYXMgZGVlcC5wcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZSAob3B0aW9uYWwpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQHJldHVybnMgdmFsdWUgb2YgcHJvcGVydHkgZm9yIGNoYWluaW5nXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ3Byb3BlcnR5JywgZnVuY3Rpb24gKG5hbWUsIHZhbCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG5cbiAgICB2YXIgZGVzY3JpcHRvciA9IGZsYWcodGhpcywgJ2RlZXAnKSA/ICdkZWVwIHByb3BlcnR5ICcgOiAncHJvcGVydHkgJ1xuICAgICAgLCBuZWdhdGUgPSBmbGFnKHRoaXMsICduZWdhdGUnKVxuICAgICAgLCBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCB2YWx1ZSA9IGZsYWcodGhpcywgJ2RlZXAnKVxuICAgICAgICA/IF8uZ2V0UGF0aFZhbHVlKG5hbWUsIG9iailcbiAgICAgICAgOiBvYmpbbmFtZV07XG5cbiAgICBpZiAobmVnYXRlICYmIHVuZGVmaW5lZCAhPT0gdmFsKSB7XG4gICAgICBpZiAodW5kZWZpbmVkID09PSB2YWx1ZSkge1xuICAgICAgICBtc2cgPSAobXNnICE9IG51bGwpID8gbXNnICsgJzogJyA6ICcnO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnICsgXy5pbnNwZWN0KG9iaikgKyAnIGhhcyBubyAnICsgZGVzY3JpcHRvciArIF8uaW5zcGVjdChuYW1lKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIHVuZGVmaW5lZCAhPT0gdmFsdWVcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyBfLmluc3BlY3QobmFtZSlcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSAnICsgZGVzY3JpcHRvciArIF8uaW5zcGVjdChuYW1lKSk7XG4gICAgfVxuXG4gICAgaWYgKHVuZGVmaW5lZCAhPT0gdmFsKSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICB2YWwgPT09IHZhbHVlXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBhICcgKyBkZXNjcmlwdG9yICsgXy5pbnNwZWN0KG5hbWUpICsgJyBvZiAje2V4cH0sIGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyBfLmluc3BlY3QobmFtZSkgKyAnIG9mICN7YWN0fSdcbiAgICAgICAgLCB2YWxcbiAgICAgICAgLCB2YWx1ZVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBmbGFnKHRoaXMsICdvYmplY3QnLCB2YWx1ZSk7XG4gIH0pO1xuXG5cbiAgLyoqXG4gICAqICMjIyAub3duUHJvcGVydHkobmFtZSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaGFzIGFuIG93biBwcm9wZXJ0eSBgbmFtZWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ3Rlc3QnKS50by5oYXZlLm93blByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICpcbiAgICogQG5hbWUgb3duUHJvcGVydHlcbiAgICogQGFsaWFzIGhhdmVPd25Qcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydE93blByb3BlcnR5IChuYW1lLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIG9iai5oYXNPd25Qcm9wZXJ0eShuYW1lKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIG93biBwcm9wZXJ0eSAnICsgXy5pbnNwZWN0KG5hbWUpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIG93biBwcm9wZXJ0eSAnICsgXy5pbnNwZWN0KG5hbWUpXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ293blByb3BlcnR5JywgYXNzZXJ0T3duUHJvcGVydHkpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdoYXZlT3duUHJvcGVydHknLCBhc3NlcnRPd25Qcm9wZXJ0eSk7XG5cbiAgLyoqXG4gICAqICMjIyAubGVuZ3RoKHZhbHVlKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCdzIGBsZW5ndGhgIHByb3BlcnR5IGhhc1xuICAgKiB0aGUgZXhwZWN0ZWQgdmFsdWUuXG4gICAqXG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzXSkudG8uaGF2ZS5sZW5ndGgoMyk7XG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicpLnRvLmhhdmUubGVuZ3RoKDYpO1xuICAgKlxuICAgKiBDYW4gYWxzbyBiZSB1c2VkIGFzIGEgY2hhaW4gcHJlY3Vyc29yIHRvIGEgdmFsdWVcbiAgICogY29tcGFyaXNvbiBmb3IgdGhlIGxlbmd0aCBwcm9wZXJ0eS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGguYWJvdmUoMik7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLmFib3ZlKDIpO1xuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aC5iZWxvdyg0KTtcbiAgICogICAgIGV4cGVjdChbIDEsIDIsIDMgXSkudG8uaGF2ZS5sZW5ndGguYmVsb3coNCk7XG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoLndpdGhpbigyLDQpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5oYXZlLmxlbmd0aC53aXRoaW4oMiw0KTtcbiAgICpcbiAgICogQG5hbWUgbGVuZ3RoXG4gICAqIEBhbGlhcyBsZW5ndGhPZlxuICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0TGVuZ3RoQ2hhaW4gKCkge1xuICAgIGZsYWcodGhpcywgJ2RvTGVuZ3RoJywgdHJ1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBhc3NlcnRMZW5ndGggKG4sIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICB2YXIgbGVuID0gb2JqLmxlbmd0aDtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBsZW4gPT0gblxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgbGVuZ3RoIG9mICN7ZXhwfSBidXQgZ290ICN7YWN0fSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgYSBsZW5ndGggb2YgI3thY3R9J1xuICAgICAgLCBuXG4gICAgICAsIGxlblxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdsZW5ndGgnLCBhc3NlcnRMZW5ndGgsIGFzc2VydExlbmd0aENoYWluKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbGVuZ3RoT2YnLCBhc3NlcnRMZW5ndGgsIGFzc2VydExlbmd0aENoYWluKTtcblxuICAvKipcbiAgICogIyMjIC5tYXRjaChyZWdleHApXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IG1hdGNoZXMgYSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicpLnRvLm1hdGNoKC9eZm9vLyk7XG4gICAqXG4gICAqIEBuYW1lIG1hdGNoXG4gICAqIEBwYXJhbSB7UmVnRXhwfSBSZWd1bGFyRXhwcmVzc2lvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ21hdGNoJywgZnVuY3Rpb24gKHJlLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIHJlLmV4ZWMob2JqKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBtYXRjaCAnICsgcmVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIG1hdGNoICcgKyByZVxuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLnN0cmluZyhzdHJpbmcpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgc3RyaW5nIHRhcmdldCBjb250YWlucyBhbm90aGVyIHN0cmluZy5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vYmFyJykudG8uaGF2ZS5zdHJpbmcoJ2JhcicpO1xuICAgKlxuICAgKiBAbmFtZSBzdHJpbmdcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0cmluZ1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ3N0cmluZycsIGZ1bmN0aW9uIChzdHIsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS5pcy5hKCdzdHJpbmcnKTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB+b2JqLmluZGV4T2Yoc3RyKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBjb250YWluICcgKyBfLmluc3BlY3Qoc3RyKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgY29udGFpbiAnICsgXy5pbnNwZWN0KHN0cilcbiAgICApO1xuICB9KTtcblxuXG4gIC8qKlxuICAgKiAjIyMgLmtleXMoa2V5MSwgW2tleTJdLCBbLi4uXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaGFzIGV4YWN0bHkgdGhlIGdpdmVuIGtleXMsIG9yXG4gICAqIGFzc2VydHMgdGhlIGluY2x1c2lvbiBvZiBzb21lIGtleXMgd2hlbiB1c2luZyB0aGVcbiAgICogYGluY2x1ZGVgIG9yIGBjb250YWluYCBtb2RpZmllcnMuXG4gICAqXG4gICAqICAgICBleHBlY3QoeyBmb286IDEsIGJhcjogMiB9KS50by5oYXZlLmtleXMoWydmb28nLCAnYmFyJ10pO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAxLCBiYXI6IDIsIGJhejogMyB9KS50by5jb250YWluLmtleXMoJ2ZvbycsICdiYXInKTtcbiAgICpcbiAgICogQG5hbWUga2V5c1xuICAgKiBAYWxpYXMga2V5XG4gICAqIEBwYXJhbSB7U3RyaW5nLi4ufEFycmF5fSBrZXlzXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEtleXMgKGtleXMpIHtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgc3RyXG4gICAgICAsIG9rID0gdHJ1ZTtcblxuICAgIGtleXMgPSBrZXlzIGluc3RhbmNlb2YgQXJyYXlcbiAgICAgID8ga2V5c1xuICAgICAgOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXG4gICAgaWYgKCFrZXlzLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdrZXlzIHJlcXVpcmVkJyk7XG5cbiAgICB2YXIgYWN0dWFsID0gT2JqZWN0LmtleXMob2JqKVxuICAgICAgLCBsZW4gPSBrZXlzLmxlbmd0aDtcblxuICAgIC8vIEluY2x1c2lvblxuICAgIG9rID0ga2V5cy5ldmVyeShmdW5jdGlvbihrZXkpe1xuICAgICAgcmV0dXJuIH5hY3R1YWwuaW5kZXhPZihrZXkpO1xuICAgIH0pO1xuXG4gICAgLy8gU3RyaWN0XG4gICAgaWYgKCFmbGFnKHRoaXMsICduZWdhdGUnKSAmJiAhZmxhZyh0aGlzLCAnY29udGFpbnMnKSkge1xuICAgICAgb2sgPSBvayAmJiBrZXlzLmxlbmd0aCA9PSBhY3R1YWwubGVuZ3RoO1xuICAgIH1cblxuICAgIC8vIEtleSBzdHJpbmdcbiAgICBpZiAobGVuID4gMSkge1xuICAgICAga2V5cyA9IGtleXMubWFwKGZ1bmN0aW9uKGtleSl7XG4gICAgICAgIHJldHVybiBfLmluc3BlY3Qoa2V5KTtcbiAgICAgIH0pO1xuICAgICAgdmFyIGxhc3QgPSBrZXlzLnBvcCgpO1xuICAgICAgc3RyID0ga2V5cy5qb2luKCcsICcpICsgJywgYW5kICcgKyBsYXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBfLmluc3BlY3Qoa2V5c1swXSk7XG4gICAgfVxuXG4gICAgLy8gRm9ybVxuICAgIHN0ciA9IChsZW4gPiAxID8gJ2tleXMgJyA6ICdrZXkgJykgKyBzdHI7XG5cbiAgICAvLyBIYXZlIC8gaW5jbHVkZVxuICAgIHN0ciA9IChmbGFnKHRoaXMsICdjb250YWlucycpID8gJ2NvbnRhaW4gJyA6ICdoYXZlICcpICsgc3RyO1xuXG4gICAgLy8gQXNzZXJ0aW9uXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIG9rXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvICcgKyBzdHJcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90ICcgKyBzdHJcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgna2V5cycsIGFzc2VydEtleXMpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdrZXknLCBhc3NlcnRLZXlzKTtcblxuICAvKipcbiAgICogIyMjIC50aHJvdyhjb25zdHJ1Y3RvcilcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSBmdW5jdGlvbiB0YXJnZXQgd2lsbCB0aHJvdyBhIHNwZWNpZmljIGVycm9yLCBvciBzcGVjaWZpYyB0eXBlIG9mIGVycm9yXG4gICAqIChhcyBkZXRlcm1pbmVkIHVzaW5nIGBpbnN0YW5jZW9mYCksIG9wdGlvbmFsbHkgd2l0aCBhIFJlZ0V4cCBvciBzdHJpbmcgaW5jbHVzaW9uIHRlc3RcbiAgICogZm9yIHRoZSBlcnJvcidzIG1lc3NhZ2UuXG4gICAqXG4gICAqICAgICB2YXIgZXJyID0gbmV3IFJlZmVyZW5jZUVycm9yKCdUaGlzIGlzIGEgYmFkIGZ1bmN0aW9uLicpO1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24gKCkgeyB0aHJvdyBlcnI7IH1cbiAgICogICAgIGV4cGVjdChmbikudG8udGhyb3coUmVmZXJlbmNlRXJyb3IpO1xuICAgKiAgICAgZXhwZWN0KGZuKS50by50aHJvdyhFcnJvcik7XG4gICAqICAgICBleHBlY3QoZm4pLnRvLnRocm93KC9iYWQgZnVuY3Rpb24vKTtcbiAgICogICAgIGV4cGVjdChmbikudG8ubm90LnRocm93KCdnb29kIGZ1bmN0aW9uJyk7XG4gICAqICAgICBleHBlY3QoZm4pLnRvLnRocm93KFJlZmVyZW5jZUVycm9yLCAvYmFkIGZ1bmN0aW9uLyk7XG4gICAqICAgICBleHBlY3QoZm4pLnRvLnRocm93KGVycik7XG4gICAqICAgICBleHBlY3QoZm4pLnRvLm5vdC50aHJvdyhuZXcgUmFuZ2VFcnJvcignT3V0IG9mIHJhbmdlLicpKTtcbiAgICpcbiAgICogUGxlYXNlIG5vdGUgdGhhdCB3aGVuIGEgdGhyb3cgZXhwZWN0YXRpb24gaXMgbmVnYXRlZCwgaXQgd2lsbCBjaGVjayBlYWNoXG4gICAqIHBhcmFtZXRlciBpbmRlcGVuZGVudGx5LCBzdGFydGluZyB3aXRoIGVycm9yIGNvbnN0cnVjdG9yIHR5cGUuIFRoZSBhcHByb3ByaWF0ZSB3YXlcbiAgICogdG8gY2hlY2sgZm9yIHRoZSBleGlzdGVuY2Ugb2YgYSB0eXBlIG9mIGVycm9yIGJ1dCBmb3IgYSBtZXNzYWdlIHRoYXQgZG9lcyBub3QgbWF0Y2hcbiAgICogaXMgdG8gdXNlIGBhbmRgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZuKS50by50aHJvdyhSZWZlcmVuY2VFcnJvcilcbiAgICogICAgICAgIC5hbmQubm90LnRocm93KC9nb29kIGZ1bmN0aW9uLyk7XG4gICAqXG4gICAqIEBuYW1lIHRocm93XG4gICAqIEBhbGlhcyB0aHJvd3NcbiAgICogQGFsaWFzIFRocm93XG4gICAqIEBwYXJhbSB7RXJyb3JDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBleHBlY3RlZCBlcnJvciBtZXNzYWdlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9FcnJvciNFcnJvcl90eXBlc1xuICAgKiBAcmV0dXJucyBlcnJvciBmb3IgY2hhaW5pbmcgKG51bGwgaWYgbm8gZXJyb3IpXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydFRocm93cyAoY29uc3RydWN0b3IsIGVyck1zZywgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLmlzLmEoJ2Z1bmN0aW9uJyk7XG5cbiAgICB2YXIgdGhyb3duID0gZmFsc2VcbiAgICAgICwgZGVzaXJlZEVycm9yID0gbnVsbFxuICAgICAgLCBuYW1lID0gbnVsbFxuICAgICAgLCB0aHJvd25FcnJvciA9IG51bGw7XG5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZXJyTXNnID0gbnVsbDtcbiAgICAgIGNvbnN0cnVjdG9yID0gbnVsbDtcbiAgICB9IGVsc2UgaWYgKGNvbnN0cnVjdG9yICYmIChjb25zdHJ1Y3RvciBpbnN0YW5jZW9mIFJlZ0V4cCB8fCAnc3RyaW5nJyA9PT0gdHlwZW9mIGNvbnN0cnVjdG9yKSkge1xuICAgICAgZXJyTXNnID0gY29uc3RydWN0b3I7XG4gICAgICBjb25zdHJ1Y3RvciA9IG51bGw7XG4gICAgfSBlbHNlIGlmIChjb25zdHJ1Y3RvciAmJiBjb25zdHJ1Y3RvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBkZXNpcmVkRXJyb3IgPSBjb25zdHJ1Y3RvcjtcbiAgICAgIGNvbnN0cnVjdG9yID0gbnVsbDtcbiAgICAgIGVyck1zZyA9IG51bGw7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgY29uc3RydWN0b3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG5hbWUgPSBjb25zdHJ1Y3Rvci5wcm90b3R5cGUubmFtZSB8fCBjb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgaWYgKG5hbWUgPT09ICdFcnJvcicgJiYgY29uc3RydWN0b3IgIT09IEVycm9yKSB7XG4gICAgICAgIG5hbWUgPSAobmV3IGNvbnN0cnVjdG9yKCkpLm5hbWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0cnVjdG9yID0gbnVsbDtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgb2JqKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBmaXJzdCwgY2hlY2sgZGVzaXJlZCBlcnJvclxuICAgICAgaWYgKGRlc2lyZWRFcnJvcikge1xuICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgIGVyciA9PT0gZGVzaXJlZEVycm9yXG4gICAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byB0aHJvdyAje2V4cH0gYnV0ICN7YWN0fSB3YXMgdGhyb3duJ1xuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IHRocm93ICN7ZXhwfSdcbiAgICAgICAgICAsIChkZXNpcmVkRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGRlc2lyZWRFcnJvci50b1N0cmluZygpIDogZGVzaXJlZEVycm9yKVxuICAgICAgICAgICwgKGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLnRvU3RyaW5nKCkgOiBlcnIpXG4gICAgICAgICk7XG5cbiAgICAgICAgZmxhZyh0aGlzLCAnb2JqZWN0JywgZXJyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIG5leHQsIGNoZWNrIGNvbnN0cnVjdG9yXG4gICAgICBpZiAoY29uc3RydWN0b3IpIHtcbiAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICBlcnIgaW5zdGFuY2VvZiBjb25zdHJ1Y3RvclxuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgI3tleHB9IGJ1dCAje2FjdH0gd2FzIHRocm93bidcbiAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCB0aHJvdyAje2V4cH0gYnV0ICN7YWN0fSB3YXMgdGhyb3duJ1xuICAgICAgICAgICwgbmFtZVxuICAgICAgICAgICwgKGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLnRvU3RyaW5nKCkgOiBlcnIpXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKCFlcnJNc2cpIHtcbiAgICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBlcnIpO1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIG5leHQsIGNoZWNrIG1lc3NhZ2VcbiAgICAgIHZhciBtZXNzYWdlID0gJ29iamVjdCcgPT09IF8udHlwZShlcnIpICYmIFwibWVzc2FnZVwiIGluIGVyclxuICAgICAgICA/IGVyci5tZXNzYWdlXG4gICAgICAgIDogJycgKyBlcnI7XG5cbiAgICAgIGlmICgobWVzc2FnZSAhPSBudWxsKSAmJiBlcnJNc2cgJiYgZXJyTXNnIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgZXJyTXNnLmV4ZWMobWVzc2FnZSlcbiAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIHRocm93IGVycm9yIG1hdGNoaW5nICN7ZXhwfSBidXQgZ290ICN7YWN0fSdcbiAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIHRocm93IGVycm9yIG5vdCBtYXRjaGluZyAje2V4cH0nXG4gICAgICAgICAgLCBlcnJNc2dcbiAgICAgICAgICAsIG1lc3NhZ2VcbiAgICAgICAgKTtcblxuICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBlcnIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH0gZWxzZSBpZiAoKG1lc3NhZ2UgIT0gbnVsbCkgJiYgZXJyTXNnICYmICdzdHJpbmcnID09PSB0eXBlb2YgZXJyTXNnKSB7XG4gICAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgICAgfm1lc3NhZ2UuaW5kZXhPZihlcnJNc2cpXG4gICAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byB0aHJvdyBlcnJvciBpbmNsdWRpbmcgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgZXJyb3Igbm90IGluY2x1ZGluZyAje2FjdH0nXG4gICAgICAgICAgLCBlcnJNc2dcbiAgICAgICAgICAsIG1lc3NhZ2VcbiAgICAgICAgKTtcblxuICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBlcnIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93biA9IHRydWU7XG4gICAgICAgIHRocm93bkVycm9yID0gZXJyO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBhY3R1YWxseUdvdCA9ICcnXG4gICAgICAsIGV4cGVjdGVkVGhyb3duID0gbmFtZSAhPT0gbnVsbFxuICAgICAgICA/IG5hbWVcbiAgICAgICAgOiBkZXNpcmVkRXJyb3JcbiAgICAgICAgICA/ICcje2V4cH0nIC8vXy5pbnNwZWN0KGRlc2lyZWRFcnJvcilcbiAgICAgICAgICA6ICdhbiBlcnJvcic7XG5cbiAgICBpZiAodGhyb3duKSB7XG4gICAgICBhY3R1YWxseUdvdCA9ICcgYnV0ICN7YWN0fSB3YXMgdGhyb3duJ1xuICAgIH1cblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB0aHJvd24gPT09IHRydWVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgJyArIGV4cGVjdGVkVGhyb3duICsgYWN0dWFsbHlHb3RcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IHRocm93ICcgKyBleHBlY3RlZFRocm93biArIGFjdHVhbGx5R290XG4gICAgICAsIChkZXNpcmVkRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGRlc2lyZWRFcnJvci50b1N0cmluZygpIDogZGVzaXJlZEVycm9yKVxuICAgICAgLCAodGhyb3duRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IHRocm93bkVycm9yLnRvU3RyaW5nKCkgOiB0aHJvd25FcnJvcilcbiAgICApO1xuXG4gICAgZmxhZyh0aGlzLCAnb2JqZWN0JywgdGhyb3duRXJyb3IpO1xuICB9O1xuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ3Rocm93JywgYXNzZXJ0VGhyb3dzKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgndGhyb3dzJywgYXNzZXJ0VGhyb3dzKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnVGhyb3cnLCBhc3NlcnRUaHJvd3MpO1xuXG4gIC8qKlxuICAgKiAjIyMgLnJlc3BvbmRUbyhtZXRob2QpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgb2JqZWN0IG9yIGNsYXNzIHRhcmdldCB3aWxsIHJlc3BvbmQgdG8gYSBtZXRob2QuXG4gICAqXG4gICAqICAgICBLbGFzcy5wcm90b3R5cGUuYmFyID0gZnVuY3Rpb24oKXt9O1xuICAgKiAgICAgZXhwZWN0KEtsYXNzKS50by5yZXNwb25kVG8oJ2JhcicpO1xuICAgKiAgICAgZXhwZWN0KG9iaikudG8ucmVzcG9uZFRvKCdiYXInKTtcbiAgICpcbiAgICogVG8gY2hlY2sgaWYgYSBjb25zdHJ1Y3RvciB3aWxsIHJlc3BvbmQgdG8gYSBzdGF0aWMgZnVuY3Rpb24sXG4gICAqIHNldCB0aGUgYGl0c2VsZmAgZmxhZy5cbiAgICpcbiAgICogICAgIEtsYXNzLmJheiA9IGZ1bmN0aW9uKCl7fTtcbiAgICogICAgIGV4cGVjdChLbGFzcykuaXRzZWxmLnRvLnJlc3BvbmRUbygnYmF6Jyk7XG4gICAqXG4gICAqIEBuYW1lIHJlc3BvbmRUb1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgncmVzcG9uZFRvJywgZnVuY3Rpb24gKG1ldGhvZCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGl0c2VsZiA9IGZsYWcodGhpcywgJ2l0c2VsZicpXG4gICAgICAsIGNvbnRleHQgPSAoJ2Z1bmN0aW9uJyA9PT0gXy50eXBlKG9iaikgJiYgIWl0c2VsZilcbiAgICAgICAgPyBvYmoucHJvdG90eXBlW21ldGhvZF1cbiAgICAgICAgOiBvYmpbbWV0aG9kXTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAnZnVuY3Rpb24nID09PSB0eXBlb2YgY29udGV4dFxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byByZXNwb25kIHRvICcgKyBfLmluc3BlY3QobWV0aG9kKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgcmVzcG9uZCB0byAnICsgXy5pbnNwZWN0KG1ldGhvZClcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5pdHNlbGZcbiAgICpcbiAgICogU2V0cyB0aGUgYGl0c2VsZmAgZmxhZywgbGF0ZXIgdXNlZCBieSB0aGUgYHJlc3BvbmRUb2AgYXNzZXJ0aW9uLlxuICAgKlxuICAgKiAgICAgZnVuY3Rpb24gRm9vKCkge31cbiAgICogICAgIEZvby5iYXIgPSBmdW5jdGlvbigpIHt9XG4gICAqICAgICBGb28ucHJvdG90eXBlLmJheiA9IGZ1bmN0aW9uKCkge31cbiAgICpcbiAgICogICAgIGV4cGVjdChGb28pLml0c2VsZi50by5yZXNwb25kVG8oJ2JhcicpO1xuICAgKiAgICAgZXhwZWN0KEZvbykuaXRzZWxmLm5vdC50by5yZXNwb25kVG8oJ2JheicpO1xuICAgKlxuICAgKiBAbmFtZSBpdHNlbGZcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdpdHNlbGYnLCBmdW5jdGlvbiAoKSB7XG4gICAgZmxhZyh0aGlzLCAnaXRzZWxmJywgdHJ1ZSk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLnNhdGlzZnkobWV0aG9kKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBwYXNzZXMgYSBnaXZlbiB0cnV0aCB0ZXN0LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEpLnRvLnNhdGlzZnkoZnVuY3Rpb24obnVtKSB7IHJldHVybiBudW0gPiAwOyB9KTtcbiAgICpcbiAgICogQG5hbWUgc2F0aXNmeVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtYXRjaGVyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnc2F0aXNmeScsIGZ1bmN0aW9uIChtYXRjaGVyLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIG1hdGNoZXIob2JqKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBzYXRpc2Z5ICcgKyBfLm9iakRpc3BsYXkobWF0Y2hlcilcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IHNhdGlzZnknICsgXy5vYmpEaXNwbGF5KG1hdGNoZXIpXG4gICAgICAsIHRoaXMubmVnYXRlID8gZmFsc2UgOiB0cnVlXG4gICAgICAsIG1hdGNoZXIob2JqKVxuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmNsb3NlVG8oZXhwZWN0ZWQsIGRlbHRhKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCBgZXhwZWN0ZWRgLCB0byB3aXRoaW4gYSArLy0gYGRlbHRhYCByYW5nZS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxLjUpLnRvLmJlLmNsb3NlVG8oMSwgMC41KTtcbiAgICpcbiAgICogQG5hbWUgY2xvc2VUb1xuICAgKiBAcGFyYW0ge051bWJlcn0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbHRhXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnY2xvc2VUbycsIGZ1bmN0aW9uIChleHBlY3RlZCwgZGVsdGEsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgTWF0aC5hYnMob2JqIC0gZXhwZWN0ZWQpIDw9IGRlbHRhXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGNsb3NlIHRvICcgKyBleHBlY3RlZCArICcgKy8tICcgKyBkZWx0YVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgY2xvc2UgdG8gJyArIGV4cGVjdGVkICsgJyArLy0gJyArIGRlbHRhXG4gICAgKTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gaXNTdWJzZXRPZihzdWJzZXQsIHN1cGVyc2V0LCBjbXApIHtcbiAgICByZXR1cm4gc3Vic2V0LmV2ZXJ5KGZ1bmN0aW9uKGVsZW0pIHtcbiAgICAgIGlmICghY21wKSByZXR1cm4gc3VwZXJzZXQuaW5kZXhPZihlbGVtKSAhPT0gLTE7XG5cbiAgICAgIHJldHVybiBzdXBlcnNldC5zb21lKGZ1bmN0aW9uKGVsZW0yKSB7XG4gICAgICAgIHJldHVybiBjbXAoZWxlbSwgZWxlbTIpO1xuICAgICAgfSk7XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyMgLm1lbWJlcnMoc2V0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBhIHN1cGVyc2V0IG9mIGBzZXRgLFxuICAgKiBvciB0aGF0IHRoZSB0YXJnZXQgYW5kIGBzZXRgIGhhdmUgdGhlIHNhbWUgc3RyaWN0bHktZXF1YWwgKD09PSkgbWVtYmVycy5cbiAgICogQWx0ZXJuYXRlbHksIGlmIHRoZSBgZGVlcGAgZmxhZyBpcyBzZXQsIHNldCBtZW1iZXJzIGFyZSBjb21wYXJlZCBmb3IgZGVlcFxuICAgKiBlcXVhbGl0eS5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLmluY2x1ZGUubWVtYmVycyhbMywgMl0pO1xuICAgKiAgICAgZXhwZWN0KFsxLCAyLCAzXSkudG8ubm90LmluY2x1ZGUubWVtYmVycyhbMywgMiwgOF0pO1xuICAgKlxuICAgKiAgICAgZXhwZWN0KFs0LCAyXSkudG8uaGF2ZS5tZW1iZXJzKFsyLCA0XSk7XG4gICAqICAgICBleHBlY3QoWzUsIDJdKS50by5ub3QuaGF2ZS5tZW1iZXJzKFs1LCAyLCAxXSk7XG4gICAqXG4gICAqICAgICBleHBlY3QoW3sgaWQ6IDEgfV0pLnRvLmRlZXAuaW5jbHVkZS5tZW1iZXJzKFt7IGlkOiAxIH1dKTtcbiAgICpcbiAgICogQG5hbWUgbWVtYmVyc1xuICAgKiBAcGFyYW0ge0FycmF5fSBzZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdtZW1iZXJzJywgZnVuY3Rpb24gKHN1YnNldCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuXG4gICAgbmV3IEFzc2VydGlvbihvYmopLnRvLmJlLmFuKCdhcnJheScpO1xuICAgIG5ldyBBc3NlcnRpb24oc3Vic2V0KS50by5iZS5hbignYXJyYXknKTtcblxuICAgIHZhciBjbXAgPSBmbGFnKHRoaXMsICdkZWVwJykgPyBfLmVxbCA6IHVuZGVmaW5lZDtcblxuICAgIGlmIChmbGFnKHRoaXMsICdjb250YWlucycpKSB7XG4gICAgICByZXR1cm4gdGhpcy5hc3NlcnQoXG4gICAgICAgICAgaXNTdWJzZXRPZihzdWJzZXQsIG9iaiwgY21wKVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGEgc3VwZXJzZXQgb2YgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBiZSBhIHN1cGVyc2V0IG9mICN7YWN0fSdcbiAgICAgICAgLCBvYmpcbiAgICAgICAgLCBzdWJzZXRcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIGlzU3Vic2V0T2Yob2JqLCBzdWJzZXQsIGNtcCkgJiYgaXNTdWJzZXRPZihzdWJzZXQsIG9iaiwgY21wKVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgdGhlIHNhbWUgbWVtYmVycyBhcyAje2FjdH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgdGhlIHNhbWUgbWVtYmVycyBhcyAje2FjdH0nXG4gICAgICAgICwgb2JqXG4gICAgICAgICwgc3Vic2V0XG4gICAgKTtcbiAgfSk7XG59O1xuIiwiLyohXG4gKiBjaGFpXG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCB1dGlsKSB7XG5cbiAgLyohXG4gICAqIENoYWkgZGVwZW5kZW5jaWVzLlxuICAgKi9cblxuICB2YXIgQXNzZXJ0aW9uID0gY2hhaS5Bc3NlcnRpb25cbiAgICAsIGZsYWcgPSB1dGlsLmZsYWc7XG5cbiAgLyohXG4gICAqIE1vZHVsZSBleHBvcnQuXG4gICAqL1xuXG4gIC8qKlxuICAgKiAjIyMgYXNzZXJ0KGV4cHJlc3Npb24sIG1lc3NhZ2UpXG4gICAqXG4gICAqIFdyaXRlIHlvdXIgb3duIHRlc3QgZXhwcmVzc2lvbnMuXG4gICAqXG4gICAqICAgICBhc3NlcnQoJ2ZvbycgIT09ICdiYXInLCAnZm9vIGlzIG5vdCBiYXInKTtcbiAgICogICAgIGFzc2VydChBcnJheS5pc0FycmF5KFtdKSwgJ2VtcHR5IGFycmF5cyBhcmUgYXJyYXlzJyk7XG4gICAqXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cHJlc3Npb24gdG8gdGVzdCBmb3IgdHJ1dGhpbmVzc1xuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSB0byBkaXNwbGF5IG9uIGVycm9yXG4gICAqIEBuYW1lIGFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICB2YXIgYXNzZXJ0ID0gY2hhaS5hc3NlcnQgPSBmdW5jdGlvbiAoZXhwcmVzcywgZXJybXNnKSB7XG4gICAgdmFyIHRlc3QgPSBuZXcgQXNzZXJ0aW9uKG51bGwsIG51bGwsIGNoYWkuYXNzZXJ0KTtcbiAgICB0ZXN0LmFzc2VydChcbiAgICAgICAgZXhwcmVzc1xuICAgICAgLCBlcnJtc2dcbiAgICAgICwgJ1sgbmVnYXRpb24gbWVzc2FnZSB1bmF2YWlsYWJsZSBdJ1xuICAgICk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0sIFtvcGVyYXRvcl0pXG4gICAqXG4gICAqIFRocm93IGEgZmFpbHVyZS4gTm9kZS5qcyBgYXNzZXJ0YCBtb2R1bGUtY29tcGF0aWJsZS5cbiAgICpcbiAgICogQG5hbWUgZmFpbFxuICAgKiBAcGFyYW0ge01peGVkfSBhY3R1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmd9IG9wZXJhdG9yXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5mYWlsID0gZnVuY3Rpb24gKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wZXJhdG9yKSB7XG4gICAgbWVzc2FnZSA9IG1lc3NhZ2UgfHwgJ2Fzc2VydC5mYWlsKCknO1xuICAgIHRocm93IG5ldyBjaGFpLkFzc2VydGlvbkVycm9yKG1lc3NhZ2UsIHtcbiAgICAgICAgYWN0dWFsOiBhY3R1YWxcbiAgICAgICwgZXhwZWN0ZWQ6IGV4cGVjdGVkXG4gICAgICAsIG9wZXJhdG9yOiBvcGVyYXRvclxuICAgIH0sIGFzc2VydC5mYWlsKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5vayhvYmplY3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIHRydXRoeS5cbiAgICpcbiAgICogICAgIGFzc2VydC5vaygnZXZlcnl0aGluZycsICdldmVyeXRoaW5nIGlzIG9rJyk7XG4gICAqICAgICBhc3NlcnQub2soZmFsc2UsICd0aGlzIHdpbGwgZmFpbCcpO1xuICAgKlxuICAgKiBAbmFtZSBva1xuICAgKiBAcGFyYW0ge01peGVkfSBvYmplY3QgdG8gdGVzdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQub2sgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS5pcy5vaztcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3RPayhvYmplY3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIGZhbHN5LlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdE9rKCdldmVyeXRoaW5nJywgJ3RoaXMgd2lsbCBmYWlsJyk7XG4gICAqICAgICBhc3NlcnQubm90T2soZmFsc2UsICd0aGlzIHdpbGwgcGFzcycpO1xuICAgKlxuICAgKiBAbmFtZSBub3RPa1xuICAgKiBAcGFyYW0ge01peGVkfSBvYmplY3QgdG8gdGVzdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90T2sgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS5pcy5ub3Qub2s7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIG5vbi1zdHJpY3QgZXF1YWxpdHkgKGA9PWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmVxdWFsKDMsICczJywgJz09IGNvZXJjZXMgdmFsdWVzIHRvIHN0cmluZ3MnKTtcbiAgICpcbiAgICogQG5hbWUgZXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgbXNnKSB7XG4gICAgdmFyIHRlc3QgPSBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnLCBhc3NlcnQuZXF1YWwpO1xuXG4gICAgdGVzdC5hc3NlcnQoXG4gICAgICAgIGV4cCA9PSBmbGFnKHRlc3QsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBlcXVhbCAje2V4cH0nXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBlcXVhbCAje2FjdH0nXG4gICAgICAsIGV4cFxuICAgICAgLCBhY3RcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBub24tc3RyaWN0IGluZXF1YWxpdHkgKGAhPWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdEVxdWFsKDMsIDQsICd0aGVzZSBudW1iZXJzIGFyZSBub3QgZXF1YWwnKTtcbiAgICpcbiAgICogQG5hbWUgbm90RXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RFcXVhbCA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgbXNnKSB7XG4gICAgdmFyIHRlc3QgPSBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnLCBhc3NlcnQubm90RXF1YWwpO1xuXG4gICAgdGVzdC5hc3NlcnQoXG4gICAgICAgIGV4cCAhPSBmbGFnKHRlc3QsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZXF1YWwgI3tleHB9J1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBlcXVhbCAje2FjdH0nXG4gICAgICAsIGV4cFxuICAgICAgLCBhY3RcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLnN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBzdHJpY3QgZXF1YWxpdHkgKGA9PT1gKSBvZiBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cnVlLCB0cnVlLCAndGhlc2UgYm9vbGVhbnMgYXJlIHN0cmljdGx5IGVxdWFsJyk7XG4gICAqXG4gICAqIEBuYW1lIHN0cmljdEVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuc3RyaWN0RXF1YWwgPSBmdW5jdGlvbiAoYWN0LCBleHAsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2cpLnRvLmVxdWFsKGV4cCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHN0cmljdCBpbmVxdWFsaXR5IChgIT09YCkgb2YgYGFjdHVhbGAgYW5kIGBleHBlY3RlZGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90U3RyaWN0RXF1YWwoMywgJzMnLCAnbm8gY29lcmNpb24gZm9yIHN0cmljdCBlcXVhbGl0eScpO1xuICAgKlxuICAgKiBAbmFtZSBub3RTdHJpY3RFcXVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBhY3R1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsID0gZnVuY3Rpb24gKGFjdCwgZXhwLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnKS50by5ub3QuZXF1YWwoZXhwKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYGFjdHVhbGAgaXMgZGVlcGx5IGVxdWFsIHRvIGBleHBlY3RlZGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZGVlcEVxdWFsKHsgdGVhOiAnZ3JlZW4nIH0sIHsgdGVhOiAnZ3JlZW4nIH0pO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwRXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiAoYWN0LCBleHAsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2cpLnRvLmVxbChleHApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydCB0aGF0IGBhY3R1YWxgIGlzIG5vdCBkZWVwbHkgZXF1YWwgdG8gYGV4cGVjdGVkYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3REZWVwRXF1YWwoeyB0ZWE6ICdncmVlbicgfSwgeyB0ZWE6ICdqYXNtaW5lJyB9KTtcbiAgICpcbiAgICogQG5hbWUgbm90RGVlcEVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RGVlcEVxdWFsID0gZnVuY3Rpb24gKGFjdCwgZXhwLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnKS50by5ub3QuZXFsKGV4cCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNUcnVlKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIHRydWUuXG4gICAqXG4gICAqICAgICB2YXIgdGVhU2VydmVkID0gdHJ1ZTtcbiAgICogICAgIGFzc2VydC5pc1RydWUodGVhU2VydmVkLCAndGhlIHRlYSBoYXMgYmVlbiBzZXJ2ZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNUcnVlXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc1RydWUgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS5pc1sndHJ1ZSddO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzRmFsc2UodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgZmFsc2UuXG4gICAqXG4gICAqICAgICB2YXIgdGVhU2VydmVkID0gZmFsc2U7XG4gICAqICAgICBhc3NlcnQuaXNGYWxzZSh0ZWFTZXJ2ZWQsICdubyB0ZWEgeWV0PyBobW0uLi4nKTtcbiAgICpcbiAgICogQG5hbWUgaXNGYWxzZVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNGYWxzZSA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLmlzWydmYWxzZSddO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTnVsbCh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBudWxsLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTnVsbChlcnIsICd0aGVyZSB3YXMgbm8gZXJyb3InKTtcbiAgICpcbiAgICogQG5hbWUgaXNOdWxsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc051bGwgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5lcXVhbChudWxsKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdE51bGwodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgbm90IG51bGwuXG4gICAqXG4gICAqICAgICB2YXIgdGVhID0gJ3Rhc3R5IGNoYWknO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90TnVsbCh0ZWEsICdncmVhdCwgdGltZSBmb3IgdGVhIScpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdE51bGxcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90TnVsbCA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLm5vdC5lcXVhbChudWxsKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc1VuZGVmaW5lZCh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYC5cbiAgICpcbiAgICogICAgIHZhciB0ZWE7XG4gICAqICAgICBhc3NlcnQuaXNVbmRlZmluZWQodGVhLCAnbm8gdGVhIGRlZmluZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNVbmRlZmluZWRcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzVW5kZWZpbmVkID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uZXF1YWwodW5kZWZpbmVkKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0RlZmluZWQodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgbm90IGB1bmRlZmluZWRgLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYSA9ICdjdXAgb2YgY2hhaSc7XG4gICAqICAgICBhc3NlcnQuaXNEZWZpbmVkKHRlYSwgJ3RlYSBoYXMgYmVlbiBkZWZpbmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzRGVmaW5lZFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNEZWZpbmVkID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmVxdWFsKHVuZGVmaW5lZCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNGdW5jdGlvbih2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLlxuICAgKlxuICAgKiAgICAgZnVuY3Rpb24gc2VydmVUZWEoKSB7IHJldHVybiAnY3VwIG9mIHRlYSc7IH07XG4gICAqICAgICBhc3NlcnQuaXNGdW5jdGlvbihzZXJ2ZVRlYSwgJ2dyZWF0LCB3ZSBjYW4gaGF2ZSB0ZWEgbm93Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzRnVuY3Rpb25cbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzRnVuY3Rpb24gPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5iZS5hKCdmdW5jdGlvbicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90RnVuY3Rpb24odmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgX25vdF8gYSBmdW5jdGlvbi5cbiAgICpcbiAgICogICAgIHZhciBzZXJ2ZVRlYSA9IFsgJ2hlYXQnLCAncG91cicsICdzaXAnIF07XG4gICAqICAgICBhc3NlcnQuaXNOb3RGdW5jdGlvbihzZXJ2ZVRlYSwgJ2dyZWF0LCB3ZSBoYXZlIGxpc3RlZCB0aGUgc3RlcHMnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RGdW5jdGlvblxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RGdW5jdGlvbiA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLm5vdC5iZS5hKCdmdW5jdGlvbicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzT2JqZWN0KHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGFuIG9iamVjdCAoYXMgcmV2ZWFsZWQgYnlcbiAgICogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdgKS5cbiAgICpcbiAgICogICAgIHZhciBzZWxlY3Rpb24gPSB7IG5hbWU6ICdDaGFpJywgc2VydmU6ICd3aXRoIHNwaWNlcycgfTtcbiAgICogICAgIGFzc2VydC5pc09iamVjdChzZWxlY3Rpb24sICd0ZWEgc2VsZWN0aW9uIGlzIGFuIG9iamVjdCcpO1xuICAgKlxuICAgKiBAbmFtZSBpc09iamVjdFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNPYmplY3QgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5iZS5hKCdvYmplY3QnKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdE9iamVjdCh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBfbm90XyBhbiBvYmplY3QuXG4gICAqXG4gICAqICAgICB2YXIgc2VsZWN0aW9uID0gJ2NoYWknXG4gICAqICAgICBhc3NlcnQuaXNOb3RPYmplY3Qoc2VsZWN0aW9uLCAndGVhIHNlbGVjdGlvbiBpcyBub3QgYW4gb2JqZWN0Jyk7XG4gICAqICAgICBhc3NlcnQuaXNOb3RPYmplY3QobnVsbCwgJ251bGwgaXMgbm90IGFuIG9iamVjdCcpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdE9iamVjdFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RPYmplY3QgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuYmUuYSgnb2JqZWN0Jyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNBcnJheSh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhbiBhcnJheS5cbiAgICpcbiAgICogICAgIHZhciBtZW51ID0gWyAnZ3JlZW4nLCAnY2hhaScsICdvb2xvbmcnIF07XG4gICAqICAgICBhc3NlcnQuaXNBcnJheShtZW51LCAnd2hhdCBraW5kIG9mIHRlYSBkbyB3ZSB3YW50PycpO1xuICAgKlxuICAgKiBAbmFtZSBpc0FycmF5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0FycmF5ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uYmUuYW4oJ2FycmF5Jyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RBcnJheSh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBfbm90XyBhbiBhcnJheS5cbiAgICpcbiAgICogICAgIHZhciBtZW51ID0gJ2dyZWVufGNoYWl8b29sb25nJztcbiAgICogICAgIGFzc2VydC5pc05vdEFycmF5KG1lbnUsICd3aGF0IGtpbmQgb2YgdGVhIGRvIHdlIHdhbnQ/Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90QXJyYXlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90QXJyYXkgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuYmUuYW4oJ2FycmF5Jyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNTdHJpbmcodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYSBzdHJpbmcuXG4gICAqXG4gICAqICAgICB2YXIgdGVhT3JkZXIgPSAnY2hhaSc7XG4gICAqICAgICBhc3NlcnQuaXNTdHJpbmcodGVhT3JkZXIsICdvcmRlciBwbGFjZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNTdHJpbmdcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzU3RyaW5nID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uYmUuYSgnc3RyaW5nJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RTdHJpbmcodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgX25vdF8gYSBzdHJpbmcuXG4gICAqXG4gICAqICAgICB2YXIgdGVhT3JkZXIgPSA0O1xuICAgKiAgICAgYXNzZXJ0LmlzTm90U3RyaW5nKHRlYU9yZGVyLCAnb3JkZXIgcGxhY2VkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTm90U3RyaW5nXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdFN0cmluZyA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLm5vdC5iZS5hKCdzdHJpbmcnKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc051bWJlcih2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhIG51bWJlci5cbiAgICpcbiAgICogICAgIHZhciBjdXBzID0gMjtcbiAgICogICAgIGFzc2VydC5pc051bWJlcihjdXBzLCAnaG93IG1hbnkgY3VwcycpO1xuICAgKlxuICAgKiBAbmFtZSBpc051bWJlclxuICAgKiBAcGFyYW0ge051bWJlcn0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTnVtYmVyID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uYmUuYSgnbnVtYmVyJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3ROdW1iZXIodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgX25vdF8gYSBudW1iZXIuXG4gICAqXG4gICAqICAgICB2YXIgY3VwcyA9ICcyIGN1cHMgcGxlYXNlJztcbiAgICogICAgIGFzc2VydC5pc05vdE51bWJlcihjdXBzLCAnaG93IG1hbnkgY3VwcycpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdE51bWJlclxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3ROdW1iZXIgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuYmUuYSgnbnVtYmVyJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNCb29sZWFuKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGEgYm9vbGVhbi5cbiAgICpcbiAgICogICAgIHZhciB0ZWFSZWFkeSA9IHRydWVcbiAgICogICAgICAgLCB0ZWFTZXJ2ZWQgPSBmYWxzZTtcbiAgICpcbiAgICogICAgIGFzc2VydC5pc0Jvb2xlYW4odGVhUmVhZHksICdpcyB0aGUgdGVhIHJlYWR5Jyk7XG4gICAqICAgICBhc3NlcnQuaXNCb29sZWFuKHRlYVNlcnZlZCwgJ2hhcyB0ZWEgYmVlbiBzZXJ2ZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNCb29sZWFuXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc0Jvb2xlYW4gPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5iZS5hKCdib29sZWFuJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RCb29sZWFuKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGEgYm9vbGVhbi5cbiAgICpcbiAgICogICAgIHZhciB0ZWFSZWFkeSA9ICd5ZXAnXG4gICAqICAgICAgICwgdGVhU2VydmVkID0gJ25vcGUnO1xuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90Qm9vbGVhbih0ZWFSZWFkeSwgJ2lzIHRoZSB0ZWEgcmVhZHknKTtcbiAgICogICAgIGFzc2VydC5pc05vdEJvb2xlYW4odGVhU2VydmVkLCAnaGFzIHRlYSBiZWVuIHNlcnZlZCcpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdEJvb2xlYW5cbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90Qm9vbGVhbiA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLm5vdC5iZS5hKCdib29sZWFuJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAudHlwZU9mKHZhbHVlLCBuYW1lLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgJ3MgdHlwZSBpcyBgbmFtZWAsIGFzIGRldGVybWluZWQgYnlcbiAgICogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnR5cGVPZih7IHRlYTogJ2NoYWknIH0sICdvYmplY3QnLCAnd2UgaGF2ZSBhbiBvYmplY3QnKTtcbiAgICogICAgIGFzc2VydC50eXBlT2YoWydjaGFpJywgJ2phc21pbmUnXSwgJ2FycmF5JywgJ3dlIGhhdmUgYW4gYXJyYXknKTtcbiAgICogICAgIGFzc2VydC50eXBlT2YoJ3RlYScsICdzdHJpbmcnLCAnd2UgaGF2ZSBhIHN0cmluZycpO1xuICAgKiAgICAgYXNzZXJ0LnR5cGVPZigvdGVhLywgJ3JlZ2V4cCcsICd3ZSBoYXZlIGEgcmVndWxhciBleHByZXNzaW9uJyk7XG4gICAqICAgICBhc3NlcnQudHlwZU9mKG51bGwsICdudWxsJywgJ3dlIGhhdmUgYSBudWxsJyk7XG4gICAqICAgICBhc3NlcnQudHlwZU9mKHVuZGVmaW5lZCwgJ3VuZGVmaW5lZCcsICd3ZSBoYXZlIGFuIHVuZGVmaW5lZCcpO1xuICAgKlxuICAgKiBAbmFtZSB0eXBlT2ZcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LnR5cGVPZiA9IGZ1bmN0aW9uICh2YWwsIHR5cGUsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmEodHlwZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90VHlwZU9mKHZhbHVlLCBuYW1lLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgJ3MgdHlwZSBpcyBfbm90XyBgbmFtZWAsIGFzIGRldGVybWluZWQgYnlcbiAgICogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdFR5cGVPZigndGVhJywgJ251bWJlcicsICdzdHJpbmdzIGFyZSBub3QgbnVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBub3RUeXBlT2ZcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IHR5cGVvZiBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RUeXBlT2YgPSBmdW5jdGlvbiAodmFsLCB0eXBlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuYmUuYSh0eXBlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pbnN0YW5jZU9mKG9iamVjdCwgY29uc3RydWN0b3IsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYW4gaW5zdGFuY2Ugb2YgYGNvbnN0cnVjdG9yYC5cbiAgICpcbiAgICogICAgIHZhciBUZWEgPSBmdW5jdGlvbiAobmFtZSkgeyB0aGlzLm5hbWUgPSBuYW1lOyB9XG4gICAqICAgICAgICwgY2hhaSA9IG5ldyBUZWEoJ2NoYWknKTtcbiAgICpcbiAgICogICAgIGFzc2VydC5pbnN0YW5jZU9mKGNoYWksIFRlYSwgJ2NoYWkgaXMgYW4gaW5zdGFuY2Ugb2YgdGVhJyk7XG4gICAqXG4gICAqIEBuYW1lIGluc3RhbmNlT2ZcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yfSBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaW5zdGFuY2VPZiA9IGZ1bmN0aW9uICh2YWwsIHR5cGUsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmluc3RhbmNlT2YodHlwZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90SW5zdGFuY2VPZihvYmplY3QsIGNvbnN0cnVjdG9yLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgYHZhbHVlYCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgYGNvbnN0cnVjdG9yYC5cbiAgICpcbiAgICogICAgIHZhciBUZWEgPSBmdW5jdGlvbiAobmFtZSkgeyB0aGlzLm5hbWUgPSBuYW1lOyB9XG4gICAqICAgICAgICwgY2hhaSA9IG5ldyBTdHJpbmcoJ2NoYWknKTtcbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RJbnN0YW5jZU9mKGNoYWksIFRlYSwgJ2NoYWkgaXMgbm90IGFuIGluc3RhbmNlIG9mIHRlYScpO1xuICAgKlxuICAgKiBAbmFtZSBub3RJbnN0YW5jZU9mXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdEluc3RhbmNlT2YgPSBmdW5jdGlvbiAodmFsLCB0eXBlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuYmUuaW5zdGFuY2VPZih0eXBlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlKGhheXN0YWNrLCBuZWVkbGUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBoYXlzdGFja2AgaW5jbHVkZXMgYG5lZWRsZWAuIFdvcmtzXG4gICAqIGZvciBzdHJpbmdzIGFuZCBhcnJheXMuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaW5jbHVkZSgnZm9vYmFyJywgJ2JhcicsICdmb29iYXIgY29udGFpbnMgc3RyaW5nIFwiYmFyXCInKTtcbiAgICogICAgIGFzc2VydC5pbmNsdWRlKFsgMSwgMiwgMyBdLCAzLCAnYXJyYXkgY29udGFpbnMgdmFsdWUnKTtcbiAgICpcbiAgICogQG5hbWUgaW5jbHVkZVxuICAgKiBAcGFyYW0ge0FycmF5fFN0cmluZ30gaGF5c3RhY2tcbiAgICogQHBhcmFtIHtNaXhlZH0gbmVlZGxlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pbmNsdWRlID0gZnVuY3Rpb24gKGV4cCwgaW5jLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnLCBhc3NlcnQuaW5jbHVkZSkuaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEluY2x1ZGUoaGF5c3RhY2ssIG5lZWRsZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYGhheXN0YWNrYCBkb2VzIG5vdCBpbmNsdWRlIGBuZWVkbGVgLiBXb3Jrc1xuICAgKiBmb3Igc3RyaW5ncyBhbmQgYXJyYXlzLlxuICAgKmlcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlKCdmb29iYXInLCAnYmF6JywgJ3N0cmluZyBub3QgaW5jbHVkZSBzdWJzdHJpbmcnKTtcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlKFsgMSwgMiwgMyBdLCA0LCAnYXJyYXkgbm90IGluY2x1ZGUgY29udGFpbiB2YWx1ZScpO1xuICAgKlxuICAgKiBAbmFtZSBub3RJbmNsdWRlXG4gICAqIEBwYXJhbSB7QXJyYXl8U3RyaW5nfSBoYXlzdGFja1xuICAgKiBAcGFyYW0ge01peGVkfSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdEluY2x1ZGUgPSBmdW5jdGlvbiAoZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5ub3RJbmNsdWRlKS5ub3QuaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm1hdGNoKHZhbHVlLCByZWdleHAsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgbWF0Y2hlcyB0aGUgcmVndWxhciBleHByZXNzaW9uIGByZWdleHBgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm1hdGNoKCdmb29iYXInLCAvXmZvby8sICdyZWdleHAgbWF0Y2hlcycpO1xuICAgKlxuICAgKiBAbmFtZSBtYXRjaFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXhwXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5tYXRjaCA9IGZ1bmN0aW9uIChleHAsIHJlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnKS50by5tYXRjaChyZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90TWF0Y2godmFsdWUsIHJlZ2V4cCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBkb2VzIG5vdCBtYXRjaCB0aGUgcmVndWxhciBleHByZXNzaW9uIGByZWdleHBgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdE1hdGNoKCdmb29iYXInLCAvXmZvby8sICdyZWdleHAgZG9lcyBub3QgbWF0Y2gnKTtcbiAgICpcbiAgICogQG5hbWUgbm90TWF0Y2hcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90TWF0Y2ggPSBmdW5jdGlvbiAoZXhwLCByZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZykudG8ubm90Lm1hdGNoKHJlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5wcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnByb3BlcnR5KHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RlYScpO1xuICAgKlxuICAgKiBAbmFtZSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQucHJvcGVydHkgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KHByb3ApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdFByb3BlcnR5KG9iamVjdCwgcHJvcGVydHksIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGRvZXMgX25vdF8gaGF2ZSBhIHByb3BlcnR5IG5hbWVkIGJ5IGBwcm9wZXJ0eWAuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90UHJvcGVydHkoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH19LCAnY29mZmVlJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdFByb3BlcnR5XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLm5vdC5oYXZlLnByb3BlcnR5KHByb3ApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmRlZXBQcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgLCB3aGljaCBjYW4gYmUgYVxuICAgKiBzdHJpbmcgdXNpbmcgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBmb3IgZGVlcCByZWZlcmVuY2UuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZGVlcFByb3BlcnR5KHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RlYS5ncmVlbicpO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwUHJvcGVydHlcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eShwcm9wKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3REZWVwUHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgZG9lcyBfbm90XyBoYXZlIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCwgd2hpY2hcbiAgICogY2FuIGJlIGEgc3RyaW5nIHVzaW5nIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gZm9yIGRlZXAgcmVmZXJlbmNlLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBQcm9wZXJ0eSh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0ZWEub29sb25nJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdERlZXBQcm9wZXJ0eVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RGVlcFByb3BlcnR5ID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmhhdmUuZGVlcC5wcm9wZXJ0eShwcm9wKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5wcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCB3aXRoIHZhbHVlIGdpdmVuXG4gICAqIGJ5IGB2YWx1ZWAuXG4gICAqXG4gICAqICAgICBhc3NlcnQucHJvcGVydHlWYWwoeyB0ZWE6ICdpcyBnb29kJyB9LCAndGVhJywgJ2lzIGdvb2QnKTtcbiAgICpcbiAgICogQG5hbWUgcHJvcGVydHlWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LnByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAucHJvcGVydHlOb3RWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIHByb3BlcnR5IG5hbWVkIGJ5IGBwcm9wZXJ0eWAsIGJ1dCB3aXRoIGEgdmFsdWVcbiAgICogZGlmZmVyZW50IGZyb20gdGhhdCBnaXZlbiBieSBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnByb3BlcnR5Tm90VmFsKHsgdGVhOiAnaXMgZ29vZCcgfSwgJ3RlYScsICdpcyBiYWQnKTtcbiAgICpcbiAgICogQG5hbWUgcHJvcGVydHlOb3RWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LnByb3BlcnR5Tm90VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5ub3QuaGF2ZS5wcm9wZXJ0eShwcm9wLCB2YWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmRlZXBQcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCB3aXRoIHZhbHVlIGdpdmVuXG4gICAqIGJ5IGB2YWx1ZWAuIGBwcm9wZXJ0eWAgY2FuIHVzZSBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIGZvciBkZWVwXG4gICAqIHJlZmVyZW5jZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5kZWVwUHJvcGVydHlWYWwoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH19LCAndGVhLmdyZWVuJywgJ21hdGNoYScpO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwUHJvcGVydHlWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBQcm9wZXJ0eVZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8uaGF2ZS5kZWVwLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZGVlcFByb3BlcnR5Tm90VmFsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgLCBidXQgd2l0aCBhIHZhbHVlXG4gICAqIGRpZmZlcmVudCBmcm9tIHRoYXQgZ2l2ZW4gYnkgYHZhbHVlYC4gYHByb3BlcnR5YCBjYW4gdXNlIGRvdC0gYW5kXG4gICAqIGJyYWNrZXQtbm90YXRpb24gZm9yIGRlZXAgcmVmZXJlbmNlLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmRlZXBQcm9wZXJ0eU5vdFZhbCh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0ZWEuZ3JlZW4nLCAna29uYWNoYScpO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwUHJvcGVydHlOb3RWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBQcm9wZXJ0eU5vdFZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmhhdmUuZGVlcC5wcm9wZXJ0eShwcm9wLCB2YWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmxlbmd0aE9mKG9iamVjdCwgbGVuZ3RoLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBgbGVuZ3RoYCBwcm9wZXJ0eSB3aXRoIHRoZSBleHBlY3RlZCB2YWx1ZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5sZW5ndGhPZihbMSwyLDNdLCAzLCAnYXJyYXkgaGFzIGxlbmd0aCBvZiAzJyk7XG4gICAqICAgICBhc3NlcnQubGVuZ3RoT2YoJ2Zvb2JhcicsIDUsICdzdHJpbmcgaGFzIGxlbmd0aCBvZiA2Jyk7XG4gICAqXG4gICAqIEBuYW1lIGxlbmd0aE9mXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5sZW5ndGhPZiA9IGZ1bmN0aW9uIChleHAsIGxlbiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZykudG8uaGF2ZS5sZW5ndGgobGVuKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC50aHJvd3MoZnVuY3Rpb24sIFtjb25zdHJ1Y3Rvci9zdHJpbmcvcmVnZXhwXSwgW3N0cmluZy9yZWdleHBdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgZnVuY3Rpb25gIHdpbGwgdGhyb3cgYW4gZXJyb3IgdGhhdCBpcyBhbiBpbnN0YW5jZSBvZlxuICAgKiBgY29uc3RydWN0b3JgLCBvciBhbHRlcm5hdGVseSB0aGF0IGl0IHdpbGwgdGhyb3cgYW4gZXJyb3Igd2l0aCBtZXNzYWdlXG4gICAqIG1hdGNoaW5nIGByZWdleHBgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnRocm93KGZuLCAnZnVuY3Rpb24gdGhyb3dzIGEgcmVmZXJlbmNlIGVycm9yJyk7XG4gICAqICAgICBhc3NlcnQudGhyb3coZm4sIC9mdW5jdGlvbiB0aHJvd3MgYSByZWZlcmVuY2UgZXJyb3IvKTtcbiAgICogICAgIGFzc2VydC50aHJvdyhmbiwgUmVmZXJlbmNlRXJyb3IpO1xuICAgKiAgICAgYXNzZXJ0LnRocm93KGZuLCBSZWZlcmVuY2VFcnJvciwgJ2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvcicpO1xuICAgKiAgICAgYXNzZXJ0LnRocm93KGZuLCBSZWZlcmVuY2VFcnJvciwgL2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvci8pO1xuICAgKlxuICAgKiBAbmFtZSB0aHJvd3NcbiAgICogQGFsaWFzIHRocm93XG4gICAqIEBhbGlhcyBUaHJvd1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jdGlvblxuICAgKiBAcGFyYW0ge0Vycm9yQ29uc3RydWN0b3J9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7UmVnRXhwfSByZWdleHBcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9FcnJvciNFcnJvcl90eXBlc1xuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuVGhyb3cgPSBmdW5jdGlvbiAoZm4sIGVycnQsIGVycnMsIG1zZykge1xuICAgIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIGVycnQgfHwgZXJydCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgZXJycyA9IGVycnQ7XG4gICAgICBlcnJ0ID0gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgYXNzZXJ0RXJyID0gbmV3IEFzc2VydGlvbihmbiwgbXNnKS50by5UaHJvdyhlcnJ0LCBlcnJzKTtcbiAgICByZXR1cm4gZmxhZyhhc3NlcnRFcnIsICdvYmplY3QnKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kb2VzTm90VGhyb3coZnVuY3Rpb24sIFtjb25zdHJ1Y3Rvci9yZWdleHBdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgZnVuY3Rpb25gIHdpbGwgX25vdF8gdGhyb3cgYW4gZXJyb3IgdGhhdCBpcyBhbiBpbnN0YW5jZSBvZlxuICAgKiBgY29uc3RydWN0b3JgLCBvciBhbHRlcm5hdGVseSB0aGF0IGl0IHdpbGwgbm90IHRocm93IGFuIGVycm9yIHdpdGggbWVzc2FnZVxuICAgKiBtYXRjaGluZyBgcmVnZXhwYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5kb2VzTm90VGhyb3coZm4sIEVycm9yLCAnZnVuY3Rpb24gZG9lcyBub3QgdGhyb3cnKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdFRocm93XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7RXJyb3JDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Vycm9yI0Vycm9yX3R5cGVzXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kb2VzTm90VGhyb3cgPSBmdW5jdGlvbiAoZm4sIHR5cGUsIG1zZykge1xuICAgIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIHR5cGUpIHtcbiAgICAgIG1zZyA9IHR5cGU7XG4gICAgICB0eXBlID0gbnVsbDtcbiAgICB9XG5cbiAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2cpLnRvLm5vdC5UaHJvdyh0eXBlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5vcGVyYXRvcih2YWwxLCBvcGVyYXRvciwgdmFsMiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBDb21wYXJlcyB0d28gdmFsdWVzIHVzaW5nIGBvcGVyYXRvcmAuXG4gICAqXG4gICAqICAgICBhc3NlcnQub3BlcmF0b3IoMSwgJzwnLCAyLCAnZXZlcnl0aGluZyBpcyBvaycpO1xuICAgKiAgICAgYXNzZXJ0Lm9wZXJhdG9yKDEsICc+JywgMiwgJ3RoaXMgd2lsbCBmYWlsJyk7XG4gICAqXG4gICAqIEBuYW1lIG9wZXJhdG9yXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbDFcbiAgICogQHBhcmFtIHtTdHJpbmd9IG9wZXJhdG9yXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbDJcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm9wZXJhdG9yID0gZnVuY3Rpb24gKHZhbCwgb3BlcmF0b3IsIHZhbDIsIG1zZykge1xuICAgIGlmICghflsnPT0nLCAnPT09JywgJz4nLCAnPj0nLCAnPCcsICc8PScsICchPScsICchPT0nXS5pbmRleE9mKG9wZXJhdG9yKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG9wZXJhdG9yIFwiJyArIG9wZXJhdG9yICsgJ1wiJyk7XG4gICAgfVxuICAgIHZhciB0ZXN0ID0gbmV3IEFzc2VydGlvbihldmFsKHZhbCArIG9wZXJhdG9yICsgdmFsMiksIG1zZyk7XG4gICAgdGVzdC5hc3NlcnQoXG4gICAgICAgIHRydWUgPT09IGZsYWcodGVzdCwgJ29iamVjdCcpXG4gICAgICAsICdleHBlY3RlZCAnICsgdXRpbC5pbnNwZWN0KHZhbCkgKyAnIHRvIGJlICcgKyBvcGVyYXRvciArICcgJyArIHV0aWwuaW5zcGVjdCh2YWwyKVxuICAgICAgLCAnZXhwZWN0ZWQgJyArIHV0aWwuaW5zcGVjdCh2YWwpICsgJyB0byBub3QgYmUgJyArIG9wZXJhdG9yICsgJyAnICsgdXRpbC5pbnNwZWN0KHZhbDIpICk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuY2xvc2VUbyhhY3R1YWwsIGV4cGVjdGVkLCBkZWx0YSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCBgZXhwZWN0ZWRgLCB0byB3aXRoaW4gYSArLy0gYGRlbHRhYCByYW5nZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5jbG9zZVRvKDEuNSwgMSwgMC41LCAnbnVtYmVycyBhcmUgY2xvc2UnKTtcbiAgICpcbiAgICogQG5hbWUgY2xvc2VUb1xuICAgKiBAcGFyYW0ge051bWJlcn0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsdGFcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmNsb3NlVG8gPSBmdW5jdGlvbiAoYWN0LCBleHAsIGRlbHRhLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnKS50by5iZS5jbG9zZVRvKGV4cCwgZGVsdGEpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLnNhbWVNZW1iZXJzKHNldDEsIHNldDIsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzZXQxYCBhbmQgYHNldDJgIGhhdmUgdGhlIHNhbWUgbWVtYmVycy5cbiAgICogT3JkZXIgaXMgbm90IHRha2VuIGludG8gYWNjb3VudC5cbiAgICpcbiAgICogICAgIGFzc2VydC5zYW1lTWVtYmVycyhbIDEsIDIsIDMgXSwgWyAyLCAxLCAzIF0sICdzYW1lIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgc2FtZU1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc3VwZXJzZXRcbiAgICogQHBhcmFtIHtBcnJheX0gc3Vic2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5zYW1lTWVtYmVycyA9IGZ1bmN0aW9uIChzZXQxLCBzZXQyLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHNldDEsIG1zZykudG8uaGF2ZS5zYW1lLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlTWVtYmVycyhzdXBlcnNldCwgc3Vic2V0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc3Vic2V0YCBpcyBpbmNsdWRlZCBpbiBgc3VwZXJzZXRgLlxuICAgKiBPcmRlciBpcyBub3QgdGFrZW4gaW50byBhY2NvdW50LlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmluY2x1ZGVNZW1iZXJzKFsgMSwgMiwgMyBdLCBbIDIsIDEgXSwgJ2luY2x1ZGUgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBpbmNsdWRlTWVtYmVyc1xuICAgKiBAcGFyYW0ge0FycmF5fSBzdXBlcnNldFxuICAgKiBAcGFyYW0ge0FycmF5fSBzdWJzZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmluY2x1ZGVNZW1iZXJzID0gZnVuY3Rpb24gKHN1cGVyc2V0LCBzdWJzZXQsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc3VwZXJzZXQsIG1zZykudG8uaW5jbHVkZS5tZW1iZXJzKHN1YnNldCk7XG4gIH1cblxuICAvKiFcbiAgICogVW5kb2N1bWVudGVkIC8gdW50ZXN0ZWRcbiAgICovXG5cbiAgYXNzZXJ0LmlmRXJyb3IgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuYmUub2s7XG4gIH07XG5cbiAgLyohXG4gICAqIEFsaWFzZXMuXG4gICAqL1xuXG4gIChmdW5jdGlvbiBhbGlhcyhuYW1lLCBhcyl7XG4gICAgYXNzZXJ0W2FzXSA9IGFzc2VydFtuYW1lXTtcbiAgICByZXR1cm4gYWxpYXM7XG4gIH0pXG4gICgnVGhyb3cnLCAndGhyb3cnKVxuICAoJ1Rocm93JywgJ3Rocm93cycpO1xufTtcbiIsIi8qIVxuICogY2hhaVxuICogQ29weXJpZ2h0KGMpIDIwMTEtMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGNoYWksIHV0aWwpIHtcbiAgY2hhaS5leHBlY3QgPSBmdW5jdGlvbiAodmFsLCBtZXNzYWdlKSB7XG4gICAgcmV0dXJuIG5ldyBjaGFpLkFzc2VydGlvbih2YWwsIG1lc3NhZ2UpO1xuICB9O1xufTtcblxuIiwiLyohXG4gKiBjaGFpXG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY2hhaSwgdXRpbCkge1xuICB2YXIgQXNzZXJ0aW9uID0gY2hhaS5Bc3NlcnRpb247XG5cbiAgZnVuY3Rpb24gbG9hZFNob3VsZCAoKSB7XG4gICAgLy8gZXhwbGljaXRseSBkZWZpbmUgdGhpcyBtZXRob2QgYXMgZnVuY3Rpb24gYXMgdG8gaGF2ZSBpdCdzIG5hbWUgdG8gaW5jbHVkZSBhcyBgc3NmaWBcbiAgICBmdW5jdGlvbiBzaG91bGRHZXR0ZXIoKSB7XG4gICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFN0cmluZyB8fCB0aGlzIGluc3RhbmNlb2YgTnVtYmVyKSB7XG4gICAgICAgIHJldHVybiBuZXcgQXNzZXJ0aW9uKHRoaXMuY29uc3RydWN0b3IodGhpcyksIG51bGwsIHNob3VsZEdldHRlcik7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMgaW5zdGFuY2VvZiBCb29sZWFuKSB7XG4gICAgICAgIHJldHVybiBuZXcgQXNzZXJ0aW9uKHRoaXMgPT0gdHJ1ZSwgbnVsbCwgc2hvdWxkR2V0dGVyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgQXNzZXJ0aW9uKHRoaXMsIG51bGwsIHNob3VsZEdldHRlcik7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHNob3VsZFNldHRlcih2YWx1ZSkge1xuICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFpanMvY2hhaS9pc3N1ZXMvODY6IHRoaXMgbWFrZXNcbiAgICAgIC8vIGB3aGF0ZXZlci5zaG91bGQgPSBzb21lVmFsdWVgIGFjdHVhbGx5IHNldCBgc29tZVZhbHVlYCwgd2hpY2ggaXNcbiAgICAgIC8vIGVzcGVjaWFsbHkgdXNlZnVsIGZvciBgZ2xvYmFsLnNob3VsZCA9IHJlcXVpcmUoJ2NoYWknKS5zaG91bGQoKWAuXG4gICAgICAvL1xuICAgICAgLy8gTm90ZSB0aGF0IHdlIGhhdmUgdG8gdXNlIFtbRGVmaW5lUHJvcGVydHldXSBpbnN0ZWFkIG9mIFtbUHV0XV1cbiAgICAgIC8vIHNpbmNlIG90aGVyd2lzZSB3ZSB3b3VsZCB0cmlnZ2VyIHRoaXMgdmVyeSBzZXR0ZXIhXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3Nob3VsZCcsIHtcbiAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gbW9kaWZ5IE9iamVjdC5wcm90b3R5cGUgdG8gaGF2ZSBgc2hvdWxkYFxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QucHJvdG90eXBlLCAnc2hvdWxkJywge1xuICAgICAgc2V0OiBzaG91bGRTZXR0ZXJcbiAgICAgICwgZ2V0OiBzaG91bGRHZXR0ZXJcbiAgICAgICwgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG5cbiAgICB2YXIgc2hvdWxkID0ge307XG5cbiAgICBzaG91bGQuZXF1YWwgPSBmdW5jdGlvbiAodmFsMSwgdmFsMiwgbXNnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKHZhbDEsIG1zZykudG8uZXF1YWwodmFsMik7XG4gICAgfTtcblxuICAgIHNob3VsZC5UaHJvdyA9IGZ1bmN0aW9uIChmbiwgZXJydCwgZXJycywgbXNnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2cpLnRvLlRocm93KGVycnQsIGVycnMpO1xuICAgIH07XG5cbiAgICBzaG91bGQuZXhpc3QgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmV4aXN0O1xuICAgIH1cblxuICAgIC8vIG5lZ2F0aW9uXG4gICAgc2hvdWxkLm5vdCA9IHt9XG5cbiAgICBzaG91bGQubm90LmVxdWFsID0gZnVuY3Rpb24gKHZhbDEsIHZhbDIsIG1zZykge1xuICAgICAgbmV3IEFzc2VydGlvbih2YWwxLCBtc2cpLnRvLm5vdC5lcXVhbCh2YWwyKTtcbiAgICB9O1xuXG4gICAgc2hvdWxkLm5vdC5UaHJvdyA9IGZ1bmN0aW9uIChmbiwgZXJydCwgZXJycywgbXNnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2cpLnRvLm5vdC5UaHJvdyhlcnJ0LCBlcnJzKTtcbiAgICB9O1xuXG4gICAgc2hvdWxkLm5vdC5leGlzdCA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmV4aXN0O1xuICAgIH1cblxuICAgIHNob3VsZFsndGhyb3cnXSA9IHNob3VsZFsnVGhyb3cnXTtcbiAgICBzaG91bGQubm90Wyd0aHJvdyddID0gc2hvdWxkLm5vdFsnVGhyb3cnXTtcblxuICAgIHJldHVybiBzaG91bGQ7XG4gIH07XG5cbiAgY2hhaS5zaG91bGQgPSBsb2FkU2hvdWxkO1xuICBjaGFpLlNob3VsZCA9IGxvYWRTaG91bGQ7XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gYWRkQ2hhaW5pbmdNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qIVxuICogTW9kdWxlIGRlcGVuZGVuY2llc1xuICovXG5cbnZhciB0cmFuc2ZlckZsYWdzID0gcmVxdWlyZSgnLi90cmFuc2ZlckZsYWdzJyk7XG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpO1xuXG4vKiFcbiAqIE1vZHVsZSB2YXJpYWJsZXNcbiAqL1xuXG4vLyBDaGVjayB3aGV0aGVyIGBfX3Byb3RvX19gIGlzIHN1cHBvcnRlZFxudmFyIGhhc1Byb3RvU3VwcG9ydCA9ICdfX3Byb3RvX18nIGluIE9iamVjdDtcblxuLy8gV2l0aG91dCBgX19wcm90b19fYCBzdXBwb3J0LCB0aGlzIG1vZHVsZSB3aWxsIG5lZWQgdG8gYWRkIHByb3BlcnRpZXMgdG8gYSBmdW5jdGlvbi5cbi8vIEhvd2V2ZXIsIHNvbWUgRnVuY3Rpb24ucHJvdG90eXBlIG1ldGhvZHMgY2Fubm90IGJlIG92ZXJ3cml0dGVuLFxuLy8gYW5kIHRoZXJlIHNlZW1zIG5vIGVhc3kgY3Jvc3MtcGxhdGZvcm0gd2F5IHRvIGRldGVjdCB0aGVtIChAc2VlIGNoYWlqcy9jaGFpL2lzc3Vlcy82OSkuXG52YXIgZXhjbHVkZU5hbWVzID0gL14oPzpsZW5ndGh8bmFtZXxhcmd1bWVudHN8Y2FsbGVyKSQvO1xuXG4vLyBDYWNoZSBgRnVuY3Rpb25gIHByb3BlcnRpZXNcbnZhciBjYWxsICA9IEZ1bmN0aW9uLnByb3RvdHlwZS5jYWxsLFxuICAgIGFwcGx5ID0gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5O1xuXG4vKipcbiAqICMjIyBhZGRDaGFpbmFibGVNZXRob2QgKGN0eCwgbmFtZSwgbWV0aG9kLCBjaGFpbmluZ0JlaGF2aW9yKVxuICpcbiAqIEFkZHMgYSBtZXRob2QgdG8gYW4gb2JqZWN0LCBzdWNoIHRoYXQgdGhlIG1ldGhvZCBjYW4gYWxzbyBiZSBjaGFpbmVkLlxuICpcbiAqICAgICB1dGlscy5hZGRDaGFpbmFibGVNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnZm9vJywgZnVuY3Rpb24gKHN0cikge1xuICogICAgICAgdmFyIG9iaiA9IHV0aWxzLmZsYWcodGhpcywgJ29iamVjdCcpO1xuICogICAgICAgbmV3IGNoYWkuQXNzZXJ0aW9uKG9iaikudG8uYmUuZXF1YWwoc3RyKTtcbiAqICAgICB9KTtcbiAqXG4gKiBDYW4gYWxzbyBiZSBhY2Nlc3NlZCBkaXJlY3RseSBmcm9tIGBjaGFpLkFzc2VydGlvbmAuXG4gKlxuICogICAgIGNoYWkuQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnZm9vJywgZm4sIGNoYWluaW5nQmVoYXZpb3IpO1xuICpcbiAqIFRoZSByZXN1bHQgY2FuIHRoZW4gYmUgdXNlZCBhcyBib3RoIGEgbWV0aG9kIGFzc2VydGlvbiwgZXhlY3V0aW5nIGJvdGggYG1ldGhvZGAgYW5kXG4gKiBgY2hhaW5pbmdCZWhhdmlvcmAsIG9yIGFzIGEgbGFuZ3VhZ2UgY2hhaW4sIHdoaWNoIG9ubHkgZXhlY3V0ZXMgYGNoYWluaW5nQmVoYXZpb3JgLlxuICpcbiAqICAgICBleHBlY3QoZm9vU3RyKS50by5iZS5mb28oJ2JhcicpO1xuICogICAgIGV4cGVjdChmb29TdHIpLnRvLmJlLmZvby5lcXVhbCgnZm9vJyk7XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGN0eCBvYmplY3QgdG8gd2hpY2ggdGhlIG1ldGhvZCBpcyBhZGRlZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgbWV0aG9kIHRvIGFkZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gbWV0aG9kIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIGBuYW1lYCwgd2hlbiBjYWxsZWRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNoYWluaW5nQmVoYXZpb3IgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIGV2ZXJ5IHRpbWUgdGhlIHByb3BlcnR5IGlzIGFjY2Vzc2VkXG4gKiBAbmFtZSBhZGRDaGFpbmFibGVNZXRob2RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY3R4LCBuYW1lLCBtZXRob2QsIGNoYWluaW5nQmVoYXZpb3IpIHtcbiAgaWYgKHR5cGVvZiBjaGFpbmluZ0JlaGF2aW9yICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgY2hhaW5pbmdCZWhhdmlvciA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgfVxuXG4gIHZhciBjaGFpbmFibGVCZWhhdmlvciA9IHtcbiAgICAgIG1ldGhvZDogbWV0aG9kXG4gICAgLCBjaGFpbmluZ0JlaGF2aW9yOiBjaGFpbmluZ0JlaGF2aW9yXG4gIH07XG5cbiAgLy8gc2F2ZSB0aGUgbWV0aG9kcyBzbyB3ZSBjYW4gb3ZlcndyaXRlIHRoZW0gbGF0ZXIsIGlmIHdlIG5lZWQgdG8uXG4gIGlmICghY3R4Ll9fbWV0aG9kcykge1xuICAgIGN0eC5fX21ldGhvZHMgPSB7fTtcbiAgfVxuICBjdHguX19tZXRob2RzW25hbWVdID0gY2hhaW5hYmxlQmVoYXZpb3I7XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwgbmFtZSxcbiAgICB7IGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICBjaGFpbmFibGVCZWhhdmlvci5jaGFpbmluZ0JlaGF2aW9yLmNhbGwodGhpcyk7XG5cbiAgICAgICAgdmFyIGFzc2VydCA9IGZ1bmN0aW9uIGFzc2VydCgpIHtcbiAgICAgICAgICB2YXIgb2xkX3NzZmkgPSBmbGFnKHRoaXMsICdzc2ZpJyk7XG4gICAgICAgICAgaWYgKG9sZF9zc2ZpICYmIGNvbmZpZy5pbmNsdWRlU3RhY2sgPT09IGZhbHNlKVxuICAgICAgICAgICAgZmxhZyh0aGlzLCAnc3NmaScsIGFzc2VydCk7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IGNoYWluYWJsZUJlaGF2aW9yLm1ldGhvZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IHRoaXMgOiByZXN1bHQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gVXNlIGBfX3Byb3RvX19gIGlmIGF2YWlsYWJsZVxuICAgICAgICBpZiAoaGFzUHJvdG9TdXBwb3J0KSB7XG4gICAgICAgICAgLy8gSW5oZXJpdCBhbGwgcHJvcGVydGllcyBmcm9tIHRoZSBvYmplY3QgYnkgcmVwbGFjaW5nIHRoZSBgRnVuY3Rpb25gIHByb3RvdHlwZVxuICAgICAgICAgIHZhciBwcm90b3R5cGUgPSBhc3NlcnQuX19wcm90b19fID0gT2JqZWN0LmNyZWF0ZSh0aGlzKTtcbiAgICAgICAgICAvLyBSZXN0b3JlIHRoZSBgY2FsbGAgYW5kIGBhcHBseWAgbWV0aG9kcyBmcm9tIGBGdW5jdGlvbmBcbiAgICAgICAgICBwcm90b3R5cGUuY2FsbCA9IGNhbGw7XG4gICAgICAgICAgcHJvdG90eXBlLmFwcGx5ID0gYXBwbHk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCByZWRlZmluZSBhbGwgcHJvcGVydGllcyAoc2xvdyEpXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBhc3NlcnRlck5hbWVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoY3R4KTtcbiAgICAgICAgICBhc3NlcnRlck5hbWVzLmZvckVhY2goZnVuY3Rpb24gKGFzc2VydGVyTmFtZSkge1xuICAgICAgICAgICAgaWYgKCFleGNsdWRlTmFtZXMudGVzdChhc3NlcnRlck5hbWUpKSB7XG4gICAgICAgICAgICAgIHZhciBwZCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoY3R4LCBhc3NlcnRlck5hbWUpO1xuICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYXNzZXJ0LCBhc3NlcnRlck5hbWUsIHBkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyYW5zZmVyRmxhZ3ModGhpcywgYXNzZXJ0KTtcbiAgICAgICAgcmV0dXJuIGFzc2VydDtcbiAgICAgIH1cbiAgICAsIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICB9KTtcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBhZGRNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxuLyoqXG4gKiAjIyMgLmFkZE1ldGhvZCAoY3R4LCBuYW1lLCBtZXRob2QpXG4gKlxuICogQWRkcyBhIG1ldGhvZCB0byB0aGUgcHJvdG90eXBlIG9mIGFuIG9iamVjdC5cbiAqXG4gKiAgICAgdXRpbHMuYWRkTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgJ2ZvbycsIGZ1bmN0aW9uIChzdHIpIHtcbiAqICAgICAgIHZhciBvYmogPSB1dGlscy5mbGFnKHRoaXMsICdvYmplY3QnKTtcbiAqICAgICAgIG5ldyBjaGFpLkFzc2VydGlvbihvYmopLnRvLmJlLmVxdWFsKHN0cik7XG4gKiAgICAgfSk7XG4gKlxuICogQ2FuIGFsc28gYmUgYWNjZXNzZWQgZGlyZWN0bHkgZnJvbSBgY2hhaS5Bc3NlcnRpb25gLlxuICpcbiAqICAgICBjaGFpLkFzc2VydGlvbi5hZGRNZXRob2QoJ2ZvbycsIGZuKTtcbiAqXG4gKiBUaGVuIGNhbiBiZSB1c2VkIGFzIGFueSBvdGhlciBhc3NlcnRpb24uXG4gKlxuICogICAgIGV4cGVjdChmb29TdHIpLnRvLmJlLmZvbygnYmFyJyk7XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGN0eCBvYmplY3QgdG8gd2hpY2ggdGhlIG1ldGhvZCBpcyBhZGRlZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgbWV0aG9kIHRvIGFkZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gbWV0aG9kIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIG5hbWVcbiAqIEBuYW1lIGFkZE1ldGhvZFxuICogQGFwaSBwdWJsaWNcbiAqL1xudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY3R4LCBuYW1lLCBtZXRob2QpIHtcbiAgY3R4W25hbWVdID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBvbGRfc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKTtcbiAgICBpZiAob2xkX3NzZmkgJiYgY29uZmlnLmluY2x1ZGVTdGFjayA9PT0gZmFsc2UpXG4gICAgICBmbGFnKHRoaXMsICdzc2ZpJywgY3R4W25hbWVdKTtcbiAgICB2YXIgcmVzdWx0ID0gbWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gdGhpcyA6IHJlc3VsdDtcbiAgfTtcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBhZGRQcm9wZXJ0eSB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgYWRkUHJvcGVydHkgKGN0eCwgbmFtZSwgZ2V0dGVyKVxuICpcbiAqIEFkZHMgYSBwcm9wZXJ0eSB0byB0aGUgcHJvdG90eXBlIG9mIGFuIG9iamVjdC5cbiAqXG4gKiAgICAgdXRpbHMuYWRkUHJvcGVydHkoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnZm9vJywgZnVuY3Rpb24gKCkge1xuICogICAgICAgdmFyIG9iaiA9IHV0aWxzLmZsYWcodGhpcywgJ29iamVjdCcpO1xuICogICAgICAgbmV3IGNoYWkuQXNzZXJ0aW9uKG9iaikudG8uYmUuaW5zdGFuY2VvZihGb28pO1xuICogICAgIH0pO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24uYWRkUHJvcGVydHkoJ2ZvbycsIGZuKTtcbiAqXG4gKiBUaGVuIGNhbiBiZSB1c2VkIGFzIGFueSBvdGhlciBhc3NlcnRpb24uXG4gKlxuICogICAgIGV4cGVjdChteUZvbykudG8uYmUuZm9vO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHRvIHdoaWNoIHRoZSBwcm9wZXJ0eSBpcyBhZGRlZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgcHJvcGVydHkgdG8gYWRkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBnZXR0ZXIgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQG5hbWUgYWRkUHJvcGVydHlcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY3R4LCBuYW1lLCBnZXR0ZXIpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwgbmFtZSxcbiAgICB7IGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gZ2V0dGVyLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IHRoaXMgOiByZXN1bHQ7XG4gICAgICB9XG4gICAgLCBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gZmxhZyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgZmxhZyhvYmplY3QgLGtleSwgW3ZhbHVlXSlcbiAqXG4gKiBHZXQgb3Igc2V0IGEgZmxhZyB2YWx1ZSBvbiBhbiBvYmplY3QuIElmIGFcbiAqIHZhbHVlIGlzIHByb3ZpZGVkIGl0IHdpbGwgYmUgc2V0LCBlbHNlIGl0IHdpbGxcbiAqIHJldHVybiB0aGUgY3VycmVudGx5IHNldCB2YWx1ZSBvciBgdW5kZWZpbmVkYCBpZlxuICogdGhlIHZhbHVlIGlzIG5vdCBzZXQuXG4gKlxuICogICAgIHV0aWxzLmZsYWcodGhpcywgJ2ZvbycsICdiYXInKTsgLy8gc2V0dGVyXG4gKiAgICAgdXRpbHMuZmxhZyh0aGlzLCAnZm9vJyk7IC8vIGdldHRlciwgcmV0dXJucyBgYmFyYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgKGNvbnN0cnVjdGVkIEFzc2VydGlvblxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHtNaXhlZH0gdmFsdWUgKG9wdGlvbmFsKVxuICogQG5hbWUgZmxhZ1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqLCBrZXksIHZhbHVlKSB7XG4gIHZhciBmbGFncyA9IG9iai5fX2ZsYWdzIHx8IChvYmouX19mbGFncyA9IE9iamVjdC5jcmVhdGUobnVsbCkpO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xuICAgIGZsYWdzW2tleV0gPSB2YWx1ZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmxhZ3Nba2V5XTtcbiAgfVxufTtcbiIsIi8qIVxuICogQ2hhaSAtIGdldEFjdHVhbCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIGdldEFjdHVhbChvYmplY3QsIFthY3R1YWxdKVxuICpcbiAqIFJldHVybnMgdGhlIGBhY3R1YWxgIHZhbHVlIGZvciBhbiBBc3NlcnRpb25cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IChjb25zdHJ1Y3RlZCBBc3NlcnRpb24pXG4gKiBAcGFyYW0ge0FyZ3VtZW50c30gY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLmFzc2VydCBhcmd1bWVudHNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmosIGFyZ3MpIHtcbiAgcmV0dXJuIGFyZ3MubGVuZ3RoID4gNCA/IGFyZ3NbNF0gOiBvYmouX29iajtcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBnZXRFbnVtZXJhYmxlUHJvcGVydGllcyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmdldEVudW1lcmFibGVQcm9wZXJ0aWVzKG9iamVjdClcbiAqXG4gKiBUaGlzIGFsbG93cyB0aGUgcmV0cmlldmFsIG9mIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYW4gb2JqZWN0LFxuICogaW5oZXJpdGVkIG9yIG5vdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJucyB7QXJyYXl9XG4gKiBAbmFtZSBnZXRFbnVtZXJhYmxlUHJvcGVydGllc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldEVudW1lcmFibGVQcm9wZXJ0aWVzKG9iamVjdCkge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIGZvciAodmFyIG5hbWUgaW4gb2JqZWN0KSB7XG4gICAgcmVzdWx0LnB1c2gobmFtZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBtZXNzYWdlIGNvbXBvc2l0aW9uIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKiFcbiAqIE1vZHVsZSBkZXBlbmRhbmNpZXNcbiAqL1xuXG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpXG4gICwgZ2V0QWN0dWFsID0gcmVxdWlyZSgnLi9nZXRBY3R1YWwnKVxuICAsIGluc3BlY3QgPSByZXF1aXJlKCcuL2luc3BlY3QnKVxuICAsIG9iakRpc3BsYXkgPSByZXF1aXJlKCcuL29iakRpc3BsYXknKTtcblxuLyoqXG4gKiAjIyMgLmdldE1lc3NhZ2Uob2JqZWN0LCBtZXNzYWdlLCBuZWdhdGVNZXNzYWdlKVxuICpcbiAqIENvbnN0cnVjdCB0aGUgZXJyb3IgbWVzc2FnZSBiYXNlZCBvbiBmbGFnc1xuICogYW5kIHRlbXBsYXRlIHRhZ3MuIFRlbXBsYXRlIHRhZ3Mgd2lsbCByZXR1cm5cbiAqIGEgc3RyaW5naWZpZWQgaW5zcGVjdGlvbiBvZiB0aGUgb2JqZWN0IHJlZmVyZW5jZWQuXG4gKlxuICogTWVzc2FnZSB0ZW1wbGF0ZSB0YWdzOlxuICogLSBgI3t0aGlzfWAgY3VycmVudCBhc3NlcnRlZCBvYmplY3RcbiAqIC0gYCN7YWN0fWAgYWN0dWFsIHZhbHVlXG4gKiAtIGAje2V4cH1gIGV4cGVjdGVkIHZhbHVlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCAoY29uc3RydWN0ZWQgQXNzZXJ0aW9uKVxuICogQHBhcmFtIHtBcmd1bWVudHN9IGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZS5hc3NlcnQgYXJndW1lbnRzXG4gKiBAbmFtZSBnZXRNZXNzYWdlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaiwgYXJncykge1xuICB2YXIgbmVnYXRlID0gZmxhZyhvYmosICduZWdhdGUnKVxuICAgICwgdmFsID0gZmxhZyhvYmosICdvYmplY3QnKVxuICAgICwgZXhwZWN0ZWQgPSBhcmdzWzNdXG4gICAgLCBhY3R1YWwgPSBnZXRBY3R1YWwob2JqLCBhcmdzKVxuICAgICwgbXNnID0gbmVnYXRlID8gYXJnc1syXSA6IGFyZ3NbMV1cbiAgICAsIGZsYWdNc2cgPSBmbGFnKG9iaiwgJ21lc3NhZ2UnKTtcblxuICBtc2cgPSBtc2cgfHwgJyc7XG4gIG1zZyA9IG1zZ1xuICAgIC5yZXBsYWNlKC8je3RoaXN9L2csIG9iakRpc3BsYXkodmFsKSlcbiAgICAucmVwbGFjZSgvI3thY3R9L2csIG9iakRpc3BsYXkoYWN0dWFsKSlcbiAgICAucmVwbGFjZSgvI3tleHB9L2csIG9iakRpc3BsYXkoZXhwZWN0ZWQpKTtcblxuICByZXR1cm4gZmxhZ01zZyA/IGZsYWdNc2cgKyAnOiAnICsgbXNnIDogbXNnO1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIGdldE5hbWUgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyBnZXROYW1lKGZ1bmMpXG4gKlxuICogR2V0cyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLCBpbiBhIGNyb3NzLWJyb3dzZXIgd2F5LlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGEgZnVuY3Rpb24gKHVzdWFsbHkgYSBjb25zdHJ1Y3RvcilcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gIGlmIChmdW5jLm5hbWUpIHJldHVybiBmdW5jLm5hbWU7XG5cbiAgdmFyIG1hdGNoID0gL15cXHM/ZnVuY3Rpb24gKFteKF0qKVxcKC8uZXhlYyhmdW5jKTtcbiAgcmV0dXJuIG1hdGNoICYmIG1hdGNoWzFdID8gbWF0Y2hbMV0gOiBcIlwiO1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIGdldFBhdGhWYWx1ZSB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vbG9naWNhbHBhcmFkb3gvZmlsdHJcbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIC5nZXRQYXRoVmFsdWUocGF0aCwgb2JqZWN0KVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgdmFsdWVzIGluIGFuXG4gKiBvYmplY3QgZ2l2ZW4gYSBzdHJpbmcgcGF0aC5cbiAqXG4gKiAgICAgdmFyIG9iaiA9IHtcbiAqICAgICAgICAgcHJvcDE6IHtcbiAqICAgICAgICAgICAgIGFycjogWydhJywgJ2InLCAnYyddXG4gKiAgICAgICAgICAgLCBzdHI6ICdIZWxsbydcbiAqICAgICAgICAgfVxuICogICAgICAgLCBwcm9wMjoge1xuICogICAgICAgICAgICAgYXJyOiBbIHsgbmVzdGVkOiAnVW5pdmVyc2UnIH0gXVxuICogICAgICAgICAgICwgc3RyOiAnSGVsbG8gYWdhaW4hJ1xuICogICAgICAgICB9XG4gKiAgICAgfVxuICpcbiAqIFRoZSBmb2xsb3dpbmcgd291bGQgYmUgdGhlIHJlc3VsdHMuXG4gKlxuICogICAgIGdldFBhdGhWYWx1ZSgncHJvcDEuc3RyJywgb2JqKTsgLy8gSGVsbG9cbiAqICAgICBnZXRQYXRoVmFsdWUoJ3Byb3AxLmF0dFsyXScsIG9iaik7IC8vIGJcbiAqICAgICBnZXRQYXRoVmFsdWUoJ3Byb3AyLmFyclswXS5uZXN0ZWQnLCBvYmopOyAvLyBVbml2ZXJzZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJucyB7T2JqZWN0fSB2YWx1ZSBvciBgdW5kZWZpbmVkYFxuICogQG5hbWUgZ2V0UGF0aFZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnZhciBnZXRQYXRoVmFsdWUgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChwYXRoLCBvYmopIHtcbiAgdmFyIHBhcnNlZCA9IHBhcnNlUGF0aChwYXRoKTtcbiAgcmV0dXJuIF9nZXRQYXRoVmFsdWUocGFyc2VkLCBvYmopO1xufTtcblxuLyohXG4gKiAjIyBwYXJzZVBhdGgocGF0aClcbiAqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdXNlZCB0byBwYXJzZSBzdHJpbmcgb2JqZWN0XG4gKiBwYXRocy4gVXNlIGluIGNvbmp1bmN0aW9uIHdpdGggYF9nZXRQYXRoVmFsdWVgLlxuICpcbiAqICAgICAgdmFyIHBhcnNlZCA9IHBhcnNlUGF0aCgnbXlvYmplY3QucHJvcGVydHkuc3VicHJvcCcpO1xuICpcbiAqICMjIyBQYXRoczpcbiAqXG4gKiAqIENhbiBiZSBhcyBuZWFyIGluZmluaXRlbHkgZGVlcCBhbmQgbmVzdGVkXG4gKiAqIEFycmF5cyBhcmUgYWxzbyB2YWxpZCB1c2luZyB0aGUgZm9ybWFsIGBteW9iamVjdC5kb2N1bWVudFszXS5wcm9wZXJ0eWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhdGhcbiAqIEByZXR1cm5zIHtPYmplY3R9IHBhcnNlZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcGFyc2VQYXRoIChwYXRoKSB7XG4gIHZhciBzdHIgPSBwYXRoLnJlcGxhY2UoL1xcWy9nLCAnLlsnKVxuICAgICwgcGFydHMgPSBzdHIubWF0Y2goLyhcXFxcXFwufFteLl0rPykrL2cpO1xuICByZXR1cm4gcGFydHMubWFwKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciByZSA9IC9cXFsoXFxkKylcXF0kL1xuICAgICAgLCBtQXJyID0gcmUuZXhlYyh2YWx1ZSlcbiAgICBpZiAobUFycikgcmV0dXJuIHsgaTogcGFyc2VGbG9hdChtQXJyWzFdKSB9O1xuICAgIGVsc2UgcmV0dXJuIHsgcDogdmFsdWUgfTtcbiAgfSk7XG59O1xuXG4vKiFcbiAqICMjIF9nZXRQYXRoVmFsdWUocGFyc2VkLCBvYmopXG4gKlxuICogSGVscGVyIGNvbXBhbmlvbiBmdW5jdGlvbiBmb3IgYC5wYXJzZVBhdGhgIHRoYXQgcmV0dXJuc1xuICogdGhlIHZhbHVlIGxvY2F0ZWQgYXQgdGhlIHBhcnNlZCBhZGRyZXNzLlxuICpcbiAqICAgICAgdmFyIHZhbHVlID0gZ2V0UGF0aFZhbHVlKHBhcnNlZCwgb2JqKTtcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFyc2VkIGRlZmluaXRpb24gZnJvbSBgcGFyc2VQYXRoYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgdG8gc2VhcmNoIGFnYWluc3RcbiAqIEByZXR1cm5zIHtPYmplY3R8VW5kZWZpbmVkfSB2YWx1ZVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gX2dldFBhdGhWYWx1ZSAocGFyc2VkLCBvYmopIHtcbiAgdmFyIHRtcCA9IG9ialxuICAgICwgcmVzO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHBhcnNlZC5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIgcGFydCA9IHBhcnNlZFtpXTtcbiAgICBpZiAodG1wKSB7XG4gICAgICBpZiAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiBwYXJ0LnApXG4gICAgICAgIHRtcCA9IHRtcFtwYXJ0LnBdO1xuICAgICAgZWxzZSBpZiAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiBwYXJ0LmkpXG4gICAgICAgIHRtcCA9IHRtcFtwYXJ0LmldO1xuICAgICAgaWYgKGkgPT0gKGwgLSAxKSkgcmVzID0gdG1wO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXM7XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gZ2V0UHJvcGVydGllcyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgLmdldFByb3BlcnRpZXMob2JqZWN0KVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgcHJvcGVydHkgbmFtZXMgb2YgYW4gb2JqZWN0LCBlbnVtZXJhYmxlIG9yIG5vdCxcbiAqIGluaGVyaXRlZCBvciBub3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICogQHJldHVybnMge0FycmF5fVxuICogQG5hbWUgZ2V0UHJvcGVydGllc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFByb3BlcnRpZXMob2JqZWN0KSB7XG4gIHZhciByZXN1bHQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhzdWJqZWN0KTtcblxuICBmdW5jdGlvbiBhZGRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgIGlmIChyZXN1bHQuaW5kZXhPZihwcm9wZXJ0eSkgPT09IC0xKSB7XG4gICAgICByZXN1bHQucHVzaChwcm9wZXJ0eSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHN1YmplY3QpO1xuICB3aGlsZSAocHJvdG8gIT09IG51bGwpIHtcbiAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhwcm90bykuZm9yRWFjaChhZGRQcm9wZXJ0eSk7XG4gICAgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExIEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNYWluIGV4cG9ydHNcbiAqL1xuXG52YXIgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8qIVxuICogdGVzdCB1dGlsaXR5XG4gKi9cblxuZXhwb3J0cy50ZXN0ID0gcmVxdWlyZSgnLi90ZXN0Jyk7XG5cbi8qIVxuICogdHlwZSB1dGlsaXR5XG4gKi9cblxuZXhwb3J0cy50eXBlID0gcmVxdWlyZSgnLi90eXBlJyk7XG5cbi8qIVxuICogbWVzc2FnZSB1dGlsaXR5XG4gKi9cblxuZXhwb3J0cy5nZXRNZXNzYWdlID0gcmVxdWlyZSgnLi9nZXRNZXNzYWdlJyk7XG5cbi8qIVxuICogYWN0dWFsIHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLmdldEFjdHVhbCA9IHJlcXVpcmUoJy4vZ2V0QWN0dWFsJyk7XG5cbi8qIVxuICogSW5zcGVjdCB1dGlsXG4gKi9cblxuZXhwb3J0cy5pbnNwZWN0ID0gcmVxdWlyZSgnLi9pbnNwZWN0Jyk7XG5cbi8qIVxuICogT2JqZWN0IERpc3BsYXkgdXRpbFxuICovXG5cbmV4cG9ydHMub2JqRGlzcGxheSA9IHJlcXVpcmUoJy4vb2JqRGlzcGxheScpO1xuXG4vKiFcbiAqIEZsYWcgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMuZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xuXG4vKiFcbiAqIEZsYWcgdHJhbnNmZXJyaW5nIHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLnRyYW5zZmVyRmxhZ3MgPSByZXF1aXJlKCcuL3RyYW5zZmVyRmxhZ3MnKTtcblxuLyohXG4gKiBEZWVwIGVxdWFsIHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLmVxbCA9IHJlcXVpcmUoJ2RlZXAtZXFsJyk7XG5cbi8qIVxuICogRGVlcCBwYXRoIHZhbHVlXG4gKi9cblxuZXhwb3J0cy5nZXRQYXRoVmFsdWUgPSByZXF1aXJlKCcuL2dldFBhdGhWYWx1ZScpO1xuXG4vKiFcbiAqIEZ1bmN0aW9uIG5hbWVcbiAqL1xuXG5leHBvcnRzLmdldE5hbWUgPSByZXF1aXJlKCcuL2dldE5hbWUnKTtcblxuLyohXG4gKiBhZGQgUHJvcGVydHlcbiAqL1xuXG5leHBvcnRzLmFkZFByb3BlcnR5ID0gcmVxdWlyZSgnLi9hZGRQcm9wZXJ0eScpO1xuXG4vKiFcbiAqIGFkZCBNZXRob2RcbiAqL1xuXG5leHBvcnRzLmFkZE1ldGhvZCA9IHJlcXVpcmUoJy4vYWRkTWV0aG9kJyk7XG5cbi8qIVxuICogb3ZlcndyaXRlIFByb3BlcnR5XG4gKi9cblxuZXhwb3J0cy5vdmVyd3JpdGVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vb3ZlcndyaXRlUHJvcGVydHknKTtcblxuLyohXG4gKiBvdmVyd3JpdGUgTWV0aG9kXG4gKi9cblxuZXhwb3J0cy5vdmVyd3JpdGVNZXRob2QgPSByZXF1aXJlKCcuL292ZXJ3cml0ZU1ldGhvZCcpO1xuXG4vKiFcbiAqIEFkZCBhIGNoYWluYWJsZSBtZXRob2RcbiAqL1xuXG5leHBvcnRzLmFkZENoYWluYWJsZU1ldGhvZCA9IHJlcXVpcmUoJy4vYWRkQ2hhaW5hYmxlTWV0aG9kJyk7XG5cbi8qIVxuICogT3ZlcndyaXRlIGNoYWluYWJsZSBtZXRob2RcbiAqL1xuXG5leHBvcnRzLm92ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCA9IHJlcXVpcmUoJy4vb3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kJyk7XG5cbiIsIi8vIFRoaXMgaXMgKGFsbW9zdCkgZGlyZWN0bHkgZnJvbSBOb2RlLmpzIHV0aWxzXG4vLyBodHRwczovL2dpdGh1Yi5jb20vam95ZW50L25vZGUvYmxvYi9mOGMzMzVkMGNhZjQ3ZjE2ZDMxNDEzZjg5YWEyOGVkYTM4NzhlM2FhL2xpYi91dGlsLmpzXG5cbnZhciBnZXROYW1lID0gcmVxdWlyZSgnLi9nZXROYW1lJyk7XG52YXIgZ2V0UHJvcGVydGllcyA9IHJlcXVpcmUoJy4vZ2V0UHJvcGVydGllcycpO1xudmFyIGdldEVudW1lcmFibGVQcm9wZXJ0aWVzID0gcmVxdWlyZSgnLi9nZXRFbnVtZXJhYmxlUHJvcGVydGllcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGluc3BlY3Q7XG5cbi8qKlxuICogRWNob3MgdGhlIHZhbHVlIG9mIGEgdmFsdWUuIFRyeXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gc2hvd0hpZGRlbiBGbGFnIHRoYXQgc2hvd3MgaGlkZGVuIChub3QgZW51bWVyYWJsZSlcbiAqICAgIHByb3BlcnRpZXMgb2Ygb2JqZWN0cy5cbiAqIEBwYXJhbSB7TnVtYmVyfSBkZXB0aCBEZXB0aCBpbiB3aGljaCB0byBkZXNjZW5kIGluIG9iamVjdC4gRGVmYXVsdCBpcyAyLlxuICogQHBhcmFtIHtCb29sZWFufSBjb2xvcnMgRmxhZyB0byB0dXJuIG9uIEFOU0kgZXNjYXBlIGNvZGVzIHRvIGNvbG9yIHRoZVxuICogICAgb3V0cHV0LiBEZWZhdWx0IGlzIGZhbHNlIChubyBjb2xvcmluZykuXG4gKi9cbmZ1bmN0aW9uIGluc3BlY3Qob2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKSB7XG4gIHZhciBjdHggPSB7XG4gICAgc2hvd0hpZGRlbjogc2hvd0hpZGRlbixcbiAgICBzZWVuOiBbXSxcbiAgICBzdHlsaXplOiBmdW5jdGlvbiAoc3RyKSB7IHJldHVybiBzdHI7IH1cbiAgfTtcbiAgcmV0dXJuIGZvcm1hdFZhbHVlKGN0eCwgb2JqLCAodHlwZW9mIGRlcHRoID09PSAndW5kZWZpbmVkJyA/IDIgOiBkZXB0aCkpO1xufVxuXG4vLyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS8xMDQ0MTI4L1xudmFyIGdldE91dGVySFRNTCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgaWYgKCdvdXRlckhUTUwnIGluIGVsZW1lbnQpIHJldHVybiBlbGVtZW50Lm91dGVySFRNTDtcbiAgdmFyIG5zID0gXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI7XG4gIHZhciBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMobnMsICdfJyk7XG4gIHZhciBlbGVtUHJvdG8gPSAod2luZG93LkhUTUxFbGVtZW50IHx8IHdpbmRvdy5FbGVtZW50KS5wcm90b3R5cGU7XG4gIHZhciB4bWxTZXJpYWxpemVyID0gbmV3IFhNTFNlcmlhbGl6ZXIoKTtcbiAgdmFyIGh0bWw7XG4gIGlmIChkb2N1bWVudC54bWxWZXJzaW9uKSB7XG4gICAgcmV0dXJuIHhtbFNlcmlhbGl6ZXIuc2VyaWFsaXplVG9TdHJpbmcoZWxlbWVudCk7XG4gIH0gZWxzZSB7XG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGVsZW1lbnQuY2xvbmVOb2RlKGZhbHNlKSk7XG4gICAgaHRtbCA9IGNvbnRhaW5lci5pbm5lckhUTUwucmVwbGFjZSgnPjwnLCAnPicgKyBlbGVtZW50LmlubmVySFRNTCArICc8Jyk7XG4gICAgY29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xuICAgIHJldHVybiBodG1sO1xuICB9XG59O1xuXG4vLyBSZXR1cm5zIHRydWUgaWYgb2JqZWN0IGlzIGEgRE9NIGVsZW1lbnQuXG52YXIgaXNET01FbGVtZW50ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICBpZiAodHlwZW9mIEhUTUxFbGVtZW50ID09PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBIVE1MRWxlbWVudDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gb2JqZWN0ICYmXG4gICAgICB0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuICAgICAgb2JqZWN0Lm5vZGVUeXBlID09PSAxICYmXG4gICAgICB0eXBlb2Ygb2JqZWN0Lm5vZGVOYW1lID09PSAnc3RyaW5nJztcbiAgfVxufTtcblxuZnVuY3Rpb24gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzKSB7XG4gIC8vIFByb3ZpZGUgYSBob29rIGZvciB1c2VyLXNwZWNpZmllZCBpbnNwZWN0IGZ1bmN0aW9ucy5cbiAgLy8gQ2hlY2sgdGhhdCB2YWx1ZSBpcyBhbiBvYmplY3Qgd2l0aCBhbiBpbnNwZWN0IGZ1bmN0aW9uIG9uIGl0XG4gIGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUuaW5zcGVjdCA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBleHBvcnRzLmluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcyk7XG4gICAgaWYgKHR5cGVvZiByZXQgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXQgPSBmb3JtYXRWYWx1ZShjdHgsIHJldCwgcmVjdXJzZVRpbWVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8vIFByaW1pdGl2ZSB0eXBlcyBjYW5ub3QgaGF2ZSBwcm9wZXJ0aWVzXG4gIHZhciBwcmltaXRpdmUgPSBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSk7XG4gIGlmIChwcmltaXRpdmUpIHtcbiAgICByZXR1cm4gcHJpbWl0aXZlO1xuICB9XG5cbiAgLy8gSWYgaXQncyBET00gZWxlbSwgZ2V0IG91dGVyIEhUTUwuXG4gIGlmIChpc0RPTUVsZW1lbnQodmFsdWUpKSB7XG4gICAgcmV0dXJuIGdldE91dGVySFRNTCh2YWx1ZSk7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciB2aXNpYmxlS2V5cyA9IGdldEVudW1lcmFibGVQcm9wZXJ0aWVzKHZhbHVlKTtcbiAgdmFyIGtleXMgPSBjdHguc2hvd0hpZGRlbiA/IGdldFByb3BlcnRpZXModmFsdWUpIDogdmlzaWJsZUtleXM7XG5cbiAgLy8gU29tZSB0eXBlIG9mIG9iamVjdCB3aXRob3V0IHByb3BlcnRpZXMgY2FuIGJlIHNob3J0Y3V0dGVkLlxuICAvLyBJbiBJRSwgZXJyb3JzIGhhdmUgYSBzaW5nbGUgYHN0YWNrYCBwcm9wZXJ0eSwgb3IgaWYgdGhleSBhcmUgdmFuaWxsYSBgRXJyb3JgLFxuICAvLyBhIGBzdGFja2AgcGx1cyBgZGVzY3JpcHRpb25gIHByb3BlcnR5OyBpZ25vcmUgdGhvc2UgZm9yIGNvbnNpc3RlbmN5LlxuICBpZiAoa2V5cy5sZW5ndGggPT09IDAgfHwgKGlzRXJyb3IodmFsdWUpICYmIChcbiAgICAgIChrZXlzLmxlbmd0aCA9PT0gMSAmJiBrZXlzWzBdID09PSAnc3RhY2snKSB8fFxuICAgICAgKGtleXMubGVuZ3RoID09PSAyICYmIGtleXNbMF0gPT09ICdkZXNjcmlwdGlvbicgJiYga2V5c1sxXSA9PT0gJ3N0YWNrJylcbiAgICAgKSkpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgbmFtZSA9IGdldE5hbWUodmFsdWUpO1xuICAgICAgdmFyIG5hbWVTdWZmaXggPSBuYW1lID8gJzogJyArIG5hbWUgOiAnJztcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW0Z1bmN0aW9uJyArIG5hbWVTdWZmaXggKyAnXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfVxuICAgIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSksICdkYXRlJyk7XG4gICAgfVxuICAgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgYmFzZSA9ICcnLCBhcnJheSA9IGZhbHNlLCBicmFjZXMgPSBbJ3snLCAnfSddO1xuXG4gIC8vIE1ha2UgQXJyYXkgc2F5IHRoYXQgdGhleSBhcmUgQXJyYXlcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgYXJyYXkgPSB0cnVlO1xuICAgIGJyYWNlcyA9IFsnWycsICddJ107XG4gIH1cblxuICAvLyBNYWtlIGZ1bmN0aW9ucyBzYXkgdGhhdCB0aGV5IGFyZSBmdW5jdGlvbnNcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHZhciBuYW1lID0gZ2V0TmFtZSh2YWx1ZSk7XG4gICAgdmFyIG5hbWVTdWZmaXggPSBuYW1lID8gJzogJyArIG5hbWUgOiAnJztcbiAgICBiYXNlID0gJyBbRnVuY3Rpb24nICsgbmFtZVN1ZmZpeCArICddJztcbiAgfVxuXG4gIC8vIE1ha2UgUmVnRXhwcyBzYXkgdGhhdCB0aGV5IGFyZSBSZWdFeHBzXG4gIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZGF0ZXMgd2l0aCBwcm9wZXJ0aWVzIGZpcnN0IHNheSB0aGUgZGF0ZVxuICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZXJyb3Igd2l0aCBtZXNzYWdlIGZpcnN0IHNheSB0aGUgZXJyb3JcbiAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCAmJiAoIWFycmF5IHx8IHZhbHVlLmxlbmd0aCA9PSAwKSkge1xuICAgIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgYnJhY2VzWzFdO1xuICB9XG5cbiAgaWYgKHJlY3Vyc2VUaW1lcyA8IDApIHtcbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tPYmplY3RdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cblxuICBjdHguc2Vlbi5wdXNoKHZhbHVlKTtcblxuICB2YXIgb3V0cHV0O1xuICBpZiAoYXJyYXkpIHtcbiAgICBvdXRwdXQgPSBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRwdXQgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgc3dpdGNoICh0eXBlb2YgdmFsdWUpIHtcbiAgICBjYXNlICd1bmRlZmluZWQnOlxuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG5cbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgdmFyIHNpbXBsZSA9ICdcXCcnICsgSlNPTi5zdHJpbmdpZnkodmFsdWUpLnJlcGxhY2UoL15cInxcIiQvZywgJycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKHNpbXBsZSwgJ3N0cmluZycpO1xuXG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG5cbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICB9XG4gIC8vIEZvciBzb21lIHJlYXNvbiB0eXBlb2YgbnVsbCBpcyBcIm9iamVjdFwiLCBzbyBzcGVjaWFsIGNhc2UgaGVyZS5cbiAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCdudWxsJywgJ251bGwnKTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG4gIHJldHVybiAnWycgKyBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgKyAnXSc7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuICB2YXIgb3V0cHV0ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgU3RyaW5nKGkpKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBTdHJpbmcoaSksIHRydWUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0LnB1c2goJycpO1xuICAgIH1cbiAgfVxuICBrZXlzLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgaWYgKCFrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIGtleSwgdHJ1ZSkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvdXRwdXQ7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSkge1xuICB2YXIgbmFtZSwgc3RyO1xuICBpZiAodmFsdWUuX19sb29rdXBHZXR0ZXJfXykge1xuICAgIGlmICh2YWx1ZS5fX2xvb2t1cEdldHRlcl9fKGtleSkpIHtcbiAgICAgIGlmICh2YWx1ZS5fX2xvb2t1cFNldHRlcl9fKGtleSkpIHtcbiAgICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXIvU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodmFsdWUuX19sb29rdXBTZXR0ZXJfXyhrZXkpKSB7XG4gICAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmICh2aXNpYmxlS2V5cy5pbmRleE9mKGtleSkgPCAwKSB7XG4gICAgbmFtZSA9ICdbJyArIGtleSArICddJztcbiAgfVxuICBpZiAoIXN0cikge1xuICAgIGlmIChjdHguc2Vlbi5pbmRleE9mKHZhbHVlW2tleV0pIDwgMCkge1xuICAgICAgaWYgKHJlY3Vyc2VUaW1lcyA9PT0gbnVsbCkge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlW2tleV0sIG51bGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZVtrZXldLCByZWN1cnNlVGltZXMgLSAxKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdHIuaW5kZXhPZignXFxuJykgPiAtMSkge1xuICAgICAgICBpZiAoYXJyYXkpIHtcbiAgICAgICAgICBzdHIgPSBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJykuc3Vic3RyKDIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0ciA9ICdcXG4nICsgc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0NpcmN1bGFyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cblxuZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcbiAgdmFyIG51bUxpbmVzRXN0ID0gMDtcbiAgdmFyIGxlbmd0aCA9IG91dHB1dC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIubGVuZ3RoICsgMTtcbiAgfSwgMCk7XG5cbiAgaWYgKGxlbmd0aCA+IDYwKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArXG4gICAgICAgICAgIChiYXNlID09PSAnJyA/ICcnIDogYmFzZSArICdcXG4gJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBvdXRwdXQuam9pbignLFxcbiAgJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBicmFjZXNbMV07XG4gIH1cblxuICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArICcgJyArIG91dHB1dC5qb2luKCcsICcpICsgJyAnICsgYnJhY2VzWzFdO1xufVxuXG5mdW5jdGlvbiBpc0FycmF5KGFyKSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGFyKSB8fFxuICAgICAgICAgKHR5cGVvZiBhciA9PT0gJ29iamVjdCcgJiYgb2JqZWN0VG9TdHJpbmcoYXIpID09PSAnW29iamVjdCBBcnJheV0nKTtcbn1cblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIHR5cGVvZiByZSA9PT0gJ29iamVjdCcgJiYgb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIHR5cGVvZiBkID09PSAnb2JqZWN0JyAmJiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIHR5cGVvZiBlID09PSAnb2JqZWN0JyAmJiBvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJztcbn1cblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuIiwiLyohXG4gKiBDaGFpIC0gZmxhZyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kYW5jaWVzXG4gKi9cblxudmFyIGluc3BlY3QgPSByZXF1aXJlKCcuL2luc3BlY3QnKTtcbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxuLyoqXG4gKiAjIyMgLm9iakRpc3BsYXkgKG9iamVjdClcbiAqXG4gKiBEZXRlcm1pbmVzIGlmIGFuIG9iamVjdCBvciBhbiBhcnJheSBtYXRjaGVzXG4gKiBjcml0ZXJpYSB0byBiZSBpbnNwZWN0ZWQgaW4tbGluZSBmb3IgZXJyb3JcbiAqIG1lc3NhZ2VzIG9yIHNob3VsZCBiZSB0cnVuY2F0ZWQuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gamF2YXNjcmlwdCBvYmplY3QgdG8gaW5zcGVjdFxuICogQG5hbWUgb2JqRGlzcGxheVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIHN0ciA9IGluc3BlY3Qob2JqKVxuICAgICwgdHlwZSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xuXG4gIGlmIChjb25maWcudHJ1bmNhdGVUaHJlc2hvbGQgJiYgc3RyLmxlbmd0aCA+PSBjb25maWcudHJ1bmNhdGVUaHJlc2hvbGQpIHtcbiAgICBpZiAodHlwZSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJykge1xuICAgICAgcmV0dXJuICFvYmoubmFtZSB8fCBvYmoubmFtZSA9PT0gJydcbiAgICAgICAgPyAnW0Z1bmN0aW9uXSdcbiAgICAgICAgOiAnW0Z1bmN0aW9uOiAnICsgb2JqLm5hbWUgKyAnXSc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICByZXR1cm4gJ1sgQXJyYXkoJyArIG9iai5sZW5ndGggKyAnKSBdJztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iailcbiAgICAgICAgLCBrc3RyID0ga2V5cy5sZW5ndGggPiAyXG4gICAgICAgICAgPyBrZXlzLnNwbGljZSgwLCAyKS5qb2luKCcsICcpICsgJywgLi4uJ1xuICAgICAgICAgIDoga2V5cy5qb2luKCcsICcpO1xuICAgICAgcmV0dXJuICd7IE9iamVjdCAoJyArIGtzdHIgKyAnKSB9JztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufTtcbiIsIi8qIVxuICogQ2hhaSAtIG92ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgb3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kIChjdHgsIG5hbWUsIGZuKVxuICpcbiAqIE92ZXJ3aXRlcyBhbiBhbHJlYWR5IGV4aXN0aW5nIGNoYWluYWJsZSBtZXRob2RcbiAqIGFuZCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIHByZXZpb3VzIGZ1bmN0aW9uIG9yXG4gKiBwcm9wZXJ0eS4gIE11c3QgcmV0dXJuIGZ1bmN0aW9ucyB0byBiZSB1c2VkIGZvclxuICogbmFtZS5cbiAqXG4gKiAgICAgdXRpbHMub3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgJ2xlbmd0aCcsXG4gKiAgICAgICBmdW5jdGlvbiAoX3N1cGVyKSB7XG4gKiAgICAgICB9XG4gKiAgICAgLCBmdW5jdGlvbiAoX3N1cGVyKSB7XG4gKiAgICAgICB9XG4gKiAgICAgKTtcbiAqXG4gKiBDYW4gYWxzbyBiZSBhY2Nlc3NlZCBkaXJlY3RseSBmcm9tIGBjaGFpLkFzc2VydGlvbmAuXG4gKlxuICogICAgIGNoYWkuQXNzZXJ0aW9uLm92ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCgnZm9vJywgZm4sIGZuKTtcbiAqXG4gKiBUaGVuIGNhbiBiZSB1c2VkIGFzIGFueSBvdGhlciBhc3NlcnRpb24uXG4gKlxuICogICAgIGV4cGVjdChteUZvbykudG8uaGF2ZS5sZW5ndGgoMyk7XG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5oYXZlLmxlbmd0aC5hYm92ZSgzKTtcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4IG9iamVjdCB3aG9zZSBtZXRob2QgLyBwcm9wZXJ0eSBpcyB0byBiZSBvdmVyd3JpdHRlblxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgbWV0aG9kIC8gcHJvcGVydHkgdG8gb3ZlcndyaXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2hhaW5pbmdCZWhhdmlvciBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBwcm9wZXJ0eVxuICogQG5hbWUgb3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGN0eCwgbmFtZSwgbWV0aG9kLCBjaGFpbmluZ0JlaGF2aW9yKSB7XG4gIHZhciBjaGFpbmFibGVCZWhhdmlvciA9IGN0eC5fX21ldGhvZHNbbmFtZV07XG5cbiAgdmFyIF9jaGFpbmluZ0JlaGF2aW9yID0gY2hhaW5hYmxlQmVoYXZpb3IuY2hhaW5pbmdCZWhhdmlvcjtcbiAgY2hhaW5hYmxlQmVoYXZpb3IuY2hhaW5pbmdCZWhhdmlvciA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcmVzdWx0ID0gY2hhaW5pbmdCZWhhdmlvcihfY2hhaW5pbmdCZWhhdmlvcikuY2FsbCh0aGlzKTtcbiAgICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgPyB0aGlzIDogcmVzdWx0O1xuICB9O1xuXG4gIHZhciBfbWV0aG9kID0gY2hhaW5hYmxlQmVoYXZpb3IubWV0aG9kO1xuICBjaGFpbmFibGVCZWhhdmlvci5tZXRob2QgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHJlc3VsdCA9IG1ldGhvZChfbWV0aG9kKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IHRoaXMgOiByZXN1bHQ7XG4gIH07XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gb3ZlcndyaXRlTWV0aG9kIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMjIyBvdmVyd3JpdGVNZXRob2QgKGN0eCwgbmFtZSwgZm4pXG4gKlxuICogT3ZlcndpdGVzIGFuIGFscmVhZHkgZXhpc3RpbmcgbWV0aG9kIGFuZCBwcm92aWRlc1xuICogYWNjZXNzIHRvIHByZXZpb3VzIGZ1bmN0aW9uLiBNdXN0IHJldHVybiBmdW5jdGlvblxuICogdG8gYmUgdXNlZCBmb3IgbmFtZS5cbiAqXG4gKiAgICAgdXRpbHMub3ZlcndyaXRlTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgJ2VxdWFsJywgZnVuY3Rpb24gKF9zdXBlcikge1xuICogICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzdHIpIHtcbiAqICAgICAgICAgdmFyIG9iaiA9IHV0aWxzLmZsYWcodGhpcywgJ29iamVjdCcpO1xuICogICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgRm9vKSB7XG4gKiAgICAgICAgICAgbmV3IGNoYWkuQXNzZXJ0aW9uKG9iai52YWx1ZSkudG8uZXF1YWwoc3RyKTtcbiAqICAgICAgICAgfSBlbHNlIHtcbiAqICAgICAgICAgICBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAqICAgICAgICAgfVxuICogICAgICAgfVxuICogICAgIH0pO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24ub3ZlcndyaXRlTWV0aG9kKCdmb28nLCBmbik7XG4gKlxuICogVGhlbiBjYW4gYmUgdXNlZCBhcyBhbnkgb3RoZXIgYXNzZXJ0aW9uLlxuICpcbiAqICAgICBleHBlY3QobXlGb28pLnRvLmVxdWFsKCdiYXInKTtcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4IG9iamVjdCB3aG9zZSBtZXRob2QgaXMgdG8gYmUgb3ZlcndyaXR0ZW5cbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG9mIG1ldGhvZCB0byBvdmVyd3JpdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG1ldGhvZCBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBuYW1lXG4gKiBAbmFtZSBvdmVyd3JpdGVNZXRob2RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY3R4LCBuYW1lLCBtZXRob2QpIHtcbiAgdmFyIF9tZXRob2QgPSBjdHhbbmFtZV1cbiAgICAsIF9zdXBlciA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH07XG5cbiAgaWYgKF9tZXRob2QgJiYgJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIF9tZXRob2QpXG4gICAgX3N1cGVyID0gX21ldGhvZDtcblxuICBjdHhbbmFtZV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHJlc3VsdCA9IG1ldGhvZChfc3VwZXIpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gdGhpcyA6IHJlc3VsdDtcbiAgfVxufTtcbiIsIi8qIVxuICogQ2hhaSAtIG92ZXJ3cml0ZVByb3BlcnR5IHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMjIyBvdmVyd3JpdGVQcm9wZXJ0eSAoY3R4LCBuYW1lLCBmbilcbiAqXG4gKiBPdmVyd2l0ZXMgYW4gYWxyZWFkeSBleGlzdGluZyBwcm9wZXJ0eSBnZXR0ZXIgYW5kIHByb3ZpZGVzXG4gKiBhY2Nlc3MgdG8gcHJldmlvdXMgdmFsdWUuIE11c3QgcmV0dXJuIGZ1bmN0aW9uIHRvIHVzZSBhcyBnZXR0ZXIuXG4gKlxuICogICAgIHV0aWxzLm92ZXJ3cml0ZVByb3BlcnR5KGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgJ29rJywgZnVuY3Rpb24gKF9zdXBlcikge1xuICogICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAqICAgICAgICAgdmFyIG9iaiA9IHV0aWxzLmZsYWcodGhpcywgJ29iamVjdCcpO1xuICogICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgRm9vKSB7XG4gKiAgICAgICAgICAgbmV3IGNoYWkuQXNzZXJ0aW9uKG9iai5uYW1lKS50by5lcXVhbCgnYmFyJyk7XG4gKiAgICAgICAgIH0gZWxzZSB7XG4gKiAgICAgICAgICAgX3N1cGVyLmNhbGwodGhpcyk7XG4gKiAgICAgICAgIH1cbiAqICAgICAgIH1cbiAqICAgICB9KTtcbiAqXG4gKlxuICogQ2FuIGFsc28gYmUgYWNjZXNzZWQgZGlyZWN0bHkgZnJvbSBgY2hhaS5Bc3NlcnRpb25gLlxuICpcbiAqICAgICBjaGFpLkFzc2VydGlvbi5vdmVyd3JpdGVQcm9wZXJ0eSgnZm9vJywgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5iZS5vaztcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4IG9iamVjdCB3aG9zZSBwcm9wZXJ0eSBpcyB0byBiZSBvdmVyd3JpdHRlblxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgcHJvcGVydHkgdG8gb3ZlcndyaXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBnZXR0ZXIgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgZ2V0dGVyIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIG5hbWVcbiAqIEBuYW1lIG92ZXJ3cml0ZVByb3BlcnR5XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGN0eCwgbmFtZSwgZ2V0dGVyKSB7XG4gIHZhciBfZ2V0ID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihjdHgsIG5hbWUpXG4gICAgLCBfc3VwZXIgPSBmdW5jdGlvbiAoKSB7fTtcblxuICBpZiAoX2dldCAmJiAnZnVuY3Rpb24nID09PSB0eXBlb2YgX2dldC5nZXQpXG4gICAgX3N1cGVyID0gX2dldC5nZXRcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBuYW1lLFxuICAgIHsgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBnZXR0ZXIoX3N1cGVyKS5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgPyB0aGlzIDogcmVzdWx0O1xuICAgICAgfVxuICAgICwgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIHRlc3QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qIVxuICogTW9kdWxlIGRlcGVuZGFuY2llc1xuICovXG5cbnZhciBmbGFnID0gcmVxdWlyZSgnLi9mbGFnJyk7XG5cbi8qKlxuICogIyB0ZXN0KG9iamVjdCwgZXhwcmVzc2lvbilcbiAqXG4gKiBUZXN0IGFuZCBvYmplY3QgZm9yIGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCAoY29uc3RydWN0ZWQgQXNzZXJ0aW9uKVxuICogQHBhcmFtIHtBcmd1bWVudHN9IGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZS5hc3NlcnQgYXJndW1lbnRzXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqLCBhcmdzKSB7XG4gIHZhciBuZWdhdGUgPSBmbGFnKG9iaiwgJ25lZ2F0ZScpXG4gICAgLCBleHByID0gYXJnc1swXTtcbiAgcmV0dXJuIG5lZ2F0ZSA/ICFleHByIDogZXhwcjtcbn07XG4iLCIvKiFcbiAqIENoYWkgLSB0cmFuc2ZlckZsYWdzIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMjIyB0cmFuc2ZlckZsYWdzKGFzc2VydGlvbiwgb2JqZWN0LCBpbmNsdWRlQWxsID0gdHJ1ZSlcbiAqXG4gKiBUcmFuc2ZlciBhbGwgdGhlIGZsYWdzIGZvciBgYXNzZXJ0aW9uYCB0byBgb2JqZWN0YC4gSWZcbiAqIGBpbmNsdWRlQWxsYCBpcyBzZXQgdG8gYGZhbHNlYCwgdGhlbiB0aGUgYmFzZSBDaGFpXG4gKiBhc3NlcnRpb24gZmxhZ3MgKG5hbWVseSBgb2JqZWN0YCwgYHNzZmlgLCBhbmQgYG1lc3NhZ2VgKVxuICogd2lsbCBub3QgYmUgdHJhbnNmZXJyZWQuXG4gKlxuICpcbiAqICAgICB2YXIgbmV3QXNzZXJ0aW9uID0gbmV3IEFzc2VydGlvbigpO1xuICogICAgIHV0aWxzLnRyYW5zZmVyRmxhZ3MoYXNzZXJ0aW9uLCBuZXdBc3NlcnRpb24pO1xuICpcbiAqICAgICB2YXIgYW5vdGhlckFzc2VyaXRvbiA9IG5ldyBBc3NlcnRpb24obXlPYmopO1xuICogICAgIHV0aWxzLnRyYW5zZmVyRmxhZ3MoYXNzZXJ0aW9uLCBhbm90aGVyQXNzZXJ0aW9uLCBmYWxzZSk7XG4gKlxuICogQHBhcmFtIHtBc3NlcnRpb259IGFzc2VydGlvbiB0aGUgYXNzZXJ0aW9uIHRvIHRyYW5zZmVyIHRoZSBmbGFncyBmcm9tXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IHRoZSBvYmplY3QgdG8gdHJhbnNmZXIgdGhlIGZsYWdzIHRvbzsgdXN1YWxseSBhIG5ldyBhc3NlcnRpb25cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaW5jbHVkZUFsbFxuICogQG5hbWUgZ2V0QWxsRmxhZ3NcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGFzc2VydGlvbiwgb2JqZWN0LCBpbmNsdWRlQWxsKSB7XG4gIHZhciBmbGFncyA9IGFzc2VydGlvbi5fX2ZsYWdzIHx8IChhc3NlcnRpb24uX19mbGFncyA9IE9iamVjdC5jcmVhdGUobnVsbCkpO1xuXG4gIGlmICghb2JqZWN0Ll9fZmxhZ3MpIHtcbiAgICBvYmplY3QuX19mbGFncyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIH1cblxuICBpbmNsdWRlQWxsID0gYXJndW1lbnRzLmxlbmd0aCA9PT0gMyA/IGluY2x1ZGVBbGwgOiB0cnVlO1xuXG4gIGZvciAodmFyIGZsYWcgaW4gZmxhZ3MpIHtcbiAgICBpZiAoaW5jbHVkZUFsbCB8fFxuICAgICAgICAoZmxhZyAhPT0gJ29iamVjdCcgJiYgZmxhZyAhPT0gJ3NzZmknICYmIGZsYWcgIT0gJ21lc3NhZ2UnKSkge1xuICAgICAgb2JqZWN0Ll9fZmxhZ3NbZmxhZ10gPSBmbGFnc1tmbGFnXTtcbiAgICB9XG4gIH1cbn07XG4iLCIvKiFcbiAqIENoYWkgLSB0eXBlIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKiFcbiAqIERldGVjdGFibGUgamF2YXNjcmlwdCBuYXRpdmVzXG4gKi9cblxudmFyIG5hdGl2ZXMgPSB7XG4gICAgJ1tvYmplY3QgQXJndW1lbnRzXSc6ICdhcmd1bWVudHMnXG4gICwgJ1tvYmplY3QgQXJyYXldJzogJ2FycmF5J1xuICAsICdbb2JqZWN0IERhdGVdJzogJ2RhdGUnXG4gICwgJ1tvYmplY3QgRnVuY3Rpb25dJzogJ2Z1bmN0aW9uJ1xuICAsICdbb2JqZWN0IE51bWJlcl0nOiAnbnVtYmVyJ1xuICAsICdbb2JqZWN0IFJlZ0V4cF0nOiAncmVnZXhwJ1xuICAsICdbb2JqZWN0IFN0cmluZ10nOiAnc3RyaW5nJ1xufTtcblxuLyoqXG4gKiAjIyMgdHlwZShvYmplY3QpXG4gKlxuICogQmV0dGVyIGltcGxlbWVudGF0aW9uIG9mIGB0eXBlb2ZgIGRldGVjdGlvbiB0aGF0IGNhblxuICogYmUgdXNlZCBjcm9zcy1icm93c2VyLiBIYW5kbGVzIHRoZSBpbmNvbnNpc3RlbmNpZXMgb2ZcbiAqIEFycmF5LCBgbnVsbGAsIGFuZCBgdW5kZWZpbmVkYCBkZXRlY3Rpb24uXG4gKlxuICogICAgIHV0aWxzLnR5cGUoe30pIC8vICdvYmplY3QnXG4gKiAgICAgdXRpbHMudHlwZShudWxsKSAvLyBgbnVsbCdcbiAqICAgICB1dGlscy50eXBlKHVuZGVmaW5lZCkgLy8gYHVuZGVmaW5lZGBcbiAqICAgICB1dGlscy50eXBlKFtdKSAvLyBgYXJyYXlgXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0IHRvIGRldGVjdCB0eXBlIG9mXG4gKiBAbmFtZSB0eXBlXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIHN0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xuICBpZiAobmF0aXZlc1tzdHJdKSByZXR1cm4gbmF0aXZlc1tzdHJdO1xuICBpZiAob2JqID09PSBudWxsKSByZXR1cm4gJ251bGwnO1xuICBpZiAob2JqID09PSB1bmRlZmluZWQpIHJldHVybiAndW5kZWZpbmVkJztcbiAgaWYgKG9iaiA9PT0gT2JqZWN0KG9iaikpIHJldHVybiAnb2JqZWN0JztcbiAgcmV0dXJuIHR5cGVvZiBvYmo7XG59O1xuIiwiLyohXG4gKiBhc3NlcnRpb24tZXJyb3JcbiAqIENvcHlyaWdodChjKSAyMDEzIEpha2UgTHVlciA8amFrZUBxdWFsaWFuY3kuY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBSZXR1cm4gYSBmdW5jdGlvbiB0aGF0IHdpbGwgY29weSBwcm9wZXJ0aWVzIGZyb21cbiAqIG9uZSBvYmplY3QgdG8gYW5vdGhlciBleGNsdWRpbmcgYW55IG9yaWdpbmFsbHlcbiAqIGxpc3RlZC4gUmV0dXJuZWQgZnVuY3Rpb24gd2lsbCBjcmVhdGUgYSBuZXcgYHt9YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXhjbHVkZWQgcHJvcGVydGllcyAuLi5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5cbmZ1bmN0aW9uIGV4Y2x1ZGUgKCkge1xuICB2YXIgZXhjbHVkZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgZnVuY3Rpb24gZXhjbHVkZVByb3BzIChyZXMsIG9iaikge1xuICAgIE9iamVjdC5rZXlzKG9iaikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICBpZiAoIX5leGNsdWRlcy5pbmRleE9mKGtleSkpIHJlc1trZXldID0gb2JqW2tleV07XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gZXh0ZW5kRXhjbHVkZSAoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cylcbiAgICAgICwgaSA9IDBcbiAgICAgICwgcmVzID0ge307XG5cbiAgICBmb3IgKDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGV4Y2x1ZGVQcm9wcyhyZXMsIGFyZ3NbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH07XG59O1xuXG4vKiFcbiAqIFByaW1hcnkgRXhwb3J0c1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gQXNzZXJ0aW9uRXJyb3I7XG5cbi8qKlxuICogIyMjIEFzc2VydGlvbkVycm9yXG4gKlxuICogQW4gZXh0ZW5zaW9uIG9mIHRoZSBKYXZhU2NyaXB0IGBFcnJvcmAgY29uc3RydWN0b3IgZm9yXG4gKiBhc3NlcnRpb24gYW5kIHZhbGlkYXRpb24gc2NlbmFyaW9zLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyB0byBpbmNsdWRlIChvcHRpb25hbClcbiAqIEBwYXJhbSB7Y2FsbGVlfSBzdGFydCBzdGFjayBmdW5jdGlvbiAob3B0aW9uYWwpXG4gKi9cblxuZnVuY3Rpb24gQXNzZXJ0aW9uRXJyb3IgKG1lc3NhZ2UsIF9wcm9wcywgc3NmKSB7XG4gIHZhciBleHRlbmQgPSBleGNsdWRlKCduYW1lJywgJ21lc3NhZ2UnLCAnc3RhY2snLCAnY29uc3RydWN0b3InLCAndG9KU09OJylcbiAgICAsIHByb3BzID0gZXh0ZW5kKF9wcm9wcyB8fCB7fSk7XG5cbiAgLy8gZGVmYXVsdCB2YWx1ZXNcbiAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZSB8fCAnVW5zcGVjaWZpZWQgQXNzZXJ0aW9uRXJyb3InO1xuICB0aGlzLnNob3dEaWZmID0gZmFsc2U7XG5cbiAgLy8gY29weSBmcm9tIHByb3BlcnRpZXNcbiAgZm9yICh2YXIga2V5IGluIHByb3BzKSB7XG4gICAgdGhpc1trZXldID0gcHJvcHNba2V5XTtcbiAgfVxuXG4gIC8vIGNhcHR1cmUgc3RhY2sgdHJhY2VcbiAgc3NmID0gc3NmIHx8IGFyZ3VtZW50cy5jYWxsZWU7XG4gIGlmIChzc2YgJiYgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBzc2YpO1xuICB9XG59XG5cbi8qIVxuICogSW5oZXJpdCBmcm9tIEVycm9yLnByb3RvdHlwZVxuICovXG5cbkFzc2VydGlvbkVycm9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKTtcblxuLyohXG4gKiBTdGF0aWNhbGx5IHNldCBuYW1lXG4gKi9cblxuQXNzZXJ0aW9uRXJyb3IucHJvdG90eXBlLm5hbWUgPSAnQXNzZXJ0aW9uRXJyb3InO1xuXG4vKiFcbiAqIEVuc3VyZSBjb3JyZWN0IGNvbnN0cnVjdG9yXG4gKi9cblxuQXNzZXJ0aW9uRXJyb3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQXNzZXJ0aW9uRXJyb3I7XG5cbi8qKlxuICogQWxsb3cgZXJyb3JzIHRvIGJlIGNvbnZlcnRlZCB0byBKU09OIGZvciBzdGF0aWMgdHJhbnNmZXIuXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSBpbmNsdWRlIHN0YWNrIChkZWZhdWx0OiBgdHJ1ZWApXG4gKiBAcmV0dXJuIHtPYmplY3R9IG9iamVjdCB0aGF0IGNhbiBiZSBgSlNPTi5zdHJpbmdpZnlgXG4gKi9cblxuQXNzZXJ0aW9uRXJyb3IucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIChzdGFjaykge1xuICB2YXIgZXh0ZW5kID0gZXhjbHVkZSgnY29uc3RydWN0b3InLCAndG9KU09OJywgJ3N0YWNrJylcbiAgICAsIHByb3BzID0gZXh0ZW5kKHsgbmFtZTogdGhpcy5uYW1lIH0sIHRoaXMpO1xuXG4gIC8vIGluY2x1ZGUgc3RhY2sgaWYgZXhpc3RzIGFuZCBub3QgdHVybmVkIG9mZlxuICBpZiAoZmFsc2UgIT09IHN0YWNrICYmIHRoaXMuc3RhY2spIHtcbiAgICBwcm9wcy5zdGFjayA9IHRoaXMuc3RhY2s7XG4gIH1cblxuICByZXR1cm4gcHJvcHM7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9lcWwnKTtcbiIsIi8qIVxuICogZGVlcC1lcWxcbiAqIENvcHlyaWdodChjKSAyMDEzIEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzXG4gKi9cblxudmFyIHR5cGUgPSByZXF1aXJlKCd0eXBlLWRldGVjdCcpO1xuXG4vKiFcbiAqIEJ1ZmZlci5pc0J1ZmZlciBicm93c2VyIHNoaW1cbiAqL1xuXG52YXIgQnVmZmVyO1xudHJ5IHsgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyOyB9XG5jYXRjaChleCkge1xuICBCdWZmZXIgPSB7fTtcbiAgQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24oKSB7IHJldHVybiBmYWxzZTsgfVxufVxuXG4vKiFcbiAqIFByaW1hcnkgRXhwb3J0XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBkZWVwRXF1YWw7XG5cbi8qKlxuICogQXNzZXJ0IHN1cGVyLXN0cmljdCAoZWdhbCkgZXF1YWxpdHkgYmV0d2VlblxuICogdHdvIG9iamVjdHMgb2YgYW55IHR5cGUuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gYVxuICogQHBhcmFtIHtNaXhlZH0gYlxuICogQHBhcmFtIHtBcnJheX0gbWVtb2lzZWQgKG9wdGlvbmFsKVxuICogQHJldHVybiB7Qm9vbGVhbn0gZXF1YWwgbWF0Y2hcbiAqL1xuXG5mdW5jdGlvbiBkZWVwRXF1YWwoYSwgYiwgbSkge1xuICBpZiAoc2FtZVZhbHVlKGEsIGIpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAoJ2RhdGUnID09PSB0eXBlKGEpKSB7XG4gICAgcmV0dXJuIGRhdGVFcXVhbChhLCBiKTtcbiAgfSBlbHNlIGlmICgncmVnZXhwJyA9PT0gdHlwZShhKSkge1xuICAgIHJldHVybiByZWdleHBFcXVhbChhLCBiKTtcbiAgfSBlbHNlIGlmIChCdWZmZXIuaXNCdWZmZXIoYSkpIHtcbiAgICByZXR1cm4gYnVmZmVyRXF1YWwoYSwgYik7XG4gIH0gZWxzZSBpZiAoJ2FyZ3VtZW50cycgPT09IHR5cGUoYSkpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzRXF1YWwoYSwgYiwgbSk7XG4gIH0gZWxzZSBpZiAoIXR5cGVFcXVhbChhLCBiKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSBlbHNlIGlmICgoJ29iamVjdCcgIT09IHR5cGUoYSkgJiYgJ29iamVjdCcgIT09IHR5cGUoYikpXG4gICYmICgnYXJyYXknICE9PSB0eXBlKGEpICYmICdhcnJheScgIT09IHR5cGUoYikpKSB7XG4gICAgcmV0dXJuIHNhbWVWYWx1ZShhLCBiKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gb2JqZWN0RXF1YWwoYSwgYiwgbSk7XG4gIH1cbn1cblxuLyohXG4gKiBTdHJpY3QgKGVnYWwpIGVxdWFsaXR5IHRlc3QuIEVuc3VyZXMgdGhhdCBOYU4gYWx3YXlzXG4gKiBlcXVhbHMgTmFOIGFuZCBgLTBgIGRvZXMgbm90IGVxdWFsIGArMGAuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gYVxuICogQHBhcmFtIHtNaXhlZH0gYlxuICogQHJldHVybiB7Qm9vbGVhbn0gZXF1YWwgbWF0Y2hcbiAqL1xuXG5mdW5jdGlvbiBzYW1lVmFsdWUoYSwgYikge1xuICBpZiAoYSA9PT0gYikgcmV0dXJuIGEgIT09IDAgfHwgMSAvIGEgPT09IDEgLyBiO1xuICByZXR1cm4gYSAhPT0gYSAmJiBiICE9PSBiO1xufVxuXG4vKiFcbiAqIENvbXBhcmUgdGhlIHR5cGVzIG9mIHR3byBnaXZlbiBvYmplY3RzIGFuZFxuICogcmV0dXJuIGlmIHRoZXkgYXJlIGVxdWFsLiBOb3RlIHRoYXQgYW4gQXJyYXlcbiAqIGhhcyBhIHR5cGUgb2YgYGFycmF5YCAobm90IGBvYmplY3RgKSBhbmQgYXJndW1lbnRzXG4gKiBoYXZlIGEgdHlwZSBvZiBgYXJndW1lbnRzYCAobm90IGBhcnJheWAvYG9iamVjdGApLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IGFcbiAqIEBwYXJhbSB7TWl4ZWR9IGJcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHJlc3VsdFxuICovXG5cbmZ1bmN0aW9uIHR5cGVFcXVhbChhLCBiKSB7XG4gIHJldHVybiB0eXBlKGEpID09PSB0eXBlKGIpO1xufVxuXG4vKiFcbiAqIENvbXBhcmUgdHdvIERhdGUgb2JqZWN0cyBieSBhc3NlcnRpbmcgdGhhdFxuICogdGhlIHRpbWUgdmFsdWVzIGFyZSBlcXVhbCB1c2luZyBgc2F2ZVZhbHVlYC5cbiAqXG4gKiBAcGFyYW0ge0RhdGV9IGFcbiAqIEBwYXJhbSB7RGF0ZX0gYlxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gZGF0ZUVxdWFsKGEsIGIpIHtcbiAgaWYgKCdkYXRlJyAhPT0gdHlwZShiKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gc2FtZVZhbHVlKGEuZ2V0VGltZSgpLCBiLmdldFRpbWUoKSk7XG59XG5cbi8qIVxuICogQ29tcGFyZSB0d28gcmVndWxhciBleHByZXNzaW9ucyBieSBjb252ZXJ0aW5nIHRoZW1cbiAqIHRvIHN0cmluZyBhbmQgY2hlY2tpbmcgZm9yIGBzYW1lVmFsdWVgLlxuICpcbiAqIEBwYXJhbSB7UmVnRXhwfSBhXG4gKiBAcGFyYW0ge1JlZ0V4cH0gYlxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gcmVnZXhwRXF1YWwoYSwgYikge1xuICBpZiAoJ3JlZ2V4cCcgIT09IHR5cGUoYikpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHNhbWVWYWx1ZShhLnRvU3RyaW5nKCksIGIudG9TdHJpbmcoKSk7XG59XG5cbi8qIVxuICogQXNzZXJ0IGRlZXAgZXF1YWxpdHkgb2YgdHdvIGBhcmd1bWVudHNgIG9iamVjdHMuXG4gKiBVbmZvcnR1bmF0ZWx5LCB0aGVzZSBtdXN0IGJlIHNsaWNlZCB0byBhcnJheXNcbiAqIHByaW9yIHRvIHRlc3QgdG8gZW5zdXJlIG5vIGJhZCBiZWhhdmlvci5cbiAqXG4gKiBAcGFyYW0ge0FyZ3VtZW50c30gYVxuICogQHBhcmFtIHtBcmd1bWVudHN9IGJcbiAqIEBwYXJhbSB7QXJyYXl9IG1lbW9pemUgKG9wdGlvbmFsKVxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gYXJndW1lbnRzRXF1YWwoYSwgYiwgbSkge1xuICBpZiAoJ2FyZ3VtZW50cycgIT09IHR5cGUoYikpIHJldHVybiBmYWxzZTtcbiAgYSA9IFtdLnNsaWNlLmNhbGwoYSk7XG4gIGIgPSBbXS5zbGljZS5jYWxsKGIpO1xuICByZXR1cm4gZGVlcEVxdWFsKGEsIGIsIG0pO1xufVxuXG4vKiFcbiAqIEdldCBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb2YgYSBnaXZlbiBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGFcbiAqIEByZXR1cm4ge0FycmF5fSBwcm9wZXJ0eSBuYW1lc1xuICovXG5cbmZ1bmN0aW9uIGVudW1lcmFibGUoYSkge1xuICB2YXIgcmVzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBhKSByZXMucHVzaChrZXkpO1xuICByZXR1cm4gcmVzO1xufVxuXG4vKiFcbiAqIFNpbXBsZSBlcXVhbGl0eSBmb3IgZmxhdCBpdGVyYWJsZSBvYmplY3RzXG4gKiBzdWNoIGFzIEFycmF5cyBvciBOb2RlLmpzIGJ1ZmZlcnMuXG4gKlxuICogQHBhcmFtIHtJdGVyYWJsZX0gYVxuICogQHBhcmFtIHtJdGVyYWJsZX0gYlxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gaXRlcmFibGVFcXVhbChhLCBiKSB7XG4gIGlmIChhLmxlbmd0aCAhPT0gIGIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGkgPSAwO1xuICB2YXIgbWF0Y2ggPSB0cnVlO1xuXG4gIGZvciAoOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICBtYXRjaCA9IGZhbHNlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1hdGNoO1xufVxuXG4vKiFcbiAqIEV4dGVuc2lvbiB0byBgaXRlcmFibGVFcXVhbGAgc3BlY2lmaWNhbGx5XG4gKiBmb3IgTm9kZS5qcyBCdWZmZXJzLlxuICpcbiAqIEBwYXJhbSB7QnVmZmVyfSBhXG4gKiBAcGFyYW0ge01peGVkfSBiXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiBidWZmZXJFcXVhbChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBpdGVyYWJsZUVxdWFsKGEsIGIpO1xufVxuXG4vKiFcbiAqIEJsb2NrIGZvciBgb2JqZWN0RXF1YWxgIGVuc3VyaW5nIG5vbi1leGlzdGluZ1xuICogdmFsdWVzIGRvbid0IGdldCBpbi5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBvYmplY3RcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHJlc3VsdFxuICovXG5cbmZ1bmN0aW9uIGlzVmFsdWUoYSkge1xuICByZXR1cm4gYSAhPT0gbnVsbCAmJiBhICE9PSB1bmRlZmluZWQ7XG59XG5cbi8qIVxuICogUmVjdXJzaXZlbHkgY2hlY2sgdGhlIGVxdWFsaXR5IG9mIHR3byBvYmplY3RzLlxuICogT25jZSBiYXNpYyBzYW1lbmVzcyBoYXMgYmVlbiBlc3RhYmxpc2hlZCBpdCB3aWxsXG4gKiBkZWZlciB0byBgZGVlcEVxdWFsYCBmb3IgZWFjaCBlbnVtZXJhYmxlIGtleVxuICogaW4gdGhlIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBhXG4gKiBAcGFyYW0ge01peGVkfSBiXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiBvYmplY3RFcXVhbChhLCBiLCBtKSB7XG4gIGlmICghaXNWYWx1ZShhKSB8fCAhaXNWYWx1ZShiKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChhLnByb3RvdHlwZSAhPT0gYi5wcm90b3R5cGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgaTtcbiAgaWYgKG0pIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKChtW2ldWzBdID09PSBhICYmIG1baV1bMV0gPT09IGIpXG4gICAgICB8fCAgKG1baV1bMF0gPT09IGIgJiYgbVtpXVsxXSA9PT0gYSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIG0gPSBbXTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgdmFyIGthID0gZW51bWVyYWJsZShhKTtcbiAgICB2YXIga2IgPSBlbnVtZXJhYmxlKGIpO1xuICB9IGNhdGNoIChleCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGthLnNvcnQoKTtcbiAga2Iuc29ydCgpO1xuXG4gIGlmICghaXRlcmFibGVFcXVhbChrYSwga2IpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgbS5wdXNoKFsgYSwgYiBdKTtcblxuICB2YXIga2V5O1xuICBmb3IgKGkgPSBrYS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGtleSA9IGthW2ldO1xuICAgIGlmICghZGVlcEVxdWFsKGFba2V5XSwgYltrZXldLCBtKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi90eXBlJyk7XG4iLCIvKiFcbiAqIHR5cGUtZGV0ZWN0XG4gKiBDb3B5cmlnaHQoYykgMjAxMyBqYWtlIGx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qIVxuICogUHJpbWFyeSBFeHBvcnRzXG4gKi9cblxudmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGdldFR5cGU7XG5cbi8qIVxuICogRGV0ZWN0YWJsZSBqYXZhc2NyaXB0IG5hdGl2ZXNcbiAqL1xuXG52YXIgbmF0aXZlcyA9IHtcbiAgICAnW29iamVjdCBBcnJheV0nOiAnYXJyYXknXG4gICwgJ1tvYmplY3QgUmVnRXhwXSc6ICdyZWdleHAnXG4gICwgJ1tvYmplY3QgRnVuY3Rpb25dJzogJ2Z1bmN0aW9uJ1xuICAsICdbb2JqZWN0IEFyZ3VtZW50c10nOiAnYXJndW1lbnRzJ1xuICAsICdbb2JqZWN0IERhdGVdJzogJ2RhdGUnXG59O1xuXG4vKipcbiAqICMjIyB0eXBlT2YgKG9iailcbiAqXG4gKiBVc2Ugc2V2ZXJhbCBkaWZmZXJlbnQgdGVjaG5pcXVlcyB0byBkZXRlcm1pbmVcbiAqIHRoZSB0eXBlIG9mIG9iamVjdCBiZWluZyB0ZXN0ZWQuXG4gKlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICogQHJldHVybiB7U3RyaW5nfSBvYmplY3QgdHlwZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBnZXRUeXBlIChvYmopIHtcbiAgdmFyIHN0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xuICBpZiAobmF0aXZlc1tzdHJdKSByZXR1cm4gbmF0aXZlc1tzdHJdO1xuICBpZiAob2JqID09PSBudWxsKSByZXR1cm4gJ251bGwnO1xuICBpZiAob2JqID09PSB1bmRlZmluZWQpIHJldHVybiAndW5kZWZpbmVkJztcbiAgaWYgKG9iaiA9PT0gT2JqZWN0KG9iaikpIHJldHVybiAnb2JqZWN0JztcbiAgcmV0dXJuIHR5cGVvZiBvYmo7XG59XG5cbmV4cG9ydHMuTGlicmFyeSA9IExpYnJhcnk7XG5cbi8qKlxuICogIyMjIExpYnJhcnlcbiAqXG4gKiBDcmVhdGUgYSByZXBvc2l0b3J5IGZvciBjdXN0b20gdHlwZSBkZXRlY3Rpb24uXG4gKlxuICogYGBganNcbiAqIHZhciBsaWIgPSBuZXcgdHlwZS5MaWJyYXJ5O1xuICogYGBgXG4gKlxuICovXG5cbmZ1bmN0aW9uIExpYnJhcnkgKCkge1xuICB0aGlzLnRlc3RzID0ge307XG59XG5cbi8qKlxuICogIyMjIyAub2YgKG9iailcbiAqXG4gKiBFeHBvc2UgcmVwbGFjZW1lbnQgYHR5cGVvZmAgZGV0ZWN0aW9uIHRvIHRoZSBsaWJyYXJ5LlxuICpcbiAqIGBgYGpzXG4gKiBpZiAoJ3N0cmluZycgPT09IGxpYi5vZignaGVsbG8gd29ybGQnKSkge1xuICogICAvLyAuLi5cbiAqIH1cbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdCB0byB0ZXN0XG4gKiBAcmV0dXJuIHtTdHJpbmd9IHR5cGVcbiAqL1xuXG5MaWJyYXJ5LnByb3RvdHlwZS5vZiA9IGdldFR5cGU7XG5cbi8qKlxuICogIyMjIyAuZGVmaW5lICh0eXBlLCB0ZXN0KVxuICpcbiAqIEFkZCBhIHRlc3QgdG8gZm9yIHRoZSBgLnRlc3QoKWAgYXNzZXJ0aW9uLlxuICpcbiAqIENhbiBiZSBkZWZpbmVkIGFzIGEgcmVndWxhciBleHByZXNzaW9uOlxuICpcbiAqIGBgYGpzXG4gKiBsaWIuZGVmaW5lKCdpbnQnLCAvXlswLTldKyQvKTtcbiAqIGBgYFxuICpcbiAqIC4uLiBvciBhcyBhIGZ1bmN0aW9uOlxuICpcbiAqIGBgYGpzXG4gKiBsaWIuZGVmaW5lKCdibG4nLCBmdW5jdGlvbiAob2JqKSB7XG4gKiAgIGlmICgnYm9vbGVhbicgPT09IGxpYi5vZihvYmopKSByZXR1cm4gdHJ1ZTtcbiAqICAgdmFyIGJsbnMgPSBbICd5ZXMnLCAnbm8nLCAndHJ1ZScsICdmYWxzZScsIDEsIDAgXTtcbiAqICAgaWYgKCdzdHJpbmcnID09PSBsaWIub2Yob2JqKSkgb2JqID0gb2JqLnRvTG93ZXJDYXNlKCk7XG4gKiAgIHJldHVybiAhISB+Ymxucy5pbmRleE9mKG9iaik7XG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge1JlZ0V4cHxGdW5jdGlvbn0gdGVzdFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5MaWJyYXJ5LnByb3RvdHlwZS5kZWZpbmUgPSBmdW5jdGlvbiAodHlwZSwgdGVzdCkge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHRoaXMudGVzdHNbdHlwZV07XG4gIHRoaXMudGVzdHNbdHlwZV0gPSB0ZXN0O1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogIyMjIyAudGVzdCAob2JqLCB0ZXN0KVxuICpcbiAqIEFzc2VydCB0aGF0IGFuIG9iamVjdCBpcyBvZiB0eXBlLiBXaWxsIGZpcnN0XG4gKiBjaGVjayBuYXRpdmVzLCBhbmQgaWYgdGhhdCBkb2VzIG5vdCBwYXNzIGl0IHdpbGxcbiAqIHVzZSB0aGUgdXNlciBkZWZpbmVkIGN1c3RvbSB0ZXN0cy5cbiAqXG4gKiBgYGBqc1xuICogYXNzZXJ0KGxpYi50ZXN0KCcxJywgJ2ludCcpKTtcbiAqIGFzc2VydChsaWIudGVzdCgneWVzJywgJ2JsbicpKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHJlc3VsdFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5MaWJyYXJ5LnByb3RvdHlwZS50ZXN0ID0gZnVuY3Rpb24gKG9iaiwgdHlwZSkge1xuICBpZiAodHlwZSA9PT0gZ2V0VHlwZShvYmopKSByZXR1cm4gdHJ1ZTtcbiAgdmFyIHRlc3QgPSB0aGlzLnRlc3RzW3R5cGVdO1xuXG4gIGlmICh0ZXN0ICYmICdyZWdleHAnID09PSBnZXRUeXBlKHRlc3QpKSB7XG4gICAgcmV0dXJuIHRlc3QudGVzdChvYmopO1xuICB9IGVsc2UgaWYgKHRlc3QgJiYgJ2Z1bmN0aW9uJyA9PT0gZ2V0VHlwZSh0ZXN0KSkge1xuICAgIHJldHVybiB0ZXN0KG9iaik7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCdUeXBlIHRlc3QgXCInICsgdHlwZSArICdcIiBub3QgZGVmaW5lZCBvciBpbnZhbGlkLicpO1xuICB9XG59O1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjYuM1xudmFyIGNvZmZlZSwgY29tcGlsZSwgY29tcGlsZUZpbGUsIGV4dCwgZXh0ZW5zaW9ucywgZm9ybWF0U291cmNlUG9zaXRpb24sIGZzLCBnZXRTb3VyY2VNYXAsIGhlbHBlcnMsIGxvYWRGaWxlLCBwYXRjaFN0YWNrVHJhY2UsIHBhdGNoZWQsIHBhdGgsIHNvdXJjZU1hcHMsIF9pLCBfbGVuLFxuICBfX2luZGV4T2YgPSBbXS5pbmRleE9mIHx8IGZ1bmN0aW9uKGl0ZW0pIHsgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLmxlbmd0aDsgaSA8IGw7IGkrKykgeyBpZiAoaSBpbiB0aGlzICYmIHRoaXNbaV0gPT09IGl0ZW0pIHJldHVybiBpOyB9IHJldHVybiAtMTsgfTtcblxuZnMgPSByZXF1aXJlKCdmcycpO1xuXG5wYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuXG5oZWxwZXJzID0gcmVxdWlyZSgnY29mZmVlLXNjcmlwdC9saWIvY29mZmVlLXNjcmlwdC9oZWxwZXJzJyk7XG5cbmNvZmZlZSA9IHJlcXVpcmUoJ2NvZmZlZS1zY3JpcHQnKTtcblxuaWYgKHBhcnNlSW50KGNvZmZlZS5WRVJTSU9OLnJlcGxhY2UoL1xcRCsvZywgJycpKSA8IDE2Mikge1xuICB0aHJvdyBuZXcgRXJyb3IoJ2Bjb2ZmZWUtZXJyb3JzYCBleHBlY3RzIGBjb2ZmZWUtc2NyaXB0QH4xLjYuMmAnKTtcbn1cblxuY29tcGlsZSA9IGNvZmZlZS5jb21waWxlO1xuXG5wYXRjaGVkID0gZmFsc2U7XG5cbmV4dGVuc2lvbnMgPSBbJy5jb2ZmZWUnLCAnLmxpdGNvZmZlZScsICcuY29mZmVlLm1kJ107XG5cbnNvdXJjZU1hcHMgPSB7fTtcblxucGF0Y2hTdGFja1RyYWNlID0gZnVuY3Rpb24oKSB7XG4gIHZhciBvbGRQcmVwYXJlU3RhY2tUcmFjaztcbiAgaWYgKHBhdGNoZWQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcGF0Y2hlZCA9IHRydWU7XG4gIG9sZFByZXBhcmVTdGFja1RyYWNrID0gRXJyb3IucHJlcGFyZVN0YWNrVHJhY2U7XG4gIHJldHVybiBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IGZ1bmN0aW9uKGVyciwgc3RhY2spIHtcbiAgICB2YXIgZSwgZnJhbWUsIGZyYW1lcywgZ2V0U291cmNlTWFwcGluZywgc291cmNlRmlsZXMsIF9yZWY7XG4gICAgdHJ5IHtcbiAgICAgIHNvdXJjZUZpbGVzID0ge307XG4gICAgICBnZXRTb3VyY2VNYXBwaW5nID0gZnVuY3Rpb24oZmlsZW5hbWUsIGxpbmUsIGNvbHVtbikge1xuICAgICAgICB2YXIgYW5zd2VyLCBzb3VyY2VNYXA7XG4gICAgICAgIHNvdXJjZU1hcCA9IGdldFNvdXJjZU1hcChmaWxlbmFtZSk7XG4gICAgICAgIGlmIChzb3VyY2VNYXApIHtcbiAgICAgICAgICBhbnN3ZXIgPSBzb3VyY2VNYXAuc291cmNlTG9jYXRpb24oW2xpbmUgLSAxLCBjb2x1bW4gLSAxXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFuc3dlcikge1xuICAgICAgICAgIHJldHVybiBbYW5zd2VyWzBdICsgMSwgYW5zd2VyWzFdICsgMV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBmcmFtZXMgPSAoZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBfaSwgX2xlbiwgX3Jlc3VsdHM7XG4gICAgICAgIF9yZXN1bHRzID0gW107XG4gICAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gc3RhY2subGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgICBmcmFtZSA9IHN0YWNrW19pXTtcbiAgICAgICAgICBpZiAoZnJhbWUuZ2V0RnVuY3Rpb24oKSA9PT0gY29mZmVlLnJ1bikge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIF9yZXN1bHRzLnB1c2goXCIgIGF0IFwiICsgKGZvcm1hdFNvdXJjZVBvc2l0aW9uKGZyYW1lLCBnZXRTb3VyY2VNYXBwaW5nKSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfcmVzdWx0cztcbiAgICAgIH0pKCk7XG4gICAgICByZXR1cm4gXCJcIiArIGVyci5uYW1lICsgXCI6IFwiICsgKChfcmVmID0gZXJyLm1lc3NhZ2UpICE9IG51bGwgPyBfcmVmIDogJycpICsgXCJcXG5cIiArIChmcmFtZXMuam9pbignXFxuJykpICsgXCJcXG5cIjtcbiAgICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICAgIGUgPSBfZXJyb3I7XG4gICAgICBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IG9sZFByZXBhcmVTdGFja1RyYWNrO1xuICAgICAgXCJgY29mZmVlLWVycm9yc2AgZmFpbGVkIGR1cmluZyBzdGFjayBwYXJzaW5nLCBmYWxsaW5nIGJhY2sgb250byB0aGUgcHJldmlvdXMgcGFyc2VyLiBcIiArIGVyci5zdGFjaztcbiAgICAgIHJldHVybiBlcnIuc3RhY2s7XG4gICAgfVxuICB9O1xufTtcblxuZm9ybWF0U291cmNlUG9zaXRpb24gPSBmdW5jdGlvbihmcmFtZSwgZ2V0U291cmNlTWFwcGluZykge1xuICB2YXIgYXMsIGNvbHVtbiwgZmlsZUxvY2F0aW9uLCBmaWxlTmFtZSwgZnVuY3Rpb25OYW1lLCBpc0NvbnN0cnVjdG9yLCBpc01ldGhvZENhbGwsIGxpbmUsIG1ldGhvZE5hbWUsIHNvdXJjZSwgdHAsIHR5cGVOYW1lO1xuICBmaWxlTmFtZSA9IHZvaWQgMDtcbiAgZmlsZUxvY2F0aW9uID0gJyc7XG4gIGlmIChmcmFtZS5pc05hdGl2ZSgpKSB7XG4gICAgZmlsZUxvY2F0aW9uID0gXCJuYXRpdmVcIjtcbiAgfSBlbHNlIHtcbiAgICBpZiAoZnJhbWUuaXNFdmFsKCkpIHtcbiAgICAgIGZpbGVOYW1lID0gZnJhbWUuZ2V0U2NyaXB0TmFtZU9yU291cmNlVVJMKCk7XG4gICAgICBpZiAoIWZpbGVOYW1lKSB7XG4gICAgICAgIGZpbGVMb2NhdGlvbiA9IFwiXCIgKyAoZnJhbWUuZ2V0RXZhbE9yaWdpbigpKSArIFwiLCBcIjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZmlsZU5hbWUgPSBmcmFtZS5nZXRGaWxlTmFtZSgpO1xuICAgIH1cbiAgICBmaWxlTmFtZSB8fCAoZmlsZU5hbWUgPSBcIjxhbm9ueW1vdXM+XCIpO1xuICAgIGxpbmUgPSBmcmFtZS5nZXRMaW5lTnVtYmVyKCk7XG4gICAgY29sdW1uID0gZnJhbWUuZ2V0Q29sdW1uTnVtYmVyKCk7XG4gICAgc291cmNlID0gZ2V0U291cmNlTWFwcGluZyhmaWxlTmFtZSwgbGluZSwgY29sdW1uKTtcbiAgICBmaWxlTG9jYXRpb24gPSBzb3VyY2UgPyBcIlwiICsgZmlsZU5hbWUgKyBcIjpcIiArIHNvdXJjZVswXSArIFwiOlwiICsgc291cmNlWzFdIDogXCJcIiArIGZpbGVOYW1lICsgXCI6XCIgKyBsaW5lICsgXCI6XCIgKyBjb2x1bW47XG4gIH1cbiAgZnVuY3Rpb25OYW1lID0gZnJhbWUuZ2V0RnVuY3Rpb25OYW1lKCk7XG4gIGlzQ29uc3RydWN0b3IgPSBmcmFtZS5pc0NvbnN0cnVjdG9yKCk7XG4gIGlzTWV0aG9kQ2FsbCA9ICEoZnJhbWUuaXNUb3BsZXZlbCgpIHx8IGlzQ29uc3RydWN0b3IpO1xuICBpZiAoaXNNZXRob2RDYWxsKSB7XG4gICAgbWV0aG9kTmFtZSA9IGZyYW1lLmdldE1ldGhvZE5hbWUoKTtcbiAgICB0eXBlTmFtZSA9IGZyYW1lLmdldFR5cGVOYW1lKCk7XG4gICAgaWYgKGZ1bmN0aW9uTmFtZSkge1xuICAgICAgdHAgPSBhcyA9ICcnO1xuICAgICAgaWYgKHR5cGVOYW1lICYmIGZ1bmN0aW9uTmFtZS5pbmRleE9mKHR5cGVOYW1lKSkge1xuICAgICAgICB0cCA9IFwiXCIgKyB0eXBlTmFtZSArIFwiLlwiO1xuICAgICAgfVxuICAgICAgaWYgKG1ldGhvZE5hbWUgJiYgZnVuY3Rpb25OYW1lLmluZGV4T2YoXCIuXCIgKyBtZXRob2ROYW1lKSAhPT0gZnVuY3Rpb25OYW1lLmxlbmd0aCAtIG1ldGhvZE5hbWUubGVuZ3RoIC0gMSkge1xuICAgICAgICBhcyA9IFwiIFthcyBcIiArIG1ldGhvZE5hbWUgKyBcIl1cIjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBcIlwiICsgdHAgKyBmdW5jdGlvbk5hbWUgKyBhcyArIFwiIChcIiArIGZpbGVMb2NhdGlvbiArIFwiKVwiO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gXCJcIiArIHR5cGVOYW1lICsgXCIuXCIgKyAobWV0aG9kTmFtZSB8fCAnPGFub255bW91cz4nKSArIFwiIChcIiArIGZpbGVMb2NhdGlvbiArIFwiKVwiO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc0NvbnN0cnVjdG9yKSB7XG4gICAgcmV0dXJuIFwibmV3IFwiICsgKGZ1bmN0aW9uTmFtZSB8fCAnPGFub255bW91cz4nKSArIFwiIChcIiArIGZpbGVMb2NhdGlvbiArIFwiKVwiO1xuICB9IGVsc2UgaWYgKGZ1bmN0aW9uTmFtZSkge1xuICAgIHJldHVybiBcIlwiICsgZnVuY3Rpb25OYW1lICsgXCIgKFwiICsgZmlsZUxvY2F0aW9uICsgXCIpXCI7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZpbGVMb2NhdGlvbjtcbiAgfVxufTtcblxuY29tcGlsZUZpbGUgPSBmdW5jdGlvbihmaWxlbmFtZSwgc291cmNlTWFwKSB7XG4gIHZhciBhbnN3ZXIsIGVyciwgcmF3LCBzdHJpcHBlZDtcbiAgcmF3ID0gZnMucmVhZEZpbGVTeW5jKGZpbGVuYW1lLCAndXRmOCcpO1xuICBzdHJpcHBlZCA9IHJhdy5jaGFyQ29kZUF0KDApID09PSAweEZFRkYgPyByYXcuc3Vic3RyaW5nKDEpIDogcmF3O1xuICB0cnkge1xuICAgIGFuc3dlciA9IGNvbXBpbGUoc3RyaXBwZWQsIHtcbiAgICAgIGZpbGVuYW1lOiBmaWxlbmFtZSxcbiAgICAgIHNvdXJjZU1hcDogc291cmNlTWFwLFxuICAgICAgbGl0ZXJhdGU6IGhlbHBlcnMuaXNMaXRlcmF0ZShmaWxlbmFtZSlcbiAgICB9KTtcbiAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgZXJyID0gX2Vycm9yO1xuICAgIGVyci5maWxlbmFtZSA9IGZpbGVuYW1lO1xuICAgIGVyci5jb2RlID0gc3RyaXBwZWQ7XG4gICAgdGhyb3cgZXJyO1xuICB9XG4gIHJldHVybiBhbnN3ZXI7XG59O1xuXG5nZXRTb3VyY2VNYXAgPSBmdW5jdGlvbihmaWxlbmFtZSkge1xuICB2YXIgYW5zd2VyLCBfcmVmO1xuICBpZiAoc291cmNlTWFwc1tmaWxlbmFtZV0pIHtcbiAgICByZXR1cm4gc291cmNlTWFwc1tmaWxlbmFtZV07XG4gIH1cbiAgaWYgKF9yZWYgPSBwYXRoLmV4dG5hbWUoZmlsZW5hbWUpLCBfX2luZGV4T2YuY2FsbChleHRlbnNpb25zLCBfcmVmKSA8IDApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgYW5zd2VyID0gY29tcGlsZUZpbGUoZmlsZW5hbWUsIHRydWUpO1xuICByZXR1cm4gc291cmNlTWFwc1tmaWxlbmFtZV0gPSBhbnN3ZXIuc291cmNlTWFwO1xufTtcblxubG9hZEZpbGUgPSBmdW5jdGlvbihtb2R1bGUsIGZpbGVuYW1lKSB7XG4gIHZhciBhbnN3ZXI7XG4gIGFuc3dlciA9IGNvbXBpbGVGaWxlKGZpbGVuYW1lLCBmYWxzZSk7XG4gIHJldHVybiBtb2R1bGUuX2NvbXBpbGUoYW5zd2VyLCBmaWxlbmFtZSk7XG59O1xuXG5pZiAocmVxdWlyZS5leHRlbnNpb25zKSB7XG4gIGZvciAoX2kgPSAwLCBfbGVuID0gZXh0ZW5zaW9ucy5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgIGV4dCA9IGV4dGVuc2lvbnNbX2ldO1xuICAgIHJlcXVpcmUuZXh0ZW5zaW9uc1tleHRdID0gbG9hZEZpbGU7XG4gIH1cbn1cblxucGF0Y2hTdGFja1RyYWNlKCk7XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsKXtcbi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS44LjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIExleGVyLCBTb3VyY2VNYXAsIGNvbXBpbGUsIGV4dCwgZm9ybWF0U291cmNlUG9zaXRpb24sIGZzLCBnZXRTb3VyY2VNYXAsIGhlbHBlcnMsIGxleGVyLCBwYXJzZXIsIHBhdGgsIHNvdXJjZU1hcHMsIHZtLCB3aXRoUHJldHR5RXJyb3JzLCBfYmFzZSwgX2ksIF9sZW4sIF9yZWYsXG4gICAgX19oYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgX19pbmRleE9mID0gW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH07XG5cbiAgZnMgPSByZXF1aXJlKCdmcycpO1xuXG4gIHZtID0gcmVxdWlyZSgndm0nKTtcblxuICBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuXG4gIExleGVyID0gcmVxdWlyZSgnLi9sZXhlcicpLkxleGVyO1xuXG4gIHBhcnNlciA9IHJlcXVpcmUoJy4vcGFyc2VyJykucGFyc2VyO1xuXG4gIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcblxuICBTb3VyY2VNYXAgPSByZXF1aXJlKCcuL3NvdXJjZW1hcCcpO1xuXG4gIGV4cG9ydHMuVkVSU0lPTiA9ICcxLjguMCc7XG5cbiAgZXhwb3J0cy5GSUxFX0VYVEVOU0lPTlMgPSBbJy5jb2ZmZWUnLCAnLmxpdGNvZmZlZScsICcuY29mZmVlLm1kJ107XG5cbiAgZXhwb3J0cy5oZWxwZXJzID0gaGVscGVycztcblxuICB3aXRoUHJldHR5RXJyb3JzID0gZnVuY3Rpb24oZm4pIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oY29kZSwgb3B0aW9ucykge1xuICAgICAgdmFyIGVycjtcbiAgICAgIGlmIChvcHRpb25zID09IG51bGwpIHtcbiAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGZuLmNhbGwodGhpcywgY29kZSwgb3B0aW9ucyk7XG4gICAgICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICAgICAgZXJyID0gX2Vycm9yO1xuICAgICAgICB0aHJvdyBoZWxwZXJzLnVwZGF0ZVN5bnRheEVycm9yKGVyciwgY29kZSwgb3B0aW9ucy5maWxlbmFtZSk7XG4gICAgICB9XG4gICAgfTtcbiAgfTtcblxuICBleHBvcnRzLmNvbXBpbGUgPSBjb21waWxlID0gd2l0aFByZXR0eUVycm9ycyhmdW5jdGlvbihjb2RlLCBvcHRpb25zKSB7XG4gICAgdmFyIGFuc3dlciwgY3VycmVudENvbHVtbiwgY3VycmVudExpbmUsIGV4dGVuZCwgZnJhZ21lbnQsIGZyYWdtZW50cywgaGVhZGVyLCBqcywgbWFwLCBtZXJnZSwgbmV3TGluZXMsIF9pLCBfbGVuO1xuICAgIG1lcmdlID0gaGVscGVycy5tZXJnZSwgZXh0ZW5kID0gaGVscGVycy5leHRlbmQ7XG4gICAgb3B0aW9ucyA9IGV4dGVuZCh7fSwgb3B0aW9ucyk7XG4gICAgaWYgKG9wdGlvbnMuc291cmNlTWFwKSB7XG4gICAgICBtYXAgPSBuZXcgU291cmNlTWFwO1xuICAgIH1cbiAgICBmcmFnbWVudHMgPSBwYXJzZXIucGFyc2UobGV4ZXIudG9rZW5pemUoY29kZSwgb3B0aW9ucykpLmNvbXBpbGVUb0ZyYWdtZW50cyhvcHRpb25zKTtcbiAgICBjdXJyZW50TGluZSA9IDA7XG4gICAgaWYgKG9wdGlvbnMuaGVhZGVyKSB7XG4gICAgICBjdXJyZW50TGluZSArPSAxO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5zaGlmdExpbmUpIHtcbiAgICAgIGN1cnJlbnRMaW5lICs9IDE7XG4gICAgfVxuICAgIGN1cnJlbnRDb2x1bW4gPSAwO1xuICAgIGpzID0gXCJcIjtcbiAgICBmb3IgKF9pID0gMCwgX2xlbiA9IGZyYWdtZW50cy5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgZnJhZ21lbnQgPSBmcmFnbWVudHNbX2ldO1xuICAgICAgaWYgKG9wdGlvbnMuc291cmNlTWFwKSB7XG4gICAgICAgIGlmIChmcmFnbWVudC5sb2NhdGlvbkRhdGEpIHtcbiAgICAgICAgICBtYXAuYWRkKFtmcmFnbWVudC5sb2NhdGlvbkRhdGEuZmlyc3RfbGluZSwgZnJhZ21lbnQubG9jYXRpb25EYXRhLmZpcnN0X2NvbHVtbl0sIFtjdXJyZW50TGluZSwgY3VycmVudENvbHVtbl0sIHtcbiAgICAgICAgICAgIG5vUmVwbGFjZTogdHJ1ZVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIG5ld0xpbmVzID0gaGVscGVycy5jb3VudChmcmFnbWVudC5jb2RlLCBcIlxcblwiKTtcbiAgICAgICAgY3VycmVudExpbmUgKz0gbmV3TGluZXM7XG4gICAgICAgIGlmIChuZXdMaW5lcykge1xuICAgICAgICAgIGN1cnJlbnRDb2x1bW4gPSBmcmFnbWVudC5jb2RlLmxlbmd0aCAtIChmcmFnbWVudC5jb2RlLmxhc3RJbmRleE9mKFwiXFxuXCIpICsgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3VycmVudENvbHVtbiArPSBmcmFnbWVudC5jb2RlLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAganMgKz0gZnJhZ21lbnQuY29kZTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMuaGVhZGVyKSB7XG4gICAgICBoZWFkZXIgPSBcIkdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgXCIgKyB0aGlzLlZFUlNJT047XG4gICAgICBqcyA9IFwiLy8gXCIgKyBoZWFkZXIgKyBcIlxcblwiICsganM7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLnNvdXJjZU1hcCkge1xuICAgICAgYW5zd2VyID0ge1xuICAgICAgICBqczoganNcbiAgICAgIH07XG4gICAgICBhbnN3ZXIuc291cmNlTWFwID0gbWFwO1xuICAgICAgYW5zd2VyLnYzU291cmNlTWFwID0gbWFwLmdlbmVyYXRlKG9wdGlvbnMsIGNvZGUpO1xuICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGpzO1xuICAgIH1cbiAgfSk7XG5cbiAgZXhwb3J0cy50b2tlbnMgPSB3aXRoUHJldHR5RXJyb3JzKGZ1bmN0aW9uKGNvZGUsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbGV4ZXIudG9rZW5pemUoY29kZSwgb3B0aW9ucyk7XG4gIH0pO1xuXG4gIGV4cG9ydHMubm9kZXMgPSB3aXRoUHJldHR5RXJyb3JzKGZ1bmN0aW9uKHNvdXJjZSwgb3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygc291cmNlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHBhcnNlci5wYXJzZShsZXhlci50b2tlbml6ZShzb3VyY2UsIG9wdGlvbnMpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHBhcnNlci5wYXJzZShzb3VyY2UpO1xuICAgIH1cbiAgfSk7XG5cbiAgZXhwb3J0cy5ydW4gPSBmdW5jdGlvbihjb2RlLCBvcHRpb25zKSB7XG4gICAgdmFyIGFuc3dlciwgZGlyLCBtYWluTW9kdWxlLCBfcmVmO1xuICAgIGlmIChvcHRpb25zID09IG51bGwpIHtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG4gICAgbWFpbk1vZHVsZSA9IHJlcXVpcmUubWFpbjtcbiAgICBtYWluTW9kdWxlLmZpbGVuYW1lID0gcHJvY2Vzcy5hcmd2WzFdID0gb3B0aW9ucy5maWxlbmFtZSA/IGZzLnJlYWxwYXRoU3luYyhvcHRpb25zLmZpbGVuYW1lKSA6ICcuJztcbiAgICBtYWluTW9kdWxlLm1vZHVsZUNhY2hlICYmIChtYWluTW9kdWxlLm1vZHVsZUNhY2hlID0ge30pO1xuICAgIGRpciA9IG9wdGlvbnMuZmlsZW5hbWUgPyBwYXRoLmRpcm5hbWUoZnMucmVhbHBhdGhTeW5jKG9wdGlvbnMuZmlsZW5hbWUpKSA6IGZzLnJlYWxwYXRoU3luYygnLicpO1xuICAgIG1haW5Nb2R1bGUucGF0aHMgPSByZXF1aXJlKCdtb2R1bGUnKS5fbm9kZU1vZHVsZVBhdGhzKGRpcik7XG4gICAgaWYgKCFoZWxwZXJzLmlzQ29mZmVlKG1haW5Nb2R1bGUuZmlsZW5hbWUpIHx8IHJlcXVpcmUuZXh0ZW5zaW9ucykge1xuICAgICAgYW5zd2VyID0gY29tcGlsZShjb2RlLCBvcHRpb25zKTtcbiAgICAgIGNvZGUgPSAoX3JlZiA9IGFuc3dlci5qcykgIT0gbnVsbCA/IF9yZWYgOiBhbnN3ZXI7XG4gICAgfVxuICAgIHJldHVybiBtYWluTW9kdWxlLl9jb21waWxlKGNvZGUsIG1haW5Nb2R1bGUuZmlsZW5hbWUpO1xuICB9O1xuXG4gIGV4cG9ydHNbXCJldmFsXCJdID0gZnVuY3Rpb24oY29kZSwgb3B0aW9ucykge1xuICAgIHZhciBNb2R1bGUsIFNjcmlwdCwganMsIGssIG8sIHIsIHNhbmRib3gsIHYsIF9pLCBfbGVuLCBfbW9kdWxlLCBfcmVmLCBfcmVmMSwgX3JlcXVpcmU7XG4gICAgaWYgKG9wdGlvbnMgPT0gbnVsbCkge1xuICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cbiAgICBpZiAoIShjb2RlID0gY29kZS50cmltKCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIFNjcmlwdCA9IHZtLlNjcmlwdDtcbiAgICBpZiAoU2NyaXB0KSB7XG4gICAgICBpZiAob3B0aW9ucy5zYW5kYm94ICE9IG51bGwpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuc2FuZGJveCBpbnN0YW5jZW9mIFNjcmlwdC5jcmVhdGVDb250ZXh0KCkuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICBzYW5kYm94ID0gb3B0aW9ucy5zYW5kYm94O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNhbmRib3ggPSBTY3JpcHQuY3JlYXRlQ29udGV4dCgpO1xuICAgICAgICAgIF9yZWYgPSBvcHRpb25zLnNhbmRib3g7XG4gICAgICAgICAgZm9yIChrIGluIF9yZWYpIHtcbiAgICAgICAgICAgIGlmICghX19oYXNQcm9wLmNhbGwoX3JlZiwgaykpIGNvbnRpbnVlO1xuICAgICAgICAgICAgdiA9IF9yZWZba107XG4gICAgICAgICAgICBzYW5kYm94W2tdID0gdjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2FuZGJveC5nbG9iYWwgPSBzYW5kYm94LnJvb3QgPSBzYW5kYm94LkdMT0JBTCA9IHNhbmRib3g7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzYW5kYm94ID0gZ2xvYmFsO1xuICAgICAgfVxuICAgICAgc2FuZGJveC5fX2ZpbGVuYW1lID0gb3B0aW9ucy5maWxlbmFtZSB8fCAnZXZhbCc7XG4gICAgICBzYW5kYm94Ll9fZGlybmFtZSA9IHBhdGguZGlybmFtZShzYW5kYm94Ll9fZmlsZW5hbWUpO1xuICAgICAgaWYgKCEoc2FuZGJveCAhPT0gZ2xvYmFsIHx8IHNhbmRib3gubW9kdWxlIHx8IHNhbmRib3gucmVxdWlyZSkpIHtcbiAgICAgICAgTW9kdWxlID0gcmVxdWlyZSgnbW9kdWxlJyk7XG4gICAgICAgIHNhbmRib3gubW9kdWxlID0gX21vZHVsZSA9IG5ldyBNb2R1bGUob3B0aW9ucy5tb2R1bGVuYW1lIHx8ICdldmFsJyk7XG4gICAgICAgIHNhbmRib3gucmVxdWlyZSA9IF9yZXF1aXJlID0gZnVuY3Rpb24ocGF0aCkge1xuICAgICAgICAgIHJldHVybiBNb2R1bGUuX2xvYWQocGF0aCwgX21vZHVsZSwgdHJ1ZSk7XG4gICAgICAgIH07XG4gICAgICAgIF9tb2R1bGUuZmlsZW5hbWUgPSBzYW5kYm94Ll9fZmlsZW5hbWU7XG4gICAgICAgIF9yZWYxID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocmVxdWlyZSk7XG4gICAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gX3JlZjEubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgICByID0gX3JlZjFbX2ldO1xuICAgICAgICAgIGlmIChyICE9PSAncGF0aHMnKSB7XG4gICAgICAgICAgICBfcmVxdWlyZVtyXSA9IHJlcXVpcmVbcl07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIF9yZXF1aXJlLnBhdGhzID0gX21vZHVsZS5wYXRocyA9IE1vZHVsZS5fbm9kZU1vZHVsZVBhdGhzKHByb2Nlc3MuY3dkKCkpO1xuICAgICAgICBfcmVxdWlyZS5yZXNvbHZlID0gZnVuY3Rpb24ocmVxdWVzdCkge1xuICAgICAgICAgIHJldHVybiBNb2R1bGUuX3Jlc29sdmVGaWxlbmFtZShyZXF1ZXN0LCBfbW9kdWxlKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgbyA9IHt9O1xuICAgIGZvciAoayBpbiBvcHRpb25zKSB7XG4gICAgICBpZiAoIV9faGFzUHJvcC5jYWxsKG9wdGlvbnMsIGspKSBjb250aW51ZTtcbiAgICAgIHYgPSBvcHRpb25zW2tdO1xuICAgICAgb1trXSA9IHY7XG4gICAgfVxuICAgIG8uYmFyZSA9IHRydWU7XG4gICAganMgPSBjb21waWxlKGNvZGUsIG8pO1xuICAgIGlmIChzYW5kYm94ID09PSBnbG9iYWwpIHtcbiAgICAgIHJldHVybiB2bS5ydW5JblRoaXNDb250ZXh0KGpzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHZtLnJ1bkluQ29udGV4dChqcywgc2FuZGJveCk7XG4gICAgfVxuICB9O1xuXG4gIGV4cG9ydHMucmVnaXN0ZXIgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gcmVxdWlyZSgnLi9yZWdpc3RlcicpO1xuICB9O1xuXG4gIGlmIChyZXF1aXJlLmV4dGVuc2lvbnMpIHtcbiAgICBfcmVmID0gdGhpcy5GSUxFX0VYVEVOU0lPTlM7XG4gICAgZm9yIChfaSA9IDAsIF9sZW4gPSBfcmVmLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICBleHQgPSBfcmVmW19pXTtcbiAgICAgIGlmICgoX2Jhc2UgPSByZXF1aXJlLmV4dGVuc2lvbnMpW2V4dF0gPT0gbnVsbCkge1xuICAgICAgICBfYmFzZVtleHRdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVXNlIENvZmZlZVNjcmlwdC5yZWdpc3RlcigpIG9yIHJlcXVpcmUgdGhlIGNvZmZlZS1zY3JpcHQvcmVnaXN0ZXIgbW9kdWxlIHRvIHJlcXVpcmUgXCIgKyBleHQgKyBcIiBmaWxlcy5cIik7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZXhwb3J0cy5fY29tcGlsZUZpbGUgPSBmdW5jdGlvbihmaWxlbmFtZSwgc291cmNlTWFwKSB7XG4gICAgdmFyIGFuc3dlciwgZXJyLCByYXcsIHN0cmlwcGVkO1xuICAgIGlmIChzb3VyY2VNYXAgPT0gbnVsbCkge1xuICAgICAgc291cmNlTWFwID0gZmFsc2U7XG4gICAgfVxuICAgIHJhdyA9IGZzLnJlYWRGaWxlU3luYyhmaWxlbmFtZSwgJ3V0ZjgnKTtcbiAgICBzdHJpcHBlZCA9IHJhdy5jaGFyQ29kZUF0KDApID09PSAweEZFRkYgPyByYXcuc3Vic3RyaW5nKDEpIDogcmF3O1xuICAgIHRyeSB7XG4gICAgICBhbnN3ZXIgPSBjb21waWxlKHN0cmlwcGVkLCB7XG4gICAgICAgIGZpbGVuYW1lOiBmaWxlbmFtZSxcbiAgICAgICAgc291cmNlTWFwOiBzb3VyY2VNYXAsXG4gICAgICAgIGxpdGVyYXRlOiBoZWxwZXJzLmlzTGl0ZXJhdGUoZmlsZW5hbWUpXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICAgIGVyciA9IF9lcnJvcjtcbiAgICAgIHRocm93IGhlbHBlcnMudXBkYXRlU3ludGF4RXJyb3IoZXJyLCBzdHJpcHBlZCwgZmlsZW5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gYW5zd2VyO1xuICB9O1xuXG4gIGxleGVyID0gbmV3IExleGVyO1xuXG4gIHBhcnNlci5sZXhlciA9IHtcbiAgICBsZXg6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHRhZywgdG9rZW47XG4gICAgICB0b2tlbiA9IHRoaXMudG9rZW5zW3RoaXMucG9zKytdO1xuICAgICAgaWYgKHRva2VuKSB7XG4gICAgICAgIHRhZyA9IHRva2VuWzBdLCB0aGlzLnl5dGV4dCA9IHRva2VuWzFdLCB0aGlzLnl5bGxvYyA9IHRva2VuWzJdO1xuICAgICAgICB0aGlzLmVycm9yVG9rZW4gPSB0b2tlbi5vcmlnaW4gfHwgdG9rZW47XG4gICAgICAgIHRoaXMueXlsaW5lbm8gPSB0aGlzLnl5bGxvYy5maXJzdF9saW5lO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFnID0gJyc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGFnO1xuICAgIH0sXG4gICAgc2V0SW5wdXQ6IGZ1bmN0aW9uKHRva2Vucykge1xuICAgICAgdGhpcy50b2tlbnMgPSB0b2tlbnM7XG4gICAgICByZXR1cm4gdGhpcy5wb3MgPSAwO1xuICAgIH0sXG4gICAgdXBjb21pbmdJbnB1dDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG4gIH07XG5cbiAgcGFyc2VyLnl5ID0gcmVxdWlyZSgnLi9ub2RlcycpO1xuXG4gIHBhcnNlci55eS5wYXJzZUVycm9yID0gZnVuY3Rpb24obWVzc2FnZSwgX2FyZykge1xuICAgIHZhciBlcnJvckxvYywgZXJyb3JUYWcsIGVycm9yVGV4dCwgZXJyb3JUb2tlbiwgdG9rZW4sIHRva2VucywgX3JlZjE7XG4gICAgdG9rZW4gPSBfYXJnLnRva2VuO1xuICAgIF9yZWYxID0gcGFyc2VyLmxleGVyLCBlcnJvclRva2VuID0gX3JlZjEuZXJyb3JUb2tlbiwgdG9rZW5zID0gX3JlZjEudG9rZW5zO1xuICAgIGVycm9yVGFnID0gZXJyb3JUb2tlblswXSwgZXJyb3JUZXh0ID0gZXJyb3JUb2tlblsxXSwgZXJyb3JMb2MgPSBlcnJvclRva2VuWzJdO1xuICAgIGVycm9yVGV4dCA9IGVycm9yVG9rZW4gPT09IHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV0gPyAnZW5kIG9mIGlucHV0JyA6IGVycm9yVGFnID09PSAnSU5ERU5UJyB8fCBlcnJvclRhZyA9PT0gJ09VVERFTlQnID8gJ2luZGVudGF0aW9uJyA6IGhlbHBlcnMubmFtZVdoaXRlc3BhY2VDaGFyYWN0ZXIoZXJyb3JUZXh0KTtcbiAgICByZXR1cm4gaGVscGVycy50aHJvd1N5bnRheEVycm9yKFwidW5leHBlY3RlZCBcIiArIGVycm9yVGV4dCwgZXJyb3JMb2MpO1xuICB9O1xuXG4gIGZvcm1hdFNvdXJjZVBvc2l0aW9uID0gZnVuY3Rpb24oZnJhbWUsIGdldFNvdXJjZU1hcHBpbmcpIHtcbiAgICB2YXIgYXMsIGNvbHVtbiwgZmlsZUxvY2F0aW9uLCBmaWxlTmFtZSwgZnVuY3Rpb25OYW1lLCBpc0NvbnN0cnVjdG9yLCBpc01ldGhvZENhbGwsIGxpbmUsIG1ldGhvZE5hbWUsIHNvdXJjZSwgdHAsIHR5cGVOYW1lO1xuICAgIGZpbGVOYW1lID0gdm9pZCAwO1xuICAgIGZpbGVMb2NhdGlvbiA9ICcnO1xuICAgIGlmIChmcmFtZS5pc05hdGl2ZSgpKSB7XG4gICAgICBmaWxlTG9jYXRpb24gPSBcIm5hdGl2ZVwiO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZnJhbWUuaXNFdmFsKCkpIHtcbiAgICAgICAgZmlsZU5hbWUgPSBmcmFtZS5nZXRTY3JpcHROYW1lT3JTb3VyY2VVUkwoKTtcbiAgICAgICAgaWYgKCFmaWxlTmFtZSkge1xuICAgICAgICAgIGZpbGVMb2NhdGlvbiA9IFwiXCIgKyAoZnJhbWUuZ2V0RXZhbE9yaWdpbigpKSArIFwiLCBcIjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZmlsZU5hbWUgPSBmcmFtZS5nZXRGaWxlTmFtZSgpO1xuICAgICAgfVxuICAgICAgZmlsZU5hbWUgfHwgKGZpbGVOYW1lID0gXCI8YW5vbnltb3VzPlwiKTtcbiAgICAgIGxpbmUgPSBmcmFtZS5nZXRMaW5lTnVtYmVyKCk7XG4gICAgICBjb2x1bW4gPSBmcmFtZS5nZXRDb2x1bW5OdW1iZXIoKTtcbiAgICAgIHNvdXJjZSA9IGdldFNvdXJjZU1hcHBpbmcoZmlsZU5hbWUsIGxpbmUsIGNvbHVtbik7XG4gICAgICBmaWxlTG9jYXRpb24gPSBzb3VyY2UgPyBcIlwiICsgZmlsZU5hbWUgKyBcIjpcIiArIHNvdXJjZVswXSArIFwiOlwiICsgc291cmNlWzFdIDogXCJcIiArIGZpbGVOYW1lICsgXCI6XCIgKyBsaW5lICsgXCI6XCIgKyBjb2x1bW47XG4gICAgfVxuICAgIGZ1bmN0aW9uTmFtZSA9IGZyYW1lLmdldEZ1bmN0aW9uTmFtZSgpO1xuICAgIGlzQ29uc3RydWN0b3IgPSBmcmFtZS5pc0NvbnN0cnVjdG9yKCk7XG4gICAgaXNNZXRob2RDYWxsID0gIShmcmFtZS5pc1RvcGxldmVsKCkgfHwgaXNDb25zdHJ1Y3Rvcik7XG4gICAgaWYgKGlzTWV0aG9kQ2FsbCkge1xuICAgICAgbWV0aG9kTmFtZSA9IGZyYW1lLmdldE1ldGhvZE5hbWUoKTtcbiAgICAgIHR5cGVOYW1lID0gZnJhbWUuZ2V0VHlwZU5hbWUoKTtcbiAgICAgIGlmIChmdW5jdGlvbk5hbWUpIHtcbiAgICAgICAgdHAgPSBhcyA9ICcnO1xuICAgICAgICBpZiAodHlwZU5hbWUgJiYgZnVuY3Rpb25OYW1lLmluZGV4T2YodHlwZU5hbWUpKSB7XG4gICAgICAgICAgdHAgPSBcIlwiICsgdHlwZU5hbWUgKyBcIi5cIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0aG9kTmFtZSAmJiBmdW5jdGlvbk5hbWUuaW5kZXhPZihcIi5cIiArIG1ldGhvZE5hbWUpICE9PSBmdW5jdGlvbk5hbWUubGVuZ3RoIC0gbWV0aG9kTmFtZS5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgYXMgPSBcIiBbYXMgXCIgKyBtZXRob2ROYW1lICsgXCJdXCI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFwiXCIgKyB0cCArIGZ1bmN0aW9uTmFtZSArIGFzICsgXCIgKFwiICsgZmlsZUxvY2F0aW9uICsgXCIpXCI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gXCJcIiArIHR5cGVOYW1lICsgXCIuXCIgKyAobWV0aG9kTmFtZSB8fCAnPGFub255bW91cz4nKSArIFwiIChcIiArIGZpbGVMb2NhdGlvbiArIFwiKVwiO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNDb25zdHJ1Y3Rvcikge1xuICAgICAgcmV0dXJuIFwibmV3IFwiICsgKGZ1bmN0aW9uTmFtZSB8fCAnPGFub255bW91cz4nKSArIFwiIChcIiArIGZpbGVMb2NhdGlvbiArIFwiKVwiO1xuICAgIH0gZWxzZSBpZiAoZnVuY3Rpb25OYW1lKSB7XG4gICAgICByZXR1cm4gXCJcIiArIGZ1bmN0aW9uTmFtZSArIFwiIChcIiArIGZpbGVMb2NhdGlvbiArIFwiKVwiO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmlsZUxvY2F0aW9uO1xuICAgIH1cbiAgfTtcblxuICBzb3VyY2VNYXBzID0ge307XG5cbiAgZ2V0U291cmNlTWFwID0gZnVuY3Rpb24oZmlsZW5hbWUpIHtcbiAgICB2YXIgYW5zd2VyLCBfcmVmMTtcbiAgICBpZiAoc291cmNlTWFwc1tmaWxlbmFtZV0pIHtcbiAgICAgIHJldHVybiBzb3VyY2VNYXBzW2ZpbGVuYW1lXTtcbiAgICB9XG4gICAgaWYgKF9yZWYxID0gcGF0aCAhPSBudWxsID8gcGF0aC5leHRuYW1lKGZpbGVuYW1lKSA6IHZvaWQgMCwgX19pbmRleE9mLmNhbGwoZXhwb3J0cy5GSUxFX0VYVEVOU0lPTlMsIF9yZWYxKSA8IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgYW5zd2VyID0gZXhwb3J0cy5fY29tcGlsZUZpbGUoZmlsZW5hbWUsIHRydWUpO1xuICAgIHJldHVybiBzb3VyY2VNYXBzW2ZpbGVuYW1lXSA9IGFuc3dlci5zb3VyY2VNYXA7XG4gIH07XG5cbiAgRXJyb3IucHJlcGFyZVN0YWNrVHJhY2UgPSBmdW5jdGlvbihlcnIsIHN0YWNrKSB7XG4gICAgdmFyIGZyYW1lLCBmcmFtZXMsIGdldFNvdXJjZU1hcHBpbmc7XG4gICAgZ2V0U291cmNlTWFwcGluZyA9IGZ1bmN0aW9uKGZpbGVuYW1lLCBsaW5lLCBjb2x1bW4pIHtcbiAgICAgIHZhciBhbnN3ZXIsIHNvdXJjZU1hcDtcbiAgICAgIHNvdXJjZU1hcCA9IGdldFNvdXJjZU1hcChmaWxlbmFtZSk7XG4gICAgICBpZiAoc291cmNlTWFwKSB7XG4gICAgICAgIGFuc3dlciA9IHNvdXJjZU1hcC5zb3VyY2VMb2NhdGlvbihbbGluZSAtIDEsIGNvbHVtbiAtIDFdKTtcbiAgICAgIH1cbiAgICAgIGlmIChhbnN3ZXIpIHtcbiAgICAgICAgcmV0dXJuIFthbnN3ZXJbMF0gKyAxLCBhbnN3ZXJbMV0gKyAxXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH07XG4gICAgZnJhbWVzID0gKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIF9qLCBfbGVuMSwgX3Jlc3VsdHM7XG4gICAgICBfcmVzdWx0cyA9IFtdO1xuICAgICAgZm9yIChfaiA9IDAsIF9sZW4xID0gc3RhY2subGVuZ3RoOyBfaiA8IF9sZW4xOyBfaisrKSB7XG4gICAgICAgIGZyYW1lID0gc3RhY2tbX2pdO1xuICAgICAgICBpZiAoZnJhbWUuZ2V0RnVuY3Rpb24oKSA9PT0gZXhwb3J0cy5ydW4pIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBfcmVzdWx0cy5wdXNoKFwiICBhdCBcIiArIChmb3JtYXRTb3VyY2VQb3NpdGlvbihmcmFtZSwgZ2V0U291cmNlTWFwcGluZykpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBfcmVzdWx0cztcbiAgICB9KSgpO1xuICAgIHJldHVybiBcIlwiICsgKGVyci50b1N0cmluZygpKSArIFwiXFxuXCIgKyAoZnJhbWVzLmpvaW4oJ1xcbicpKSArIFwiXFxuXCI7XG4gIH07XG5cbn0pLmNhbGwodGhpcyk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwiMVlpWjVTXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSkiLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjguMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgYnVpbGRMb2NhdGlvbkRhdGEsIGV4dGVuZCwgZmxhdHRlbiwgbGFzdCwgcmVwZWF0LCBzeW50YXhFcnJvclRvU3RyaW5nLCBfcmVmO1xuXG4gIGV4cG9ydHMuc3RhcnRzID0gZnVuY3Rpb24oc3RyaW5nLCBsaXRlcmFsLCBzdGFydCkge1xuICAgIHJldHVybiBsaXRlcmFsID09PSBzdHJpbmcuc3Vic3RyKHN0YXJ0LCBsaXRlcmFsLmxlbmd0aCk7XG4gIH07XG5cbiAgZXhwb3J0cy5lbmRzID0gZnVuY3Rpb24oc3RyaW5nLCBsaXRlcmFsLCBiYWNrKSB7XG4gICAgdmFyIGxlbjtcbiAgICBsZW4gPSBsaXRlcmFsLmxlbmd0aDtcbiAgICByZXR1cm4gbGl0ZXJhbCA9PT0gc3RyaW5nLnN1YnN0cihzdHJpbmcubGVuZ3RoIC0gbGVuIC0gKGJhY2sgfHwgMCksIGxlbik7XG4gIH07XG5cbiAgZXhwb3J0cy5yZXBlYXQgPSByZXBlYXQgPSBmdW5jdGlvbihzdHIsIG4pIHtcbiAgICB2YXIgcmVzO1xuICAgIHJlcyA9ICcnO1xuICAgIHdoaWxlIChuID4gMCkge1xuICAgICAgaWYgKG4gJiAxKSB7XG4gICAgICAgIHJlcyArPSBzdHI7XG4gICAgICB9XG4gICAgICBuID4+Pj0gMTtcbiAgICAgIHN0ciArPSBzdHI7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgZXhwb3J0cy5jb21wYWN0ID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICB2YXIgaXRlbSwgX2ksIF9sZW4sIF9yZXN1bHRzO1xuICAgIF9yZXN1bHRzID0gW107XG4gICAgZm9yIChfaSA9IDAsIF9sZW4gPSBhcnJheS5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgaXRlbSA9IGFycmF5W19pXTtcbiAgICAgIGlmIChpdGVtKSB7XG4gICAgICAgIF9yZXN1bHRzLnB1c2goaXRlbSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBfcmVzdWx0cztcbiAgfTtcblxuICBleHBvcnRzLmNvdW50ID0gZnVuY3Rpb24oc3RyaW5nLCBzdWJzdHIpIHtcbiAgICB2YXIgbnVtLCBwb3M7XG4gICAgbnVtID0gcG9zID0gMDtcbiAgICBpZiAoIXN1YnN0ci5sZW5ndGgpIHtcbiAgICAgIHJldHVybiAxIC8gMDtcbiAgICB9XG4gICAgd2hpbGUgKHBvcyA9IDEgKyBzdHJpbmcuaW5kZXhPZihzdWJzdHIsIHBvcykpIHtcbiAgICAgIG51bSsrO1xuICAgIH1cbiAgICByZXR1cm4gbnVtO1xuICB9O1xuXG4gIGV4cG9ydHMubWVyZ2UgPSBmdW5jdGlvbihvcHRpb25zLCBvdmVycmlkZXMpIHtcbiAgICByZXR1cm4gZXh0ZW5kKGV4dGVuZCh7fSwgb3B0aW9ucyksIG92ZXJyaWRlcyk7XG4gIH07XG5cbiAgZXh0ZW5kID0gZXhwb3J0cy5leHRlbmQgPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnRpZXMpIHtcbiAgICB2YXIga2V5LCB2YWw7XG4gICAgZm9yIChrZXkgaW4gcHJvcGVydGllcykge1xuICAgICAgdmFsID0gcHJvcGVydGllc1trZXldO1xuICAgICAgb2JqZWN0W2tleV0gPSB2YWw7XG4gICAgfVxuICAgIHJldHVybiBvYmplY3Q7XG4gIH07XG5cbiAgZXhwb3J0cy5mbGF0dGVuID0gZmxhdHRlbiA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgdmFyIGVsZW1lbnQsIGZsYXR0ZW5lZCwgX2ksIF9sZW47XG4gICAgZmxhdHRlbmVkID0gW107XG4gICAgZm9yIChfaSA9IDAsIF9sZW4gPSBhcnJheS5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgZWxlbWVudCA9IGFycmF5W19pXTtcbiAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgZmxhdHRlbmVkID0gZmxhdHRlbmVkLmNvbmNhdChmbGF0dGVuKGVsZW1lbnQpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZsYXR0ZW5lZC5wdXNoKGVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmxhdHRlbmVkO1xuICB9O1xuXG4gIGV4cG9ydHMuZGVsID0gZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICB2YXIgdmFsO1xuICAgIHZhbCA9IG9ialtrZXldO1xuICAgIGRlbGV0ZSBvYmpba2V5XTtcbiAgICByZXR1cm4gdmFsO1xuICB9O1xuXG4gIGV4cG9ydHMubGFzdCA9IGxhc3QgPSBmdW5jdGlvbihhcnJheSwgYmFjaykge1xuICAgIHJldHVybiBhcnJheVthcnJheS5sZW5ndGggLSAoYmFjayB8fCAwKSAtIDFdO1xuICB9O1xuXG4gIGV4cG9ydHMuc29tZSA9IChfcmVmID0gQXJyYXkucHJvdG90eXBlLnNvbWUpICE9IG51bGwgPyBfcmVmIDogZnVuY3Rpb24oZm4pIHtcbiAgICB2YXIgZSwgX2ksIF9sZW47XG4gICAgZm9yIChfaSA9IDAsIF9sZW4gPSB0aGlzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICBlID0gdGhpc1tfaV07XG4gICAgICBpZiAoZm4oZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICBleHBvcnRzLmludmVydExpdGVyYXRlID0gZnVuY3Rpb24oY29kZSkge1xuICAgIHZhciBsaW5lLCBsaW5lcywgbWF5YmVfY29kZTtcbiAgICBtYXliZV9jb2RlID0gdHJ1ZTtcbiAgICBsaW5lcyA9IChmdW5jdGlvbigpIHtcbiAgICAgIHZhciBfaSwgX2xlbiwgX3JlZjEsIF9yZXN1bHRzO1xuICAgICAgX3JlZjEgPSBjb2RlLnNwbGl0KCdcXG4nKTtcbiAgICAgIF9yZXN1bHRzID0gW107XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYxLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGxpbmUgPSBfcmVmMVtfaV07XG4gICAgICAgIGlmIChtYXliZV9jb2RlICYmIC9eKFsgXXs0fXxbIF17MCwzfVxcdCkvLnRlc3QobGluZSkpIHtcbiAgICAgICAgICBfcmVzdWx0cy5wdXNoKGxpbmUpO1xuICAgICAgICB9IGVsc2UgaWYgKG1heWJlX2NvZGUgPSAvXlxccyokLy50ZXN0KGxpbmUpKSB7XG4gICAgICAgICAgX3Jlc3VsdHMucHVzaChsaW5lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBfcmVzdWx0cy5wdXNoKCcjICcgKyBsaW5lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIF9yZXN1bHRzO1xuICAgIH0pKCk7XG4gICAgcmV0dXJuIGxpbmVzLmpvaW4oJ1xcbicpO1xuICB9O1xuXG4gIGJ1aWxkTG9jYXRpb25EYXRhID0gZnVuY3Rpb24oZmlyc3QsIGxhc3QpIHtcbiAgICBpZiAoIWxhc3QpIHtcbiAgICAgIHJldHVybiBmaXJzdDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZmlyc3RfbGluZTogZmlyc3QuZmlyc3RfbGluZSxcbiAgICAgICAgZmlyc3RfY29sdW1uOiBmaXJzdC5maXJzdF9jb2x1bW4sXG4gICAgICAgIGxhc3RfbGluZTogbGFzdC5sYXN0X2xpbmUsXG4gICAgICAgIGxhc3RfY29sdW1uOiBsYXN0Lmxhc3RfY29sdW1uXG4gICAgICB9O1xuICAgIH1cbiAgfTtcblxuICBleHBvcnRzLmFkZExvY2F0aW9uRGF0YUZuID0gZnVuY3Rpb24oZmlyc3QsIGxhc3QpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24ob2JqKSB7XG4gICAgICBpZiAoKCh0eXBlb2Ygb2JqKSA9PT0gJ29iamVjdCcpICYmICghIW9ialsndXBkYXRlTG9jYXRpb25EYXRhSWZNaXNzaW5nJ10pKSB7XG4gICAgICAgIG9iai51cGRhdGVMb2NhdGlvbkRhdGFJZk1pc3NpbmcoYnVpbGRMb2NhdGlvbkRhdGEoZmlyc3QsIGxhc3QpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmo7XG4gICAgfTtcbiAgfTtcblxuICBleHBvcnRzLmxvY2F0aW9uRGF0YVRvU3RyaW5nID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIGxvY2F0aW9uRGF0YTtcbiAgICBpZiAoKFwiMlwiIGluIG9iaikgJiYgKFwiZmlyc3RfbGluZVwiIGluIG9ialsyXSkpIHtcbiAgICAgIGxvY2F0aW9uRGF0YSA9IG9ialsyXTtcbiAgICB9IGVsc2UgaWYgKFwiZmlyc3RfbGluZVwiIGluIG9iaikge1xuICAgICAgbG9jYXRpb25EYXRhID0gb2JqO1xuICAgIH1cbiAgICBpZiAobG9jYXRpb25EYXRhKSB7XG4gICAgICByZXR1cm4gKFwiXCIgKyAobG9jYXRpb25EYXRhLmZpcnN0X2xpbmUgKyAxKSArIFwiOlwiICsgKGxvY2F0aW9uRGF0YS5maXJzdF9jb2x1bW4gKyAxKSArIFwiLVwiKSArIChcIlwiICsgKGxvY2F0aW9uRGF0YS5sYXN0X2xpbmUgKyAxKSArIFwiOlwiICsgKGxvY2F0aW9uRGF0YS5sYXN0X2NvbHVtbiArIDEpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFwiTm8gbG9jYXRpb24gZGF0YVwiO1xuICAgIH1cbiAgfTtcblxuICBleHBvcnRzLmJhc2VGaWxlTmFtZSA9IGZ1bmN0aW9uKGZpbGUsIHN0cmlwRXh0LCB1c2VXaW5QYXRoU2VwKSB7XG4gICAgdmFyIHBhcnRzLCBwYXRoU2VwO1xuICAgIGlmIChzdHJpcEV4dCA9PSBudWxsKSB7XG4gICAgICBzdHJpcEV4dCA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAodXNlV2luUGF0aFNlcCA9PSBudWxsKSB7XG4gICAgICB1c2VXaW5QYXRoU2VwID0gZmFsc2U7XG4gICAgfVxuICAgIHBhdGhTZXAgPSB1c2VXaW5QYXRoU2VwID8gL1xcXFx8XFwvLyA6IC9cXC8vO1xuICAgIHBhcnRzID0gZmlsZS5zcGxpdChwYXRoU2VwKTtcbiAgICBmaWxlID0gcGFydHNbcGFydHMubGVuZ3RoIC0gMV07XG4gICAgaWYgKCEoc3RyaXBFeHQgJiYgZmlsZS5pbmRleE9mKCcuJykgPj0gMCkpIHtcbiAgICAgIHJldHVybiBmaWxlO1xuICAgIH1cbiAgICBwYXJ0cyA9IGZpbGUuc3BsaXQoJy4nKTtcbiAgICBwYXJ0cy5wb3AoKTtcbiAgICBpZiAocGFydHNbcGFydHMubGVuZ3RoIC0gMV0gPT09ICdjb2ZmZWUnICYmIHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHBhcnRzLnBvcCgpO1xuICAgIH1cbiAgICByZXR1cm4gcGFydHMuam9pbignLicpO1xuICB9O1xuXG4gIGV4cG9ydHMuaXNDb2ZmZWUgPSBmdW5jdGlvbihmaWxlKSB7XG4gICAgcmV0dXJuIC9cXC4oKGxpdCk/Y29mZmVlfGNvZmZlZVxcLm1kKSQvLnRlc3QoZmlsZSk7XG4gIH07XG5cbiAgZXhwb3J0cy5pc0xpdGVyYXRlID0gZnVuY3Rpb24oZmlsZSkge1xuICAgIHJldHVybiAvXFwuKGxpdGNvZmZlZXxjb2ZmZWVcXC5tZCkkLy50ZXN0KGZpbGUpO1xuICB9O1xuXG4gIGV4cG9ydHMudGhyb3dTeW50YXhFcnJvciA9IGZ1bmN0aW9uKG1lc3NhZ2UsIGxvY2F0aW9uKSB7XG4gICAgdmFyIGVycm9yO1xuICAgIGVycm9yID0gbmV3IFN5bnRheEVycm9yKG1lc3NhZ2UpO1xuICAgIGVycm9yLmxvY2F0aW9uID0gbG9jYXRpb247XG4gICAgZXJyb3IudG9TdHJpbmcgPSBzeW50YXhFcnJvclRvU3RyaW5nO1xuICAgIGVycm9yLnN0YWNrID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfTtcblxuICBleHBvcnRzLnVwZGF0ZVN5bnRheEVycm9yID0gZnVuY3Rpb24oZXJyb3IsIGNvZGUsIGZpbGVuYW1lKSB7XG4gICAgaWYgKGVycm9yLnRvU3RyaW5nID09PSBzeW50YXhFcnJvclRvU3RyaW5nKSB7XG4gICAgICBlcnJvci5jb2RlIHx8IChlcnJvci5jb2RlID0gY29kZSk7XG4gICAgICBlcnJvci5maWxlbmFtZSB8fCAoZXJyb3IuZmlsZW5hbWUgPSBmaWxlbmFtZSk7XG4gICAgICBlcnJvci5zdGFjayA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIHJldHVybiBlcnJvcjtcbiAgfTtcblxuICBzeW50YXhFcnJvclRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNvZGVMaW5lLCBjb2xvcml6ZSwgY29sb3JzRW5hYmxlZCwgZW5kLCBmaWxlbmFtZSwgZmlyc3RfY29sdW1uLCBmaXJzdF9saW5lLCBsYXN0X2NvbHVtbiwgbGFzdF9saW5lLCBtYXJrZXIsIHN0YXJ0LCBfcmVmMSwgX3JlZjI7XG4gICAgaWYgKCEodGhpcy5jb2RlICYmIHRoaXMubG9jYXRpb24pKSB7XG4gICAgICByZXR1cm4gRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodGhpcyk7XG4gICAgfVxuICAgIF9yZWYxID0gdGhpcy5sb2NhdGlvbiwgZmlyc3RfbGluZSA9IF9yZWYxLmZpcnN0X2xpbmUsIGZpcnN0X2NvbHVtbiA9IF9yZWYxLmZpcnN0X2NvbHVtbiwgbGFzdF9saW5lID0gX3JlZjEubGFzdF9saW5lLCBsYXN0X2NvbHVtbiA9IF9yZWYxLmxhc3RfY29sdW1uO1xuICAgIGlmIChsYXN0X2xpbmUgPT0gbnVsbCkge1xuICAgICAgbGFzdF9saW5lID0gZmlyc3RfbGluZTtcbiAgICB9XG4gICAgaWYgKGxhc3RfY29sdW1uID09IG51bGwpIHtcbiAgICAgIGxhc3RfY29sdW1uID0gZmlyc3RfY29sdW1uO1xuICAgIH1cbiAgICBmaWxlbmFtZSA9IHRoaXMuZmlsZW5hbWUgfHwgJ1tzdGRpbl0nO1xuICAgIGNvZGVMaW5lID0gdGhpcy5jb2RlLnNwbGl0KCdcXG4nKVtmaXJzdF9saW5lXTtcbiAgICBzdGFydCA9IGZpcnN0X2NvbHVtbjtcbiAgICBlbmQgPSBmaXJzdF9saW5lID09PSBsYXN0X2xpbmUgPyBsYXN0X2NvbHVtbiArIDEgOiBjb2RlTGluZS5sZW5ndGg7XG4gICAgbWFya2VyID0gY29kZUxpbmUuc2xpY2UoMCwgc3RhcnQpLnJlcGxhY2UoL1teXFxzXS9nLCAnICcpICsgcmVwZWF0KCdeJywgZW5kIC0gc3RhcnQpO1xuICAgIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBwcm9jZXNzICE9PSBudWxsKSB7XG4gICAgICBjb2xvcnNFbmFibGVkID0gcHJvY2Vzcy5zdGRvdXQuaXNUVFkgJiYgIXByb2Nlc3MuZW52Lk5PREVfRElTQUJMRV9DT0xPUlM7XG4gICAgfVxuICAgIGlmICgoX3JlZjIgPSB0aGlzLmNvbG9yZnVsKSAhPSBudWxsID8gX3JlZjIgOiBjb2xvcnNFbmFibGVkKSB7XG4gICAgICBjb2xvcml6ZSA9IGZ1bmN0aW9uKHN0cikge1xuICAgICAgICByZXR1cm4gXCJcXHgxQlsxOzMxbVwiICsgc3RyICsgXCJcXHgxQlswbVwiO1xuICAgICAgfTtcbiAgICAgIGNvZGVMaW5lID0gY29kZUxpbmUuc2xpY2UoMCwgc3RhcnQpICsgY29sb3JpemUoY29kZUxpbmUuc2xpY2Uoc3RhcnQsIGVuZCkpICsgY29kZUxpbmUuc2xpY2UoZW5kKTtcbiAgICAgIG1hcmtlciA9IGNvbG9yaXplKG1hcmtlcik7XG4gICAgfVxuICAgIHJldHVybiBcIlwiICsgZmlsZW5hbWUgKyBcIjpcIiArIChmaXJzdF9saW5lICsgMSkgKyBcIjpcIiArIChmaXJzdF9jb2x1bW4gKyAxKSArIFwiOiBlcnJvcjogXCIgKyB0aGlzLm1lc3NhZ2UgKyBcIlxcblwiICsgY29kZUxpbmUgKyBcIlxcblwiICsgbWFya2VyO1xuICB9O1xuXG4gIGV4cG9ydHMubmFtZVdoaXRlc3BhY2VDaGFyYWN0ZXIgPSBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICBzd2l0Y2ggKHN0cmluZykge1xuICAgICAgY2FzZSAnICc6XG4gICAgICAgIHJldHVybiAnc3BhY2UnO1xuICAgICAgY2FzZSAnXFxuJzpcbiAgICAgICAgcmV0dXJuICduZXdsaW5lJztcbiAgICAgIGNhc2UgJ1xccic6XG4gICAgICAgIHJldHVybiAnY2FycmlhZ2UgcmV0dXJuJztcbiAgICAgIGNhc2UgJ1xcdCc6XG4gICAgICAgIHJldHVybiAndGFiJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgfVxuICB9O1xuXG59KS5jYWxsKHRoaXMpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIjFZaVo1U1wiKSkiLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuOC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBCT00sIEJPT0wsIENBTExBQkxFLCBDT0RFLCBDT0ZGRUVfQUxJQVNFUywgQ09GRkVFX0FMSUFTX01BUCwgQ09GRkVFX0tFWVdPUkRTLCBDT01NRU5ULCBDT01QQVJFLCBDT01QT1VORF9BU1NJR04sIEhFUkVET0MsIEhFUkVET0NfSUxMRUdBTCwgSEVSRURPQ19JTkRFTlQsIEhFUkVHRVgsIEhFUkVHRVhfT01JVCwgSURFTlRJRklFUiwgSU5ERU5UQUJMRV9DTE9TRVJTLCBJTkRFWEFCTEUsIElOVkVSU0VTLCBKU1RPS0VOLCBKU19GT1JCSURERU4sIEpTX0tFWVdPUkRTLCBMSU5FX0JSRUFLLCBMSU5FX0NPTlRJTlVFUiwgTE9HSUMsIExleGVyLCBNQVRILCBNVUxUSUxJTkVSLCBNVUxUSV9ERU5ULCBOT1RfUkVHRVgsIE5PVF9TUEFDRURfUkVHRVgsIE5VTUJFUiwgT1BFUkFUT1IsIFJFR0VYLCBSRUxBVElPTiwgUkVTRVJWRUQsIFJld3JpdGVyLCBTSElGVCwgU0lNUExFU1RSLCBTVFJJQ1RfUFJPU0NSSUJFRCwgVFJBSUxJTkdfU1BBQ0VTLCBVTkFSWSwgVU5BUllfTUFUSCwgV0hJVEVTUEFDRSwgY29tcGFjdCwgY291bnQsIGludmVydExpdGVyYXRlLCBrZXksIGxhc3QsIGxvY2F0aW9uRGF0YVRvU3RyaW5nLCByZXBlYXQsIHN0YXJ0cywgdGhyb3dTeW50YXhFcnJvciwgX3JlZiwgX3JlZjEsXG4gICAgX19pbmRleE9mID0gW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH07XG5cbiAgX3JlZiA9IHJlcXVpcmUoJy4vcmV3cml0ZXInKSwgUmV3cml0ZXIgPSBfcmVmLlJld3JpdGVyLCBJTlZFUlNFUyA9IF9yZWYuSU5WRVJTRVM7XG5cbiAgX3JlZjEgPSByZXF1aXJlKCcuL2hlbHBlcnMnKSwgY291bnQgPSBfcmVmMS5jb3VudCwgc3RhcnRzID0gX3JlZjEuc3RhcnRzLCBjb21wYWN0ID0gX3JlZjEuY29tcGFjdCwgbGFzdCA9IF9yZWYxLmxhc3QsIHJlcGVhdCA9IF9yZWYxLnJlcGVhdCwgaW52ZXJ0TGl0ZXJhdGUgPSBfcmVmMS5pbnZlcnRMaXRlcmF0ZSwgbG9jYXRpb25EYXRhVG9TdHJpbmcgPSBfcmVmMS5sb2NhdGlvbkRhdGFUb1N0cmluZywgdGhyb3dTeW50YXhFcnJvciA9IF9yZWYxLnRocm93U3ludGF4RXJyb3I7XG5cbiAgZXhwb3J0cy5MZXhlciA9IExleGVyID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIExleGVyKCkge31cblxuICAgIExleGVyLnByb3RvdHlwZS50b2tlbml6ZSA9IGZ1bmN0aW9uKGNvZGUsIG9wdHMpIHtcbiAgICAgIHZhciBjb25zdW1lZCwgaSwgdGFnLCBfcmVmMjtcbiAgICAgIGlmIChvcHRzID09IG51bGwpIHtcbiAgICAgICAgb3B0cyA9IHt9O1xuICAgICAgfVxuICAgICAgdGhpcy5saXRlcmF0ZSA9IG9wdHMubGl0ZXJhdGU7XG4gICAgICB0aGlzLmluZGVudCA9IDA7XG4gICAgICB0aGlzLmJhc2VJbmRlbnQgPSAwO1xuICAgICAgdGhpcy5pbmRlYnQgPSAwO1xuICAgICAgdGhpcy5vdXRkZWJ0ID0gMDtcbiAgICAgIHRoaXMuaW5kZW50cyA9IFtdO1xuICAgICAgdGhpcy5lbmRzID0gW107XG4gICAgICB0aGlzLnRva2VucyA9IFtdO1xuICAgICAgdGhpcy5jaHVua0xpbmUgPSBvcHRzLmxpbmUgfHwgMDtcbiAgICAgIHRoaXMuY2h1bmtDb2x1bW4gPSBvcHRzLmNvbHVtbiB8fCAwO1xuICAgICAgY29kZSA9IHRoaXMuY2xlYW4oY29kZSk7XG4gICAgICBpID0gMDtcbiAgICAgIHdoaWxlICh0aGlzLmNodW5rID0gY29kZS5zbGljZShpKSkge1xuICAgICAgICBjb25zdW1lZCA9IHRoaXMuaWRlbnRpZmllclRva2VuKCkgfHwgdGhpcy5jb21tZW50VG9rZW4oKSB8fCB0aGlzLndoaXRlc3BhY2VUb2tlbigpIHx8IHRoaXMubGluZVRva2VuKCkgfHwgdGhpcy5oZXJlZG9jVG9rZW4oKSB8fCB0aGlzLnN0cmluZ1Rva2VuKCkgfHwgdGhpcy5udW1iZXJUb2tlbigpIHx8IHRoaXMucmVnZXhUb2tlbigpIHx8IHRoaXMuanNUb2tlbigpIHx8IHRoaXMubGl0ZXJhbFRva2VuKCk7XG4gICAgICAgIF9yZWYyID0gdGhpcy5nZXRMaW5lQW5kQ29sdW1uRnJvbUNodW5rKGNvbnN1bWVkKSwgdGhpcy5jaHVua0xpbmUgPSBfcmVmMlswXSwgdGhpcy5jaHVua0NvbHVtbiA9IF9yZWYyWzFdO1xuICAgICAgICBpICs9IGNvbnN1bWVkO1xuICAgICAgfVxuICAgICAgdGhpcy5jbG9zZUluZGVudGF0aW9uKCk7XG4gICAgICBpZiAodGFnID0gdGhpcy5lbmRzLnBvcCgpKSB7XG4gICAgICAgIHRoaXMuZXJyb3IoXCJtaXNzaW5nIFwiICsgdGFnKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRzLnJld3JpdGUgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRva2VucztcbiAgICAgIH1cbiAgICAgIHJldHVybiAobmV3IFJld3JpdGVyKS5yZXdyaXRlKHRoaXMudG9rZW5zKTtcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLmNsZWFuID0gZnVuY3Rpb24oY29kZSkge1xuICAgICAgaWYgKGNvZGUuY2hhckNvZGVBdCgwKSA9PT0gQk9NKSB7XG4gICAgICAgIGNvZGUgPSBjb2RlLnNsaWNlKDEpO1xuICAgICAgfVxuICAgICAgY29kZSA9IGNvZGUucmVwbGFjZSgvXFxyL2csICcnKS5yZXBsYWNlKFRSQUlMSU5HX1NQQUNFUywgJycpO1xuICAgICAgaWYgKFdISVRFU1BBQ0UudGVzdChjb2RlKSkge1xuICAgICAgICBjb2RlID0gXCJcXG5cIiArIGNvZGU7XG4gICAgICAgIHRoaXMuY2h1bmtMaW5lLS07XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5saXRlcmF0ZSkge1xuICAgICAgICBjb2RlID0gaW52ZXJ0TGl0ZXJhdGUoY29kZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY29kZTtcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLmlkZW50aWZpZXJUb2tlbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGNvbG9uLCBjb2xvbk9mZnNldCwgZm9yY2VkSWRlbnRpZmllciwgaWQsIGlkTGVuZ3RoLCBpbnB1dCwgbWF0Y2gsIHBvcHBlZFRva2VuLCBwcmV2LCB0YWcsIHRhZ1Rva2VuLCBfcmVmMiwgX3JlZjMsIF9yZWY0O1xuICAgICAgaWYgKCEobWF0Y2ggPSBJREVOVElGSUVSLmV4ZWModGhpcy5jaHVuaykpKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgICAgaW5wdXQgPSBtYXRjaFswXSwgaWQgPSBtYXRjaFsxXSwgY29sb24gPSBtYXRjaFsyXTtcbiAgICAgIGlkTGVuZ3RoID0gaWQubGVuZ3RoO1xuICAgICAgcG9wcGVkVG9rZW4gPSB2b2lkIDA7XG4gICAgICBpZiAoaWQgPT09ICdvd24nICYmIHRoaXMudGFnKCkgPT09ICdGT1InKSB7XG4gICAgICAgIHRoaXMudG9rZW4oJ09XTicsIGlkKTtcbiAgICAgICAgcmV0dXJuIGlkLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGZvcmNlZElkZW50aWZpZXIgPSBjb2xvbiB8fCAocHJldiA9IGxhc3QodGhpcy50b2tlbnMpKSAmJiAoKChfcmVmMiA9IHByZXZbMF0pID09PSAnLicgfHwgX3JlZjIgPT09ICc/LicgfHwgX3JlZjIgPT09ICc6OicgfHwgX3JlZjIgPT09ICc/OjonKSB8fCAhcHJldi5zcGFjZWQgJiYgcHJldlswXSA9PT0gJ0AnKTtcbiAgICAgIHRhZyA9ICdJREVOVElGSUVSJztcbiAgICAgIGlmICghZm9yY2VkSWRlbnRpZmllciAmJiAoX19pbmRleE9mLmNhbGwoSlNfS0VZV09SRFMsIGlkKSA+PSAwIHx8IF9faW5kZXhPZi5jYWxsKENPRkZFRV9LRVlXT1JEUywgaWQpID49IDApKSB7XG4gICAgICAgIHRhZyA9IGlkLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgIGlmICh0YWcgPT09ICdXSEVOJyAmJiAoX3JlZjMgPSB0aGlzLnRhZygpLCBfX2luZGV4T2YuY2FsbChMSU5FX0JSRUFLLCBfcmVmMykgPj0gMCkpIHtcbiAgICAgICAgICB0YWcgPSAnTEVBRElOR19XSEVOJztcbiAgICAgICAgfSBlbHNlIGlmICh0YWcgPT09ICdGT1InKSB7XG4gICAgICAgICAgdGhpcy5zZWVuRm9yID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmICh0YWcgPT09ICdVTkxFU1MnKSB7XG4gICAgICAgICAgdGFnID0gJ0lGJztcbiAgICAgICAgfSBlbHNlIGlmIChfX2luZGV4T2YuY2FsbChVTkFSWSwgdGFnKSA+PSAwKSB7XG4gICAgICAgICAgdGFnID0gJ1VOQVJZJztcbiAgICAgICAgfSBlbHNlIGlmIChfX2luZGV4T2YuY2FsbChSRUxBVElPTiwgdGFnKSA+PSAwKSB7XG4gICAgICAgICAgaWYgKHRhZyAhPT0gJ0lOU1RBTkNFT0YnICYmIHRoaXMuc2VlbkZvcikge1xuICAgICAgICAgICAgdGFnID0gJ0ZPUicgKyB0YWc7XG4gICAgICAgICAgICB0aGlzLnNlZW5Gb3IgPSBmYWxzZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGFnID0gJ1JFTEFUSU9OJztcbiAgICAgICAgICAgIGlmICh0aGlzLnZhbHVlKCkgPT09ICchJykge1xuICAgICAgICAgICAgICBwb3BwZWRUb2tlbiA9IHRoaXMudG9rZW5zLnBvcCgpO1xuICAgICAgICAgICAgICBpZCA9ICchJyArIGlkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKF9faW5kZXhPZi5jYWxsKEpTX0ZPUkJJRERFTiwgaWQpID49IDApIHtcbiAgICAgICAgaWYgKGZvcmNlZElkZW50aWZpZXIpIHtcbiAgICAgICAgICB0YWcgPSAnSURFTlRJRklFUic7XG4gICAgICAgICAgaWQgPSBuZXcgU3RyaW5nKGlkKTtcbiAgICAgICAgICBpZC5yZXNlcnZlZCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAoX19pbmRleE9mLmNhbGwoUkVTRVJWRUQsIGlkKSA+PSAwKSB7XG4gICAgICAgICAgdGhpcy5lcnJvcihcInJlc2VydmVkIHdvcmQgXFxcIlwiICsgaWQgKyBcIlxcXCJcIik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghZm9yY2VkSWRlbnRpZmllcikge1xuICAgICAgICBpZiAoX19pbmRleE9mLmNhbGwoQ09GRkVFX0FMSUFTRVMsIGlkKSA+PSAwKSB7XG4gICAgICAgICAgaWQgPSBDT0ZGRUVfQUxJQVNfTUFQW2lkXTtcbiAgICAgICAgfVxuICAgICAgICB0YWcgPSAoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgc3dpdGNoIChpZCkge1xuICAgICAgICAgICAgY2FzZSAnISc6XG4gICAgICAgICAgICAgIHJldHVybiAnVU5BUlknO1xuICAgICAgICAgICAgY2FzZSAnPT0nOlxuICAgICAgICAgICAgY2FzZSAnIT0nOlxuICAgICAgICAgICAgICByZXR1cm4gJ0NPTVBBUkUnO1xuICAgICAgICAgICAgY2FzZSAnJiYnOlxuICAgICAgICAgICAgY2FzZSAnfHwnOlxuICAgICAgICAgICAgICByZXR1cm4gJ0xPR0lDJztcbiAgICAgICAgICAgIGNhc2UgJ3RydWUnOlxuICAgICAgICAgICAgY2FzZSAnZmFsc2UnOlxuICAgICAgICAgICAgICByZXR1cm4gJ0JPT0wnO1xuICAgICAgICAgICAgY2FzZSAnYnJlYWsnOlxuICAgICAgICAgICAgY2FzZSAnY29udGludWUnOlxuICAgICAgICAgICAgICByZXR1cm4gJ1NUQVRFTUVOVCc7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gdGFnO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKTtcbiAgICAgIH1cbiAgICAgIHRhZ1Rva2VuID0gdGhpcy50b2tlbih0YWcsIGlkLCAwLCBpZExlbmd0aCk7XG4gICAgICBpZiAocG9wcGVkVG9rZW4pIHtcbiAgICAgICAgX3JlZjQgPSBbcG9wcGVkVG9rZW5bMl0uZmlyc3RfbGluZSwgcG9wcGVkVG9rZW5bMl0uZmlyc3RfY29sdW1uXSwgdGFnVG9rZW5bMl0uZmlyc3RfbGluZSA9IF9yZWY0WzBdLCB0YWdUb2tlblsyXS5maXJzdF9jb2x1bW4gPSBfcmVmNFsxXTtcbiAgICAgIH1cbiAgICAgIGlmIChjb2xvbikge1xuICAgICAgICBjb2xvbk9mZnNldCA9IGlucHV0Lmxhc3RJbmRleE9mKCc6Jyk7XG4gICAgICAgIHRoaXMudG9rZW4oJzonLCAnOicsIGNvbG9uT2Zmc2V0LCBjb2xvbi5sZW5ndGgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlucHV0Lmxlbmd0aDtcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLm51bWJlclRva2VuID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYmluYXJ5TGl0ZXJhbCwgbGV4ZWRMZW5ndGgsIG1hdGNoLCBudW1iZXIsIG9jdGFsTGl0ZXJhbDtcbiAgICAgIGlmICghKG1hdGNoID0gTlVNQkVSLmV4ZWModGhpcy5jaHVuaykpKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgICAgbnVtYmVyID0gbWF0Y2hbMF07XG4gICAgICBpZiAoL14wW0JPWF0vLnRlc3QobnVtYmVyKSkge1xuICAgICAgICB0aGlzLmVycm9yKFwicmFkaXggcHJlZml4ICdcIiArIG51bWJlciArIFwiJyBtdXN0IGJlIGxvd2VyY2FzZVwiKTtcbiAgICAgIH0gZWxzZSBpZiAoL0UvLnRlc3QobnVtYmVyKSAmJiAhL14weC8udGVzdChudW1iZXIpKSB7XG4gICAgICAgIHRoaXMuZXJyb3IoXCJleHBvbmVudGlhbCBub3RhdGlvbiAnXCIgKyBudW1iZXIgKyBcIicgbXVzdCBiZSBpbmRpY2F0ZWQgd2l0aCBhIGxvd2VyY2FzZSAnZSdcIik7XG4gICAgICB9IGVsc2UgaWYgKC9eMFxcZCpbODldLy50ZXN0KG51bWJlcikpIHtcbiAgICAgICAgdGhpcy5lcnJvcihcImRlY2ltYWwgbGl0ZXJhbCAnXCIgKyBudW1iZXIgKyBcIicgbXVzdCBub3QgYmUgcHJlZml4ZWQgd2l0aCAnMCdcIik7XG4gICAgICB9IGVsc2UgaWYgKC9eMFxcZCsvLnRlc3QobnVtYmVyKSkge1xuICAgICAgICB0aGlzLmVycm9yKFwib2N0YWwgbGl0ZXJhbCAnXCIgKyBudW1iZXIgKyBcIicgbXVzdCBiZSBwcmVmaXhlZCB3aXRoICcwbydcIik7XG4gICAgICB9XG4gICAgICBsZXhlZExlbmd0aCA9IG51bWJlci5sZW5ndGg7XG4gICAgICBpZiAob2N0YWxMaXRlcmFsID0gL14wbyhbMC03XSspLy5leGVjKG51bWJlcikpIHtcbiAgICAgICAgbnVtYmVyID0gJzB4JyArIHBhcnNlSW50KG9jdGFsTGl0ZXJhbFsxXSwgOCkudG9TdHJpbmcoMTYpO1xuICAgICAgfVxuICAgICAgaWYgKGJpbmFyeUxpdGVyYWwgPSAvXjBiKFswMV0rKS8uZXhlYyhudW1iZXIpKSB7XG4gICAgICAgIG51bWJlciA9ICcweCcgKyBwYXJzZUludChiaW5hcnlMaXRlcmFsWzFdLCAyKS50b1N0cmluZygxNik7XG4gICAgICB9XG4gICAgICB0aGlzLnRva2VuKCdOVU1CRVInLCBudW1iZXIsIDAsIGxleGVkTGVuZ3RoKTtcbiAgICAgIHJldHVybiBsZXhlZExlbmd0aDtcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLnN0cmluZ1Rva2VuID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaW5uZXIsIGlubmVyTGVuLCBudW1CcmVhaywgb2N0YWxFc2MsIHBvcywgcXVvdGUsIHN0cmluZywgdHJpbW1lZDtcbiAgICAgIHN3aXRjaCAocXVvdGUgPSB0aGlzLmNodW5rLmNoYXJBdCgwKSkge1xuICAgICAgICBjYXNlIFwiJ1wiOlxuICAgICAgICAgIHN0cmluZyA9IChTSU1QTEVTVFIuZXhlYyh0aGlzLmNodW5rKSB8fCBbXSlbMF07XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1wiJzpcbiAgICAgICAgICBzdHJpbmcgPSB0aGlzLmJhbGFuY2VkU3RyaW5nKHRoaXMuY2h1bmssICdcIicpO1xuICAgICAgfVxuICAgICAgaWYgKCFzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBpbm5lciA9IHN0cmluZy5zbGljZSgxLCAtMSk7XG4gICAgICB0cmltbWVkID0gdGhpcy5yZW1vdmVOZXdsaW5lcyhpbm5lcik7XG4gICAgICBpZiAocXVvdGUgPT09ICdcIicgJiYgMCA8IHN0cmluZy5pbmRleE9mKCcjeycsIDEpKSB7XG4gICAgICAgIG51bUJyZWFrID0gcG9zID0gMDtcbiAgICAgICAgaW5uZXJMZW4gPSBpbm5lci5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChpbm5lci5jaGFyQXQocG9zKyspID09PSAnXFxuJyAmJiBwb3MgPCBpbm5lckxlbikge1xuICAgICAgICAgIG51bUJyZWFrKys7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbnRlcnBvbGF0ZVN0cmluZyh0cmltbWVkLCB7XG4gICAgICAgICAgc3RyT2Zmc2V0OiAxICsgbnVtQnJlYWssXG4gICAgICAgICAgbGV4ZWRMZW5ndGg6IHN0cmluZy5sZW5ndGhcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnRva2VuKCdTVFJJTkcnLCBxdW90ZSArIHRoaXMuZXNjYXBlTGluZXModHJpbW1lZCkgKyBxdW90ZSwgMCwgc3RyaW5nLmxlbmd0aCk7XG4gICAgICB9XG4gICAgICBpZiAob2N0YWxFc2MgPSAvXig/OlxcXFwufFteXFxcXF0pKlxcXFwoPzowWzAtN118WzEtN10pLy50ZXN0KHN0cmluZykpIHtcbiAgICAgICAgdGhpcy5lcnJvcihcIm9jdGFsIGVzY2FwZSBzZXF1ZW5jZXMgXCIgKyBzdHJpbmcgKyBcIiBhcmUgbm90IGFsbG93ZWRcIik7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RyaW5nLmxlbmd0aDtcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLmhlcmVkb2NUb2tlbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGRvYywgaGVyZWRvYywgbWF0Y2gsIHF1b3RlLCBzdHJPZmZzZXQ7XG4gICAgICBpZiAoIShtYXRjaCA9IEhFUkVET0MuZXhlYyh0aGlzLmNodW5rKSkpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBoZXJlZG9jID0gbWF0Y2hbMF07XG4gICAgICBxdW90ZSA9IGhlcmVkb2MuY2hhckF0KDApO1xuICAgICAgZG9jID0gdGhpcy5zYW5pdGl6ZUhlcmVkb2MobWF0Y2hbMl0sIHtcbiAgICAgICAgcXVvdGU6IHF1b3RlLFxuICAgICAgICBpbmRlbnQ6IG51bGxcbiAgICAgIH0pO1xuICAgICAgaWYgKHF1b3RlID09PSAnXCInICYmIDAgPD0gZG9jLmluZGV4T2YoJyN7JykpIHtcbiAgICAgICAgc3RyT2Zmc2V0ID0gbWF0Y2hbMl0uY2hhckF0KDApID09PSAnXFxuJyA/IDQgOiAzO1xuICAgICAgICB0aGlzLmludGVycG9sYXRlU3RyaW5nKGRvYywge1xuICAgICAgICAgIGhlcmVkb2M6IHRydWUsXG4gICAgICAgICAgc3RyT2Zmc2V0OiBzdHJPZmZzZXQsXG4gICAgICAgICAgbGV4ZWRMZW5ndGg6IGhlcmVkb2MubGVuZ3RoXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy50b2tlbignU1RSSU5HJywgdGhpcy5tYWtlU3RyaW5nKGRvYywgcXVvdGUsIHRydWUpLCAwLCBoZXJlZG9jLmxlbmd0aCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGVyZWRvYy5sZW5ndGg7XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS5jb21tZW50VG9rZW4gPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjb21tZW50LCBoZXJlLCBtYXRjaDtcbiAgICAgIGlmICghKG1hdGNoID0gdGhpcy5jaHVuay5tYXRjaChDT01NRU5UKSkpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBjb21tZW50ID0gbWF0Y2hbMF0sIGhlcmUgPSBtYXRjaFsxXTtcbiAgICAgIGlmIChoZXJlKSB7XG4gICAgICAgIHRoaXMudG9rZW4oJ0hFUkVDT01NRU5UJywgdGhpcy5zYW5pdGl6ZUhlcmVkb2MoaGVyZSwge1xuICAgICAgICAgIGhlcmVjb21tZW50OiB0cnVlLFxuICAgICAgICAgIGluZGVudDogcmVwZWF0KCcgJywgdGhpcy5pbmRlbnQpXG4gICAgICAgIH0pLCAwLCBjb21tZW50Lmxlbmd0aCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY29tbWVudC5sZW5ndGg7XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS5qc1Rva2VuID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgbWF0Y2gsIHNjcmlwdDtcbiAgICAgIGlmICghKHRoaXMuY2h1bmsuY2hhckF0KDApID09PSAnYCcgJiYgKG1hdGNoID0gSlNUT0tFTi5leGVjKHRoaXMuY2h1bmspKSkpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICB0aGlzLnRva2VuKCdKUycsIChzY3JpcHQgPSBtYXRjaFswXSkuc2xpY2UoMSwgLTEpLCAwLCBzY3JpcHQubGVuZ3RoKTtcbiAgICAgIHJldHVybiBzY3JpcHQubGVuZ3RoO1xuICAgIH07XG5cbiAgICBMZXhlci5wcm90b3R5cGUucmVnZXhUb2tlbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGZsYWdzLCBsZW5ndGgsIG1hdGNoLCBwcmV2LCByZWdleCwgX3JlZjIsIF9yZWYzO1xuICAgICAgaWYgKHRoaXMuY2h1bmsuY2hhckF0KDApICE9PSAnLycpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBpZiAobGVuZ3RoID0gdGhpcy5oZXJlZ2V4VG9rZW4oKSkge1xuICAgICAgICByZXR1cm4gbGVuZ3RoO1xuICAgICAgfVxuICAgICAgcHJldiA9IGxhc3QodGhpcy50b2tlbnMpO1xuICAgICAgaWYgKHByZXYgJiYgKF9yZWYyID0gcHJldlswXSwgX19pbmRleE9mLmNhbGwoKHByZXYuc3BhY2VkID8gTk9UX1JFR0VYIDogTk9UX1NQQUNFRF9SRUdFWCksIF9yZWYyKSA+PSAwKSkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmICghKG1hdGNoID0gUkVHRVguZXhlYyh0aGlzLmNodW5rKSkpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBfcmVmMyA9IG1hdGNoLCBtYXRjaCA9IF9yZWYzWzBdLCByZWdleCA9IF9yZWYzWzFdLCBmbGFncyA9IF9yZWYzWzJdO1xuICAgICAgaWYgKHJlZ2V4ID09PSAnLy8nKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgICAgaWYgKHJlZ2V4LnNsaWNlKDAsIDIpID09PSAnLyonKSB7XG4gICAgICAgIHRoaXMuZXJyb3IoJ3JlZ3VsYXIgZXhwcmVzc2lvbnMgY2Fubm90IGJlZ2luIHdpdGggYCpgJyk7XG4gICAgICB9XG4gICAgICB0aGlzLnRva2VuKCdSRUdFWCcsIFwiXCIgKyByZWdleCArIGZsYWdzLCAwLCBtYXRjaC5sZW5ndGgpO1xuICAgICAgcmV0dXJuIG1hdGNoLmxlbmd0aDtcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLmhlcmVnZXhUb2tlbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJvZHksIGZsYWdzLCBmbGFnc09mZnNldCwgaGVyZWdleCwgbWF0Y2gsIHBsdXNUb2tlbiwgcHJldiwgcmUsIHRhZywgdG9rZW4sIHRva2VucywgdmFsdWUsIF9pLCBfbGVuLCBfcmVmMiwgX3JlZjMsIF9yZWY0O1xuICAgICAgaWYgKCEobWF0Y2ggPSBIRVJFR0VYLmV4ZWModGhpcy5jaHVuaykpKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgICAgaGVyZWdleCA9IG1hdGNoWzBdLCBib2R5ID0gbWF0Y2hbMV0sIGZsYWdzID0gbWF0Y2hbMl07XG4gICAgICBpZiAoMCA+IGJvZHkuaW5kZXhPZignI3snKSkge1xuICAgICAgICByZSA9IHRoaXMuZXNjYXBlTGluZXMoYm9keS5yZXBsYWNlKEhFUkVHRVhfT01JVCwgJyQxJDInKS5yZXBsYWNlKC9cXC8vZywgJ1xcXFwvJyksIHRydWUpO1xuICAgICAgICBpZiAocmUubWF0Y2goL15cXCovKSkge1xuICAgICAgICAgIHRoaXMuZXJyb3IoJ3JlZ3VsYXIgZXhwcmVzc2lvbnMgY2Fubm90IGJlZ2luIHdpdGggYCpgJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50b2tlbignUkVHRVgnLCBcIi9cIiArIChyZSB8fCAnKD86KScpICsgXCIvXCIgKyBmbGFncywgMCwgaGVyZWdleC5sZW5ndGgpO1xuICAgICAgICByZXR1cm4gaGVyZWdleC5sZW5ndGg7XG4gICAgICB9XG4gICAgICB0aGlzLnRva2VuKCdJREVOVElGSUVSJywgJ1JlZ0V4cCcsIDAsIDApO1xuICAgICAgdGhpcy50b2tlbignQ0FMTF9TVEFSVCcsICcoJywgMCwgMCk7XG4gICAgICB0b2tlbnMgPSBbXTtcbiAgICAgIF9yZWYyID0gdGhpcy5pbnRlcnBvbGF0ZVN0cmluZyhib2R5LCB7XG4gICAgICAgIHJlZ2V4OiB0cnVlLFxuICAgICAgICBzdHJPZmZzZXQ6IDNcbiAgICAgIH0pO1xuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBfcmVmMi5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgICB0b2tlbiA9IF9yZWYyW19pXTtcbiAgICAgICAgdGFnID0gdG9rZW5bMF0sIHZhbHVlID0gdG9rZW5bMV07XG4gICAgICAgIGlmICh0YWcgPT09ICdUT0tFTlMnKSB7XG4gICAgICAgICAgdG9rZW5zLnB1c2guYXBwbHkodG9rZW5zLCB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGFnID09PSAnTkVPU1RSSU5HJykge1xuICAgICAgICAgIGlmICghKHZhbHVlID0gdmFsdWUucmVwbGFjZShIRVJFR0VYX09NSVQsICckMSQyJykpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXFxcL2csICdcXFxcXFxcXCcpO1xuICAgICAgICAgIHRva2VuWzBdID0gJ1NUUklORyc7XG4gICAgICAgICAgdG9rZW5bMV0gPSB0aGlzLm1ha2VTdHJpbmcodmFsdWUsICdcIicsIHRydWUpO1xuICAgICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmVycm9yKFwiVW5leHBlY3RlZCBcIiArIHRhZyk7XG4gICAgICAgIH1cbiAgICAgICAgcHJldiA9IGxhc3QodGhpcy50b2tlbnMpO1xuICAgICAgICBwbHVzVG9rZW4gPSBbJysnLCAnKyddO1xuICAgICAgICBwbHVzVG9rZW5bMl0gPSBwcmV2WzJdO1xuICAgICAgICB0b2tlbnMucHVzaChwbHVzVG9rZW4pO1xuICAgICAgfVxuICAgICAgdG9rZW5zLnBvcCgpO1xuICAgICAgaWYgKCgoX3JlZjMgPSB0b2tlbnNbMF0pICE9IG51bGwgPyBfcmVmM1swXSA6IHZvaWQgMCkgIT09ICdTVFJJTkcnKSB7XG4gICAgICAgIHRoaXMudG9rZW4oJ1NUUklORycsICdcIlwiJywgMCwgMCk7XG4gICAgICAgIHRoaXMudG9rZW4oJysnLCAnKycsIDAsIDApO1xuICAgICAgfVxuICAgICAgKF9yZWY0ID0gdGhpcy50b2tlbnMpLnB1c2guYXBwbHkoX3JlZjQsIHRva2Vucyk7XG4gICAgICBpZiAoZmxhZ3MpIHtcbiAgICAgICAgZmxhZ3NPZmZzZXQgPSBoZXJlZ2V4Lmxhc3RJbmRleE9mKGZsYWdzKTtcbiAgICAgICAgdGhpcy50b2tlbignLCcsICcsJywgZmxhZ3NPZmZzZXQsIDApO1xuICAgICAgICB0aGlzLnRva2VuKCdTVFJJTkcnLCAnXCInICsgZmxhZ3MgKyAnXCInLCBmbGFnc09mZnNldCwgZmxhZ3MubGVuZ3RoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudG9rZW4oJyknLCAnKScsIGhlcmVnZXgubGVuZ3RoIC0gMSwgMCk7XG4gICAgICByZXR1cm4gaGVyZWdleC5sZW5ndGg7XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS5saW5lVG9rZW4gPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBkaWZmLCBpbmRlbnQsIG1hdGNoLCBub05ld2xpbmVzLCBzaXplO1xuICAgICAgaWYgKCEobWF0Y2ggPSBNVUxUSV9ERU5ULmV4ZWModGhpcy5jaHVuaykpKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgICAgaW5kZW50ID0gbWF0Y2hbMF07XG4gICAgICB0aGlzLnNlZW5Gb3IgPSBmYWxzZTtcbiAgICAgIHNpemUgPSBpbmRlbnQubGVuZ3RoIC0gMSAtIGluZGVudC5sYXN0SW5kZXhPZignXFxuJyk7XG4gICAgICBub05ld2xpbmVzID0gdGhpcy51bmZpbmlzaGVkKCk7XG4gICAgICBpZiAoc2l6ZSAtIHRoaXMuaW5kZWJ0ID09PSB0aGlzLmluZGVudCkge1xuICAgICAgICBpZiAobm9OZXdsaW5lcykge1xuICAgICAgICAgIHRoaXMuc3VwcHJlc3NOZXdsaW5lcygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMubmV3bGluZVRva2VuKDApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbmRlbnQubGVuZ3RoO1xuICAgICAgfVxuICAgICAgaWYgKHNpemUgPiB0aGlzLmluZGVudCkge1xuICAgICAgICBpZiAobm9OZXdsaW5lcykge1xuICAgICAgICAgIHRoaXMuaW5kZWJ0ID0gc2l6ZSAtIHRoaXMuaW5kZW50O1xuICAgICAgICAgIHRoaXMuc3VwcHJlc3NOZXdsaW5lcygpO1xuICAgICAgICAgIHJldHVybiBpbmRlbnQubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy50b2tlbnMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhpcy5iYXNlSW5kZW50ID0gdGhpcy5pbmRlbnQgPSBzaXplO1xuICAgICAgICAgIHJldHVybiBpbmRlbnQubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGRpZmYgPSBzaXplIC0gdGhpcy5pbmRlbnQgKyB0aGlzLm91dGRlYnQ7XG4gICAgICAgIHRoaXMudG9rZW4oJ0lOREVOVCcsIGRpZmYsIGluZGVudC5sZW5ndGggLSBzaXplLCBzaXplKTtcbiAgICAgICAgdGhpcy5pbmRlbnRzLnB1c2goZGlmZik7XG4gICAgICAgIHRoaXMuZW5kcy5wdXNoKCdPVVRERU5UJyk7XG4gICAgICAgIHRoaXMub3V0ZGVidCA9IHRoaXMuaW5kZWJ0ID0gMDtcbiAgICAgICAgdGhpcy5pbmRlbnQgPSBzaXplO1xuICAgICAgfSBlbHNlIGlmIChzaXplIDwgdGhpcy5iYXNlSW5kZW50KSB7XG4gICAgICAgIHRoaXMuZXJyb3IoJ21pc3NpbmcgaW5kZW50YXRpb24nLCBpbmRlbnQubGVuZ3RoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaW5kZWJ0ID0gMDtcbiAgICAgICAgdGhpcy5vdXRkZW50VG9rZW4odGhpcy5pbmRlbnQgLSBzaXplLCBub05ld2xpbmVzLCBpbmRlbnQubGVuZ3RoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpbmRlbnQubGVuZ3RoO1xuICAgIH07XG5cbiAgICBMZXhlci5wcm90b3R5cGUub3V0ZGVudFRva2VuID0gZnVuY3Rpb24obW92ZU91dCwgbm9OZXdsaW5lcywgb3V0ZGVudExlbmd0aCkge1xuICAgICAgdmFyIGRlY3JlYXNlZEluZGVudCwgZGVudCwgbGFzdEluZGVudCwgX3JlZjI7XG4gICAgICBkZWNyZWFzZWRJbmRlbnQgPSB0aGlzLmluZGVudCAtIG1vdmVPdXQ7XG4gICAgICB3aGlsZSAobW92ZU91dCA+IDApIHtcbiAgICAgICAgbGFzdEluZGVudCA9IHRoaXMuaW5kZW50c1t0aGlzLmluZGVudHMubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmICghbGFzdEluZGVudCkge1xuICAgICAgICAgIG1vdmVPdXQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGxhc3RJbmRlbnQgPT09IHRoaXMub3V0ZGVidCkge1xuICAgICAgICAgIG1vdmVPdXQgLT0gdGhpcy5vdXRkZWJ0O1xuICAgICAgICAgIHRoaXMub3V0ZGVidCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAobGFzdEluZGVudCA8IHRoaXMub3V0ZGVidCkge1xuICAgICAgICAgIHRoaXMub3V0ZGVidCAtPSBsYXN0SW5kZW50O1xuICAgICAgICAgIG1vdmVPdXQgLT0gbGFzdEluZGVudDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZW50ID0gdGhpcy5pbmRlbnRzLnBvcCgpICsgdGhpcy5vdXRkZWJ0O1xuICAgICAgICAgIGlmIChvdXRkZW50TGVuZ3RoICYmIChfcmVmMiA9IHRoaXMuY2h1bmtbb3V0ZGVudExlbmd0aF0sIF9faW5kZXhPZi5jYWxsKElOREVOVEFCTEVfQ0xPU0VSUywgX3JlZjIpID49IDApKSB7XG4gICAgICAgICAgICBkZWNyZWFzZWRJbmRlbnQgLT0gZGVudCAtIG1vdmVPdXQ7XG4gICAgICAgICAgICBtb3ZlT3V0ID0gZGVudDtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5vdXRkZWJ0ID0gMDtcbiAgICAgICAgICB0aGlzLnBhaXIoJ09VVERFTlQnKTtcbiAgICAgICAgICB0aGlzLnRva2VuKCdPVVRERU5UJywgbW92ZU91dCwgMCwgb3V0ZGVudExlbmd0aCk7XG4gICAgICAgICAgbW92ZU91dCAtPSBkZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZGVudCkge1xuICAgICAgICB0aGlzLm91dGRlYnQgLT0gbW92ZU91dDtcbiAgICAgIH1cbiAgICAgIHdoaWxlICh0aGlzLnZhbHVlKCkgPT09ICc7Jykge1xuICAgICAgICB0aGlzLnRva2Vucy5wb3AoKTtcbiAgICAgIH1cbiAgICAgIGlmICghKHRoaXMudGFnKCkgPT09ICdURVJNSU5BVE9SJyB8fCBub05ld2xpbmVzKSkge1xuICAgICAgICB0aGlzLnRva2VuKCdURVJNSU5BVE9SJywgJ1xcbicsIG91dGRlbnRMZW5ndGgsIDApO1xuICAgICAgfVxuICAgICAgdGhpcy5pbmRlbnQgPSBkZWNyZWFzZWRJbmRlbnQ7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLndoaXRlc3BhY2VUb2tlbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG1hdGNoLCBubGluZSwgcHJldjtcbiAgICAgIGlmICghKChtYXRjaCA9IFdISVRFU1BBQ0UuZXhlYyh0aGlzLmNodW5rKSkgfHwgKG5saW5lID0gdGhpcy5jaHVuay5jaGFyQXQoMCkgPT09ICdcXG4nKSkpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBwcmV2ID0gbGFzdCh0aGlzLnRva2Vucyk7XG4gICAgICBpZiAocHJldikge1xuICAgICAgICBwcmV2W21hdGNoID8gJ3NwYWNlZCcgOiAnbmV3TGluZSddID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICByZXR1cm4gbWF0Y2hbMF0ubGVuZ3RoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS5uZXdsaW5lVG9rZW4gPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgICAgIHdoaWxlICh0aGlzLnZhbHVlKCkgPT09ICc7Jykge1xuICAgICAgICB0aGlzLnRva2Vucy5wb3AoKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnRhZygpICE9PSAnVEVSTUlOQVRPUicpIHtcbiAgICAgICAgdGhpcy50b2tlbignVEVSTUlOQVRPUicsICdcXG4nLCBvZmZzZXQsIDApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS5zdXBwcmVzc05ld2xpbmVzID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy52YWx1ZSgpID09PSAnXFxcXCcpIHtcbiAgICAgICAgdGhpcy50b2tlbnMucG9wKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLmxpdGVyYWxUb2tlbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG1hdGNoLCBwcmV2LCB0YWcsIHZhbHVlLCBfcmVmMiwgX3JlZjMsIF9yZWY0LCBfcmVmNTtcbiAgICAgIGlmIChtYXRjaCA9IE9QRVJBVE9SLmV4ZWModGhpcy5jaHVuaykpIHtcbiAgICAgICAgdmFsdWUgPSBtYXRjaFswXTtcbiAgICAgICAgaWYgKENPREUudGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICB0aGlzLnRhZ1BhcmFtZXRlcnMoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLmNodW5rLmNoYXJBdCgwKTtcbiAgICAgIH1cbiAgICAgIHRhZyA9IHZhbHVlO1xuICAgICAgcHJldiA9IGxhc3QodGhpcy50b2tlbnMpO1xuICAgICAgaWYgKHZhbHVlID09PSAnPScgJiYgcHJldikge1xuICAgICAgICBpZiAoIXByZXZbMV0ucmVzZXJ2ZWQgJiYgKF9yZWYyID0gcHJldlsxXSwgX19pbmRleE9mLmNhbGwoSlNfRk9SQklEREVOLCBfcmVmMikgPj0gMCkpIHtcbiAgICAgICAgICB0aGlzLmVycm9yKFwicmVzZXJ2ZWQgd29yZCBcXFwiXCIgKyAodGhpcy52YWx1ZSgpKSArIFwiXFxcIiBjYW4ndCBiZSBhc3NpZ25lZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKF9yZWYzID0gcHJldlsxXSkgPT09ICd8fCcgfHwgX3JlZjMgPT09ICcmJicpIHtcbiAgICAgICAgICBwcmV2WzBdID0gJ0NPTVBPVU5EX0FTU0lHTic7XG4gICAgICAgICAgcHJldlsxXSArPSAnPSc7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHZhbHVlID09PSAnOycpIHtcbiAgICAgICAgdGhpcy5zZWVuRm9yID0gZmFsc2U7XG4gICAgICAgIHRhZyA9ICdURVJNSU5BVE9SJztcbiAgICAgIH0gZWxzZSBpZiAoX19pbmRleE9mLmNhbGwoTUFUSCwgdmFsdWUpID49IDApIHtcbiAgICAgICAgdGFnID0gJ01BVEgnO1xuICAgICAgfSBlbHNlIGlmIChfX2luZGV4T2YuY2FsbChDT01QQVJFLCB2YWx1ZSkgPj0gMCkge1xuICAgICAgICB0YWcgPSAnQ09NUEFSRSc7XG4gICAgICB9IGVsc2UgaWYgKF9faW5kZXhPZi5jYWxsKENPTVBPVU5EX0FTU0lHTiwgdmFsdWUpID49IDApIHtcbiAgICAgICAgdGFnID0gJ0NPTVBPVU5EX0FTU0lHTic7XG4gICAgICB9IGVsc2UgaWYgKF9faW5kZXhPZi5jYWxsKFVOQVJZLCB2YWx1ZSkgPj0gMCkge1xuICAgICAgICB0YWcgPSAnVU5BUlknO1xuICAgICAgfSBlbHNlIGlmIChfX2luZGV4T2YuY2FsbChVTkFSWV9NQVRILCB2YWx1ZSkgPj0gMCkge1xuICAgICAgICB0YWcgPSAnVU5BUllfTUFUSCc7XG4gICAgICB9IGVsc2UgaWYgKF9faW5kZXhPZi5jYWxsKFNISUZULCB2YWx1ZSkgPj0gMCkge1xuICAgICAgICB0YWcgPSAnU0hJRlQnO1xuICAgICAgfSBlbHNlIGlmIChfX2luZGV4T2YuY2FsbChMT0dJQywgdmFsdWUpID49IDAgfHwgdmFsdWUgPT09ICc/JyAmJiAocHJldiAhPSBudWxsID8gcHJldi5zcGFjZWQgOiB2b2lkIDApKSB7XG4gICAgICAgIHRhZyA9ICdMT0dJQyc7XG4gICAgICB9IGVsc2UgaWYgKHByZXYgJiYgIXByZXYuc3BhY2VkKSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gJygnICYmIChfcmVmNCA9IHByZXZbMF0sIF9faW5kZXhPZi5jYWxsKENBTExBQkxFLCBfcmVmNCkgPj0gMCkpIHtcbiAgICAgICAgICBpZiAocHJldlswXSA9PT0gJz8nKSB7XG4gICAgICAgICAgICBwcmV2WzBdID0gJ0ZVTkNfRVhJU1QnO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0YWcgPSAnQ0FMTF9TVEFSVCc7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICdbJyAmJiAoX3JlZjUgPSBwcmV2WzBdLCBfX2luZGV4T2YuY2FsbChJTkRFWEFCTEUsIF9yZWY1KSA+PSAwKSkge1xuICAgICAgICAgIHRhZyA9ICdJTkRFWF9TVEFSVCc7XG4gICAgICAgICAgc3dpdGNoIChwcmV2WzBdKSB7XG4gICAgICAgICAgICBjYXNlICc/JzpcbiAgICAgICAgICAgICAgcHJldlswXSA9ICdJTkRFWF9TT0FLJztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN3aXRjaCAodmFsdWUpIHtcbiAgICAgICAgY2FzZSAnKCc6XG4gICAgICAgIGNhc2UgJ3snOlxuICAgICAgICBjYXNlICdbJzpcbiAgICAgICAgICB0aGlzLmVuZHMucHVzaChJTlZFUlNFU1t2YWx1ZV0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICcpJzpcbiAgICAgICAgY2FzZSAnfSc6XG4gICAgICAgIGNhc2UgJ10nOlxuICAgICAgICAgIHRoaXMucGFpcih2YWx1ZSk7XG4gICAgICB9XG4gICAgICB0aGlzLnRva2VuKHRhZywgdmFsdWUpO1xuICAgICAgcmV0dXJuIHZhbHVlLmxlbmd0aDtcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLnNhbml0aXplSGVyZWRvYyA9IGZ1bmN0aW9uKGRvYywgb3B0aW9ucykge1xuICAgICAgdmFyIGF0dGVtcHQsIGhlcmVjb21tZW50LCBpbmRlbnQsIG1hdGNoLCBfcmVmMjtcbiAgICAgIGluZGVudCA9IG9wdGlvbnMuaW5kZW50LCBoZXJlY29tbWVudCA9IG9wdGlvbnMuaGVyZWNvbW1lbnQ7XG4gICAgICBpZiAoaGVyZWNvbW1lbnQpIHtcbiAgICAgICAgaWYgKEhFUkVET0NfSUxMRUdBTC50ZXN0KGRvYykpIHtcbiAgICAgICAgICB0aGlzLmVycm9yKFwiYmxvY2sgY29tbWVudCBjYW5ub3QgY29udGFpbiBcXFwiKi9cXFwiLCBzdGFydGluZ1wiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZG9jLmluZGV4T2YoJ1xcbicpIDwgMCkge1xuICAgICAgICAgIHJldHVybiBkb2M7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdoaWxlIChtYXRjaCA9IEhFUkVET0NfSU5ERU5ULmV4ZWMoZG9jKSkge1xuICAgICAgICAgIGF0dGVtcHQgPSBtYXRjaFsxXTtcbiAgICAgICAgICBpZiAoaW5kZW50ID09PSBudWxsIHx8ICgwIDwgKF9yZWYyID0gYXR0ZW1wdC5sZW5ndGgpICYmIF9yZWYyIDwgaW5kZW50Lmxlbmd0aCkpIHtcbiAgICAgICAgICAgIGluZGVudCA9IGF0dGVtcHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaW5kZW50KSB7XG4gICAgICAgIGRvYyA9IGRvYy5yZXBsYWNlKFJlZ0V4cChcIlxcXFxuXCIgKyBpbmRlbnQsIFwiZ1wiKSwgJ1xcbicpO1xuICAgICAgfVxuICAgICAgaWYgKCFoZXJlY29tbWVudCkge1xuICAgICAgICBkb2MgPSBkb2MucmVwbGFjZSgvXlxcbi8sICcnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkb2M7XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS50YWdQYXJhbWV0ZXJzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaSwgc3RhY2ssIHRvaywgdG9rZW5zO1xuICAgICAgaWYgKHRoaXMudGFnKCkgIT09ICcpJykge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHN0YWNrID0gW107XG4gICAgICB0b2tlbnMgPSB0aGlzLnRva2VucztcbiAgICAgIGkgPSB0b2tlbnMubGVuZ3RoO1xuICAgICAgdG9rZW5zWy0taV1bMF0gPSAnUEFSQU1fRU5EJztcbiAgICAgIHdoaWxlICh0b2sgPSB0b2tlbnNbLS1pXSkge1xuICAgICAgICBzd2l0Y2ggKHRva1swXSkge1xuICAgICAgICAgIGNhc2UgJyknOlxuICAgICAgICAgICAgc3RhY2sucHVzaCh0b2spO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnKCc6XG4gICAgICAgICAgY2FzZSAnQ0FMTF9TVEFSVCc6XG4gICAgICAgICAgICBpZiAoc3RhY2subGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0b2tbMF0gPT09ICcoJykge1xuICAgICAgICAgICAgICB0b2tbMF0gPSAnUEFSQU1fU1RBUlQnO1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLmNsb3NlSW5kZW50YXRpb24gPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLm91dGRlbnRUb2tlbih0aGlzLmluZGVudCk7XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS5iYWxhbmNlZFN0cmluZyA9IGZ1bmN0aW9uKHN0ciwgZW5kKSB7XG4gICAgICB2YXIgY29udGludWVDb3VudCwgaSwgbGV0dGVyLCBtYXRjaCwgcHJldiwgc3RhY2ssIF9pLCBfcmVmMjtcbiAgICAgIGNvbnRpbnVlQ291bnQgPSAwO1xuICAgICAgc3RhY2sgPSBbZW5kXTtcbiAgICAgIGZvciAoaSA9IF9pID0gMSwgX3JlZjIgPSBzdHIubGVuZ3RoOyAxIDw9IF9yZWYyID8gX2kgPCBfcmVmMiA6IF9pID4gX3JlZjI7IGkgPSAxIDw9IF9yZWYyID8gKytfaSA6IC0tX2kpIHtcbiAgICAgICAgaWYgKGNvbnRpbnVlQ291bnQpIHtcbiAgICAgICAgICAtLWNvbnRpbnVlQ291bnQ7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoIChsZXR0ZXIgPSBzdHIuY2hhckF0KGkpKSB7XG4gICAgICAgICAgY2FzZSAnXFxcXCc6XG4gICAgICAgICAgICArK2NvbnRpbnVlQ291bnQ7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICBjYXNlIGVuZDpcbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgaWYgKCFzdGFjay5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHN0ci5zbGljZSgwLCAraSArIDEgfHwgOWU5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVuZCA9IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuZCA9PT0gJ30nICYmIChsZXR0ZXIgPT09ICdcIicgfHwgbGV0dGVyID09PSBcIidcIikpIHtcbiAgICAgICAgICBzdGFjay5wdXNoKGVuZCA9IGxldHRlcik7XG4gICAgICAgIH0gZWxzZSBpZiAoZW5kID09PSAnfScgJiYgbGV0dGVyID09PSAnLycgJiYgKG1hdGNoID0gSEVSRUdFWC5leGVjKHN0ci5zbGljZShpKSkgfHwgUkVHRVguZXhlYyhzdHIuc2xpY2UoaSkpKSkge1xuICAgICAgICAgIGNvbnRpbnVlQ291bnQgKz0gbWF0Y2hbMF0ubGVuZ3RoIC0gMTtcbiAgICAgICAgfSBlbHNlIGlmIChlbmQgPT09ICd9JyAmJiBsZXR0ZXIgPT09ICd7Jykge1xuICAgICAgICAgIHN0YWNrLnB1c2goZW5kID0gJ30nKTtcbiAgICAgICAgfSBlbHNlIGlmIChlbmQgPT09ICdcIicgJiYgcHJldiA9PT0gJyMnICYmIGxldHRlciA9PT0gJ3snKSB7XG4gICAgICAgICAgc3RhY2sucHVzaChlbmQgPSAnfScpO1xuICAgICAgICB9XG4gICAgICAgIHByZXYgPSBsZXR0ZXI7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5lcnJvcihcIm1pc3NpbmcgXCIgKyAoc3RhY2sucG9wKCkpICsgXCIsIHN0YXJ0aW5nXCIpO1xuICAgIH07XG5cbiAgICBMZXhlci5wcm90b3R5cGUuaW50ZXJwb2xhdGVTdHJpbmcgPSBmdW5jdGlvbihzdHIsIG9wdGlvbnMpIHtcbiAgICAgIHZhciBjb2x1bW4sIGVycm9yVG9rZW4sIGV4cHIsIGhlcmVkb2MsIGksIGlubmVyLCBpbnRlcnBvbGF0ZWQsIGxlbiwgbGV0dGVyLCBsZXhlZExlbmd0aCwgbGluZSwgbG9jYXRpb25Ub2tlbiwgbmVzdGVkLCBvZmZzZXRJbkNodW5rLCBwaSwgcGx1c1Rva2VuLCBwb3BwZWQsIHJlZ2V4LCBycGFyZW4sIHN0ck9mZnNldCwgdGFnLCB0b2tlbiwgdG9rZW5zLCB2YWx1ZSwgX2ksIF9sZW4sIF9yZWYyLCBfcmVmMywgX3JlZjQ7XG4gICAgICBpZiAob3B0aW9ucyA9PSBudWxsKSB7XG4gICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgIH1cbiAgICAgIGhlcmVkb2MgPSBvcHRpb25zLmhlcmVkb2MsIHJlZ2V4ID0gb3B0aW9ucy5yZWdleCwgb2Zmc2V0SW5DaHVuayA9IG9wdGlvbnMub2Zmc2V0SW5DaHVuaywgc3RyT2Zmc2V0ID0gb3B0aW9ucy5zdHJPZmZzZXQsIGxleGVkTGVuZ3RoID0gb3B0aW9ucy5sZXhlZExlbmd0aDtcbiAgICAgIG9mZnNldEluQ2h1bmsgfHwgKG9mZnNldEluQ2h1bmsgPSAwKTtcbiAgICAgIHN0ck9mZnNldCB8fCAoc3RyT2Zmc2V0ID0gMCk7XG4gICAgICBsZXhlZExlbmd0aCB8fCAobGV4ZWRMZW5ndGggPSBzdHIubGVuZ3RoKTtcbiAgICAgIHRva2VucyA9IFtdO1xuICAgICAgcGkgPSAwO1xuICAgICAgaSA9IC0xO1xuICAgICAgd2hpbGUgKGxldHRlciA9IHN0ci5jaGFyQXQoaSArPSAxKSkge1xuICAgICAgICBpZiAobGV0dGVyID09PSAnXFxcXCcpIHtcbiAgICAgICAgICBpICs9IDE7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEobGV0dGVyID09PSAnIycgJiYgc3RyLmNoYXJBdChpICsgMSkgPT09ICd7JyAmJiAoZXhwciA9IHRoaXMuYmFsYW5jZWRTdHJpbmcoc3RyLnNsaWNlKGkgKyAxKSwgJ30nKSkpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBpIDwgaSkge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHRoaXMubWFrZVRva2VuKCdORU9TVFJJTkcnLCBzdHIuc2xpY2UocGksIGkpLCBzdHJPZmZzZXQgKyBwaSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZXJyb3JUb2tlbikge1xuICAgICAgICAgIGVycm9yVG9rZW4gPSB0aGlzLm1ha2VUb2tlbignJywgJ3N0cmluZyBpbnRlcnBvbGF0aW9uJywgb2Zmc2V0SW5DaHVuayArIGkgKyAxLCAyKTtcbiAgICAgICAgfVxuICAgICAgICBpbm5lciA9IGV4cHIuc2xpY2UoMSwgLTEpO1xuICAgICAgICBpZiAoaW5uZXIubGVuZ3RoKSB7XG4gICAgICAgICAgX3JlZjIgPSB0aGlzLmdldExpbmVBbmRDb2x1bW5Gcm9tQ2h1bmsoc3RyT2Zmc2V0ICsgaSArIDIpLCBsaW5lID0gX3JlZjJbMF0sIGNvbHVtbiA9IF9yZWYyWzFdO1xuICAgICAgICAgIG5lc3RlZCA9IG5ldyBMZXhlcigpLnRva2VuaXplKGlubmVyLCB7XG4gICAgICAgICAgICBsaW5lOiBsaW5lLFxuICAgICAgICAgICAgY29sdW1uOiBjb2x1bW4sXG4gICAgICAgICAgICByZXdyaXRlOiBmYWxzZVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHBvcHBlZCA9IG5lc3RlZC5wb3AoKTtcbiAgICAgICAgICBpZiAoKChfcmVmMyA9IG5lc3RlZFswXSkgIT0gbnVsbCA/IF9yZWYzWzBdIDogdm9pZCAwKSA9PT0gJ1RFUk1JTkFUT1InKSB7XG4gICAgICAgICAgICBwb3BwZWQgPSBuZXN0ZWQuc2hpZnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGxlbiA9IG5lc3RlZC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChsZW4gPiAxKSB7XG4gICAgICAgICAgICAgIG5lc3RlZC51bnNoaWZ0KHRoaXMubWFrZVRva2VuKCcoJywgJygnLCBzdHJPZmZzZXQgKyBpICsgMSwgMCkpO1xuICAgICAgICAgICAgICBuZXN0ZWQucHVzaCh0aGlzLm1ha2VUb2tlbignKScsICcpJywgc3RyT2Zmc2V0ICsgaSArIDEgKyBpbm5lci5sZW5ndGgsIDApKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRva2Vucy5wdXNoKFsnVE9LRU5TJywgbmVzdGVkXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGkgKz0gZXhwci5sZW5ndGg7XG4gICAgICAgIHBpID0gaSArIDE7XG4gICAgICB9XG4gICAgICBpZiAoKGkgPiBwaSAmJiBwaSA8IHN0ci5sZW5ndGgpKSB7XG4gICAgICAgIHRva2Vucy5wdXNoKHRoaXMubWFrZVRva2VuKCdORU9TVFJJTkcnLCBzdHIuc2xpY2UocGkpLCBzdHJPZmZzZXQgKyBwaSkpO1xuICAgICAgfVxuICAgICAgaWYgKHJlZ2V4KSB7XG4gICAgICAgIHJldHVybiB0b2tlbnM7XG4gICAgICB9XG4gICAgICBpZiAoIXRva2Vucy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9rZW4oJ1NUUklORycsICdcIlwiJywgb2Zmc2V0SW5DaHVuaywgbGV4ZWRMZW5ndGgpO1xuICAgICAgfVxuICAgICAgaWYgKHRva2Vuc1swXVswXSAhPT0gJ05FT1NUUklORycpIHtcbiAgICAgICAgdG9rZW5zLnVuc2hpZnQodGhpcy5tYWtlVG9rZW4oJ05FT1NUUklORycsICcnLCBvZmZzZXRJbkNodW5rKSk7XG4gICAgICB9XG4gICAgICBpZiAoaW50ZXJwb2xhdGVkID0gdG9rZW5zLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgdGhpcy50b2tlbignKCcsICcoJywgb2Zmc2V0SW5DaHVuaywgMCwgZXJyb3JUb2tlbik7XG4gICAgICB9XG4gICAgICBmb3IgKGkgPSBfaSA9IDAsIF9sZW4gPSB0b2tlbnMubGVuZ3RoOyBfaSA8IF9sZW47IGkgPSArK19pKSB7XG4gICAgICAgIHRva2VuID0gdG9rZW5zW2ldO1xuICAgICAgICB0YWcgPSB0b2tlblswXSwgdmFsdWUgPSB0b2tlblsxXTtcbiAgICAgICAgaWYgKGkpIHtcbiAgICAgICAgICBpZiAoaSkge1xuICAgICAgICAgICAgcGx1c1Rva2VuID0gdGhpcy50b2tlbignKycsICcrJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxvY2F0aW9uVG9rZW4gPSB0YWcgPT09ICdUT0tFTlMnID8gdmFsdWVbMF0gOiB0b2tlbjtcbiAgICAgICAgICBwbHVzVG9rZW5bMl0gPSB7XG4gICAgICAgICAgICBmaXJzdF9saW5lOiBsb2NhdGlvblRva2VuWzJdLmZpcnN0X2xpbmUsXG4gICAgICAgICAgICBmaXJzdF9jb2x1bW46IGxvY2F0aW9uVG9rZW5bMl0uZmlyc3RfY29sdW1uLFxuICAgICAgICAgICAgbGFzdF9saW5lOiBsb2NhdGlvblRva2VuWzJdLmZpcnN0X2xpbmUsXG4gICAgICAgICAgICBsYXN0X2NvbHVtbjogbG9jYXRpb25Ub2tlblsyXS5maXJzdF9jb2x1bW5cbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0YWcgPT09ICdUT0tFTlMnKSB7XG4gICAgICAgICAgKF9yZWY0ID0gdGhpcy50b2tlbnMpLnB1c2guYXBwbHkoX3JlZjQsIHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIGlmICh0YWcgPT09ICdORU9TVFJJTkcnKSB7XG4gICAgICAgICAgdG9rZW5bMF0gPSAnU1RSSU5HJztcbiAgICAgICAgICB0b2tlblsxXSA9IHRoaXMubWFrZVN0cmluZyh2YWx1ZSwgJ1wiJywgaGVyZWRvYyk7XG4gICAgICAgICAgdGhpcy50b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5lcnJvcihcIlVuZXhwZWN0ZWQgXCIgKyB0YWcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaW50ZXJwb2xhdGVkKSB7XG4gICAgICAgIHJwYXJlbiA9IHRoaXMubWFrZVRva2VuKCcpJywgJyknLCBvZmZzZXRJbkNodW5rICsgbGV4ZWRMZW5ndGgsIDApO1xuICAgICAgICBycGFyZW4uc3RyaW5nRW5kID0gdHJ1ZTtcbiAgICAgICAgdGhpcy50b2tlbnMucHVzaChycGFyZW4pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRva2VucztcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLnBhaXIgPSBmdW5jdGlvbih0YWcpIHtcbiAgICAgIHZhciB3YW50ZWQ7XG4gICAgICBpZiAodGFnICE9PSAod2FudGVkID0gbGFzdCh0aGlzLmVuZHMpKSkge1xuICAgICAgICBpZiAoJ09VVERFTlQnICE9PSB3YW50ZWQpIHtcbiAgICAgICAgICB0aGlzLmVycm9yKFwidW5tYXRjaGVkIFwiICsgdGFnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm91dGRlbnRUb2tlbihsYXN0KHRoaXMuaW5kZW50cyksIHRydWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5wYWlyKHRhZyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5lbmRzLnBvcCgpO1xuICAgIH07XG5cbiAgICBMZXhlci5wcm90b3R5cGUuZ2V0TGluZUFuZENvbHVtbkZyb21DaHVuayA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgdmFyIGNvbHVtbiwgbGluZUNvdW50LCBsaW5lcywgc3RyaW5nO1xuICAgICAgaWYgKG9mZnNldCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW3RoaXMuY2h1bmtMaW5lLCB0aGlzLmNodW5rQ29sdW1uXTtcbiAgICAgIH1cbiAgICAgIGlmIChvZmZzZXQgPj0gdGhpcy5jaHVuay5sZW5ndGgpIHtcbiAgICAgICAgc3RyaW5nID0gdGhpcy5jaHVuaztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0cmluZyA9IHRoaXMuY2h1bmsuc2xpY2UoMCwgKyhvZmZzZXQgLSAxKSArIDEgfHwgOWU5KTtcbiAgICAgIH1cbiAgICAgIGxpbmVDb3VudCA9IGNvdW50KHN0cmluZywgJ1xcbicpO1xuICAgICAgY29sdW1uID0gdGhpcy5jaHVua0NvbHVtbjtcbiAgICAgIGlmIChsaW5lQ291bnQgPiAwKSB7XG4gICAgICAgIGxpbmVzID0gc3RyaW5nLnNwbGl0KCdcXG4nKTtcbiAgICAgICAgY29sdW1uID0gbGFzdChsaW5lcykubGVuZ3RoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29sdW1uICs9IHN0cmluZy5sZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gW3RoaXMuY2h1bmtMaW5lICsgbGluZUNvdW50LCBjb2x1bW5dO1xuICAgIH07XG5cbiAgICBMZXhlci5wcm90b3R5cGUubWFrZVRva2VuID0gZnVuY3Rpb24odGFnLCB2YWx1ZSwgb2Zmc2V0SW5DaHVuaywgbGVuZ3RoKSB7XG4gICAgICB2YXIgbGFzdENoYXJhY3RlciwgbG9jYXRpb25EYXRhLCB0b2tlbiwgX3JlZjIsIF9yZWYzO1xuICAgICAgaWYgKG9mZnNldEluQ2h1bmsgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXRJbkNodW5rID0gMDtcbiAgICAgIH1cbiAgICAgIGlmIChsZW5ndGggPT0gbnVsbCkge1xuICAgICAgICBsZW5ndGggPSB2YWx1ZS5sZW5ndGg7XG4gICAgICB9XG4gICAgICBsb2NhdGlvbkRhdGEgPSB7fTtcbiAgICAgIF9yZWYyID0gdGhpcy5nZXRMaW5lQW5kQ29sdW1uRnJvbUNodW5rKG9mZnNldEluQ2h1bmspLCBsb2NhdGlvbkRhdGEuZmlyc3RfbGluZSA9IF9yZWYyWzBdLCBsb2NhdGlvbkRhdGEuZmlyc3RfY29sdW1uID0gX3JlZjJbMV07XG4gICAgICBsYXN0Q2hhcmFjdGVyID0gTWF0aC5tYXgoMCwgbGVuZ3RoIC0gMSk7XG4gICAgICBfcmVmMyA9IHRoaXMuZ2V0TGluZUFuZENvbHVtbkZyb21DaHVuayhvZmZzZXRJbkNodW5rICsgbGFzdENoYXJhY3RlciksIGxvY2F0aW9uRGF0YS5sYXN0X2xpbmUgPSBfcmVmM1swXSwgbG9jYXRpb25EYXRhLmxhc3RfY29sdW1uID0gX3JlZjNbMV07XG4gICAgICB0b2tlbiA9IFt0YWcsIHZhbHVlLCBsb2NhdGlvbkRhdGFdO1xuICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH07XG5cbiAgICBMZXhlci5wcm90b3R5cGUudG9rZW4gPSBmdW5jdGlvbih0YWcsIHZhbHVlLCBvZmZzZXRJbkNodW5rLCBsZW5ndGgsIG9yaWdpbikge1xuICAgICAgdmFyIHRva2VuO1xuICAgICAgdG9rZW4gPSB0aGlzLm1ha2VUb2tlbih0YWcsIHZhbHVlLCBvZmZzZXRJbkNodW5rLCBsZW5ndGgpO1xuICAgICAgaWYgKG9yaWdpbikge1xuICAgICAgICB0b2tlbi5vcmlnaW4gPSBvcmlnaW47XG4gICAgICB9XG4gICAgICB0aGlzLnRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgIHJldHVybiB0b2tlbjtcbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLnRhZyA9IGZ1bmN0aW9uKGluZGV4LCB0YWcpIHtcbiAgICAgIHZhciB0b2s7XG4gICAgICByZXR1cm4gKHRvayA9IGxhc3QodGhpcy50b2tlbnMsIGluZGV4KSkgJiYgKHRhZyA/IHRva1swXSA9IHRhZyA6IHRva1swXSk7XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS52YWx1ZSA9IGZ1bmN0aW9uKGluZGV4LCB2YWwpIHtcbiAgICAgIHZhciB0b2s7XG4gICAgICByZXR1cm4gKHRvayA9IGxhc3QodGhpcy50b2tlbnMsIGluZGV4KSkgJiYgKHZhbCA/IHRva1sxXSA9IHZhbCA6IHRva1sxXSk7XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS51bmZpbmlzaGVkID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX3JlZjI7XG4gICAgICByZXR1cm4gTElORV9DT05USU5VRVIudGVzdCh0aGlzLmNodW5rKSB8fCAoKF9yZWYyID0gdGhpcy50YWcoKSkgPT09ICdcXFxcJyB8fCBfcmVmMiA9PT0gJy4nIHx8IF9yZWYyID09PSAnPy4nIHx8IF9yZWYyID09PSAnPzo6JyB8fCBfcmVmMiA9PT0gJ1VOQVJZJyB8fCBfcmVmMiA9PT0gJ01BVEgnIHx8IF9yZWYyID09PSAnVU5BUllfTUFUSCcgfHwgX3JlZjIgPT09ICcrJyB8fCBfcmVmMiA9PT0gJy0nIHx8IF9yZWYyID09PSAnKionIHx8IF9yZWYyID09PSAnU0hJRlQnIHx8IF9yZWYyID09PSAnUkVMQVRJT04nIHx8IF9yZWYyID09PSAnQ09NUEFSRScgfHwgX3JlZjIgPT09ICdMT0dJQycgfHwgX3JlZjIgPT09ICdUSFJPVycgfHwgX3JlZjIgPT09ICdFWFRFTkRTJyk7XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS5yZW1vdmVOZXdsaW5lcyA9IGZ1bmN0aW9uKHN0cikge1xuICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzKlxcblxccyovLCAnJykucmVwbGFjZSgvKFteXFxcXF18XFxcXFxcXFwpXFxzKlxcblxccyokLywgJyQxJyk7XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS5lc2NhcGVMaW5lcyA9IGZ1bmN0aW9uKHN0ciwgaGVyZWRvYykge1xuICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1xcXFxbXlxcU1xcbl0qKFxcbnxcXFxcKVxccyovZywgZnVuY3Rpb24oZXNjYXBlZCwgY2hhcmFjdGVyKSB7XG4gICAgICAgIGlmIChjaGFyYWN0ZXIgPT09ICdcXG4nKSB7XG4gICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBlc2NhcGVkO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmIChoZXJlZG9jKSB7XG4gICAgICAgIHJldHVybiBzdHIucmVwbGFjZShNVUxUSUxJTkVSLCAnXFxcXG4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzdHIucmVwbGFjZSgvXFxzKlxcblxccyovZywgJyAnKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgTGV4ZXIucHJvdG90eXBlLm1ha2VTdHJpbmcgPSBmdW5jdGlvbihib2R5LCBxdW90ZSwgaGVyZWRvYykge1xuICAgICAgaWYgKCFib2R5KSB7XG4gICAgICAgIHJldHVybiBxdW90ZSArIHF1b3RlO1xuICAgICAgfVxuICAgICAgYm9keSA9IGJvZHkucmVwbGFjZShSZWdFeHAoXCJcXFxcXFxcXChcIiArIHF1b3RlICsgXCJ8XFxcXFxcXFwpXCIsIFwiZ1wiKSwgZnVuY3Rpb24obWF0Y2gsIGNvbnRlbnRzKSB7XG4gICAgICAgIGlmIChjb250ZW50cyA9PT0gcXVvdGUpIHtcbiAgICAgICAgICByZXR1cm4gY29udGVudHM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG1hdGNoO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGJvZHkgPSBib2R5LnJlcGxhY2UoUmVnRXhwKFwiXCIgKyBxdW90ZSwgXCJnXCIpLCAnXFxcXCQmJyk7XG4gICAgICByZXR1cm4gcXVvdGUgKyB0aGlzLmVzY2FwZUxpbmVzKGJvZHksIGhlcmVkb2MpICsgcXVvdGU7XG4gICAgfTtcblxuICAgIExleGVyLnByb3RvdHlwZS5lcnJvciA9IGZ1bmN0aW9uKG1lc3NhZ2UsIG9mZnNldCkge1xuICAgICAgdmFyIGZpcnN0X2NvbHVtbiwgZmlyc3RfbGluZSwgX3JlZjI7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIF9yZWYyID0gdGhpcy5nZXRMaW5lQW5kQ29sdW1uRnJvbUNodW5rKG9mZnNldCksIGZpcnN0X2xpbmUgPSBfcmVmMlswXSwgZmlyc3RfY29sdW1uID0gX3JlZjJbMV07XG4gICAgICByZXR1cm4gdGhyb3dTeW50YXhFcnJvcihtZXNzYWdlLCB7XG4gICAgICAgIGZpcnN0X2xpbmU6IGZpcnN0X2xpbmUsXG4gICAgICAgIGZpcnN0X2NvbHVtbjogZmlyc3RfY29sdW1uXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIExleGVyO1xuXG4gIH0pKCk7XG5cbiAgSlNfS0VZV09SRFMgPSBbJ3RydWUnLCAnZmFsc2UnLCAnbnVsbCcsICd0aGlzJywgJ25ldycsICdkZWxldGUnLCAndHlwZW9mJywgJ2luJywgJ2luc3RhbmNlb2YnLCAncmV0dXJuJywgJ3Rocm93JywgJ2JyZWFrJywgJ2NvbnRpbnVlJywgJ2RlYnVnZ2VyJywgJ2lmJywgJ2Vsc2UnLCAnc3dpdGNoJywgJ2ZvcicsICd3aGlsZScsICdkbycsICd0cnknLCAnY2F0Y2gnLCAnZmluYWxseScsICdjbGFzcycsICdleHRlbmRzJywgJ3N1cGVyJ107XG5cbiAgQ09GRkVFX0tFWVdPUkRTID0gWyd1bmRlZmluZWQnLCAndGhlbicsICd1bmxlc3MnLCAndW50aWwnLCAnbG9vcCcsICdvZicsICdieScsICd3aGVuJ107XG5cbiAgQ09GRkVFX0FMSUFTX01BUCA9IHtcbiAgICBhbmQ6ICcmJicsXG4gICAgb3I6ICd8fCcsXG4gICAgaXM6ICc9PScsXG4gICAgaXNudDogJyE9JyxcbiAgICBub3Q6ICchJyxcbiAgICB5ZXM6ICd0cnVlJyxcbiAgICBubzogJ2ZhbHNlJyxcbiAgICBvbjogJ3RydWUnLFxuICAgIG9mZjogJ2ZhbHNlJ1xuICB9O1xuXG4gIENPRkZFRV9BTElBU0VTID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBfcmVzdWx0cztcbiAgICBfcmVzdWx0cyA9IFtdO1xuICAgIGZvciAoa2V5IGluIENPRkZFRV9BTElBU19NQVApIHtcbiAgICAgIF9yZXN1bHRzLnB1c2goa2V5KTtcbiAgICB9XG4gICAgcmV0dXJuIF9yZXN1bHRzO1xuICB9KSgpO1xuXG4gIENPRkZFRV9LRVlXT1JEUyA9IENPRkZFRV9LRVlXT1JEUy5jb25jYXQoQ09GRkVFX0FMSUFTRVMpO1xuXG4gIFJFU0VSVkVEID0gWydjYXNlJywgJ2RlZmF1bHQnLCAnZnVuY3Rpb24nLCAndmFyJywgJ3ZvaWQnLCAnd2l0aCcsICdjb25zdCcsICdsZXQnLCAnZW51bScsICdleHBvcnQnLCAnaW1wb3J0JywgJ25hdGl2ZScsICdfX2hhc1Byb3AnLCAnX19leHRlbmRzJywgJ19fc2xpY2UnLCAnX19iaW5kJywgJ19faW5kZXhPZicsICdpbXBsZW1lbnRzJywgJ2ludGVyZmFjZScsICdwYWNrYWdlJywgJ3ByaXZhdGUnLCAncHJvdGVjdGVkJywgJ3B1YmxpYycsICdzdGF0aWMnLCAneWllbGQnXTtcblxuICBTVFJJQ1RfUFJPU0NSSUJFRCA9IFsnYXJndW1lbnRzJywgJ2V2YWwnXTtcblxuICBKU19GT1JCSURERU4gPSBKU19LRVlXT1JEUy5jb25jYXQoUkVTRVJWRUQpLmNvbmNhdChTVFJJQ1RfUFJPU0NSSUJFRCk7XG5cbiAgZXhwb3J0cy5SRVNFUlZFRCA9IFJFU0VSVkVELmNvbmNhdChKU19LRVlXT1JEUykuY29uY2F0KENPRkZFRV9LRVlXT1JEUykuY29uY2F0KFNUUklDVF9QUk9TQ1JJQkVEKTtcblxuICBleHBvcnRzLlNUUklDVF9QUk9TQ1JJQkVEID0gU1RSSUNUX1BST1NDUklCRUQ7XG5cbiAgQk9NID0gNjUyNzk7XG5cbiAgSURFTlRJRklFUiA9IC9eKFskQS1aYS16X1xceDdmLVxcdWZmZmZdWyRcXHdcXHg3Zi1cXHVmZmZmXSopKFteXFxuXFxTXSo6KD8hOikpPy87XG5cbiAgTlVNQkVSID0gL14wYlswMV0rfF4wb1swLTddK3xeMHhbXFxkYS1mXSt8XlxcZCpcXC4/XFxkKyg/OmVbKy1dP1xcZCspPy9pO1xuXG4gIEhFUkVET0MgPSAvXihcIlwiXCJ8JycnKSgoPzpcXFxcW1xcc1xcU118W15cXFxcXSkqPykoPzpcXG5bXlxcblxcU10qKT9cXDEvO1xuXG4gIE9QRVJBVE9SID0gL14oPzpbLT1dPnxbLSsqXFwvJTw+JnxeIT89XT18Pj4+PT98KFstKzpdKVxcMXwoWyZ8PD4qXFwvJV0pXFwyPT98XFw/KFxcLnw6Oil8XFwuezIsM30pLztcblxuICBXSElURVNQQUNFID0gL15bXlxcblxcU10rLztcblxuICBDT01NRU5UID0gL14jIyMoW14jXVtcXHNcXFNdKj8pKD86IyMjW15cXG5cXFNdKnwjIyMkKXxeKD86XFxzKiMoPyEjI1teI10pLiopKy87XG5cbiAgQ09ERSA9IC9eWy09XT4vO1xuXG4gIE1VTFRJX0RFTlQgPSAvXig/OlxcblteXFxuXFxTXSopKy87XG5cbiAgU0lNUExFU1RSID0gL14nW15cXFxcJ10qKD86XFxcXFtcXHNcXFNdW15cXFxcJ10qKSonLztcblxuICBKU1RPS0VOID0gL15gW15cXFxcYF0qKD86XFxcXC5bXlxcXFxgXSopKmAvO1xuXG4gIFJFR0VYID0gL14oXFwvKD8hW1xccz1dKVteW1xcL1xcblxcXFxdKig/Oig/OlxcXFxbXFxzXFxTXXxcXFtbXlxcXVxcblxcXFxdKig/OlxcXFxbXFxzXFxTXVteXFxdXFxuXFxcXF0qKSpdKVteW1xcL1xcblxcXFxdKikqXFwvKShbaW1neV17MCw0fSkoPyFcXHcpLztcblxuICBIRVJFR0VYID0gL15cXC97M30oKD86XFxcXD9bXFxzXFxTXSkrPylcXC97M30oW2ltZ3ldezAsNH0pKD8hXFx3KS87XG5cbiAgSEVSRUdFWF9PTUlUID0gLygoPzpcXFxcXFxcXCkrKXxcXFxcKFxcc3xcXC8pfFxccysoPzojLiopPy9nO1xuXG4gIE1VTFRJTElORVIgPSAvXFxuL2c7XG5cbiAgSEVSRURPQ19JTkRFTlQgPSAvXFxuKyhbXlxcblxcU10qKS9nO1xuXG4gIEhFUkVET0NfSUxMRUdBTCA9IC9cXCpcXC8vO1xuXG4gIExJTkVfQ09OVElOVUVSID0gL15cXHMqKD86LHxcXD8/XFwuKD8hWy5cXGRdKXw6OikvO1xuXG4gIFRSQUlMSU5HX1NQQUNFUyA9IC9cXHMrJC87XG5cbiAgQ09NUE9VTkRfQVNTSUdOID0gWyctPScsICcrPScsICcvPScsICcqPScsICclPScsICd8fD0nLCAnJiY9JywgJz89JywgJzw8PScsICc+Pj0nLCAnPj4+PScsICcmPScsICdePScsICd8PScsICcqKj0nLCAnLy89JywgJyUlPSddO1xuXG4gIFVOQVJZID0gWydORVcnLCAnVFlQRU9GJywgJ0RFTEVURScsICdETyddO1xuXG4gIFVOQVJZX01BVEggPSBbJyEnLCAnfiddO1xuXG4gIExPR0lDID0gWycmJicsICd8fCcsICcmJywgJ3wnLCAnXiddO1xuXG4gIFNISUZUID0gWyc8PCcsICc+PicsICc+Pj4nXTtcblxuICBDT01QQVJFID0gWyc9PScsICchPScsICc8JywgJz4nLCAnPD0nLCAnPj0nXTtcblxuICBNQVRIID0gWycqJywgJy8nLCAnJScsICcvLycsICclJSddO1xuXG4gIFJFTEFUSU9OID0gWydJTicsICdPRicsICdJTlNUQU5DRU9GJ107XG5cbiAgQk9PTCA9IFsnVFJVRScsICdGQUxTRSddO1xuXG4gIE5PVF9SRUdFWCA9IFsnTlVNQkVSJywgJ1JFR0VYJywgJ0JPT0wnLCAnTlVMTCcsICdVTkRFRklORUQnLCAnKysnLCAnLS0nXTtcblxuICBOT1RfU1BBQ0VEX1JFR0VYID0gTk9UX1JFR0VYLmNvbmNhdCgnKScsICd9JywgJ1RISVMnLCAnSURFTlRJRklFUicsICdTVFJJTkcnLCAnXScpO1xuXG4gIENBTExBQkxFID0gWydJREVOVElGSUVSJywgJ1NUUklORycsICdSRUdFWCcsICcpJywgJ10nLCAnfScsICc/JywgJzo6JywgJ0AnLCAnVEhJUycsICdTVVBFUiddO1xuXG4gIElOREVYQUJMRSA9IENBTExBQkxFLmNvbmNhdCgnTlVNQkVSJywgJ0JPT0wnLCAnTlVMTCcsICdVTkRFRklORUQnKTtcblxuICBMSU5FX0JSRUFLID0gWydJTkRFTlQnLCAnT1VUREVOVCcsICdURVJNSU5BVE9SJ107XG5cbiAgSU5ERU5UQUJMRV9DTE9TRVJTID0gWycpJywgJ30nLCAnXSddO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjguMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQWNjZXNzLCBBcnIsIEFzc2lnbiwgQmFzZSwgQmxvY2ssIENhbGwsIENsYXNzLCBDb2RlLCBDb2RlRnJhZ21lbnQsIENvbW1lbnQsIEV4aXN0ZW5jZSwgRXhwYW5zaW9uLCBFeHRlbmRzLCBGb3IsIEhFWE5VTSwgSURFTlRJRklFUiwgSURFTlRJRklFUl9TVFIsIElTX1JFR0VYLCBJU19TVFJJTkcsIElmLCBJbiwgSW5kZXgsIExFVkVMX0FDQ0VTUywgTEVWRUxfQ09ORCwgTEVWRUxfTElTVCwgTEVWRUxfT1AsIExFVkVMX1BBUkVOLCBMRVZFTF9UT1AsIExpdGVyYWwsIE1FVEhPRF9ERUYsIE5FR0FURSwgTk8sIE5VTUJFUiwgT2JqLCBPcCwgUGFyYW0sIFBhcmVucywgUkVTRVJWRUQsIFJhbmdlLCBSZXR1cm4sIFNJTVBMRU5VTSwgU1RSSUNUX1BST1NDUklCRUQsIFNjb3BlLCBTbGljZSwgU3BsYXQsIFN3aXRjaCwgVEFCLCBUSElTLCBUaHJvdywgVHJ5LCBVVElMSVRJRVMsIFZhbHVlLCBXaGlsZSwgWUVTLCBhZGRMb2NhdGlvbkRhdGFGbiwgY29tcGFjdCwgZGVsLCBlbmRzLCBleHRlbmQsIGZsYXR0ZW4sIGZyYWdtZW50c1RvVGV4dCwgaXNMaXRlcmFsQXJndW1lbnRzLCBpc0xpdGVyYWxUaGlzLCBsYXN0LCBsb2NhdGlvbkRhdGFUb1N0cmluZywgbWVyZ2UsIG11bHRpZGVudCwgcGFyc2VOdW0sIHNvbWUsIHN0YXJ0cywgdGhyb3dTeW50YXhFcnJvciwgdW5mb2xkU29haywgdXRpbGl0eSwgX3JlZiwgX3JlZjEsXG4gICAgX19oYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgX19leHRlbmRzID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChfX2hhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgX19pbmRleE9mID0gW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH0sXG4gICAgX19zbGljZSA9IFtdLnNsaWNlO1xuXG4gIEVycm9yLnN0YWNrVHJhY2VMaW1pdCA9IEluZmluaXR5O1xuXG4gIFNjb3BlID0gcmVxdWlyZSgnLi9zY29wZScpLlNjb3BlO1xuXG4gIF9yZWYgPSByZXF1aXJlKCcuL2xleGVyJyksIFJFU0VSVkVEID0gX3JlZi5SRVNFUlZFRCwgU1RSSUNUX1BST1NDUklCRUQgPSBfcmVmLlNUUklDVF9QUk9TQ1JJQkVEO1xuXG4gIF9yZWYxID0gcmVxdWlyZSgnLi9oZWxwZXJzJyksIGNvbXBhY3QgPSBfcmVmMS5jb21wYWN0LCBmbGF0dGVuID0gX3JlZjEuZmxhdHRlbiwgZXh0ZW5kID0gX3JlZjEuZXh0ZW5kLCBtZXJnZSA9IF9yZWYxLm1lcmdlLCBkZWwgPSBfcmVmMS5kZWwsIHN0YXJ0cyA9IF9yZWYxLnN0YXJ0cywgZW5kcyA9IF9yZWYxLmVuZHMsIGxhc3QgPSBfcmVmMS5sYXN0LCBzb21lID0gX3JlZjEuc29tZSwgYWRkTG9jYXRpb25EYXRhRm4gPSBfcmVmMS5hZGRMb2NhdGlvbkRhdGFGbiwgbG9jYXRpb25EYXRhVG9TdHJpbmcgPSBfcmVmMS5sb2NhdGlvbkRhdGFUb1N0cmluZywgdGhyb3dTeW50YXhFcnJvciA9IF9yZWYxLnRocm93U3ludGF4RXJyb3I7XG5cbiAgZXhwb3J0cy5leHRlbmQgPSBleHRlbmQ7XG5cbiAgZXhwb3J0cy5hZGRMb2NhdGlvbkRhdGFGbiA9IGFkZExvY2F0aW9uRGF0YUZuO1xuXG4gIFlFUyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIE5PID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuXG4gIFRISVMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBORUdBVEUgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLm5lZ2F0ZWQgPSAhdGhpcy5uZWdhdGVkO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIGV4cG9ydHMuQ29kZUZyYWdtZW50ID0gQ29kZUZyYWdtZW50ID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIENvZGVGcmFnbWVudChwYXJlbnQsIGNvZGUpIHtcbiAgICAgIHZhciBfcmVmMjtcbiAgICAgIHRoaXMuY29kZSA9IFwiXCIgKyBjb2RlO1xuICAgICAgdGhpcy5sb2NhdGlvbkRhdGEgPSBwYXJlbnQgIT0gbnVsbCA/IHBhcmVudC5sb2NhdGlvbkRhdGEgOiB2b2lkIDA7XG4gICAgICB0aGlzLnR5cGUgPSAocGFyZW50ICE9IG51bGwgPyAoX3JlZjIgPSBwYXJlbnQuY29uc3RydWN0b3IpICE9IG51bGwgPyBfcmVmMi5uYW1lIDogdm9pZCAwIDogdm9pZCAwKSB8fCAndW5rbm93bic7XG4gICAgfVxuXG4gICAgQ29kZUZyYWdtZW50LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIFwiXCIgKyB0aGlzLmNvZGUgKyAodGhpcy5sb2NhdGlvbkRhdGEgPyBcIjogXCIgKyBsb2NhdGlvbkRhdGFUb1N0cmluZyh0aGlzLmxvY2F0aW9uRGF0YSkgOiAnJyk7XG4gICAgfTtcblxuICAgIHJldHVybiBDb2RlRnJhZ21lbnQ7XG5cbiAgfSkoKTtcblxuICBmcmFnbWVudHNUb1RleHQgPSBmdW5jdGlvbihmcmFnbWVudHMpIHtcbiAgICB2YXIgZnJhZ21lbnQ7XG4gICAgcmV0dXJuICgoZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX2ksIF9sZW4sIF9yZXN1bHRzO1xuICAgICAgX3Jlc3VsdHMgPSBbXTtcbiAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gZnJhZ21lbnRzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGZyYWdtZW50ID0gZnJhZ21lbnRzW19pXTtcbiAgICAgICAgX3Jlc3VsdHMucHVzaChmcmFnbWVudC5jb2RlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBfcmVzdWx0cztcbiAgICB9KSgpKS5qb2luKCcnKTtcbiAgfTtcblxuICBleHBvcnRzLkJhc2UgPSBCYXNlID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIEJhc2UoKSB7fVxuXG4gICAgQmFzZS5wcm90b3R5cGUuY29tcGlsZSA9IGZ1bmN0aW9uKG8sIGx2bCkge1xuICAgICAgcmV0dXJuIGZyYWdtZW50c1RvVGV4dCh0aGlzLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBsdmwpKTtcbiAgICB9O1xuXG4gICAgQmFzZS5wcm90b3R5cGUuY29tcGlsZVRvRnJhZ21lbnRzID0gZnVuY3Rpb24obywgbHZsKSB7XG4gICAgICB2YXIgbm9kZTtcbiAgICAgIG8gPSBleHRlbmQoe30sIG8pO1xuICAgICAgaWYgKGx2bCkge1xuICAgICAgICBvLmxldmVsID0gbHZsO1xuICAgICAgfVxuICAgICAgbm9kZSA9IHRoaXMudW5mb2xkU29hayhvKSB8fCB0aGlzO1xuICAgICAgbm9kZS50YWIgPSBvLmluZGVudDtcbiAgICAgIGlmIChvLmxldmVsID09PSBMRVZFTF9UT1AgfHwgIW5vZGUuaXNTdGF0ZW1lbnQobykpIHtcbiAgICAgICAgcmV0dXJuIG5vZGUuY29tcGlsZU5vZGUobyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbm9kZS5jb21waWxlQ2xvc3VyZShvKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQmFzZS5wcm90b3R5cGUuY29tcGlsZUNsb3N1cmUgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgYXJncywgYXJndW1lbnRzTm9kZSwgZnVuYywganVtcE5vZGUsIG1ldGg7XG4gICAgICBpZiAoanVtcE5vZGUgPSB0aGlzLmp1bXBzKCkpIHtcbiAgICAgICAganVtcE5vZGUuZXJyb3IoJ2Nhbm5vdCB1c2UgYSBwdXJlIHN0YXRlbWVudCBpbiBhbiBleHByZXNzaW9uJyk7XG4gICAgICB9XG4gICAgICBvLnNoYXJlZFNjb3BlID0gdHJ1ZTtcbiAgICAgIGZ1bmMgPSBuZXcgQ29kZShbXSwgQmxvY2sud3JhcChbdGhpc10pKTtcbiAgICAgIGFyZ3MgPSBbXTtcbiAgICAgIGlmICgoYXJndW1lbnRzTm9kZSA9IHRoaXMuY29udGFpbnMoaXNMaXRlcmFsQXJndW1lbnRzKSkgfHwgdGhpcy5jb250YWlucyhpc0xpdGVyYWxUaGlzKSkge1xuICAgICAgICBhcmdzID0gW25ldyBMaXRlcmFsKCd0aGlzJyldO1xuICAgICAgICBpZiAoYXJndW1lbnRzTm9kZSkge1xuICAgICAgICAgIG1ldGggPSAnYXBwbHknO1xuICAgICAgICAgIGFyZ3MucHVzaChuZXcgTGl0ZXJhbCgnYXJndW1lbnRzJykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1ldGggPSAnY2FsbCc7XG4gICAgICAgIH1cbiAgICAgICAgZnVuYyA9IG5ldyBWYWx1ZShmdW5jLCBbbmV3IEFjY2VzcyhuZXcgTGl0ZXJhbChtZXRoKSldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAobmV3IENhbGwoZnVuYywgYXJncykpLmNvbXBpbGVOb2RlKG8pO1xuICAgIH07XG5cbiAgICBCYXNlLnByb3RvdHlwZS5jYWNoZSA9IGZ1bmN0aW9uKG8sIGxldmVsLCByZXVzZWQpIHtcbiAgICAgIHZhciByZWYsIHN1YjtcbiAgICAgIGlmICghdGhpcy5pc0NvbXBsZXgoKSkge1xuICAgICAgICByZWYgPSBsZXZlbCA/IHRoaXMuY29tcGlsZVRvRnJhZ21lbnRzKG8sIGxldmVsKSA6IHRoaXM7XG4gICAgICAgIHJldHVybiBbcmVmLCByZWZdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVmID0gbmV3IExpdGVyYWwocmV1c2VkIHx8IG8uc2NvcGUuZnJlZVZhcmlhYmxlKCdyZWYnKSk7XG4gICAgICAgIHN1YiA9IG5ldyBBc3NpZ24ocmVmLCB0aGlzKTtcbiAgICAgICAgaWYgKGxldmVsKSB7XG4gICAgICAgICAgcmV0dXJuIFtzdWIuY29tcGlsZVRvRnJhZ21lbnRzKG8sIGxldmVsKSwgW3RoaXMubWFrZUNvZGUocmVmLnZhbHVlKV1dO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBbc3ViLCByZWZdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJhc2UucHJvdG90eXBlLmNhY2hlVG9Db2RlRnJhZ21lbnRzID0gZnVuY3Rpb24oY2FjaGVWYWx1ZXMpIHtcbiAgICAgIHJldHVybiBbZnJhZ21lbnRzVG9UZXh0KGNhY2hlVmFsdWVzWzBdKSwgZnJhZ21lbnRzVG9UZXh0KGNhY2hlVmFsdWVzWzFdKV07XG4gICAgfTtcblxuICAgIEJhc2UucHJvdG90eXBlLm1ha2VSZXR1cm4gPSBmdW5jdGlvbihyZXMpIHtcbiAgICAgIHZhciBtZTtcbiAgICAgIG1lID0gdGhpcy51bndyYXBBbGwoKTtcbiAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBDYWxsKG5ldyBMaXRlcmFsKFwiXCIgKyByZXMgKyBcIi5wdXNoXCIpLCBbbWVdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgUmV0dXJuKG1lKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQmFzZS5wcm90b3R5cGUuY29udGFpbnMgPSBmdW5jdGlvbihwcmVkKSB7XG4gICAgICB2YXIgbm9kZTtcbiAgICAgIG5vZGUgPSB2b2lkIDA7XG4gICAgICB0aGlzLnRyYXZlcnNlQ2hpbGRyZW4oZmFsc2UsIGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgaWYgKHByZWQobikpIHtcbiAgICAgICAgICBub2RlID0gbjtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfTtcblxuICAgIEJhc2UucHJvdG90eXBlLmxhc3ROb25Db21tZW50ID0gZnVuY3Rpb24obGlzdCkge1xuICAgICAgdmFyIGk7XG4gICAgICBpID0gbGlzdC5sZW5ndGg7XG4gICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgIGlmICghKGxpc3RbaV0gaW5zdGFuY2VvZiBDb21tZW50KSkge1xuICAgICAgICAgIHJldHVybiBsaXN0W2ldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgQmFzZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihpZHQsIG5hbWUpIHtcbiAgICAgIHZhciB0cmVlO1xuICAgICAgaWYgKGlkdCA9PSBudWxsKSB7XG4gICAgICAgIGlkdCA9ICcnO1xuICAgICAgfVxuICAgICAgaWYgKG5hbWUgPT0gbnVsbCkge1xuICAgICAgICBuYW1lID0gdGhpcy5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgfVxuICAgICAgdHJlZSA9ICdcXG4nICsgaWR0ICsgbmFtZTtcbiAgICAgIGlmICh0aGlzLnNvYWspIHtcbiAgICAgICAgdHJlZSArPSAnPyc7XG4gICAgICB9XG4gICAgICB0aGlzLmVhY2hDaGlsZChmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIHJldHVybiB0cmVlICs9IG5vZGUudG9TdHJpbmcoaWR0ICsgVEFCKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRyZWU7XG4gICAgfTtcblxuICAgIEJhc2UucHJvdG90eXBlLmVhY2hDaGlsZCA9IGZ1bmN0aW9uKGZ1bmMpIHtcbiAgICAgIHZhciBhdHRyLCBjaGlsZCwgX2ksIF9qLCBfbGVuLCBfbGVuMSwgX3JlZjIsIF9yZWYzO1xuICAgICAgaWYgKCF0aGlzLmNoaWxkcmVuKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgX3JlZjIgPSB0aGlzLmNoaWxkcmVuO1xuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBfcmVmMi5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgICBhdHRyID0gX3JlZjJbX2ldO1xuICAgICAgICBpZiAodGhpc1thdHRyXSkge1xuICAgICAgICAgIF9yZWYzID0gZmxhdHRlbihbdGhpc1thdHRyXV0pO1xuICAgICAgICAgIGZvciAoX2ogPSAwLCBfbGVuMSA9IF9yZWYzLmxlbmd0aDsgX2ogPCBfbGVuMTsgX2orKykge1xuICAgICAgICAgICAgY2hpbGQgPSBfcmVmM1tfal07XG4gICAgICAgICAgICBpZiAoZnVuYyhjaGlsZCkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIEJhc2UucHJvdG90eXBlLnRyYXZlcnNlQ2hpbGRyZW4gPSBmdW5jdGlvbihjcm9zc1Njb3BlLCBmdW5jKSB7XG4gICAgICByZXR1cm4gdGhpcy5lYWNoQ2hpbGQoZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgICAgdmFyIHJlY3VyO1xuICAgICAgICByZWN1ciA9IGZ1bmMoY2hpbGQpO1xuICAgICAgICBpZiAocmVjdXIgIT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuIGNoaWxkLnRyYXZlcnNlQ2hpbGRyZW4oY3Jvc3NTY29wZSwgZnVuYyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBCYXNlLnByb3RvdHlwZS5pbnZlcnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgT3AoJyEnLCB0aGlzKTtcbiAgICB9O1xuXG4gICAgQmFzZS5wcm90b3R5cGUudW53cmFwQWxsID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgbm9kZTtcbiAgICAgIG5vZGUgPSB0aGlzO1xuICAgICAgd2hpbGUgKG5vZGUgIT09IChub2RlID0gbm9kZS51bndyYXAoKSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gbm9kZTtcbiAgICB9O1xuXG4gICAgQmFzZS5wcm90b3R5cGUuY2hpbGRyZW4gPSBbXTtcblxuICAgIEJhc2UucHJvdG90eXBlLmlzU3RhdGVtZW50ID0gTk87XG5cbiAgICBCYXNlLnByb3RvdHlwZS5qdW1wcyA9IE5PO1xuXG4gICAgQmFzZS5wcm90b3R5cGUuaXNDb21wbGV4ID0gWUVTO1xuXG4gICAgQmFzZS5wcm90b3R5cGUuaXNDaGFpbmFibGUgPSBOTztcblxuICAgIEJhc2UucHJvdG90eXBlLmlzQXNzaWduYWJsZSA9IE5PO1xuXG4gICAgQmFzZS5wcm90b3R5cGUudW53cmFwID0gVEhJUztcblxuICAgIEJhc2UucHJvdG90eXBlLnVuZm9sZFNvYWsgPSBOTztcblxuICAgIEJhc2UucHJvdG90eXBlLmFzc2lnbnMgPSBOTztcblxuICAgIEJhc2UucHJvdG90eXBlLnVwZGF0ZUxvY2F0aW9uRGF0YUlmTWlzc2luZyA9IGZ1bmN0aW9uKGxvY2F0aW9uRGF0YSkge1xuICAgICAgaWYgKHRoaXMubG9jYXRpb25EYXRhKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2NhdGlvbkRhdGEgPSBsb2NhdGlvbkRhdGE7XG4gICAgICByZXR1cm4gdGhpcy5lYWNoQ2hpbGQoZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgICAgcmV0dXJuIGNoaWxkLnVwZGF0ZUxvY2F0aW9uRGF0YUlmTWlzc2luZyhsb2NhdGlvbkRhdGEpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIEJhc2UucHJvdG90eXBlLmVycm9yID0gZnVuY3Rpb24obWVzc2FnZSkge1xuICAgICAgcmV0dXJuIHRocm93U3ludGF4RXJyb3IobWVzc2FnZSwgdGhpcy5sb2NhdGlvbkRhdGEpO1xuICAgIH07XG5cbiAgICBCYXNlLnByb3RvdHlwZS5tYWtlQ29kZSA9IGZ1bmN0aW9uKGNvZGUpIHtcbiAgICAgIHJldHVybiBuZXcgQ29kZUZyYWdtZW50KHRoaXMsIGNvZGUpO1xuICAgIH07XG5cbiAgICBCYXNlLnByb3RvdHlwZS53cmFwSW5CcmFjZXMgPSBmdW5jdGlvbihmcmFnbWVudHMpIHtcbiAgICAgIHJldHVybiBbXS5jb25jYXQodGhpcy5tYWtlQ29kZSgnKCcpLCBmcmFnbWVudHMsIHRoaXMubWFrZUNvZGUoJyknKSk7XG4gICAgfTtcblxuICAgIEJhc2UucHJvdG90eXBlLmpvaW5GcmFnbWVudEFycmF5cyA9IGZ1bmN0aW9uKGZyYWdtZW50c0xpc3QsIGpvaW5TdHIpIHtcbiAgICAgIHZhciBhbnN3ZXIsIGZyYWdtZW50cywgaSwgX2ksIF9sZW47XG4gICAgICBhbnN3ZXIgPSBbXTtcbiAgICAgIGZvciAoaSA9IF9pID0gMCwgX2xlbiA9IGZyYWdtZW50c0xpc3QubGVuZ3RoOyBfaSA8IF9sZW47IGkgPSArK19pKSB7XG4gICAgICAgIGZyYWdtZW50cyA9IGZyYWdtZW50c0xpc3RbaV07XG4gICAgICAgIGlmIChpKSB7XG4gICAgICAgICAgYW5zd2VyLnB1c2godGhpcy5tYWtlQ29kZShqb2luU3RyKSk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyID0gYW5zd2VyLmNvbmNhdChmcmFnbWVudHMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJhc2U7XG5cbiAgfSkoKTtcblxuICBleHBvcnRzLkJsb2NrID0gQmxvY2sgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKEJsb2NrLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gQmxvY2sobm9kZXMpIHtcbiAgICAgIHRoaXMuZXhwcmVzc2lvbnMgPSBjb21wYWN0KGZsYXR0ZW4obm9kZXMgfHwgW10pKTtcbiAgICB9XG5cbiAgICBCbG9jay5wcm90b3R5cGUuY2hpbGRyZW4gPSBbJ2V4cHJlc3Npb25zJ107XG5cbiAgICBCbG9jay5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIHRoaXMuZXhwcmVzc2lvbnMucHVzaChub2RlKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBCbG9jay5wcm90b3R5cGUucG9wID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5leHByZXNzaW9ucy5wb3AoKTtcbiAgICB9O1xuXG4gICAgQmxvY2sucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgICB0aGlzLmV4cHJlc3Npb25zLnVuc2hpZnQobm9kZSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgQmxvY2sucHJvdG90eXBlLnVud3JhcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuZXhwcmVzc2lvbnMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmV4cHJlc3Npb25zWzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJsb2NrLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gIXRoaXMuZXhwcmVzc2lvbnMubGVuZ3RoO1xuICAgIH07XG5cbiAgICBCbG9jay5wcm90b3R5cGUuaXNTdGF0ZW1lbnQgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgZXhwLCBfaSwgX2xlbiwgX3JlZjI7XG4gICAgICBfcmVmMiA9IHRoaXMuZXhwcmVzc2lvbnM7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYyLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGV4cCA9IF9yZWYyW19pXTtcbiAgICAgICAgaWYgKGV4cC5pc1N0YXRlbWVudChvKSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIEJsb2NrLnByb3RvdHlwZS5qdW1wcyA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBleHAsIGp1bXBOb2RlLCBfaSwgX2xlbiwgX3JlZjI7XG4gICAgICBfcmVmMiA9IHRoaXMuZXhwcmVzc2lvbnM7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYyLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGV4cCA9IF9yZWYyW19pXTtcbiAgICAgICAgaWYgKGp1bXBOb2RlID0gZXhwLmp1bXBzKG8pKSB7XG4gICAgICAgICAgcmV0dXJuIGp1bXBOb2RlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJsb2NrLnByb3RvdHlwZS5tYWtlUmV0dXJuID0gZnVuY3Rpb24ocmVzKSB7XG4gICAgICB2YXIgZXhwciwgbGVuO1xuICAgICAgbGVuID0gdGhpcy5leHByZXNzaW9ucy5sZW5ndGg7XG4gICAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgICAgZXhwciA9IHRoaXMuZXhwcmVzc2lvbnNbbGVuXTtcbiAgICAgICAgaWYgKCEoZXhwciBpbnN0YW5jZW9mIENvbW1lbnQpKSB7XG4gICAgICAgICAgdGhpcy5leHByZXNzaW9uc1tsZW5dID0gZXhwci5tYWtlUmV0dXJuKHJlcyk7XG4gICAgICAgICAgaWYgKGV4cHIgaW5zdGFuY2VvZiBSZXR1cm4gJiYgIWV4cHIuZXhwcmVzc2lvbikge1xuICAgICAgICAgICAgdGhpcy5leHByZXNzaW9ucy5zcGxpY2UobGVuLCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBCbG9jay5wcm90b3R5cGUuY29tcGlsZVRvRnJhZ21lbnRzID0gZnVuY3Rpb24obywgbGV2ZWwpIHtcbiAgICAgIGlmIChvID09IG51bGwpIHtcbiAgICAgICAgbyA9IHt9O1xuICAgICAgfVxuICAgICAgaWYgKG8uc2NvcGUpIHtcbiAgICAgICAgcmV0dXJuIEJsb2NrLl9fc3VwZXJfXy5jb21waWxlVG9GcmFnbWVudHMuY2FsbCh0aGlzLCBvLCBsZXZlbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21waWxlUm9vdChvKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQmxvY2sucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGFuc3dlciwgY29tcGlsZWROb2RlcywgZnJhZ21lbnRzLCBpbmRleCwgbm9kZSwgdG9wLCBfaSwgX2xlbiwgX3JlZjI7XG4gICAgICB0aGlzLnRhYiA9IG8uaW5kZW50O1xuICAgICAgdG9wID0gby5sZXZlbCA9PT0gTEVWRUxfVE9QO1xuICAgICAgY29tcGlsZWROb2RlcyA9IFtdO1xuICAgICAgX3JlZjIgPSB0aGlzLmV4cHJlc3Npb25zO1xuICAgICAgZm9yIChpbmRleCA9IF9pID0gMCwgX2xlbiA9IF9yZWYyLmxlbmd0aDsgX2kgPCBfbGVuOyBpbmRleCA9ICsrX2kpIHtcbiAgICAgICAgbm9kZSA9IF9yZWYyW2luZGV4XTtcbiAgICAgICAgbm9kZSA9IG5vZGUudW53cmFwQWxsKCk7XG4gICAgICAgIG5vZGUgPSBub2RlLnVuZm9sZFNvYWsobykgfHwgbm9kZTtcbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBCbG9jaykge1xuICAgICAgICAgIGNvbXBpbGVkTm9kZXMucHVzaChub2RlLmNvbXBpbGVOb2RlKG8pKTtcbiAgICAgICAgfSBlbHNlIGlmICh0b3ApIHtcbiAgICAgICAgICBub2RlLmZyb250ID0gdHJ1ZTtcbiAgICAgICAgICBmcmFnbWVudHMgPSBub2RlLmNvbXBpbGVUb0ZyYWdtZW50cyhvKTtcbiAgICAgICAgICBpZiAoIW5vZGUuaXNTdGF0ZW1lbnQobykpIHtcbiAgICAgICAgICAgIGZyYWdtZW50cy51bnNoaWZ0KHRoaXMubWFrZUNvZGUoXCJcIiArIHRoaXMudGFiKSk7XG4gICAgICAgICAgICBmcmFnbWVudHMucHVzaCh0aGlzLm1ha2VDb2RlKFwiO1wiKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbXBpbGVkTm9kZXMucHVzaChmcmFnbWVudHMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbXBpbGVkTm9kZXMucHVzaChub2RlLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9MSVNUKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0b3ApIHtcbiAgICAgICAgaWYgKHRoaXMuc3BhY2VkKSB7XG4gICAgICAgICAgcmV0dXJuIFtdLmNvbmNhdCh0aGlzLmpvaW5GcmFnbWVudEFycmF5cyhjb21waWxlZE5vZGVzLCAnXFxuXFxuJyksIHRoaXMubWFrZUNvZGUoXCJcXG5cIikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmpvaW5GcmFnbWVudEFycmF5cyhjb21waWxlZE5vZGVzLCAnXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjb21waWxlZE5vZGVzLmxlbmd0aCkge1xuICAgICAgICBhbnN3ZXIgPSB0aGlzLmpvaW5GcmFnbWVudEFycmF5cyhjb21waWxlZE5vZGVzLCAnLCAnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFuc3dlciA9IFt0aGlzLm1ha2VDb2RlKFwidm9pZCAwXCIpXTtcbiAgICAgIH1cbiAgICAgIGlmIChjb21waWxlZE5vZGVzLmxlbmd0aCA+IDEgJiYgby5sZXZlbCA+PSBMRVZFTF9MSVNUKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXBJbkJyYWNlcyhhbnN3ZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQmxvY2sucHJvdG90eXBlLmNvbXBpbGVSb290ID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGV4cCwgZnJhZ21lbnRzLCBpLCBuYW1lLCBwcmVsdWRlLCBwcmVsdWRlRXhwcywgcmVzdCwgX2ksIF9sZW4sIF9yZWYyO1xuICAgICAgby5pbmRlbnQgPSBvLmJhcmUgPyAnJyA6IFRBQjtcbiAgICAgIG8ubGV2ZWwgPSBMRVZFTF9UT1A7XG4gICAgICB0aGlzLnNwYWNlZCA9IHRydWU7XG4gICAgICBvLnNjb3BlID0gbmV3IFNjb3BlKG51bGwsIHRoaXMsIG51bGwpO1xuICAgICAgX3JlZjIgPSBvLmxvY2FscyB8fCBbXTtcbiAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gX3JlZjIubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgbmFtZSA9IF9yZWYyW19pXTtcbiAgICAgICAgby5zY29wZS5wYXJhbWV0ZXIobmFtZSk7XG4gICAgICB9XG4gICAgICBwcmVsdWRlID0gW107XG4gICAgICBpZiAoIW8uYmFyZSkge1xuICAgICAgICBwcmVsdWRlRXhwcyA9IChmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgX2osIF9sZW4xLCBfcmVmMywgX3Jlc3VsdHM7XG4gICAgICAgICAgX3JlZjMgPSB0aGlzLmV4cHJlc3Npb25zO1xuICAgICAgICAgIF9yZXN1bHRzID0gW107XG4gICAgICAgICAgZm9yIChpID0gX2ogPSAwLCBfbGVuMSA9IF9yZWYzLmxlbmd0aDsgX2ogPCBfbGVuMTsgaSA9ICsrX2opIHtcbiAgICAgICAgICAgIGV4cCA9IF9yZWYzW2ldO1xuICAgICAgICAgICAgaWYgKCEoZXhwLnVud3JhcCgpIGluc3RhbmNlb2YgQ29tbWVudCkpIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfcmVzdWx0cy5wdXNoKGV4cCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBfcmVzdWx0cztcbiAgICAgICAgfSkuY2FsbCh0aGlzKTtcbiAgICAgICAgcmVzdCA9IHRoaXMuZXhwcmVzc2lvbnMuc2xpY2UocHJlbHVkZUV4cHMubGVuZ3RoKTtcbiAgICAgICAgdGhpcy5leHByZXNzaW9ucyA9IHByZWx1ZGVFeHBzO1xuICAgICAgICBpZiAocHJlbHVkZUV4cHMubGVuZ3RoKSB7XG4gICAgICAgICAgcHJlbHVkZSA9IHRoaXMuY29tcGlsZU5vZGUobWVyZ2Uobywge1xuICAgICAgICAgICAgaW5kZW50OiAnJ1xuICAgICAgICAgIH0pKTtcbiAgICAgICAgICBwcmVsdWRlLnB1c2godGhpcy5tYWtlQ29kZShcIlxcblwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5leHByZXNzaW9ucyA9IHJlc3Q7XG4gICAgICB9XG4gICAgICBmcmFnbWVudHMgPSB0aGlzLmNvbXBpbGVXaXRoRGVjbGFyYXRpb25zKG8pO1xuICAgICAgaWYgKG8uYmFyZSkge1xuICAgICAgICByZXR1cm4gZnJhZ21lbnRzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtdLmNvbmNhdChwcmVsdWRlLCB0aGlzLm1ha2VDb2RlKFwiKGZ1bmN0aW9uKCkge1xcblwiKSwgZnJhZ21lbnRzLCB0aGlzLm1ha2VDb2RlKFwiXFxufSkuY2FsbCh0aGlzKTtcXG5cIikpO1xuICAgIH07XG5cbiAgICBCbG9jay5wcm90b3R5cGUuY29tcGlsZVdpdGhEZWNsYXJhdGlvbnMgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgYXNzaWducywgZGVjbGFycywgZXhwLCBmcmFnbWVudHMsIGksIHBvc3QsIHJlc3QsIHNjb3BlLCBzcGFjZWQsIF9pLCBfbGVuLCBfcmVmMiwgX3JlZjMsIF9yZWY0O1xuICAgICAgZnJhZ21lbnRzID0gW107XG4gICAgICBwb3N0ID0gW107XG4gICAgICBfcmVmMiA9IHRoaXMuZXhwcmVzc2lvbnM7XG4gICAgICBmb3IgKGkgPSBfaSA9IDAsIF9sZW4gPSBfcmVmMi5sZW5ndGg7IF9pIDwgX2xlbjsgaSA9ICsrX2kpIHtcbiAgICAgICAgZXhwID0gX3JlZjJbaV07XG4gICAgICAgIGV4cCA9IGV4cC51bndyYXAoKTtcbiAgICAgICAgaWYgKCEoZXhwIGluc3RhbmNlb2YgQ29tbWVudCB8fCBleHAgaW5zdGFuY2VvZiBMaXRlcmFsKSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBvID0gbWVyZ2Uobywge1xuICAgICAgICBsZXZlbDogTEVWRUxfVE9QXG4gICAgICB9KTtcbiAgICAgIGlmIChpKSB7XG4gICAgICAgIHJlc3QgPSB0aGlzLmV4cHJlc3Npb25zLnNwbGljZShpLCA5ZTkpO1xuICAgICAgICBfcmVmMyA9IFt0aGlzLnNwYWNlZCwgZmFsc2VdLCBzcGFjZWQgPSBfcmVmM1swXSwgdGhpcy5zcGFjZWQgPSBfcmVmM1sxXTtcbiAgICAgICAgX3JlZjQgPSBbdGhpcy5jb21waWxlTm9kZShvKSwgc3BhY2VkXSwgZnJhZ21lbnRzID0gX3JlZjRbMF0sIHRoaXMuc3BhY2VkID0gX3JlZjRbMV07XG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbnMgPSByZXN0O1xuICAgICAgfVxuICAgICAgcG9zdCA9IHRoaXMuY29tcGlsZU5vZGUobyk7XG4gICAgICBzY29wZSA9IG8uc2NvcGU7XG4gICAgICBpZiAoc2NvcGUuZXhwcmVzc2lvbnMgPT09IHRoaXMpIHtcbiAgICAgICAgZGVjbGFycyA9IG8uc2NvcGUuaGFzRGVjbGFyYXRpb25zKCk7XG4gICAgICAgIGFzc2lnbnMgPSBzY29wZS5oYXNBc3NpZ25tZW50cztcbiAgICAgICAgaWYgKGRlY2xhcnMgfHwgYXNzaWducykge1xuICAgICAgICAgIGlmIChpKSB7XG4gICAgICAgICAgICBmcmFnbWVudHMucHVzaCh0aGlzLm1ha2VDb2RlKCdcXG4nKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZyYWdtZW50cy5wdXNoKHRoaXMubWFrZUNvZGUoXCJcIiArIHRoaXMudGFiICsgXCJ2YXIgXCIpKTtcbiAgICAgICAgICBpZiAoZGVjbGFycykge1xuICAgICAgICAgICAgZnJhZ21lbnRzLnB1c2godGhpcy5tYWtlQ29kZShzY29wZS5kZWNsYXJlZFZhcmlhYmxlcygpLmpvaW4oJywgJykpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGFzc2lnbnMpIHtcbiAgICAgICAgICAgIGlmIChkZWNsYXJzKSB7XG4gICAgICAgICAgICAgIGZyYWdtZW50cy5wdXNoKHRoaXMubWFrZUNvZGUoXCIsXFxuXCIgKyAodGhpcy50YWIgKyBUQUIpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmcmFnbWVudHMucHVzaCh0aGlzLm1ha2VDb2RlKHNjb3BlLmFzc2lnbmVkVmFyaWFibGVzKCkuam9pbihcIixcXG5cIiArICh0aGlzLnRhYiArIFRBQikpKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZyYWdtZW50cy5wdXNoKHRoaXMubWFrZUNvZGUoXCI7XFxuXCIgKyAodGhpcy5zcGFjZWQgPyAnXFxuJyA6ICcnKSkpO1xuICAgICAgICB9IGVsc2UgaWYgKGZyYWdtZW50cy5sZW5ndGggJiYgcG9zdC5sZW5ndGgpIHtcbiAgICAgICAgICBmcmFnbWVudHMucHVzaCh0aGlzLm1ha2VDb2RlKFwiXFxuXCIpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZyYWdtZW50cy5jb25jYXQocG9zdCk7XG4gICAgfTtcblxuICAgIEJsb2NrLndyYXAgPSBmdW5jdGlvbihub2Rlcykge1xuICAgICAgaWYgKG5vZGVzLmxlbmd0aCA9PT0gMSAmJiBub2Rlc1swXSBpbnN0YW5jZW9mIEJsb2NrKSB7XG4gICAgICAgIHJldHVybiBub2Rlc1swXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgQmxvY2sobm9kZXMpO1xuICAgIH07XG5cbiAgICByZXR1cm4gQmxvY2s7XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5MaXRlcmFsID0gTGl0ZXJhbCA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoTGl0ZXJhbCwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIExpdGVyYWwodmFsdWUpIHtcbiAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICBMaXRlcmFsLnByb3RvdHlwZS5tYWtlUmV0dXJuID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5pc1N0YXRlbWVudCgpKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIExpdGVyYWwuX19zdXBlcl9fLm1ha2VSZXR1cm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgTGl0ZXJhbC5wcm90b3R5cGUuaXNBc3NpZ25hYmxlID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gSURFTlRJRklFUi50ZXN0KHRoaXMudmFsdWUpO1xuICAgIH07XG5cbiAgICBMaXRlcmFsLnByb3RvdHlwZS5pc1N0YXRlbWVudCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIF9yZWYyO1xuICAgICAgcmV0dXJuIChfcmVmMiA9IHRoaXMudmFsdWUpID09PSAnYnJlYWsnIHx8IF9yZWYyID09PSAnY29udGludWUnIHx8IF9yZWYyID09PSAnZGVidWdnZXInO1xuICAgIH07XG5cbiAgICBMaXRlcmFsLnByb3RvdHlwZS5pc0NvbXBsZXggPSBOTztcblxuICAgIExpdGVyYWwucHJvdG90eXBlLmFzc2lnbnMgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICByZXR1cm4gbmFtZSA9PT0gdGhpcy52YWx1ZTtcbiAgICB9O1xuXG4gICAgTGl0ZXJhbC5wcm90b3R5cGUuanVtcHMgPSBmdW5jdGlvbihvKSB7XG4gICAgICBpZiAodGhpcy52YWx1ZSA9PT0gJ2JyZWFrJyAmJiAhKChvICE9IG51bGwgPyBvLmxvb3AgOiB2b2lkIDApIHx8IChvICE9IG51bGwgPyBvLmJsb2NrIDogdm9pZCAwKSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy52YWx1ZSA9PT0gJ2NvbnRpbnVlJyAmJiAhKG8gIT0gbnVsbCA/IG8ubG9vcCA6IHZvaWQgMCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfTtcblxuICAgIExpdGVyYWwucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGFuc3dlciwgY29kZSwgX3JlZjI7XG4gICAgICBjb2RlID0gdGhpcy52YWx1ZSA9PT0gJ3RoaXMnID8gKChfcmVmMiA9IG8uc2NvcGUubWV0aG9kKSAhPSBudWxsID8gX3JlZjIuYm91bmQgOiB2b2lkIDApID8gby5zY29wZS5tZXRob2QuY29udGV4dCA6IHRoaXMudmFsdWUgOiB0aGlzLnZhbHVlLnJlc2VydmVkID8gXCJcXFwiXCIgKyB0aGlzLnZhbHVlICsgXCJcXFwiXCIgOiB0aGlzLnZhbHVlO1xuICAgICAgYW5zd2VyID0gdGhpcy5pc1N0YXRlbWVudCgpID8gXCJcIiArIHRoaXMudGFiICsgY29kZSArIFwiO1wiIDogY29kZTtcbiAgICAgIHJldHVybiBbdGhpcy5tYWtlQ29kZShhbnN3ZXIpXTtcbiAgICB9O1xuXG4gICAgTGl0ZXJhbC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAnIFwiJyArIHRoaXMudmFsdWUgKyAnXCInO1xuICAgIH07XG5cbiAgICByZXR1cm4gTGl0ZXJhbDtcblxuICB9KShCYXNlKTtcblxuICBleHBvcnRzLlVuZGVmaW5lZCA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVW5kZWZpbmVkLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gVW5kZWZpbmVkKCkge1xuICAgICAgcmV0dXJuIFVuZGVmaW5lZC5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBVbmRlZmluZWQucHJvdG90eXBlLmlzQXNzaWduYWJsZSA9IE5PO1xuXG4gICAgVW5kZWZpbmVkLnByb3RvdHlwZS5pc0NvbXBsZXggPSBOTztcblxuICAgIFVuZGVmaW5lZC5wcm90b3R5cGUuY29tcGlsZU5vZGUgPSBmdW5jdGlvbihvKSB7XG4gICAgICByZXR1cm4gW3RoaXMubWFrZUNvZGUoby5sZXZlbCA+PSBMRVZFTF9BQ0NFU1MgPyAnKHZvaWQgMCknIDogJ3ZvaWQgMCcpXTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFVuZGVmaW5lZDtcblxuICB9KShCYXNlKTtcblxuICBleHBvcnRzLk51bGwgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKE51bGwsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBOdWxsKCkge1xuICAgICAgcmV0dXJuIE51bGwuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgTnVsbC5wcm90b3R5cGUuaXNBc3NpZ25hYmxlID0gTk87XG5cbiAgICBOdWxsLnByb3RvdHlwZS5pc0NvbXBsZXggPSBOTztcblxuICAgIE51bGwucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gW3RoaXMubWFrZUNvZGUoXCJudWxsXCIpXTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIE51bGw7XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5Cb29sID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhCb29sLCBfc3VwZXIpO1xuXG4gICAgQm9vbC5wcm90b3R5cGUuaXNBc3NpZ25hYmxlID0gTk87XG5cbiAgICBCb29sLnByb3RvdHlwZS5pc0NvbXBsZXggPSBOTztcblxuICAgIEJvb2wucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gW3RoaXMubWFrZUNvZGUodGhpcy52YWwpXTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gQm9vbCh2YWwpIHtcbiAgICAgIHRoaXMudmFsID0gdmFsO1xuICAgIH1cblxuICAgIHJldHVybiBCb29sO1xuXG4gIH0pKEJhc2UpO1xuXG4gIGV4cG9ydHMuUmV0dXJuID0gUmV0dXJuID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhSZXR1cm4sIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBSZXR1cm4oZXhwcmVzc2lvbikge1xuICAgICAgdGhpcy5leHByZXNzaW9uID0gZXhwcmVzc2lvbjtcbiAgICB9XG5cbiAgICBSZXR1cm4ucHJvdG90eXBlLmNoaWxkcmVuID0gWydleHByZXNzaW9uJ107XG5cbiAgICBSZXR1cm4ucHJvdG90eXBlLmlzU3RhdGVtZW50ID0gWUVTO1xuXG4gICAgUmV0dXJuLnByb3RvdHlwZS5tYWtlUmV0dXJuID0gVEhJUztcblxuICAgIFJldHVybi5wcm90b3R5cGUuanVtcHMgPSBUSElTO1xuXG4gICAgUmV0dXJuLnByb3RvdHlwZS5jb21waWxlVG9GcmFnbWVudHMgPSBmdW5jdGlvbihvLCBsZXZlbCkge1xuICAgICAgdmFyIGV4cHIsIF9yZWYyO1xuICAgICAgZXhwciA9IChfcmVmMiA9IHRoaXMuZXhwcmVzc2lvbikgIT0gbnVsbCA/IF9yZWYyLm1ha2VSZXR1cm4oKSA6IHZvaWQgMDtcbiAgICAgIGlmIChleHByICYmICEoZXhwciBpbnN0YW5jZW9mIFJldHVybikpIHtcbiAgICAgICAgcmV0dXJuIGV4cHIuY29tcGlsZVRvRnJhZ21lbnRzKG8sIGxldmVsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBSZXR1cm4uX19zdXBlcl9fLmNvbXBpbGVUb0ZyYWdtZW50cy5jYWxsKHRoaXMsIG8sIGxldmVsKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgUmV0dXJuLnByb3RvdHlwZS5jb21waWxlTm9kZSA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBhbnN3ZXI7XG4gICAgICBhbnN3ZXIgPSBbXTtcbiAgICAgIGFuc3dlci5wdXNoKHRoaXMubWFrZUNvZGUodGhpcy50YWIgKyAoXCJyZXR1cm5cIiArICh0aGlzLmV4cHJlc3Npb24gPyBcIiBcIiA6IFwiXCIpKSkpO1xuICAgICAgaWYgKHRoaXMuZXhwcmVzc2lvbikge1xuICAgICAgICBhbnN3ZXIgPSBhbnN3ZXIuY29uY2F0KHRoaXMuZXhwcmVzc2lvbi5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfUEFSRU4pKTtcbiAgICAgIH1cbiAgICAgIGFuc3dlci5wdXNoKHRoaXMubWFrZUNvZGUoXCI7XCIpKTtcbiAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgfTtcblxuICAgIHJldHVybiBSZXR1cm47XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5WYWx1ZSA9IFZhbHVlID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhWYWx1ZSwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIFZhbHVlKGJhc2UsIHByb3BzLCB0YWcpIHtcbiAgICAgIGlmICghcHJvcHMgJiYgYmFzZSBpbnN0YW5jZW9mIFZhbHVlKSB7XG4gICAgICAgIHJldHVybiBiYXNlO1xuICAgICAgfVxuICAgICAgdGhpcy5iYXNlID0gYmFzZTtcbiAgICAgIHRoaXMucHJvcGVydGllcyA9IHByb3BzIHx8IFtdO1xuICAgICAgaWYgKHRhZykge1xuICAgICAgICB0aGlzW3RhZ10gPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgVmFsdWUucHJvdG90eXBlLmNoaWxkcmVuID0gWydiYXNlJywgJ3Byb3BlcnRpZXMnXTtcblxuICAgIFZhbHVlLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbihwcm9wcykge1xuICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gdGhpcy5wcm9wZXJ0aWVzLmNvbmNhdChwcm9wcyk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgVmFsdWUucHJvdG90eXBlLmhhc1Byb3BlcnRpZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAhIXRoaXMucHJvcGVydGllcy5sZW5ndGg7XG4gICAgfTtcblxuICAgIFZhbHVlLnByb3RvdHlwZS5iYXJlTGl0ZXJhbCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgICAgIHJldHVybiAhdGhpcy5wcm9wZXJ0aWVzLmxlbmd0aCAmJiB0aGlzLmJhc2UgaW5zdGFuY2VvZiB0eXBlO1xuICAgIH07XG5cbiAgICBWYWx1ZS5wcm90b3R5cGUuaXNBcnJheSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuYmFyZUxpdGVyYWwoQXJyKTtcbiAgICB9O1xuXG4gICAgVmFsdWUucHJvdG90eXBlLmlzUmFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmJhcmVMaXRlcmFsKFJhbmdlKTtcbiAgICB9O1xuXG4gICAgVmFsdWUucHJvdG90eXBlLmlzQ29tcGxleCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFzUHJvcGVydGllcygpIHx8IHRoaXMuYmFzZS5pc0NvbXBsZXgoKTtcbiAgICB9O1xuXG4gICAgVmFsdWUucHJvdG90eXBlLmlzQXNzaWduYWJsZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFzUHJvcGVydGllcygpIHx8IHRoaXMuYmFzZS5pc0Fzc2lnbmFibGUoKTtcbiAgICB9O1xuXG4gICAgVmFsdWUucHJvdG90eXBlLmlzU2ltcGxlTnVtYmVyID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5iYXJlTGl0ZXJhbChMaXRlcmFsKSAmJiBTSU1QTEVOVU0udGVzdCh0aGlzLmJhc2UudmFsdWUpO1xuICAgIH07XG5cbiAgICBWYWx1ZS5wcm90b3R5cGUuaXNTdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmJhcmVMaXRlcmFsKExpdGVyYWwpICYmIElTX1NUUklORy50ZXN0KHRoaXMuYmFzZS52YWx1ZSk7XG4gICAgfTtcblxuICAgIFZhbHVlLnByb3RvdHlwZS5pc1JlZ2V4ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5iYXJlTGl0ZXJhbChMaXRlcmFsKSAmJiBJU19SRUdFWC50ZXN0KHRoaXMuYmFzZS52YWx1ZSk7XG4gICAgfTtcblxuICAgIFZhbHVlLnByb3RvdHlwZS5pc0F0b21pYyA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG5vZGUsIF9pLCBfbGVuLCBfcmVmMjtcbiAgICAgIF9yZWYyID0gdGhpcy5wcm9wZXJ0aWVzLmNvbmNhdCh0aGlzLmJhc2UpO1xuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBfcmVmMi5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgICBub2RlID0gX3JlZjJbX2ldO1xuICAgICAgICBpZiAobm9kZS5zb2FrIHx8IG5vZGUgaW5zdGFuY2VvZiBDYWxsKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgVmFsdWUucHJvdG90eXBlLmlzTm90Q2FsbGFibGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmlzU2ltcGxlTnVtYmVyKCkgfHwgdGhpcy5pc1N0cmluZygpIHx8IHRoaXMuaXNSZWdleCgpIHx8IHRoaXMuaXNBcnJheSgpIHx8IHRoaXMuaXNSYW5nZSgpIHx8IHRoaXMuaXNTcGxpY2UoKSB8fCB0aGlzLmlzT2JqZWN0KCk7XG4gICAgfTtcblxuICAgIFZhbHVlLnByb3RvdHlwZS5pc1N0YXRlbWVudCA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHJldHVybiAhdGhpcy5wcm9wZXJ0aWVzLmxlbmd0aCAmJiB0aGlzLmJhc2UuaXNTdGF0ZW1lbnQobyk7XG4gICAgfTtcblxuICAgIFZhbHVlLnByb3RvdHlwZS5hc3NpZ25zID0gZnVuY3Rpb24obmFtZSkge1xuICAgICAgcmV0dXJuICF0aGlzLnByb3BlcnRpZXMubGVuZ3RoICYmIHRoaXMuYmFzZS5hc3NpZ25zKG5hbWUpO1xuICAgIH07XG5cbiAgICBWYWx1ZS5wcm90b3R5cGUuanVtcHMgPSBmdW5jdGlvbihvKSB7XG4gICAgICByZXR1cm4gIXRoaXMucHJvcGVydGllcy5sZW5ndGggJiYgdGhpcy5iYXNlLmp1bXBzKG8pO1xuICAgIH07XG5cbiAgICBWYWx1ZS5wcm90b3R5cGUuaXNPYmplY3QgPSBmdW5jdGlvbihvbmx5R2VuZXJhdGVkKSB7XG4gICAgICBpZiAodGhpcy5wcm9wZXJ0aWVzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gKHRoaXMuYmFzZSBpbnN0YW5jZW9mIE9iaikgJiYgKCFvbmx5R2VuZXJhdGVkIHx8IHRoaXMuYmFzZS5nZW5lcmF0ZWQpO1xuICAgIH07XG5cbiAgICBWYWx1ZS5wcm90b3R5cGUuaXNTcGxpY2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBsYXN0KHRoaXMucHJvcGVydGllcykgaW5zdGFuY2VvZiBTbGljZTtcbiAgICB9O1xuXG4gICAgVmFsdWUucHJvdG90eXBlLmxvb2tzU3RhdGljID0gZnVuY3Rpb24oY2xhc3NOYW1lKSB7XG4gICAgICB2YXIgX3JlZjI7XG4gICAgICByZXR1cm4gdGhpcy5iYXNlLnZhbHVlID09PSBjbGFzc05hbWUgJiYgdGhpcy5wcm9wZXJ0aWVzLmxlbmd0aCAmJiAoKF9yZWYyID0gdGhpcy5wcm9wZXJ0aWVzWzBdLm5hbWUpICE9IG51bGwgPyBfcmVmMi52YWx1ZSA6IHZvaWQgMCkgIT09ICdwcm90b3R5cGUnO1xuICAgIH07XG5cbiAgICBWYWx1ZS5wcm90b3R5cGUudW53cmFwID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5wcm9wZXJ0aWVzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJhc2U7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFZhbHVlLnByb3RvdHlwZS5jYWNoZVJlZmVyZW5jZSA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBiYXNlLCBicmVmLCBuYW1lLCBucmVmO1xuICAgICAgbmFtZSA9IGxhc3QodGhpcy5wcm9wZXJ0aWVzKTtcbiAgICAgIGlmICh0aGlzLnByb3BlcnRpZXMubGVuZ3RoIDwgMiAmJiAhdGhpcy5iYXNlLmlzQ29tcGxleCgpICYmICEobmFtZSAhPSBudWxsID8gbmFtZS5pc0NvbXBsZXgoKSA6IHZvaWQgMCkpIHtcbiAgICAgICAgcmV0dXJuIFt0aGlzLCB0aGlzXTtcbiAgICAgIH1cbiAgICAgIGJhc2UgPSBuZXcgVmFsdWUodGhpcy5iYXNlLCB0aGlzLnByb3BlcnRpZXMuc2xpY2UoMCwgLTEpKTtcbiAgICAgIGlmIChiYXNlLmlzQ29tcGxleCgpKSB7XG4gICAgICAgIGJyZWYgPSBuZXcgTGl0ZXJhbChvLnNjb3BlLmZyZWVWYXJpYWJsZSgnYmFzZScpKTtcbiAgICAgICAgYmFzZSA9IG5ldyBWYWx1ZShuZXcgUGFyZW5zKG5ldyBBc3NpZ24oYnJlZiwgYmFzZSkpKTtcbiAgICAgIH1cbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICByZXR1cm4gW2Jhc2UsIGJyZWZdO1xuICAgICAgfVxuICAgICAgaWYgKG5hbWUuaXNDb21wbGV4KCkpIHtcbiAgICAgICAgbnJlZiA9IG5ldyBMaXRlcmFsKG8uc2NvcGUuZnJlZVZhcmlhYmxlKCduYW1lJykpO1xuICAgICAgICBuYW1lID0gbmV3IEluZGV4KG5ldyBBc3NpZ24obnJlZiwgbmFtZS5pbmRleCkpO1xuICAgICAgICBucmVmID0gbmV3IEluZGV4KG5yZWYpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtiYXNlLmFkZChuYW1lKSwgbmV3IFZhbHVlKGJyZWYgfHwgYmFzZS5iYXNlLCBbbnJlZiB8fCBuYW1lXSldO1xuICAgIH07XG5cbiAgICBWYWx1ZS5wcm90b3R5cGUuY29tcGlsZU5vZGUgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgZnJhZ21lbnRzLCBwcm9wLCBwcm9wcywgX2ksIF9sZW47XG4gICAgICB0aGlzLmJhc2UuZnJvbnQgPSB0aGlzLmZyb250O1xuICAgICAgcHJvcHMgPSB0aGlzLnByb3BlcnRpZXM7XG4gICAgICBmcmFnbWVudHMgPSB0aGlzLmJhc2UuY29tcGlsZVRvRnJhZ21lbnRzKG8sIChwcm9wcy5sZW5ndGggPyBMRVZFTF9BQ0NFU1MgOiBudWxsKSk7XG4gICAgICBpZiAoKHRoaXMuYmFzZSBpbnN0YW5jZW9mIFBhcmVucyB8fCBwcm9wcy5sZW5ndGgpICYmIFNJTVBMRU5VTS50ZXN0KGZyYWdtZW50c1RvVGV4dChmcmFnbWVudHMpKSkge1xuICAgICAgICBmcmFnbWVudHMucHVzaCh0aGlzLm1ha2VDb2RlKCcuJykpO1xuICAgICAgfVxuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBwcm9wcy5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgICBwcm9wID0gcHJvcHNbX2ldO1xuICAgICAgICBmcmFnbWVudHMucHVzaC5hcHBseShmcmFnbWVudHMsIHByb3AuY29tcGlsZVRvRnJhZ21lbnRzKG8pKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmcmFnbWVudHM7XG4gICAgfTtcblxuICAgIFZhbHVlLnByb3RvdHlwZS51bmZvbGRTb2FrID0gZnVuY3Rpb24obykge1xuICAgICAgcmV0dXJuIHRoaXMudW5mb2xkZWRTb2FrICE9IG51bGwgPyB0aGlzLnVuZm9sZGVkU29hayA6IHRoaXMudW5mb2xkZWRTb2FrID0gKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgZnN0LCBpLCBpZm4sIHByb3AsIHJlZiwgc25kLCBfaSwgX2xlbiwgX3JlZjIsIF9yZWYzO1xuICAgICAgICAgIGlmIChpZm4gPSBfdGhpcy5iYXNlLnVuZm9sZFNvYWsobykpIHtcbiAgICAgICAgICAgIChfcmVmMiA9IGlmbi5ib2R5LnByb3BlcnRpZXMpLnB1c2guYXBwbHkoX3JlZjIsIF90aGlzLnByb3BlcnRpZXMpO1xuICAgICAgICAgICAgcmV0dXJuIGlmbjtcbiAgICAgICAgICB9XG4gICAgICAgICAgX3JlZjMgPSBfdGhpcy5wcm9wZXJ0aWVzO1xuICAgICAgICAgIGZvciAoaSA9IF9pID0gMCwgX2xlbiA9IF9yZWYzLmxlbmd0aDsgX2kgPCBfbGVuOyBpID0gKytfaSkge1xuICAgICAgICAgICAgcHJvcCA9IF9yZWYzW2ldO1xuICAgICAgICAgICAgaWYgKCFwcm9wLnNvYWspIHtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwcm9wLnNvYWsgPSBmYWxzZTtcbiAgICAgICAgICAgIGZzdCA9IG5ldyBWYWx1ZShfdGhpcy5iYXNlLCBfdGhpcy5wcm9wZXJ0aWVzLnNsaWNlKDAsIGkpKTtcbiAgICAgICAgICAgIHNuZCA9IG5ldyBWYWx1ZShfdGhpcy5iYXNlLCBfdGhpcy5wcm9wZXJ0aWVzLnNsaWNlKGkpKTtcbiAgICAgICAgICAgIGlmIChmc3QuaXNDb21wbGV4KCkpIHtcbiAgICAgICAgICAgICAgcmVmID0gbmV3IExpdGVyYWwoby5zY29wZS5mcmVlVmFyaWFibGUoJ3JlZicpKTtcbiAgICAgICAgICAgICAgZnN0ID0gbmV3IFBhcmVucyhuZXcgQXNzaWduKHJlZiwgZnN0KSk7XG4gICAgICAgICAgICAgIHNuZC5iYXNlID0gcmVmO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBJZihuZXcgRXhpc3RlbmNlKGZzdCksIHNuZCwge1xuICAgICAgICAgICAgICBzb2FrOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFZhbHVlO1xuXG4gIH0pKEJhc2UpO1xuXG4gIGV4cG9ydHMuQ29tbWVudCA9IENvbW1lbnQgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKENvbW1lbnQsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBDb21tZW50KGNvbW1lbnQpIHtcbiAgICAgIHRoaXMuY29tbWVudCA9IGNvbW1lbnQ7XG4gICAgfVxuXG4gICAgQ29tbWVudC5wcm90b3R5cGUuaXNTdGF0ZW1lbnQgPSBZRVM7XG5cbiAgICBDb21tZW50LnByb3RvdHlwZS5tYWtlUmV0dXJuID0gVEhJUztcblxuICAgIENvbW1lbnQucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24obywgbGV2ZWwpIHtcbiAgICAgIHZhciBjb2RlLCBjb21tZW50O1xuICAgICAgY29tbWVudCA9IHRoaXMuY29tbWVudC5yZXBsYWNlKC9eKFxccyopIy9nbSwgXCIkMSAqXCIpO1xuICAgICAgY29kZSA9IFwiLypcIiArIChtdWx0aWRlbnQoY29tbWVudCwgdGhpcy50YWIpKSArIChfX2luZGV4T2YuY2FsbChjb21tZW50LCAnXFxuJykgPj0gMCA/IFwiXFxuXCIgKyB0aGlzLnRhYiA6ICcnKSArIFwiICovXCI7XG4gICAgICBpZiAoKGxldmVsIHx8IG8ubGV2ZWwpID09PSBMRVZFTF9UT1ApIHtcbiAgICAgICAgY29kZSA9IG8uaW5kZW50ICsgY29kZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbdGhpcy5tYWtlQ29kZShcIlxcblwiKSwgdGhpcy5tYWtlQ29kZShjb2RlKV07XG4gICAgfTtcblxuICAgIHJldHVybiBDb21tZW50O1xuXG4gIH0pKEJhc2UpO1xuXG4gIGV4cG9ydHMuQ2FsbCA9IENhbGwgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKENhbGwsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBDYWxsKHZhcmlhYmxlLCBhcmdzLCBzb2FrKSB7XG4gICAgICB0aGlzLmFyZ3MgPSBhcmdzICE9IG51bGwgPyBhcmdzIDogW107XG4gICAgICB0aGlzLnNvYWsgPSBzb2FrO1xuICAgICAgdGhpcy5pc05ldyA9IGZhbHNlO1xuICAgICAgdGhpcy5pc1N1cGVyID0gdmFyaWFibGUgPT09ICdzdXBlcic7XG4gICAgICB0aGlzLnZhcmlhYmxlID0gdGhpcy5pc1N1cGVyID8gbnVsbCA6IHZhcmlhYmxlO1xuICAgICAgaWYgKHZhcmlhYmxlIGluc3RhbmNlb2YgVmFsdWUgJiYgdmFyaWFibGUuaXNOb3RDYWxsYWJsZSgpKSB7XG4gICAgICAgIHZhcmlhYmxlLmVycm9yKFwibGl0ZXJhbCBpcyBub3QgYSBmdW5jdGlvblwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBDYWxsLnByb3RvdHlwZS5jaGlsZHJlbiA9IFsndmFyaWFibGUnLCAnYXJncyddO1xuXG4gICAgQ2FsbC5wcm90b3R5cGUubmV3SW5zdGFuY2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBiYXNlLCBfcmVmMjtcbiAgICAgIGJhc2UgPSAoKF9yZWYyID0gdGhpcy52YXJpYWJsZSkgIT0gbnVsbCA/IF9yZWYyLmJhc2UgOiB2b2lkIDApIHx8IHRoaXMudmFyaWFibGU7XG4gICAgICBpZiAoYmFzZSBpbnN0YW5jZW9mIENhbGwgJiYgIWJhc2UuaXNOZXcpIHtcbiAgICAgICAgYmFzZS5uZXdJbnN0YW5jZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pc05ldyA9IHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgQ2FsbC5wcm90b3R5cGUuc3VwZXJSZWZlcmVuY2UgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgYWNjZXNzZXMsIG1ldGhvZDtcbiAgICAgIG1ldGhvZCA9IG8uc2NvcGUubmFtZWRNZXRob2QoKTtcbiAgICAgIGlmIChtZXRob2QgIT0gbnVsbCA/IG1ldGhvZC5rbGFzcyA6IHZvaWQgMCkge1xuICAgICAgICBhY2Nlc3NlcyA9IFtuZXcgQWNjZXNzKG5ldyBMaXRlcmFsKCdfX3N1cGVyX18nKSldO1xuICAgICAgICBpZiAobWV0aG9kW1wic3RhdGljXCJdKSB7XG4gICAgICAgICAgYWNjZXNzZXMucHVzaChuZXcgQWNjZXNzKG5ldyBMaXRlcmFsKCdjb25zdHJ1Y3RvcicpKSk7XG4gICAgICAgIH1cbiAgICAgICAgYWNjZXNzZXMucHVzaChuZXcgQWNjZXNzKG5ldyBMaXRlcmFsKG1ldGhvZC5uYW1lKSkpO1xuICAgICAgICByZXR1cm4gKG5ldyBWYWx1ZShuZXcgTGl0ZXJhbChtZXRob2Qua2xhc3MpLCBhY2Nlc3NlcykpLmNvbXBpbGUobyk7XG4gICAgICB9IGVsc2UgaWYgKG1ldGhvZCAhPSBudWxsID8gbWV0aG9kLmN0b3IgOiB2b2lkIDApIHtcbiAgICAgICAgcmV0dXJuIFwiXCIgKyBtZXRob2QubmFtZSArIFwiLl9fc3VwZXJfXy5jb25zdHJ1Y3RvclwiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZXJyb3IoJ2Nhbm5vdCBjYWxsIHN1cGVyIG91dHNpZGUgb2YgYW4gaW5zdGFuY2UgbWV0aG9kLicpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBDYWxsLnByb3RvdHlwZS5zdXBlclRoaXMgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgbWV0aG9kO1xuICAgICAgbWV0aG9kID0gby5zY29wZS5tZXRob2Q7XG4gICAgICByZXR1cm4gKG1ldGhvZCAmJiAhbWV0aG9kLmtsYXNzICYmIG1ldGhvZC5jb250ZXh0KSB8fCBcInRoaXNcIjtcbiAgICB9O1xuXG4gICAgQ2FsbC5wcm90b3R5cGUudW5mb2xkU29hayA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBjYWxsLCBpZm4sIGxlZnQsIGxpc3QsIHJpdGUsIF9pLCBfbGVuLCBfcmVmMiwgX3JlZjM7XG4gICAgICBpZiAodGhpcy5zb2FrKSB7XG4gICAgICAgIGlmICh0aGlzLnZhcmlhYmxlKSB7XG4gICAgICAgICAgaWYgKGlmbiA9IHVuZm9sZFNvYWsobywgdGhpcywgJ3ZhcmlhYmxlJykpIHtcbiAgICAgICAgICAgIHJldHVybiBpZm47XG4gICAgICAgICAgfVxuICAgICAgICAgIF9yZWYyID0gbmV3IFZhbHVlKHRoaXMudmFyaWFibGUpLmNhY2hlUmVmZXJlbmNlKG8pLCBsZWZ0ID0gX3JlZjJbMF0sIHJpdGUgPSBfcmVmMlsxXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsZWZ0ID0gbmV3IExpdGVyYWwodGhpcy5zdXBlclJlZmVyZW5jZShvKSk7XG4gICAgICAgICAgcml0ZSA9IG5ldyBWYWx1ZShsZWZ0KTtcbiAgICAgICAgfVxuICAgICAgICByaXRlID0gbmV3IENhbGwocml0ZSwgdGhpcy5hcmdzKTtcbiAgICAgICAgcml0ZS5pc05ldyA9IHRoaXMuaXNOZXc7XG4gICAgICAgIGxlZnQgPSBuZXcgTGl0ZXJhbChcInR5cGVvZiBcIiArIChsZWZ0LmNvbXBpbGUobykpICsgXCIgPT09IFxcXCJmdW5jdGlvblxcXCJcIik7XG4gICAgICAgIHJldHVybiBuZXcgSWYobGVmdCwgbmV3IFZhbHVlKHJpdGUpLCB7XG4gICAgICAgICAgc29hazogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNhbGwgPSB0aGlzO1xuICAgICAgbGlzdCA9IFtdO1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaWYgKGNhbGwudmFyaWFibGUgaW5zdGFuY2VvZiBDYWxsKSB7XG4gICAgICAgICAgbGlzdC5wdXNoKGNhbGwpO1xuICAgICAgICAgIGNhbGwgPSBjYWxsLnZhcmlhYmxlO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghKGNhbGwudmFyaWFibGUgaW5zdGFuY2VvZiBWYWx1ZSkpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBsaXN0LnB1c2goY2FsbCk7XG4gICAgICAgIGlmICghKChjYWxsID0gY2FsbC52YXJpYWJsZS5iYXNlKSBpbnN0YW5jZW9mIENhbGwpKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIF9yZWYzID0gbGlzdC5yZXZlcnNlKCk7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGNhbGwgPSBfcmVmM1tfaV07XG4gICAgICAgIGlmIChpZm4pIHtcbiAgICAgICAgICBpZiAoY2FsbC52YXJpYWJsZSBpbnN0YW5jZW9mIENhbGwpIHtcbiAgICAgICAgICAgIGNhbGwudmFyaWFibGUgPSBpZm47XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhbGwudmFyaWFibGUuYmFzZSA9IGlmbjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWZuID0gdW5mb2xkU29hayhvLCBjYWxsLCAndmFyaWFibGUnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpZm47XG4gICAgfTtcblxuICAgIENhbGwucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGFyZywgYXJnSW5kZXgsIGNvbXBpbGVkQXJncywgY29tcGlsZWRBcnJheSwgZnJhZ21lbnRzLCBwcmVmYWNlLCBfaSwgX2xlbiwgX3JlZjIsIF9yZWYzO1xuICAgICAgaWYgKChfcmVmMiA9IHRoaXMudmFyaWFibGUpICE9IG51bGwpIHtcbiAgICAgICAgX3JlZjIuZnJvbnQgPSB0aGlzLmZyb250O1xuICAgICAgfVxuICAgICAgY29tcGlsZWRBcnJheSA9IFNwbGF0LmNvbXBpbGVTcGxhdHRlZEFycmF5KG8sIHRoaXMuYXJncywgdHJ1ZSk7XG4gICAgICBpZiAoY29tcGlsZWRBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcGlsZVNwbGF0KG8sIGNvbXBpbGVkQXJyYXkpO1xuICAgICAgfVxuICAgICAgY29tcGlsZWRBcmdzID0gW107XG4gICAgICBfcmVmMyA9IHRoaXMuYXJncztcbiAgICAgIGZvciAoYXJnSW5kZXggPSBfaSA9IDAsIF9sZW4gPSBfcmVmMy5sZW5ndGg7IF9pIDwgX2xlbjsgYXJnSW5kZXggPSArK19pKSB7XG4gICAgICAgIGFyZyA9IF9yZWYzW2FyZ0luZGV4XTtcbiAgICAgICAgaWYgKGFyZ0luZGV4KSB7XG4gICAgICAgICAgY29tcGlsZWRBcmdzLnB1c2godGhpcy5tYWtlQ29kZShcIiwgXCIpKTtcbiAgICAgICAgfVxuICAgICAgICBjb21waWxlZEFyZ3MucHVzaC5hcHBseShjb21waWxlZEFyZ3MsIGFyZy5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfTElTVCkpO1xuICAgICAgfVxuICAgICAgZnJhZ21lbnRzID0gW107XG4gICAgICBpZiAodGhpcy5pc1N1cGVyKSB7XG4gICAgICAgIHByZWZhY2UgPSB0aGlzLnN1cGVyUmVmZXJlbmNlKG8pICsgKFwiLmNhbGwoXCIgKyAodGhpcy5zdXBlclRoaXMobykpKTtcbiAgICAgICAgaWYgKGNvbXBpbGVkQXJncy5sZW5ndGgpIHtcbiAgICAgICAgICBwcmVmYWNlICs9IFwiLCBcIjtcbiAgICAgICAgfVxuICAgICAgICBmcmFnbWVudHMucHVzaCh0aGlzLm1ha2VDb2RlKHByZWZhY2UpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLmlzTmV3KSB7XG4gICAgICAgICAgZnJhZ21lbnRzLnB1c2godGhpcy5tYWtlQ29kZSgnbmV3ICcpKTtcbiAgICAgICAgfVxuICAgICAgICBmcmFnbWVudHMucHVzaC5hcHBseShmcmFnbWVudHMsIHRoaXMudmFyaWFibGUuY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX0FDQ0VTUykpO1xuICAgICAgICBmcmFnbWVudHMucHVzaCh0aGlzLm1ha2VDb2RlKFwiKFwiKSk7XG4gICAgICB9XG4gICAgICBmcmFnbWVudHMucHVzaC5hcHBseShmcmFnbWVudHMsIGNvbXBpbGVkQXJncyk7XG4gICAgICBmcmFnbWVudHMucHVzaCh0aGlzLm1ha2VDb2RlKFwiKVwiKSk7XG4gICAgICByZXR1cm4gZnJhZ21lbnRzO1xuICAgIH07XG5cbiAgICBDYWxsLnByb3RvdHlwZS5jb21waWxlU3BsYXQgPSBmdW5jdGlvbihvLCBzcGxhdEFyZ3MpIHtcbiAgICAgIHZhciBhbnN3ZXIsIGJhc2UsIGZ1biwgaWR0LCBuYW1lLCByZWY7XG4gICAgICBpZiAodGhpcy5pc1N1cGVyKSB7XG4gICAgICAgIHJldHVybiBbXS5jb25jYXQodGhpcy5tYWtlQ29kZShcIlwiICsgKHRoaXMuc3VwZXJSZWZlcmVuY2UobykpICsgXCIuYXBwbHkoXCIgKyAodGhpcy5zdXBlclRoaXMobykpICsgXCIsIFwiKSwgc3BsYXRBcmdzLCB0aGlzLm1ha2VDb2RlKFwiKVwiKSk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5pc05ldykge1xuICAgICAgICBpZHQgPSB0aGlzLnRhYiArIFRBQjtcbiAgICAgICAgcmV0dXJuIFtdLmNvbmNhdCh0aGlzLm1ha2VDb2RlKFwiKGZ1bmN0aW9uKGZ1bmMsIGFyZ3MsIGN0b3IpIHtcXG5cIiArIGlkdCArIFwiY3Rvci5wcm90b3R5cGUgPSBmdW5jLnByb3RvdHlwZTtcXG5cIiArIGlkdCArIFwidmFyIGNoaWxkID0gbmV3IGN0b3IsIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY2hpbGQsIGFyZ3MpO1xcblwiICsgaWR0ICsgXCJyZXR1cm4gT2JqZWN0KHJlc3VsdCkgPT09IHJlc3VsdCA/IHJlc3VsdCA6IGNoaWxkO1xcblwiICsgdGhpcy50YWIgKyBcIn0pKFwiKSwgdGhpcy52YXJpYWJsZS5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfTElTVCksIHRoaXMubWFrZUNvZGUoXCIsIFwiKSwgc3BsYXRBcmdzLCB0aGlzLm1ha2VDb2RlKFwiLCBmdW5jdGlvbigpe30pXCIpKTtcbiAgICAgIH1cbiAgICAgIGFuc3dlciA9IFtdO1xuICAgICAgYmFzZSA9IG5ldyBWYWx1ZSh0aGlzLnZhcmlhYmxlKTtcbiAgICAgIGlmICgobmFtZSA9IGJhc2UucHJvcGVydGllcy5wb3AoKSkgJiYgYmFzZS5pc0NvbXBsZXgoKSkge1xuICAgICAgICByZWYgPSBvLnNjb3BlLmZyZWVWYXJpYWJsZSgncmVmJyk7XG4gICAgICAgIGFuc3dlciA9IGFuc3dlci5jb25jYXQodGhpcy5tYWtlQ29kZShcIihcIiArIHJlZiArIFwiID0gXCIpLCBiYXNlLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9MSVNUKSwgdGhpcy5tYWtlQ29kZShcIilcIiksIG5hbWUuY29tcGlsZVRvRnJhZ21lbnRzKG8pKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZ1biA9IGJhc2UuY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX0FDQ0VTUyk7XG4gICAgICAgIGlmIChTSU1QTEVOVU0udGVzdChmcmFnbWVudHNUb1RleHQoZnVuKSkpIHtcbiAgICAgICAgICBmdW4gPSB0aGlzLndyYXBJbkJyYWNlcyhmdW4pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgICAgcmVmID0gZnJhZ21lbnRzVG9UZXh0KGZ1bik7XG4gICAgICAgICAgZnVuLnB1c2guYXBwbHkoZnVuLCBuYW1lLmNvbXBpbGVUb0ZyYWdtZW50cyhvKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVmID0gJ251bGwnO1xuICAgICAgICB9XG4gICAgICAgIGFuc3dlciA9IGFuc3dlci5jb25jYXQoZnVuKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhbnN3ZXIgPSBhbnN3ZXIuY29uY2F0KHRoaXMubWFrZUNvZGUoXCIuYXBwbHkoXCIgKyByZWYgKyBcIiwgXCIpLCBzcGxhdEFyZ3MsIHRoaXMubWFrZUNvZGUoXCIpXCIpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIENhbGw7XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5FeHRlbmRzID0gRXh0ZW5kcyA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoRXh0ZW5kcywgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIEV4dGVuZHMoY2hpbGQsIHBhcmVudCkge1xuICAgICAgdGhpcy5jaGlsZCA9IGNoaWxkO1xuICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgfVxuXG4gICAgRXh0ZW5kcy5wcm90b3R5cGUuY2hpbGRyZW4gPSBbJ2NoaWxkJywgJ3BhcmVudCddO1xuXG4gICAgRXh0ZW5kcy5wcm90b3R5cGUuY29tcGlsZVRvRnJhZ21lbnRzID0gZnVuY3Rpb24obykge1xuICAgICAgcmV0dXJuIG5ldyBDYWxsKG5ldyBWYWx1ZShuZXcgTGl0ZXJhbCh1dGlsaXR5KCdleHRlbmRzJykpKSwgW3RoaXMuY2hpbGQsIHRoaXMucGFyZW50XSkuY29tcGlsZVRvRnJhZ21lbnRzKG8pO1xuICAgIH07XG5cbiAgICByZXR1cm4gRXh0ZW5kcztcblxuICB9KShCYXNlKTtcblxuICBleHBvcnRzLkFjY2VzcyA9IEFjY2VzcyA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoQWNjZXNzLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gQWNjZXNzKG5hbWUsIHRhZykge1xuICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgIHRoaXMubmFtZS5hc0tleSA9IHRydWU7XG4gICAgICB0aGlzLnNvYWsgPSB0YWcgPT09ICdzb2FrJztcbiAgICB9XG5cbiAgICBBY2Nlc3MucHJvdG90eXBlLmNoaWxkcmVuID0gWyduYW1lJ107XG5cbiAgICBBY2Nlc3MucHJvdG90eXBlLmNvbXBpbGVUb0ZyYWdtZW50cyA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBuYW1lO1xuICAgICAgbmFtZSA9IHRoaXMubmFtZS5jb21waWxlVG9GcmFnbWVudHMobyk7XG4gICAgICBpZiAoSURFTlRJRklFUi50ZXN0KGZyYWdtZW50c1RvVGV4dChuYW1lKSkpIHtcbiAgICAgICAgbmFtZS51bnNoaWZ0KHRoaXMubWFrZUNvZGUoXCIuXCIpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5hbWUudW5zaGlmdCh0aGlzLm1ha2VDb2RlKFwiW1wiKSk7XG4gICAgICAgIG5hbWUucHVzaCh0aGlzLm1ha2VDb2RlKFwiXVwiKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmFtZTtcbiAgICB9O1xuXG4gICAgQWNjZXNzLnByb3RvdHlwZS5pc0NvbXBsZXggPSBOTztcblxuICAgIHJldHVybiBBY2Nlc3M7XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5JbmRleCA9IEluZGV4ID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhJbmRleCwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIEluZGV4KGluZGV4KSB7XG4gICAgICB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgfVxuXG4gICAgSW5kZXgucHJvdG90eXBlLmNoaWxkcmVuID0gWydpbmRleCddO1xuXG4gICAgSW5kZXgucHJvdG90eXBlLmNvbXBpbGVUb0ZyYWdtZW50cyA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHJldHVybiBbXS5jb25jYXQodGhpcy5tYWtlQ29kZShcIltcIiksIHRoaXMuaW5kZXguY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX1BBUkVOKSwgdGhpcy5tYWtlQ29kZShcIl1cIikpO1xuICAgIH07XG5cbiAgICBJbmRleC5wcm90b3R5cGUuaXNDb21wbGV4ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5pbmRleC5pc0NvbXBsZXgoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEluZGV4O1xuXG4gIH0pKEJhc2UpO1xuXG4gIGV4cG9ydHMuUmFuZ2UgPSBSYW5nZSA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoUmFuZ2UsIF9zdXBlcik7XG5cbiAgICBSYW5nZS5wcm90b3R5cGUuY2hpbGRyZW4gPSBbJ2Zyb20nLCAndG8nXTtcblxuICAgIGZ1bmN0aW9uIFJhbmdlKGZyb20sIHRvLCB0YWcpIHtcbiAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgICB0aGlzLnRvID0gdG87XG4gICAgICB0aGlzLmV4Y2x1c2l2ZSA9IHRhZyA9PT0gJ2V4Y2x1c2l2ZSc7XG4gICAgICB0aGlzLmVxdWFscyA9IHRoaXMuZXhjbHVzaXZlID8gJycgOiAnPSc7XG4gICAgfVxuXG4gICAgUmFuZ2UucHJvdG90eXBlLmNvbXBpbGVWYXJpYWJsZXMgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgc3RlcCwgX3JlZjIsIF9yZWYzLCBfcmVmNCwgX3JlZjU7XG4gICAgICBvID0gbWVyZ2Uobywge1xuICAgICAgICB0b3A6IHRydWVcbiAgICAgIH0pO1xuICAgICAgX3JlZjIgPSB0aGlzLmNhY2hlVG9Db2RlRnJhZ21lbnRzKHRoaXMuZnJvbS5jYWNoZShvLCBMRVZFTF9MSVNUKSksIHRoaXMuZnJvbUMgPSBfcmVmMlswXSwgdGhpcy5mcm9tVmFyID0gX3JlZjJbMV07XG4gICAgICBfcmVmMyA9IHRoaXMuY2FjaGVUb0NvZGVGcmFnbWVudHModGhpcy50by5jYWNoZShvLCBMRVZFTF9MSVNUKSksIHRoaXMudG9DID0gX3JlZjNbMF0sIHRoaXMudG9WYXIgPSBfcmVmM1sxXTtcbiAgICAgIGlmIChzdGVwID0gZGVsKG8sICdzdGVwJykpIHtcbiAgICAgICAgX3JlZjQgPSB0aGlzLmNhY2hlVG9Db2RlRnJhZ21lbnRzKHN0ZXAuY2FjaGUobywgTEVWRUxfTElTVCkpLCB0aGlzLnN0ZXAgPSBfcmVmNFswXSwgdGhpcy5zdGVwVmFyID0gX3JlZjRbMV07XG4gICAgICB9XG4gICAgICBfcmVmNSA9IFt0aGlzLmZyb21WYXIubWF0Y2goTlVNQkVSKSwgdGhpcy50b1Zhci5tYXRjaChOVU1CRVIpXSwgdGhpcy5mcm9tTnVtID0gX3JlZjVbMF0sIHRoaXMudG9OdW0gPSBfcmVmNVsxXTtcbiAgICAgIGlmICh0aGlzLnN0ZXBWYXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RlcE51bSA9IHRoaXMuc3RlcFZhci5tYXRjaChOVU1CRVIpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBSYW5nZS5wcm90b3R5cGUuY29tcGlsZU5vZGUgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgY29uZCwgY29uZFBhcnQsIGZyb20sIGd0LCBpZHgsIGlkeE5hbWUsIGtub3duLCBsdCwgbmFtZWRJbmRleCwgc3RlcFBhcnQsIHRvLCB2YXJQYXJ0LCBfcmVmMiwgX3JlZjM7XG4gICAgICBpZiAoIXRoaXMuZnJvbVZhcikge1xuICAgICAgICB0aGlzLmNvbXBpbGVWYXJpYWJsZXMobyk7XG4gICAgICB9XG4gICAgICBpZiAoIW8uaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcGlsZUFycmF5KG8pO1xuICAgICAgfVxuICAgICAga25vd24gPSB0aGlzLmZyb21OdW0gJiYgdGhpcy50b051bTtcbiAgICAgIGlkeCA9IGRlbChvLCAnaW5kZXgnKTtcbiAgICAgIGlkeE5hbWUgPSBkZWwobywgJ25hbWUnKTtcbiAgICAgIG5hbWVkSW5kZXggPSBpZHhOYW1lICYmIGlkeE5hbWUgIT09IGlkeDtcbiAgICAgIHZhclBhcnQgPSBcIlwiICsgaWR4ICsgXCIgPSBcIiArIHRoaXMuZnJvbUM7XG4gICAgICBpZiAodGhpcy50b0MgIT09IHRoaXMudG9WYXIpIHtcbiAgICAgICAgdmFyUGFydCArPSBcIiwgXCIgKyB0aGlzLnRvQztcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnN0ZXAgIT09IHRoaXMuc3RlcFZhcikge1xuICAgICAgICB2YXJQYXJ0ICs9IFwiLCBcIiArIHRoaXMuc3RlcDtcbiAgICAgIH1cbiAgICAgIF9yZWYyID0gW1wiXCIgKyBpZHggKyBcIiA8XCIgKyB0aGlzLmVxdWFscywgXCJcIiArIGlkeCArIFwiID5cIiArIHRoaXMuZXF1YWxzXSwgbHQgPSBfcmVmMlswXSwgZ3QgPSBfcmVmMlsxXTtcbiAgICAgIGNvbmRQYXJ0ID0gdGhpcy5zdGVwTnVtID8gcGFyc2VOdW0odGhpcy5zdGVwTnVtWzBdKSA+IDAgPyBcIlwiICsgbHQgKyBcIiBcIiArIHRoaXMudG9WYXIgOiBcIlwiICsgZ3QgKyBcIiBcIiArIHRoaXMudG9WYXIgOiBrbm93biA/ICgoX3JlZjMgPSBbcGFyc2VOdW0odGhpcy5mcm9tTnVtWzBdKSwgcGFyc2VOdW0odGhpcy50b051bVswXSldLCBmcm9tID0gX3JlZjNbMF0sIHRvID0gX3JlZjNbMV0sIF9yZWYzKSwgZnJvbSA8PSB0byA/IFwiXCIgKyBsdCArIFwiIFwiICsgdG8gOiBcIlwiICsgZ3QgKyBcIiBcIiArIHRvKSA6IChjb25kID0gdGhpcy5zdGVwVmFyID8gXCJcIiArIHRoaXMuc3RlcFZhciArIFwiID4gMFwiIDogXCJcIiArIHRoaXMuZnJvbVZhciArIFwiIDw9IFwiICsgdGhpcy50b1ZhciwgXCJcIiArIGNvbmQgKyBcIiA/IFwiICsgbHQgKyBcIiBcIiArIHRoaXMudG9WYXIgKyBcIiA6IFwiICsgZ3QgKyBcIiBcIiArIHRoaXMudG9WYXIpO1xuICAgICAgc3RlcFBhcnQgPSB0aGlzLnN0ZXBWYXIgPyBcIlwiICsgaWR4ICsgXCIgKz0gXCIgKyB0aGlzLnN0ZXBWYXIgOiBrbm93biA/IG5hbWVkSW5kZXggPyBmcm9tIDw9IHRvID8gXCIrK1wiICsgaWR4IDogXCItLVwiICsgaWR4IDogZnJvbSA8PSB0byA/IFwiXCIgKyBpZHggKyBcIisrXCIgOiBcIlwiICsgaWR4ICsgXCItLVwiIDogbmFtZWRJbmRleCA/IFwiXCIgKyBjb25kICsgXCIgPyArK1wiICsgaWR4ICsgXCIgOiAtLVwiICsgaWR4IDogXCJcIiArIGNvbmQgKyBcIiA/IFwiICsgaWR4ICsgXCIrKyA6IFwiICsgaWR4ICsgXCItLVwiO1xuICAgICAgaWYgKG5hbWVkSW5kZXgpIHtcbiAgICAgICAgdmFyUGFydCA9IFwiXCIgKyBpZHhOYW1lICsgXCIgPSBcIiArIHZhclBhcnQ7XG4gICAgICB9XG4gICAgICBpZiAobmFtZWRJbmRleCkge1xuICAgICAgICBzdGVwUGFydCA9IFwiXCIgKyBpZHhOYW1lICsgXCIgPSBcIiArIHN0ZXBQYXJ0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIFt0aGlzLm1ha2VDb2RlKFwiXCIgKyB2YXJQYXJ0ICsgXCI7IFwiICsgY29uZFBhcnQgKyBcIjsgXCIgKyBzdGVwUGFydCldO1xuICAgIH07XG5cbiAgICBSYW5nZS5wcm90b3R5cGUuY29tcGlsZUFycmF5ID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGFyZ3MsIGJvZHksIGNvbmQsIGhhc0FyZ3MsIGksIGlkdCwgcG9zdCwgcHJlLCByYW5nZSwgcmVzdWx0LCB2YXJzLCBfaSwgX3JlZjIsIF9yZWYzLCBfcmVzdWx0cztcbiAgICAgIGlmICh0aGlzLmZyb21OdW0gJiYgdGhpcy50b051bSAmJiBNYXRoLmFicyh0aGlzLmZyb21OdW0gLSB0aGlzLnRvTnVtKSA8PSAyMCkge1xuICAgICAgICByYW5nZSA9IChmdW5jdGlvbigpIHtcbiAgICAgICAgICBfcmVzdWx0cyA9IFtdO1xuICAgICAgICAgIGZvciAodmFyIF9pID0gX3JlZjIgPSArdGhpcy5mcm9tTnVtLCBfcmVmMyA9ICt0aGlzLnRvTnVtOyBfcmVmMiA8PSBfcmVmMyA/IF9pIDw9IF9yZWYzIDogX2kgPj0gX3JlZjM7IF9yZWYyIDw9IF9yZWYzID8gX2krKyA6IF9pLS0peyBfcmVzdWx0cy5wdXNoKF9pKTsgfVxuICAgICAgICAgIHJldHVybiBfcmVzdWx0cztcbiAgICAgICAgfSkuYXBwbHkodGhpcyk7XG4gICAgICAgIGlmICh0aGlzLmV4Y2x1c2l2ZSkge1xuICAgICAgICAgIHJhbmdlLnBvcCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbdGhpcy5tYWtlQ29kZShcIltcIiArIChyYW5nZS5qb2luKCcsICcpKSArIFwiXVwiKV07XG4gICAgICB9XG4gICAgICBpZHQgPSB0aGlzLnRhYiArIFRBQjtcbiAgICAgIGkgPSBvLnNjb3BlLmZyZWVWYXJpYWJsZSgnaScpO1xuICAgICAgcmVzdWx0ID0gby5zY29wZS5mcmVlVmFyaWFibGUoJ3Jlc3VsdHMnKTtcbiAgICAgIHByZSA9IFwiXFxuXCIgKyBpZHQgKyByZXN1bHQgKyBcIiA9IFtdO1wiO1xuICAgICAgaWYgKHRoaXMuZnJvbU51bSAmJiB0aGlzLnRvTnVtKSB7XG4gICAgICAgIG8uaW5kZXggPSBpO1xuICAgICAgICBib2R5ID0gZnJhZ21lbnRzVG9UZXh0KHRoaXMuY29tcGlsZU5vZGUobykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFycyA9IChcIlwiICsgaSArIFwiID0gXCIgKyB0aGlzLmZyb21DKSArICh0aGlzLnRvQyAhPT0gdGhpcy50b1ZhciA/IFwiLCBcIiArIHRoaXMudG9DIDogJycpO1xuICAgICAgICBjb25kID0gXCJcIiArIHRoaXMuZnJvbVZhciArIFwiIDw9IFwiICsgdGhpcy50b1ZhcjtcbiAgICAgICAgYm9keSA9IFwidmFyIFwiICsgdmFycyArIFwiOyBcIiArIGNvbmQgKyBcIiA/IFwiICsgaSArIFwiIDxcIiArIHRoaXMuZXF1YWxzICsgXCIgXCIgKyB0aGlzLnRvVmFyICsgXCIgOiBcIiArIGkgKyBcIiA+XCIgKyB0aGlzLmVxdWFscyArIFwiIFwiICsgdGhpcy50b1ZhciArIFwiOyBcIiArIGNvbmQgKyBcIiA/IFwiICsgaSArIFwiKysgOiBcIiArIGkgKyBcIi0tXCI7XG4gICAgICB9XG4gICAgICBwb3N0ID0gXCJ7IFwiICsgcmVzdWx0ICsgXCIucHVzaChcIiArIGkgKyBcIik7IH1cXG5cIiArIGlkdCArIFwicmV0dXJuIFwiICsgcmVzdWx0ICsgXCI7XFxuXCIgKyBvLmluZGVudDtcbiAgICAgIGhhc0FyZ3MgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIHJldHVybiBub2RlICE9IG51bGwgPyBub2RlLmNvbnRhaW5zKGlzTGl0ZXJhbEFyZ3VtZW50cykgOiB2b2lkIDA7XG4gICAgICB9O1xuICAgICAgaWYgKGhhc0FyZ3ModGhpcy5mcm9tKSB8fCBoYXNBcmdzKHRoaXMudG8pKSB7XG4gICAgICAgIGFyZ3MgPSAnLCBhcmd1bWVudHMnO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFt0aGlzLm1ha2VDb2RlKFwiKGZ1bmN0aW9uKCkge1wiICsgcHJlICsgXCJcXG5cIiArIGlkdCArIFwiZm9yIChcIiArIGJvZHkgKyBcIilcIiArIHBvc3QgKyBcIn0pLmFwcGx5KHRoaXNcIiArIChhcmdzICE9IG51bGwgPyBhcmdzIDogJycpICsgXCIpXCIpXTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFJhbmdlO1xuXG4gIH0pKEJhc2UpO1xuXG4gIGV4cG9ydHMuU2xpY2UgPSBTbGljZSA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoU2xpY2UsIF9zdXBlcik7XG5cbiAgICBTbGljZS5wcm90b3R5cGUuY2hpbGRyZW4gPSBbJ3JhbmdlJ107XG5cbiAgICBmdW5jdGlvbiBTbGljZShyYW5nZSkge1xuICAgICAgdGhpcy5yYW5nZSA9IHJhbmdlO1xuICAgICAgU2xpY2UuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7XG4gICAgfVxuXG4gICAgU2xpY2UucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGNvbXBpbGVkLCBjb21waWxlZFRleHQsIGZyb20sIGZyb21Db21waWxlZCwgdG8sIHRvU3RyLCBfcmVmMjtcbiAgICAgIF9yZWYyID0gdGhpcy5yYW5nZSwgdG8gPSBfcmVmMi50bywgZnJvbSA9IF9yZWYyLmZyb207XG4gICAgICBmcm9tQ29tcGlsZWQgPSBmcm9tICYmIGZyb20uY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX1BBUkVOKSB8fCBbdGhpcy5tYWtlQ29kZSgnMCcpXTtcbiAgICAgIGlmICh0bykge1xuICAgICAgICBjb21waWxlZCA9IHRvLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9QQVJFTik7XG4gICAgICAgIGNvbXBpbGVkVGV4dCA9IGZyYWdtZW50c1RvVGV4dChjb21waWxlZCk7XG4gICAgICAgIGlmICghKCF0aGlzLnJhbmdlLmV4Y2x1c2l2ZSAmJiArY29tcGlsZWRUZXh0ID09PSAtMSkpIHtcbiAgICAgICAgICB0b1N0ciA9ICcsICcgKyAodGhpcy5yYW5nZS5leGNsdXNpdmUgPyBjb21waWxlZFRleHQgOiBTSU1QTEVOVU0udGVzdChjb21waWxlZFRleHQpID8gXCJcIiArICgrY29tcGlsZWRUZXh0ICsgMSkgOiAoY29tcGlsZWQgPSB0by5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfQUNDRVNTKSwgXCIrXCIgKyAoZnJhZ21lbnRzVG9UZXh0KGNvbXBpbGVkKSkgKyBcIiArIDEgfHwgOWU5XCIpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIFt0aGlzLm1ha2VDb2RlKFwiLnNsaWNlKFwiICsgKGZyYWdtZW50c1RvVGV4dChmcm9tQ29tcGlsZWQpKSArICh0b1N0ciB8fCAnJykgKyBcIilcIildO1xuICAgIH07XG5cbiAgICByZXR1cm4gU2xpY2U7XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5PYmogPSBPYmogPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKE9iaiwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIE9iaihwcm9wcywgZ2VuZXJhdGVkKSB7XG4gICAgICB0aGlzLmdlbmVyYXRlZCA9IGdlbmVyYXRlZCAhPSBudWxsID8gZ2VuZXJhdGVkIDogZmFsc2U7XG4gICAgICB0aGlzLm9iamVjdHMgPSB0aGlzLnByb3BlcnRpZXMgPSBwcm9wcyB8fCBbXTtcbiAgICB9XG5cbiAgICBPYmoucHJvdG90eXBlLmNoaWxkcmVuID0gWydwcm9wZXJ0aWVzJ107XG5cbiAgICBPYmoucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGFuc3dlciwgaSwgaWR0LCBpbmRlbnQsIGpvaW4sIGxhc3ROb25jb20sIG5vZGUsIHByb3AsIHByb3BzLCBfaSwgX2osIF9sZW4sIF9sZW4xO1xuICAgICAgcHJvcHMgPSB0aGlzLnByb3BlcnRpZXM7XG4gICAgICBpZiAoIXByb3BzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW3RoaXMubWFrZUNvZGUodGhpcy5mcm9udCA/ICcoe30pJyA6ICd7fScpXTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmdlbmVyYXRlZCkge1xuICAgICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IHByb3BzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgICAgbm9kZSA9IHByb3BzW19pXTtcbiAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFZhbHVlKSB7XG4gICAgICAgICAgICBub2RlLmVycm9yKCdjYW5ub3QgaGF2ZSBhbiBpbXBsaWNpdCB2YWx1ZSBpbiBhbiBpbXBsaWNpdCBvYmplY3QnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlkdCA9IG8uaW5kZW50ICs9IFRBQjtcbiAgICAgIGxhc3ROb25jb20gPSB0aGlzLmxhc3ROb25Db21tZW50KHRoaXMucHJvcGVydGllcyk7XG4gICAgICBhbnN3ZXIgPSBbXTtcbiAgICAgIGZvciAoaSA9IF9qID0gMCwgX2xlbjEgPSBwcm9wcy5sZW5ndGg7IF9qIDwgX2xlbjE7IGkgPSArK19qKSB7XG4gICAgICAgIHByb3AgPSBwcm9wc1tpXTtcbiAgICAgICAgam9pbiA9IGkgPT09IHByb3BzLmxlbmd0aCAtIDEgPyAnJyA6IHByb3AgPT09IGxhc3ROb25jb20gfHwgcHJvcCBpbnN0YW5jZW9mIENvbW1lbnQgPyAnXFxuJyA6ICcsXFxuJztcbiAgICAgICAgaW5kZW50ID0gcHJvcCBpbnN0YW5jZW9mIENvbW1lbnQgPyAnJyA6IGlkdDtcbiAgICAgICAgaWYgKHByb3AgaW5zdGFuY2VvZiBBc3NpZ24gJiYgcHJvcC52YXJpYWJsZSBpbnN0YW5jZW9mIFZhbHVlICYmIHByb3AudmFyaWFibGUuaGFzUHJvcGVydGllcygpKSB7XG4gICAgICAgICAgcHJvcC52YXJpYWJsZS5lcnJvcignSW52YWxpZCBvYmplY3Qga2V5Jyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3AgaW5zdGFuY2VvZiBWYWx1ZSAmJiBwcm9wW1widGhpc1wiXSkge1xuICAgICAgICAgIHByb3AgPSBuZXcgQXNzaWduKHByb3AucHJvcGVydGllc1swXS5uYW1lLCBwcm9wLCAnb2JqZWN0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEocHJvcCBpbnN0YW5jZW9mIENvbW1lbnQpKSB7XG4gICAgICAgICAgaWYgKCEocHJvcCBpbnN0YW5jZW9mIEFzc2lnbikpIHtcbiAgICAgICAgICAgIHByb3AgPSBuZXcgQXNzaWduKHByb3AsIHByb3AsICdvYmplY3QnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgKHByb3AudmFyaWFibGUuYmFzZSB8fCBwcm9wLnZhcmlhYmxlKS5hc0tleSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGluZGVudCkge1xuICAgICAgICAgIGFuc3dlci5wdXNoKHRoaXMubWFrZUNvZGUoaW5kZW50KSk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyLnB1c2guYXBwbHkoYW5zd2VyLCBwcm9wLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9UT1ApKTtcbiAgICAgICAgaWYgKGpvaW4pIHtcbiAgICAgICAgICBhbnN3ZXIucHVzaCh0aGlzLm1ha2VDb2RlKGpvaW4pKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYW5zd2VyLnVuc2hpZnQodGhpcy5tYWtlQ29kZShcIntcIiArIChwcm9wcy5sZW5ndGggJiYgJ1xcbicpKSk7XG4gICAgICBhbnN3ZXIucHVzaCh0aGlzLm1ha2VDb2RlKFwiXCIgKyAocHJvcHMubGVuZ3RoICYmICdcXG4nICsgdGhpcy50YWIpICsgXCJ9XCIpKTtcbiAgICAgIGlmICh0aGlzLmZyb250KSB7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXBJbkJyYWNlcyhhbnN3ZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgT2JqLnByb3RvdHlwZS5hc3NpZ25zID0gZnVuY3Rpb24obmFtZSkge1xuICAgICAgdmFyIHByb3AsIF9pLCBfbGVuLCBfcmVmMjtcbiAgICAgIF9yZWYyID0gdGhpcy5wcm9wZXJ0aWVzO1xuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBfcmVmMi5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgICBwcm9wID0gX3JlZjJbX2ldO1xuICAgICAgICBpZiAocHJvcC5hc3NpZ25zKG5hbWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIE9iajtcblxuICB9KShCYXNlKTtcblxuICBleHBvcnRzLkFyciA9IEFyciA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoQXJyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gQXJyKG9ianMpIHtcbiAgICAgIHRoaXMub2JqZWN0cyA9IG9ianMgfHwgW107XG4gICAgfVxuXG4gICAgQXJyLnByb3RvdHlwZS5jaGlsZHJlbiA9IFsnb2JqZWN0cyddO1xuXG4gICAgQXJyLnByb3RvdHlwZS5jb21waWxlTm9kZSA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBhbnN3ZXIsIGNvbXBpbGVkT2JqcywgZnJhZ21lbnRzLCBpbmRleCwgb2JqLCBfaSwgX2xlbjtcbiAgICAgIGlmICghdGhpcy5vYmplY3RzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW3RoaXMubWFrZUNvZGUoJ1tdJyldO1xuICAgICAgfVxuICAgICAgby5pbmRlbnQgKz0gVEFCO1xuICAgICAgYW5zd2VyID0gU3BsYXQuY29tcGlsZVNwbGF0dGVkQXJyYXkobywgdGhpcy5vYmplY3RzKTtcbiAgICAgIGlmIChhbnN3ZXIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgICB9XG4gICAgICBhbnN3ZXIgPSBbXTtcbiAgICAgIGNvbXBpbGVkT2JqcyA9IChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIF9pLCBfbGVuLCBfcmVmMiwgX3Jlc3VsdHM7XG4gICAgICAgIF9yZWYyID0gdGhpcy5vYmplY3RzO1xuICAgICAgICBfcmVzdWx0cyA9IFtdO1xuICAgICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYyLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgICAgb2JqID0gX3JlZjJbX2ldO1xuICAgICAgICAgIF9yZXN1bHRzLnB1c2gob2JqLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9MSVNUKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9yZXN1bHRzO1xuICAgICAgfSkuY2FsbCh0aGlzKTtcbiAgICAgIGZvciAoaW5kZXggPSBfaSA9IDAsIF9sZW4gPSBjb21waWxlZE9ianMubGVuZ3RoOyBfaSA8IF9sZW47IGluZGV4ID0gKytfaSkge1xuICAgICAgICBmcmFnbWVudHMgPSBjb21waWxlZE9ianNbaW5kZXhdO1xuICAgICAgICBpZiAoaW5kZXgpIHtcbiAgICAgICAgICBhbnN3ZXIucHVzaCh0aGlzLm1ha2VDb2RlKFwiLCBcIikpO1xuICAgICAgICB9XG4gICAgICAgIGFuc3dlci5wdXNoLmFwcGx5KGFuc3dlciwgZnJhZ21lbnRzKTtcbiAgICAgIH1cbiAgICAgIGlmIChmcmFnbWVudHNUb1RleHQoYW5zd2VyKS5pbmRleE9mKCdcXG4nKSA+PSAwKSB7XG4gICAgICAgIGFuc3dlci51bnNoaWZ0KHRoaXMubWFrZUNvZGUoXCJbXFxuXCIgKyBvLmluZGVudCkpO1xuICAgICAgICBhbnN3ZXIucHVzaCh0aGlzLm1ha2VDb2RlKFwiXFxuXCIgKyB0aGlzLnRhYiArIFwiXVwiKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhbnN3ZXIudW5zaGlmdCh0aGlzLm1ha2VDb2RlKFwiW1wiKSk7XG4gICAgICAgIGFuc3dlci5wdXNoKHRoaXMubWFrZUNvZGUoXCJdXCIpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgfTtcblxuICAgIEFyci5wcm90b3R5cGUuYXNzaWducyA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIHZhciBvYmosIF9pLCBfbGVuLCBfcmVmMjtcbiAgICAgIF9yZWYyID0gdGhpcy5vYmplY3RzO1xuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBfcmVmMi5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgICBvYmogPSBfcmVmMltfaV07XG4gICAgICAgIGlmIChvYmouYXNzaWducyhuYW1lKSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIHJldHVybiBBcnI7XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5DbGFzcyA9IENsYXNzID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhDbGFzcywgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIENsYXNzKHZhcmlhYmxlLCBwYXJlbnQsIGJvZHkpIHtcbiAgICAgIHRoaXMudmFyaWFibGUgPSB2YXJpYWJsZTtcbiAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50O1xuICAgICAgdGhpcy5ib2R5ID0gYm9keSAhPSBudWxsID8gYm9keSA6IG5ldyBCbG9jaztcbiAgICAgIHRoaXMuYm91bmRGdW5jcyA9IFtdO1xuICAgICAgdGhpcy5ib2R5LmNsYXNzQm9keSA9IHRydWU7XG4gICAgfVxuXG4gICAgQ2xhc3MucHJvdG90eXBlLmNoaWxkcmVuID0gWyd2YXJpYWJsZScsICdwYXJlbnQnLCAnYm9keSddO1xuXG4gICAgQ2xhc3MucHJvdG90eXBlLmRldGVybWluZU5hbWUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBkZWNsLCB0YWlsO1xuICAgICAgaWYgKCF0aGlzLnZhcmlhYmxlKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgZGVjbCA9ICh0YWlsID0gbGFzdCh0aGlzLnZhcmlhYmxlLnByb3BlcnRpZXMpKSA/IHRhaWwgaW5zdGFuY2VvZiBBY2Nlc3MgJiYgdGFpbC5uYW1lLnZhbHVlIDogdGhpcy52YXJpYWJsZS5iYXNlLnZhbHVlO1xuICAgICAgaWYgKF9faW5kZXhPZi5jYWxsKFNUUklDVF9QUk9TQ1JJQkVELCBkZWNsKSA+PSAwKSB7XG4gICAgICAgIHRoaXMudmFyaWFibGUuZXJyb3IoXCJjbGFzcyB2YXJpYWJsZSBuYW1lIG1heSBub3QgYmUgXCIgKyBkZWNsKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZWNsICYmIChkZWNsID0gSURFTlRJRklFUi50ZXN0KGRlY2wpICYmIGRlY2wpO1xuICAgIH07XG5cbiAgICBDbGFzcy5wcm90b3R5cGUuc2V0Q29udGV4dCA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmJvZHkudHJhdmVyc2VDaGlsZHJlbihmYWxzZSwgZnVuY3Rpb24obm9kZSkge1xuICAgICAgICBpZiAobm9kZS5jbGFzc0JvZHkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBMaXRlcmFsICYmIG5vZGUudmFsdWUgPT09ICd0aGlzJykge1xuICAgICAgICAgIHJldHVybiBub2RlLnZhbHVlID0gbmFtZTtcbiAgICAgICAgfSBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgQ29kZSkge1xuICAgICAgICAgIG5vZGUua2xhc3MgPSBuYW1lO1xuICAgICAgICAgIGlmIChub2RlLmJvdW5kKSB7XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5jb250ZXh0ID0gbmFtZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBDbGFzcy5wcm90b3R5cGUuYWRkQm91bmRGdW5jdGlvbnMgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgYnZhciwgbGhzLCBfaSwgX2xlbiwgX3JlZjI7XG4gICAgICBfcmVmMiA9IHRoaXMuYm91bmRGdW5jcztcbiAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gX3JlZjIubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgYnZhciA9IF9yZWYyW19pXTtcbiAgICAgICAgbGhzID0gKG5ldyBWYWx1ZShuZXcgTGl0ZXJhbChcInRoaXNcIiksIFtuZXcgQWNjZXNzKGJ2YXIpXSkpLmNvbXBpbGUobyk7XG4gICAgICAgIHRoaXMuY3Rvci5ib2R5LnVuc2hpZnQobmV3IExpdGVyYWwoXCJcIiArIGxocyArIFwiID0gXCIgKyAodXRpbGl0eSgnYmluZCcpKSArIFwiKFwiICsgbGhzICsgXCIsIHRoaXMpXCIpKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQ2xhc3MucHJvdG90eXBlLmFkZFByb3BlcnRpZXMgPSBmdW5jdGlvbihub2RlLCBuYW1lLCBvKSB7XG4gICAgICB2YXIgYXNzaWduLCBiYXNlLCBleHBycywgZnVuYywgcHJvcHM7XG4gICAgICBwcm9wcyA9IG5vZGUuYmFzZS5wcm9wZXJ0aWVzLnNsaWNlKDApO1xuICAgICAgZXhwcnMgPSAoZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBfcmVzdWx0cztcbiAgICAgICAgX3Jlc3VsdHMgPSBbXTtcbiAgICAgICAgd2hpbGUgKGFzc2lnbiA9IHByb3BzLnNoaWZ0KCkpIHtcbiAgICAgICAgICBpZiAoYXNzaWduIGluc3RhbmNlb2YgQXNzaWduKSB7XG4gICAgICAgICAgICBiYXNlID0gYXNzaWduLnZhcmlhYmxlLmJhc2U7XG4gICAgICAgICAgICBkZWxldGUgYXNzaWduLmNvbnRleHQ7XG4gICAgICAgICAgICBmdW5jID0gYXNzaWduLnZhbHVlO1xuICAgICAgICAgICAgaWYgKGJhc2UudmFsdWUgPT09ICdjb25zdHJ1Y3RvcicpIHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuY3Rvcikge1xuICAgICAgICAgICAgICAgIGFzc2lnbi5lcnJvcignY2Fubm90IGRlZmluZSBtb3JlIHRoYW4gb25lIGNvbnN0cnVjdG9yIGluIGEgY2xhc3MnKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoZnVuYy5ib3VuZCkge1xuICAgICAgICAgICAgICAgIGFzc2lnbi5lcnJvcignY2Fubm90IGRlZmluZSBhIGNvbnN0cnVjdG9yIGFzIGEgYm91bmQgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoZnVuYyBpbnN0YW5jZW9mIENvZGUpIHtcbiAgICAgICAgICAgICAgICBhc3NpZ24gPSB0aGlzLmN0b3IgPSBmdW5jO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZXh0ZXJuYWxDdG9yID0gby5jbGFzc1Njb3BlLmZyZWVWYXJpYWJsZSgnY2xhc3MnKTtcbiAgICAgICAgICAgICAgICBhc3NpZ24gPSBuZXcgQXNzaWduKG5ldyBMaXRlcmFsKHRoaXMuZXh0ZXJuYWxDdG9yKSwgZnVuYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChhc3NpZ24udmFyaWFibGVbXCJ0aGlzXCJdKSB7XG4gICAgICAgICAgICAgICAgZnVuY1tcInN0YXRpY1wiXSA9IHRydWU7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXNzaWduLnZhcmlhYmxlID0gbmV3IFZhbHVlKG5ldyBMaXRlcmFsKG5hbWUpLCBbbmV3IEFjY2VzcyhuZXcgTGl0ZXJhbCgncHJvdG90eXBlJykpLCBuZXcgQWNjZXNzKGJhc2UpXSk7XG4gICAgICAgICAgICAgICAgaWYgKGZ1bmMgaW5zdGFuY2VvZiBDb2RlICYmIGZ1bmMuYm91bmQpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuYm91bmRGdW5jcy5wdXNoKGJhc2UpO1xuICAgICAgICAgICAgICAgICAgZnVuYy5ib3VuZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBfcmVzdWx0cy5wdXNoKGFzc2lnbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9yZXN1bHRzO1xuICAgICAgfSkuY2FsbCh0aGlzKTtcbiAgICAgIHJldHVybiBjb21wYWN0KGV4cHJzKTtcbiAgICB9O1xuXG4gICAgQ2xhc3MucHJvdG90eXBlLndhbGtCb2R5ID0gZnVuY3Rpb24obmFtZSwgbykge1xuICAgICAgcmV0dXJuIHRoaXMudHJhdmVyc2VDaGlsZHJlbihmYWxzZSwgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihjaGlsZCkge1xuICAgICAgICAgIHZhciBjb250LCBleHBzLCBpLCBub2RlLCBfaSwgX2xlbiwgX3JlZjI7XG4gICAgICAgICAgY29udCA9IHRydWU7XG4gICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgQ2xhc3MpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgQmxvY2spIHtcbiAgICAgICAgICAgIF9yZWYyID0gZXhwcyA9IGNoaWxkLmV4cHJlc3Npb25zO1xuICAgICAgICAgICAgZm9yIChpID0gX2kgPSAwLCBfbGVuID0gX3JlZjIubGVuZ3RoOyBfaSA8IF9sZW47IGkgPSArK19pKSB7XG4gICAgICAgICAgICAgIG5vZGUgPSBfcmVmMltpXTtcbiAgICAgICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBBc3NpZ24gJiYgbm9kZS52YXJpYWJsZS5sb29rc1N0YXRpYyhuYW1lKSkge1xuICAgICAgICAgICAgICAgIG5vZGUudmFsdWVbXCJzdGF0aWNcIl0gPSB0cnVlO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiBWYWx1ZSAmJiBub2RlLmlzT2JqZWN0KHRydWUpKSB7XG4gICAgICAgICAgICAgICAgY29udCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGV4cHNbaV0gPSBfdGhpcy5hZGRQcm9wZXJ0aWVzKG5vZGUsIG5hbWUsIG8pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjaGlsZC5leHByZXNzaW9ucyA9IGV4cHMgPSBmbGF0dGVuKGV4cHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gY29udCAmJiAhKGNoaWxkIGluc3RhbmNlb2YgQ2xhc3MpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH07XG5cbiAgICBDbGFzcy5wcm90b3R5cGUuaG9pc3REaXJlY3RpdmVQcm9sb2d1ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGV4cHJlc3Npb25zLCBpbmRleCwgbm9kZTtcbiAgICAgIGluZGV4ID0gMDtcbiAgICAgIGV4cHJlc3Npb25zID0gdGhpcy5ib2R5LmV4cHJlc3Npb25zO1xuICAgICAgd2hpbGUgKChub2RlID0gZXhwcmVzc2lvbnNbaW5kZXhdKSAmJiBub2RlIGluc3RhbmNlb2YgQ29tbWVudCB8fCBub2RlIGluc3RhbmNlb2YgVmFsdWUgJiYgbm9kZS5pc1N0cmluZygpKSB7XG4gICAgICAgICsraW5kZXg7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5kaXJlY3RpdmVzID0gZXhwcmVzc2lvbnMuc3BsaWNlKDAsIGluZGV4KTtcbiAgICB9O1xuXG4gICAgQ2xhc3MucHJvdG90eXBlLmVuc3VyZUNvbnN0cnVjdG9yID0gZnVuY3Rpb24obmFtZSkge1xuICAgICAgaWYgKCF0aGlzLmN0b3IpIHtcbiAgICAgICAgdGhpcy5jdG9yID0gbmV3IENvZGU7XG4gICAgICAgIGlmICh0aGlzLmV4dGVybmFsQ3Rvcikge1xuICAgICAgICAgIHRoaXMuY3Rvci5ib2R5LnB1c2gobmV3IExpdGVyYWwoXCJcIiArIHRoaXMuZXh0ZXJuYWxDdG9yICsgXCIuYXBwbHkodGhpcywgYXJndW1lbnRzKVwiKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5wYXJlbnQpIHtcbiAgICAgICAgICB0aGlzLmN0b3IuYm9keS5wdXNoKG5ldyBMaXRlcmFsKFwiXCIgKyBuYW1lICsgXCIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcIikpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY3Rvci5ib2R5Lm1ha2VSZXR1cm4oKTtcbiAgICAgICAgdGhpcy5ib2R5LmV4cHJlc3Npb25zLnVuc2hpZnQodGhpcy5jdG9yKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY3Rvci5jdG9yID0gdGhpcy5jdG9yLm5hbWUgPSBuYW1lO1xuICAgICAgdGhpcy5jdG9yLmtsYXNzID0gbnVsbDtcbiAgICAgIHJldHVybiB0aGlzLmN0b3Iubm9SZXR1cm4gPSB0cnVlO1xuICAgIH07XG5cbiAgICBDbGFzcy5wcm90b3R5cGUuY29tcGlsZU5vZGUgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgYXJncywgYXJndW1lbnRzTm9kZSwgZnVuYywganVtcE5vZGUsIGtsYXNzLCBsbmFtZSwgbmFtZSwgc3VwZXJDbGFzcywgX3JlZjI7XG4gICAgICBpZiAoanVtcE5vZGUgPSB0aGlzLmJvZHkuanVtcHMoKSkge1xuICAgICAgICBqdW1wTm9kZS5lcnJvcignQ2xhc3MgYm9kaWVzIGNhbm5vdCBjb250YWluIHB1cmUgc3RhdGVtZW50cycpO1xuICAgICAgfVxuICAgICAgaWYgKGFyZ3VtZW50c05vZGUgPSB0aGlzLmJvZHkuY29udGFpbnMoaXNMaXRlcmFsQXJndW1lbnRzKSkge1xuICAgICAgICBhcmd1bWVudHNOb2RlLmVycm9yKFwiQ2xhc3MgYm9kaWVzIHNob3VsZG4ndCByZWZlcmVuY2UgYXJndW1lbnRzXCIpO1xuICAgICAgfVxuICAgICAgbmFtZSA9IHRoaXMuZGV0ZXJtaW5lTmFtZSgpIHx8ICdfQ2xhc3MnO1xuICAgICAgaWYgKG5hbWUucmVzZXJ2ZWQpIHtcbiAgICAgICAgbmFtZSA9IFwiX1wiICsgbmFtZTtcbiAgICAgIH1cbiAgICAgIGxuYW1lID0gbmV3IExpdGVyYWwobmFtZSk7XG4gICAgICBmdW5jID0gbmV3IENvZGUoW10sIEJsb2NrLndyYXAoW3RoaXMuYm9keV0pKTtcbiAgICAgIGFyZ3MgPSBbXTtcbiAgICAgIG8uY2xhc3NTY29wZSA9IGZ1bmMubWFrZVNjb3BlKG8uc2NvcGUpO1xuICAgICAgdGhpcy5ob2lzdERpcmVjdGl2ZVByb2xvZ3VlKCk7XG4gICAgICB0aGlzLnNldENvbnRleHQobmFtZSk7XG4gICAgICB0aGlzLndhbGtCb2R5KG5hbWUsIG8pO1xuICAgICAgdGhpcy5lbnN1cmVDb25zdHJ1Y3RvcihuYW1lKTtcbiAgICAgIHRoaXMuYWRkQm91bmRGdW5jdGlvbnMobyk7XG4gICAgICB0aGlzLmJvZHkuc3BhY2VkID0gdHJ1ZTtcbiAgICAgIHRoaXMuYm9keS5leHByZXNzaW9ucy5wdXNoKGxuYW1lKTtcbiAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICBzdXBlckNsYXNzID0gbmV3IExpdGVyYWwoby5jbGFzc1Njb3BlLmZyZWVWYXJpYWJsZSgnc3VwZXInLCBmYWxzZSkpO1xuICAgICAgICB0aGlzLmJvZHkuZXhwcmVzc2lvbnMudW5zaGlmdChuZXcgRXh0ZW5kcyhsbmFtZSwgc3VwZXJDbGFzcykpO1xuICAgICAgICBmdW5jLnBhcmFtcy5wdXNoKG5ldyBQYXJhbShzdXBlckNsYXNzKSk7XG4gICAgICAgIGFyZ3MucHVzaCh0aGlzLnBhcmVudCk7XG4gICAgICB9XG4gICAgICAoX3JlZjIgPSB0aGlzLmJvZHkuZXhwcmVzc2lvbnMpLnVuc2hpZnQuYXBwbHkoX3JlZjIsIHRoaXMuZGlyZWN0aXZlcyk7XG4gICAgICBrbGFzcyA9IG5ldyBQYXJlbnMobmV3IENhbGwoZnVuYywgYXJncykpO1xuICAgICAgaWYgKHRoaXMudmFyaWFibGUpIHtcbiAgICAgICAga2xhc3MgPSBuZXcgQXNzaWduKHRoaXMudmFyaWFibGUsIGtsYXNzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBrbGFzcy5jb21waWxlVG9GcmFnbWVudHMobyk7XG4gICAgfTtcblxuICAgIHJldHVybiBDbGFzcztcblxuICB9KShCYXNlKTtcblxuICBleHBvcnRzLkFzc2lnbiA9IEFzc2lnbiA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoQXNzaWduLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gQXNzaWduKHZhcmlhYmxlLCB2YWx1ZSwgY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgdmFyIGZvcmJpZGRlbiwgbmFtZSwgX3JlZjI7XG4gICAgICB0aGlzLnZhcmlhYmxlID0gdmFyaWFibGU7XG4gICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgdGhpcy5wYXJhbSA9IG9wdGlvbnMgJiYgb3B0aW9ucy5wYXJhbTtcbiAgICAgIHRoaXMuc3VicGF0dGVybiA9IG9wdGlvbnMgJiYgb3B0aW9ucy5zdWJwYXR0ZXJuO1xuICAgICAgZm9yYmlkZGVuID0gKF9yZWYyID0gKG5hbWUgPSB0aGlzLnZhcmlhYmxlLnVud3JhcEFsbCgpLnZhbHVlKSwgX19pbmRleE9mLmNhbGwoU1RSSUNUX1BST1NDUklCRUQsIF9yZWYyKSA+PSAwKTtcbiAgICAgIGlmIChmb3JiaWRkZW4gJiYgdGhpcy5jb250ZXh0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICB0aGlzLnZhcmlhYmxlLmVycm9yKFwidmFyaWFibGUgbmFtZSBtYXkgbm90IGJlIFxcXCJcIiArIG5hbWUgKyBcIlxcXCJcIik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgQXNzaWduLnByb3RvdHlwZS5jaGlsZHJlbiA9IFsndmFyaWFibGUnLCAndmFsdWUnXTtcblxuICAgIEFzc2lnbi5wcm90b3R5cGUuaXNTdGF0ZW1lbnQgPSBmdW5jdGlvbihvKSB7XG4gICAgICByZXR1cm4gKG8gIT0gbnVsbCA/IG8ubGV2ZWwgOiB2b2lkIDApID09PSBMRVZFTF9UT1AgJiYgKHRoaXMuY29udGV4dCAhPSBudWxsKSAmJiBfX2luZGV4T2YuY2FsbCh0aGlzLmNvbnRleHQsIFwiP1wiKSA+PSAwO1xuICAgIH07XG5cbiAgICBBc3NpZ24ucHJvdG90eXBlLmFzc2lnbnMgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICByZXR1cm4gdGhpc1t0aGlzLmNvbnRleHQgPT09ICdvYmplY3QnID8gJ3ZhbHVlJyA6ICd2YXJpYWJsZSddLmFzc2lnbnMobmFtZSk7XG4gICAgfTtcblxuICAgIEFzc2lnbi5wcm90b3R5cGUudW5mb2xkU29hayA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHJldHVybiB1bmZvbGRTb2FrKG8sIHRoaXMsICd2YXJpYWJsZScpO1xuICAgIH07XG5cbiAgICBBc3NpZ24ucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGFuc3dlciwgY29tcGlsZWROYW1lLCBpc1ZhbHVlLCBtYXRjaCwgbmFtZSwgdmFsLCB2YXJCYXNlLCBfcmVmMiwgX3JlZjMsIF9yZWY0LCBfcmVmNTtcbiAgICAgIGlmIChpc1ZhbHVlID0gdGhpcy52YXJpYWJsZSBpbnN0YW5jZW9mIFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLnZhcmlhYmxlLmlzQXJyYXkoKSB8fCB0aGlzLnZhcmlhYmxlLmlzT2JqZWN0KCkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jb21waWxlUGF0dGVybk1hdGNoKG8pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnZhcmlhYmxlLmlzU3BsaWNlKCkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jb21waWxlU3BsaWNlKG8pO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoX3JlZjIgPSB0aGlzLmNvbnRleHQpID09PSAnfHw9JyB8fCBfcmVmMiA9PT0gJyYmPScgfHwgX3JlZjIgPT09ICc/PScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jb21waWxlQ29uZGl0aW9uYWwobyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKChfcmVmMyA9IHRoaXMuY29udGV4dCkgPT09ICcqKj0nIHx8IF9yZWYzID09PSAnLy89JyB8fCBfcmVmMyA9PT0gJyUlPScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jb21waWxlU3BlY2lhbE1hdGgobyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbXBpbGVkTmFtZSA9IHRoaXMudmFyaWFibGUuY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX0xJU1QpO1xuICAgICAgbmFtZSA9IGZyYWdtZW50c1RvVGV4dChjb21waWxlZE5hbWUpO1xuICAgICAgaWYgKCF0aGlzLmNvbnRleHQpIHtcbiAgICAgICAgdmFyQmFzZSA9IHRoaXMudmFyaWFibGUudW53cmFwQWxsKCk7XG4gICAgICAgIGlmICghdmFyQmFzZS5pc0Fzc2lnbmFibGUoKSkge1xuICAgICAgICAgIHRoaXMudmFyaWFibGUuZXJyb3IoXCJcXFwiXCIgKyAodGhpcy52YXJpYWJsZS5jb21waWxlKG8pKSArIFwiXFxcIiBjYW5ub3QgYmUgYXNzaWduZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEodHlwZW9mIHZhckJhc2UuaGFzUHJvcGVydGllcyA9PT0gXCJmdW5jdGlvblwiID8gdmFyQmFzZS5oYXNQcm9wZXJ0aWVzKCkgOiB2b2lkIDApKSB7XG4gICAgICAgICAgaWYgKHRoaXMucGFyYW0pIHtcbiAgICAgICAgICAgIG8uc2NvcGUuYWRkKG5hbWUsICd2YXInKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgby5zY29wZS5maW5kKG5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRoaXMudmFsdWUgaW5zdGFuY2VvZiBDb2RlICYmIChtYXRjaCA9IE1FVEhPRF9ERUYuZXhlYyhuYW1lKSkpIHtcbiAgICAgICAgaWYgKG1hdGNoWzJdKSB7XG4gICAgICAgICAgdGhpcy52YWx1ZS5rbGFzcyA9IG1hdGNoWzFdO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmFsdWUubmFtZSA9IChfcmVmNCA9IChfcmVmNSA9IG1hdGNoWzNdKSAhPSBudWxsID8gX3JlZjUgOiBtYXRjaFs0XSkgIT0gbnVsbCA/IF9yZWY0IDogbWF0Y2hbNV07XG4gICAgICB9XG4gICAgICB2YWwgPSB0aGlzLnZhbHVlLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9MSVNUKTtcbiAgICAgIGlmICh0aGlzLmNvbnRleHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBjb21waWxlZE5hbWUuY29uY2F0KHRoaXMubWFrZUNvZGUoXCI6IFwiKSwgdmFsKTtcbiAgICAgIH1cbiAgICAgIGFuc3dlciA9IGNvbXBpbGVkTmFtZS5jb25jYXQodGhpcy5tYWtlQ29kZShcIiBcIiArICh0aGlzLmNvbnRleHQgfHwgJz0nKSArIFwiIFwiKSwgdmFsKTtcbiAgICAgIGlmIChvLmxldmVsIDw9IExFVkVMX0xJU1QpIHtcbiAgICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXBJbkJyYWNlcyhhbnN3ZXIpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NpZ24ucHJvdG90eXBlLmNvbXBpbGVQYXR0ZXJuTWF0Y2ggPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgYWNjLCBhc3NpZ25zLCBjb2RlLCBleHBhbmRlZElkeCwgZnJhZ21lbnRzLCBpLCBpZHgsIGlzT2JqZWN0LCBpdmFyLCBuYW1lLCBvYmosIG9iamVjdHMsIG9sZW4sIHJlZiwgcmVzdCwgdG9wLCB2YWwsIHZhbHVlLCB2dmFyLCB2dmFyVGV4dCwgX2ksIF9sZW4sIF9yZWYyLCBfcmVmMywgX3JlZjQsIF9yZWY1LCBfcmVmNiwgX3JlZjc7XG4gICAgICB0b3AgPSBvLmxldmVsID09PSBMRVZFTF9UT1A7XG4gICAgICB2YWx1ZSA9IHRoaXMudmFsdWU7XG4gICAgICBvYmplY3RzID0gdGhpcy52YXJpYWJsZS5iYXNlLm9iamVjdHM7XG4gICAgICBpZiAoIShvbGVuID0gb2JqZWN0cy5sZW5ndGgpKSB7XG4gICAgICAgIGNvZGUgPSB2YWx1ZS5jb21waWxlVG9GcmFnbWVudHMobyk7XG4gICAgICAgIGlmIChvLmxldmVsID49IExFVkVMX09QKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMud3JhcEluQnJhY2VzKGNvZGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBjb2RlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpc09iamVjdCA9IHRoaXMudmFyaWFibGUuaXNPYmplY3QoKTtcbiAgICAgIGlmICh0b3AgJiYgb2xlbiA9PT0gMSAmJiAhKChvYmogPSBvYmplY3RzWzBdKSBpbnN0YW5jZW9mIFNwbGF0KSkge1xuICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgQXNzaWduKSB7XG4gICAgICAgICAgX3JlZjIgPSBvYmosIChfcmVmMyA9IF9yZWYyLnZhcmlhYmxlLCBpZHggPSBfcmVmMy5iYXNlKSwgb2JqID0gX3JlZjIudmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWR4ID0gaXNPYmplY3QgPyBvYmpbXCJ0aGlzXCJdID8gb2JqLnByb3BlcnRpZXNbMF0ubmFtZSA6IG9iaiA6IG5ldyBMaXRlcmFsKDApO1xuICAgICAgICB9XG4gICAgICAgIGFjYyA9IElERU5USUZJRVIudGVzdChpZHgudW53cmFwKCkudmFsdWUgfHwgMCk7XG4gICAgICAgIHZhbHVlID0gbmV3IFZhbHVlKHZhbHVlKTtcbiAgICAgICAgdmFsdWUucHJvcGVydGllcy5wdXNoKG5ldyAoYWNjID8gQWNjZXNzIDogSW5kZXgpKGlkeCkpO1xuICAgICAgICBpZiAoX3JlZjQgPSBvYmoudW53cmFwKCkudmFsdWUsIF9faW5kZXhPZi5jYWxsKFJFU0VSVkVELCBfcmVmNCkgPj0gMCkge1xuICAgICAgICAgIG9iai5lcnJvcihcImFzc2lnbm1lbnQgdG8gYSByZXNlcnZlZCB3b3JkOiBcIiArIChvYmouY29tcGlsZShvKSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQXNzaWduKG9iaiwgdmFsdWUsIG51bGwsIHtcbiAgICAgICAgICBwYXJhbTogdGhpcy5wYXJhbVxuICAgICAgICB9KS5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfVE9QKTtcbiAgICAgIH1cbiAgICAgIHZ2YXIgPSB2YWx1ZS5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfTElTVCk7XG4gICAgICB2dmFyVGV4dCA9IGZyYWdtZW50c1RvVGV4dCh2dmFyKTtcbiAgICAgIGFzc2lnbnMgPSBbXTtcbiAgICAgIGV4cGFuZGVkSWR4ID0gZmFsc2U7XG4gICAgICBpZiAoIUlERU5USUZJRVIudGVzdCh2dmFyVGV4dCkgfHwgdGhpcy52YXJpYWJsZS5hc3NpZ25zKHZ2YXJUZXh0KSkge1xuICAgICAgICBhc3NpZ25zLnB1c2goW3RoaXMubWFrZUNvZGUoXCJcIiArIChyZWYgPSBvLnNjb3BlLmZyZWVWYXJpYWJsZSgncmVmJykpICsgXCIgPSBcIildLmNvbmNhdChfX3NsaWNlLmNhbGwodnZhcikpKTtcbiAgICAgICAgdnZhciA9IFt0aGlzLm1ha2VDb2RlKHJlZildO1xuICAgICAgICB2dmFyVGV4dCA9IHJlZjtcbiAgICAgIH1cbiAgICAgIGZvciAoaSA9IF9pID0gMCwgX2xlbiA9IG9iamVjdHMubGVuZ3RoOyBfaSA8IF9sZW47IGkgPSArK19pKSB7XG4gICAgICAgIG9iaiA9IG9iamVjdHNbaV07XG4gICAgICAgIGlkeCA9IGk7XG4gICAgICAgIGlmIChpc09iamVjdCkge1xuICAgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBBc3NpZ24pIHtcbiAgICAgICAgICAgIF9yZWY1ID0gb2JqLCAoX3JlZjYgPSBfcmVmNS52YXJpYWJsZSwgaWR4ID0gX3JlZjYuYmFzZSksIG9iaiA9IF9yZWY1LnZhbHVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAob2JqLmJhc2UgaW5zdGFuY2VvZiBQYXJlbnMpIHtcbiAgICAgICAgICAgICAgX3JlZjcgPSBuZXcgVmFsdWUob2JqLnVud3JhcEFsbCgpKS5jYWNoZVJlZmVyZW5jZShvKSwgb2JqID0gX3JlZjdbMF0sIGlkeCA9IF9yZWY3WzFdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWR4ID0gb2JqW1widGhpc1wiXSA/IG9iai5wcm9wZXJ0aWVzWzBdLm5hbWUgOiBvYmo7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghZXhwYW5kZWRJZHggJiYgb2JqIGluc3RhbmNlb2YgU3BsYXQpIHtcbiAgICAgICAgICBuYW1lID0gb2JqLm5hbWUudW53cmFwKCkudmFsdWU7XG4gICAgICAgICAgb2JqID0gb2JqLnVud3JhcCgpO1xuICAgICAgICAgIHZhbCA9IFwiXCIgKyBvbGVuICsgXCIgPD0gXCIgKyB2dmFyVGV4dCArIFwiLmxlbmd0aCA/IFwiICsgKHV0aWxpdHkoJ3NsaWNlJykpICsgXCIuY2FsbChcIiArIHZ2YXJUZXh0ICsgXCIsIFwiICsgaTtcbiAgICAgICAgICBpZiAocmVzdCA9IG9sZW4gLSBpIC0gMSkge1xuICAgICAgICAgICAgaXZhciA9IG8uc2NvcGUuZnJlZVZhcmlhYmxlKCdpJyk7XG4gICAgICAgICAgICB2YWwgKz0gXCIsIFwiICsgaXZhciArIFwiID0gXCIgKyB2dmFyVGV4dCArIFwiLmxlbmd0aCAtIFwiICsgcmVzdCArIFwiKSA6IChcIiArIGl2YXIgKyBcIiA9IFwiICsgaSArIFwiLCBbXSlcIjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsICs9IFwiKSA6IFtdXCI7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhbCA9IG5ldyBMaXRlcmFsKHZhbCk7XG4gICAgICAgICAgZXhwYW5kZWRJZHggPSBcIlwiICsgaXZhciArIFwiKytcIjtcbiAgICAgICAgfSBlbHNlIGlmICghZXhwYW5kZWRJZHggJiYgb2JqIGluc3RhbmNlb2YgRXhwYW5zaW9uKSB7XG4gICAgICAgICAgaWYgKHJlc3QgPSBvbGVuIC0gaSAtIDEpIHtcbiAgICAgICAgICAgIGlmIChyZXN0ID09PSAxKSB7XG4gICAgICAgICAgICAgIGV4cGFuZGVkSWR4ID0gXCJcIiArIHZ2YXJUZXh0ICsgXCIubGVuZ3RoIC0gMVwiO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaXZhciA9IG8uc2NvcGUuZnJlZVZhcmlhYmxlKCdpJyk7XG4gICAgICAgICAgICAgIHZhbCA9IG5ldyBMaXRlcmFsKFwiXCIgKyBpdmFyICsgXCIgPSBcIiArIHZ2YXJUZXh0ICsgXCIubGVuZ3RoIC0gXCIgKyByZXN0KTtcbiAgICAgICAgICAgICAgZXhwYW5kZWRJZHggPSBcIlwiICsgaXZhciArIFwiKytcIjtcbiAgICAgICAgICAgICAgYXNzaWducy5wdXNoKHZhbC5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfTElTVCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gb2JqLnVud3JhcCgpLnZhbHVlO1xuICAgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBTcGxhdCB8fCBvYmogaW5zdGFuY2VvZiBFeHBhbnNpb24pIHtcbiAgICAgICAgICAgIG9iai5lcnJvcihcIm11bHRpcGxlIHNwbGF0cy9leHBhbnNpb25zIGFyZSBkaXNhbGxvd2VkIGluIGFuIGFzc2lnbm1lbnRcIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eXBlb2YgaWR4ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgaWR4ID0gbmV3IExpdGVyYWwoZXhwYW5kZWRJZHggfHwgaWR4KTtcbiAgICAgICAgICAgIGFjYyA9IGZhbHNlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhY2MgPSBpc09iamVjdCAmJiBJREVOVElGSUVSLnRlc3QoaWR4LnVud3JhcCgpLnZhbHVlIHx8IDApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YWwgPSBuZXcgVmFsdWUobmV3IExpdGVyYWwodnZhclRleHQpLCBbbmV3IChhY2MgPyBBY2Nlc3MgOiBJbmRleCkoaWR4KV0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICgobmFtZSAhPSBudWxsKSAmJiBfX2luZGV4T2YuY2FsbChSRVNFUlZFRCwgbmFtZSkgPj0gMCkge1xuICAgICAgICAgIG9iai5lcnJvcihcImFzc2lnbm1lbnQgdG8gYSByZXNlcnZlZCB3b3JkOiBcIiArIChvYmouY29tcGlsZShvKSkpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbnMucHVzaChuZXcgQXNzaWduKG9iaiwgdmFsLCBudWxsLCB7XG4gICAgICAgICAgcGFyYW06IHRoaXMucGFyYW0sXG4gICAgICAgICAgc3VicGF0dGVybjogdHJ1ZVxuICAgICAgICB9KS5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfTElTVCkpO1xuICAgICAgfVxuICAgICAgaWYgKCEodG9wIHx8IHRoaXMuc3VicGF0dGVybikpIHtcbiAgICAgICAgYXNzaWducy5wdXNoKHZ2YXIpO1xuICAgICAgfVxuICAgICAgZnJhZ21lbnRzID0gdGhpcy5qb2luRnJhZ21lbnRBcnJheXMoYXNzaWducywgJywgJyk7XG4gICAgICBpZiAoby5sZXZlbCA8IExFVkVMX0xJU1QpIHtcbiAgICAgICAgcmV0dXJuIGZyYWdtZW50cztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXBJbkJyYWNlcyhmcmFnbWVudHMpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NpZ24ucHJvdG90eXBlLmNvbXBpbGVDb25kaXRpb25hbCA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBmcmFnbWVudHMsIGxlZnQsIHJpZ2h0LCBfcmVmMjtcbiAgICAgIF9yZWYyID0gdGhpcy52YXJpYWJsZS5jYWNoZVJlZmVyZW5jZShvKSwgbGVmdCA9IF9yZWYyWzBdLCByaWdodCA9IF9yZWYyWzFdO1xuICAgICAgaWYgKCFsZWZ0LnByb3BlcnRpZXMubGVuZ3RoICYmIGxlZnQuYmFzZSBpbnN0YW5jZW9mIExpdGVyYWwgJiYgbGVmdC5iYXNlLnZhbHVlICE9PSBcInRoaXNcIiAmJiAhby5zY29wZS5jaGVjayhsZWZ0LmJhc2UudmFsdWUpKSB7XG4gICAgICAgIHRoaXMudmFyaWFibGUuZXJyb3IoXCJ0aGUgdmFyaWFibGUgXFxcIlwiICsgbGVmdC5iYXNlLnZhbHVlICsgXCJcXFwiIGNhbid0IGJlIGFzc2lnbmVkIHdpdGggXCIgKyB0aGlzLmNvbnRleHQgKyBcIiBiZWNhdXNlIGl0IGhhcyBub3QgYmVlbiBkZWNsYXJlZCBiZWZvcmVcIik7XG4gICAgICB9XG4gICAgICBpZiAoX19pbmRleE9mLmNhbGwodGhpcy5jb250ZXh0LCBcIj9cIikgPj0gMCkge1xuICAgICAgICBvLmlzRXhpc3RlbnRpYWxFcXVhbHMgPSB0cnVlO1xuICAgICAgICByZXR1cm4gbmV3IElmKG5ldyBFeGlzdGVuY2UobGVmdCksIHJpZ2h0LCB7XG4gICAgICAgICAgdHlwZTogJ2lmJ1xuICAgICAgICB9KS5hZGRFbHNlKG5ldyBBc3NpZ24ocmlnaHQsIHRoaXMudmFsdWUsICc9JykpLmNvbXBpbGVUb0ZyYWdtZW50cyhvKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZyYWdtZW50cyA9IG5ldyBPcCh0aGlzLmNvbnRleHQuc2xpY2UoMCwgLTEpLCBsZWZ0LCBuZXcgQXNzaWduKHJpZ2h0LCB0aGlzLnZhbHVlLCAnPScpKS5jb21waWxlVG9GcmFnbWVudHMobyk7XG4gICAgICAgIGlmIChvLmxldmVsIDw9IExFVkVMX0xJU1QpIHtcbiAgICAgICAgICByZXR1cm4gZnJhZ21lbnRzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLndyYXBJbkJyYWNlcyhmcmFnbWVudHMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIEFzc2lnbi5wcm90b3R5cGUuY29tcGlsZVNwZWNpYWxNYXRoID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGxlZnQsIHJpZ2h0LCBfcmVmMjtcbiAgICAgIF9yZWYyID0gdGhpcy52YXJpYWJsZS5jYWNoZVJlZmVyZW5jZShvKSwgbGVmdCA9IF9yZWYyWzBdLCByaWdodCA9IF9yZWYyWzFdO1xuICAgICAgcmV0dXJuIG5ldyBBc3NpZ24obGVmdCwgbmV3IE9wKHRoaXMuY29udGV4dC5zbGljZSgwLCAtMSksIHJpZ2h0LCB0aGlzLnZhbHVlKSkuY29tcGlsZVRvRnJhZ21lbnRzKG8pO1xuICAgIH07XG5cbiAgICBBc3NpZ24ucHJvdG90eXBlLmNvbXBpbGVTcGxpY2UgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgYW5zd2VyLCBleGNsdXNpdmUsIGZyb20sIGZyb21EZWNsLCBmcm9tUmVmLCBuYW1lLCB0bywgdmFsRGVmLCB2YWxSZWYsIF9yZWYyLCBfcmVmMywgX3JlZjQ7XG4gICAgICBfcmVmMiA9IHRoaXMudmFyaWFibGUucHJvcGVydGllcy5wb3AoKS5yYW5nZSwgZnJvbSA9IF9yZWYyLmZyb20sIHRvID0gX3JlZjIudG8sIGV4Y2x1c2l2ZSA9IF9yZWYyLmV4Y2x1c2l2ZTtcbiAgICAgIG5hbWUgPSB0aGlzLnZhcmlhYmxlLmNvbXBpbGUobyk7XG4gICAgICBpZiAoZnJvbSkge1xuICAgICAgICBfcmVmMyA9IHRoaXMuY2FjaGVUb0NvZGVGcmFnbWVudHMoZnJvbS5jYWNoZShvLCBMRVZFTF9PUCkpLCBmcm9tRGVjbCA9IF9yZWYzWzBdLCBmcm9tUmVmID0gX3JlZjNbMV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmcm9tRGVjbCA9IGZyb21SZWYgPSAnMCc7XG4gICAgICB9XG4gICAgICBpZiAodG8pIHtcbiAgICAgICAgaWYgKGZyb20gaW5zdGFuY2VvZiBWYWx1ZSAmJiBmcm9tLmlzU2ltcGxlTnVtYmVyKCkgJiYgdG8gaW5zdGFuY2VvZiBWYWx1ZSAmJiB0by5pc1NpbXBsZU51bWJlcigpKSB7XG4gICAgICAgICAgdG8gPSB0by5jb21waWxlKG8pIC0gZnJvbVJlZjtcbiAgICAgICAgICBpZiAoIWV4Y2x1c2l2ZSkge1xuICAgICAgICAgICAgdG8gKz0gMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG8gPSB0by5jb21waWxlKG8sIExFVkVMX0FDQ0VTUykgKyAnIC0gJyArIGZyb21SZWY7XG4gICAgICAgICAgaWYgKCFleGNsdXNpdmUpIHtcbiAgICAgICAgICAgIHRvICs9ICcgKyAxJztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRvID0gXCI5ZTlcIjtcbiAgICAgIH1cbiAgICAgIF9yZWY0ID0gdGhpcy52YWx1ZS5jYWNoZShvLCBMRVZFTF9MSVNUKSwgdmFsRGVmID0gX3JlZjRbMF0sIHZhbFJlZiA9IF9yZWY0WzFdO1xuICAgICAgYW5zd2VyID0gW10uY29uY2F0KHRoaXMubWFrZUNvZGUoXCJbXS5zcGxpY2UuYXBwbHkoXCIgKyBuYW1lICsgXCIsIFtcIiArIGZyb21EZWNsICsgXCIsIFwiICsgdG8gKyBcIl0uY29uY2F0KFwiKSwgdmFsRGVmLCB0aGlzLm1ha2VDb2RlKFwiKSksIFwiKSwgdmFsUmVmKTtcbiAgICAgIGlmIChvLmxldmVsID4gTEVWRUxfVE9QKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXBJbkJyYWNlcyhhbnN3ZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIEFzc2lnbjtcblxuICB9KShCYXNlKTtcblxuICBleHBvcnRzLkNvZGUgPSBDb2RlID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhDb2RlLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gQ29kZShwYXJhbXMsIGJvZHksIHRhZykge1xuICAgICAgdGhpcy5wYXJhbXMgPSBwYXJhbXMgfHwgW107XG4gICAgICB0aGlzLmJvZHkgPSBib2R5IHx8IG5ldyBCbG9jaztcbiAgICAgIHRoaXMuYm91bmQgPSB0YWcgPT09ICdib3VuZGZ1bmMnO1xuICAgIH1cblxuICAgIENvZGUucHJvdG90eXBlLmNoaWxkcmVuID0gWydwYXJhbXMnLCAnYm9keSddO1xuXG4gICAgQ29kZS5wcm90b3R5cGUuaXNTdGF0ZW1lbnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAhIXRoaXMuY3RvcjtcbiAgICB9O1xuXG4gICAgQ29kZS5wcm90b3R5cGUuanVtcHMgPSBOTztcblxuICAgIENvZGUucHJvdG90eXBlLm1ha2VTY29wZSA9IGZ1bmN0aW9uKHBhcmVudFNjb3BlKSB7XG4gICAgICByZXR1cm4gbmV3IFNjb3BlKHBhcmVudFNjb3BlLCB0aGlzLmJvZHksIHRoaXMpO1xuICAgIH07XG5cbiAgICBDb2RlLnByb3RvdHlwZS5jb21waWxlTm9kZSA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBhbnN3ZXIsIGJvdW5kZnVuYywgY29kZSwgZXhwcnMsIGksIGxpdCwgcCwgcGFyYW0sIHBhcmFtcywgcmVmLCBzcGxhdHMsIHVuaXFzLCB2YWwsIHdhc0VtcHR5LCB3cmFwcGVyLCBfaSwgX2osIF9rLCBfbCwgX2xlbiwgX2xlbjEsIF9sZW4yLCBfbGVuMywgX2xlbjQsIF9sZW41LCBfbSwgX24sIF9yZWYyLCBfcmVmMywgX3JlZjQsIF9yZWY1LCBfcmVmNiwgX3JlZjc7XG4gICAgICBpZiAodGhpcy5ib3VuZCAmJiAoKF9yZWYyID0gby5zY29wZS5tZXRob2QpICE9IG51bGwgPyBfcmVmMi5ib3VuZCA6IHZvaWQgMCkpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0ID0gby5zY29wZS5tZXRob2QuY29udGV4dDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmJvdW5kICYmICF0aGlzLmNvbnRleHQpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0ID0gJ190aGlzJztcbiAgICAgICAgd3JhcHBlciA9IG5ldyBDb2RlKFtuZXcgUGFyYW0obmV3IExpdGVyYWwodGhpcy5jb250ZXh0KSldLCBuZXcgQmxvY2soW3RoaXNdKSk7XG4gICAgICAgIGJvdW5kZnVuYyA9IG5ldyBDYWxsKHdyYXBwZXIsIFtuZXcgTGl0ZXJhbCgndGhpcycpXSk7XG4gICAgICAgIGJvdW5kZnVuYy51cGRhdGVMb2NhdGlvbkRhdGFJZk1pc3NpbmcodGhpcy5sb2NhdGlvbkRhdGEpO1xuICAgICAgICByZXR1cm4gYm91bmRmdW5jLmNvbXBpbGVOb2RlKG8pO1xuICAgICAgfVxuICAgICAgby5zY29wZSA9IGRlbChvLCAnY2xhc3NTY29wZScpIHx8IHRoaXMubWFrZVNjb3BlKG8uc2NvcGUpO1xuICAgICAgby5zY29wZS5zaGFyZWQgPSBkZWwobywgJ3NoYXJlZFNjb3BlJyk7XG4gICAgICBvLmluZGVudCArPSBUQUI7XG4gICAgICBkZWxldGUgby5iYXJlO1xuICAgICAgZGVsZXRlIG8uaXNFeGlzdGVudGlhbEVxdWFscztcbiAgICAgIHBhcmFtcyA9IFtdO1xuICAgICAgZXhwcnMgPSBbXTtcbiAgICAgIF9yZWYzID0gdGhpcy5wYXJhbXM7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIHBhcmFtID0gX3JlZjNbX2ldO1xuICAgICAgICBpZiAoIShwYXJhbSBpbnN0YW5jZW9mIEV4cGFuc2lvbikpIHtcbiAgICAgICAgICBvLnNjb3BlLnBhcmFtZXRlcihwYXJhbS5hc1JlZmVyZW5jZShvKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIF9yZWY0ID0gdGhpcy5wYXJhbXM7XG4gICAgICBmb3IgKF9qID0gMCwgX2xlbjEgPSBfcmVmNC5sZW5ndGg7IF9qIDwgX2xlbjE7IF9qKyspIHtcbiAgICAgICAgcGFyYW0gPSBfcmVmNFtfal07XG4gICAgICAgIGlmICghKHBhcmFtLnNwbGF0IHx8IHBhcmFtIGluc3RhbmNlb2YgRXhwYW5zaW9uKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIF9yZWY1ID0gdGhpcy5wYXJhbXM7XG4gICAgICAgIGZvciAoX2sgPSAwLCBfbGVuMiA9IF9yZWY1Lmxlbmd0aDsgX2sgPCBfbGVuMjsgX2srKykge1xuICAgICAgICAgIHAgPSBfcmVmNVtfa10ubmFtZTtcbiAgICAgICAgICBpZiAoISghKHBhcmFtIGluc3RhbmNlb2YgRXhwYW5zaW9uKSkpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocFtcInRoaXNcIl0pIHtcbiAgICAgICAgICAgIHAgPSBwLnByb3BlcnRpZXNbMF0ubmFtZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHAudmFsdWUpIHtcbiAgICAgICAgICAgIG8uc2NvcGUuYWRkKHAudmFsdWUsICd2YXInLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3BsYXRzID0gbmV3IEFzc2lnbihuZXcgVmFsdWUobmV3IEFycigoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdmFyIF9sLCBfbGVuMywgX3JlZjYsIF9yZXN1bHRzO1xuICAgICAgICAgIF9yZWY2ID0gdGhpcy5wYXJhbXM7XG4gICAgICAgICAgX3Jlc3VsdHMgPSBbXTtcbiAgICAgICAgICBmb3IgKF9sID0gMCwgX2xlbjMgPSBfcmVmNi5sZW5ndGg7IF9sIDwgX2xlbjM7IF9sKyspIHtcbiAgICAgICAgICAgIHAgPSBfcmVmNltfbF07XG4gICAgICAgICAgICBfcmVzdWx0cy5wdXNoKHAuYXNSZWZlcmVuY2UobykpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gX3Jlc3VsdHM7XG4gICAgICAgIH0pLmNhbGwodGhpcykpKSwgbmV3IFZhbHVlKG5ldyBMaXRlcmFsKCdhcmd1bWVudHMnKSkpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIF9yZWY2ID0gdGhpcy5wYXJhbXM7XG4gICAgICBmb3IgKF9sID0gMCwgX2xlbjMgPSBfcmVmNi5sZW5ndGg7IF9sIDwgX2xlbjM7IF9sKyspIHtcbiAgICAgICAgcGFyYW0gPSBfcmVmNltfbF07XG4gICAgICAgIGlmIChwYXJhbS5pc0NvbXBsZXgoKSkge1xuICAgICAgICAgIHZhbCA9IHJlZiA9IHBhcmFtLmFzUmVmZXJlbmNlKG8pO1xuICAgICAgICAgIGlmIChwYXJhbS52YWx1ZSkge1xuICAgICAgICAgICAgdmFsID0gbmV3IE9wKCc/JywgcmVmLCBwYXJhbS52YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGV4cHJzLnB1c2gobmV3IEFzc2lnbihuZXcgVmFsdWUocGFyYW0ubmFtZSksIHZhbCwgJz0nLCB7XG4gICAgICAgICAgICBwYXJhbTogdHJ1ZVxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZWYgPSBwYXJhbTtcbiAgICAgICAgICBpZiAocGFyYW0udmFsdWUpIHtcbiAgICAgICAgICAgIGxpdCA9IG5ldyBMaXRlcmFsKHJlZi5uYW1lLnZhbHVlICsgJyA9PSBudWxsJyk7XG4gICAgICAgICAgICB2YWwgPSBuZXcgQXNzaWduKG5ldyBWYWx1ZShwYXJhbS5uYW1lKSwgcGFyYW0udmFsdWUsICc9Jyk7XG4gICAgICAgICAgICBleHBycy5wdXNoKG5ldyBJZihsaXQsIHZhbCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIXNwbGF0cykge1xuICAgICAgICAgIHBhcmFtcy5wdXNoKHJlZik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHdhc0VtcHR5ID0gdGhpcy5ib2R5LmlzRW1wdHkoKTtcbiAgICAgIGlmIChzcGxhdHMpIHtcbiAgICAgICAgZXhwcnMudW5zaGlmdChzcGxhdHMpO1xuICAgICAgfVxuICAgICAgaWYgKGV4cHJzLmxlbmd0aCkge1xuICAgICAgICAoX3JlZjcgPSB0aGlzLmJvZHkuZXhwcmVzc2lvbnMpLnVuc2hpZnQuYXBwbHkoX3JlZjcsIGV4cHJzKTtcbiAgICAgIH1cbiAgICAgIGZvciAoaSA9IF9tID0gMCwgX2xlbjQgPSBwYXJhbXMubGVuZ3RoOyBfbSA8IF9sZW40OyBpID0gKytfbSkge1xuICAgICAgICBwID0gcGFyYW1zW2ldO1xuICAgICAgICBwYXJhbXNbaV0gPSBwLmNvbXBpbGVUb0ZyYWdtZW50cyhvKTtcbiAgICAgICAgby5zY29wZS5wYXJhbWV0ZXIoZnJhZ21lbnRzVG9UZXh0KHBhcmFtc1tpXSkpO1xuICAgICAgfVxuICAgICAgdW5pcXMgPSBbXTtcbiAgICAgIHRoaXMuZWFjaFBhcmFtTmFtZShmdW5jdGlvbihuYW1lLCBub2RlKSB7XG4gICAgICAgIGlmIChfX2luZGV4T2YuY2FsbCh1bmlxcywgbmFtZSkgPj0gMCkge1xuICAgICAgICAgIG5vZGUuZXJyb3IoXCJtdWx0aXBsZSBwYXJhbWV0ZXJzIG5hbWVkICdcIiArIG5hbWUgKyBcIidcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuaXFzLnB1c2gobmFtZSk7XG4gICAgICB9KTtcbiAgICAgIGlmICghKHdhc0VtcHR5IHx8IHRoaXMubm9SZXR1cm4pKSB7XG4gICAgICAgIHRoaXMuYm9keS5tYWtlUmV0dXJuKCk7XG4gICAgICB9XG4gICAgICBjb2RlID0gJ2Z1bmN0aW9uJztcbiAgICAgIGlmICh0aGlzLmN0b3IpIHtcbiAgICAgICAgY29kZSArPSAnICcgKyB0aGlzLm5hbWU7XG4gICAgICB9XG4gICAgICBjb2RlICs9ICcoJztcbiAgICAgIGFuc3dlciA9IFt0aGlzLm1ha2VDb2RlKGNvZGUpXTtcbiAgICAgIGZvciAoaSA9IF9uID0gMCwgX2xlbjUgPSBwYXJhbXMubGVuZ3RoOyBfbiA8IF9sZW41OyBpID0gKytfbikge1xuICAgICAgICBwID0gcGFyYW1zW2ldO1xuICAgICAgICBpZiAoaSkge1xuICAgICAgICAgIGFuc3dlci5wdXNoKHRoaXMubWFrZUNvZGUoXCIsIFwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyLnB1c2guYXBwbHkoYW5zd2VyLCBwKTtcbiAgICAgIH1cbiAgICAgIGFuc3dlci5wdXNoKHRoaXMubWFrZUNvZGUoJykgeycpKTtcbiAgICAgIGlmICghdGhpcy5ib2R5LmlzRW1wdHkoKSkge1xuICAgICAgICBhbnN3ZXIgPSBhbnN3ZXIuY29uY2F0KHRoaXMubWFrZUNvZGUoXCJcXG5cIiksIHRoaXMuYm9keS5jb21waWxlV2l0aERlY2xhcmF0aW9ucyhvKSwgdGhpcy5tYWtlQ29kZShcIlxcblwiICsgdGhpcy50YWIpKTtcbiAgICAgIH1cbiAgICAgIGFuc3dlci5wdXNoKHRoaXMubWFrZUNvZGUoJ30nKSk7XG4gICAgICBpZiAodGhpcy5jdG9yKSB7XG4gICAgICAgIHJldHVybiBbdGhpcy5tYWtlQ29kZSh0aGlzLnRhYildLmNvbmNhdChfX3NsaWNlLmNhbGwoYW5zd2VyKSk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5mcm9udCB8fCAoby5sZXZlbCA+PSBMRVZFTF9BQ0NFU1MpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXBJbkJyYWNlcyhhbnN3ZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQ29kZS5wcm90b3R5cGUuZWFjaFBhcmFtTmFtZSA9IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7XG4gICAgICB2YXIgcGFyYW0sIF9pLCBfbGVuLCBfcmVmMiwgX3Jlc3VsdHM7XG4gICAgICBfcmVmMiA9IHRoaXMucGFyYW1zO1xuICAgICAgX3Jlc3VsdHMgPSBbXTtcbiAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gX3JlZjIubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgcGFyYW0gPSBfcmVmMltfaV07XG4gICAgICAgIF9yZXN1bHRzLnB1c2gocGFyYW0uZWFjaE5hbWUoaXRlcmF0b3IpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBfcmVzdWx0cztcbiAgICB9O1xuXG4gICAgQ29kZS5wcm90b3R5cGUudHJhdmVyc2VDaGlsZHJlbiA9IGZ1bmN0aW9uKGNyb3NzU2NvcGUsIGZ1bmMpIHtcbiAgICAgIGlmIChjcm9zc1Njb3BlKSB7XG4gICAgICAgIHJldHVybiBDb2RlLl9fc3VwZXJfXy50cmF2ZXJzZUNoaWxkcmVuLmNhbGwodGhpcywgY3Jvc3NTY29wZSwgZnVuYyk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBDb2RlO1xuXG4gIH0pKEJhc2UpO1xuXG4gIGV4cG9ydHMuUGFyYW0gPSBQYXJhbSA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoUGFyYW0sIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBQYXJhbShuYW1lLCB2YWx1ZSwgc3BsYXQpIHtcbiAgICAgIHZhciBfcmVmMjtcbiAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICB0aGlzLnNwbGF0ID0gc3BsYXQ7XG4gICAgICBpZiAoX3JlZjIgPSAobmFtZSA9IHRoaXMubmFtZS51bndyYXBBbGwoKS52YWx1ZSksIF9faW5kZXhPZi5jYWxsKFNUUklDVF9QUk9TQ1JJQkVELCBfcmVmMikgPj0gMCkge1xuICAgICAgICB0aGlzLm5hbWUuZXJyb3IoXCJwYXJhbWV0ZXIgbmFtZSBcXFwiXCIgKyBuYW1lICsgXCJcXFwiIGlzIG5vdCBhbGxvd2VkXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIFBhcmFtLnByb3RvdHlwZS5jaGlsZHJlbiA9IFsnbmFtZScsICd2YWx1ZSddO1xuXG4gICAgUGFyYW0ucHJvdG90eXBlLmNvbXBpbGVUb0ZyYWdtZW50cyA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHJldHVybiB0aGlzLm5hbWUuY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX0xJU1QpO1xuICAgIH07XG5cbiAgICBQYXJhbS5wcm90b3R5cGUuYXNSZWZlcmVuY2UgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgbm9kZTtcbiAgICAgIGlmICh0aGlzLnJlZmVyZW5jZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWZlcmVuY2U7XG4gICAgICB9XG4gICAgICBub2RlID0gdGhpcy5uYW1lO1xuICAgICAgaWYgKG5vZGVbXCJ0aGlzXCJdKSB7XG4gICAgICAgIG5vZGUgPSBub2RlLnByb3BlcnRpZXNbMF0ubmFtZTtcbiAgICAgICAgaWYgKG5vZGUudmFsdWUucmVzZXJ2ZWQpIHtcbiAgICAgICAgICBub2RlID0gbmV3IExpdGVyYWwoby5zY29wZS5mcmVlVmFyaWFibGUobm9kZS52YWx1ZSkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG5vZGUuaXNDb21wbGV4KCkpIHtcbiAgICAgICAgbm9kZSA9IG5ldyBMaXRlcmFsKG8uc2NvcGUuZnJlZVZhcmlhYmxlKCdhcmcnKSk7XG4gICAgICB9XG4gICAgICBub2RlID0gbmV3IFZhbHVlKG5vZGUpO1xuICAgICAgaWYgKHRoaXMuc3BsYXQpIHtcbiAgICAgICAgbm9kZSA9IG5ldyBTcGxhdChub2RlKTtcbiAgICAgIH1cbiAgICAgIG5vZGUudXBkYXRlTG9jYXRpb25EYXRhSWZNaXNzaW5nKHRoaXMubG9jYXRpb25EYXRhKTtcbiAgICAgIHJldHVybiB0aGlzLnJlZmVyZW5jZSA9IG5vZGU7XG4gICAgfTtcblxuICAgIFBhcmFtLnByb3RvdHlwZS5pc0NvbXBsZXggPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLm5hbWUuaXNDb21wbGV4KCk7XG4gICAgfTtcblxuICAgIFBhcmFtLnByb3RvdHlwZS5lYWNoTmFtZSA9IGZ1bmN0aW9uKGl0ZXJhdG9yLCBuYW1lKSB7XG4gICAgICB2YXIgYXRQYXJhbSwgbm9kZSwgb2JqLCBfaSwgX2xlbiwgX3JlZjI7XG4gICAgICBpZiAobmFtZSA9PSBudWxsKSB7XG4gICAgICAgIG5hbWUgPSB0aGlzLm5hbWU7XG4gICAgICB9XG4gICAgICBhdFBhcmFtID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgICAgIHZhciBub2RlO1xuICAgICAgICBub2RlID0gb2JqLnByb3BlcnRpZXNbMF0ubmFtZTtcbiAgICAgICAgaWYgKCFub2RlLnZhbHVlLnJlc2VydmVkKSB7XG4gICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yKG5vZGUudmFsdWUsIG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgaWYgKG5hbWUgaW5zdGFuY2VvZiBMaXRlcmFsKSB7XG4gICAgICAgIHJldHVybiBpdGVyYXRvcihuYW1lLnZhbHVlLCBuYW1lKTtcbiAgICAgIH1cbiAgICAgIGlmIChuYW1lIGluc3RhbmNlb2YgVmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGF0UGFyYW0obmFtZSk7XG4gICAgICB9XG4gICAgICBfcmVmMiA9IG5hbWUub2JqZWN0cztcbiAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gX3JlZjIubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgb2JqID0gX3JlZjJbX2ldO1xuICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgQXNzaWduKSB7XG4gICAgICAgICAgdGhpcy5lYWNoTmFtZShpdGVyYXRvciwgb2JqLnZhbHVlLnVud3JhcCgpKTtcbiAgICAgICAgfSBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBTcGxhdCkge1xuICAgICAgICAgIG5vZGUgPSBvYmoubmFtZS51bndyYXAoKTtcbiAgICAgICAgICBpdGVyYXRvcihub2RlLnZhbHVlLCBub2RlKTtcbiAgICAgICAgfSBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBWYWx1ZSkge1xuICAgICAgICAgIGlmIChvYmouaXNBcnJheSgpIHx8IG9iai5pc09iamVjdCgpKSB7XG4gICAgICAgICAgICB0aGlzLmVhY2hOYW1lKGl0ZXJhdG9yLCBvYmouYmFzZSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChvYmpbXCJ0aGlzXCJdKSB7XG4gICAgICAgICAgICBhdFBhcmFtKG9iaik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yKG9iai5iYXNlLnZhbHVlLCBvYmouYmFzZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEob2JqIGluc3RhbmNlb2YgRXhwYW5zaW9uKSkge1xuICAgICAgICAgIG9iai5lcnJvcihcImlsbGVnYWwgcGFyYW1ldGVyIFwiICsgKG9iai5jb21waWxlKCkpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gUGFyYW07XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5TcGxhdCA9IFNwbGF0ID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhTcGxhdCwgX3N1cGVyKTtcblxuICAgIFNwbGF0LnByb3RvdHlwZS5jaGlsZHJlbiA9IFsnbmFtZSddO1xuXG4gICAgU3BsYXQucHJvdG90eXBlLmlzQXNzaWduYWJsZSA9IFlFUztcblxuICAgIGZ1bmN0aW9uIFNwbGF0KG5hbWUpIHtcbiAgICAgIHRoaXMubmFtZSA9IG5hbWUuY29tcGlsZSA/IG5hbWUgOiBuZXcgTGl0ZXJhbChuYW1lKTtcbiAgICB9XG5cbiAgICBTcGxhdC5wcm90b3R5cGUuYXNzaWducyA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLm5hbWUuYXNzaWducyhuYW1lKTtcbiAgICB9O1xuXG4gICAgU3BsYXQucHJvdG90eXBlLmNvbXBpbGVUb0ZyYWdtZW50cyA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHJldHVybiB0aGlzLm5hbWUuY29tcGlsZVRvRnJhZ21lbnRzKG8pO1xuICAgIH07XG5cbiAgICBTcGxhdC5wcm90b3R5cGUudW53cmFwID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5uYW1lO1xuICAgIH07XG5cbiAgICBTcGxhdC5jb21waWxlU3BsYXR0ZWRBcnJheSA9IGZ1bmN0aW9uKG8sIGxpc3QsIGFwcGx5KSB7XG4gICAgICB2YXIgYXJncywgYmFzZSwgY29tcGlsZWROb2RlLCBjb25jYXRQYXJ0LCBmcmFnbWVudHMsIGksIGluZGV4LCBub2RlLCBfaSwgX2xlbjtcbiAgICAgIGluZGV4ID0gLTE7XG4gICAgICB3aGlsZSAoKG5vZGUgPSBsaXN0WysraW5kZXhdKSAmJiAhKG5vZGUgaW5zdGFuY2VvZiBTcGxhdCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoaW5kZXggPj0gbGlzdC5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIG5vZGUgPSBsaXN0WzBdO1xuICAgICAgICBmcmFnbWVudHMgPSBub2RlLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9MSVNUKTtcbiAgICAgICAgaWYgKGFwcGx5KSB7XG4gICAgICAgICAgcmV0dXJuIGZyYWdtZW50cztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW10uY29uY2F0KG5vZGUubWFrZUNvZGUoXCJcIiArICh1dGlsaXR5KCdzbGljZScpKSArIFwiLmNhbGwoXCIpLCBmcmFnbWVudHMsIG5vZGUubWFrZUNvZGUoXCIpXCIpKTtcbiAgICAgIH1cbiAgICAgIGFyZ3MgPSBsaXN0LnNsaWNlKGluZGV4KTtcbiAgICAgIGZvciAoaSA9IF9pID0gMCwgX2xlbiA9IGFyZ3MubGVuZ3RoOyBfaSA8IF9sZW47IGkgPSArK19pKSB7XG4gICAgICAgIG5vZGUgPSBhcmdzW2ldO1xuICAgICAgICBjb21waWxlZE5vZGUgPSBub2RlLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9MSVNUKTtcbiAgICAgICAgYXJnc1tpXSA9IG5vZGUgaW5zdGFuY2VvZiBTcGxhdCA/IFtdLmNvbmNhdChub2RlLm1ha2VDb2RlKFwiXCIgKyAodXRpbGl0eSgnc2xpY2UnKSkgKyBcIi5jYWxsKFwiKSwgY29tcGlsZWROb2RlLCBub2RlLm1ha2VDb2RlKFwiKVwiKSkgOiBbXS5jb25jYXQobm9kZS5tYWtlQ29kZShcIltcIiksIGNvbXBpbGVkTm9kZSwgbm9kZS5tYWtlQ29kZShcIl1cIikpO1xuICAgICAgfVxuICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgIG5vZGUgPSBsaXN0WzBdO1xuICAgICAgICBjb25jYXRQYXJ0ID0gbm9kZS5qb2luRnJhZ21lbnRBcnJheXMoYXJncy5zbGljZSgxKSwgJywgJyk7XG4gICAgICAgIHJldHVybiBhcmdzWzBdLmNvbmNhdChub2RlLm1ha2VDb2RlKFwiLmNvbmNhdChcIiksIGNvbmNhdFBhcnQsIG5vZGUubWFrZUNvZGUoXCIpXCIpKTtcbiAgICAgIH1cbiAgICAgIGJhc2UgPSAoZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBfaiwgX2xlbjEsIF9yZWYyLCBfcmVzdWx0cztcbiAgICAgICAgX3JlZjIgPSBsaXN0LnNsaWNlKDAsIGluZGV4KTtcbiAgICAgICAgX3Jlc3VsdHMgPSBbXTtcbiAgICAgICAgZm9yIChfaiA9IDAsIF9sZW4xID0gX3JlZjIubGVuZ3RoOyBfaiA8IF9sZW4xOyBfaisrKSB7XG4gICAgICAgICAgbm9kZSA9IF9yZWYyW19qXTtcbiAgICAgICAgICBfcmVzdWx0cy5wdXNoKG5vZGUuY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX0xJU1QpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX3Jlc3VsdHM7XG4gICAgICB9KSgpO1xuICAgICAgYmFzZSA9IGxpc3RbMF0uam9pbkZyYWdtZW50QXJyYXlzKGJhc2UsICcsICcpO1xuICAgICAgY29uY2F0UGFydCA9IGxpc3RbaW5kZXhdLmpvaW5GcmFnbWVudEFycmF5cyhhcmdzLCAnLCAnKTtcbiAgICAgIHJldHVybiBbXS5jb25jYXQobGlzdFswXS5tYWtlQ29kZShcIltcIiksIGJhc2UsIGxpc3RbaW5kZXhdLm1ha2VDb2RlKFwiXS5jb25jYXQoXCIpLCBjb25jYXRQYXJ0LCAobGFzdChsaXN0KSkubWFrZUNvZGUoXCIpXCIpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFNwbGF0O1xuXG4gIH0pKEJhc2UpO1xuXG4gIGV4cG9ydHMuRXhwYW5zaW9uID0gRXhwYW5zaW9uID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhFeHBhbnNpb24sIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBFeHBhbnNpb24oKSB7XG4gICAgICByZXR1cm4gRXhwYW5zaW9uLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIEV4cGFuc2lvbi5wcm90b3R5cGUuaXNDb21wbGV4ID0gTk87XG5cbiAgICBFeHBhbnNpb24ucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24obykge1xuICAgICAgcmV0dXJuIHRoaXMuZXJyb3IoJ0V4cGFuc2lvbiBtdXN0IGJlIHVzZWQgaW5zaWRlIGEgZGVzdHJ1Y3R1cmluZyBhc3NpZ25tZW50IG9yIHBhcmFtZXRlciBsaXN0Jyk7XG4gICAgfTtcblxuICAgIEV4cGFuc2lvbi5wcm90b3R5cGUuYXNSZWZlcmVuY2UgPSBmdW5jdGlvbihvKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgRXhwYW5zaW9uLnByb3RvdHlwZS5lYWNoTmFtZSA9IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7fTtcblxuICAgIHJldHVybiBFeHBhbnNpb247XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5XaGlsZSA9IFdoaWxlID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhXaGlsZSwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIFdoaWxlKGNvbmRpdGlvbiwgb3B0aW9ucykge1xuICAgICAgdGhpcy5jb25kaXRpb24gPSAob3B0aW9ucyAhPSBudWxsID8gb3B0aW9ucy5pbnZlcnQgOiB2b2lkIDApID8gY29uZGl0aW9uLmludmVydCgpIDogY29uZGl0aW9uO1xuICAgICAgdGhpcy5ndWFyZCA9IG9wdGlvbnMgIT0gbnVsbCA/IG9wdGlvbnMuZ3VhcmQgOiB2b2lkIDA7XG4gICAgfVxuXG4gICAgV2hpbGUucHJvdG90eXBlLmNoaWxkcmVuID0gWydjb25kaXRpb24nLCAnZ3VhcmQnLCAnYm9keSddO1xuXG4gICAgV2hpbGUucHJvdG90eXBlLmlzU3RhdGVtZW50ID0gWUVTO1xuXG4gICAgV2hpbGUucHJvdG90eXBlLm1ha2VSZXR1cm4gPSBmdW5jdGlvbihyZXMpIHtcbiAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgcmV0dXJuIFdoaWxlLl9fc3VwZXJfXy5tYWtlUmV0dXJuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJldHVybnMgPSAhdGhpcy5qdW1wcyh7XG4gICAgICAgICAgbG9vcDogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFdoaWxlLnByb3RvdHlwZS5hZGRCb2R5ID0gZnVuY3Rpb24oYm9keSkge1xuICAgICAgdGhpcy5ib2R5ID0gYm9keTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBXaGlsZS5wcm90b3R5cGUuanVtcHMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBleHByZXNzaW9ucywganVtcE5vZGUsIG5vZGUsIF9pLCBfbGVuO1xuICAgICAgZXhwcmVzc2lvbnMgPSB0aGlzLmJvZHkuZXhwcmVzc2lvbnM7XG4gICAgICBpZiAoIWV4cHJlc3Npb25zLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IGV4cHJlc3Npb25zLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIG5vZGUgPSBleHByZXNzaW9uc1tfaV07XG4gICAgICAgIGlmIChqdW1wTm9kZSA9IG5vZGUuanVtcHMoe1xuICAgICAgICAgIGxvb3A6IHRydWVcbiAgICAgICAgfSkpIHtcbiAgICAgICAgICByZXR1cm4ganVtcE5vZGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgV2hpbGUucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGFuc3dlciwgYm9keSwgcnZhciwgc2V0O1xuICAgICAgby5pbmRlbnQgKz0gVEFCO1xuICAgICAgc2V0ID0gJyc7XG4gICAgICBib2R5ID0gdGhpcy5ib2R5O1xuICAgICAgaWYgKGJvZHkuaXNFbXB0eSgpKSB7XG4gICAgICAgIGJvZHkgPSB0aGlzLm1ha2VDb2RlKCcnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLnJldHVybnMpIHtcbiAgICAgICAgICBib2R5Lm1ha2VSZXR1cm4ocnZhciA9IG8uc2NvcGUuZnJlZVZhcmlhYmxlKCdyZXN1bHRzJykpO1xuICAgICAgICAgIHNldCA9IFwiXCIgKyB0aGlzLnRhYiArIHJ2YXIgKyBcIiA9IFtdO1xcblwiO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmd1YXJkKSB7XG4gICAgICAgICAgaWYgKGJvZHkuZXhwcmVzc2lvbnMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgYm9keS5leHByZXNzaW9ucy51bnNoaWZ0KG5ldyBJZigobmV3IFBhcmVucyh0aGlzLmd1YXJkKSkuaW52ZXJ0KCksIG5ldyBMaXRlcmFsKFwiY29udGludWVcIikpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMuZ3VhcmQpIHtcbiAgICAgICAgICAgICAgYm9keSA9IEJsb2NrLndyYXAoW25ldyBJZih0aGlzLmd1YXJkLCBib2R5KV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBib2R5ID0gW10uY29uY2F0KHRoaXMubWFrZUNvZGUoXCJcXG5cIiksIGJvZHkuY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX1RPUCksIHRoaXMubWFrZUNvZGUoXCJcXG5cIiArIHRoaXMudGFiKSk7XG4gICAgICB9XG4gICAgICBhbnN3ZXIgPSBbXS5jb25jYXQodGhpcy5tYWtlQ29kZShzZXQgKyB0aGlzLnRhYiArIFwid2hpbGUgKFwiKSwgdGhpcy5jb25kaXRpb24uY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX1BBUkVOKSwgdGhpcy5tYWtlQ29kZShcIikge1wiKSwgYm9keSwgdGhpcy5tYWtlQ29kZShcIn1cIikpO1xuICAgICAgaWYgKHRoaXMucmV0dXJucykge1xuICAgICAgICBhbnN3ZXIucHVzaCh0aGlzLm1ha2VDb2RlKFwiXFxuXCIgKyB0aGlzLnRhYiArIFwicmV0dXJuIFwiICsgcnZhciArIFwiO1wiKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYW5zd2VyO1xuICAgIH07XG5cbiAgICByZXR1cm4gV2hpbGU7XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5PcCA9IE9wID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIHZhciBDT05WRVJTSU9OUywgSU5WRVJTSU9OUztcblxuICAgIF9fZXh0ZW5kcyhPcCwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIE9wKG9wLCBmaXJzdCwgc2Vjb25kLCBmbGlwKSB7XG4gICAgICBpZiAob3AgPT09ICdpbicpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBJbihmaXJzdCwgc2Vjb25kKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcCA9PT0gJ2RvJykge1xuICAgICAgICByZXR1cm4gdGhpcy5nZW5lcmF0ZURvKGZpcnN0KTtcbiAgICAgIH1cbiAgICAgIGlmIChvcCA9PT0gJ25ldycpIHtcbiAgICAgICAgaWYgKGZpcnN0IGluc3RhbmNlb2YgQ2FsbCAmJiAhZmlyc3RbXCJkb1wiXSAmJiAhZmlyc3QuaXNOZXcpIHtcbiAgICAgICAgICByZXR1cm4gZmlyc3QubmV3SW5zdGFuY2UoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmlyc3QgaW5zdGFuY2VvZiBDb2RlICYmIGZpcnN0LmJvdW5kIHx8IGZpcnN0W1wiZG9cIl0pIHtcbiAgICAgICAgICBmaXJzdCA9IG5ldyBQYXJlbnMoZmlyc3QpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLm9wZXJhdG9yID0gQ09OVkVSU0lPTlNbb3BdIHx8IG9wO1xuICAgICAgdGhpcy5maXJzdCA9IGZpcnN0O1xuICAgICAgdGhpcy5zZWNvbmQgPSBzZWNvbmQ7XG4gICAgICB0aGlzLmZsaXAgPSAhIWZsaXA7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBDT05WRVJTSU9OUyA9IHtcbiAgICAgICc9PSc6ICc9PT0nLFxuICAgICAgJyE9JzogJyE9PScsXG4gICAgICAnb2YnOiAnaW4nXG4gICAgfTtcblxuICAgIElOVkVSU0lPTlMgPSB7XG4gICAgICAnIT09JzogJz09PScsXG4gICAgICAnPT09JzogJyE9PSdcbiAgICB9O1xuXG4gICAgT3AucHJvdG90eXBlLmNoaWxkcmVuID0gWydmaXJzdCcsICdzZWNvbmQnXTtcblxuICAgIE9wLnByb3RvdHlwZS5pc1NpbXBsZU51bWJlciA9IE5PO1xuXG4gICAgT3AucHJvdG90eXBlLmlzVW5hcnkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAhdGhpcy5zZWNvbmQ7XG4gICAgfTtcblxuICAgIE9wLnByb3RvdHlwZS5pc0NvbXBsZXggPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBfcmVmMjtcbiAgICAgIHJldHVybiAhKHRoaXMuaXNVbmFyeSgpICYmICgoX3JlZjIgPSB0aGlzLm9wZXJhdG9yKSA9PT0gJysnIHx8IF9yZWYyID09PSAnLScpKSB8fCB0aGlzLmZpcnN0LmlzQ29tcGxleCgpO1xuICAgIH07XG5cbiAgICBPcC5wcm90b3R5cGUuaXNDaGFpbmFibGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBfcmVmMjtcbiAgICAgIHJldHVybiAoX3JlZjIgPSB0aGlzLm9wZXJhdG9yKSA9PT0gJzwnIHx8IF9yZWYyID09PSAnPicgfHwgX3JlZjIgPT09ICc+PScgfHwgX3JlZjIgPT09ICc8PScgfHwgX3JlZjIgPT09ICc9PT0nIHx8IF9yZWYyID09PSAnIT09JztcbiAgICB9O1xuXG4gICAgT3AucHJvdG90eXBlLmludmVydCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGFsbEludmVydGFibGUsIGN1cnIsIGZzdCwgb3AsIF9yZWYyO1xuICAgICAgaWYgKHRoaXMuaXNDaGFpbmFibGUoKSAmJiB0aGlzLmZpcnN0LmlzQ2hhaW5hYmxlKCkpIHtcbiAgICAgICAgYWxsSW52ZXJ0YWJsZSA9IHRydWU7XG4gICAgICAgIGN1cnIgPSB0aGlzO1xuICAgICAgICB3aGlsZSAoY3VyciAmJiBjdXJyLm9wZXJhdG9yKSB7XG4gICAgICAgICAgYWxsSW52ZXJ0YWJsZSAmJiAoYWxsSW52ZXJ0YWJsZSA9IGN1cnIub3BlcmF0b3IgaW4gSU5WRVJTSU9OUyk7XG4gICAgICAgICAgY3VyciA9IGN1cnIuZmlyc3Q7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFhbGxJbnZlcnRhYmxlKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBQYXJlbnModGhpcykuaW52ZXJ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgY3VyciA9IHRoaXM7XG4gICAgICAgIHdoaWxlIChjdXJyICYmIGN1cnIub3BlcmF0b3IpIHtcbiAgICAgICAgICBjdXJyLmludmVydCA9ICFjdXJyLmludmVydDtcbiAgICAgICAgICBjdXJyLm9wZXJhdG9yID0gSU5WRVJTSU9OU1tjdXJyLm9wZXJhdG9yXTtcbiAgICAgICAgICBjdXJyID0gY3Vyci5maXJzdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH0gZWxzZSBpZiAob3AgPSBJTlZFUlNJT05TW3RoaXMub3BlcmF0b3JdKSB7XG4gICAgICAgIHRoaXMub3BlcmF0b3IgPSBvcDtcbiAgICAgICAgaWYgKHRoaXMuZmlyc3QudW53cmFwKCkgaW5zdGFuY2VvZiBPcCkge1xuICAgICAgICAgIHRoaXMuZmlyc3QuaW52ZXJ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc2Vjb25kKSB7XG4gICAgICAgIHJldHVybiBuZXcgUGFyZW5zKHRoaXMpLmludmVydCgpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLm9wZXJhdG9yID09PSAnIScgJiYgKGZzdCA9IHRoaXMuZmlyc3QudW53cmFwKCkpIGluc3RhbmNlb2YgT3AgJiYgKChfcmVmMiA9IGZzdC5vcGVyYXRvcikgPT09ICchJyB8fCBfcmVmMiA9PT0gJ2luJyB8fCBfcmVmMiA9PT0gJ2luc3RhbmNlb2YnKSkge1xuICAgICAgICByZXR1cm4gZnN0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBPcCgnIScsIHRoaXMpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBPcC5wcm90b3R5cGUudW5mb2xkU29hayA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBfcmVmMjtcbiAgICAgIHJldHVybiAoKF9yZWYyID0gdGhpcy5vcGVyYXRvcikgPT09ICcrKycgfHwgX3JlZjIgPT09ICctLScgfHwgX3JlZjIgPT09ICdkZWxldGUnKSAmJiB1bmZvbGRTb2FrKG8sIHRoaXMsICdmaXJzdCcpO1xuICAgIH07XG5cbiAgICBPcC5wcm90b3R5cGUuZ2VuZXJhdGVEbyA9IGZ1bmN0aW9uKGV4cCkge1xuICAgICAgdmFyIGNhbGwsIGZ1bmMsIHBhcmFtLCBwYXNzZWRQYXJhbXMsIHJlZiwgX2ksIF9sZW4sIF9yZWYyO1xuICAgICAgcGFzc2VkUGFyYW1zID0gW107XG4gICAgICBmdW5jID0gZXhwIGluc3RhbmNlb2YgQXNzaWduICYmIChyZWYgPSBleHAudmFsdWUudW53cmFwKCkpIGluc3RhbmNlb2YgQ29kZSA/IHJlZiA6IGV4cDtcbiAgICAgIF9yZWYyID0gZnVuYy5wYXJhbXMgfHwgW107XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYyLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIHBhcmFtID0gX3JlZjJbX2ldO1xuICAgICAgICBpZiAocGFyYW0udmFsdWUpIHtcbiAgICAgICAgICBwYXNzZWRQYXJhbXMucHVzaChwYXJhbS52YWx1ZSk7XG4gICAgICAgICAgZGVsZXRlIHBhcmFtLnZhbHVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhc3NlZFBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2FsbCA9IG5ldyBDYWxsKGV4cCwgcGFzc2VkUGFyYW1zKTtcbiAgICAgIGNhbGxbXCJkb1wiXSA9IHRydWU7XG4gICAgICByZXR1cm4gY2FsbDtcbiAgICB9O1xuXG4gICAgT3AucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGFuc3dlciwgaXNDaGFpbiwgbGhzLCByaHMsIF9yZWYyLCBfcmVmMztcbiAgICAgIGlzQ2hhaW4gPSB0aGlzLmlzQ2hhaW5hYmxlKCkgJiYgdGhpcy5maXJzdC5pc0NoYWluYWJsZSgpO1xuICAgICAgaWYgKCFpc0NoYWluKSB7XG4gICAgICAgIHRoaXMuZmlyc3QuZnJvbnQgPSB0aGlzLmZyb250O1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMub3BlcmF0b3IgPT09ICdkZWxldGUnICYmIG8uc2NvcGUuY2hlY2sodGhpcy5maXJzdC51bndyYXBBbGwoKS52YWx1ZSkpIHtcbiAgICAgICAgdGhpcy5lcnJvcignZGVsZXRlIG9wZXJhbmQgbWF5IG5vdCBiZSBhcmd1bWVudCBvciB2YXInKTtcbiAgICAgIH1cbiAgICAgIGlmICgoKF9yZWYyID0gdGhpcy5vcGVyYXRvcikgPT09ICctLScgfHwgX3JlZjIgPT09ICcrKycpICYmIChfcmVmMyA9IHRoaXMuZmlyc3QudW53cmFwQWxsKCkudmFsdWUsIF9faW5kZXhPZi5jYWxsKFNUUklDVF9QUk9TQ1JJQkVELCBfcmVmMykgPj0gMCkpIHtcbiAgICAgICAgdGhpcy5lcnJvcihcImNhbm5vdCBpbmNyZW1lbnQvZGVjcmVtZW50IFxcXCJcIiArICh0aGlzLmZpcnN0LnVud3JhcEFsbCgpLnZhbHVlKSArIFwiXFxcIlwiKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmlzVW5hcnkoKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21waWxlVW5hcnkobyk7XG4gICAgICB9XG4gICAgICBpZiAoaXNDaGFpbikge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21waWxlQ2hhaW4obyk7XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKHRoaXMub3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSAnPyc6XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGlsZUV4aXN0ZW5jZShvKTtcbiAgICAgICAgY2FzZSAnKionOlxuICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBpbGVQb3dlcihvKTtcbiAgICAgICAgY2FzZSAnLy8nOlxuICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBpbGVGbG9vckRpdmlzaW9uKG8pO1xuICAgICAgICBjYXNlICclJSc6XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGlsZU1vZHVsbyhvKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBsaHMgPSB0aGlzLmZpcnN0LmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9PUCk7XG4gICAgICAgICAgcmhzID0gdGhpcy5zZWNvbmQuY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX09QKTtcbiAgICAgICAgICBhbnN3ZXIgPSBbXS5jb25jYXQobGhzLCB0aGlzLm1ha2VDb2RlKFwiIFwiICsgdGhpcy5vcGVyYXRvciArIFwiIFwiKSwgcmhzKTtcbiAgICAgICAgICBpZiAoby5sZXZlbCA8PSBMRVZFTF9PUCkge1xuICAgICAgICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud3JhcEluQnJhY2VzKGFuc3dlcik7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBPcC5wcm90b3R5cGUuY29tcGlsZUNoYWluID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGZyYWdtZW50cywgZnN0LCBzaGFyZWQsIF9yZWYyO1xuICAgICAgX3JlZjIgPSB0aGlzLmZpcnN0LnNlY29uZC5jYWNoZShvKSwgdGhpcy5maXJzdC5zZWNvbmQgPSBfcmVmMlswXSwgc2hhcmVkID0gX3JlZjJbMV07XG4gICAgICBmc3QgPSB0aGlzLmZpcnN0LmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9PUCk7XG4gICAgICBmcmFnbWVudHMgPSBmc3QuY29uY2F0KHRoaXMubWFrZUNvZGUoXCIgXCIgKyAodGhpcy5pbnZlcnQgPyAnJiYnIDogJ3x8JykgKyBcIiBcIiksIHNoYXJlZC5jb21waWxlVG9GcmFnbWVudHMobyksIHRoaXMubWFrZUNvZGUoXCIgXCIgKyB0aGlzLm9wZXJhdG9yICsgXCIgXCIpLCB0aGlzLnNlY29uZC5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfT1ApKTtcbiAgICAgIHJldHVybiB0aGlzLndyYXBJbkJyYWNlcyhmcmFnbWVudHMpO1xuICAgIH07XG5cbiAgICBPcC5wcm90b3R5cGUuY29tcGlsZUV4aXN0ZW5jZSA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBmc3QsIHJlZjtcbiAgICAgIGlmICh0aGlzLmZpcnN0LmlzQ29tcGxleCgpKSB7XG4gICAgICAgIHJlZiA9IG5ldyBMaXRlcmFsKG8uc2NvcGUuZnJlZVZhcmlhYmxlKCdyZWYnKSk7XG4gICAgICAgIGZzdCA9IG5ldyBQYXJlbnMobmV3IEFzc2lnbihyZWYsIHRoaXMuZmlyc3QpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZzdCA9IHRoaXMuZmlyc3Q7XG4gICAgICAgIHJlZiA9IGZzdDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgSWYobmV3IEV4aXN0ZW5jZShmc3QpLCByZWYsIHtcbiAgICAgICAgdHlwZTogJ2lmJ1xuICAgICAgfSkuYWRkRWxzZSh0aGlzLnNlY29uZCkuY29tcGlsZVRvRnJhZ21lbnRzKG8pO1xuICAgIH07XG5cbiAgICBPcC5wcm90b3R5cGUuY29tcGlsZVVuYXJ5ID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIG9wLCBwYXJ0cywgcGx1c01pbnVzO1xuICAgICAgcGFydHMgPSBbXTtcbiAgICAgIG9wID0gdGhpcy5vcGVyYXRvcjtcbiAgICAgIHBhcnRzLnB1c2goW3RoaXMubWFrZUNvZGUob3ApXSk7XG4gICAgICBpZiAob3AgPT09ICchJyAmJiB0aGlzLmZpcnN0IGluc3RhbmNlb2YgRXhpc3RlbmNlKSB7XG4gICAgICAgIHRoaXMuZmlyc3QubmVnYXRlZCA9ICF0aGlzLmZpcnN0Lm5lZ2F0ZWQ7XG4gICAgICAgIHJldHVybiB0aGlzLmZpcnN0LmNvbXBpbGVUb0ZyYWdtZW50cyhvKTtcbiAgICAgIH1cbiAgICAgIGlmIChvLmxldmVsID49IExFVkVMX0FDQ0VTUykge1xuICAgICAgICByZXR1cm4gKG5ldyBQYXJlbnModGhpcykpLmNvbXBpbGVUb0ZyYWdtZW50cyhvKTtcbiAgICAgIH1cbiAgICAgIHBsdXNNaW51cyA9IG9wID09PSAnKycgfHwgb3AgPT09ICctJztcbiAgICAgIGlmICgob3AgPT09ICduZXcnIHx8IG9wID09PSAndHlwZW9mJyB8fCBvcCA9PT0gJ2RlbGV0ZScpIHx8IHBsdXNNaW51cyAmJiB0aGlzLmZpcnN0IGluc3RhbmNlb2YgT3AgJiYgdGhpcy5maXJzdC5vcGVyYXRvciA9PT0gb3ApIHtcbiAgICAgICAgcGFydHMucHVzaChbdGhpcy5tYWtlQ29kZSgnICcpXSk7XG4gICAgICB9XG4gICAgICBpZiAoKHBsdXNNaW51cyAmJiB0aGlzLmZpcnN0IGluc3RhbmNlb2YgT3ApIHx8IChvcCA9PT0gJ25ldycgJiYgdGhpcy5maXJzdC5pc1N0YXRlbWVudChvKSkpIHtcbiAgICAgICAgdGhpcy5maXJzdCA9IG5ldyBQYXJlbnModGhpcy5maXJzdCk7XG4gICAgICB9XG4gICAgICBwYXJ0cy5wdXNoKHRoaXMuZmlyc3QuY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX09QKSk7XG4gICAgICBpZiAodGhpcy5mbGlwKSB7XG4gICAgICAgIHBhcnRzLnJldmVyc2UoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmpvaW5GcmFnbWVudEFycmF5cyhwYXJ0cywgJycpO1xuICAgIH07XG5cbiAgICBPcC5wcm90b3R5cGUuY29tcGlsZVBvd2VyID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIHBvdztcbiAgICAgIHBvdyA9IG5ldyBWYWx1ZShuZXcgTGl0ZXJhbCgnTWF0aCcpLCBbbmV3IEFjY2VzcyhuZXcgTGl0ZXJhbCgncG93JykpXSk7XG4gICAgICByZXR1cm4gbmV3IENhbGwocG93LCBbdGhpcy5maXJzdCwgdGhpcy5zZWNvbmRdKS5jb21waWxlVG9GcmFnbWVudHMobyk7XG4gICAgfTtcblxuICAgIE9wLnByb3RvdHlwZS5jb21waWxlRmxvb3JEaXZpc2lvbiA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBkaXYsIGZsb29yO1xuICAgICAgZmxvb3IgPSBuZXcgVmFsdWUobmV3IExpdGVyYWwoJ01hdGgnKSwgW25ldyBBY2Nlc3MobmV3IExpdGVyYWwoJ2Zsb29yJykpXSk7XG4gICAgICBkaXYgPSBuZXcgT3AoJy8nLCB0aGlzLmZpcnN0LCB0aGlzLnNlY29uZCk7XG4gICAgICByZXR1cm4gbmV3IENhbGwoZmxvb3IsIFtkaXZdKS5jb21waWxlVG9GcmFnbWVudHMobyk7XG4gICAgfTtcblxuICAgIE9wLnByb3RvdHlwZS5jb21waWxlTW9kdWxvID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIG1vZDtcbiAgICAgIG1vZCA9IG5ldyBWYWx1ZShuZXcgTGl0ZXJhbCh1dGlsaXR5KCdtb2R1bG8nKSkpO1xuICAgICAgcmV0dXJuIG5ldyBDYWxsKG1vZCwgW3RoaXMuZmlyc3QsIHRoaXMuc2Vjb25kXSkuY29tcGlsZVRvRnJhZ21lbnRzKG8pO1xuICAgIH07XG5cbiAgICBPcC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihpZHQpIHtcbiAgICAgIHJldHVybiBPcC5fX3N1cGVyX18udG9TdHJpbmcuY2FsbCh0aGlzLCBpZHQsIHRoaXMuY29uc3RydWN0b3IubmFtZSArICcgJyArIHRoaXMub3BlcmF0b3IpO1xuICAgIH07XG5cbiAgICByZXR1cm4gT3A7XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5JbiA9IEluID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhJbiwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIEluKG9iamVjdCwgYXJyYXkpIHtcbiAgICAgIHRoaXMub2JqZWN0ID0gb2JqZWN0O1xuICAgICAgdGhpcy5hcnJheSA9IGFycmF5O1xuICAgIH1cblxuICAgIEluLnByb3RvdHlwZS5jaGlsZHJlbiA9IFsnb2JqZWN0JywgJ2FycmF5J107XG5cbiAgICBJbi5wcm90b3R5cGUuaW52ZXJ0ID0gTkVHQVRFO1xuXG4gICAgSW4ucHJvdG90eXBlLmNvbXBpbGVOb2RlID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGhhc1NwbGF0LCBvYmosIF9pLCBfbGVuLCBfcmVmMjtcbiAgICAgIGlmICh0aGlzLmFycmF5IGluc3RhbmNlb2YgVmFsdWUgJiYgdGhpcy5hcnJheS5pc0FycmF5KCkgJiYgdGhpcy5hcnJheS5iYXNlLm9iamVjdHMubGVuZ3RoKSB7XG4gICAgICAgIF9yZWYyID0gdGhpcy5hcnJheS5iYXNlLm9iamVjdHM7XG4gICAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gX3JlZjIubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgICBvYmogPSBfcmVmMltfaV07XG4gICAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgU3BsYXQpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaGFzU3BsYXQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaGFzU3BsYXQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jb21waWxlT3JUZXN0KG8pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5jb21waWxlTG9vcFRlc3Qobyk7XG4gICAgfTtcblxuICAgIEluLnByb3RvdHlwZS5jb21waWxlT3JUZXN0ID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGNtcCwgY25qLCBpLCBpdGVtLCByZWYsIHN1YiwgdGVzdHMsIF9pLCBfbGVuLCBfcmVmMiwgX3JlZjMsIF9yZWY0O1xuICAgICAgX3JlZjIgPSB0aGlzLm9iamVjdC5jYWNoZShvLCBMRVZFTF9PUCksIHN1YiA9IF9yZWYyWzBdLCByZWYgPSBfcmVmMlsxXTtcbiAgICAgIF9yZWYzID0gdGhpcy5uZWdhdGVkID8gWycgIT09ICcsICcgJiYgJ10gOiBbJyA9PT0gJywgJyB8fCAnXSwgY21wID0gX3JlZjNbMF0sIGNuaiA9IF9yZWYzWzFdO1xuICAgICAgdGVzdHMgPSBbXTtcbiAgICAgIF9yZWY0ID0gdGhpcy5hcnJheS5iYXNlLm9iamVjdHM7XG4gICAgICBmb3IgKGkgPSBfaSA9IDAsIF9sZW4gPSBfcmVmNC5sZW5ndGg7IF9pIDwgX2xlbjsgaSA9ICsrX2kpIHtcbiAgICAgICAgaXRlbSA9IF9yZWY0W2ldO1xuICAgICAgICBpZiAoaSkge1xuICAgICAgICAgIHRlc3RzLnB1c2godGhpcy5tYWtlQ29kZShjbmopKTtcbiAgICAgICAgfVxuICAgICAgICB0ZXN0cyA9IHRlc3RzLmNvbmNhdCgoaSA/IHJlZiA6IHN1YiksIHRoaXMubWFrZUNvZGUoY21wKSwgaXRlbS5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfQUNDRVNTKSk7XG4gICAgICB9XG4gICAgICBpZiAoby5sZXZlbCA8IExFVkVMX09QKSB7XG4gICAgICAgIHJldHVybiB0ZXN0cztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXBJbkJyYWNlcyh0ZXN0cyk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEluLnByb3RvdHlwZS5jb21waWxlTG9vcFRlc3QgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgZnJhZ21lbnRzLCByZWYsIHN1YiwgX3JlZjI7XG4gICAgICBfcmVmMiA9IHRoaXMub2JqZWN0LmNhY2hlKG8sIExFVkVMX0xJU1QpLCBzdWIgPSBfcmVmMlswXSwgcmVmID0gX3JlZjJbMV07XG4gICAgICBmcmFnbWVudHMgPSBbXS5jb25jYXQodGhpcy5tYWtlQ29kZSh1dGlsaXR5KCdpbmRleE9mJykgKyBcIi5jYWxsKFwiKSwgdGhpcy5hcnJheS5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfTElTVCksIHRoaXMubWFrZUNvZGUoXCIsIFwiKSwgcmVmLCB0aGlzLm1ha2VDb2RlKFwiKSBcIiArICh0aGlzLm5lZ2F0ZWQgPyAnPCAwJyA6ICc+PSAwJykpKTtcbiAgICAgIGlmIChmcmFnbWVudHNUb1RleHQoc3ViKSA9PT0gZnJhZ21lbnRzVG9UZXh0KHJlZikpIHtcbiAgICAgICAgcmV0dXJuIGZyYWdtZW50cztcbiAgICAgIH1cbiAgICAgIGZyYWdtZW50cyA9IHN1Yi5jb25jYXQodGhpcy5tYWtlQ29kZSgnLCAnKSwgZnJhZ21lbnRzKTtcbiAgICAgIGlmIChvLmxldmVsIDwgTEVWRUxfTElTVCkge1xuICAgICAgICByZXR1cm4gZnJhZ21lbnRzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud3JhcEluQnJhY2VzKGZyYWdtZW50cyk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEluLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKGlkdCkge1xuICAgICAgcmV0dXJuIEluLl9fc3VwZXJfXy50b1N0cmluZy5jYWxsKHRoaXMsIGlkdCwgdGhpcy5jb25zdHJ1Y3Rvci5uYW1lICsgKHRoaXMubmVnYXRlZCA/ICchJyA6ICcnKSk7XG4gICAgfTtcblxuICAgIHJldHVybiBJbjtcblxuICB9KShCYXNlKTtcblxuICBleHBvcnRzLlRyeSA9IFRyeSA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVHJ5LCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gVHJ5KGF0dGVtcHQsIGVycm9yVmFyaWFibGUsIHJlY292ZXJ5LCBlbnN1cmUpIHtcbiAgICAgIHRoaXMuYXR0ZW1wdCA9IGF0dGVtcHQ7XG4gICAgICB0aGlzLmVycm9yVmFyaWFibGUgPSBlcnJvclZhcmlhYmxlO1xuICAgICAgdGhpcy5yZWNvdmVyeSA9IHJlY292ZXJ5O1xuICAgICAgdGhpcy5lbnN1cmUgPSBlbnN1cmU7XG4gICAgfVxuXG4gICAgVHJ5LnByb3RvdHlwZS5jaGlsZHJlbiA9IFsnYXR0ZW1wdCcsICdyZWNvdmVyeScsICdlbnN1cmUnXTtcblxuICAgIFRyeS5wcm90b3R5cGUuaXNTdGF0ZW1lbnQgPSBZRVM7XG5cbiAgICBUcnkucHJvdG90eXBlLmp1bXBzID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIF9yZWYyO1xuICAgICAgcmV0dXJuIHRoaXMuYXR0ZW1wdC5qdW1wcyhvKSB8fCAoKF9yZWYyID0gdGhpcy5yZWNvdmVyeSkgIT0gbnVsbCA/IF9yZWYyLmp1bXBzKG8pIDogdm9pZCAwKTtcbiAgICB9O1xuXG4gICAgVHJ5LnByb3RvdHlwZS5tYWtlUmV0dXJuID0gZnVuY3Rpb24ocmVzKSB7XG4gICAgICBpZiAodGhpcy5hdHRlbXB0KSB7XG4gICAgICAgIHRoaXMuYXR0ZW1wdCA9IHRoaXMuYXR0ZW1wdC5tYWtlUmV0dXJuKHJlcyk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5yZWNvdmVyeSkge1xuICAgICAgICB0aGlzLnJlY292ZXJ5ID0gdGhpcy5yZWNvdmVyeS5tYWtlUmV0dXJuKHJlcyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgVHJ5LnByb3RvdHlwZS5jb21waWxlTm9kZSA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBjYXRjaFBhcnQsIGVuc3VyZVBhcnQsIHBsYWNlaG9sZGVyLCB0cnlQYXJ0O1xuICAgICAgby5pbmRlbnQgKz0gVEFCO1xuICAgICAgdHJ5UGFydCA9IHRoaXMuYXR0ZW1wdC5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfVE9QKTtcbiAgICAgIGNhdGNoUGFydCA9IHRoaXMucmVjb3ZlcnkgPyAocGxhY2Vob2xkZXIgPSBuZXcgTGl0ZXJhbCgnX2Vycm9yJyksIHRoaXMuZXJyb3JWYXJpYWJsZSA/IHRoaXMucmVjb3ZlcnkudW5zaGlmdChuZXcgQXNzaWduKHRoaXMuZXJyb3JWYXJpYWJsZSwgcGxhY2Vob2xkZXIpKSA6IHZvaWQgMCwgW10uY29uY2F0KHRoaXMubWFrZUNvZGUoXCIgY2F0Y2ggKFwiKSwgcGxhY2Vob2xkZXIuY29tcGlsZVRvRnJhZ21lbnRzKG8pLCB0aGlzLm1ha2VDb2RlKFwiKSB7XFxuXCIpLCB0aGlzLnJlY292ZXJ5LmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9UT1ApLCB0aGlzLm1ha2VDb2RlKFwiXFxuXCIgKyB0aGlzLnRhYiArIFwifVwiKSkpIDogISh0aGlzLmVuc3VyZSB8fCB0aGlzLnJlY292ZXJ5KSA/IFt0aGlzLm1ha2VDb2RlKCcgY2F0Y2ggKF9lcnJvcikge30nKV0gOiBbXTtcbiAgICAgIGVuc3VyZVBhcnQgPSB0aGlzLmVuc3VyZSA/IFtdLmNvbmNhdCh0aGlzLm1ha2VDb2RlKFwiIGZpbmFsbHkge1xcblwiKSwgdGhpcy5lbnN1cmUuY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX1RPUCksIHRoaXMubWFrZUNvZGUoXCJcXG5cIiArIHRoaXMudGFiICsgXCJ9XCIpKSA6IFtdO1xuICAgICAgcmV0dXJuIFtdLmNvbmNhdCh0aGlzLm1ha2VDb2RlKFwiXCIgKyB0aGlzLnRhYiArIFwidHJ5IHtcXG5cIiksIHRyeVBhcnQsIHRoaXMubWFrZUNvZGUoXCJcXG5cIiArIHRoaXMudGFiICsgXCJ9XCIpLCBjYXRjaFBhcnQsIGVuc3VyZVBhcnQpO1xuICAgIH07XG5cbiAgICByZXR1cm4gVHJ5O1xuXG4gIH0pKEJhc2UpO1xuXG4gIGV4cG9ydHMuVGhyb3cgPSBUaHJvdyA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVGhyb3csIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBUaHJvdyhleHByZXNzaW9uKSB7XG4gICAgICB0aGlzLmV4cHJlc3Npb24gPSBleHByZXNzaW9uO1xuICAgIH1cblxuICAgIFRocm93LnByb3RvdHlwZS5jaGlsZHJlbiA9IFsnZXhwcmVzc2lvbiddO1xuXG4gICAgVGhyb3cucHJvdG90eXBlLmlzU3RhdGVtZW50ID0gWUVTO1xuXG4gICAgVGhyb3cucHJvdG90eXBlLmp1bXBzID0gTk87XG5cbiAgICBUaHJvdy5wcm90b3R5cGUubWFrZVJldHVybiA9IFRISVM7XG5cbiAgICBUaHJvdy5wcm90b3R5cGUuY29tcGlsZU5vZGUgPSBmdW5jdGlvbihvKSB7XG4gICAgICByZXR1cm4gW10uY29uY2F0KHRoaXMubWFrZUNvZGUodGhpcy50YWIgKyBcInRocm93IFwiKSwgdGhpcy5leHByZXNzaW9uLmNvbXBpbGVUb0ZyYWdtZW50cyhvKSwgdGhpcy5tYWtlQ29kZShcIjtcIikpO1xuICAgIH07XG5cbiAgICByZXR1cm4gVGhyb3c7XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5FeGlzdGVuY2UgPSBFeGlzdGVuY2UgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKEV4aXN0ZW5jZSwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIEV4aXN0ZW5jZShleHByZXNzaW9uKSB7XG4gICAgICB0aGlzLmV4cHJlc3Npb24gPSBleHByZXNzaW9uO1xuICAgIH1cblxuICAgIEV4aXN0ZW5jZS5wcm90b3R5cGUuY2hpbGRyZW4gPSBbJ2V4cHJlc3Npb24nXTtcblxuICAgIEV4aXN0ZW5jZS5wcm90b3R5cGUuaW52ZXJ0ID0gTkVHQVRFO1xuXG4gICAgRXhpc3RlbmNlLnByb3RvdHlwZS5jb21waWxlTm9kZSA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBjbXAsIGNuaiwgY29kZSwgX3JlZjI7XG4gICAgICB0aGlzLmV4cHJlc3Npb24uZnJvbnQgPSB0aGlzLmZyb250O1xuICAgICAgY29kZSA9IHRoaXMuZXhwcmVzc2lvbi5jb21waWxlKG8sIExFVkVMX09QKTtcbiAgICAgIGlmIChJREVOVElGSUVSLnRlc3QoY29kZSkgJiYgIW8uc2NvcGUuY2hlY2soY29kZSkpIHtcbiAgICAgICAgX3JlZjIgPSB0aGlzLm5lZ2F0ZWQgPyBbJz09PScsICd8fCddIDogWychPT0nLCAnJiYnXSwgY21wID0gX3JlZjJbMF0sIGNuaiA9IF9yZWYyWzFdO1xuICAgICAgICBjb2RlID0gXCJ0eXBlb2YgXCIgKyBjb2RlICsgXCIgXCIgKyBjbXAgKyBcIiBcXFwidW5kZWZpbmVkXFxcIiBcIiArIGNuaiArIFwiIFwiICsgY29kZSArIFwiIFwiICsgY21wICsgXCIgbnVsbFwiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29kZSA9IFwiXCIgKyBjb2RlICsgXCIgXCIgKyAodGhpcy5uZWdhdGVkID8gJz09JyA6ICchPScpICsgXCIgbnVsbFwiO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFt0aGlzLm1ha2VDb2RlKG8ubGV2ZWwgPD0gTEVWRUxfQ09ORCA/IGNvZGUgOiBcIihcIiArIGNvZGUgKyBcIilcIildO1xuICAgIH07XG5cbiAgICByZXR1cm4gRXhpc3RlbmNlO1xuXG4gIH0pKEJhc2UpO1xuXG4gIGV4cG9ydHMuUGFyZW5zID0gUGFyZW5zID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhQYXJlbnMsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBQYXJlbnMoYm9keSkge1xuICAgICAgdGhpcy5ib2R5ID0gYm9keTtcbiAgICB9XG5cbiAgICBQYXJlbnMucHJvdG90eXBlLmNoaWxkcmVuID0gWydib2R5J107XG5cbiAgICBQYXJlbnMucHJvdG90eXBlLnVud3JhcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuYm9keTtcbiAgICB9O1xuXG4gICAgUGFyZW5zLnByb3RvdHlwZS5pc0NvbXBsZXggPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmJvZHkuaXNDb21wbGV4KCk7XG4gICAgfTtcblxuICAgIFBhcmVucy5wcm90b3R5cGUuY29tcGlsZU5vZGUgPSBmdW5jdGlvbihvKSB7XG4gICAgICB2YXIgYmFyZSwgZXhwciwgZnJhZ21lbnRzO1xuICAgICAgZXhwciA9IHRoaXMuYm9keS51bndyYXAoKTtcbiAgICAgIGlmIChleHByIGluc3RhbmNlb2YgVmFsdWUgJiYgZXhwci5pc0F0b21pYygpKSB7XG4gICAgICAgIGV4cHIuZnJvbnQgPSB0aGlzLmZyb250O1xuICAgICAgICByZXR1cm4gZXhwci5jb21waWxlVG9GcmFnbWVudHMobyk7XG4gICAgICB9XG4gICAgICBmcmFnbWVudHMgPSBleHByLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9QQVJFTik7XG4gICAgICBiYXJlID0gby5sZXZlbCA8IExFVkVMX09QICYmIChleHByIGluc3RhbmNlb2YgT3AgfHwgZXhwciBpbnN0YW5jZW9mIENhbGwgfHwgKGV4cHIgaW5zdGFuY2VvZiBGb3IgJiYgZXhwci5yZXR1cm5zKSk7XG4gICAgICBpZiAoYmFyZSkge1xuICAgICAgICByZXR1cm4gZnJhZ21lbnRzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud3JhcEluQnJhY2VzKGZyYWdtZW50cyk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBQYXJlbnM7XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5Gb3IgPSBGb3IgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKEZvciwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIEZvcihib2R5LCBzb3VyY2UpIHtcbiAgICAgIHZhciBfcmVmMjtcbiAgICAgIHRoaXMuc291cmNlID0gc291cmNlLnNvdXJjZSwgdGhpcy5ndWFyZCA9IHNvdXJjZS5ndWFyZCwgdGhpcy5zdGVwID0gc291cmNlLnN0ZXAsIHRoaXMubmFtZSA9IHNvdXJjZS5uYW1lLCB0aGlzLmluZGV4ID0gc291cmNlLmluZGV4O1xuICAgICAgdGhpcy5ib2R5ID0gQmxvY2sud3JhcChbYm9keV0pO1xuICAgICAgdGhpcy5vd24gPSAhIXNvdXJjZS5vd247XG4gICAgICB0aGlzLm9iamVjdCA9ICEhc291cmNlLm9iamVjdDtcbiAgICAgIGlmICh0aGlzLm9iamVjdCkge1xuICAgICAgICBfcmVmMiA9IFt0aGlzLmluZGV4LCB0aGlzLm5hbWVdLCB0aGlzLm5hbWUgPSBfcmVmMlswXSwgdGhpcy5pbmRleCA9IF9yZWYyWzFdO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuaW5kZXggaW5zdGFuY2VvZiBWYWx1ZSkge1xuICAgICAgICB0aGlzLmluZGV4LmVycm9yKCdpbmRleCBjYW5ub3QgYmUgYSBwYXR0ZXJuIG1hdGNoaW5nIGV4cHJlc3Npb24nKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucmFuZ2UgPSB0aGlzLnNvdXJjZSBpbnN0YW5jZW9mIFZhbHVlICYmIHRoaXMuc291cmNlLmJhc2UgaW5zdGFuY2VvZiBSYW5nZSAmJiAhdGhpcy5zb3VyY2UucHJvcGVydGllcy5sZW5ndGg7XG4gICAgICB0aGlzLnBhdHRlcm4gPSB0aGlzLm5hbWUgaW5zdGFuY2VvZiBWYWx1ZTtcbiAgICAgIGlmICh0aGlzLnJhbmdlICYmIHRoaXMuaW5kZXgpIHtcbiAgICAgICAgdGhpcy5pbmRleC5lcnJvcignaW5kZXhlcyBkbyBub3QgYXBwbHkgdG8gcmFuZ2UgbG9vcHMnKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnJhbmdlICYmIHRoaXMucGF0dGVybikge1xuICAgICAgICB0aGlzLm5hbWUuZXJyb3IoJ2Nhbm5vdCBwYXR0ZXJuIG1hdGNoIG92ZXIgcmFuZ2UgbG9vcHMnKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm93biAmJiAhdGhpcy5vYmplY3QpIHtcbiAgICAgICAgdGhpcy5uYW1lLmVycm9yKCdjYW5ub3QgdXNlIG93biB3aXRoIGZvci1pbicpO1xuICAgICAgfVxuICAgICAgdGhpcy5yZXR1cm5zID0gZmFsc2U7XG4gICAgfVxuXG4gICAgRm9yLnByb3RvdHlwZS5jaGlsZHJlbiA9IFsnYm9keScsICdzb3VyY2UnLCAnZ3VhcmQnLCAnc3RlcCddO1xuXG4gICAgRm9yLnByb3RvdHlwZS5jb21waWxlTm9kZSA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBib2R5LCBib2R5RnJhZ21lbnRzLCBjb21wYXJlLCBjb21wYXJlRG93biwgZGVjbGFyZSwgZGVjbGFyZURvd24sIGRlZlBhcnQsIGRlZlBhcnRGcmFnbWVudHMsIGRvd24sIGZvclBhcnRGcmFnbWVudHMsIGd1YXJkUGFydCwgaWR0MSwgaW5jcmVtZW50LCBpbmRleCwgaXZhciwga3Zhciwga3ZhckFzc2lnbiwgbGFzdEp1bXBzLCBsdmFyLCBuYW1lLCBuYW1lUGFydCwgcmVmLCByZXN1bHRQYXJ0LCByZXR1cm5SZXN1bHQsIHJ2YXIsIHNjb3BlLCBzb3VyY2UsIHN0ZXAsIHN0ZXBOdW0sIHN0ZXBWYXIsIHN2YXIsIHZhclBhcnQsIF9yZWYyLCBfcmVmMztcbiAgICAgIGJvZHkgPSBCbG9jay53cmFwKFt0aGlzLmJvZHldKTtcbiAgICAgIGxhc3RKdW1wcyA9IChfcmVmMiA9IGxhc3QoYm9keS5leHByZXNzaW9ucykpICE9IG51bGwgPyBfcmVmMi5qdW1wcygpIDogdm9pZCAwO1xuICAgICAgaWYgKGxhc3RKdW1wcyAmJiBsYXN0SnVtcHMgaW5zdGFuY2VvZiBSZXR1cm4pIHtcbiAgICAgICAgdGhpcy5yZXR1cm5zID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBzb3VyY2UgPSB0aGlzLnJhbmdlID8gdGhpcy5zb3VyY2UuYmFzZSA6IHRoaXMuc291cmNlO1xuICAgICAgc2NvcGUgPSBvLnNjb3BlO1xuICAgICAgaWYgKCF0aGlzLnBhdHRlcm4pIHtcbiAgICAgICAgbmFtZSA9IHRoaXMubmFtZSAmJiAodGhpcy5uYW1lLmNvbXBpbGUobywgTEVWRUxfTElTVCkpO1xuICAgICAgfVxuICAgICAgaW5kZXggPSB0aGlzLmluZGV4ICYmICh0aGlzLmluZGV4LmNvbXBpbGUobywgTEVWRUxfTElTVCkpO1xuICAgICAgaWYgKG5hbWUgJiYgIXRoaXMucGF0dGVybikge1xuICAgICAgICBzY29wZS5maW5kKG5hbWUpO1xuICAgICAgfVxuICAgICAgaWYgKGluZGV4KSB7XG4gICAgICAgIHNjb3BlLmZpbmQoaW5kZXgpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMucmV0dXJucykge1xuICAgICAgICBydmFyID0gc2NvcGUuZnJlZVZhcmlhYmxlKCdyZXN1bHRzJyk7XG4gICAgICB9XG4gICAgICBpdmFyID0gKHRoaXMub2JqZWN0ICYmIGluZGV4KSB8fCBzY29wZS5mcmVlVmFyaWFibGUoJ2knKTtcbiAgICAgIGt2YXIgPSAodGhpcy5yYW5nZSAmJiBuYW1lKSB8fCBpbmRleCB8fCBpdmFyO1xuICAgICAga3ZhckFzc2lnbiA9IGt2YXIgIT09IGl2YXIgPyBcIlwiICsga3ZhciArIFwiID0gXCIgOiBcIlwiO1xuICAgICAgaWYgKHRoaXMuc3RlcCAmJiAhdGhpcy5yYW5nZSkge1xuICAgICAgICBfcmVmMyA9IHRoaXMuY2FjaGVUb0NvZGVGcmFnbWVudHModGhpcy5zdGVwLmNhY2hlKG8sIExFVkVMX0xJU1QpKSwgc3RlcCA9IF9yZWYzWzBdLCBzdGVwVmFyID0gX3JlZjNbMV07XG4gICAgICAgIHN0ZXBOdW0gPSBzdGVwVmFyLm1hdGNoKE5VTUJFUik7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5wYXR0ZXJuKSB7XG4gICAgICAgIG5hbWUgPSBpdmFyO1xuICAgICAgfVxuICAgICAgdmFyUGFydCA9ICcnO1xuICAgICAgZ3VhcmRQYXJ0ID0gJyc7XG4gICAgICBkZWZQYXJ0ID0gJyc7XG4gICAgICBpZHQxID0gdGhpcy50YWIgKyBUQUI7XG4gICAgICBpZiAodGhpcy5yYW5nZSkge1xuICAgICAgICBmb3JQYXJ0RnJhZ21lbnRzID0gc291cmNlLmNvbXBpbGVUb0ZyYWdtZW50cyhtZXJnZShvLCB7XG4gICAgICAgICAgaW5kZXg6IGl2YXIsXG4gICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICBzdGVwOiB0aGlzLnN0ZXBcbiAgICAgICAgfSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3ZhciA9IHRoaXMuc291cmNlLmNvbXBpbGUobywgTEVWRUxfTElTVCk7XG4gICAgICAgIGlmICgobmFtZSB8fCB0aGlzLm93bikgJiYgIUlERU5USUZJRVIudGVzdChzdmFyKSkge1xuICAgICAgICAgIGRlZlBhcnQgKz0gXCJcIiArIHRoaXMudGFiICsgKHJlZiA9IHNjb3BlLmZyZWVWYXJpYWJsZSgncmVmJykpICsgXCIgPSBcIiArIHN2YXIgKyBcIjtcXG5cIjtcbiAgICAgICAgICBzdmFyID0gcmVmO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYW1lICYmICF0aGlzLnBhdHRlcm4pIHtcbiAgICAgICAgICBuYW1lUGFydCA9IFwiXCIgKyBuYW1lICsgXCIgPSBcIiArIHN2YXIgKyBcIltcIiArIGt2YXIgKyBcIl1cIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMub2JqZWN0KSB7XG4gICAgICAgICAgaWYgKHN0ZXAgIT09IHN0ZXBWYXIpIHtcbiAgICAgICAgICAgIGRlZlBhcnQgKz0gXCJcIiArIHRoaXMudGFiICsgc3RlcCArIFwiO1xcblwiO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoISh0aGlzLnN0ZXAgJiYgc3RlcE51bSAmJiAoZG93biA9IHBhcnNlTnVtKHN0ZXBOdW1bMF0pIDwgMCkpKSB7XG4gICAgICAgICAgICBsdmFyID0gc2NvcGUuZnJlZVZhcmlhYmxlKCdsZW4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVjbGFyZSA9IFwiXCIgKyBrdmFyQXNzaWduICsgaXZhciArIFwiID0gMCwgXCIgKyBsdmFyICsgXCIgPSBcIiArIHN2YXIgKyBcIi5sZW5ndGhcIjtcbiAgICAgICAgICBkZWNsYXJlRG93biA9IFwiXCIgKyBrdmFyQXNzaWduICsgaXZhciArIFwiID0gXCIgKyBzdmFyICsgXCIubGVuZ3RoIC0gMVwiO1xuICAgICAgICAgIGNvbXBhcmUgPSBcIlwiICsgaXZhciArIFwiIDwgXCIgKyBsdmFyO1xuICAgICAgICAgIGNvbXBhcmVEb3duID0gXCJcIiArIGl2YXIgKyBcIiA+PSAwXCI7XG4gICAgICAgICAgaWYgKHRoaXMuc3RlcCkge1xuICAgICAgICAgICAgaWYgKHN0ZXBOdW0pIHtcbiAgICAgICAgICAgICAgaWYgKGRvd24pIHtcbiAgICAgICAgICAgICAgICBjb21wYXJlID0gY29tcGFyZURvd247XG4gICAgICAgICAgICAgICAgZGVjbGFyZSA9IGRlY2xhcmVEb3duO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb21wYXJlID0gXCJcIiArIHN0ZXBWYXIgKyBcIiA+IDAgPyBcIiArIGNvbXBhcmUgKyBcIiA6IFwiICsgY29tcGFyZURvd247XG4gICAgICAgICAgICAgIGRlY2xhcmUgPSBcIihcIiArIHN0ZXBWYXIgKyBcIiA+IDAgPyAoXCIgKyBkZWNsYXJlICsgXCIpIDogXCIgKyBkZWNsYXJlRG93biArIFwiKVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5jcmVtZW50ID0gXCJcIiArIGl2YXIgKyBcIiArPSBcIiArIHN0ZXBWYXI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluY3JlbWVudCA9IFwiXCIgKyAoa3ZhciAhPT0gaXZhciA/IFwiKytcIiArIGl2YXIgOiBcIlwiICsgaXZhciArIFwiKytcIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZvclBhcnRGcmFnbWVudHMgPSBbdGhpcy5tYWtlQ29kZShcIlwiICsgZGVjbGFyZSArIFwiOyBcIiArIGNvbXBhcmUgKyBcIjsgXCIgKyBrdmFyQXNzaWduICsgaW5jcmVtZW50KV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnJldHVybnMpIHtcbiAgICAgICAgcmVzdWx0UGFydCA9IFwiXCIgKyB0aGlzLnRhYiArIHJ2YXIgKyBcIiA9IFtdO1xcblwiO1xuICAgICAgICByZXR1cm5SZXN1bHQgPSBcIlxcblwiICsgdGhpcy50YWIgKyBcInJldHVybiBcIiArIHJ2YXIgKyBcIjtcIjtcbiAgICAgICAgYm9keS5tYWtlUmV0dXJuKHJ2YXIpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuZ3VhcmQpIHtcbiAgICAgICAgaWYgKGJvZHkuZXhwcmVzc2lvbnMubGVuZ3RoID4gMSkge1xuICAgICAgICAgIGJvZHkuZXhwcmVzc2lvbnMudW5zaGlmdChuZXcgSWYoKG5ldyBQYXJlbnModGhpcy5ndWFyZCkpLmludmVydCgpLCBuZXcgTGl0ZXJhbChcImNvbnRpbnVlXCIpKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHRoaXMuZ3VhcmQpIHtcbiAgICAgICAgICAgIGJvZHkgPSBCbG9jay53cmFwKFtuZXcgSWYodGhpcy5ndWFyZCwgYm9keSldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnBhdHRlcm4pIHtcbiAgICAgICAgYm9keS5leHByZXNzaW9ucy51bnNoaWZ0KG5ldyBBc3NpZ24odGhpcy5uYW1lLCBuZXcgTGl0ZXJhbChcIlwiICsgc3ZhciArIFwiW1wiICsga3ZhciArIFwiXVwiKSkpO1xuICAgICAgfVxuICAgICAgZGVmUGFydEZyYWdtZW50cyA9IFtdLmNvbmNhdCh0aGlzLm1ha2VDb2RlKGRlZlBhcnQpLCB0aGlzLnBsdWNrRGlyZWN0Q2FsbChvLCBib2R5KSk7XG4gICAgICBpZiAobmFtZVBhcnQpIHtcbiAgICAgICAgdmFyUGFydCA9IFwiXFxuXCIgKyBpZHQxICsgbmFtZVBhcnQgKyBcIjtcIjtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm9iamVjdCkge1xuICAgICAgICBmb3JQYXJ0RnJhZ21lbnRzID0gW3RoaXMubWFrZUNvZGUoXCJcIiArIGt2YXIgKyBcIiBpbiBcIiArIHN2YXIpXTtcbiAgICAgICAgaWYgKHRoaXMub3duKSB7XG4gICAgICAgICAgZ3VhcmRQYXJ0ID0gXCJcXG5cIiArIGlkdDEgKyBcImlmICghXCIgKyAodXRpbGl0eSgnaGFzUHJvcCcpKSArIFwiLmNhbGwoXCIgKyBzdmFyICsgXCIsIFwiICsga3ZhciArIFwiKSkgY29udGludWU7XCI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJvZHlGcmFnbWVudHMgPSBib2R5LmNvbXBpbGVUb0ZyYWdtZW50cyhtZXJnZShvLCB7XG4gICAgICAgIGluZGVudDogaWR0MVxuICAgICAgfSksIExFVkVMX1RPUCk7XG4gICAgICBpZiAoYm9keUZyYWdtZW50cyAmJiAoYm9keUZyYWdtZW50cy5sZW5ndGggPiAwKSkge1xuICAgICAgICBib2R5RnJhZ21lbnRzID0gW10uY29uY2F0KHRoaXMubWFrZUNvZGUoXCJcXG5cIiksIGJvZHlGcmFnbWVudHMsIHRoaXMubWFrZUNvZGUoXCJcXG5cIikpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtdLmNvbmNhdChkZWZQYXJ0RnJhZ21lbnRzLCB0aGlzLm1ha2VDb2RlKFwiXCIgKyAocmVzdWx0UGFydCB8fCAnJykgKyB0aGlzLnRhYiArIFwiZm9yIChcIiksIGZvclBhcnRGcmFnbWVudHMsIHRoaXMubWFrZUNvZGUoXCIpIHtcIiArIGd1YXJkUGFydCArIHZhclBhcnQpLCBib2R5RnJhZ21lbnRzLCB0aGlzLm1ha2VDb2RlKFwiXCIgKyB0aGlzLnRhYiArIFwifVwiICsgKHJldHVyblJlc3VsdCB8fCAnJykpKTtcbiAgICB9O1xuXG4gICAgRm9yLnByb3RvdHlwZS5wbHVja0RpcmVjdENhbGwgPSBmdW5jdGlvbihvLCBib2R5KSB7XG4gICAgICB2YXIgYmFzZSwgZGVmcywgZXhwciwgZm4sIGlkeCwgcmVmLCB2YWwsIF9pLCBfbGVuLCBfcmVmMiwgX3JlZjMsIF9yZWY0LCBfcmVmNSwgX3JlZjYsIF9yZWY3LCBfcmVmODtcbiAgICAgIGRlZnMgPSBbXTtcbiAgICAgIF9yZWYyID0gYm9keS5leHByZXNzaW9ucztcbiAgICAgIGZvciAoaWR4ID0gX2kgPSAwLCBfbGVuID0gX3JlZjIubGVuZ3RoOyBfaSA8IF9sZW47IGlkeCA9ICsrX2kpIHtcbiAgICAgICAgZXhwciA9IF9yZWYyW2lkeF07XG4gICAgICAgIGV4cHIgPSBleHByLnVud3JhcEFsbCgpO1xuICAgICAgICBpZiAoIShleHByIGluc3RhbmNlb2YgQ2FsbCkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB2YWwgPSAoX3JlZjMgPSBleHByLnZhcmlhYmxlKSAhPSBudWxsID8gX3JlZjMudW53cmFwQWxsKCkgOiB2b2lkIDA7XG4gICAgICAgIGlmICghKCh2YWwgaW5zdGFuY2VvZiBDb2RlKSB8fCAodmFsIGluc3RhbmNlb2YgVmFsdWUgJiYgKChfcmVmNCA9IHZhbC5iYXNlKSAhPSBudWxsID8gX3JlZjQudW53cmFwQWxsKCkgOiB2b2lkIDApIGluc3RhbmNlb2YgQ29kZSAmJiB2YWwucHJvcGVydGllcy5sZW5ndGggPT09IDEgJiYgKChfcmVmNSA9IChfcmVmNiA9IHZhbC5wcm9wZXJ0aWVzWzBdLm5hbWUpICE9IG51bGwgPyBfcmVmNi52YWx1ZSA6IHZvaWQgMCkgPT09ICdjYWxsJyB8fCBfcmVmNSA9PT0gJ2FwcGx5JykpKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZuID0gKChfcmVmNyA9IHZhbC5iYXNlKSAhPSBudWxsID8gX3JlZjcudW53cmFwQWxsKCkgOiB2b2lkIDApIHx8IHZhbDtcbiAgICAgICAgcmVmID0gbmV3IExpdGVyYWwoby5zY29wZS5mcmVlVmFyaWFibGUoJ2ZuJykpO1xuICAgICAgICBiYXNlID0gbmV3IFZhbHVlKHJlZik7XG4gICAgICAgIGlmICh2YWwuYmFzZSkge1xuICAgICAgICAgIF9yZWY4ID0gW2Jhc2UsIHZhbF0sIHZhbC5iYXNlID0gX3JlZjhbMF0sIGJhc2UgPSBfcmVmOFsxXTtcbiAgICAgICAgfVxuICAgICAgICBib2R5LmV4cHJlc3Npb25zW2lkeF0gPSBuZXcgQ2FsbChiYXNlLCBleHByLmFyZ3MpO1xuICAgICAgICBkZWZzID0gZGVmcy5jb25jYXQodGhpcy5tYWtlQ29kZSh0aGlzLnRhYiksIG5ldyBBc3NpZ24ocmVmLCBmbikuY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX1RPUCksIHRoaXMubWFrZUNvZGUoJztcXG4nKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGVmcztcbiAgICB9O1xuXG4gICAgcmV0dXJuIEZvcjtcblxuICB9KShXaGlsZSk7XG5cbiAgZXhwb3J0cy5Td2l0Y2ggPSBTd2l0Y2ggPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFN3aXRjaCwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIFN3aXRjaChzdWJqZWN0LCBjYXNlcywgb3RoZXJ3aXNlKSB7XG4gICAgICB0aGlzLnN1YmplY3QgPSBzdWJqZWN0O1xuICAgICAgdGhpcy5jYXNlcyA9IGNhc2VzO1xuICAgICAgdGhpcy5vdGhlcndpc2UgPSBvdGhlcndpc2U7XG4gICAgfVxuXG4gICAgU3dpdGNoLnByb3RvdHlwZS5jaGlsZHJlbiA9IFsnc3ViamVjdCcsICdjYXNlcycsICdvdGhlcndpc2UnXTtcblxuICAgIFN3aXRjaC5wcm90b3R5cGUuaXNTdGF0ZW1lbnQgPSBZRVM7XG5cbiAgICBTd2l0Y2gucHJvdG90eXBlLmp1bXBzID0gZnVuY3Rpb24obykge1xuICAgICAgdmFyIGJsb2NrLCBjb25kcywganVtcE5vZGUsIF9pLCBfbGVuLCBfcmVmMiwgX3JlZjMsIF9yZWY0O1xuICAgICAgaWYgKG8gPT0gbnVsbCkge1xuICAgICAgICBvID0ge1xuICAgICAgICAgIGJsb2NrOiB0cnVlXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBfcmVmMiA9IHRoaXMuY2FzZXM7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYyLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIF9yZWYzID0gX3JlZjJbX2ldLCBjb25kcyA9IF9yZWYzWzBdLCBibG9jayA9IF9yZWYzWzFdO1xuICAgICAgICBpZiAoanVtcE5vZGUgPSBibG9jay5qdW1wcyhvKSkge1xuICAgICAgICAgIHJldHVybiBqdW1wTm9kZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIChfcmVmNCA9IHRoaXMub3RoZXJ3aXNlKSAhPSBudWxsID8gX3JlZjQuanVtcHMobykgOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIFN3aXRjaC5wcm90b3R5cGUubWFrZVJldHVybiA9IGZ1bmN0aW9uKHJlcykge1xuICAgICAgdmFyIHBhaXIsIF9pLCBfbGVuLCBfcmVmMiwgX3JlZjM7XG4gICAgICBfcmVmMiA9IHRoaXMuY2FzZXM7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYyLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIHBhaXIgPSBfcmVmMltfaV07XG4gICAgICAgIHBhaXJbMV0ubWFrZVJldHVybihyZXMpO1xuICAgICAgfVxuICAgICAgaWYgKHJlcykge1xuICAgICAgICB0aGlzLm90aGVyd2lzZSB8fCAodGhpcy5vdGhlcndpc2UgPSBuZXcgQmxvY2soW25ldyBMaXRlcmFsKCd2b2lkIDAnKV0pKTtcbiAgICAgIH1cbiAgICAgIGlmICgoX3JlZjMgPSB0aGlzLm90aGVyd2lzZSkgIT0gbnVsbCkge1xuICAgICAgICBfcmVmMy5tYWtlUmV0dXJuKHJlcyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgU3dpdGNoLnByb3RvdHlwZS5jb21waWxlTm9kZSA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBibG9jaywgYm9keSwgY29uZCwgY29uZGl0aW9ucywgZXhwciwgZnJhZ21lbnRzLCBpLCBpZHQxLCBpZHQyLCBfaSwgX2osIF9sZW4sIF9sZW4xLCBfcmVmMiwgX3JlZjMsIF9yZWY0O1xuICAgICAgaWR0MSA9IG8uaW5kZW50ICsgVEFCO1xuICAgICAgaWR0MiA9IG8uaW5kZW50ID0gaWR0MSArIFRBQjtcbiAgICAgIGZyYWdtZW50cyA9IFtdLmNvbmNhdCh0aGlzLm1ha2VDb2RlKHRoaXMudGFiICsgXCJzd2l0Y2ggKFwiKSwgKHRoaXMuc3ViamVjdCA/IHRoaXMuc3ViamVjdC5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfUEFSRU4pIDogdGhpcy5tYWtlQ29kZShcImZhbHNlXCIpKSwgdGhpcy5tYWtlQ29kZShcIikge1xcblwiKSk7XG4gICAgICBfcmVmMiA9IHRoaXMuY2FzZXM7XG4gICAgICBmb3IgKGkgPSBfaSA9IDAsIF9sZW4gPSBfcmVmMi5sZW5ndGg7IF9pIDwgX2xlbjsgaSA9ICsrX2kpIHtcbiAgICAgICAgX3JlZjMgPSBfcmVmMltpXSwgY29uZGl0aW9ucyA9IF9yZWYzWzBdLCBibG9jayA9IF9yZWYzWzFdO1xuICAgICAgICBfcmVmNCA9IGZsYXR0ZW4oW2NvbmRpdGlvbnNdKTtcbiAgICAgICAgZm9yIChfaiA9IDAsIF9sZW4xID0gX3JlZjQubGVuZ3RoOyBfaiA8IF9sZW4xOyBfaisrKSB7XG4gICAgICAgICAgY29uZCA9IF9yZWY0W19qXTtcbiAgICAgICAgICBpZiAoIXRoaXMuc3ViamVjdCkge1xuICAgICAgICAgICAgY29uZCA9IGNvbmQuaW52ZXJ0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZyYWdtZW50cyA9IGZyYWdtZW50cy5jb25jYXQodGhpcy5tYWtlQ29kZShpZHQxICsgXCJjYXNlIFwiKSwgY29uZC5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfUEFSRU4pLCB0aGlzLm1ha2VDb2RlKFwiOlxcblwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKChib2R5ID0gYmxvY2suY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX1RPUCkpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBmcmFnbWVudHMgPSBmcmFnbWVudHMuY29uY2F0KGJvZHksIHRoaXMubWFrZUNvZGUoJ1xcbicpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gdGhpcy5jYXNlcy5sZW5ndGggLSAxICYmICF0aGlzLm90aGVyd2lzZSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGV4cHIgPSB0aGlzLmxhc3ROb25Db21tZW50KGJsb2NrLmV4cHJlc3Npb25zKTtcbiAgICAgICAgaWYgKGV4cHIgaW5zdGFuY2VvZiBSZXR1cm4gfHwgKGV4cHIgaW5zdGFuY2VvZiBMaXRlcmFsICYmIGV4cHIuanVtcHMoKSAmJiBleHByLnZhbHVlICE9PSAnZGVidWdnZXInKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZyYWdtZW50cy5wdXNoKGNvbmQubWFrZUNvZGUoaWR0MiArICdicmVhaztcXG4nKSk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5vdGhlcndpc2UgJiYgdGhpcy5vdGhlcndpc2UuZXhwcmVzc2lvbnMubGVuZ3RoKSB7XG4gICAgICAgIGZyYWdtZW50cy5wdXNoLmFwcGx5KGZyYWdtZW50cywgW3RoaXMubWFrZUNvZGUoaWR0MSArIFwiZGVmYXVsdDpcXG5cIildLmNvbmNhdChfX3NsaWNlLmNhbGwodGhpcy5vdGhlcndpc2UuY29tcGlsZVRvRnJhZ21lbnRzKG8sIExFVkVMX1RPUCkpLCBbdGhpcy5tYWtlQ29kZShcIlxcblwiKV0pKTtcbiAgICAgIH1cbiAgICAgIGZyYWdtZW50cy5wdXNoKHRoaXMubWFrZUNvZGUodGhpcy50YWIgKyAnfScpKTtcbiAgICAgIHJldHVybiBmcmFnbWVudHM7XG4gICAgfTtcblxuICAgIHJldHVybiBTd2l0Y2g7XG5cbiAgfSkoQmFzZSk7XG5cbiAgZXhwb3J0cy5JZiA9IElmID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhJZiwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIElmKGNvbmRpdGlvbiwgYm9keSwgb3B0aW9ucykge1xuICAgICAgdGhpcy5ib2R5ID0gYm9keTtcbiAgICAgIGlmIChvcHRpb25zID09IG51bGwpIHtcbiAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgfVxuICAgICAgdGhpcy5jb25kaXRpb24gPSBvcHRpb25zLnR5cGUgPT09ICd1bmxlc3MnID8gY29uZGl0aW9uLmludmVydCgpIDogY29uZGl0aW9uO1xuICAgICAgdGhpcy5lbHNlQm9keSA9IG51bGw7XG4gICAgICB0aGlzLmlzQ2hhaW4gPSBmYWxzZTtcbiAgICAgIHRoaXMuc29hayA9IG9wdGlvbnMuc29haztcbiAgICB9XG5cbiAgICBJZi5wcm90b3R5cGUuY2hpbGRyZW4gPSBbJ2NvbmRpdGlvbicsICdib2R5JywgJ2Vsc2VCb2R5J107XG5cbiAgICBJZi5wcm90b3R5cGUuYm9keU5vZGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBfcmVmMjtcbiAgICAgIHJldHVybiAoX3JlZjIgPSB0aGlzLmJvZHkpICE9IG51bGwgPyBfcmVmMi51bndyYXAoKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgSWYucHJvdG90eXBlLmVsc2VCb2R5Tm9kZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIF9yZWYyO1xuICAgICAgcmV0dXJuIChfcmVmMiA9IHRoaXMuZWxzZUJvZHkpICE9IG51bGwgPyBfcmVmMi51bndyYXAoKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgSWYucHJvdG90eXBlLmFkZEVsc2UgPSBmdW5jdGlvbihlbHNlQm9keSkge1xuICAgICAgaWYgKHRoaXMuaXNDaGFpbikge1xuICAgICAgICB0aGlzLmVsc2VCb2R5Tm9kZSgpLmFkZEVsc2UoZWxzZUJvZHkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pc0NoYWluID0gZWxzZUJvZHkgaW5zdGFuY2VvZiBJZjtcbiAgICAgICAgdGhpcy5lbHNlQm9keSA9IHRoaXMuZW5zdXJlQmxvY2soZWxzZUJvZHkpO1xuICAgICAgICB0aGlzLmVsc2VCb2R5LnVwZGF0ZUxvY2F0aW9uRGF0YUlmTWlzc2luZyhlbHNlQm9keS5sb2NhdGlvbkRhdGEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIElmLnByb3RvdHlwZS5pc1N0YXRlbWVudCA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBfcmVmMjtcbiAgICAgIHJldHVybiAobyAhPSBudWxsID8gby5sZXZlbCA6IHZvaWQgMCkgPT09IExFVkVMX1RPUCB8fCB0aGlzLmJvZHlOb2RlKCkuaXNTdGF0ZW1lbnQobykgfHwgKChfcmVmMiA9IHRoaXMuZWxzZUJvZHlOb2RlKCkpICE9IG51bGwgPyBfcmVmMi5pc1N0YXRlbWVudChvKSA6IHZvaWQgMCk7XG4gICAgfTtcblxuICAgIElmLnByb3RvdHlwZS5qdW1wcyA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBfcmVmMjtcbiAgICAgIHJldHVybiB0aGlzLmJvZHkuanVtcHMobykgfHwgKChfcmVmMiA9IHRoaXMuZWxzZUJvZHkpICE9IG51bGwgPyBfcmVmMi5qdW1wcyhvKSA6IHZvaWQgMCk7XG4gICAgfTtcblxuICAgIElmLnByb3RvdHlwZS5jb21waWxlTm9kZSA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIGlmICh0aGlzLmlzU3RhdGVtZW50KG8pKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbXBpbGVTdGF0ZW1lbnQobyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21waWxlRXhwcmVzc2lvbihvKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgSWYucHJvdG90eXBlLm1ha2VSZXR1cm4gPSBmdW5jdGlvbihyZXMpIHtcbiAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgdGhpcy5lbHNlQm9keSB8fCAodGhpcy5lbHNlQm9keSA9IG5ldyBCbG9jayhbbmV3IExpdGVyYWwoJ3ZvaWQgMCcpXSkpO1xuICAgICAgfVxuICAgICAgdGhpcy5ib2R5ICYmICh0aGlzLmJvZHkgPSBuZXcgQmxvY2soW3RoaXMuYm9keS5tYWtlUmV0dXJuKHJlcyldKSk7XG4gICAgICB0aGlzLmVsc2VCb2R5ICYmICh0aGlzLmVsc2VCb2R5ID0gbmV3IEJsb2NrKFt0aGlzLmVsc2VCb2R5Lm1ha2VSZXR1cm4ocmVzKV0pKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBJZi5wcm90b3R5cGUuZW5zdXJlQmxvY2sgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIEJsb2NrKSB7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBCbG9jayhbbm9kZV0pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBJZi5wcm90b3R5cGUuY29tcGlsZVN0YXRlbWVudCA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBhbnN3ZXIsIGJvZHksIGNoaWxkLCBjb25kLCBleGVxLCBpZlBhcnQsIGluZGVudDtcbiAgICAgIGNoaWxkID0gZGVsKG8sICdjaGFpbkNoaWxkJyk7XG4gICAgICBleGVxID0gZGVsKG8sICdpc0V4aXN0ZW50aWFsRXF1YWxzJyk7XG4gICAgICBpZiAoZXhlcSkge1xuICAgICAgICByZXR1cm4gbmV3IElmKHRoaXMuY29uZGl0aW9uLmludmVydCgpLCB0aGlzLmVsc2VCb2R5Tm9kZSgpLCB7XG4gICAgICAgICAgdHlwZTogJ2lmJ1xuICAgICAgICB9KS5jb21waWxlVG9GcmFnbWVudHMobyk7XG4gICAgICB9XG4gICAgICBpbmRlbnQgPSBvLmluZGVudCArIFRBQjtcbiAgICAgIGNvbmQgPSB0aGlzLmNvbmRpdGlvbi5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfUEFSRU4pO1xuICAgICAgYm9keSA9IHRoaXMuZW5zdXJlQmxvY2sodGhpcy5ib2R5KS5jb21waWxlVG9GcmFnbWVudHMobWVyZ2Uobywge1xuICAgICAgICBpbmRlbnQ6IGluZGVudFxuICAgICAgfSkpO1xuICAgICAgaWZQYXJ0ID0gW10uY29uY2F0KHRoaXMubWFrZUNvZGUoXCJpZiAoXCIpLCBjb25kLCB0aGlzLm1ha2VDb2RlKFwiKSB7XFxuXCIpLCBib2R5LCB0aGlzLm1ha2VDb2RlKFwiXFxuXCIgKyB0aGlzLnRhYiArIFwifVwiKSk7XG4gICAgICBpZiAoIWNoaWxkKSB7XG4gICAgICAgIGlmUGFydC51bnNoaWZ0KHRoaXMubWFrZUNvZGUodGhpcy50YWIpKTtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5lbHNlQm9keSkge1xuICAgICAgICByZXR1cm4gaWZQYXJ0O1xuICAgICAgfVxuICAgICAgYW5zd2VyID0gaWZQYXJ0LmNvbmNhdCh0aGlzLm1ha2VDb2RlKCcgZWxzZSAnKSk7XG4gICAgICBpZiAodGhpcy5pc0NoYWluKSB7XG4gICAgICAgIG8uY2hhaW5DaGlsZCA9IHRydWU7XG4gICAgICAgIGFuc3dlciA9IGFuc3dlci5jb25jYXQodGhpcy5lbHNlQm9keS51bndyYXAoKS5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfVE9QKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhbnN3ZXIgPSBhbnN3ZXIuY29uY2F0KHRoaXMubWFrZUNvZGUoXCJ7XFxuXCIpLCB0aGlzLmVsc2VCb2R5LmNvbXBpbGVUb0ZyYWdtZW50cyhtZXJnZShvLCB7XG4gICAgICAgICAgaW5kZW50OiBpbmRlbnRcbiAgICAgICAgfSksIExFVkVMX1RPUCksIHRoaXMubWFrZUNvZGUoXCJcXG5cIiArIHRoaXMudGFiICsgXCJ9XCIpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgfTtcblxuICAgIElmLnByb3RvdHlwZS5jb21waWxlRXhwcmVzc2lvbiA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgIHZhciBhbHQsIGJvZHksIGNvbmQsIGZyYWdtZW50cztcbiAgICAgIGNvbmQgPSB0aGlzLmNvbmRpdGlvbi5jb21waWxlVG9GcmFnbWVudHMobywgTEVWRUxfQ09ORCk7XG4gICAgICBib2R5ID0gdGhpcy5ib2R5Tm9kZSgpLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9MSVNUKTtcbiAgICAgIGFsdCA9IHRoaXMuZWxzZUJvZHlOb2RlKCkgPyB0aGlzLmVsc2VCb2R5Tm9kZSgpLmNvbXBpbGVUb0ZyYWdtZW50cyhvLCBMRVZFTF9MSVNUKSA6IFt0aGlzLm1ha2VDb2RlKCd2b2lkIDAnKV07XG4gICAgICBmcmFnbWVudHMgPSBjb25kLmNvbmNhdCh0aGlzLm1ha2VDb2RlKFwiID8gXCIpLCBib2R5LCB0aGlzLm1ha2VDb2RlKFwiIDogXCIpLCBhbHQpO1xuICAgICAgaWYgKG8ubGV2ZWwgPj0gTEVWRUxfQ09ORCkge1xuICAgICAgICByZXR1cm4gdGhpcy53cmFwSW5CcmFjZXMoZnJhZ21lbnRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmcmFnbWVudHM7XG4gICAgICB9XG4gICAgfTtcblxuICAgIElmLnByb3RvdHlwZS51bmZvbGRTb2FrID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5zb2FrICYmIHRoaXM7XG4gICAgfTtcblxuICAgIHJldHVybiBJZjtcblxuICB9KShCYXNlKTtcblxuICBVVElMSVRJRVMgPSB7XG4gICAgXCJleHRlbmRzXCI6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIFwiZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChcIiArICh1dGlsaXR5KCdoYXNQcm9wJykpICsgXCIuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH1cIjtcbiAgICB9LFxuICAgIGJpbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuICdmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9JztcbiAgICB9LFxuICAgIGluZGV4T2Y6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIFwiW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH1cIjtcbiAgICB9LFxuICAgIG1vZHVsbzogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gXCJmdW5jdGlvbihhLCBiKSB7IHJldHVybiAoK2EgJSAoYiA9ICtiKSArIGIpICUgYjsgfVwiO1xuICAgIH0sXG4gICAgaGFzUHJvcDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gJ3t9Lmhhc093blByb3BlcnR5JztcbiAgICB9LFxuICAgIHNsaWNlOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAnW10uc2xpY2UnO1xuICAgIH1cbiAgfTtcblxuICBMRVZFTF9UT1AgPSAxO1xuXG4gIExFVkVMX1BBUkVOID0gMjtcblxuICBMRVZFTF9MSVNUID0gMztcblxuICBMRVZFTF9DT05EID0gNDtcblxuICBMRVZFTF9PUCA9IDU7XG5cbiAgTEVWRUxfQUNDRVNTID0gNjtcblxuICBUQUIgPSAnICAnO1xuXG4gIElERU5USUZJRVJfU1RSID0gXCJbJEEtWmEtel9cXFxceDdmLVxcXFx1ZmZmZl1bJFxcXFx3XFxcXHg3Zi1cXFxcdWZmZmZdKlwiO1xuXG4gIElERU5USUZJRVIgPSBSZWdFeHAoXCJeXCIgKyBJREVOVElGSUVSX1NUUiArIFwiJFwiKTtcblxuICBTSU1QTEVOVU0gPSAvXlsrLV0/XFxkKyQvO1xuXG4gIEhFWE5VTSA9IC9eWystXT8weFtcXGRhLWZdKy9pO1xuXG4gIE5VTUJFUiA9IC9eWystXT8oPzoweFtcXGRhLWZdK3xcXGQqXFwuP1xcZCsoPzplWystXT9cXGQrKT8pJC9pO1xuXG4gIE1FVEhPRF9ERUYgPSBSZWdFeHAoXCJeKFwiICsgSURFTlRJRklFUl9TVFIgKyBcIikoXFxcXC5wcm90b3R5cGUpPyg/OlxcXFwuKFwiICsgSURFTlRJRklFUl9TVFIgKyBcIil8XFxcXFsoXFxcIig/OlteXFxcXFxcXFxcXFwiXFxcXHJcXFxcbl18XFxcXFxcXFwuKSpcXFwifCcoPzpbXlxcXFxcXFxcJ1xcXFxyXFxcXG5dfFxcXFxcXFxcLikqJylcXFxcXXxcXFxcWygweFtcXFxcZGEtZkEtRl0rfFxcXFxkKlxcXFwuP1xcXFxkKyg/OltlRV1bKy1dP1xcXFxkKyk/KVxcXFxdKSRcIik7XG5cbiAgSVNfU1RSSU5HID0gL15bJ1wiXS87XG5cbiAgSVNfUkVHRVggPSAvXlxcLy87XG5cbiAgdXRpbGl0eSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgcmVmO1xuICAgIHJlZiA9IFwiX19cIiArIG5hbWU7XG4gICAgU2NvcGUucm9vdC5hc3NpZ24ocmVmLCBVVElMSVRJRVNbbmFtZV0oKSk7XG4gICAgcmV0dXJuIHJlZjtcbiAgfTtcblxuICBtdWx0aWRlbnQgPSBmdW5jdGlvbihjb2RlLCB0YWIpIHtcbiAgICBjb2RlID0gY29kZS5yZXBsYWNlKC9cXG4vZywgJyQmJyArIHRhYik7XG4gICAgcmV0dXJuIGNvZGUucmVwbGFjZSgvXFxzKyQvLCAnJyk7XG4gIH07XG5cbiAgcGFyc2VOdW0gPSBmdW5jdGlvbih4KSB7XG4gICAgaWYgKHggPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIGlmICh4Lm1hdGNoKEhFWE5VTSkpIHtcbiAgICAgIHJldHVybiBwYXJzZUludCh4LCAxNik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBwYXJzZUZsb2F0KHgpO1xuICAgIH1cbiAgfTtcblxuICBpc0xpdGVyYWxBcmd1bWVudHMgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBMaXRlcmFsICYmIG5vZGUudmFsdWUgPT09ICdhcmd1bWVudHMnICYmICFub2RlLmFzS2V5O1xuICB9O1xuXG4gIGlzTGl0ZXJhbFRoaXMgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgcmV0dXJuIChub2RlIGluc3RhbmNlb2YgTGl0ZXJhbCAmJiBub2RlLnZhbHVlID09PSAndGhpcycgJiYgIW5vZGUuYXNLZXkpIHx8IChub2RlIGluc3RhbmNlb2YgQ29kZSAmJiBub2RlLmJvdW5kKSB8fCAobm9kZSBpbnN0YW5jZW9mIENhbGwgJiYgbm9kZS5pc1N1cGVyKTtcbiAgfTtcblxuICB1bmZvbGRTb2FrID0gZnVuY3Rpb24obywgcGFyZW50LCBuYW1lKSB7XG4gICAgdmFyIGlmbjtcbiAgICBpZiAoIShpZm4gPSBwYXJlbnRbbmFtZV0udW5mb2xkU29hayhvKSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcGFyZW50W25hbWVdID0gaWZuLmJvZHk7XG4gICAgaWZuLmJvZHkgPSBuZXcgVmFsdWUocGFyZW50KTtcbiAgICByZXR1cm4gaWZuO1xuICB9O1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiKGZ1bmN0aW9uIChwcm9jZXNzKXtcbi8qIHBhcnNlciBnZW5lcmF0ZWQgYnkgamlzb24gMC40LjEzICovXG4vKlxuICBSZXR1cm5zIGEgUGFyc2VyIG9iamVjdCBvZiB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcblxuICBQYXJzZXI6IHtcbiAgICB5eToge31cbiAgfVxuXG4gIFBhcnNlci5wcm90b3R5cGU6IHtcbiAgICB5eToge30sXG4gICAgdHJhY2U6IGZ1bmN0aW9uKCksXG4gICAgc3ltYm9sc186IHthc3NvY2lhdGl2ZSBsaXN0OiBuYW1lID09PiBudW1iZXJ9LFxuICAgIHRlcm1pbmFsc186IHthc3NvY2lhdGl2ZSBsaXN0OiBudW1iZXIgPT0+IG5hbWV9LFxuICAgIHByb2R1Y3Rpb25zXzogWy4uLl0sXG4gICAgcGVyZm9ybUFjdGlvbjogZnVuY3Rpb24gYW5vbnltb3VzKHl5dGV4dCwgeXlsZW5nLCB5eWxpbmVubywgeXksIHl5c3RhdGUsICQkLCBfJCksXG4gICAgdGFibGU6IFsuLi5dLFxuICAgIGRlZmF1bHRBY3Rpb25zOiB7Li4ufSxcbiAgICBwYXJzZUVycm9yOiBmdW5jdGlvbihzdHIsIGhhc2gpLFxuICAgIHBhcnNlOiBmdW5jdGlvbihpbnB1dCksXG5cbiAgICBsZXhlcjoge1xuICAgICAgICBFT0Y6IDEsXG4gICAgICAgIHBhcnNlRXJyb3I6IGZ1bmN0aW9uKHN0ciwgaGFzaCksXG4gICAgICAgIHNldElucHV0OiBmdW5jdGlvbihpbnB1dCksXG4gICAgICAgIGlucHV0OiBmdW5jdGlvbigpLFxuICAgICAgICB1bnB1dDogZnVuY3Rpb24oc3RyKSxcbiAgICAgICAgbW9yZTogZnVuY3Rpb24oKSxcbiAgICAgICAgbGVzczogZnVuY3Rpb24obiksXG4gICAgICAgIHBhc3RJbnB1dDogZnVuY3Rpb24oKSxcbiAgICAgICAgdXBjb21pbmdJbnB1dDogZnVuY3Rpb24oKSxcbiAgICAgICAgc2hvd1Bvc2l0aW9uOiBmdW5jdGlvbigpLFxuICAgICAgICB0ZXN0X21hdGNoOiBmdW5jdGlvbihyZWdleF9tYXRjaF9hcnJheSwgcnVsZV9pbmRleCksXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uKCksXG4gICAgICAgIGxleDogZnVuY3Rpb24oKSxcbiAgICAgICAgYmVnaW46IGZ1bmN0aW9uKGNvbmRpdGlvbiksXG4gICAgICAgIHBvcFN0YXRlOiBmdW5jdGlvbigpLFxuICAgICAgICBfY3VycmVudFJ1bGVzOiBmdW5jdGlvbigpLFxuICAgICAgICB0b3BTdGF0ZTogZnVuY3Rpb24oKSxcbiAgICAgICAgcHVzaFN0YXRlOiBmdW5jdGlvbihjb25kaXRpb24pLFxuXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgIHJhbmdlczogYm9vbGVhbiAgICAgICAgICAgKG9wdGlvbmFsOiB0cnVlID09PiB0b2tlbiBsb2NhdGlvbiBpbmZvIHdpbGwgaW5jbHVkZSBhIC5yYW5nZVtdIG1lbWJlcilcbiAgICAgICAgICAgIGZsZXg6IGJvb2xlYW4gICAgICAgICAgICAgKG9wdGlvbmFsOiB0cnVlID09PiBmbGV4LWxpa2UgbGV4aW5nIGJlaGF2aW91ciB3aGVyZSB0aGUgcnVsZXMgYXJlIHRlc3RlZCBleGhhdXN0aXZlbHkgdG8gZmluZCB0aGUgbG9uZ2VzdCBtYXRjaClcbiAgICAgICAgICAgIGJhY2t0cmFja19sZXhlcjogYm9vbGVhbiAgKG9wdGlvbmFsOiB0cnVlID09PiBsZXhlciByZWdleGVzIGFyZSB0ZXN0ZWQgaW4gb3JkZXIgYW5kIGZvciBlYWNoIG1hdGNoaW5nIHJlZ2V4IHRoZSBhY3Rpb24gY29kZSBpcyBpbnZva2VkOyB0aGUgbGV4ZXIgdGVybWluYXRlcyB0aGUgc2NhbiB3aGVuIGEgdG9rZW4gaXMgcmV0dXJuZWQgYnkgdGhlIGFjdGlvbiBjb2RlKVxuICAgICAgICB9LFxuXG4gICAgICAgIHBlcmZvcm1BY3Rpb246IGZ1bmN0aW9uKHl5LCB5eV8sICRhdm9pZGluZ19uYW1lX2NvbGxpc2lvbnMsIFlZX1NUQVJUKSxcbiAgICAgICAgcnVsZXM6IFsuLi5dLFxuICAgICAgICBjb25kaXRpb25zOiB7YXNzb2NpYXRpdmUgbGlzdDogbmFtZSA9PT4gc2V0fSxcbiAgICB9XG4gIH1cblxuXG4gIHRva2VuIGxvY2F0aW9uIGluZm8gKEAkLCBfJCwgZXRjLik6IHtcbiAgICBmaXJzdF9saW5lOiBuLFxuICAgIGxhc3RfbGluZTogbixcbiAgICBmaXJzdF9jb2x1bW46IG4sXG4gICAgbGFzdF9jb2x1bW46IG4sXG4gICAgcmFuZ2U6IFtzdGFydF9udW1iZXIsIGVuZF9udW1iZXJdICAgICAgICh3aGVyZSB0aGUgbnVtYmVycyBhcmUgaW5kZXhlcyBpbnRvIHRoZSBpbnB1dCBzdHJpbmcsIHJlZ3VsYXIgemVyby1iYXNlZClcbiAgfVxuXG5cbiAgdGhlIHBhcnNlRXJyb3IgZnVuY3Rpb24gcmVjZWl2ZXMgYSAnaGFzaCcgb2JqZWN0IHdpdGggdGhlc2UgbWVtYmVycyBmb3IgbGV4ZXIgYW5kIHBhcnNlciBlcnJvcnM6IHtcbiAgICB0ZXh0OiAgICAgICAgKG1hdGNoZWQgdGV4dClcbiAgICB0b2tlbjogICAgICAgKHRoZSBwcm9kdWNlZCB0ZXJtaW5hbCB0b2tlbiwgaWYgYW55KVxuICAgIGxpbmU6ICAgICAgICAoeXlsaW5lbm8pXG4gIH1cbiAgd2hpbGUgcGFyc2VyIChncmFtbWFyKSBlcnJvcnMgd2lsbCBhbHNvIHByb3ZpZGUgdGhlc2UgbWVtYmVycywgaS5lLiBwYXJzZXIgZXJyb3JzIGRlbGl2ZXIgYSBzdXBlcnNldCBvZiBhdHRyaWJ1dGVzOiB7XG4gICAgbG9jOiAgICAgICAgICh5eWxsb2MpXG4gICAgZXhwZWN0ZWQ6ICAgIChzdHJpbmcgZGVzY3JpYmluZyB0aGUgc2V0IG9mIGV4cGVjdGVkIHRva2VucylcbiAgICByZWNvdmVyYWJsZTogKGJvb2xlYW46IFRSVUUgd2hlbiB0aGUgcGFyc2VyIGhhcyBhIGVycm9yIHJlY292ZXJ5IHJ1bGUgYXZhaWxhYmxlIGZvciB0aGlzIHBhcnRpY3VsYXIgZXJyb3IpXG4gIH1cbiovXG52YXIgcGFyc2VyID0gKGZ1bmN0aW9uKCl7XG52YXIgcGFyc2VyID0ge3RyYWNlOiBmdW5jdGlvbiB0cmFjZSgpIHsgfSxcbnl5OiB7fSxcbnN5bWJvbHNfOiB7XCJlcnJvclwiOjIsXCJSb290XCI6MyxcIkJvZHlcIjo0LFwiTGluZVwiOjUsXCJURVJNSU5BVE9SXCI6NixcIkV4cHJlc3Npb25cIjo3LFwiU3RhdGVtZW50XCI6OCxcIlJldHVyblwiOjksXCJDb21tZW50XCI6MTAsXCJTVEFURU1FTlRcIjoxMSxcIlZhbHVlXCI6MTIsXCJJbnZvY2F0aW9uXCI6MTMsXCJDb2RlXCI6MTQsXCJPcGVyYXRpb25cIjoxNSxcIkFzc2lnblwiOjE2LFwiSWZcIjoxNyxcIlRyeVwiOjE4LFwiV2hpbGVcIjoxOSxcIkZvclwiOjIwLFwiU3dpdGNoXCI6MjEsXCJDbGFzc1wiOjIyLFwiVGhyb3dcIjoyMyxcIkJsb2NrXCI6MjQsXCJJTkRFTlRcIjoyNSxcIk9VVERFTlRcIjoyNixcIklkZW50aWZpZXJcIjoyNyxcIklERU5USUZJRVJcIjoyOCxcIkFscGhhTnVtZXJpY1wiOjI5LFwiTlVNQkVSXCI6MzAsXCJTVFJJTkdcIjozMSxcIkxpdGVyYWxcIjozMixcIkpTXCI6MzMsXCJSRUdFWFwiOjM0LFwiREVCVUdHRVJcIjozNSxcIlVOREVGSU5FRFwiOjM2LFwiTlVMTFwiOjM3LFwiQk9PTFwiOjM4LFwiQXNzaWduYWJsZVwiOjM5LFwiPVwiOjQwLFwiQXNzaWduT2JqXCI6NDEsXCJPYmpBc3NpZ25hYmxlXCI6NDIsXCI6XCI6NDMsXCJUaGlzUHJvcGVydHlcIjo0NCxcIlJFVFVSTlwiOjQ1LFwiSEVSRUNPTU1FTlRcIjo0NixcIlBBUkFNX1NUQVJUXCI6NDcsXCJQYXJhbUxpc3RcIjo0OCxcIlBBUkFNX0VORFwiOjQ5LFwiRnVuY0dseXBoXCI6NTAsXCItPlwiOjUxLFwiPT5cIjo1MixcIk9wdENvbW1hXCI6NTMsXCIsXCI6NTQsXCJQYXJhbVwiOjU1LFwiUGFyYW1WYXJcIjo1NixcIi4uLlwiOjU3LFwiQXJyYXlcIjo1OCxcIk9iamVjdFwiOjU5LFwiU3BsYXRcIjo2MCxcIlNpbXBsZUFzc2lnbmFibGVcIjo2MSxcIkFjY2Vzc29yXCI6NjIsXCJQYXJlbnRoZXRpY2FsXCI6NjMsXCJSYW5nZVwiOjY0LFwiVGhpc1wiOjY1LFwiLlwiOjY2LFwiPy5cIjo2NyxcIjo6XCI6NjgsXCI/OjpcIjo2OSxcIkluZGV4XCI6NzAsXCJJTkRFWF9TVEFSVFwiOjcxLFwiSW5kZXhWYWx1ZVwiOjcyLFwiSU5ERVhfRU5EXCI6NzMsXCJJTkRFWF9TT0FLXCI6NzQsXCJTbGljZVwiOjc1LFwie1wiOjc2LFwiQXNzaWduTGlzdFwiOjc3LFwifVwiOjc4LFwiQ0xBU1NcIjo3OSxcIkVYVEVORFNcIjo4MCxcIk9wdEZ1bmNFeGlzdFwiOjgxLFwiQXJndW1lbnRzXCI6ODIsXCJTVVBFUlwiOjgzLFwiRlVOQ19FWElTVFwiOjg0LFwiQ0FMTF9TVEFSVFwiOjg1LFwiQ0FMTF9FTkRcIjo4NixcIkFyZ0xpc3RcIjo4NyxcIlRISVNcIjo4OCxcIkBcIjo4OSxcIltcIjo5MCxcIl1cIjo5MSxcIlJhbmdlRG90c1wiOjkyLFwiLi5cIjo5MyxcIkFyZ1wiOjk0LFwiU2ltcGxlQXJnc1wiOjk1LFwiVFJZXCI6OTYsXCJDYXRjaFwiOjk3LFwiRklOQUxMWVwiOjk4LFwiQ0FUQ0hcIjo5OSxcIlRIUk9XXCI6MTAwLFwiKFwiOjEwMSxcIilcIjoxMDIsXCJXaGlsZVNvdXJjZVwiOjEwMyxcIldISUxFXCI6MTA0LFwiV0hFTlwiOjEwNSxcIlVOVElMXCI6MTA2LFwiTG9vcFwiOjEwNyxcIkxPT1BcIjoxMDgsXCJGb3JCb2R5XCI6MTA5LFwiRk9SXCI6MTEwLFwiRm9yU3RhcnRcIjoxMTEsXCJGb3JTb3VyY2VcIjoxMTIsXCJGb3JWYXJpYWJsZXNcIjoxMTMsXCJPV05cIjoxMTQsXCJGb3JWYWx1ZVwiOjExNSxcIkZPUklOXCI6MTE2LFwiRk9ST0ZcIjoxMTcsXCJCWVwiOjExOCxcIlNXSVRDSFwiOjExOSxcIldoZW5zXCI6MTIwLFwiRUxTRVwiOjEyMSxcIldoZW5cIjoxMjIsXCJMRUFESU5HX1dIRU5cIjoxMjMsXCJJZkJsb2NrXCI6MTI0LFwiSUZcIjoxMjUsXCJQT1NUX0lGXCI6MTI2LFwiVU5BUllcIjoxMjcsXCJVTkFSWV9NQVRIXCI6MTI4LFwiLVwiOjEyOSxcIitcIjoxMzAsXCItLVwiOjEzMSxcIisrXCI6MTMyLFwiP1wiOjEzMyxcIk1BVEhcIjoxMzQsXCIqKlwiOjEzNSxcIlNISUZUXCI6MTM2LFwiQ09NUEFSRVwiOjEzNyxcIkxPR0lDXCI6MTM4LFwiUkVMQVRJT05cIjoxMzksXCJDT01QT1VORF9BU1NJR05cIjoxNDAsXCIkYWNjZXB0XCI6MCxcIiRlbmRcIjoxfSxcbnRlcm1pbmFsc186IHsyOlwiZXJyb3JcIiw2OlwiVEVSTUlOQVRPUlwiLDExOlwiU1RBVEVNRU5UXCIsMjU6XCJJTkRFTlRcIiwyNjpcIk9VVERFTlRcIiwyODpcIklERU5USUZJRVJcIiwzMDpcIk5VTUJFUlwiLDMxOlwiU1RSSU5HXCIsMzM6XCJKU1wiLDM0OlwiUkVHRVhcIiwzNTpcIkRFQlVHR0VSXCIsMzY6XCJVTkRFRklORURcIiwzNzpcIk5VTExcIiwzODpcIkJPT0xcIiw0MDpcIj1cIiw0MzpcIjpcIiw0NTpcIlJFVFVSTlwiLDQ2OlwiSEVSRUNPTU1FTlRcIiw0NzpcIlBBUkFNX1NUQVJUXCIsNDk6XCJQQVJBTV9FTkRcIiw1MTpcIi0+XCIsNTI6XCI9PlwiLDU0OlwiLFwiLDU3OlwiLi4uXCIsNjY6XCIuXCIsNjc6XCI/LlwiLDY4OlwiOjpcIiw2OTpcIj86OlwiLDcxOlwiSU5ERVhfU1RBUlRcIiw3MzpcIklOREVYX0VORFwiLDc0OlwiSU5ERVhfU09BS1wiLDc2Olwie1wiLDc4OlwifVwiLDc5OlwiQ0xBU1NcIiw4MDpcIkVYVEVORFNcIiw4MzpcIlNVUEVSXCIsODQ6XCJGVU5DX0VYSVNUXCIsODU6XCJDQUxMX1NUQVJUXCIsODY6XCJDQUxMX0VORFwiLDg4OlwiVEhJU1wiLDg5OlwiQFwiLDkwOlwiW1wiLDkxOlwiXVwiLDkzOlwiLi5cIiw5NjpcIlRSWVwiLDk4OlwiRklOQUxMWVwiLDk5OlwiQ0FUQ0hcIiwxMDA6XCJUSFJPV1wiLDEwMTpcIihcIiwxMDI6XCIpXCIsMTA0OlwiV0hJTEVcIiwxMDU6XCJXSEVOXCIsMTA2OlwiVU5USUxcIiwxMDg6XCJMT09QXCIsMTEwOlwiRk9SXCIsMTE0OlwiT1dOXCIsMTE2OlwiRk9SSU5cIiwxMTc6XCJGT1JPRlwiLDExODpcIkJZXCIsMTE5OlwiU1dJVENIXCIsMTIxOlwiRUxTRVwiLDEyMzpcIkxFQURJTkdfV0hFTlwiLDEyNTpcIklGXCIsMTI2OlwiUE9TVF9JRlwiLDEyNzpcIlVOQVJZXCIsMTI4OlwiVU5BUllfTUFUSFwiLDEyOTpcIi1cIiwxMzA6XCIrXCIsMTMxOlwiLS1cIiwxMzI6XCIrK1wiLDEzMzpcIj9cIiwxMzQ6XCJNQVRIXCIsMTM1OlwiKipcIiwxMzY6XCJTSElGVFwiLDEzNzpcIkNPTVBBUkVcIiwxMzg6XCJMT0dJQ1wiLDEzOTpcIlJFTEFUSU9OXCIsMTQwOlwiQ09NUE9VTkRfQVNTSUdOXCJ9LFxucHJvZHVjdGlvbnNfOiBbMCxbMywwXSxbMywxXSxbNCwxXSxbNCwzXSxbNCwyXSxbNSwxXSxbNSwxXSxbOCwxXSxbOCwxXSxbOCwxXSxbNywxXSxbNywxXSxbNywxXSxbNywxXSxbNywxXSxbNywxXSxbNywxXSxbNywxXSxbNywxXSxbNywxXSxbNywxXSxbNywxXSxbMjQsMl0sWzI0LDNdLFsyNywxXSxbMjksMV0sWzI5LDFdLFszMiwxXSxbMzIsMV0sWzMyLDFdLFszMiwxXSxbMzIsMV0sWzMyLDFdLFszMiwxXSxbMTYsM10sWzE2LDRdLFsxNiw1XSxbNDEsMV0sWzQxLDNdLFs0MSw1XSxbNDEsMV0sWzQyLDFdLFs0MiwxXSxbNDIsMV0sWzksMl0sWzksMV0sWzEwLDFdLFsxNCw1XSxbMTQsMl0sWzUwLDFdLFs1MCwxXSxbNTMsMF0sWzUzLDFdLFs0OCwwXSxbNDgsMV0sWzQ4LDNdLFs0OCw0XSxbNDgsNl0sWzU1LDFdLFs1NSwyXSxbNTUsM10sWzU1LDFdLFs1NiwxXSxbNTYsMV0sWzU2LDFdLFs1NiwxXSxbNjAsMl0sWzYxLDFdLFs2MSwyXSxbNjEsMl0sWzYxLDFdLFszOSwxXSxbMzksMV0sWzM5LDFdLFsxMiwxXSxbMTIsMV0sWzEyLDFdLFsxMiwxXSxbMTIsMV0sWzYyLDJdLFs2MiwyXSxbNjIsMl0sWzYyLDJdLFs2MiwxXSxbNjIsMV0sWzcwLDNdLFs3MCwyXSxbNzIsMV0sWzcyLDFdLFs1OSw0XSxbNzcsMF0sWzc3LDFdLFs3NywzXSxbNzcsNF0sWzc3LDZdLFsyMiwxXSxbMjIsMl0sWzIyLDNdLFsyMiw0XSxbMjIsMl0sWzIyLDNdLFsyMiw0XSxbMjIsNV0sWzEzLDNdLFsxMywzXSxbMTMsMV0sWzEzLDJdLFs4MSwwXSxbODEsMV0sWzgyLDJdLFs4Miw0XSxbNjUsMV0sWzY1LDFdLFs0NCwyXSxbNTgsMl0sWzU4LDRdLFs5MiwxXSxbOTIsMV0sWzY0LDVdLFs3NSwzXSxbNzUsMl0sWzc1LDJdLFs3NSwxXSxbODcsMV0sWzg3LDNdLFs4Nyw0XSxbODcsNF0sWzg3LDZdLFs5NCwxXSxbOTQsMV0sWzk0LDFdLFs5NSwxXSxbOTUsM10sWzE4LDJdLFsxOCwzXSxbMTgsNF0sWzE4LDVdLFs5NywzXSxbOTcsM10sWzk3LDJdLFsyMywyXSxbNjMsM10sWzYzLDVdLFsxMDMsMl0sWzEwMyw0XSxbMTAzLDJdLFsxMDMsNF0sWzE5LDJdLFsxOSwyXSxbMTksMl0sWzE5LDFdLFsxMDcsMl0sWzEwNywyXSxbMjAsMl0sWzIwLDJdLFsyMCwyXSxbMTA5LDJdLFsxMDksMl0sWzExMSwyXSxbMTExLDNdLFsxMTUsMV0sWzExNSwxXSxbMTE1LDFdLFsxMTUsMV0sWzExMywxXSxbMTEzLDNdLFsxMTIsMl0sWzExMiwyXSxbMTEyLDRdLFsxMTIsNF0sWzExMiw0XSxbMTEyLDZdLFsxMTIsNl0sWzIxLDVdLFsyMSw3XSxbMjEsNF0sWzIxLDZdLFsxMjAsMV0sWzEyMCwyXSxbMTIyLDNdLFsxMjIsNF0sWzEyNCwzXSxbMTI0LDVdLFsxNywxXSxbMTcsM10sWzE3LDNdLFsxNywzXSxbMTUsMl0sWzE1LDJdLFsxNSwyXSxbMTUsMl0sWzE1LDJdLFsxNSwyXSxbMTUsMl0sWzE1LDJdLFsxNSwyXSxbMTUsM10sWzE1LDNdLFsxNSwzXSxbMTUsM10sWzE1LDNdLFsxNSwzXSxbMTUsM10sWzE1LDNdLFsxNSwzXSxbMTUsNV0sWzE1LDRdLFsxNSwzXV0sXG5wZXJmb3JtQWN0aW9uOiBmdW5jdGlvbiBhbm9ueW1vdXMoeXl0ZXh0LCB5eWxlbmcsIHl5bGluZW5vLCB5eSwgeXlzdGF0ZSAvKiBhY3Rpb25bMV0gKi8sICQkIC8qIHZzdGFjayAqLywgXyQgLyogbHN0YWNrICovKSB7XG4vKiB0aGlzID09IHl5dmFsICovXG5cbnZhciAkMCA9ICQkLmxlbmd0aCAtIDE7XG5zd2l0Y2ggKHl5c3RhdGUpIHtcbmNhc2UgMTpyZXR1cm4gdGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKG5ldyB5eS5CbG9jayk7XG5icmVhaztcbmNhc2UgMjpyZXR1cm4gdGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDM6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKHl5LkJsb2NrLndyYXAoWyQkWyQwXV0pKTtcbmJyZWFrO1xuY2FzZSA0OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTJdLCBfJFskMF0pKCQkWyQwLTJdLnB1c2goJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgNTp0aGlzLiQgPSAkJFskMC0xXTtcbmJyZWFrO1xuY2FzZSA2OnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSA3OnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSA4OnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSA5OnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSAxMDp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkobmV3IHl5LkxpdGVyYWwoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMTE6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDEyOnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSAxMzp0aGlzLiQgPSAkJFskMF07XG5icmVhaztcbmNhc2UgMTQ6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDE1OnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSAxNjp0aGlzLiQgPSAkJFskMF07XG5icmVhaztcbmNhc2UgMTc6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDE4OnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSAxOTp0aGlzLiQgPSAkJFskMF07XG5icmVhaztcbmNhc2UgMjA6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDIxOnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSAyMjp0aGlzLiQgPSAkJFskMF07XG5icmVhaztcbmNhc2UgMjM6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5LkJsb2NrKTtcbmJyZWFrO1xuY2FzZSAyNDp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSwgXyRbJDBdKSgkJFskMC0xXSk7XG5icmVhaztcbmNhc2UgMjU6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKG5ldyB5eS5MaXRlcmFsKCQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDI2OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuTGl0ZXJhbCgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAyNzp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkobmV3IHl5LkxpdGVyYWwoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMjg6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDI5OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuTGl0ZXJhbCgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAzMDp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkobmV3IHl5LkxpdGVyYWwoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMzE6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKG5ldyB5eS5MaXRlcmFsKCQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDMyOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuVW5kZWZpbmVkKTtcbmJyZWFrO1xuY2FzZSAzMzp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkobmV3IHl5Lk51bGwpO1xuYnJlYWs7XG5jYXNlIDM0OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuQm9vbCgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAzNTp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSwgXyRbJDBdKShuZXcgeXkuQXNzaWduKCQkWyQwLTJdLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAzNjp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0zXSwgXyRbJDBdKShuZXcgeXkuQXNzaWduKCQkWyQwLTNdLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAzNzp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC00XSwgXyRbJDBdKShuZXcgeXkuQXNzaWduKCQkWyQwLTRdLCAkJFskMC0xXSkpO1xuYnJlYWs7XG5jYXNlIDM4OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuVmFsdWUoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMzk6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkobmV3IHl5LkFzc2lnbih5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSkobmV3IHl5LlZhbHVlKCQkWyQwLTJdKSksICQkWyQwXSwgJ29iamVjdCcpKTtcbmJyZWFrO1xuY2FzZSA0MDp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC00XSwgXyRbJDBdKShuZXcgeXkuQXNzaWduKHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTRdKShuZXcgeXkuVmFsdWUoJCRbJDAtNF0pKSwgJCRbJDAtMV0sICdvYmplY3QnKSk7XG5icmVhaztcbmNhc2UgNDE6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDQyOnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSA0Mzp0aGlzLiQgPSAkJFskMF07XG5icmVhaztcbmNhc2UgNDQ6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDQ1OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5SZXR1cm4oJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgNDY6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKG5ldyB5eS5SZXR1cm4pO1xuYnJlYWs7XG5jYXNlIDQ3OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuQ29tbWVudCgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSA0ODp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC00XSwgXyRbJDBdKShuZXcgeXkuQ29kZSgkJFskMC0zXSwgJCRbJDBdLCAkJFskMC0xXSkpO1xuYnJlYWs7XG5jYXNlIDQ5OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5Db2RlKFtdLCAkJFskMF0sICQkWyQwLTFdKSk7XG5icmVhaztcbmNhc2UgNTA6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKCdmdW5jJyk7XG5icmVhaztcbmNhc2UgNTE6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKCdib3VuZGZ1bmMnKTtcbmJyZWFrO1xuY2FzZSA1Mjp0aGlzLiQgPSAkJFskMF07XG5icmVhaztcbmNhc2UgNTM6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDU0OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShbXSk7XG5icmVhaztcbmNhc2UgNTU6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKFskJFskMF1dKTtcbmJyZWFrO1xuY2FzZSA1Njp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSwgXyRbJDBdKSgkJFskMC0yXS5jb25jYXQoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgNTc6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtM10sIF8kWyQwXSkoJCRbJDAtM10uY29uY2F0KCQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDU4OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTVdLCBfJFskMF0pKCQkWyQwLTVdLmNvbmNhdCgkJFskMC0yXSkpO1xuYnJlYWs7XG5jYXNlIDU5OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuUGFyYW0oJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgNjA6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5LlBhcmFtKCQkWyQwLTFdLCBudWxsLCB0cnVlKSk7XG5icmVhaztcbmNhc2UgNjE6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkobmV3IHl5LlBhcmFtKCQkWyQwLTJdLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSA2Mjp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkobmV3IHl5LkV4cGFuc2lvbik7XG5icmVhaztcbmNhc2UgNjM6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDY0OnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSA2NTp0aGlzLiQgPSAkJFskMF07XG5icmVhaztcbmNhc2UgNjY6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDY3OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5TcGxhdCgkJFskMC0xXSkpO1xuYnJlYWs7XG5jYXNlIDY4OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuVmFsdWUoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgNjk6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkoJCRbJDAtMV0uYWRkKCQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDcwOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5WYWx1ZSgkJFskMC0xXSwgW10uY29uY2F0KCQkWyQwXSkpKTtcbmJyZWFrO1xuY2FzZSA3MTp0aGlzLiQgPSAkJFskMF07XG5icmVhaztcbmNhc2UgNzI6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDczOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuVmFsdWUoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgNzQ6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKG5ldyB5eS5WYWx1ZSgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSA3NTp0aGlzLiQgPSAkJFskMF07XG5icmVhaztcbmNhc2UgNzY6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKG5ldyB5eS5WYWx1ZSgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSA3Nzp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkobmV3IHl5LlZhbHVlKCQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDc4OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuVmFsdWUoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgNzk6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDgwOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5BY2Nlc3MoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgODE6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5LkFjY2VzcygkJFskMF0sICdzb2FrJykpO1xuYnJlYWs7XG5jYXNlIDgyOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKFt5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0xXSkobmV3IHl5LkFjY2VzcyhuZXcgeXkuTGl0ZXJhbCgncHJvdG90eXBlJykpKSwgeXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdKShuZXcgeXkuQWNjZXNzKCQkWyQwXSkpXSk7XG5icmVhaztcbmNhc2UgODM6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkoW3l5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdKShuZXcgeXkuQWNjZXNzKG5ldyB5eS5MaXRlcmFsKCdwcm90b3R5cGUnKSwgJ3NvYWsnKSksIHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSkobmV3IHl5LkFjY2VzcygkJFskMF0pKV0pO1xuYnJlYWs7XG5jYXNlIDg0OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuQWNjZXNzKG5ldyB5eS5MaXRlcmFsKCdwcm90b3R5cGUnKSkpO1xuYnJlYWs7XG5jYXNlIDg1OnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSA4Njp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSwgXyRbJDBdKSgkJFskMC0xXSk7XG5icmVhaztcbmNhc2UgODc6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkoeXkuZXh0ZW5kKCQkWyQwXSwge1xuICAgICAgICAgIHNvYWs6IHRydWVcbiAgICAgICAgfSkpO1xuYnJlYWs7XG5jYXNlIDg4OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuSW5kZXgoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgODk6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKG5ldyB5eS5TbGljZSgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSA5MDp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0zXSwgXyRbJDBdKShuZXcgeXkuT2JqKCQkWyQwLTJdLCAkJFskMC0zXS5nZW5lcmF0ZWQpKTtcbmJyZWFrO1xuY2FzZSA5MTp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkoW10pO1xuYnJlYWs7XG5jYXNlIDkyOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShbJCRbJDBdXSk7XG5icmVhaztcbmNhc2UgOTM6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkoJCRbJDAtMl0uY29uY2F0KCQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDk0OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTNdLCBfJFskMF0pKCQkWyQwLTNdLmNvbmNhdCgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSA5NTp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC01XSwgXyRbJDBdKSgkJFskMC01XS5jb25jYXQoJCRbJDAtMl0pKTtcbmJyZWFrO1xuY2FzZSA5Njp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkobmV3IHl5LkNsYXNzKTtcbmJyZWFrO1xuY2FzZSA5Nzp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0xXSwgXyRbJDBdKShuZXcgeXkuQ2xhc3MobnVsbCwgbnVsbCwgJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgOTg6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkobmV3IHl5LkNsYXNzKG51bGwsICQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDk5OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTNdLCBfJFskMF0pKG5ldyB5eS5DbGFzcyhudWxsLCAkJFskMC0xXSwgJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMTAwOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5DbGFzcygkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxMDE6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkobmV3IHl5LkNsYXNzKCQkWyQwLTFdLCBudWxsLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxMDI6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtM10sIF8kWyQwXSkobmV3IHl5LkNsYXNzKCQkWyQwLTJdLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxMDM6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtNF0sIF8kWyQwXSkobmV3IHl5LkNsYXNzKCQkWyQwLTNdLCAkJFskMC0xXSwgJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMTA0OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTJdLCBfJFskMF0pKG5ldyB5eS5DYWxsKCQkWyQwLTJdLCAkJFskMF0sICQkWyQwLTFdKSk7XG5icmVhaztcbmNhc2UgMTA1OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTJdLCBfJFskMF0pKG5ldyB5eS5DYWxsKCQkWyQwLTJdLCAkJFskMF0sICQkWyQwLTFdKSk7XG5icmVhaztcbmNhc2UgMTA2OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuQ2FsbCgnc3VwZXInLCBbbmV3IHl5LlNwbGF0KG5ldyB5eS5MaXRlcmFsKCdhcmd1bWVudHMnKSldKSk7XG5icmVhaztcbmNhc2UgMTA3OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5DYWxsKCdzdXBlcicsICQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDEwODp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkoZmFsc2UpO1xuYnJlYWs7XG5jYXNlIDEwOTp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkodHJ1ZSk7XG5icmVhaztcbmNhc2UgMTEwOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKFtdKTtcbmJyZWFrO1xuY2FzZSAxMTE6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtM10sIF8kWyQwXSkoJCRbJDAtMl0pO1xuYnJlYWs7XG5jYXNlIDExMjp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkobmV3IHl5LlZhbHVlKG5ldyB5eS5MaXRlcmFsKCd0aGlzJykpKTtcbmJyZWFrO1xuY2FzZSAxMTM6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDBdLCBfJFskMF0pKG5ldyB5eS5WYWx1ZShuZXcgeXkuTGl0ZXJhbCgndGhpcycpKSk7XG5icmVhaztcbmNhc2UgMTE0OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5WYWx1ZSh5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0xXSkobmV3IHl5LkxpdGVyYWwoJ3RoaXMnKSksIFt5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0pKG5ldyB5eS5BY2Nlc3MoJCRbJDBdKSldLCAndGhpcycpKTtcbmJyZWFrO1xuY2FzZSAxMTU6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5LkFycihbXSkpO1xuYnJlYWs7XG5jYXNlIDExNjp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0zXSwgXyRbJDBdKShuZXcgeXkuQXJyKCQkWyQwLTJdKSk7XG5icmVhaztcbmNhc2UgMTE3OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKSgnaW5jbHVzaXZlJyk7XG5icmVhaztcbmNhc2UgMTE4OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKSgnZXhjbHVzaXZlJyk7XG5icmVhaztcbmNhc2UgMTE5OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTRdLCBfJFskMF0pKG5ldyB5eS5SYW5nZSgkJFskMC0zXSwgJCRbJDAtMV0sICQkWyQwLTJdKSk7XG5icmVhaztcbmNhc2UgMTIwOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTJdLCBfJFskMF0pKG5ldyB5eS5SYW5nZSgkJFskMC0yXSwgJCRbJDBdLCAkJFskMC0xXSkpO1xuYnJlYWs7XG5jYXNlIDEyMTp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0xXSwgXyRbJDBdKShuZXcgeXkuUmFuZ2UoJCRbJDAtMV0sIG51bGwsICQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDEyMjp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0xXSwgXyRbJDBdKShuZXcgeXkuUmFuZ2UobnVsbCwgJCRbJDBdLCAkJFskMC0xXSkpO1xuYnJlYWs7XG5jYXNlIDEyMzp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkobmV3IHl5LlJhbmdlKG51bGwsIG51bGwsICQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDEyNDp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkoWyQkWyQwXV0pO1xuYnJlYWs7XG5jYXNlIDEyNTp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSwgXyRbJDBdKSgkJFskMC0yXS5jb25jYXQoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMTI2OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTNdLCBfJFskMF0pKCQkWyQwLTNdLmNvbmNhdCgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxMjc6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtM10sIF8kWyQwXSkoJCRbJDAtMl0pO1xuYnJlYWs7XG5jYXNlIDEyODp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC01XSwgXyRbJDBdKSgkJFskMC01XS5jb25jYXQoJCRbJDAtMl0pKTtcbmJyZWFrO1xuY2FzZSAxMjk6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDEzMDp0aGlzLiQgPSAkJFskMF07XG5icmVhaztcbmNhc2UgMTMxOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuRXhwYW5zaW9uKTtcbmJyZWFrO1xuY2FzZSAxMzI6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDEzMzp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSwgXyRbJDBdKShbXS5jb25jYXQoJCRbJDAtMl0sICQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDEzNDp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0xXSwgXyRbJDBdKShuZXcgeXkuVHJ5KCQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDEzNTp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSwgXyRbJDBdKShuZXcgeXkuVHJ5KCQkWyQwLTFdLCAkJFskMF1bMF0sICQkWyQwXVsxXSkpO1xuYnJlYWs7XG5jYXNlIDEzNjp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0zXSwgXyRbJDBdKShuZXcgeXkuVHJ5KCQkWyQwLTJdLCBudWxsLCBudWxsLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxMzc6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtNF0sIF8kWyQwXSkobmV3IHl5LlRyeSgkJFskMC0zXSwgJCRbJDAtMl1bMF0sICQkWyQwLTJdWzFdLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxMzg6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkoWyQkWyQwLTFdLCAkJFskMF1dKTtcbmJyZWFrO1xuY2FzZSAxMzk6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkoW3l5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdKShuZXcgeXkuVmFsdWUoJCRbJDAtMV0pKSwgJCRbJDBdXSk7XG5icmVhaztcbmNhc2UgMTQwOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKFtudWxsLCAkJFskMF1dKTtcbmJyZWFrO1xuY2FzZSAxNDE6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5LlRocm93KCQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDE0Mjp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSwgXyRbJDBdKShuZXcgeXkuUGFyZW5zKCQkWyQwLTFdKSk7XG5icmVhaztcbmNhc2UgMTQzOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTRdLCBfJFskMF0pKG5ldyB5eS5QYXJlbnMoJCRbJDAtMl0pKTtcbmJyZWFrO1xuY2FzZSAxNDQ6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5LldoaWxlKCQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDE0NTp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0zXSwgXyRbJDBdKShuZXcgeXkuV2hpbGUoJCRbJDAtMl0sIHtcbiAgICAgICAgICBndWFyZDogJCRbJDBdXG4gICAgICAgIH0pKTtcbmJyZWFrO1xuY2FzZSAxNDY6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5LldoaWxlKCQkWyQwXSwge1xuICAgICAgICAgIGludmVydDogdHJ1ZVxuICAgICAgICB9KSk7XG5icmVhaztcbmNhc2UgMTQ3OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTNdLCBfJFskMF0pKG5ldyB5eS5XaGlsZSgkJFskMC0yXSwge1xuICAgICAgICAgIGludmVydDogdHJ1ZSxcbiAgICAgICAgICBndWFyZDogJCRbJDBdXG4gICAgICAgIH0pKTtcbmJyZWFrO1xuY2FzZSAxNDg6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkoJCRbJDAtMV0uYWRkQm9keSgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxNDk6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkoJCRbJDBdLmFkZEJvZHkoeXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0pKHl5LkJsb2NrLndyYXAoWyQkWyQwLTFdXSkpKSk7XG5icmVhaztcbmNhc2UgMTUwOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKCQkWyQwXS5hZGRCb2R5KHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdKSh5eS5CbG9jay53cmFwKFskJFskMC0xXV0pKSkpO1xuYnJlYWs7XG5jYXNlIDE1MTp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0sIF8kWyQwXSkoJCRbJDBdKTtcbmJyZWFrO1xuY2FzZSAxNTI6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5LldoaWxlKHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdKShuZXcgeXkuTGl0ZXJhbCgndHJ1ZScpKSkuYWRkQm9keSgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxNTM6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5LldoaWxlKHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdKShuZXcgeXkuTGl0ZXJhbCgndHJ1ZScpKSkuYWRkQm9keSh5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0pKHl5LkJsb2NrLndyYXAoWyQkWyQwXV0pKSkpO1xuYnJlYWs7XG5jYXNlIDE1NDp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0xXSwgXyRbJDBdKShuZXcgeXkuRm9yKCQkWyQwLTFdLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxNTU6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5LkZvcigkJFskMC0xXSwgJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMTU2OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5Gb3IoJCRbJDBdLCAkJFskMC0xXSkpO1xuYnJlYWs7XG5jYXNlIDE1Nzp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0xXSwgXyRbJDBdKSh7XG4gICAgICAgICAgc291cmNlOiB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMF0pKG5ldyB5eS5WYWx1ZSgkJFskMF0pKVxuICAgICAgICB9KTtcbmJyZWFrO1xuY2FzZSAxNTg6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJCRbJDBdLm93biA9ICQkWyQwLTFdLm93bjtcbiAgICAgICAgJCRbJDBdLm5hbWUgPSAkJFskMC0xXVswXTtcbiAgICAgICAgJCRbJDBdLmluZGV4ID0gJCRbJDAtMV1bMV07XG4gICAgICAgIHJldHVybiAkJFskMF07XG4gICAgICB9KCkpKTtcbmJyZWFrO1xuY2FzZSAxNTk6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkoJCRbJDBdKTtcbmJyZWFrO1xuY2FzZSAxNjA6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJCRbJDBdLm93biA9IHRydWU7XG4gICAgICAgIHJldHVybiAkJFskMF07XG4gICAgICB9KCkpKTtcbmJyZWFrO1xuY2FzZSAxNjE6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDE2Mjp0aGlzLiQgPSAkJFskMF07XG5icmVhaztcbmNhc2UgMTYzOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuVmFsdWUoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMTY0OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShuZXcgeXkuVmFsdWUoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMTY1OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwXSwgXyRbJDBdKShbJCRbJDBdXSk7XG5icmVhaztcbmNhc2UgMTY2OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTJdLCBfJFskMF0pKFskJFskMC0yXSwgJCRbJDBdXSk7XG5icmVhaztcbmNhc2UgMTY3OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKHtcbiAgICAgICAgICBzb3VyY2U6ICQkWyQwXVxuICAgICAgICB9KTtcbmJyZWFrO1xuY2FzZSAxNjg6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkoe1xuICAgICAgICAgIHNvdXJjZTogJCRbJDBdLFxuICAgICAgICAgIG9iamVjdDogdHJ1ZVxuICAgICAgICB9KTtcbmJyZWFrO1xuY2FzZSAxNjk6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtM10sIF8kWyQwXSkoe1xuICAgICAgICAgIHNvdXJjZTogJCRbJDAtMl0sXG4gICAgICAgICAgZ3VhcmQ6ICQkWyQwXVxuICAgICAgICB9KTtcbmJyZWFrO1xuY2FzZSAxNzA6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtM10sIF8kWyQwXSkoe1xuICAgICAgICAgIHNvdXJjZTogJCRbJDAtMl0sXG4gICAgICAgICAgZ3VhcmQ6ICQkWyQwXSxcbiAgICAgICAgICBvYmplY3Q6IHRydWVcbiAgICAgICAgfSk7XG5icmVhaztcbmNhc2UgMTcxOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTNdLCBfJFskMF0pKHtcbiAgICAgICAgICBzb3VyY2U6ICQkWyQwLTJdLFxuICAgICAgICAgIHN0ZXA6ICQkWyQwXVxuICAgICAgICB9KTtcbmJyZWFrO1xuY2FzZSAxNzI6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtNV0sIF8kWyQwXSkoe1xuICAgICAgICAgIHNvdXJjZTogJCRbJDAtNF0sXG4gICAgICAgICAgZ3VhcmQ6ICQkWyQwLTJdLFxuICAgICAgICAgIHN0ZXA6ICQkWyQwXVxuICAgICAgICB9KTtcbmJyZWFrO1xuY2FzZSAxNzM6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtNV0sIF8kWyQwXSkoe1xuICAgICAgICAgIHNvdXJjZTogJCRbJDAtNF0sXG4gICAgICAgICAgc3RlcDogJCRbJDAtMl0sXG4gICAgICAgICAgZ3VhcmQ6ICQkWyQwXVxuICAgICAgICB9KTtcbmJyZWFrO1xuY2FzZSAxNzQ6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtNF0sIF8kWyQwXSkobmV3IHl5LlN3aXRjaCgkJFskMC0zXSwgJCRbJDAtMV0pKTtcbmJyZWFrO1xuY2FzZSAxNzU6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtNl0sIF8kWyQwXSkobmV3IHl5LlN3aXRjaCgkJFskMC01XSwgJCRbJDAtM10sICQkWyQwLTFdKSk7XG5icmVhaztcbmNhc2UgMTc2OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTNdLCBfJFskMF0pKG5ldyB5eS5Td2l0Y2gobnVsbCwgJCRbJDAtMV0pKTtcbmJyZWFrO1xuY2FzZSAxNzc6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtNV0sIF8kWyQwXSkobmV3IHl5LlN3aXRjaChudWxsLCAkJFskMC0zXSwgJCRbJDAtMV0pKTtcbmJyZWFrO1xuY2FzZSAxNzg6dGhpcy4kID0gJCRbJDBdO1xuYnJlYWs7XG5jYXNlIDE3OTp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0xXSwgXyRbJDBdKSgkJFskMC0xXS5jb25jYXQoJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMTgwOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTJdLCBfJFskMF0pKFtbJCRbJDAtMV0sICQkWyQwXV1dKTtcbmJyZWFrO1xuY2FzZSAxODE6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtM10sIF8kWyQwXSkoW1skJFskMC0yXSwgJCRbJDAtMV1dXSk7XG5icmVhaztcbmNhc2UgMTgyOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTJdLCBfJFskMF0pKG5ldyB5eS5JZigkJFskMC0xXSwgJCRbJDBdLCB7XG4gICAgICAgICAgdHlwZTogJCRbJDAtMl1cbiAgICAgICAgfSkpO1xuYnJlYWs7XG5jYXNlIDE4Mzp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC00XSwgXyRbJDBdKSgkJFskMC00XS5hZGRFbHNlKHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTJdLCBfJFskMF0pKG5ldyB5eS5JZigkJFskMC0xXSwgJCRbJDBdLCB7XG4gICAgICAgICAgdHlwZTogJCRbJDAtMl1cbiAgICAgICAgfSkpKSk7XG5icmVhaztcbmNhc2UgMTg0OnRoaXMuJCA9ICQkWyQwXTtcbmJyZWFrO1xuY2FzZSAxODU6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkoJCRbJDAtMl0uYWRkRWxzZSgkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxODY6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkobmV3IHl5LklmKCQkWyQwXSwgeXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0pKHl5LkJsb2NrLndyYXAoWyQkWyQwLTJdXSkpLCB7XG4gICAgICAgICAgdHlwZTogJCRbJDAtMV0sXG4gICAgICAgICAgc3RhdGVtZW50OiB0cnVlXG4gICAgICAgIH0pKTtcbmJyZWFrO1xuY2FzZSAxODc6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkobmV3IHl5LklmKCQkWyQwXSwgeXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0pKHl5LkJsb2NrLndyYXAoWyQkWyQwLTJdXSkpLCB7XG4gICAgICAgICAgdHlwZTogJCRbJDAtMV0sXG4gICAgICAgICAgc3RhdGVtZW50OiB0cnVlXG4gICAgICAgIH0pKTtcbmJyZWFrO1xuY2FzZSAxODg6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5Lk9wKCQkWyQwLTFdLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxODk6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5Lk9wKCQkWyQwLTFdLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxOTA6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5Lk9wKCctJywgJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMTkxOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5PcCgnKycsICQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDE5Mjp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0xXSwgXyRbJDBdKShuZXcgeXkuT3AoJy0tJywgJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMTkzOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5PcCgnKysnLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxOTQ6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMV0sIF8kWyQwXSkobmV3IHl5Lk9wKCctLScsICQkWyQwLTFdLCBudWxsLCB0cnVlKSk7XG5icmVhaztcbmNhc2UgMTk1OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTFdLCBfJFskMF0pKG5ldyB5eS5PcCgnKysnLCAkJFskMC0xXSwgbnVsbCwgdHJ1ZSkpO1xuYnJlYWs7XG5jYXNlIDE5Njp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0xXSwgXyRbJDBdKShuZXcgeXkuRXhpc3RlbmNlKCQkWyQwLTFdKSk7XG5icmVhaztcbmNhc2UgMTk3OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTJdLCBfJFskMF0pKG5ldyB5eS5PcCgnKycsICQkWyQwLTJdLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAxOTg6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkobmV3IHl5Lk9wKCctJywgJCRbJDAtMl0sICQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDE5OTp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSwgXyRbJDBdKShuZXcgeXkuT3AoJCRbJDAtMV0sICQkWyQwLTJdLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAyMDA6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkobmV3IHl5Lk9wKCQkWyQwLTFdLCAkJFskMC0yXSwgJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMjAxOnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTJdLCBfJFskMF0pKG5ldyB5eS5PcCgkJFskMC0xXSwgJCRbJDAtMl0sICQkWyQwXSkpO1xuYnJlYWs7XG5jYXNlIDIwMjp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSwgXyRbJDBdKShuZXcgeXkuT3AoJCRbJDAtMV0sICQkWyQwLTJdLCAkJFskMF0pKTtcbmJyZWFrO1xuY2FzZSAyMDM6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkobmV3IHl5Lk9wKCQkWyQwLTFdLCAkJFskMC0yXSwgJCRbJDBdKSk7XG5icmVhaztcbmNhc2UgMjA0OnRoaXMuJCA9IHl5LmFkZExvY2F0aW9uRGF0YUZuKF8kWyQwLTJdLCBfJFskMF0pKChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICgkJFskMC0xXS5jaGFyQXQoMCkgPT09ICchJykge1xuICAgICAgICAgIHJldHVybiBuZXcgeXkuT3AoJCRbJDAtMV0uc2xpY2UoMSksICQkWyQwLTJdLCAkJFskMF0pLmludmVydCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBuZXcgeXkuT3AoJCRbJDAtMV0sICQkWyQwLTJdLCAkJFskMF0pO1xuICAgICAgICB9XG4gICAgICB9KCkpKTtcbmJyZWFrO1xuY2FzZSAyMDU6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtMl0sIF8kWyQwXSkobmV3IHl5LkFzc2lnbigkJFskMC0yXSwgJCRbJDBdLCAkJFskMC0xXSkpO1xuYnJlYWs7XG5jYXNlIDIwNjp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC00XSwgXyRbJDBdKShuZXcgeXkuQXNzaWduKCQkWyQwLTRdLCAkJFskMC0xXSwgJCRbJDAtM10pKTtcbmJyZWFrO1xuY2FzZSAyMDc6dGhpcy4kID0geXkuYWRkTG9jYXRpb25EYXRhRm4oXyRbJDAtM10sIF8kWyQwXSkobmV3IHl5LkFzc2lnbigkJFskMC0zXSwgJCRbJDBdLCAkJFskMC0yXSkpO1xuYnJlYWs7XG5jYXNlIDIwODp0aGlzLiQgPSB5eS5hZGRMb2NhdGlvbkRhdGFGbihfJFskMC0yXSwgXyRbJDBdKShuZXcgeXkuRXh0ZW5kcygkJFskMC0yXSwgJCRbJDBdKSk7XG5icmVhaztcbn1cbn0sXG50YWJsZTogW3sxOlsyLDFdLDM6MSw0OjIsNTozLDc6NCw4OjUsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezE6WzNdfSx7MTpbMiwyXSw2OlsxLDczXX0sezE6WzIsM10sNjpbMiwzXSwyNjpbMiwzXSwxMDI6WzIsM119LHsxOlsyLDZdLDY6WzIsNl0sMjY6WzIsNl0sMTAyOlsyLDZdLDEwMzo4NCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA5Ojg1LDExMDpbMSw2N10sMTExOjY4LDEyNjpbMSw4M10sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHsxOlsyLDddLDY6WzIsN10sMjY6WzIsN10sMTAyOlsyLDddLDEwMzo4NywxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA5Ojg4LDExMDpbMSw2N10sMTExOjY4LDEyNjpbMSw4Nl19LHsxOlsyLDExXSw2OlsyLDExXSwyNTpbMiwxMV0sMjY6WzIsMTFdLDQ5OlsyLDExXSw1NDpbMiwxMV0sNTc6WzIsMTFdLDYyOjkwLDY2OlsxLDkyXSw2NzpbMSw5M10sNjg6WzEsOTRdLDY5OlsxLDk1XSw3MDo5Niw3MTpbMSw5N10sNzM6WzIsMTFdLDc0OlsxLDk4XSw3ODpbMiwxMV0sODE6ODksODQ6WzEsOTFdLDg1OlsyLDEwOF0sODY6WzIsMTFdLDkxOlsyLDExXSw5MzpbMiwxMV0sMTAyOlsyLDExXSwxMDQ6WzIsMTFdLDEwNTpbMiwxMV0sMTA2OlsyLDExXSwxMTA6WzIsMTFdLDExODpbMiwxMV0sMTI2OlsyLDExXSwxMjk6WzIsMTFdLDEzMDpbMiwxMV0sMTMzOlsyLDExXSwxMzQ6WzIsMTFdLDEzNTpbMiwxMV0sMTM2OlsyLDExXSwxMzc6WzIsMTFdLDEzODpbMiwxMV0sMTM5OlsyLDExXX0sezE6WzIsMTJdLDY6WzIsMTJdLDI1OlsyLDEyXSwyNjpbMiwxMl0sNDk6WzIsMTJdLDU0OlsyLDEyXSw1NzpbMiwxMl0sNjI6MTAwLDY2OlsxLDkyXSw2NzpbMSw5M10sNjg6WzEsOTRdLDY5OlsxLDk1XSw3MDo5Niw3MTpbMSw5N10sNzM6WzIsMTJdLDc0OlsxLDk4XSw3ODpbMiwxMl0sODE6OTksODQ6WzEsOTFdLDg1OlsyLDEwOF0sODY6WzIsMTJdLDkxOlsyLDEyXSw5MzpbMiwxMl0sMTAyOlsyLDEyXSwxMDQ6WzIsMTJdLDEwNTpbMiwxMl0sMTA2OlsyLDEyXSwxMTA6WzIsMTJdLDExODpbMiwxMl0sMTI2OlsyLDEyXSwxMjk6WzIsMTJdLDEzMDpbMiwxMl0sMTMzOlsyLDEyXSwxMzQ6WzIsMTJdLDEzNTpbMiwxMl0sMTM2OlsyLDEyXSwxMzc6WzIsMTJdLDEzODpbMiwxMl0sMTM5OlsyLDEyXX0sezE6WzIsMTNdLDY6WzIsMTNdLDI1OlsyLDEzXSwyNjpbMiwxM10sNDk6WzIsMTNdLDU0OlsyLDEzXSw1NzpbMiwxM10sNzM6WzIsMTNdLDc4OlsyLDEzXSw4NjpbMiwxM10sOTE6WzIsMTNdLDkzOlsyLDEzXSwxMDI6WzIsMTNdLDEwNDpbMiwxM10sMTA1OlsyLDEzXSwxMDY6WzIsMTNdLDExMDpbMiwxM10sMTE4OlsyLDEzXSwxMjY6WzIsMTNdLDEyOTpbMiwxM10sMTMwOlsyLDEzXSwxMzM6WzIsMTNdLDEzNDpbMiwxM10sMTM1OlsyLDEzXSwxMzY6WzIsMTNdLDEzNzpbMiwxM10sMTM4OlsyLDEzXSwxMzk6WzIsMTNdfSx7MTpbMiwxNF0sNjpbMiwxNF0sMjU6WzIsMTRdLDI2OlsyLDE0XSw0OTpbMiwxNF0sNTQ6WzIsMTRdLDU3OlsyLDE0XSw3MzpbMiwxNF0sNzg6WzIsMTRdLDg2OlsyLDE0XSw5MTpbMiwxNF0sOTM6WzIsMTRdLDEwMjpbMiwxNF0sMTA0OlsyLDE0XSwxMDU6WzIsMTRdLDEwNjpbMiwxNF0sMTEwOlsyLDE0XSwxMTg6WzIsMTRdLDEyNjpbMiwxNF0sMTI5OlsyLDE0XSwxMzA6WzIsMTRdLDEzMzpbMiwxNF0sMTM0OlsyLDE0XSwxMzU6WzIsMTRdLDEzNjpbMiwxNF0sMTM3OlsyLDE0XSwxMzg6WzIsMTRdLDEzOTpbMiwxNF19LHsxOlsyLDE1XSw2OlsyLDE1XSwyNTpbMiwxNV0sMjY6WzIsMTVdLDQ5OlsyLDE1XSw1NDpbMiwxNV0sNTc6WzIsMTVdLDczOlsyLDE1XSw3ODpbMiwxNV0sODY6WzIsMTVdLDkxOlsyLDE1XSw5MzpbMiwxNV0sMTAyOlsyLDE1XSwxMDQ6WzIsMTVdLDEwNTpbMiwxNV0sMTA2OlsyLDE1XSwxMTA6WzIsMTVdLDExODpbMiwxNV0sMTI2OlsyLDE1XSwxMjk6WzIsMTVdLDEzMDpbMiwxNV0sMTMzOlsyLDE1XSwxMzQ6WzIsMTVdLDEzNTpbMiwxNV0sMTM2OlsyLDE1XSwxMzc6WzIsMTVdLDEzODpbMiwxNV0sMTM5OlsyLDE1XX0sezE6WzIsMTZdLDY6WzIsMTZdLDI1OlsyLDE2XSwyNjpbMiwxNl0sNDk6WzIsMTZdLDU0OlsyLDE2XSw1NzpbMiwxNl0sNzM6WzIsMTZdLDc4OlsyLDE2XSw4NjpbMiwxNl0sOTE6WzIsMTZdLDkzOlsyLDE2XSwxMDI6WzIsMTZdLDEwNDpbMiwxNl0sMTA1OlsyLDE2XSwxMDY6WzIsMTZdLDExMDpbMiwxNl0sMTE4OlsyLDE2XSwxMjY6WzIsMTZdLDEyOTpbMiwxNl0sMTMwOlsyLDE2XSwxMzM6WzIsMTZdLDEzNDpbMiwxNl0sMTM1OlsyLDE2XSwxMzY6WzIsMTZdLDEzNzpbMiwxNl0sMTM4OlsyLDE2XSwxMzk6WzIsMTZdfSx7MTpbMiwxN10sNjpbMiwxN10sMjU6WzIsMTddLDI2OlsyLDE3XSw0OTpbMiwxN10sNTQ6WzIsMTddLDU3OlsyLDE3XSw3MzpbMiwxN10sNzg6WzIsMTddLDg2OlsyLDE3XSw5MTpbMiwxN10sOTM6WzIsMTddLDEwMjpbMiwxN10sMTA0OlsyLDE3XSwxMDU6WzIsMTddLDEwNjpbMiwxN10sMTEwOlsyLDE3XSwxMTg6WzIsMTddLDEyNjpbMiwxN10sMTI5OlsyLDE3XSwxMzA6WzIsMTddLDEzMzpbMiwxN10sMTM0OlsyLDE3XSwxMzU6WzIsMTddLDEzNjpbMiwxN10sMTM3OlsyLDE3XSwxMzg6WzIsMTddLDEzOTpbMiwxN119LHsxOlsyLDE4XSw2OlsyLDE4XSwyNTpbMiwxOF0sMjY6WzIsMThdLDQ5OlsyLDE4XSw1NDpbMiwxOF0sNTc6WzIsMThdLDczOlsyLDE4XSw3ODpbMiwxOF0sODY6WzIsMThdLDkxOlsyLDE4XSw5MzpbMiwxOF0sMTAyOlsyLDE4XSwxMDQ6WzIsMThdLDEwNTpbMiwxOF0sMTA2OlsyLDE4XSwxMTA6WzIsMThdLDExODpbMiwxOF0sMTI2OlsyLDE4XSwxMjk6WzIsMThdLDEzMDpbMiwxOF0sMTMzOlsyLDE4XSwxMzQ6WzIsMThdLDEzNTpbMiwxOF0sMTM2OlsyLDE4XSwxMzc6WzIsMThdLDEzODpbMiwxOF0sMTM5OlsyLDE4XX0sezE6WzIsMTldLDY6WzIsMTldLDI1OlsyLDE5XSwyNjpbMiwxOV0sNDk6WzIsMTldLDU0OlsyLDE5XSw1NzpbMiwxOV0sNzM6WzIsMTldLDc4OlsyLDE5XSw4NjpbMiwxOV0sOTE6WzIsMTldLDkzOlsyLDE5XSwxMDI6WzIsMTldLDEwNDpbMiwxOV0sMTA1OlsyLDE5XSwxMDY6WzIsMTldLDExMDpbMiwxOV0sMTE4OlsyLDE5XSwxMjY6WzIsMTldLDEyOTpbMiwxOV0sMTMwOlsyLDE5XSwxMzM6WzIsMTldLDEzNDpbMiwxOV0sMTM1OlsyLDE5XSwxMzY6WzIsMTldLDEzNzpbMiwxOV0sMTM4OlsyLDE5XSwxMzk6WzIsMTldfSx7MTpbMiwyMF0sNjpbMiwyMF0sMjU6WzIsMjBdLDI2OlsyLDIwXSw0OTpbMiwyMF0sNTQ6WzIsMjBdLDU3OlsyLDIwXSw3MzpbMiwyMF0sNzg6WzIsMjBdLDg2OlsyLDIwXSw5MTpbMiwyMF0sOTM6WzIsMjBdLDEwMjpbMiwyMF0sMTA0OlsyLDIwXSwxMDU6WzIsMjBdLDEwNjpbMiwyMF0sMTEwOlsyLDIwXSwxMTg6WzIsMjBdLDEyNjpbMiwyMF0sMTI5OlsyLDIwXSwxMzA6WzIsMjBdLDEzMzpbMiwyMF0sMTM0OlsyLDIwXSwxMzU6WzIsMjBdLDEzNjpbMiwyMF0sMTM3OlsyLDIwXSwxMzg6WzIsMjBdLDEzOTpbMiwyMF19LHsxOlsyLDIxXSw2OlsyLDIxXSwyNTpbMiwyMV0sMjY6WzIsMjFdLDQ5OlsyLDIxXSw1NDpbMiwyMV0sNTc6WzIsMjFdLDczOlsyLDIxXSw3ODpbMiwyMV0sODY6WzIsMjFdLDkxOlsyLDIxXSw5MzpbMiwyMV0sMTAyOlsyLDIxXSwxMDQ6WzIsMjFdLDEwNTpbMiwyMV0sMTA2OlsyLDIxXSwxMTA6WzIsMjFdLDExODpbMiwyMV0sMTI2OlsyLDIxXSwxMjk6WzIsMjFdLDEzMDpbMiwyMV0sMTMzOlsyLDIxXSwxMzQ6WzIsMjFdLDEzNTpbMiwyMV0sMTM2OlsyLDIxXSwxMzc6WzIsMjFdLDEzODpbMiwyMV0sMTM5OlsyLDIxXX0sezE6WzIsMjJdLDY6WzIsMjJdLDI1OlsyLDIyXSwyNjpbMiwyMl0sNDk6WzIsMjJdLDU0OlsyLDIyXSw1NzpbMiwyMl0sNzM6WzIsMjJdLDc4OlsyLDIyXSw4NjpbMiwyMl0sOTE6WzIsMjJdLDkzOlsyLDIyXSwxMDI6WzIsMjJdLDEwNDpbMiwyMl0sMTA1OlsyLDIyXSwxMDY6WzIsMjJdLDExMDpbMiwyMl0sMTE4OlsyLDIyXSwxMjY6WzIsMjJdLDEyOTpbMiwyMl0sMTMwOlsyLDIyXSwxMzM6WzIsMjJdLDEzNDpbMiwyMl0sMTM1OlsyLDIyXSwxMzY6WzIsMjJdLDEzNzpbMiwyMl0sMTM4OlsyLDIyXSwxMzk6WzIsMjJdfSx7MTpbMiw4XSw2OlsyLDhdLDI2OlsyLDhdLDEwMjpbMiw4XSwxMDQ6WzIsOF0sMTA2OlsyLDhdLDExMDpbMiw4XSwxMjY6WzIsOF19LHsxOlsyLDldLDY6WzIsOV0sMjY6WzIsOV0sMTAyOlsyLDldLDEwNDpbMiw5XSwxMDY6WzIsOV0sMTEwOlsyLDldLDEyNjpbMiw5XX0sezE6WzIsMTBdLDY6WzIsMTBdLDI2OlsyLDEwXSwxMDI6WzIsMTBdLDEwNDpbMiwxMF0sMTA2OlsyLDEwXSwxMTA6WzIsMTBdLDEyNjpbMiwxMF19LHsxOlsyLDc1XSw2OlsyLDc1XSwyNTpbMiw3NV0sMjY6WzIsNzVdLDQwOlsxLDEwMV0sNDk6WzIsNzVdLDU0OlsyLDc1XSw1NzpbMiw3NV0sNjY6WzIsNzVdLDY3OlsyLDc1XSw2ODpbMiw3NV0sNjk6WzIsNzVdLDcxOlsyLDc1XSw3MzpbMiw3NV0sNzQ6WzIsNzVdLDc4OlsyLDc1XSw4NDpbMiw3NV0sODU6WzIsNzVdLDg2OlsyLDc1XSw5MTpbMiw3NV0sOTM6WzIsNzVdLDEwMjpbMiw3NV0sMTA0OlsyLDc1XSwxMDU6WzIsNzVdLDEwNjpbMiw3NV0sMTEwOlsyLDc1XSwxMTg6WzIsNzVdLDEyNjpbMiw3NV0sMTI5OlsyLDc1XSwxMzA6WzIsNzVdLDEzMzpbMiw3NV0sMTM0OlsyLDc1XSwxMzU6WzIsNzVdLDEzNjpbMiw3NV0sMTM3OlsyLDc1XSwxMzg6WzIsNzVdLDEzOTpbMiw3NV19LHsxOlsyLDc2XSw2OlsyLDc2XSwyNTpbMiw3Nl0sMjY6WzIsNzZdLDQ5OlsyLDc2XSw1NDpbMiw3Nl0sNTc6WzIsNzZdLDY2OlsyLDc2XSw2NzpbMiw3Nl0sNjg6WzIsNzZdLDY5OlsyLDc2XSw3MTpbMiw3Nl0sNzM6WzIsNzZdLDc0OlsyLDc2XSw3ODpbMiw3Nl0sODQ6WzIsNzZdLDg1OlsyLDc2XSw4NjpbMiw3Nl0sOTE6WzIsNzZdLDkzOlsyLDc2XSwxMDI6WzIsNzZdLDEwNDpbMiw3Nl0sMTA1OlsyLDc2XSwxMDY6WzIsNzZdLDExMDpbMiw3Nl0sMTE4OlsyLDc2XSwxMjY6WzIsNzZdLDEyOTpbMiw3Nl0sMTMwOlsyLDc2XSwxMzM6WzIsNzZdLDEzNDpbMiw3Nl0sMTM1OlsyLDc2XSwxMzY6WzIsNzZdLDEzNzpbMiw3Nl0sMTM4OlsyLDc2XSwxMzk6WzIsNzZdfSx7MTpbMiw3N10sNjpbMiw3N10sMjU6WzIsNzddLDI2OlsyLDc3XSw0OTpbMiw3N10sNTQ6WzIsNzddLDU3OlsyLDc3XSw2NjpbMiw3N10sNjc6WzIsNzddLDY4OlsyLDc3XSw2OTpbMiw3N10sNzE6WzIsNzddLDczOlsyLDc3XSw3NDpbMiw3N10sNzg6WzIsNzddLDg0OlsyLDc3XSw4NTpbMiw3N10sODY6WzIsNzddLDkxOlsyLDc3XSw5MzpbMiw3N10sMTAyOlsyLDc3XSwxMDQ6WzIsNzddLDEwNTpbMiw3N10sMTA2OlsyLDc3XSwxMTA6WzIsNzddLDExODpbMiw3N10sMTI2OlsyLDc3XSwxMjk6WzIsNzddLDEzMDpbMiw3N10sMTMzOlsyLDc3XSwxMzQ6WzIsNzddLDEzNTpbMiw3N10sMTM2OlsyLDc3XSwxMzc6WzIsNzddLDEzODpbMiw3N10sMTM5OlsyLDc3XX0sezE6WzIsNzhdLDY6WzIsNzhdLDI1OlsyLDc4XSwyNjpbMiw3OF0sNDk6WzIsNzhdLDU0OlsyLDc4XSw1NzpbMiw3OF0sNjY6WzIsNzhdLDY3OlsyLDc4XSw2ODpbMiw3OF0sNjk6WzIsNzhdLDcxOlsyLDc4XSw3MzpbMiw3OF0sNzQ6WzIsNzhdLDc4OlsyLDc4XSw4NDpbMiw3OF0sODU6WzIsNzhdLDg2OlsyLDc4XSw5MTpbMiw3OF0sOTM6WzIsNzhdLDEwMjpbMiw3OF0sMTA0OlsyLDc4XSwxMDU6WzIsNzhdLDEwNjpbMiw3OF0sMTEwOlsyLDc4XSwxMTg6WzIsNzhdLDEyNjpbMiw3OF0sMTI5OlsyLDc4XSwxMzA6WzIsNzhdLDEzMzpbMiw3OF0sMTM0OlsyLDc4XSwxMzU6WzIsNzhdLDEzNjpbMiw3OF0sMTM3OlsyLDc4XSwxMzg6WzIsNzhdLDEzOTpbMiw3OF19LHsxOlsyLDc5XSw2OlsyLDc5XSwyNTpbMiw3OV0sMjY6WzIsNzldLDQ5OlsyLDc5XSw1NDpbMiw3OV0sNTc6WzIsNzldLDY2OlsyLDc5XSw2NzpbMiw3OV0sNjg6WzIsNzldLDY5OlsyLDc5XSw3MTpbMiw3OV0sNzM6WzIsNzldLDc0OlsyLDc5XSw3ODpbMiw3OV0sODQ6WzIsNzldLDg1OlsyLDc5XSw4NjpbMiw3OV0sOTE6WzIsNzldLDkzOlsyLDc5XSwxMDI6WzIsNzldLDEwNDpbMiw3OV0sMTA1OlsyLDc5XSwxMDY6WzIsNzldLDExMDpbMiw3OV0sMTE4OlsyLDc5XSwxMjY6WzIsNzldLDEyOTpbMiw3OV0sMTMwOlsyLDc5XSwxMzM6WzIsNzldLDEzNDpbMiw3OV0sMTM1OlsyLDc5XSwxMzY6WzIsNzldLDEzNzpbMiw3OV0sMTM4OlsyLDc5XSwxMzk6WzIsNzldfSx7MTpbMiwxMDZdLDY6WzIsMTA2XSwyNTpbMiwxMDZdLDI2OlsyLDEwNl0sNDk6WzIsMTA2XSw1NDpbMiwxMDZdLDU3OlsyLDEwNl0sNjY6WzIsMTA2XSw2NzpbMiwxMDZdLDY4OlsyLDEwNl0sNjk6WzIsMTA2XSw3MTpbMiwxMDZdLDczOlsyLDEwNl0sNzQ6WzIsMTA2XSw3ODpbMiwxMDZdLDgyOjEwMiw4NDpbMiwxMDZdLDg1OlsxLDEwM10sODY6WzIsMTA2XSw5MTpbMiwxMDZdLDkzOlsyLDEwNl0sMTAyOlsyLDEwNl0sMTA0OlsyLDEwNl0sMTA1OlsyLDEwNl0sMTA2OlsyLDEwNl0sMTEwOlsyLDEwNl0sMTE4OlsyLDEwNl0sMTI2OlsyLDEwNl0sMTI5OlsyLDEwNl0sMTMwOlsyLDEwNl0sMTMzOlsyLDEwNl0sMTM0OlsyLDEwNl0sMTM1OlsyLDEwNl0sMTM2OlsyLDEwNl0sMTM3OlsyLDEwNl0sMTM4OlsyLDEwNl0sMTM5OlsyLDEwNl19LHs2OlsyLDU0XSwyNTpbMiw1NF0sMjc6MTA4LDI4OlsxLDcyXSw0NDoxMDksNDg6MTA0LDQ5OlsyLDU0XSw1NDpbMiw1NF0sNTU6MTA1LDU2OjEwNiw1NzpbMSwxMDddLDU4OjExMCw1OToxMTEsNzY6WzEsNjldLDg5OlsxLDExMl0sOTA6WzEsMTEzXX0sezI0OjExNCwyNTpbMSwxMTVdfSx7NzoxMTYsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezc6MTE4LDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs3OjExOSw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7NzoxMjAsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezEyOjEyMiwxMzoxMjMsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MTI0LDQ0OjYyLDU4OjQ2LDU5OjQ3LDYxOjEyMSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDEwMTpbMSw1NV19LHsxMjoxMjIsMTM6MTIzLDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjEyNCw0NDo2Miw1ODo0Niw1OTo0Nyw2MToxMjUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSwxMDE6WzEsNTVdfSx7MTpbMiw3Ml0sNjpbMiw3Ml0sMjU6WzIsNzJdLDI2OlsyLDcyXSw0MDpbMiw3Ml0sNDk6WzIsNzJdLDU0OlsyLDcyXSw1NzpbMiw3Ml0sNjY6WzIsNzJdLDY3OlsyLDcyXSw2ODpbMiw3Ml0sNjk6WzIsNzJdLDcxOlsyLDcyXSw3MzpbMiw3Ml0sNzQ6WzIsNzJdLDc4OlsyLDcyXSw4MDpbMSwxMjldLDg0OlsyLDcyXSw4NTpbMiw3Ml0sODY6WzIsNzJdLDkxOlsyLDcyXSw5MzpbMiw3Ml0sMTAyOlsyLDcyXSwxMDQ6WzIsNzJdLDEwNTpbMiw3Ml0sMTA2OlsyLDcyXSwxMTA6WzIsNzJdLDExODpbMiw3Ml0sMTI2OlsyLDcyXSwxMjk6WzIsNzJdLDEzMDpbMiw3Ml0sMTMxOlsxLDEyNl0sMTMyOlsxLDEyN10sMTMzOlsyLDcyXSwxMzQ6WzIsNzJdLDEzNTpbMiw3Ml0sMTM2OlsyLDcyXSwxMzc6WzIsNzJdLDEzODpbMiw3Ml0sMTM5OlsyLDcyXSwxNDA6WzEsMTI4XX0sezE6WzIsMTg0XSw2OlsyLDE4NF0sMjU6WzIsMTg0XSwyNjpbMiwxODRdLDQ5OlsyLDE4NF0sNTQ6WzIsMTg0XSw1NzpbMiwxODRdLDczOlsyLDE4NF0sNzg6WzIsMTg0XSw4NjpbMiwxODRdLDkxOlsyLDE4NF0sOTM6WzIsMTg0XSwxMDI6WzIsMTg0XSwxMDQ6WzIsMTg0XSwxMDU6WzIsMTg0XSwxMDY6WzIsMTg0XSwxMTA6WzIsMTg0XSwxMTg6WzIsMTg0XSwxMjE6WzEsMTMwXSwxMjY6WzIsMTg0XSwxMjk6WzIsMTg0XSwxMzA6WzIsMTg0XSwxMzM6WzIsMTg0XSwxMzQ6WzIsMTg0XSwxMzU6WzIsMTg0XSwxMzY6WzIsMTg0XSwxMzc6WzIsMTg0XSwxMzg6WzIsMTg0XSwxMzk6WzIsMTg0XX0sezI0OjEzMSwyNTpbMSwxMTVdfSx7MjQ6MTMyLDI1OlsxLDExNV19LHsxOlsyLDE1MV0sNjpbMiwxNTFdLDI1OlsyLDE1MV0sMjY6WzIsMTUxXSw0OTpbMiwxNTFdLDU0OlsyLDE1MV0sNTc6WzIsMTUxXSw3MzpbMiwxNTFdLDc4OlsyLDE1MV0sODY6WzIsMTUxXSw5MTpbMiwxNTFdLDkzOlsyLDE1MV0sMTAyOlsyLDE1MV0sMTA0OlsyLDE1MV0sMTA1OlsyLDE1MV0sMTA2OlsyLDE1MV0sMTEwOlsyLDE1MV0sMTE4OlsyLDE1MV0sMTI2OlsyLDE1MV0sMTI5OlsyLDE1MV0sMTMwOlsyLDE1MV0sMTMzOlsyLDE1MV0sMTM0OlsyLDE1MV0sMTM1OlsyLDE1MV0sMTM2OlsyLDE1MV0sMTM3OlsyLDE1MV0sMTM4OlsyLDE1MV0sMTM5OlsyLDE1MV19LHsyNDoxMzMsMjU6WzEsMTE1XX0sezc6MTM0LDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjU6WzEsMTM1XSwyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezE6WzIsOTZdLDY6WzIsOTZdLDEyOjEyMiwxMzoxMjMsMjQ6MTM2LDI1OlsxLDExNV0sMjY6WzIsOTZdLDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjEyNCw0NDo2Miw0OTpbMiw5Nl0sNTQ6WzIsOTZdLDU3OlsyLDk2XSw1ODo0Niw1OTo0Nyw2MToxMzgsNjM6MjMsNjQ6MjQsNjU6MjUsNzM6WzIsOTZdLDc2OlsxLDY5XSw3ODpbMiw5Nl0sODA6WzEsMTM3XSw4MzpbMSwyNl0sODY6WzIsOTZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDkxOlsyLDk2XSw5MzpbMiw5Nl0sMTAxOlsxLDU1XSwxMDI6WzIsOTZdLDEwNDpbMiw5Nl0sMTA1OlsyLDk2XSwxMDY6WzIsOTZdLDExMDpbMiw5Nl0sMTE4OlsyLDk2XSwxMjY6WzIsOTZdLDEyOTpbMiw5Nl0sMTMwOlsyLDk2XSwxMzM6WzIsOTZdLDEzNDpbMiw5Nl0sMTM1OlsyLDk2XSwxMzY6WzIsOTZdLDEzNzpbMiw5Nl0sMTM4OlsyLDk2XSwxMzk6WzIsOTZdfSx7NzoxMzksODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezE6WzIsNDZdLDY6WzIsNDZdLDc6MTQwLDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjY6WzIsNDZdLDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDI6WzIsNDZdLDEwMzozOCwxMDQ6WzIsNDZdLDEwNjpbMiw0Nl0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMiw0Nl0sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI2OlsyLDQ2XSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezE6WzIsNDddLDY6WzIsNDddLDI1OlsyLDQ3XSwyNjpbMiw0N10sNTQ6WzIsNDddLDc4OlsyLDQ3XSwxMDI6WzIsNDddLDEwNDpbMiw0N10sMTA2OlsyLDQ3XSwxMTA6WzIsNDddLDEyNjpbMiw0N119LHsxOlsyLDczXSw2OlsyLDczXSwyNTpbMiw3M10sMjY6WzIsNzNdLDQwOlsyLDczXSw0OTpbMiw3M10sNTQ6WzIsNzNdLDU3OlsyLDczXSw2NjpbMiw3M10sNjc6WzIsNzNdLDY4OlsyLDczXSw2OTpbMiw3M10sNzE6WzIsNzNdLDczOlsyLDczXSw3NDpbMiw3M10sNzg6WzIsNzNdLDg0OlsyLDczXSw4NTpbMiw3M10sODY6WzIsNzNdLDkxOlsyLDczXSw5MzpbMiw3M10sMTAyOlsyLDczXSwxMDQ6WzIsNzNdLDEwNTpbMiw3M10sMTA2OlsyLDczXSwxMTA6WzIsNzNdLDExODpbMiw3M10sMTI2OlsyLDczXSwxMjk6WzIsNzNdLDEzMDpbMiw3M10sMTMzOlsyLDczXSwxMzQ6WzIsNzNdLDEzNTpbMiw3M10sMTM2OlsyLDczXSwxMzc6WzIsNzNdLDEzODpbMiw3M10sMTM5OlsyLDczXX0sezE6WzIsNzRdLDY6WzIsNzRdLDI1OlsyLDc0XSwyNjpbMiw3NF0sNDA6WzIsNzRdLDQ5OlsyLDc0XSw1NDpbMiw3NF0sNTc6WzIsNzRdLDY2OlsyLDc0XSw2NzpbMiw3NF0sNjg6WzIsNzRdLDY5OlsyLDc0XSw3MTpbMiw3NF0sNzM6WzIsNzRdLDc0OlsyLDc0XSw3ODpbMiw3NF0sODQ6WzIsNzRdLDg1OlsyLDc0XSw4NjpbMiw3NF0sOTE6WzIsNzRdLDkzOlsyLDc0XSwxMDI6WzIsNzRdLDEwNDpbMiw3NF0sMTA1OlsyLDc0XSwxMDY6WzIsNzRdLDExMDpbMiw3NF0sMTE4OlsyLDc0XSwxMjY6WzIsNzRdLDEyOTpbMiw3NF0sMTMwOlsyLDc0XSwxMzM6WzIsNzRdLDEzNDpbMiw3NF0sMTM1OlsyLDc0XSwxMzY6WzIsNzRdLDEzNzpbMiw3NF0sMTM4OlsyLDc0XSwxMzk6WzIsNzRdfSx7MTpbMiwyOF0sNjpbMiwyOF0sMjU6WzIsMjhdLDI2OlsyLDI4XSw0OTpbMiwyOF0sNTQ6WzIsMjhdLDU3OlsyLDI4XSw2NjpbMiwyOF0sNjc6WzIsMjhdLDY4OlsyLDI4XSw2OTpbMiwyOF0sNzE6WzIsMjhdLDczOlsyLDI4XSw3NDpbMiwyOF0sNzg6WzIsMjhdLDg0OlsyLDI4XSw4NTpbMiwyOF0sODY6WzIsMjhdLDkxOlsyLDI4XSw5MzpbMiwyOF0sMTAyOlsyLDI4XSwxMDQ6WzIsMjhdLDEwNTpbMiwyOF0sMTA2OlsyLDI4XSwxMTA6WzIsMjhdLDExODpbMiwyOF0sMTI2OlsyLDI4XSwxMjk6WzIsMjhdLDEzMDpbMiwyOF0sMTMzOlsyLDI4XSwxMzQ6WzIsMjhdLDEzNTpbMiwyOF0sMTM2OlsyLDI4XSwxMzc6WzIsMjhdLDEzODpbMiwyOF0sMTM5OlsyLDI4XX0sezE6WzIsMjldLDY6WzIsMjldLDI1OlsyLDI5XSwyNjpbMiwyOV0sNDk6WzIsMjldLDU0OlsyLDI5XSw1NzpbMiwyOV0sNjY6WzIsMjldLDY3OlsyLDI5XSw2ODpbMiwyOV0sNjk6WzIsMjldLDcxOlsyLDI5XSw3MzpbMiwyOV0sNzQ6WzIsMjldLDc4OlsyLDI5XSw4NDpbMiwyOV0sODU6WzIsMjldLDg2OlsyLDI5XSw5MTpbMiwyOV0sOTM6WzIsMjldLDEwMjpbMiwyOV0sMTA0OlsyLDI5XSwxMDU6WzIsMjldLDEwNjpbMiwyOV0sMTEwOlsyLDI5XSwxMTg6WzIsMjldLDEyNjpbMiwyOV0sMTI5OlsyLDI5XSwxMzA6WzIsMjldLDEzMzpbMiwyOV0sMTM0OlsyLDI5XSwxMzU6WzIsMjldLDEzNjpbMiwyOV0sMTM3OlsyLDI5XSwxMzg6WzIsMjldLDEzOTpbMiwyOV19LHsxOlsyLDMwXSw2OlsyLDMwXSwyNTpbMiwzMF0sMjY6WzIsMzBdLDQ5OlsyLDMwXSw1NDpbMiwzMF0sNTc6WzIsMzBdLDY2OlsyLDMwXSw2NzpbMiwzMF0sNjg6WzIsMzBdLDY5OlsyLDMwXSw3MTpbMiwzMF0sNzM6WzIsMzBdLDc0OlsyLDMwXSw3ODpbMiwzMF0sODQ6WzIsMzBdLDg1OlsyLDMwXSw4NjpbMiwzMF0sOTE6WzIsMzBdLDkzOlsyLDMwXSwxMDI6WzIsMzBdLDEwNDpbMiwzMF0sMTA1OlsyLDMwXSwxMDY6WzIsMzBdLDExMDpbMiwzMF0sMTE4OlsyLDMwXSwxMjY6WzIsMzBdLDEyOTpbMiwzMF0sMTMwOlsyLDMwXSwxMzM6WzIsMzBdLDEzNDpbMiwzMF0sMTM1OlsyLDMwXSwxMzY6WzIsMzBdLDEzNzpbMiwzMF0sMTM4OlsyLDMwXSwxMzk6WzIsMzBdfSx7MTpbMiwzMV0sNjpbMiwzMV0sMjU6WzIsMzFdLDI2OlsyLDMxXSw0OTpbMiwzMV0sNTQ6WzIsMzFdLDU3OlsyLDMxXSw2NjpbMiwzMV0sNjc6WzIsMzFdLDY4OlsyLDMxXSw2OTpbMiwzMV0sNzE6WzIsMzFdLDczOlsyLDMxXSw3NDpbMiwzMV0sNzg6WzIsMzFdLDg0OlsyLDMxXSw4NTpbMiwzMV0sODY6WzIsMzFdLDkxOlsyLDMxXSw5MzpbMiwzMV0sMTAyOlsyLDMxXSwxMDQ6WzIsMzFdLDEwNTpbMiwzMV0sMTA2OlsyLDMxXSwxMTA6WzIsMzFdLDExODpbMiwzMV0sMTI2OlsyLDMxXSwxMjk6WzIsMzFdLDEzMDpbMiwzMV0sMTMzOlsyLDMxXSwxMzQ6WzIsMzFdLDEzNTpbMiwzMV0sMTM2OlsyLDMxXSwxMzc6WzIsMzFdLDEzODpbMiwzMV0sMTM5OlsyLDMxXX0sezE6WzIsMzJdLDY6WzIsMzJdLDI1OlsyLDMyXSwyNjpbMiwzMl0sNDk6WzIsMzJdLDU0OlsyLDMyXSw1NzpbMiwzMl0sNjY6WzIsMzJdLDY3OlsyLDMyXSw2ODpbMiwzMl0sNjk6WzIsMzJdLDcxOlsyLDMyXSw3MzpbMiwzMl0sNzQ6WzIsMzJdLDc4OlsyLDMyXSw4NDpbMiwzMl0sODU6WzIsMzJdLDg2OlsyLDMyXSw5MTpbMiwzMl0sOTM6WzIsMzJdLDEwMjpbMiwzMl0sMTA0OlsyLDMyXSwxMDU6WzIsMzJdLDEwNjpbMiwzMl0sMTEwOlsyLDMyXSwxMTg6WzIsMzJdLDEyNjpbMiwzMl0sMTI5OlsyLDMyXSwxMzA6WzIsMzJdLDEzMzpbMiwzMl0sMTM0OlsyLDMyXSwxMzU6WzIsMzJdLDEzNjpbMiwzMl0sMTM3OlsyLDMyXSwxMzg6WzIsMzJdLDEzOTpbMiwzMl19LHsxOlsyLDMzXSw2OlsyLDMzXSwyNTpbMiwzM10sMjY6WzIsMzNdLDQ5OlsyLDMzXSw1NDpbMiwzM10sNTc6WzIsMzNdLDY2OlsyLDMzXSw2NzpbMiwzM10sNjg6WzIsMzNdLDY5OlsyLDMzXSw3MTpbMiwzM10sNzM6WzIsMzNdLDc0OlsyLDMzXSw3ODpbMiwzM10sODQ6WzIsMzNdLDg1OlsyLDMzXSw4NjpbMiwzM10sOTE6WzIsMzNdLDkzOlsyLDMzXSwxMDI6WzIsMzNdLDEwNDpbMiwzM10sMTA1OlsyLDMzXSwxMDY6WzIsMzNdLDExMDpbMiwzM10sMTE4OlsyLDMzXSwxMjY6WzIsMzNdLDEyOTpbMiwzM10sMTMwOlsyLDMzXSwxMzM6WzIsMzNdLDEzNDpbMiwzM10sMTM1OlsyLDMzXSwxMzY6WzIsMzNdLDEzNzpbMiwzM10sMTM4OlsyLDMzXSwxMzk6WzIsMzNdfSx7MTpbMiwzNF0sNjpbMiwzNF0sMjU6WzIsMzRdLDI2OlsyLDM0XSw0OTpbMiwzNF0sNTQ6WzIsMzRdLDU3OlsyLDM0XSw2NjpbMiwzNF0sNjc6WzIsMzRdLDY4OlsyLDM0XSw2OTpbMiwzNF0sNzE6WzIsMzRdLDczOlsyLDM0XSw3NDpbMiwzNF0sNzg6WzIsMzRdLDg0OlsyLDM0XSw4NTpbMiwzNF0sODY6WzIsMzRdLDkxOlsyLDM0XSw5MzpbMiwzNF0sMTAyOlsyLDM0XSwxMDQ6WzIsMzRdLDEwNTpbMiwzNF0sMTA2OlsyLDM0XSwxMTA6WzIsMzRdLDExODpbMiwzNF0sMTI2OlsyLDM0XSwxMjk6WzIsMzRdLDEzMDpbMiwzNF0sMTMzOlsyLDM0XSwxMzQ6WzIsMzRdLDEzNTpbMiwzNF0sMTM2OlsyLDM0XSwxMzc6WzIsMzRdLDEzODpbMiwzNF0sMTM5OlsyLDM0XX0sezQ6MTQxLDU6Myw3OjQsODo1LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjU6WzEsMTQyXSwyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezc6MTQzLDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjU6WzEsMTQ3XSwyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU3OlsxLDE0OV0sNTg6NDYsNTk6NDcsNjA6MTQ4LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg3OjE0NSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5MTpbMSwxNDRdLDk0OjE0Niw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHsxOlsyLDExMl0sNjpbMiwxMTJdLDI1OlsyLDExMl0sMjY6WzIsMTEyXSw0OTpbMiwxMTJdLDU0OlsyLDExMl0sNTc6WzIsMTEyXSw2NjpbMiwxMTJdLDY3OlsyLDExMl0sNjg6WzIsMTEyXSw2OTpbMiwxMTJdLDcxOlsyLDExMl0sNzM6WzIsMTEyXSw3NDpbMiwxMTJdLDc4OlsyLDExMl0sODQ6WzIsMTEyXSw4NTpbMiwxMTJdLDg2OlsyLDExMl0sOTE6WzIsMTEyXSw5MzpbMiwxMTJdLDEwMjpbMiwxMTJdLDEwNDpbMiwxMTJdLDEwNTpbMiwxMTJdLDEwNjpbMiwxMTJdLDExMDpbMiwxMTJdLDExODpbMiwxMTJdLDEyNjpbMiwxMTJdLDEyOTpbMiwxMTJdLDEzMDpbMiwxMTJdLDEzMzpbMiwxMTJdLDEzNDpbMiwxMTJdLDEzNTpbMiwxMTJdLDEzNjpbMiwxMTJdLDEzNzpbMiwxMTJdLDEzODpbMiwxMTJdLDEzOTpbMiwxMTJdfSx7MTpbMiwxMTNdLDY6WzIsMTEzXSwyNTpbMiwxMTNdLDI2OlsyLDExM10sMjc6MTUwLDI4OlsxLDcyXSw0OTpbMiwxMTNdLDU0OlsyLDExM10sNTc6WzIsMTEzXSw2NjpbMiwxMTNdLDY3OlsyLDExM10sNjg6WzIsMTEzXSw2OTpbMiwxMTNdLDcxOlsyLDExM10sNzM6WzIsMTEzXSw3NDpbMiwxMTNdLDc4OlsyLDExM10sODQ6WzIsMTEzXSw4NTpbMiwxMTNdLDg2OlsyLDExM10sOTE6WzIsMTEzXSw5MzpbMiwxMTNdLDEwMjpbMiwxMTNdLDEwNDpbMiwxMTNdLDEwNTpbMiwxMTNdLDEwNjpbMiwxMTNdLDExMDpbMiwxMTNdLDExODpbMiwxMTNdLDEyNjpbMiwxMTNdLDEyOTpbMiwxMTNdLDEzMDpbMiwxMTNdLDEzMzpbMiwxMTNdLDEzNDpbMiwxMTNdLDEzNTpbMiwxMTNdLDEzNjpbMiwxMTNdLDEzNzpbMiwxMTNdLDEzODpbMiwxMTNdLDEzOTpbMiwxMTNdfSx7MjU6WzIsNTBdfSx7MjU6WzIsNTFdfSx7MTpbMiw2OF0sNjpbMiw2OF0sMjU6WzIsNjhdLDI2OlsyLDY4XSw0MDpbMiw2OF0sNDk6WzIsNjhdLDU0OlsyLDY4XSw1NzpbMiw2OF0sNjY6WzIsNjhdLDY3OlsyLDY4XSw2ODpbMiw2OF0sNjk6WzIsNjhdLDcxOlsyLDY4XSw3MzpbMiw2OF0sNzQ6WzIsNjhdLDc4OlsyLDY4XSw4MDpbMiw2OF0sODQ6WzIsNjhdLDg1OlsyLDY4XSw4NjpbMiw2OF0sOTE6WzIsNjhdLDkzOlsyLDY4XSwxMDI6WzIsNjhdLDEwNDpbMiw2OF0sMTA1OlsyLDY4XSwxMDY6WzIsNjhdLDExMDpbMiw2OF0sMTE4OlsyLDY4XSwxMjY6WzIsNjhdLDEyOTpbMiw2OF0sMTMwOlsyLDY4XSwxMzE6WzIsNjhdLDEzMjpbMiw2OF0sMTMzOlsyLDY4XSwxMzQ6WzIsNjhdLDEzNTpbMiw2OF0sMTM2OlsyLDY4XSwxMzc6WzIsNjhdLDEzODpbMiw2OF0sMTM5OlsyLDY4XSwxNDA6WzIsNjhdfSx7MTpbMiw3MV0sNjpbMiw3MV0sMjU6WzIsNzFdLDI2OlsyLDcxXSw0MDpbMiw3MV0sNDk6WzIsNzFdLDU0OlsyLDcxXSw1NzpbMiw3MV0sNjY6WzIsNzFdLDY3OlsyLDcxXSw2ODpbMiw3MV0sNjk6WzIsNzFdLDcxOlsyLDcxXSw3MzpbMiw3MV0sNzQ6WzIsNzFdLDc4OlsyLDcxXSw4MDpbMiw3MV0sODQ6WzIsNzFdLDg1OlsyLDcxXSw4NjpbMiw3MV0sOTE6WzIsNzFdLDkzOlsyLDcxXSwxMDI6WzIsNzFdLDEwNDpbMiw3MV0sMTA1OlsyLDcxXSwxMDY6WzIsNzFdLDExMDpbMiw3MV0sMTE4OlsyLDcxXSwxMjY6WzIsNzFdLDEyOTpbMiw3MV0sMTMwOlsyLDcxXSwxMzE6WzIsNzFdLDEzMjpbMiw3MV0sMTMzOlsyLDcxXSwxMzQ6WzIsNzFdLDEzNTpbMiw3MV0sMTM2OlsyLDcxXSwxMzc6WzIsNzFdLDEzODpbMiw3MV0sMTM5OlsyLDcxXSwxNDA6WzIsNzFdfSx7NzoxNTEsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezc6MTUyLDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs3OjE1Myw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7NzoxNTUsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNDoxNTQsMjU6WzEsMTE1XSwyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezI3OjE2MCwyODpbMSw3Ml0sNDQ6MTYxLDU4OjE2Miw1OToxNjMsNjQ6MTU2LDc2OlsxLDY5XSw4OTpbMSwxMTJdLDkwOlsxLDU2XSwxMTM6MTU3LDExNDpbMSwxNThdLDExNToxNTl9LHsxMTI6MTY0LDExNjpbMSwxNjVdLDExNzpbMSwxNjZdfSx7NjpbMiw5MV0sMTA6MTcwLDI1OlsyLDkxXSwyNzoxNzEsMjg6WzEsNzJdLDI5OjE3MiwzMDpbMSw3MF0sMzE6WzEsNzFdLDQxOjE2OCw0MjoxNjksNDQ6MTczLDQ2OlsxLDQ1XSw1NDpbMiw5MV0sNzc6MTY3LDc4OlsyLDkxXSw4OTpbMSwxMTJdfSx7MTpbMiwyNl0sNjpbMiwyNl0sMjU6WzIsMjZdLDI2OlsyLDI2XSw0MzpbMiwyNl0sNDk6WzIsMjZdLDU0OlsyLDI2XSw1NzpbMiwyNl0sNjY6WzIsMjZdLDY3OlsyLDI2XSw2ODpbMiwyNl0sNjk6WzIsMjZdLDcxOlsyLDI2XSw3MzpbMiwyNl0sNzQ6WzIsMjZdLDc4OlsyLDI2XSw4NDpbMiwyNl0sODU6WzIsMjZdLDg2OlsyLDI2XSw5MTpbMiwyNl0sOTM6WzIsMjZdLDEwMjpbMiwyNl0sMTA0OlsyLDI2XSwxMDU6WzIsMjZdLDEwNjpbMiwyNl0sMTEwOlsyLDI2XSwxMTg6WzIsMjZdLDEyNjpbMiwyNl0sMTI5OlsyLDI2XSwxMzA6WzIsMjZdLDEzMzpbMiwyNl0sMTM0OlsyLDI2XSwxMzU6WzIsMjZdLDEzNjpbMiwyNl0sMTM3OlsyLDI2XSwxMzg6WzIsMjZdLDEzOTpbMiwyNl19LHsxOlsyLDI3XSw2OlsyLDI3XSwyNTpbMiwyN10sMjY6WzIsMjddLDQzOlsyLDI3XSw0OTpbMiwyN10sNTQ6WzIsMjddLDU3OlsyLDI3XSw2NjpbMiwyN10sNjc6WzIsMjddLDY4OlsyLDI3XSw2OTpbMiwyN10sNzE6WzIsMjddLDczOlsyLDI3XSw3NDpbMiwyN10sNzg6WzIsMjddLDg0OlsyLDI3XSw4NTpbMiwyN10sODY6WzIsMjddLDkxOlsyLDI3XSw5MzpbMiwyN10sMTAyOlsyLDI3XSwxMDQ6WzIsMjddLDEwNTpbMiwyN10sMTA2OlsyLDI3XSwxMTA6WzIsMjddLDExODpbMiwyN10sMTI2OlsyLDI3XSwxMjk6WzIsMjddLDEzMDpbMiwyN10sMTMzOlsyLDI3XSwxMzQ6WzIsMjddLDEzNTpbMiwyN10sMTM2OlsyLDI3XSwxMzc6WzIsMjddLDEzODpbMiwyN10sMTM5OlsyLDI3XX0sezE6WzIsMjVdLDY6WzIsMjVdLDI1OlsyLDI1XSwyNjpbMiwyNV0sNDA6WzIsMjVdLDQzOlsyLDI1XSw0OTpbMiwyNV0sNTQ6WzIsMjVdLDU3OlsyLDI1XSw2NjpbMiwyNV0sNjc6WzIsMjVdLDY4OlsyLDI1XSw2OTpbMiwyNV0sNzE6WzIsMjVdLDczOlsyLDI1XSw3NDpbMiwyNV0sNzg6WzIsMjVdLDgwOlsyLDI1XSw4NDpbMiwyNV0sODU6WzIsMjVdLDg2OlsyLDI1XSw5MTpbMiwyNV0sOTM6WzIsMjVdLDEwMjpbMiwyNV0sMTA0OlsyLDI1XSwxMDU6WzIsMjVdLDEwNjpbMiwyNV0sMTEwOlsyLDI1XSwxMTY6WzIsMjVdLDExNzpbMiwyNV0sMTE4OlsyLDI1XSwxMjY6WzIsMjVdLDEyOTpbMiwyNV0sMTMwOlsyLDI1XSwxMzE6WzIsMjVdLDEzMjpbMiwyNV0sMTMzOlsyLDI1XSwxMzQ6WzIsMjVdLDEzNTpbMiwyNV0sMTM2OlsyLDI1XSwxMzc6WzIsMjVdLDEzODpbMiwyNV0sMTM5OlsyLDI1XSwxNDA6WzIsMjVdfSx7MTpbMiw1XSw1OjE3NCw2OlsyLDVdLDc6NCw4OjUsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNjpbMiw1XSwyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAyOlsyLDVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHsxOlsyLDE5Nl0sNjpbMiwxOTZdLDI1OlsyLDE5Nl0sMjY6WzIsMTk2XSw0OTpbMiwxOTZdLDU0OlsyLDE5Nl0sNTc6WzIsMTk2XSw3MzpbMiwxOTZdLDc4OlsyLDE5Nl0sODY6WzIsMTk2XSw5MTpbMiwxOTZdLDkzOlsyLDE5Nl0sMTAyOlsyLDE5Nl0sMTA0OlsyLDE5Nl0sMTA1OlsyLDE5Nl0sMTA2OlsyLDE5Nl0sMTEwOlsyLDE5Nl0sMTE4OlsyLDE5Nl0sMTI2OlsyLDE5Nl0sMTI5OlsyLDE5Nl0sMTMwOlsyLDE5Nl0sMTMzOlsyLDE5Nl0sMTM0OlsyLDE5Nl0sMTM1OlsyLDE5Nl0sMTM2OlsyLDE5Nl0sMTM3OlsyLDE5Nl0sMTM4OlsyLDE5Nl0sMTM5OlsyLDE5Nl19LHs3OjE3NSw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7NzoxNzYsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezc6MTc3LDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs3OjE3OCw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7NzoxNzksODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezc6MTgwLDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs3OjE4MSw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7NzoxODIsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezc6MTgzLDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHsxOlsyLDE1MF0sNjpbMiwxNTBdLDI1OlsyLDE1MF0sMjY6WzIsMTUwXSw0OTpbMiwxNTBdLDU0OlsyLDE1MF0sNTc6WzIsMTUwXSw3MzpbMiwxNTBdLDc4OlsyLDE1MF0sODY6WzIsMTUwXSw5MTpbMiwxNTBdLDkzOlsyLDE1MF0sMTAyOlsyLDE1MF0sMTA0OlsyLDE1MF0sMTA1OlsyLDE1MF0sMTA2OlsyLDE1MF0sMTEwOlsyLDE1MF0sMTE4OlsyLDE1MF0sMTI2OlsyLDE1MF0sMTI5OlsyLDE1MF0sMTMwOlsyLDE1MF0sMTMzOlsyLDE1MF0sMTM0OlsyLDE1MF0sMTM1OlsyLDE1MF0sMTM2OlsyLDE1MF0sMTM3OlsyLDE1MF0sMTM4OlsyLDE1MF0sMTM5OlsyLDE1MF19LHsxOlsyLDE1NV0sNjpbMiwxNTVdLDI1OlsyLDE1NV0sMjY6WzIsMTU1XSw0OTpbMiwxNTVdLDU0OlsyLDE1NV0sNTc6WzIsMTU1XSw3MzpbMiwxNTVdLDc4OlsyLDE1NV0sODY6WzIsMTU1XSw5MTpbMiwxNTVdLDkzOlsyLDE1NV0sMTAyOlsyLDE1NV0sMTA0OlsyLDE1NV0sMTA1OlsyLDE1NV0sMTA2OlsyLDE1NV0sMTEwOlsyLDE1NV0sMTE4OlsyLDE1NV0sMTI2OlsyLDE1NV0sMTI5OlsyLDE1NV0sMTMwOlsyLDE1NV0sMTMzOlsyLDE1NV0sMTM0OlsyLDE1NV0sMTM1OlsyLDE1NV0sMTM2OlsyLDE1NV0sMTM3OlsyLDE1NV0sMTM4OlsyLDE1NV0sMTM5OlsyLDE1NV19LHs3OjE4NCw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7MTpbMiwxNDldLDY6WzIsMTQ5XSwyNTpbMiwxNDldLDI2OlsyLDE0OV0sNDk6WzIsMTQ5XSw1NDpbMiwxNDldLDU3OlsyLDE0OV0sNzM6WzIsMTQ5XSw3ODpbMiwxNDldLDg2OlsyLDE0OV0sOTE6WzIsMTQ5XSw5MzpbMiwxNDldLDEwMjpbMiwxNDldLDEwNDpbMiwxNDldLDEwNTpbMiwxNDldLDEwNjpbMiwxNDldLDExMDpbMiwxNDldLDExODpbMiwxNDldLDEyNjpbMiwxNDldLDEyOTpbMiwxNDldLDEzMDpbMiwxNDldLDEzMzpbMiwxNDldLDEzNDpbMiwxNDldLDEzNTpbMiwxNDldLDEzNjpbMiwxNDldLDEzNzpbMiwxNDldLDEzODpbMiwxNDldLDEzOTpbMiwxNDldfSx7MTpbMiwxNTRdLDY6WzIsMTU0XSwyNTpbMiwxNTRdLDI2OlsyLDE1NF0sNDk6WzIsMTU0XSw1NDpbMiwxNTRdLDU3OlsyLDE1NF0sNzM6WzIsMTU0XSw3ODpbMiwxNTRdLDg2OlsyLDE1NF0sOTE6WzIsMTU0XSw5MzpbMiwxNTRdLDEwMjpbMiwxNTRdLDEwNDpbMiwxNTRdLDEwNTpbMiwxNTRdLDEwNjpbMiwxNTRdLDExMDpbMiwxNTRdLDExODpbMiwxNTRdLDEyNjpbMiwxNTRdLDEyOTpbMiwxNTRdLDEzMDpbMiwxNTRdLDEzMzpbMiwxNTRdLDEzNDpbMiwxNTRdLDEzNTpbMiwxNTRdLDEzNjpbMiwxNTRdLDEzNzpbMiwxNTRdLDEzODpbMiwxNTRdLDEzOTpbMiwxNTRdfSx7ODI6MTg1LDg1OlsxLDEwM119LHsxOlsyLDY5XSw2OlsyLDY5XSwyNTpbMiw2OV0sMjY6WzIsNjldLDQwOlsyLDY5XSw0OTpbMiw2OV0sNTQ6WzIsNjldLDU3OlsyLDY5XSw2NjpbMiw2OV0sNjc6WzIsNjldLDY4OlsyLDY5XSw2OTpbMiw2OV0sNzE6WzIsNjldLDczOlsyLDY5XSw3NDpbMiw2OV0sNzg6WzIsNjldLDgwOlsyLDY5XSw4NDpbMiw2OV0sODU6WzIsNjldLDg2OlsyLDY5XSw5MTpbMiw2OV0sOTM6WzIsNjldLDEwMjpbMiw2OV0sMTA0OlsyLDY5XSwxMDU6WzIsNjldLDEwNjpbMiw2OV0sMTEwOlsyLDY5XSwxMTg6WzIsNjldLDEyNjpbMiw2OV0sMTI5OlsyLDY5XSwxMzA6WzIsNjldLDEzMTpbMiw2OV0sMTMyOlsyLDY5XSwxMzM6WzIsNjldLDEzNDpbMiw2OV0sMTM1OlsyLDY5XSwxMzY6WzIsNjldLDEzNzpbMiw2OV0sMTM4OlsyLDY5XSwxMzk6WzIsNjldLDE0MDpbMiw2OV19LHs4NTpbMiwxMDldfSx7Mjc6MTg2LDI4OlsxLDcyXX0sezI3OjE4NywyODpbMSw3Ml19LHsxOlsyLDg0XSw2OlsyLDg0XSwyNTpbMiw4NF0sMjY6WzIsODRdLDI3OjE4OCwyODpbMSw3Ml0sNDA6WzIsODRdLDQ5OlsyLDg0XSw1NDpbMiw4NF0sNTc6WzIsODRdLDY2OlsyLDg0XSw2NzpbMiw4NF0sNjg6WzIsODRdLDY5OlsyLDg0XSw3MTpbMiw4NF0sNzM6WzIsODRdLDc0OlsyLDg0XSw3ODpbMiw4NF0sODA6WzIsODRdLDg0OlsyLDg0XSw4NTpbMiw4NF0sODY6WzIsODRdLDkxOlsyLDg0XSw5MzpbMiw4NF0sMTAyOlsyLDg0XSwxMDQ6WzIsODRdLDEwNTpbMiw4NF0sMTA2OlsyLDg0XSwxMTA6WzIsODRdLDExODpbMiw4NF0sMTI2OlsyLDg0XSwxMjk6WzIsODRdLDEzMDpbMiw4NF0sMTMxOlsyLDg0XSwxMzI6WzIsODRdLDEzMzpbMiw4NF0sMTM0OlsyLDg0XSwxMzU6WzIsODRdLDEzNjpbMiw4NF0sMTM3OlsyLDg0XSwxMzg6WzIsODRdLDEzOTpbMiw4NF0sMTQwOlsyLDg0XX0sezI3OjE4OSwyODpbMSw3Ml19LHsxOlsyLDg1XSw2OlsyLDg1XSwyNTpbMiw4NV0sMjY6WzIsODVdLDQwOlsyLDg1XSw0OTpbMiw4NV0sNTQ6WzIsODVdLDU3OlsyLDg1XSw2NjpbMiw4NV0sNjc6WzIsODVdLDY4OlsyLDg1XSw2OTpbMiw4NV0sNzE6WzIsODVdLDczOlsyLDg1XSw3NDpbMiw4NV0sNzg6WzIsODVdLDgwOlsyLDg1XSw4NDpbMiw4NV0sODU6WzIsODVdLDg2OlsyLDg1XSw5MTpbMiw4NV0sOTM6WzIsODVdLDEwMjpbMiw4NV0sMTA0OlsyLDg1XSwxMDU6WzIsODVdLDEwNjpbMiw4NV0sMTEwOlsyLDg1XSwxMTg6WzIsODVdLDEyNjpbMiw4NV0sMTI5OlsyLDg1XSwxMzA6WzIsODVdLDEzMTpbMiw4NV0sMTMyOlsyLDg1XSwxMzM6WzIsODVdLDEzNDpbMiw4NV0sMTM1OlsyLDg1XSwxMzY6WzIsODVdLDEzNzpbMiw4NV0sMTM4OlsyLDg1XSwxMzk6WzIsODVdLDE0MDpbMiw4NV19LHs3OjE5MSw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTc6WzEsMTk1XSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3MjoxOTAsNzU6MTkyLDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDkyOjE5Myw5MzpbMSwxOTRdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezcwOjE5Niw3MTpbMSw5N10sNzQ6WzEsOThdfSx7ODI6MTk3LDg1OlsxLDEwM119LHsxOlsyLDcwXSw2OlsyLDcwXSwyNTpbMiw3MF0sMjY6WzIsNzBdLDQwOlsyLDcwXSw0OTpbMiw3MF0sNTQ6WzIsNzBdLDU3OlsyLDcwXSw2NjpbMiw3MF0sNjc6WzIsNzBdLDY4OlsyLDcwXSw2OTpbMiw3MF0sNzE6WzIsNzBdLDczOlsyLDcwXSw3NDpbMiw3MF0sNzg6WzIsNzBdLDgwOlsyLDcwXSw4NDpbMiw3MF0sODU6WzIsNzBdLDg2OlsyLDcwXSw5MTpbMiw3MF0sOTM6WzIsNzBdLDEwMjpbMiw3MF0sMTA0OlsyLDcwXSwxMDU6WzIsNzBdLDEwNjpbMiw3MF0sMTEwOlsyLDcwXSwxMTg6WzIsNzBdLDEyNjpbMiw3MF0sMTI5OlsyLDcwXSwxMzA6WzIsNzBdLDEzMTpbMiw3MF0sMTMyOlsyLDcwXSwxMzM6WzIsNzBdLDEzNDpbMiw3MF0sMTM1OlsyLDcwXSwxMzY6WzIsNzBdLDEzNzpbMiw3MF0sMTM4OlsyLDcwXSwxMzk6WzIsNzBdLDE0MDpbMiw3MF19LHs2OlsxLDE5OV0sNzoxOTgsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNTpbMSwyMDBdLDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7MTpbMiwxMDddLDY6WzIsMTA3XSwyNTpbMiwxMDddLDI2OlsyLDEwN10sNDk6WzIsMTA3XSw1NDpbMiwxMDddLDU3OlsyLDEwN10sNjY6WzIsMTA3XSw2NzpbMiwxMDddLDY4OlsyLDEwN10sNjk6WzIsMTA3XSw3MTpbMiwxMDddLDczOlsyLDEwN10sNzQ6WzIsMTA3XSw3ODpbMiwxMDddLDg0OlsyLDEwN10sODU6WzIsMTA3XSw4NjpbMiwxMDddLDkxOlsyLDEwN10sOTM6WzIsMTA3XSwxMDI6WzIsMTA3XSwxMDQ6WzIsMTA3XSwxMDU6WzIsMTA3XSwxMDY6WzIsMTA3XSwxMTA6WzIsMTA3XSwxMTg6WzIsMTA3XSwxMjY6WzIsMTA3XSwxMjk6WzIsMTA3XSwxMzA6WzIsMTA3XSwxMzM6WzIsMTA3XSwxMzQ6WzIsMTA3XSwxMzU6WzIsMTA3XSwxMzY6WzIsMTA3XSwxMzc6WzIsMTA3XSwxMzg6WzIsMTA3XSwxMzk6WzIsMTA3XX0sezc6MjAzLDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjU6WzEsMTQ3XSwyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU3OlsxLDE0OV0sNTg6NDYsNTk6NDcsNjA6MTQ4LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg2OlsxLDIwMV0sODc6MjAyLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk0OjE0Niw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs2OlsyLDUyXSwyNTpbMiw1Ml0sNDk6WzEsMjA0XSw1MzoyMDYsNTQ6WzEsMjA1XX0sezY6WzIsNTVdLDI1OlsyLDU1XSwyNjpbMiw1NV0sNDk6WzIsNTVdLDU0OlsyLDU1XX0sezY6WzIsNTldLDI1OlsyLDU5XSwyNjpbMiw1OV0sNDA6WzEsMjA4XSw0OTpbMiw1OV0sNTQ6WzIsNTldLDU3OlsxLDIwN119LHs2OlsyLDYyXSwyNTpbMiw2Ml0sMjY6WzIsNjJdLDQ5OlsyLDYyXSw1NDpbMiw2Ml19LHs2OlsyLDYzXSwyNTpbMiw2M10sMjY6WzIsNjNdLDQwOlsyLDYzXSw0OTpbMiw2M10sNTQ6WzIsNjNdLDU3OlsyLDYzXX0sezY6WzIsNjRdLDI1OlsyLDY0XSwyNjpbMiw2NF0sNDA6WzIsNjRdLDQ5OlsyLDY0XSw1NDpbMiw2NF0sNTc6WzIsNjRdfSx7NjpbMiw2NV0sMjU6WzIsNjVdLDI2OlsyLDY1XSw0MDpbMiw2NV0sNDk6WzIsNjVdLDU0OlsyLDY1XSw1NzpbMiw2NV19LHs2OlsyLDY2XSwyNTpbMiw2Nl0sMjY6WzIsNjZdLDQwOlsyLDY2XSw0OTpbMiw2Nl0sNTQ6WzIsNjZdLDU3OlsyLDY2XX0sezI3OjE1MCwyODpbMSw3Ml19LHs3OjIwMyw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI1OlsxLDE0N10sMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1NzpbMSwxNDldLDU4OjQ2LDU5OjQ3LDYwOjE0OCw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4NzoxNDUsODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTE6WzEsMTQ0XSw5NDoxNDYsOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7MTpbMiw0OV0sNjpbMiw0OV0sMjU6WzIsNDldLDI2OlsyLDQ5XSw0OTpbMiw0OV0sNTQ6WzIsNDldLDU3OlsyLDQ5XSw3MzpbMiw0OV0sNzg6WzIsNDldLDg2OlsyLDQ5XSw5MTpbMiw0OV0sOTM6WzIsNDldLDEwMjpbMiw0OV0sMTA0OlsyLDQ5XSwxMDU6WzIsNDldLDEwNjpbMiw0OV0sMTEwOlsyLDQ5XSwxMTg6WzIsNDldLDEyNjpbMiw0OV0sMTI5OlsyLDQ5XSwxMzA6WzIsNDldLDEzMzpbMiw0OV0sMTM0OlsyLDQ5XSwxMzU6WzIsNDldLDEzNjpbMiw0OV0sMTM3OlsyLDQ5XSwxMzg6WzIsNDldLDEzOTpbMiw0OV19LHs0OjIxMCw1OjMsNzo0LDg6NSw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI2OlsxLDIwOV0sMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHsxOlsyLDE4OF0sNjpbMiwxODhdLDI1OlsyLDE4OF0sMjY6WzIsMTg4XSw0OTpbMiwxODhdLDU0OlsyLDE4OF0sNTc6WzIsMTg4XSw3MzpbMiwxODhdLDc4OlsyLDE4OF0sODY6WzIsMTg4XSw5MTpbMiwxODhdLDkzOlsyLDE4OF0sMTAyOlsyLDE4OF0sMTAzOjg0LDEwNDpbMiwxODhdLDEwNTpbMiwxODhdLDEwNjpbMiwxODhdLDEwOTo4NSwxMTA6WzIsMTg4XSwxMTE6NjgsMTE4OlsyLDE4OF0sMTI2OlsyLDE4OF0sMTI5OlsyLDE4OF0sMTMwOlsyLDE4OF0sMTMzOlsxLDc0XSwxMzQ6WzIsMTg4XSwxMzU6WzIsMTg4XSwxMzY6WzIsMTg4XSwxMzc6WzIsMTg4XSwxMzg6WzIsMTg4XSwxMzk6WzIsMTg4XX0sezEwMzo4NywxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA5Ojg4LDExMDpbMSw2N10sMTExOjY4LDEyNjpbMSw4Nl19LHsxOlsyLDE4OV0sNjpbMiwxODldLDI1OlsyLDE4OV0sMjY6WzIsMTg5XSw0OTpbMiwxODldLDU0OlsyLDE4OV0sNTc6WzIsMTg5XSw3MzpbMiwxODldLDc4OlsyLDE4OV0sODY6WzIsMTg5XSw5MTpbMiwxODldLDkzOlsyLDE4OV0sMTAyOlsyLDE4OV0sMTAzOjg0LDEwNDpbMiwxODldLDEwNTpbMiwxODldLDEwNjpbMiwxODldLDEwOTo4NSwxMTA6WzIsMTg5XSwxMTE6NjgsMTE4OlsyLDE4OV0sMTI2OlsyLDE4OV0sMTI5OlsyLDE4OV0sMTMwOlsyLDE4OV0sMTMzOlsxLDc0XSwxMzQ6WzIsMTg5XSwxMzU6WzEsNzhdLDEzNjpbMiwxODldLDEzNzpbMiwxODldLDEzODpbMiwxODldLDEzOTpbMiwxODldfSx7MTpbMiwxOTBdLDY6WzIsMTkwXSwyNTpbMiwxOTBdLDI2OlsyLDE5MF0sNDk6WzIsMTkwXSw1NDpbMiwxOTBdLDU3OlsyLDE5MF0sNzM6WzIsMTkwXSw3ODpbMiwxOTBdLDg2OlsyLDE5MF0sOTE6WzIsMTkwXSw5MzpbMiwxOTBdLDEwMjpbMiwxOTBdLDEwMzo4NCwxMDQ6WzIsMTkwXSwxMDU6WzIsMTkwXSwxMDY6WzIsMTkwXSwxMDk6ODUsMTEwOlsyLDE5MF0sMTExOjY4LDExODpbMiwxOTBdLDEyNjpbMiwxOTBdLDEyOTpbMiwxOTBdLDEzMDpbMiwxOTBdLDEzMzpbMSw3NF0sMTM0OlsyLDE5MF0sMTM1OlsxLDc4XSwxMzY6WzIsMTkwXSwxMzc6WzIsMTkwXSwxMzg6WzIsMTkwXSwxMzk6WzIsMTkwXX0sezE6WzIsMTkxXSw2OlsyLDE5MV0sMjU6WzIsMTkxXSwyNjpbMiwxOTFdLDQ5OlsyLDE5MV0sNTQ6WzIsMTkxXSw1NzpbMiwxOTFdLDczOlsyLDE5MV0sNzg6WzIsMTkxXSw4NjpbMiwxOTFdLDkxOlsyLDE5MV0sOTM6WzIsMTkxXSwxMDI6WzIsMTkxXSwxMDM6ODQsMTA0OlsyLDE5MV0sMTA1OlsyLDE5MV0sMTA2OlsyLDE5MV0sMTA5Ojg1LDExMDpbMiwxOTFdLDExMTo2OCwxMTg6WzIsMTkxXSwxMjY6WzIsMTkxXSwxMjk6WzIsMTkxXSwxMzA6WzIsMTkxXSwxMzM6WzEsNzRdLDEzNDpbMiwxOTFdLDEzNTpbMSw3OF0sMTM2OlsyLDE5MV0sMTM3OlsyLDE5MV0sMTM4OlsyLDE5MV0sMTM5OlsyLDE5MV19LHsxOlsyLDE5Ml0sNjpbMiwxOTJdLDI1OlsyLDE5Ml0sMjY6WzIsMTkyXSw0OTpbMiwxOTJdLDU0OlsyLDE5Ml0sNTc6WzIsMTkyXSw2NjpbMiw3Ml0sNjc6WzIsNzJdLDY4OlsyLDcyXSw2OTpbMiw3Ml0sNzE6WzIsNzJdLDczOlsyLDE5Ml0sNzQ6WzIsNzJdLDc4OlsyLDE5Ml0sODQ6WzIsNzJdLDg1OlsyLDcyXSw4NjpbMiwxOTJdLDkxOlsyLDE5Ml0sOTM6WzIsMTkyXSwxMDI6WzIsMTkyXSwxMDQ6WzIsMTkyXSwxMDU6WzIsMTkyXSwxMDY6WzIsMTkyXSwxMTA6WzIsMTkyXSwxMTg6WzIsMTkyXSwxMjY6WzIsMTkyXSwxMjk6WzIsMTkyXSwxMzA6WzIsMTkyXSwxMzM6WzIsMTkyXSwxMzQ6WzIsMTkyXSwxMzU6WzIsMTkyXSwxMzY6WzIsMTkyXSwxMzc6WzIsMTkyXSwxMzg6WzIsMTkyXSwxMzk6WzIsMTkyXX0sezYyOjkwLDY2OlsxLDkyXSw2NzpbMSw5M10sNjg6WzEsOTRdLDY5OlsxLDk1XSw3MDo5Niw3MTpbMSw5N10sNzQ6WzEsOThdLDgxOjg5LDg0OlsxLDkxXSw4NTpbMiwxMDhdfSx7NjI6MTAwLDY2OlsxLDkyXSw2NzpbMSw5M10sNjg6WzEsOTRdLDY5OlsxLDk1XSw3MDo5Niw3MTpbMSw5N10sNzQ6WzEsOThdLDgxOjk5LDg0OlsxLDkxXSw4NTpbMiwxMDhdfSx7NjY6WzIsNzVdLDY3OlsyLDc1XSw2ODpbMiw3NV0sNjk6WzIsNzVdLDcxOlsyLDc1XSw3NDpbMiw3NV0sODQ6WzIsNzVdLDg1OlsyLDc1XX0sezE6WzIsMTkzXSw2OlsyLDE5M10sMjU6WzIsMTkzXSwyNjpbMiwxOTNdLDQ5OlsyLDE5M10sNTQ6WzIsMTkzXSw1NzpbMiwxOTNdLDY2OlsyLDcyXSw2NzpbMiw3Ml0sNjg6WzIsNzJdLDY5OlsyLDcyXSw3MTpbMiw3Ml0sNzM6WzIsMTkzXSw3NDpbMiw3Ml0sNzg6WzIsMTkzXSw4NDpbMiw3Ml0sODU6WzIsNzJdLDg2OlsyLDE5M10sOTE6WzIsMTkzXSw5MzpbMiwxOTNdLDEwMjpbMiwxOTNdLDEwNDpbMiwxOTNdLDEwNTpbMiwxOTNdLDEwNjpbMiwxOTNdLDExMDpbMiwxOTNdLDExODpbMiwxOTNdLDEyNjpbMiwxOTNdLDEyOTpbMiwxOTNdLDEzMDpbMiwxOTNdLDEzMzpbMiwxOTNdLDEzNDpbMiwxOTNdLDEzNTpbMiwxOTNdLDEzNjpbMiwxOTNdLDEzNzpbMiwxOTNdLDEzODpbMiwxOTNdLDEzOTpbMiwxOTNdfSx7MTpbMiwxOTRdLDY6WzIsMTk0XSwyNTpbMiwxOTRdLDI2OlsyLDE5NF0sNDk6WzIsMTk0XSw1NDpbMiwxOTRdLDU3OlsyLDE5NF0sNzM6WzIsMTk0XSw3ODpbMiwxOTRdLDg2OlsyLDE5NF0sOTE6WzIsMTk0XSw5MzpbMiwxOTRdLDEwMjpbMiwxOTRdLDEwNDpbMiwxOTRdLDEwNTpbMiwxOTRdLDEwNjpbMiwxOTRdLDExMDpbMiwxOTRdLDExODpbMiwxOTRdLDEyNjpbMiwxOTRdLDEyOTpbMiwxOTRdLDEzMDpbMiwxOTRdLDEzMzpbMiwxOTRdLDEzNDpbMiwxOTRdLDEzNTpbMiwxOTRdLDEzNjpbMiwxOTRdLDEzNzpbMiwxOTRdLDEzODpbMiwxOTRdLDEzOTpbMiwxOTRdfSx7MTpbMiwxOTVdLDY6WzIsMTk1XSwyNTpbMiwxOTVdLDI2OlsyLDE5NV0sNDk6WzIsMTk1XSw1NDpbMiwxOTVdLDU3OlsyLDE5NV0sNzM6WzIsMTk1XSw3ODpbMiwxOTVdLDg2OlsyLDE5NV0sOTE6WzIsMTk1XSw5MzpbMiwxOTVdLDEwMjpbMiwxOTVdLDEwNDpbMiwxOTVdLDEwNTpbMiwxOTVdLDEwNjpbMiwxOTVdLDExMDpbMiwxOTVdLDExODpbMiwxOTVdLDEyNjpbMiwxOTVdLDEyOTpbMiwxOTVdLDEzMDpbMiwxOTVdLDEzMzpbMiwxOTVdLDEzNDpbMiwxOTVdLDEzNTpbMiwxOTVdLDEzNjpbMiwxOTVdLDEzNzpbMiwxOTVdLDEzODpbMiwxOTVdLDEzOTpbMiwxOTVdfSx7NjpbMSwyMTNdLDc6MjExLDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjU6WzEsMjEyXSwyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezc6MjE0LDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHsyNDoyMTUsMjU6WzEsMTE1XSwxMjU6WzEsMjE2XX0sezE6WzIsMTM0XSw2OlsyLDEzNF0sMjU6WzIsMTM0XSwyNjpbMiwxMzRdLDQ5OlsyLDEzNF0sNTQ6WzIsMTM0XSw1NzpbMiwxMzRdLDczOlsyLDEzNF0sNzg6WzIsMTM0XSw4NjpbMiwxMzRdLDkxOlsyLDEzNF0sOTM6WzIsMTM0XSw5NzoyMTcsOTg6WzEsMjE4XSw5OTpbMSwyMTldLDEwMjpbMiwxMzRdLDEwNDpbMiwxMzRdLDEwNTpbMiwxMzRdLDEwNjpbMiwxMzRdLDExMDpbMiwxMzRdLDExODpbMiwxMzRdLDEyNjpbMiwxMzRdLDEyOTpbMiwxMzRdLDEzMDpbMiwxMzRdLDEzMzpbMiwxMzRdLDEzNDpbMiwxMzRdLDEzNTpbMiwxMzRdLDEzNjpbMiwxMzRdLDEzNzpbMiwxMzRdLDEzODpbMiwxMzRdLDEzOTpbMiwxMzRdfSx7MTpbMiwxNDhdLDY6WzIsMTQ4XSwyNTpbMiwxNDhdLDI2OlsyLDE0OF0sNDk6WzIsMTQ4XSw1NDpbMiwxNDhdLDU3OlsyLDE0OF0sNzM6WzIsMTQ4XSw3ODpbMiwxNDhdLDg2OlsyLDE0OF0sOTE6WzIsMTQ4XSw5MzpbMiwxNDhdLDEwMjpbMiwxNDhdLDEwNDpbMiwxNDhdLDEwNTpbMiwxNDhdLDEwNjpbMiwxNDhdLDExMDpbMiwxNDhdLDExODpbMiwxNDhdLDEyNjpbMiwxNDhdLDEyOTpbMiwxNDhdLDEzMDpbMiwxNDhdLDEzMzpbMiwxNDhdLDEzNDpbMiwxNDhdLDEzNTpbMiwxNDhdLDEzNjpbMiwxNDhdLDEzNzpbMiwxNDhdLDEzODpbMiwxNDhdLDEzOTpbMiwxNDhdfSx7MTpbMiwxNTZdLDY6WzIsMTU2XSwyNTpbMiwxNTZdLDI2OlsyLDE1Nl0sNDk6WzIsMTU2XSw1NDpbMiwxNTZdLDU3OlsyLDE1Nl0sNzM6WzIsMTU2XSw3ODpbMiwxNTZdLDg2OlsyLDE1Nl0sOTE6WzIsMTU2XSw5MzpbMiwxNTZdLDEwMjpbMiwxNTZdLDEwNDpbMiwxNTZdLDEwNTpbMiwxNTZdLDEwNjpbMiwxNTZdLDExMDpbMiwxNTZdLDExODpbMiwxNTZdLDEyNjpbMiwxNTZdLDEyOTpbMiwxNTZdLDEzMDpbMiwxNTZdLDEzMzpbMiwxNTZdLDEzNDpbMiwxNTZdLDEzNTpbMiwxNTZdLDEzNjpbMiwxNTZdLDEzNzpbMiwxNTZdLDEzODpbMiwxNTZdLDEzOTpbMiwxNTZdfSx7MjU6WzEsMjIwXSwxMDM6ODQsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwOTo4NSwxMTA6WzEsNjddLDExMTo2OCwxMjY6WzEsODNdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7MTIwOjIyMSwxMjI6MjIyLDEyMzpbMSwyMjNdfSx7MTpbMiw5N10sNjpbMiw5N10sMjU6WzIsOTddLDI2OlsyLDk3XSw0OTpbMiw5N10sNTQ6WzIsOTddLDU3OlsyLDk3XSw3MzpbMiw5N10sNzg6WzIsOTddLDg2OlsyLDk3XSw5MTpbMiw5N10sOTM6WzIsOTddLDEwMjpbMiw5N10sMTA0OlsyLDk3XSwxMDU6WzIsOTddLDEwNjpbMiw5N10sMTEwOlsyLDk3XSwxMTg6WzIsOTddLDEyNjpbMiw5N10sMTI5OlsyLDk3XSwxMzA6WzIsOTddLDEzMzpbMiw5N10sMTM0OlsyLDk3XSwxMzU6WzIsOTddLDEzNjpbMiw5N10sMTM3OlsyLDk3XSwxMzg6WzIsOTddLDEzOTpbMiw5N119LHs3OjIyNCw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7MTpbMiwxMDBdLDY6WzIsMTAwXSwyNDoyMjUsMjU6WzEsMTE1XSwyNjpbMiwxMDBdLDQ5OlsyLDEwMF0sNTQ6WzIsMTAwXSw1NzpbMiwxMDBdLDY2OlsyLDcyXSw2NzpbMiw3Ml0sNjg6WzIsNzJdLDY5OlsyLDcyXSw3MTpbMiw3Ml0sNzM6WzIsMTAwXSw3NDpbMiw3Ml0sNzg6WzIsMTAwXSw4MDpbMSwyMjZdLDg0OlsyLDcyXSw4NTpbMiw3Ml0sODY6WzIsMTAwXSw5MTpbMiwxMDBdLDkzOlsyLDEwMF0sMTAyOlsyLDEwMF0sMTA0OlsyLDEwMF0sMTA1OlsyLDEwMF0sMTA2OlsyLDEwMF0sMTEwOlsyLDEwMF0sMTE4OlsyLDEwMF0sMTI2OlsyLDEwMF0sMTI5OlsyLDEwMF0sMTMwOlsyLDEwMF0sMTMzOlsyLDEwMF0sMTM0OlsyLDEwMF0sMTM1OlsyLDEwMF0sMTM2OlsyLDEwMF0sMTM3OlsyLDEwMF0sMTM4OlsyLDEwMF0sMTM5OlsyLDEwMF19LHsxOlsyLDE0MV0sNjpbMiwxNDFdLDI1OlsyLDE0MV0sMjY6WzIsMTQxXSw0OTpbMiwxNDFdLDU0OlsyLDE0MV0sNTc6WzIsMTQxXSw3MzpbMiwxNDFdLDc4OlsyLDE0MV0sODY6WzIsMTQxXSw5MTpbMiwxNDFdLDkzOlsyLDE0MV0sMTAyOlsyLDE0MV0sMTAzOjg0LDEwNDpbMiwxNDFdLDEwNTpbMiwxNDFdLDEwNjpbMiwxNDFdLDEwOTo4NSwxMTA6WzIsMTQxXSwxMTE6NjgsMTE4OlsyLDE0MV0sMTI2OlsyLDE0MV0sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHsxOlsyLDQ1XSw2OlsyLDQ1XSwyNjpbMiw0NV0sMTAyOlsyLDQ1XSwxMDM6ODQsMTA0OlsyLDQ1XSwxMDY6WzIsNDVdLDEwOTo4NSwxMTA6WzIsNDVdLDExMTo2OCwxMjY6WzIsNDVdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7NjpbMSw3M10sMTAyOlsxLDIyN119LHs0OjIyOCw1OjMsNzo0LDg6NSw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7NjpbMiwxMjldLDI1OlsyLDEyOV0sNTQ6WzIsMTI5XSw1NzpbMSwyMzBdLDkxOlsyLDEyOV0sOTI6MjI5LDkzOlsxLDE5NF0sMTAzOjg0LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDk6ODUsMTEwOlsxLDY3XSwxMTE6NjgsMTI2OlsxLDgzXSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMSw4MV0sMTM5OlsxLDgyXX0sezE6WzIsMTE1XSw2OlsyLDExNV0sMjU6WzIsMTE1XSwyNjpbMiwxMTVdLDQwOlsyLDExNV0sNDk6WzIsMTE1XSw1NDpbMiwxMTVdLDU3OlsyLDExNV0sNjY6WzIsMTE1XSw2NzpbMiwxMTVdLDY4OlsyLDExNV0sNjk6WzIsMTE1XSw3MTpbMiwxMTVdLDczOlsyLDExNV0sNzQ6WzIsMTE1XSw3ODpbMiwxMTVdLDg0OlsyLDExNV0sODU6WzIsMTE1XSw4NjpbMiwxMTVdLDkxOlsyLDExNV0sOTM6WzIsMTE1XSwxMDI6WzIsMTE1XSwxMDQ6WzIsMTE1XSwxMDU6WzIsMTE1XSwxMDY6WzIsMTE1XSwxMTA6WzIsMTE1XSwxMTY6WzIsMTE1XSwxMTc6WzIsMTE1XSwxMTg6WzIsMTE1XSwxMjY6WzIsMTE1XSwxMjk6WzIsMTE1XSwxMzA6WzIsMTE1XSwxMzM6WzIsMTE1XSwxMzQ6WzIsMTE1XSwxMzU6WzIsMTE1XSwxMzY6WzIsMTE1XSwxMzc6WzIsMTE1XSwxMzg6WzIsMTE1XSwxMzk6WzIsMTE1XX0sezY6WzIsNTJdLDI1OlsyLDUyXSw1MzoyMzEsNTQ6WzEsMjMyXSw5MTpbMiw1Ml19LHs2OlsyLDEyNF0sMjU6WzIsMTI0XSwyNjpbMiwxMjRdLDU0OlsyLDEyNF0sODY6WzIsMTI0XSw5MTpbMiwxMjRdfSx7NzoyMDMsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNTpbMSwxNDddLDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTc6WzEsMTQ5XSw1ODo0Niw1OTo0Nyw2MDoxNDgsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODc6MjMzLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk0OjE0Niw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs2OlsyLDEzMF0sMjU6WzIsMTMwXSwyNjpbMiwxMzBdLDU0OlsyLDEzMF0sODY6WzIsMTMwXSw5MTpbMiwxMzBdfSx7NjpbMiwxMzFdLDI1OlsyLDEzMV0sMjY6WzIsMTMxXSw1NDpbMiwxMzFdLDg2OlsyLDEzMV0sOTE6WzIsMTMxXX0sezE6WzIsMTE0XSw2OlsyLDExNF0sMjU6WzIsMTE0XSwyNjpbMiwxMTRdLDQwOlsyLDExNF0sNDM6WzIsMTE0XSw0OTpbMiwxMTRdLDU0OlsyLDExNF0sNTc6WzIsMTE0XSw2NjpbMiwxMTRdLDY3OlsyLDExNF0sNjg6WzIsMTE0XSw2OTpbMiwxMTRdLDcxOlsyLDExNF0sNzM6WzIsMTE0XSw3NDpbMiwxMTRdLDc4OlsyLDExNF0sODA6WzIsMTE0XSw4NDpbMiwxMTRdLDg1OlsyLDExNF0sODY6WzIsMTE0XSw5MTpbMiwxMTRdLDkzOlsyLDExNF0sMTAyOlsyLDExNF0sMTA0OlsyLDExNF0sMTA1OlsyLDExNF0sMTA2OlsyLDExNF0sMTEwOlsyLDExNF0sMTE2OlsyLDExNF0sMTE3OlsyLDExNF0sMTE4OlsyLDExNF0sMTI2OlsyLDExNF0sMTI5OlsyLDExNF0sMTMwOlsyLDExNF0sMTMxOlsyLDExNF0sMTMyOlsyLDExNF0sMTMzOlsyLDExNF0sMTM0OlsyLDExNF0sMTM1OlsyLDExNF0sMTM2OlsyLDExNF0sMTM3OlsyLDExNF0sMTM4OlsyLDExNF0sMTM5OlsyLDExNF0sMTQwOlsyLDExNF19LHsyNDoyMzQsMjU6WzEsMTE1XSwxMDM6ODQsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwOTo4NSwxMTA6WzEsNjddLDExMTo2OCwxMjY6WzEsODNdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7MTpbMiwxNDRdLDY6WzIsMTQ0XSwyNTpbMiwxNDRdLDI2OlsyLDE0NF0sNDk6WzIsMTQ0XSw1NDpbMiwxNDRdLDU3OlsyLDE0NF0sNzM6WzIsMTQ0XSw3ODpbMiwxNDRdLDg2OlsyLDE0NF0sOTE6WzIsMTQ0XSw5MzpbMiwxNDRdLDEwMjpbMiwxNDRdLDEwMzo4NCwxMDQ6WzEsNjRdLDEwNTpbMSwyMzVdLDEwNjpbMSw2NV0sMTA5Ojg1LDExMDpbMSw2N10sMTExOjY4LDExODpbMiwxNDRdLDEyNjpbMiwxNDRdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7MTpbMiwxNDZdLDY6WzIsMTQ2XSwyNTpbMiwxNDZdLDI2OlsyLDE0Nl0sNDk6WzIsMTQ2XSw1NDpbMiwxNDZdLDU3OlsyLDE0Nl0sNzM6WzIsMTQ2XSw3ODpbMiwxNDZdLDg2OlsyLDE0Nl0sOTE6WzIsMTQ2XSw5MzpbMiwxNDZdLDEwMjpbMiwxNDZdLDEwMzo4NCwxMDQ6WzEsNjRdLDEwNTpbMSwyMzZdLDEwNjpbMSw2NV0sMTA5Ojg1LDExMDpbMSw2N10sMTExOjY4LDExODpbMiwxNDZdLDEyNjpbMiwxNDZdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7MTpbMiwxNTJdLDY6WzIsMTUyXSwyNTpbMiwxNTJdLDI2OlsyLDE1Ml0sNDk6WzIsMTUyXSw1NDpbMiwxNTJdLDU3OlsyLDE1Ml0sNzM6WzIsMTUyXSw3ODpbMiwxNTJdLDg2OlsyLDE1Ml0sOTE6WzIsMTUyXSw5MzpbMiwxNTJdLDEwMjpbMiwxNTJdLDEwNDpbMiwxNTJdLDEwNTpbMiwxNTJdLDEwNjpbMiwxNTJdLDExMDpbMiwxNTJdLDExODpbMiwxNTJdLDEyNjpbMiwxNTJdLDEyOTpbMiwxNTJdLDEzMDpbMiwxNTJdLDEzMzpbMiwxNTJdLDEzNDpbMiwxNTJdLDEzNTpbMiwxNTJdLDEzNjpbMiwxNTJdLDEzNzpbMiwxNTJdLDEzODpbMiwxNTJdLDEzOTpbMiwxNTJdfSx7MTpbMiwxNTNdLDY6WzIsMTUzXSwyNTpbMiwxNTNdLDI2OlsyLDE1M10sNDk6WzIsMTUzXSw1NDpbMiwxNTNdLDU3OlsyLDE1M10sNzM6WzIsMTUzXSw3ODpbMiwxNTNdLDg2OlsyLDE1M10sOTE6WzIsMTUzXSw5MzpbMiwxNTNdLDEwMjpbMiwxNTNdLDEwMzo4NCwxMDQ6WzEsNjRdLDEwNTpbMiwxNTNdLDEwNjpbMSw2NV0sMTA5Ojg1LDExMDpbMSw2N10sMTExOjY4LDExODpbMiwxNTNdLDEyNjpbMiwxNTNdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7MTpbMiwxNTddLDY6WzIsMTU3XSwyNTpbMiwxNTddLDI2OlsyLDE1N10sNDk6WzIsMTU3XSw1NDpbMiwxNTddLDU3OlsyLDE1N10sNzM6WzIsMTU3XSw3ODpbMiwxNTddLDg2OlsyLDE1N10sOTE6WzIsMTU3XSw5MzpbMiwxNTddLDEwMjpbMiwxNTddLDEwNDpbMiwxNTddLDEwNTpbMiwxNTddLDEwNjpbMiwxNTddLDExMDpbMiwxNTddLDExODpbMiwxNTddLDEyNjpbMiwxNTddLDEyOTpbMiwxNTddLDEzMDpbMiwxNTddLDEzMzpbMiwxNTddLDEzNDpbMiwxNTddLDEzNTpbMiwxNTddLDEzNjpbMiwxNTddLDEzNzpbMiwxNTddLDEzODpbMiwxNTddLDEzOTpbMiwxNTddfSx7MTE2OlsyLDE1OV0sMTE3OlsyLDE1OV19LHsyNzoxNjAsMjg6WzEsNzJdLDQ0OjE2MSw1ODoxNjIsNTk6MTYzLDc2OlsxLDY5XSw4OTpbMSwxMTJdLDkwOlsxLDExM10sMTEzOjIzNywxMTU6MTU5fSx7NTQ6WzEsMjM4XSwxMTY6WzIsMTY1XSwxMTc6WzIsMTY1XX0sezU0OlsyLDE2MV0sMTE2OlsyLDE2MV0sMTE3OlsyLDE2MV19LHs1NDpbMiwxNjJdLDExNjpbMiwxNjJdLDExNzpbMiwxNjJdfSx7NTQ6WzIsMTYzXSwxMTY6WzIsMTYzXSwxMTc6WzIsMTYzXX0sezU0OlsyLDE2NF0sMTE2OlsyLDE2NF0sMTE3OlsyLDE2NF19LHsxOlsyLDE1OF0sNjpbMiwxNThdLDI1OlsyLDE1OF0sMjY6WzIsMTU4XSw0OTpbMiwxNThdLDU0OlsyLDE1OF0sNTc6WzIsMTU4XSw3MzpbMiwxNThdLDc4OlsyLDE1OF0sODY6WzIsMTU4XSw5MTpbMiwxNThdLDkzOlsyLDE1OF0sMTAyOlsyLDE1OF0sMTA0OlsyLDE1OF0sMTA1OlsyLDE1OF0sMTA2OlsyLDE1OF0sMTEwOlsyLDE1OF0sMTE4OlsyLDE1OF0sMTI2OlsyLDE1OF0sMTI5OlsyLDE1OF0sMTMwOlsyLDE1OF0sMTMzOlsyLDE1OF0sMTM0OlsyLDE1OF0sMTM1OlsyLDE1OF0sMTM2OlsyLDE1OF0sMTM3OlsyLDE1OF0sMTM4OlsyLDE1OF0sMTM5OlsyLDE1OF19LHs3OjIzOSw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7NzoyNDAsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezY6WzIsNTJdLDI1OlsyLDUyXSw1MzoyNDEsNTQ6WzEsMjQyXSw3ODpbMiw1Ml19LHs2OlsyLDkyXSwyNTpbMiw5Ml0sMjY6WzIsOTJdLDU0OlsyLDkyXSw3ODpbMiw5Ml19LHs2OlsyLDM4XSwyNTpbMiwzOF0sMjY6WzIsMzhdLDQzOlsxLDI0M10sNTQ6WzIsMzhdLDc4OlsyLDM4XX0sezY6WzIsNDFdLDI1OlsyLDQxXSwyNjpbMiw0MV0sNTQ6WzIsNDFdLDc4OlsyLDQxXX0sezY6WzIsNDJdLDI1OlsyLDQyXSwyNjpbMiw0Ml0sNDM6WzIsNDJdLDU0OlsyLDQyXSw3ODpbMiw0Ml19LHs2OlsyLDQzXSwyNTpbMiw0M10sMjY6WzIsNDNdLDQzOlsyLDQzXSw1NDpbMiw0M10sNzg6WzIsNDNdfSx7NjpbMiw0NF0sMjU6WzIsNDRdLDI2OlsyLDQ0XSw0MzpbMiw0NF0sNTQ6WzIsNDRdLDc4OlsyLDQ0XX0sezE6WzIsNF0sNjpbMiw0XSwyNjpbMiw0XSwxMDI6WzIsNF19LHsxOlsyLDE5N10sNjpbMiwxOTddLDI1OlsyLDE5N10sMjY6WzIsMTk3XSw0OTpbMiwxOTddLDU0OlsyLDE5N10sNTc6WzIsMTk3XSw3MzpbMiwxOTddLDc4OlsyLDE5N10sODY6WzIsMTk3XSw5MTpbMiwxOTddLDkzOlsyLDE5N10sMTAyOlsyLDE5N10sMTAzOjg0LDEwNDpbMiwxOTddLDEwNTpbMiwxOTddLDEwNjpbMiwxOTddLDEwOTo4NSwxMTA6WzIsMTk3XSwxMTE6NjgsMTE4OlsyLDE5N10sMTI2OlsyLDE5N10sMTI5OlsyLDE5N10sMTMwOlsyLDE5N10sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsyLDE5N10sMTM3OlsyLDE5N10sMTM4OlsyLDE5N10sMTM5OlsyLDE5N119LHsxOlsyLDE5OF0sNjpbMiwxOThdLDI1OlsyLDE5OF0sMjY6WzIsMTk4XSw0OTpbMiwxOThdLDU0OlsyLDE5OF0sNTc6WzIsMTk4XSw3MzpbMiwxOThdLDc4OlsyLDE5OF0sODY6WzIsMTk4XSw5MTpbMiwxOThdLDkzOlsyLDE5OF0sMTAyOlsyLDE5OF0sMTAzOjg0LDEwNDpbMiwxOThdLDEwNTpbMiwxOThdLDEwNjpbMiwxOThdLDEwOTo4NSwxMTA6WzIsMTk4XSwxMTE6NjgsMTE4OlsyLDE5OF0sMTI2OlsyLDE5OF0sMTI5OlsyLDE5OF0sMTMwOlsyLDE5OF0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsyLDE5OF0sMTM3OlsyLDE5OF0sMTM4OlsyLDE5OF0sMTM5OlsyLDE5OF19LHsxOlsyLDE5OV0sNjpbMiwxOTldLDI1OlsyLDE5OV0sMjY6WzIsMTk5XSw0OTpbMiwxOTldLDU0OlsyLDE5OV0sNTc6WzIsMTk5XSw3MzpbMiwxOTldLDc4OlsyLDE5OV0sODY6WzIsMTk5XSw5MTpbMiwxOTldLDkzOlsyLDE5OV0sMTAyOlsyLDE5OV0sMTAzOjg0LDEwNDpbMiwxOTldLDEwNTpbMiwxOTldLDEwNjpbMiwxOTldLDEwOTo4NSwxMTA6WzIsMTk5XSwxMTE6NjgsMTE4OlsyLDE5OV0sMTI2OlsyLDE5OV0sMTI5OlsyLDE5OV0sMTMwOlsyLDE5OV0sMTMzOlsxLDc0XSwxMzQ6WzIsMTk5XSwxMzU6WzEsNzhdLDEzNjpbMiwxOTldLDEzNzpbMiwxOTldLDEzODpbMiwxOTldLDEzOTpbMiwxOTldfSx7MTpbMiwyMDBdLDY6WzIsMjAwXSwyNTpbMiwyMDBdLDI2OlsyLDIwMF0sNDk6WzIsMjAwXSw1NDpbMiwyMDBdLDU3OlsyLDIwMF0sNzM6WzIsMjAwXSw3ODpbMiwyMDBdLDg2OlsyLDIwMF0sOTE6WzIsMjAwXSw5MzpbMiwyMDBdLDEwMjpbMiwyMDBdLDEwMzo4NCwxMDQ6WzIsMjAwXSwxMDU6WzIsMjAwXSwxMDY6WzIsMjAwXSwxMDk6ODUsMTEwOlsyLDIwMF0sMTExOjY4LDExODpbMiwyMDBdLDEyNjpbMiwyMDBdLDEyOTpbMiwyMDBdLDEzMDpbMiwyMDBdLDEzMzpbMSw3NF0sMTM0OlsyLDIwMF0sMTM1OlsxLDc4XSwxMzY6WzIsMjAwXSwxMzc6WzIsMjAwXSwxMzg6WzIsMjAwXSwxMzk6WzIsMjAwXX0sezE6WzIsMjAxXSw2OlsyLDIwMV0sMjU6WzIsMjAxXSwyNjpbMiwyMDFdLDQ5OlsyLDIwMV0sNTQ6WzIsMjAxXSw1NzpbMiwyMDFdLDczOlsyLDIwMV0sNzg6WzIsMjAxXSw4NjpbMiwyMDFdLDkxOlsyLDIwMV0sOTM6WzIsMjAxXSwxMDI6WzIsMjAxXSwxMDM6ODQsMTA0OlsyLDIwMV0sMTA1OlsyLDIwMV0sMTA2OlsyLDIwMV0sMTA5Ojg1LDExMDpbMiwyMDFdLDExMTo2OCwxMTg6WzIsMjAxXSwxMjY6WzIsMjAxXSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsyLDIwMV0sMTM3OlsyLDIwMV0sMTM4OlsyLDIwMV0sMTM5OlsyLDIwMV19LHsxOlsyLDIwMl0sNjpbMiwyMDJdLDI1OlsyLDIwMl0sMjY6WzIsMjAyXSw0OTpbMiwyMDJdLDU0OlsyLDIwMl0sNTc6WzIsMjAyXSw3MzpbMiwyMDJdLDc4OlsyLDIwMl0sODY6WzIsMjAyXSw5MTpbMiwyMDJdLDkzOlsyLDIwMl0sMTAyOlsyLDIwMl0sMTAzOjg0LDEwNDpbMiwyMDJdLDEwNTpbMiwyMDJdLDEwNjpbMiwyMDJdLDEwOTo4NSwxMTA6WzIsMjAyXSwxMTE6NjgsMTE4OlsyLDIwMl0sMTI2OlsyLDIwMl0sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsyLDIwMl0sMTM4OlsyLDIwMl0sMTM5OlsxLDgyXX0sezE6WzIsMjAzXSw2OlsyLDIwM10sMjU6WzIsMjAzXSwyNjpbMiwyMDNdLDQ5OlsyLDIwM10sNTQ6WzIsMjAzXSw1NzpbMiwyMDNdLDczOlsyLDIwM10sNzg6WzIsMjAzXSw4NjpbMiwyMDNdLDkxOlsyLDIwM10sOTM6WzIsMjAzXSwxMDI6WzIsMjAzXSwxMDM6ODQsMTA0OlsyLDIwM10sMTA1OlsyLDIwM10sMTA2OlsyLDIwM10sMTA5Ojg1LDExMDpbMiwyMDNdLDExMTo2OCwxMTg6WzIsMjAzXSwxMjY6WzIsMjAzXSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMiwyMDNdLDEzOTpbMSw4Ml19LHsxOlsyLDIwNF0sNjpbMiwyMDRdLDI1OlsyLDIwNF0sMjY6WzIsMjA0XSw0OTpbMiwyMDRdLDU0OlsyLDIwNF0sNTc6WzIsMjA0XSw3MzpbMiwyMDRdLDc4OlsyLDIwNF0sODY6WzIsMjA0XSw5MTpbMiwyMDRdLDkzOlsyLDIwNF0sMTAyOlsyLDIwNF0sMTAzOjg0LDEwNDpbMiwyMDRdLDEwNTpbMiwyMDRdLDEwNjpbMiwyMDRdLDEwOTo4NSwxMTA6WzIsMjA0XSwxMTE6NjgsMTE4OlsyLDIwNF0sMTI2OlsyLDIwNF0sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsyLDIwNF0sMTM4OlsyLDIwNF0sMTM5OlsyLDIwNF19LHsxOlsyLDE4N10sNjpbMiwxODddLDI1OlsyLDE4N10sMjY6WzIsMTg3XSw0OTpbMiwxODddLDU0OlsyLDE4N10sNTc6WzIsMTg3XSw3MzpbMiwxODddLDc4OlsyLDE4N10sODY6WzIsMTg3XSw5MTpbMiwxODddLDkzOlsyLDE4N10sMTAyOlsyLDE4N10sMTAzOjg0LDEwNDpbMSw2NF0sMTA1OlsyLDE4N10sMTA2OlsxLDY1XSwxMDk6ODUsMTEwOlsxLDY3XSwxMTE6NjgsMTE4OlsyLDE4N10sMTI2OlsyLDE4N10sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHsxOlsyLDE4Nl0sNjpbMiwxODZdLDI1OlsyLDE4Nl0sMjY6WzIsMTg2XSw0OTpbMiwxODZdLDU0OlsyLDE4Nl0sNTc6WzIsMTg2XSw3MzpbMiwxODZdLDc4OlsyLDE4Nl0sODY6WzIsMTg2XSw5MTpbMiwxODZdLDkzOlsyLDE4Nl0sMTAyOlsyLDE4Nl0sMTAzOjg0LDEwNDpbMSw2NF0sMTA1OlsyLDE4Nl0sMTA2OlsxLDY1XSwxMDk6ODUsMTEwOlsxLDY3XSwxMTE6NjgsMTE4OlsyLDE4Nl0sMTI2OlsyLDE4Nl0sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHsxOlsyLDEwNF0sNjpbMiwxMDRdLDI1OlsyLDEwNF0sMjY6WzIsMTA0XSw0OTpbMiwxMDRdLDU0OlsyLDEwNF0sNTc6WzIsMTA0XSw2NjpbMiwxMDRdLDY3OlsyLDEwNF0sNjg6WzIsMTA0XSw2OTpbMiwxMDRdLDcxOlsyLDEwNF0sNzM6WzIsMTA0XSw3NDpbMiwxMDRdLDc4OlsyLDEwNF0sODQ6WzIsMTA0XSw4NTpbMiwxMDRdLDg2OlsyLDEwNF0sOTE6WzIsMTA0XSw5MzpbMiwxMDRdLDEwMjpbMiwxMDRdLDEwNDpbMiwxMDRdLDEwNTpbMiwxMDRdLDEwNjpbMiwxMDRdLDExMDpbMiwxMDRdLDExODpbMiwxMDRdLDEyNjpbMiwxMDRdLDEyOTpbMiwxMDRdLDEzMDpbMiwxMDRdLDEzMzpbMiwxMDRdLDEzNDpbMiwxMDRdLDEzNTpbMiwxMDRdLDEzNjpbMiwxMDRdLDEzNzpbMiwxMDRdLDEzODpbMiwxMDRdLDEzOTpbMiwxMDRdfSx7MTpbMiw4MF0sNjpbMiw4MF0sMjU6WzIsODBdLDI2OlsyLDgwXSw0MDpbMiw4MF0sNDk6WzIsODBdLDU0OlsyLDgwXSw1NzpbMiw4MF0sNjY6WzIsODBdLDY3OlsyLDgwXSw2ODpbMiw4MF0sNjk6WzIsODBdLDcxOlsyLDgwXSw3MzpbMiw4MF0sNzQ6WzIsODBdLDc4OlsyLDgwXSw4MDpbMiw4MF0sODQ6WzIsODBdLDg1OlsyLDgwXSw4NjpbMiw4MF0sOTE6WzIsODBdLDkzOlsyLDgwXSwxMDI6WzIsODBdLDEwNDpbMiw4MF0sMTA1OlsyLDgwXSwxMDY6WzIsODBdLDExMDpbMiw4MF0sMTE4OlsyLDgwXSwxMjY6WzIsODBdLDEyOTpbMiw4MF0sMTMwOlsyLDgwXSwxMzE6WzIsODBdLDEzMjpbMiw4MF0sMTMzOlsyLDgwXSwxMzQ6WzIsODBdLDEzNTpbMiw4MF0sMTM2OlsyLDgwXSwxMzc6WzIsODBdLDEzODpbMiw4MF0sMTM5OlsyLDgwXSwxNDA6WzIsODBdfSx7MTpbMiw4MV0sNjpbMiw4MV0sMjU6WzIsODFdLDI2OlsyLDgxXSw0MDpbMiw4MV0sNDk6WzIsODFdLDU0OlsyLDgxXSw1NzpbMiw4MV0sNjY6WzIsODFdLDY3OlsyLDgxXSw2ODpbMiw4MV0sNjk6WzIsODFdLDcxOlsyLDgxXSw3MzpbMiw4MV0sNzQ6WzIsODFdLDc4OlsyLDgxXSw4MDpbMiw4MV0sODQ6WzIsODFdLDg1OlsyLDgxXSw4NjpbMiw4MV0sOTE6WzIsODFdLDkzOlsyLDgxXSwxMDI6WzIsODFdLDEwNDpbMiw4MV0sMTA1OlsyLDgxXSwxMDY6WzIsODFdLDExMDpbMiw4MV0sMTE4OlsyLDgxXSwxMjY6WzIsODFdLDEyOTpbMiw4MV0sMTMwOlsyLDgxXSwxMzE6WzIsODFdLDEzMjpbMiw4MV0sMTMzOlsyLDgxXSwxMzQ6WzIsODFdLDEzNTpbMiw4MV0sMTM2OlsyLDgxXSwxMzc6WzIsODFdLDEzODpbMiw4MV0sMTM5OlsyLDgxXSwxNDA6WzIsODFdfSx7MTpbMiw4Ml0sNjpbMiw4Ml0sMjU6WzIsODJdLDI2OlsyLDgyXSw0MDpbMiw4Ml0sNDk6WzIsODJdLDU0OlsyLDgyXSw1NzpbMiw4Ml0sNjY6WzIsODJdLDY3OlsyLDgyXSw2ODpbMiw4Ml0sNjk6WzIsODJdLDcxOlsyLDgyXSw3MzpbMiw4Ml0sNzQ6WzIsODJdLDc4OlsyLDgyXSw4MDpbMiw4Ml0sODQ6WzIsODJdLDg1OlsyLDgyXSw4NjpbMiw4Ml0sOTE6WzIsODJdLDkzOlsyLDgyXSwxMDI6WzIsODJdLDEwNDpbMiw4Ml0sMTA1OlsyLDgyXSwxMDY6WzIsODJdLDExMDpbMiw4Ml0sMTE4OlsyLDgyXSwxMjY6WzIsODJdLDEyOTpbMiw4Ml0sMTMwOlsyLDgyXSwxMzE6WzIsODJdLDEzMjpbMiw4Ml0sMTMzOlsyLDgyXSwxMzQ6WzIsODJdLDEzNTpbMiw4Ml0sMTM2OlsyLDgyXSwxMzc6WzIsODJdLDEzODpbMiw4Ml0sMTM5OlsyLDgyXSwxNDA6WzIsODJdfSx7MTpbMiw4M10sNjpbMiw4M10sMjU6WzIsODNdLDI2OlsyLDgzXSw0MDpbMiw4M10sNDk6WzIsODNdLDU0OlsyLDgzXSw1NzpbMiw4M10sNjY6WzIsODNdLDY3OlsyLDgzXSw2ODpbMiw4M10sNjk6WzIsODNdLDcxOlsyLDgzXSw3MzpbMiw4M10sNzQ6WzIsODNdLDc4OlsyLDgzXSw4MDpbMiw4M10sODQ6WzIsODNdLDg1OlsyLDgzXSw4NjpbMiw4M10sOTE6WzIsODNdLDkzOlsyLDgzXSwxMDI6WzIsODNdLDEwNDpbMiw4M10sMTA1OlsyLDgzXSwxMDY6WzIsODNdLDExMDpbMiw4M10sMTE4OlsyLDgzXSwxMjY6WzIsODNdLDEyOTpbMiw4M10sMTMwOlsyLDgzXSwxMzE6WzIsODNdLDEzMjpbMiw4M10sMTMzOlsyLDgzXSwxMzQ6WzIsODNdLDEzNTpbMiw4M10sMTM2OlsyLDgzXSwxMzc6WzIsODNdLDEzODpbMiw4M10sMTM5OlsyLDgzXSwxNDA6WzIsODNdfSx7NzM6WzEsMjQ0XX0sezU3OlsxLDE5NV0sNzM6WzIsODhdLDkyOjI0NSw5MzpbMSwxOTRdLDEwMzo4NCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA5Ojg1LDExMDpbMSw2N10sMTExOjY4LDEyNjpbMSw4M10sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHs3MzpbMiw4OV19LHs3OjI0Niw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzM6WzIsMTIzXSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHsxMTpbMiwxMTddLDI4OlsyLDExN10sMzA6WzIsMTE3XSwzMTpbMiwxMTddLDMzOlsyLDExN10sMzQ6WzIsMTE3XSwzNTpbMiwxMTddLDM2OlsyLDExN10sMzc6WzIsMTE3XSwzODpbMiwxMTddLDQ1OlsyLDExN10sNDY6WzIsMTE3XSw0NzpbMiwxMTddLDUxOlsyLDExN10sNTI6WzIsMTE3XSw3MzpbMiwxMTddLDc2OlsyLDExN10sNzk6WzIsMTE3XSw4MzpbMiwxMTddLDg4OlsyLDExN10sODk6WzIsMTE3XSw5MDpbMiwxMTddLDk2OlsyLDExN10sMTAwOlsyLDExN10sMTAxOlsyLDExN10sMTA0OlsyLDExN10sMTA2OlsyLDExN10sMTA4OlsyLDExN10sMTEwOlsyLDExN10sMTE5OlsyLDExN10sMTI1OlsyLDExN10sMTI3OlsyLDExN10sMTI4OlsyLDExN10sMTI5OlsyLDExN10sMTMwOlsyLDExN10sMTMxOlsyLDExN10sMTMyOlsyLDExN119LHsxMTpbMiwxMThdLDI4OlsyLDExOF0sMzA6WzIsMTE4XSwzMTpbMiwxMThdLDMzOlsyLDExOF0sMzQ6WzIsMTE4XSwzNTpbMiwxMThdLDM2OlsyLDExOF0sMzc6WzIsMTE4XSwzODpbMiwxMThdLDQ1OlsyLDExOF0sNDY6WzIsMTE4XSw0NzpbMiwxMThdLDUxOlsyLDExOF0sNTI6WzIsMTE4XSw3MzpbMiwxMThdLDc2OlsyLDExOF0sNzk6WzIsMTE4XSw4MzpbMiwxMThdLDg4OlsyLDExOF0sODk6WzIsMTE4XSw5MDpbMiwxMThdLDk2OlsyLDExOF0sMTAwOlsyLDExOF0sMTAxOlsyLDExOF0sMTA0OlsyLDExOF0sMTA2OlsyLDExOF0sMTA4OlsyLDExOF0sMTEwOlsyLDExOF0sMTE5OlsyLDExOF0sMTI1OlsyLDExOF0sMTI3OlsyLDExOF0sMTI4OlsyLDExOF0sMTI5OlsyLDExOF0sMTMwOlsyLDExOF0sMTMxOlsyLDExOF0sMTMyOlsyLDExOF19LHsxOlsyLDg3XSw2OlsyLDg3XSwyNTpbMiw4N10sMjY6WzIsODddLDQwOlsyLDg3XSw0OTpbMiw4N10sNTQ6WzIsODddLDU3OlsyLDg3XSw2NjpbMiw4N10sNjc6WzIsODddLDY4OlsyLDg3XSw2OTpbMiw4N10sNzE6WzIsODddLDczOlsyLDg3XSw3NDpbMiw4N10sNzg6WzIsODddLDgwOlsyLDg3XSw4NDpbMiw4N10sODU6WzIsODddLDg2OlsyLDg3XSw5MTpbMiw4N10sOTM6WzIsODddLDEwMjpbMiw4N10sMTA0OlsyLDg3XSwxMDU6WzIsODddLDEwNjpbMiw4N10sMTEwOlsyLDg3XSwxMTg6WzIsODddLDEyNjpbMiw4N10sMTI5OlsyLDg3XSwxMzA6WzIsODddLDEzMTpbMiw4N10sMTMyOlsyLDg3XSwxMzM6WzIsODddLDEzNDpbMiw4N10sMTM1OlsyLDg3XSwxMzY6WzIsODddLDEzNzpbMiw4N10sMTM4OlsyLDg3XSwxMzk6WzIsODddLDE0MDpbMiw4N119LHsxOlsyLDEwNV0sNjpbMiwxMDVdLDI1OlsyLDEwNV0sMjY6WzIsMTA1XSw0OTpbMiwxMDVdLDU0OlsyLDEwNV0sNTc6WzIsMTA1XSw2NjpbMiwxMDVdLDY3OlsyLDEwNV0sNjg6WzIsMTA1XSw2OTpbMiwxMDVdLDcxOlsyLDEwNV0sNzM6WzIsMTA1XSw3NDpbMiwxMDVdLDc4OlsyLDEwNV0sODQ6WzIsMTA1XSw4NTpbMiwxMDVdLDg2OlsyLDEwNV0sOTE6WzIsMTA1XSw5MzpbMiwxMDVdLDEwMjpbMiwxMDVdLDEwNDpbMiwxMDVdLDEwNTpbMiwxMDVdLDEwNjpbMiwxMDVdLDExMDpbMiwxMDVdLDExODpbMiwxMDVdLDEyNjpbMiwxMDVdLDEyOTpbMiwxMDVdLDEzMDpbMiwxMDVdLDEzMzpbMiwxMDVdLDEzNDpbMiwxMDVdLDEzNTpbMiwxMDVdLDEzNjpbMiwxMDVdLDEzNzpbMiwxMDVdLDEzODpbMiwxMDVdLDEzOTpbMiwxMDVdfSx7MTpbMiwzNV0sNjpbMiwzNV0sMjU6WzIsMzVdLDI2OlsyLDM1XSw0OTpbMiwzNV0sNTQ6WzIsMzVdLDU3OlsyLDM1XSw3MzpbMiwzNV0sNzg6WzIsMzVdLDg2OlsyLDM1XSw5MTpbMiwzNV0sOTM6WzIsMzVdLDEwMjpbMiwzNV0sMTAzOjg0LDEwNDpbMiwzNV0sMTA1OlsyLDM1XSwxMDY6WzIsMzVdLDEwOTo4NSwxMTA6WzIsMzVdLDExMTo2OCwxMTg6WzIsMzVdLDEyNjpbMiwzNV0sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHs3OjI0Nyw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7NzoyNDgsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezE6WzIsMTEwXSw2OlsyLDExMF0sMjU6WzIsMTEwXSwyNjpbMiwxMTBdLDQ5OlsyLDExMF0sNTQ6WzIsMTEwXSw1NzpbMiwxMTBdLDY2OlsyLDExMF0sNjc6WzIsMTEwXSw2ODpbMiwxMTBdLDY5OlsyLDExMF0sNzE6WzIsMTEwXSw3MzpbMiwxMTBdLDc0OlsyLDExMF0sNzg6WzIsMTEwXSw4NDpbMiwxMTBdLDg1OlsyLDExMF0sODY6WzIsMTEwXSw5MTpbMiwxMTBdLDkzOlsyLDExMF0sMTAyOlsyLDExMF0sMTA0OlsyLDExMF0sMTA1OlsyLDExMF0sMTA2OlsyLDExMF0sMTEwOlsyLDExMF0sMTE4OlsyLDExMF0sMTI2OlsyLDExMF0sMTI5OlsyLDExMF0sMTMwOlsyLDExMF0sMTMzOlsyLDExMF0sMTM0OlsyLDExMF0sMTM1OlsyLDExMF0sMTM2OlsyLDExMF0sMTM3OlsyLDExMF0sMTM4OlsyLDExMF0sMTM5OlsyLDExMF19LHs2OlsyLDUyXSwyNTpbMiw1Ml0sNTM6MjQ5LDU0OlsxLDIzMl0sODY6WzIsNTJdfSx7NjpbMiwxMjldLDI1OlsyLDEyOV0sMjY6WzIsMTI5XSw1NDpbMiwxMjldLDU3OlsxLDI1MF0sODY6WzIsMTI5XSw5MTpbMiwxMjldLDEwMzo4NCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA5Ojg1LDExMDpbMSw2N10sMTExOjY4LDEyNjpbMSw4M10sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHs1MDoyNTEsNTE6WzEsNTldLDUyOlsxLDYwXX0sezY6WzIsNTNdLDI1OlsyLDUzXSwyNjpbMiw1M10sMjc6MTA4LDI4OlsxLDcyXSw0NDoxMDksNTU6MjUyLDU2OjEwNiw1NzpbMSwxMDddLDU4OjExMCw1OToxMTEsNzY6WzEsNjldLDg5OlsxLDExMl0sOTA6WzEsMTEzXX0sezY6WzEsMjUzXSwyNTpbMSwyNTRdfSx7NjpbMiw2MF0sMjU6WzIsNjBdLDI2OlsyLDYwXSw0OTpbMiw2MF0sNTQ6WzIsNjBdfSx7NzoyNTUsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezE6WzIsMjNdLDY6WzIsMjNdLDI1OlsyLDIzXSwyNjpbMiwyM10sNDk6WzIsMjNdLDU0OlsyLDIzXSw1NzpbMiwyM10sNzM6WzIsMjNdLDc4OlsyLDIzXSw4NjpbMiwyM10sOTE6WzIsMjNdLDkzOlsyLDIzXSw5ODpbMiwyM10sOTk6WzIsMjNdLDEwMjpbMiwyM10sMTA0OlsyLDIzXSwxMDU6WzIsMjNdLDEwNjpbMiwyM10sMTEwOlsyLDIzXSwxMTg6WzIsMjNdLDEyMTpbMiwyM10sMTIzOlsyLDIzXSwxMjY6WzIsMjNdLDEyOTpbMiwyM10sMTMwOlsyLDIzXSwxMzM6WzIsMjNdLDEzNDpbMiwyM10sMTM1OlsyLDIzXSwxMzY6WzIsMjNdLDEzNzpbMiwyM10sMTM4OlsyLDIzXSwxMzk6WzIsMjNdfSx7NjpbMSw3M10sMjY6WzEsMjU2XX0sezE6WzIsMjA1XSw2OlsyLDIwNV0sMjU6WzIsMjA1XSwyNjpbMiwyMDVdLDQ5OlsyLDIwNV0sNTQ6WzIsMjA1XSw1NzpbMiwyMDVdLDczOlsyLDIwNV0sNzg6WzIsMjA1XSw4NjpbMiwyMDVdLDkxOlsyLDIwNV0sOTM6WzIsMjA1XSwxMDI6WzIsMjA1XSwxMDM6ODQsMTA0OlsyLDIwNV0sMTA1OlsyLDIwNV0sMTA2OlsyLDIwNV0sMTA5Ojg1LDExMDpbMiwyMDVdLDExMTo2OCwxMTg6WzIsMjA1XSwxMjY6WzIsMjA1XSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMSw4MV0sMTM5OlsxLDgyXX0sezc6MjU3LDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs3OjI1OCw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7MTpbMiwyMDhdLDY6WzIsMjA4XSwyNTpbMiwyMDhdLDI2OlsyLDIwOF0sNDk6WzIsMjA4XSw1NDpbMiwyMDhdLDU3OlsyLDIwOF0sNzM6WzIsMjA4XSw3ODpbMiwyMDhdLDg2OlsyLDIwOF0sOTE6WzIsMjA4XSw5MzpbMiwyMDhdLDEwMjpbMiwyMDhdLDEwMzo4NCwxMDQ6WzIsMjA4XSwxMDU6WzIsMjA4XSwxMDY6WzIsMjA4XSwxMDk6ODUsMTEwOlsyLDIwOF0sMTExOjY4LDExODpbMiwyMDhdLDEyNjpbMiwyMDhdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7MTpbMiwxODVdLDY6WzIsMTg1XSwyNTpbMiwxODVdLDI2OlsyLDE4NV0sNDk6WzIsMTg1XSw1NDpbMiwxODVdLDU3OlsyLDE4NV0sNzM6WzIsMTg1XSw3ODpbMiwxODVdLDg2OlsyLDE4NV0sOTE6WzIsMTg1XSw5MzpbMiwxODVdLDEwMjpbMiwxODVdLDEwNDpbMiwxODVdLDEwNTpbMiwxODVdLDEwNjpbMiwxODVdLDExMDpbMiwxODVdLDExODpbMiwxODVdLDEyNjpbMiwxODVdLDEyOTpbMiwxODVdLDEzMDpbMiwxODVdLDEzMzpbMiwxODVdLDEzNDpbMiwxODVdLDEzNTpbMiwxODVdLDEzNjpbMiwxODVdLDEzNzpbMiwxODVdLDEzODpbMiwxODVdLDEzOTpbMiwxODVdfSx7NzoyNTksODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezE6WzIsMTM1XSw2OlsyLDEzNV0sMjU6WzIsMTM1XSwyNjpbMiwxMzVdLDQ5OlsyLDEzNV0sNTQ6WzIsMTM1XSw1NzpbMiwxMzVdLDczOlsyLDEzNV0sNzg6WzIsMTM1XSw4NjpbMiwxMzVdLDkxOlsyLDEzNV0sOTM6WzIsMTM1XSw5ODpbMSwyNjBdLDEwMjpbMiwxMzVdLDEwNDpbMiwxMzVdLDEwNTpbMiwxMzVdLDEwNjpbMiwxMzVdLDExMDpbMiwxMzVdLDExODpbMiwxMzVdLDEyNjpbMiwxMzVdLDEyOTpbMiwxMzVdLDEzMDpbMiwxMzVdLDEzMzpbMiwxMzVdLDEzNDpbMiwxMzVdLDEzNTpbMiwxMzVdLDEzNjpbMiwxMzVdLDEzNzpbMiwxMzVdLDEzODpbMiwxMzVdLDEzOTpbMiwxMzVdfSx7MjQ6MjYxLDI1OlsxLDExNV19LHsyNDoyNjQsMjU6WzEsMTE1XSwyNzoyNjIsMjg6WzEsNzJdLDU5OjI2Myw3NjpbMSw2OV19LHsxMjA6MjY1LDEyMjoyMjIsMTIzOlsxLDIyM119LHsyNjpbMSwyNjZdLDEyMTpbMSwyNjddLDEyMjoyNjgsMTIzOlsxLDIyM119LHsyNjpbMiwxNzhdLDEyMTpbMiwxNzhdLDEyMzpbMiwxNzhdfSx7NzoyNzAsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk1OjI2OSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHsxOlsyLDk4XSw2OlsyLDk4XSwyNDoyNzEsMjU6WzEsMTE1XSwyNjpbMiw5OF0sNDk6WzIsOThdLDU0OlsyLDk4XSw1NzpbMiw5OF0sNzM6WzIsOThdLDc4OlsyLDk4XSw4NjpbMiw5OF0sOTE6WzIsOThdLDkzOlsyLDk4XSwxMDI6WzIsOThdLDEwMzo4NCwxMDQ6WzEsNjRdLDEwNTpbMiw5OF0sMTA2OlsxLDY1XSwxMDk6ODUsMTEwOlsxLDY3XSwxMTE6NjgsMTE4OlsyLDk4XSwxMjY6WzIsOThdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7MTpbMiwxMDFdLDY6WzIsMTAxXSwyNTpbMiwxMDFdLDI2OlsyLDEwMV0sNDk6WzIsMTAxXSw1NDpbMiwxMDFdLDU3OlsyLDEwMV0sNzM6WzIsMTAxXSw3ODpbMiwxMDFdLDg2OlsyLDEwMV0sOTE6WzIsMTAxXSw5MzpbMiwxMDFdLDEwMjpbMiwxMDFdLDEwNDpbMiwxMDFdLDEwNTpbMiwxMDFdLDEwNjpbMiwxMDFdLDExMDpbMiwxMDFdLDExODpbMiwxMDFdLDEyNjpbMiwxMDFdLDEyOTpbMiwxMDFdLDEzMDpbMiwxMDFdLDEzMzpbMiwxMDFdLDEzNDpbMiwxMDFdLDEzNTpbMiwxMDFdLDEzNjpbMiwxMDFdLDEzNzpbMiwxMDFdLDEzODpbMiwxMDFdLDEzOTpbMiwxMDFdfSx7NzoyNzIsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezE6WzIsMTQyXSw2OlsyLDE0Ml0sMjU6WzIsMTQyXSwyNjpbMiwxNDJdLDQ5OlsyLDE0Ml0sNTQ6WzIsMTQyXSw1NzpbMiwxNDJdLDY2OlsyLDE0Ml0sNjc6WzIsMTQyXSw2ODpbMiwxNDJdLDY5OlsyLDE0Ml0sNzE6WzIsMTQyXSw3MzpbMiwxNDJdLDc0OlsyLDE0Ml0sNzg6WzIsMTQyXSw4NDpbMiwxNDJdLDg1OlsyLDE0Ml0sODY6WzIsMTQyXSw5MTpbMiwxNDJdLDkzOlsyLDE0Ml0sMTAyOlsyLDE0Ml0sMTA0OlsyLDE0Ml0sMTA1OlsyLDE0Ml0sMTA2OlsyLDE0Ml0sMTEwOlsyLDE0Ml0sMTE4OlsyLDE0Ml0sMTI2OlsyLDE0Ml0sMTI5OlsyLDE0Ml0sMTMwOlsyLDE0Ml0sMTMzOlsyLDE0Ml0sMTM0OlsyLDE0Ml0sMTM1OlsyLDE0Ml0sMTM2OlsyLDE0Ml0sMTM3OlsyLDE0Ml0sMTM4OlsyLDE0Ml0sMTM5OlsyLDE0Ml19LHs2OlsxLDczXSwyNjpbMSwyNzNdfSx7NzoyNzQsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezY6WzIsNjddLDExOlsyLDExOF0sMjU6WzIsNjddLDI4OlsyLDExOF0sMzA6WzIsMTE4XSwzMTpbMiwxMThdLDMzOlsyLDExOF0sMzQ6WzIsMTE4XSwzNTpbMiwxMThdLDM2OlsyLDExOF0sMzc6WzIsMTE4XSwzODpbMiwxMThdLDQ1OlsyLDExOF0sNDY6WzIsMTE4XSw0NzpbMiwxMThdLDUxOlsyLDExOF0sNTI6WzIsMTE4XSw1NDpbMiw2N10sNzY6WzIsMTE4XSw3OTpbMiwxMThdLDgzOlsyLDExOF0sODg6WzIsMTE4XSw4OTpbMiwxMThdLDkwOlsyLDExOF0sOTE6WzIsNjddLDk2OlsyLDExOF0sMTAwOlsyLDExOF0sMTAxOlsyLDExOF0sMTA0OlsyLDExOF0sMTA2OlsyLDExOF0sMTA4OlsyLDExOF0sMTEwOlsyLDExOF0sMTE5OlsyLDExOF0sMTI1OlsyLDExOF0sMTI3OlsyLDExOF0sMTI4OlsyLDExOF0sMTI5OlsyLDExOF0sMTMwOlsyLDExOF0sMTMxOlsyLDExOF0sMTMyOlsyLDExOF19LHs2OlsxLDI3Nl0sMjU6WzEsMjc3XSw5MTpbMSwyNzVdfSx7NjpbMiw1M10sNzoyMDMsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNTpbMiw1M10sMjY6WzIsNTNdLDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTc6WzEsMTQ5XSw1ODo0Niw1OTo0Nyw2MDoxNDgsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODY6WzIsNTNdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDkxOlsyLDUzXSw5NDoyNzgsOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7NjpbMiw1Ml0sMjU6WzIsNTJdLDI2OlsyLDUyXSw1MzoyNzksNTQ6WzEsMjMyXX0sezE6WzIsMTgyXSw2OlsyLDE4Ml0sMjU6WzIsMTgyXSwyNjpbMiwxODJdLDQ5OlsyLDE4Ml0sNTQ6WzIsMTgyXSw1NzpbMiwxODJdLDczOlsyLDE4Ml0sNzg6WzIsMTgyXSw4NjpbMiwxODJdLDkxOlsyLDE4Ml0sOTM6WzIsMTgyXSwxMDI6WzIsMTgyXSwxMDQ6WzIsMTgyXSwxMDU6WzIsMTgyXSwxMDY6WzIsMTgyXSwxMTA6WzIsMTgyXSwxMTg6WzIsMTgyXSwxMjE6WzIsMTgyXSwxMjY6WzIsMTgyXSwxMjk6WzIsMTgyXSwxMzA6WzIsMTgyXSwxMzM6WzIsMTgyXSwxMzQ6WzIsMTgyXSwxMzU6WzIsMTgyXSwxMzY6WzIsMTgyXSwxMzc6WzIsMTgyXSwxMzg6WzIsMTgyXSwxMzk6WzIsMTgyXX0sezc6MjgwLDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs3OjI4MSw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7MTE2OlsyLDE2MF0sMTE3OlsyLDE2MF19LHsyNzoxNjAsMjg6WzEsNzJdLDQ0OjE2MSw1ODoxNjIsNTk6MTYzLDc2OlsxLDY5XSw4OTpbMSwxMTJdLDkwOlsxLDExM10sMTE1OjI4Mn0sezE6WzIsMTY3XSw2OlsyLDE2N10sMjU6WzIsMTY3XSwyNjpbMiwxNjddLDQ5OlsyLDE2N10sNTQ6WzIsMTY3XSw1NzpbMiwxNjddLDczOlsyLDE2N10sNzg6WzIsMTY3XSw4NjpbMiwxNjddLDkxOlsyLDE2N10sOTM6WzIsMTY3XSwxMDI6WzIsMTY3XSwxMDM6ODQsMTA0OlsyLDE2N10sMTA1OlsxLDI4M10sMTA2OlsyLDE2N10sMTA5Ojg1LDExMDpbMiwxNjddLDExMTo2OCwxMTg6WzEsMjg0XSwxMjY6WzIsMTY3XSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMSw4MV0sMTM5OlsxLDgyXX0sezE6WzIsMTY4XSw2OlsyLDE2OF0sMjU6WzIsMTY4XSwyNjpbMiwxNjhdLDQ5OlsyLDE2OF0sNTQ6WzIsMTY4XSw1NzpbMiwxNjhdLDczOlsyLDE2OF0sNzg6WzIsMTY4XSw4NjpbMiwxNjhdLDkxOlsyLDE2OF0sOTM6WzIsMTY4XSwxMDI6WzIsMTY4XSwxMDM6ODQsMTA0OlsyLDE2OF0sMTA1OlsxLDI4NV0sMTA2OlsyLDE2OF0sMTA5Ojg1LDExMDpbMiwxNjhdLDExMTo2OCwxMTg6WzIsMTY4XSwxMjY6WzIsMTY4XSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMSw4MV0sMTM5OlsxLDgyXX0sezY6WzEsMjg3XSwyNTpbMSwyODhdLDc4OlsxLDI4Nl19LHs2OlsyLDUzXSwxMDoxNzAsMjU6WzIsNTNdLDI2OlsyLDUzXSwyNzoxNzEsMjg6WzEsNzJdLDI5OjE3MiwzMDpbMSw3MF0sMzE6WzEsNzFdLDQxOjI4OSw0MjoxNjksNDQ6MTczLDQ2OlsxLDQ1XSw3ODpbMiw1M10sODk6WzEsMTEyXX0sezc6MjkwLDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjU6WzEsMjkxXSwyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezE6WzIsODZdLDY6WzIsODZdLDI1OlsyLDg2XSwyNjpbMiw4Nl0sNDA6WzIsODZdLDQ5OlsyLDg2XSw1NDpbMiw4Nl0sNTc6WzIsODZdLDY2OlsyLDg2XSw2NzpbMiw4Nl0sNjg6WzIsODZdLDY5OlsyLDg2XSw3MTpbMiw4Nl0sNzM6WzIsODZdLDc0OlsyLDg2XSw3ODpbMiw4Nl0sODA6WzIsODZdLDg0OlsyLDg2XSw4NTpbMiw4Nl0sODY6WzIsODZdLDkxOlsyLDg2XSw5MzpbMiw4Nl0sMTAyOlsyLDg2XSwxMDQ6WzIsODZdLDEwNTpbMiw4Nl0sMTA2OlsyLDg2XSwxMTA6WzIsODZdLDExODpbMiw4Nl0sMTI2OlsyLDg2XSwxMjk6WzIsODZdLDEzMDpbMiw4Nl0sMTMxOlsyLDg2XSwxMzI6WzIsODZdLDEzMzpbMiw4Nl0sMTM0OlsyLDg2XSwxMzU6WzIsODZdLDEzNjpbMiw4Nl0sMTM3OlsyLDg2XSwxMzg6WzIsODZdLDEzOTpbMiw4Nl0sMTQwOlsyLDg2XX0sezc6MjkyLDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3MzpbMiwxMjFdLDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezczOlsyLDEyMl0sMTAzOjg0LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDk6ODUsMTEwOlsxLDY3XSwxMTE6NjgsMTI2OlsxLDgzXSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMSw4MV0sMTM5OlsxLDgyXX0sezE6WzIsMzZdLDY6WzIsMzZdLDI1OlsyLDM2XSwyNjpbMiwzNl0sNDk6WzIsMzZdLDU0OlsyLDM2XSw1NzpbMiwzNl0sNzM6WzIsMzZdLDc4OlsyLDM2XSw4NjpbMiwzNl0sOTE6WzIsMzZdLDkzOlsyLDM2XSwxMDI6WzIsMzZdLDEwMzo4NCwxMDQ6WzIsMzZdLDEwNTpbMiwzNl0sMTA2OlsyLDM2XSwxMDk6ODUsMTEwOlsyLDM2XSwxMTE6NjgsMTE4OlsyLDM2XSwxMjY6WzIsMzZdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7MjY6WzEsMjkzXSwxMDM6ODQsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwOTo4NSwxMTA6WzEsNjddLDExMTo2OCwxMjY6WzEsODNdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7NjpbMSwyNzZdLDI1OlsxLDI3N10sODY6WzEsMjk0XX0sezY6WzIsNjddLDI1OlsyLDY3XSwyNjpbMiw2N10sNTQ6WzIsNjddLDg2OlsyLDY3XSw5MTpbMiw2N119LHsyNDoyOTUsMjU6WzEsMTE1XX0sezY6WzIsNTZdLDI1OlsyLDU2XSwyNjpbMiw1Nl0sNDk6WzIsNTZdLDU0OlsyLDU2XX0sezI3OjEwOCwyODpbMSw3Ml0sNDQ6MTA5LDU1OjI5Niw1NjoxMDYsNTc6WzEsMTA3XSw1ODoxMTAsNTk6MTExLDc2OlsxLDY5XSw4OTpbMSwxMTJdLDkwOlsxLDExM119LHs2OlsyLDU0XSwyNTpbMiw1NF0sMjY6WzIsNTRdLDI3OjEwOCwyODpbMSw3Ml0sNDQ6MTA5LDQ4OjI5Nyw1NDpbMiw1NF0sNTU6MTA1LDU2OjEwNiw1NzpbMSwxMDddLDU4OjExMCw1OToxMTEsNzY6WzEsNjldLDg5OlsxLDExMl0sOTA6WzEsMTEzXX0sezY6WzIsNjFdLDI1OlsyLDYxXSwyNjpbMiw2MV0sNDk6WzIsNjFdLDU0OlsyLDYxXSwxMDM6ODQsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwOTo4NSwxMTA6WzEsNjddLDExMTo2OCwxMjY6WzEsODNdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7MTpbMiwyNF0sNjpbMiwyNF0sMjU6WzIsMjRdLDI2OlsyLDI0XSw0OTpbMiwyNF0sNTQ6WzIsMjRdLDU3OlsyLDI0XSw3MzpbMiwyNF0sNzg6WzIsMjRdLDg2OlsyLDI0XSw5MTpbMiwyNF0sOTM6WzIsMjRdLDk4OlsyLDI0XSw5OTpbMiwyNF0sMTAyOlsyLDI0XSwxMDQ6WzIsMjRdLDEwNTpbMiwyNF0sMTA2OlsyLDI0XSwxMTA6WzIsMjRdLDExODpbMiwyNF0sMTIxOlsyLDI0XSwxMjM6WzIsMjRdLDEyNjpbMiwyNF0sMTI5OlsyLDI0XSwxMzA6WzIsMjRdLDEzMzpbMiwyNF0sMTM0OlsyLDI0XSwxMzU6WzIsMjRdLDEzNjpbMiwyNF0sMTM3OlsyLDI0XSwxMzg6WzIsMjRdLDEzOTpbMiwyNF19LHsyNjpbMSwyOThdLDEwMzo4NCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA5Ojg1LDExMDpbMSw2N10sMTExOjY4LDEyNjpbMSw4M10sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHsxOlsyLDIwN10sNjpbMiwyMDddLDI1OlsyLDIwN10sMjY6WzIsMjA3XSw0OTpbMiwyMDddLDU0OlsyLDIwN10sNTc6WzIsMjA3XSw3MzpbMiwyMDddLDc4OlsyLDIwN10sODY6WzIsMjA3XSw5MTpbMiwyMDddLDkzOlsyLDIwN10sMTAyOlsyLDIwN10sMTAzOjg0LDEwNDpbMiwyMDddLDEwNTpbMiwyMDddLDEwNjpbMiwyMDddLDEwOTo4NSwxMTA6WzIsMjA3XSwxMTE6NjgsMTE4OlsyLDIwN10sMTI2OlsyLDIwN10sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHsyNDoyOTksMjU6WzEsMTE1XSwxMDM6ODQsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwOTo4NSwxMTA6WzEsNjddLDExMTo2OCwxMjY6WzEsODNdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7MjQ6MzAwLDI1OlsxLDExNV19LHsxOlsyLDEzNl0sNjpbMiwxMzZdLDI1OlsyLDEzNl0sMjY6WzIsMTM2XSw0OTpbMiwxMzZdLDU0OlsyLDEzNl0sNTc6WzIsMTM2XSw3MzpbMiwxMzZdLDc4OlsyLDEzNl0sODY6WzIsMTM2XSw5MTpbMiwxMzZdLDkzOlsyLDEzNl0sMTAyOlsyLDEzNl0sMTA0OlsyLDEzNl0sMTA1OlsyLDEzNl0sMTA2OlsyLDEzNl0sMTEwOlsyLDEzNl0sMTE4OlsyLDEzNl0sMTI2OlsyLDEzNl0sMTI5OlsyLDEzNl0sMTMwOlsyLDEzNl0sMTMzOlsyLDEzNl0sMTM0OlsyLDEzNl0sMTM1OlsyLDEzNl0sMTM2OlsyLDEzNl0sMTM3OlsyLDEzNl0sMTM4OlsyLDEzNl0sMTM5OlsyLDEzNl19LHsyNDozMDEsMjU6WzEsMTE1XX0sezI0OjMwMiwyNTpbMSwxMTVdfSx7MTpbMiwxNDBdLDY6WzIsMTQwXSwyNTpbMiwxNDBdLDI2OlsyLDE0MF0sNDk6WzIsMTQwXSw1NDpbMiwxNDBdLDU3OlsyLDE0MF0sNzM6WzIsMTQwXSw3ODpbMiwxNDBdLDg2OlsyLDE0MF0sOTE6WzIsMTQwXSw5MzpbMiwxNDBdLDk4OlsyLDE0MF0sMTAyOlsyLDE0MF0sMTA0OlsyLDE0MF0sMTA1OlsyLDE0MF0sMTA2OlsyLDE0MF0sMTEwOlsyLDE0MF0sMTE4OlsyLDE0MF0sMTI2OlsyLDE0MF0sMTI5OlsyLDE0MF0sMTMwOlsyLDE0MF0sMTMzOlsyLDE0MF0sMTM0OlsyLDE0MF0sMTM1OlsyLDE0MF0sMTM2OlsyLDE0MF0sMTM3OlsyLDE0MF0sMTM4OlsyLDE0MF0sMTM5OlsyLDE0MF19LHsyNjpbMSwzMDNdLDEyMTpbMSwzMDRdLDEyMjoyNjgsMTIzOlsxLDIyM119LHsxOlsyLDE3Nl0sNjpbMiwxNzZdLDI1OlsyLDE3Nl0sMjY6WzIsMTc2XSw0OTpbMiwxNzZdLDU0OlsyLDE3Nl0sNTc6WzIsMTc2XSw3MzpbMiwxNzZdLDc4OlsyLDE3Nl0sODY6WzIsMTc2XSw5MTpbMiwxNzZdLDkzOlsyLDE3Nl0sMTAyOlsyLDE3Nl0sMTA0OlsyLDE3Nl0sMTA1OlsyLDE3Nl0sMTA2OlsyLDE3Nl0sMTEwOlsyLDE3Nl0sMTE4OlsyLDE3Nl0sMTI2OlsyLDE3Nl0sMTI5OlsyLDE3Nl0sMTMwOlsyLDE3Nl0sMTMzOlsyLDE3Nl0sMTM0OlsyLDE3Nl0sMTM1OlsyLDE3Nl0sMTM2OlsyLDE3Nl0sMTM3OlsyLDE3Nl0sMTM4OlsyLDE3Nl0sMTM5OlsyLDE3Nl19LHsyNDozMDUsMjU6WzEsMTE1XX0sezI2OlsyLDE3OV0sMTIxOlsyLDE3OV0sMTIzOlsyLDE3OV19LHsyNDozMDYsMjU6WzEsMTE1XSw1NDpbMSwzMDddfSx7MjU6WzIsMTMyXSw1NDpbMiwxMzJdLDEwMzo4NCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA5Ojg1LDExMDpbMSw2N10sMTExOjY4LDEyNjpbMSw4M10sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHsxOlsyLDk5XSw2OlsyLDk5XSwyNTpbMiw5OV0sMjY6WzIsOTldLDQ5OlsyLDk5XSw1NDpbMiw5OV0sNTc6WzIsOTldLDczOlsyLDk5XSw3ODpbMiw5OV0sODY6WzIsOTldLDkxOlsyLDk5XSw5MzpbMiw5OV0sMTAyOlsyLDk5XSwxMDQ6WzIsOTldLDEwNTpbMiw5OV0sMTA2OlsyLDk5XSwxMTA6WzIsOTldLDExODpbMiw5OV0sMTI2OlsyLDk5XSwxMjk6WzIsOTldLDEzMDpbMiw5OV0sMTMzOlsyLDk5XSwxMzQ6WzIsOTldLDEzNTpbMiw5OV0sMTM2OlsyLDk5XSwxMzc6WzIsOTldLDEzODpbMiw5OV0sMTM5OlsyLDk5XX0sezE6WzIsMTAyXSw2OlsyLDEwMl0sMjQ6MzA4LDI1OlsxLDExNV0sMjY6WzIsMTAyXSw0OTpbMiwxMDJdLDU0OlsyLDEwMl0sNTc6WzIsMTAyXSw3MzpbMiwxMDJdLDc4OlsyLDEwMl0sODY6WzIsMTAyXSw5MTpbMiwxMDJdLDkzOlsyLDEwMl0sMTAyOlsyLDEwMl0sMTAzOjg0LDEwNDpbMSw2NF0sMTA1OlsyLDEwMl0sMTA2OlsxLDY1XSwxMDk6ODUsMTEwOlsxLDY3XSwxMTE6NjgsMTE4OlsyLDEwMl0sMTI2OlsyLDEwMl0sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHsxMDI6WzEsMzA5XX0sezkxOlsxLDMxMF0sMTAzOjg0LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDk6ODUsMTEwOlsxLDY3XSwxMTE6NjgsMTI2OlsxLDgzXSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMSw4MV0sMTM5OlsxLDgyXX0sezE6WzIsMTE2XSw2OlsyLDExNl0sMjU6WzIsMTE2XSwyNjpbMiwxMTZdLDQwOlsyLDExNl0sNDk6WzIsMTE2XSw1NDpbMiwxMTZdLDU3OlsyLDExNl0sNjY6WzIsMTE2XSw2NzpbMiwxMTZdLDY4OlsyLDExNl0sNjk6WzIsMTE2XSw3MTpbMiwxMTZdLDczOlsyLDExNl0sNzQ6WzIsMTE2XSw3ODpbMiwxMTZdLDg0OlsyLDExNl0sODU6WzIsMTE2XSw4NjpbMiwxMTZdLDkxOlsyLDExNl0sOTM6WzIsMTE2XSwxMDI6WzIsMTE2XSwxMDQ6WzIsMTE2XSwxMDU6WzIsMTE2XSwxMDY6WzIsMTE2XSwxMTA6WzIsMTE2XSwxMTY6WzIsMTE2XSwxMTc6WzIsMTE2XSwxMTg6WzIsMTE2XSwxMjY6WzIsMTE2XSwxMjk6WzIsMTE2XSwxMzA6WzIsMTE2XSwxMzM6WzIsMTE2XSwxMzQ6WzIsMTE2XSwxMzU6WzIsMTE2XSwxMzY6WzIsMTE2XSwxMzc6WzIsMTE2XSwxMzg6WzIsMTE2XSwxMzk6WzIsMTE2XX0sezc6MjAzLDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1NzpbMSwxNDldLDU4OjQ2LDU5OjQ3LDYwOjE0OCw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NDozMTEsOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7NzoyMDMsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNTpbMSwxNDddLDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTc6WzEsMTQ5XSw1ODo0Niw1OTo0Nyw2MDoxNDgsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODc6MzEyLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk0OjE0Niw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs2OlsyLDEyNV0sMjU6WzIsMTI1XSwyNjpbMiwxMjVdLDU0OlsyLDEyNV0sODY6WzIsMTI1XSw5MTpbMiwxMjVdfSx7NjpbMSwyNzZdLDI1OlsxLDI3N10sMjY6WzEsMzEzXX0sezE6WzIsMTQ1XSw2OlsyLDE0NV0sMjU6WzIsMTQ1XSwyNjpbMiwxNDVdLDQ5OlsyLDE0NV0sNTQ6WzIsMTQ1XSw1NzpbMiwxNDVdLDczOlsyLDE0NV0sNzg6WzIsMTQ1XSw4NjpbMiwxNDVdLDkxOlsyLDE0NV0sOTM6WzIsMTQ1XSwxMDI6WzIsMTQ1XSwxMDM6ODQsMTA0OlsxLDY0XSwxMDU6WzIsMTQ1XSwxMDY6WzEsNjVdLDEwOTo4NSwxMTA6WzEsNjddLDExMTo2OCwxMTg6WzIsMTQ1XSwxMjY6WzIsMTQ1XSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMSw4MV0sMTM5OlsxLDgyXX0sezE6WzIsMTQ3XSw2OlsyLDE0N10sMjU6WzIsMTQ3XSwyNjpbMiwxNDddLDQ5OlsyLDE0N10sNTQ6WzIsMTQ3XSw1NzpbMiwxNDddLDczOlsyLDE0N10sNzg6WzIsMTQ3XSw4NjpbMiwxNDddLDkxOlsyLDE0N10sOTM6WzIsMTQ3XSwxMDI6WzIsMTQ3XSwxMDM6ODQsMTA0OlsxLDY0XSwxMDU6WzIsMTQ3XSwxMDY6WzEsNjVdLDEwOTo4NSwxMTA6WzEsNjddLDExMTo2OCwxMTg6WzIsMTQ3XSwxMjY6WzIsMTQ3XSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMSw4MV0sMTM5OlsxLDgyXX0sezExNjpbMiwxNjZdLDExNzpbMiwxNjZdfSx7NzozMTQsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezc6MzE1LDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs3OjMxNiw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7MTpbMiw5MF0sNjpbMiw5MF0sMjU6WzIsOTBdLDI2OlsyLDkwXSw0MDpbMiw5MF0sNDk6WzIsOTBdLDU0OlsyLDkwXSw1NzpbMiw5MF0sNjY6WzIsOTBdLDY3OlsyLDkwXSw2ODpbMiw5MF0sNjk6WzIsOTBdLDcxOlsyLDkwXSw3MzpbMiw5MF0sNzQ6WzIsOTBdLDc4OlsyLDkwXSw4NDpbMiw5MF0sODU6WzIsOTBdLDg2OlsyLDkwXSw5MTpbMiw5MF0sOTM6WzIsOTBdLDEwMjpbMiw5MF0sMTA0OlsyLDkwXSwxMDU6WzIsOTBdLDEwNjpbMiw5MF0sMTEwOlsyLDkwXSwxMTY6WzIsOTBdLDExNzpbMiw5MF0sMTE4OlsyLDkwXSwxMjY6WzIsOTBdLDEyOTpbMiw5MF0sMTMwOlsyLDkwXSwxMzM6WzIsOTBdLDEzNDpbMiw5MF0sMTM1OlsyLDkwXSwxMzY6WzIsOTBdLDEzNzpbMiw5MF0sMTM4OlsyLDkwXSwxMzk6WzIsOTBdfSx7MTA6MTcwLDI3OjE3MSwyODpbMSw3Ml0sMjk6MTcyLDMwOlsxLDcwXSwzMTpbMSw3MV0sNDE6MzE3LDQyOjE2OSw0NDoxNzMsNDY6WzEsNDVdLDg5OlsxLDExMl19LHs2OlsyLDkxXSwxMDoxNzAsMjU6WzIsOTFdLDI2OlsyLDkxXSwyNzoxNzEsMjg6WzEsNzJdLDI5OjE3MiwzMDpbMSw3MF0sMzE6WzEsNzFdLDQxOjE2OCw0MjoxNjksNDQ6MTczLDQ2OlsxLDQ1XSw1NDpbMiw5MV0sNzc6MzE4LDg5OlsxLDExMl19LHs2OlsyLDkzXSwyNTpbMiw5M10sMjY6WzIsOTNdLDU0OlsyLDkzXSw3ODpbMiw5M119LHs2OlsyLDM5XSwyNTpbMiwzOV0sMjY6WzIsMzldLDU0OlsyLDM5XSw3ODpbMiwzOV0sMTAzOjg0LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDk6ODUsMTEwOlsxLDY3XSwxMTE6NjgsMTI2OlsxLDgzXSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMSw4MV0sMTM5OlsxLDgyXX0sezc6MzE5LDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs3MzpbMiwxMjBdLDEwMzo4NCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA5Ojg1LDExMDpbMSw2N10sMTExOjY4LDEyNjpbMSw4M10sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHsxOlsyLDM3XSw2OlsyLDM3XSwyNTpbMiwzN10sMjY6WzIsMzddLDQ5OlsyLDM3XSw1NDpbMiwzN10sNTc6WzIsMzddLDczOlsyLDM3XSw3ODpbMiwzN10sODY6WzIsMzddLDkxOlsyLDM3XSw5MzpbMiwzN10sMTAyOlsyLDM3XSwxMDQ6WzIsMzddLDEwNTpbMiwzN10sMTA2OlsyLDM3XSwxMTA6WzIsMzddLDExODpbMiwzN10sMTI2OlsyLDM3XSwxMjk6WzIsMzddLDEzMDpbMiwzN10sMTMzOlsyLDM3XSwxMzQ6WzIsMzddLDEzNTpbMiwzN10sMTM2OlsyLDM3XSwxMzc6WzIsMzddLDEzODpbMiwzN10sMTM5OlsyLDM3XX0sezE6WzIsMTExXSw2OlsyLDExMV0sMjU6WzIsMTExXSwyNjpbMiwxMTFdLDQ5OlsyLDExMV0sNTQ6WzIsMTExXSw1NzpbMiwxMTFdLDY2OlsyLDExMV0sNjc6WzIsMTExXSw2ODpbMiwxMTFdLDY5OlsyLDExMV0sNzE6WzIsMTExXSw3MzpbMiwxMTFdLDc0OlsyLDExMV0sNzg6WzIsMTExXSw4NDpbMiwxMTFdLDg1OlsyLDExMV0sODY6WzIsMTExXSw5MTpbMiwxMTFdLDkzOlsyLDExMV0sMTAyOlsyLDExMV0sMTA0OlsyLDExMV0sMTA1OlsyLDExMV0sMTA2OlsyLDExMV0sMTEwOlsyLDExMV0sMTE4OlsyLDExMV0sMTI2OlsyLDExMV0sMTI5OlsyLDExMV0sMTMwOlsyLDExMV0sMTMzOlsyLDExMV0sMTM0OlsyLDExMV0sMTM1OlsyLDExMV0sMTM2OlsyLDExMV0sMTM3OlsyLDExMV0sMTM4OlsyLDExMV0sMTM5OlsyLDExMV19LHsxOlsyLDQ4XSw2OlsyLDQ4XSwyNTpbMiw0OF0sMjY6WzIsNDhdLDQ5OlsyLDQ4XSw1NDpbMiw0OF0sNTc6WzIsNDhdLDczOlsyLDQ4XSw3ODpbMiw0OF0sODY6WzIsNDhdLDkxOlsyLDQ4XSw5MzpbMiw0OF0sMTAyOlsyLDQ4XSwxMDQ6WzIsNDhdLDEwNTpbMiw0OF0sMTA2OlsyLDQ4XSwxMTA6WzIsNDhdLDExODpbMiw0OF0sMTI2OlsyLDQ4XSwxMjk6WzIsNDhdLDEzMDpbMiw0OF0sMTMzOlsyLDQ4XSwxMzQ6WzIsNDhdLDEzNTpbMiw0OF0sMTM2OlsyLDQ4XSwxMzc6WzIsNDhdLDEzODpbMiw0OF0sMTM5OlsyLDQ4XX0sezY6WzIsNTddLDI1OlsyLDU3XSwyNjpbMiw1N10sNDk6WzIsNTddLDU0OlsyLDU3XX0sezY6WzIsNTJdLDI1OlsyLDUyXSwyNjpbMiw1Ml0sNTM6MzIwLDU0OlsxLDIwNV19LHsxOlsyLDIwNl0sNjpbMiwyMDZdLDI1OlsyLDIwNl0sMjY6WzIsMjA2XSw0OTpbMiwyMDZdLDU0OlsyLDIwNl0sNTc6WzIsMjA2XSw3MzpbMiwyMDZdLDc4OlsyLDIwNl0sODY6WzIsMjA2XSw5MTpbMiwyMDZdLDkzOlsyLDIwNl0sMTAyOlsyLDIwNl0sMTA0OlsyLDIwNl0sMTA1OlsyLDIwNl0sMTA2OlsyLDIwNl0sMTEwOlsyLDIwNl0sMTE4OlsyLDIwNl0sMTI2OlsyLDIwNl0sMTI5OlsyLDIwNl0sMTMwOlsyLDIwNl0sMTMzOlsyLDIwNl0sMTM0OlsyLDIwNl0sMTM1OlsyLDIwNl0sMTM2OlsyLDIwNl0sMTM3OlsyLDIwNl0sMTM4OlsyLDIwNl0sMTM5OlsyLDIwNl19LHsxOlsyLDE4M10sNjpbMiwxODNdLDI1OlsyLDE4M10sMjY6WzIsMTgzXSw0OTpbMiwxODNdLDU0OlsyLDE4M10sNTc6WzIsMTgzXSw3MzpbMiwxODNdLDc4OlsyLDE4M10sODY6WzIsMTgzXSw5MTpbMiwxODNdLDkzOlsyLDE4M10sMTAyOlsyLDE4M10sMTA0OlsyLDE4M10sMTA1OlsyLDE4M10sMTA2OlsyLDE4M10sMTEwOlsyLDE4M10sMTE4OlsyLDE4M10sMTIxOlsyLDE4M10sMTI2OlsyLDE4M10sMTI5OlsyLDE4M10sMTMwOlsyLDE4M10sMTMzOlsyLDE4M10sMTM0OlsyLDE4M10sMTM1OlsyLDE4M10sMTM2OlsyLDE4M10sMTM3OlsyLDE4M10sMTM4OlsyLDE4M10sMTM5OlsyLDE4M119LHsxOlsyLDEzN10sNjpbMiwxMzddLDI1OlsyLDEzN10sMjY6WzIsMTM3XSw0OTpbMiwxMzddLDU0OlsyLDEzN10sNTc6WzIsMTM3XSw3MzpbMiwxMzddLDc4OlsyLDEzN10sODY6WzIsMTM3XSw5MTpbMiwxMzddLDkzOlsyLDEzN10sMTAyOlsyLDEzN10sMTA0OlsyLDEzN10sMTA1OlsyLDEzN10sMTA2OlsyLDEzN10sMTEwOlsyLDEzN10sMTE4OlsyLDEzN10sMTI2OlsyLDEzN10sMTI5OlsyLDEzN10sMTMwOlsyLDEzN10sMTMzOlsyLDEzN10sMTM0OlsyLDEzN10sMTM1OlsyLDEzN10sMTM2OlsyLDEzN10sMTM3OlsyLDEzN10sMTM4OlsyLDEzN10sMTM5OlsyLDEzN119LHsxOlsyLDEzOF0sNjpbMiwxMzhdLDI1OlsyLDEzOF0sMjY6WzIsMTM4XSw0OTpbMiwxMzhdLDU0OlsyLDEzOF0sNTc6WzIsMTM4XSw3MzpbMiwxMzhdLDc4OlsyLDEzOF0sODY6WzIsMTM4XSw5MTpbMiwxMzhdLDkzOlsyLDEzOF0sOTg6WzIsMTM4XSwxMDI6WzIsMTM4XSwxMDQ6WzIsMTM4XSwxMDU6WzIsMTM4XSwxMDY6WzIsMTM4XSwxMTA6WzIsMTM4XSwxMTg6WzIsMTM4XSwxMjY6WzIsMTM4XSwxMjk6WzIsMTM4XSwxMzA6WzIsMTM4XSwxMzM6WzIsMTM4XSwxMzQ6WzIsMTM4XSwxMzU6WzIsMTM4XSwxMzY6WzIsMTM4XSwxMzc6WzIsMTM4XSwxMzg6WzIsMTM4XSwxMzk6WzIsMTM4XX0sezE6WzIsMTM5XSw2OlsyLDEzOV0sMjU6WzIsMTM5XSwyNjpbMiwxMzldLDQ5OlsyLDEzOV0sNTQ6WzIsMTM5XSw1NzpbMiwxMzldLDczOlsyLDEzOV0sNzg6WzIsMTM5XSw4NjpbMiwxMzldLDkxOlsyLDEzOV0sOTM6WzIsMTM5XSw5ODpbMiwxMzldLDEwMjpbMiwxMzldLDEwNDpbMiwxMzldLDEwNTpbMiwxMzldLDEwNjpbMiwxMzldLDExMDpbMiwxMzldLDExODpbMiwxMzldLDEyNjpbMiwxMzldLDEyOTpbMiwxMzldLDEzMDpbMiwxMzldLDEzMzpbMiwxMzldLDEzNDpbMiwxMzldLDEzNTpbMiwxMzldLDEzNjpbMiwxMzldLDEzNzpbMiwxMzldLDEzODpbMiwxMzldLDEzOTpbMiwxMzldfSx7MTpbMiwxNzRdLDY6WzIsMTc0XSwyNTpbMiwxNzRdLDI2OlsyLDE3NF0sNDk6WzIsMTc0XSw1NDpbMiwxNzRdLDU3OlsyLDE3NF0sNzM6WzIsMTc0XSw3ODpbMiwxNzRdLDg2OlsyLDE3NF0sOTE6WzIsMTc0XSw5MzpbMiwxNzRdLDEwMjpbMiwxNzRdLDEwNDpbMiwxNzRdLDEwNTpbMiwxNzRdLDEwNjpbMiwxNzRdLDExMDpbMiwxNzRdLDExODpbMiwxNzRdLDEyNjpbMiwxNzRdLDEyOTpbMiwxNzRdLDEzMDpbMiwxNzRdLDEzMzpbMiwxNzRdLDEzNDpbMiwxNzRdLDEzNTpbMiwxNzRdLDEzNjpbMiwxNzRdLDEzNzpbMiwxNzRdLDEzODpbMiwxNzRdLDEzOTpbMiwxNzRdfSx7MjQ6MzIxLDI1OlsxLDExNV19LHsyNjpbMSwzMjJdfSx7NjpbMSwzMjNdLDI2OlsyLDE4MF0sMTIxOlsyLDE4MF0sMTIzOlsyLDE4MF19LHs3OjMyNCw4OjExNyw5OjE4LDEwOjE5LDExOlsxLDIwXSwxMjo2LDEzOjcsMTQ6OCwxNTo5LDE2OjEwLDE3OjExLDE4OjEyLDE5OjEzLDIwOjE0LDIxOjE1LDIyOjE2LDIzOjE3LDI3OjYxLDI4OlsxLDcyXSwyOTo0OCwzMDpbMSw3MF0sMzE6WzEsNzFdLDMyOjIyLDMzOlsxLDQ5XSwzNDpbMSw1MF0sMzU6WzEsNTFdLDM2OlsxLDUyXSwzNzpbMSw1M10sMzg6WzEsNTRdLDM5OjIxLDQ0OjYyLDQ1OlsxLDQ0XSw0NjpbMSw0NV0sNDc6WzEsMjddLDUwOjI4LDUxOlsxLDU5XSw1MjpbMSw2MF0sNTg6NDYsNTk6NDcsNjE6MzUsNjM6MjMsNjQ6MjQsNjU6MjUsNzY6WzEsNjldLDc5OlsxLDQyXSw4MzpbMSwyNl0sODg6WzEsNTddLDg5OlsxLDU4XSw5MDpbMSw1Nl0sOTY6WzEsMzddLDEwMDpbMSw0M10sMTAxOlsxLDU1XSwxMDM6MzgsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwNzozOSwxMDg6WzEsNjZdLDEwOTo0MCwxMTA6WzEsNjddLDExMTo2OCwxMTk6WzEsNDFdLDEyNDozNiwxMjU6WzEsNjNdLDEyNzpbMSwyOV0sMTI4OlsxLDMwXSwxMjk6WzEsMzFdLDEzMDpbMSwzMl0sMTMxOlsxLDMzXSwxMzI6WzEsMzRdfSx7MTpbMiwxMDNdLDY6WzIsMTAzXSwyNTpbMiwxMDNdLDI2OlsyLDEwM10sNDk6WzIsMTAzXSw1NDpbMiwxMDNdLDU3OlsyLDEwM10sNzM6WzIsMTAzXSw3ODpbMiwxMDNdLDg2OlsyLDEwM10sOTE6WzIsMTAzXSw5MzpbMiwxMDNdLDEwMjpbMiwxMDNdLDEwNDpbMiwxMDNdLDEwNTpbMiwxMDNdLDEwNjpbMiwxMDNdLDExMDpbMiwxMDNdLDExODpbMiwxMDNdLDEyNjpbMiwxMDNdLDEyOTpbMiwxMDNdLDEzMDpbMiwxMDNdLDEzMzpbMiwxMDNdLDEzNDpbMiwxMDNdLDEzNTpbMiwxMDNdLDEzNjpbMiwxMDNdLDEzNzpbMiwxMDNdLDEzODpbMiwxMDNdLDEzOTpbMiwxMDNdfSx7MTpbMiwxNDNdLDY6WzIsMTQzXSwyNTpbMiwxNDNdLDI2OlsyLDE0M10sNDk6WzIsMTQzXSw1NDpbMiwxNDNdLDU3OlsyLDE0M10sNjY6WzIsMTQzXSw2NzpbMiwxNDNdLDY4OlsyLDE0M10sNjk6WzIsMTQzXSw3MTpbMiwxNDNdLDczOlsyLDE0M10sNzQ6WzIsMTQzXSw3ODpbMiwxNDNdLDg0OlsyLDE0M10sODU6WzIsMTQzXSw4NjpbMiwxNDNdLDkxOlsyLDE0M10sOTM6WzIsMTQzXSwxMDI6WzIsMTQzXSwxMDQ6WzIsMTQzXSwxMDU6WzIsMTQzXSwxMDY6WzIsMTQzXSwxMTA6WzIsMTQzXSwxMTg6WzIsMTQzXSwxMjY6WzIsMTQzXSwxMjk6WzIsMTQzXSwxMzA6WzIsMTQzXSwxMzM6WzIsMTQzXSwxMzQ6WzIsMTQzXSwxMzU6WzIsMTQzXSwxMzY6WzIsMTQzXSwxMzc6WzIsMTQzXSwxMzg6WzIsMTQzXSwxMzk6WzIsMTQzXX0sezE6WzIsMTE5XSw2OlsyLDExOV0sMjU6WzIsMTE5XSwyNjpbMiwxMTldLDQ5OlsyLDExOV0sNTQ6WzIsMTE5XSw1NzpbMiwxMTldLDY2OlsyLDExOV0sNjc6WzIsMTE5XSw2ODpbMiwxMTldLDY5OlsyLDExOV0sNzE6WzIsMTE5XSw3MzpbMiwxMTldLDc0OlsyLDExOV0sNzg6WzIsMTE5XSw4NDpbMiwxMTldLDg1OlsyLDExOV0sODY6WzIsMTE5XSw5MTpbMiwxMTldLDkzOlsyLDExOV0sMTAyOlsyLDExOV0sMTA0OlsyLDExOV0sMTA1OlsyLDExOV0sMTA2OlsyLDExOV0sMTEwOlsyLDExOV0sMTE4OlsyLDExOV0sMTI2OlsyLDExOV0sMTI5OlsyLDExOV0sMTMwOlsyLDExOV0sMTMzOlsyLDExOV0sMTM0OlsyLDExOV0sMTM1OlsyLDExOV0sMTM2OlsyLDExOV0sMTM3OlsyLDExOV0sMTM4OlsyLDExOV0sMTM5OlsyLDExOV19LHs2OlsyLDEyNl0sMjU6WzIsMTI2XSwyNjpbMiwxMjZdLDU0OlsyLDEyNl0sODY6WzIsMTI2XSw5MTpbMiwxMjZdfSx7NjpbMiw1Ml0sMjU6WzIsNTJdLDI2OlsyLDUyXSw1MzozMjUsNTQ6WzEsMjMyXX0sezY6WzIsMTI3XSwyNTpbMiwxMjddLDI2OlsyLDEyN10sNTQ6WzIsMTI3XSw4NjpbMiwxMjddLDkxOlsyLDEyN119LHsxOlsyLDE2OV0sNjpbMiwxNjldLDI1OlsyLDE2OV0sMjY6WzIsMTY5XSw0OTpbMiwxNjldLDU0OlsyLDE2OV0sNTc6WzIsMTY5XSw3MzpbMiwxNjldLDc4OlsyLDE2OV0sODY6WzIsMTY5XSw5MTpbMiwxNjldLDkzOlsyLDE2OV0sMTAyOlsyLDE2OV0sMTAzOjg0LDEwNDpbMiwxNjldLDEwNTpbMiwxNjldLDEwNjpbMiwxNjldLDEwOTo4NSwxMTA6WzIsMTY5XSwxMTE6NjgsMTE4OlsxLDMyNl0sMTI2OlsyLDE2OV0sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHsxOlsyLDE3MV0sNjpbMiwxNzFdLDI1OlsyLDE3MV0sMjY6WzIsMTcxXSw0OTpbMiwxNzFdLDU0OlsyLDE3MV0sNTc6WzIsMTcxXSw3MzpbMiwxNzFdLDc4OlsyLDE3MV0sODY6WzIsMTcxXSw5MTpbMiwxNzFdLDkzOlsyLDE3MV0sMTAyOlsyLDE3MV0sMTAzOjg0LDEwNDpbMiwxNzFdLDEwNTpbMSwzMjddLDEwNjpbMiwxNzFdLDEwOTo4NSwxMTA6WzIsMTcxXSwxMTE6NjgsMTE4OlsyLDE3MV0sMTI2OlsyLDE3MV0sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHsxOlsyLDE3MF0sNjpbMiwxNzBdLDI1OlsyLDE3MF0sMjY6WzIsMTcwXSw0OTpbMiwxNzBdLDU0OlsyLDE3MF0sNTc6WzIsMTcwXSw3MzpbMiwxNzBdLDc4OlsyLDE3MF0sODY6WzIsMTcwXSw5MTpbMiwxNzBdLDkzOlsyLDE3MF0sMTAyOlsyLDE3MF0sMTAzOjg0LDEwNDpbMiwxNzBdLDEwNTpbMiwxNzBdLDEwNjpbMiwxNzBdLDEwOTo4NSwxMTA6WzIsMTcwXSwxMTE6NjgsMTE4OlsyLDE3MF0sMTI2OlsyLDE3MF0sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHs2OlsyLDk0XSwyNTpbMiw5NF0sMjY6WzIsOTRdLDU0OlsyLDk0XSw3ODpbMiw5NF19LHs2OlsyLDUyXSwyNTpbMiw1Ml0sMjY6WzIsNTJdLDUzOjMyOCw1NDpbMSwyNDJdfSx7MjY6WzEsMzI5XSwxMDM6ODQsMTA0OlsxLDY0XSwxMDY6WzEsNjVdLDEwOTo4NSwxMTA6WzEsNjddLDExMTo2OCwxMjY6WzEsODNdLDEyOTpbMSw3Nl0sMTMwOlsxLDc1XSwxMzM6WzEsNzRdLDEzNDpbMSw3N10sMTM1OlsxLDc4XSwxMzY6WzEsNzldLDEzNzpbMSw4MF0sMTM4OlsxLDgxXSwxMzk6WzEsODJdfSx7NjpbMSwyNTNdLDI1OlsxLDI1NF0sMjY6WzEsMzMwXX0sezI2OlsxLDMzMV19LHsxOlsyLDE3N10sNjpbMiwxNzddLDI1OlsyLDE3N10sMjY6WzIsMTc3XSw0OTpbMiwxNzddLDU0OlsyLDE3N10sNTc6WzIsMTc3XSw3MzpbMiwxNzddLDc4OlsyLDE3N10sODY6WzIsMTc3XSw5MTpbMiwxNzddLDkzOlsyLDE3N10sMTAyOlsyLDE3N10sMTA0OlsyLDE3N10sMTA1OlsyLDE3N10sMTA2OlsyLDE3N10sMTEwOlsyLDE3N10sMTE4OlsyLDE3N10sMTI2OlsyLDE3N10sMTI5OlsyLDE3N10sMTMwOlsyLDE3N10sMTMzOlsyLDE3N10sMTM0OlsyLDE3N10sMTM1OlsyLDE3N10sMTM2OlsyLDE3N10sMTM3OlsyLDE3N10sMTM4OlsyLDE3N10sMTM5OlsyLDE3N119LHsyNjpbMiwxODFdLDEyMTpbMiwxODFdLDEyMzpbMiwxODFdfSx7MjU6WzIsMTMzXSw1NDpbMiwxMzNdLDEwMzo4NCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA5Ojg1LDExMDpbMSw2N10sMTExOjY4LDEyNjpbMSw4M10sMTI5OlsxLDc2XSwxMzA6WzEsNzVdLDEzMzpbMSw3NF0sMTM0OlsxLDc3XSwxMzU6WzEsNzhdLDEzNjpbMSw3OV0sMTM3OlsxLDgwXSwxMzg6WzEsODFdLDEzOTpbMSw4Ml19LHs2OlsxLDI3Nl0sMjU6WzEsMjc3XSwyNjpbMSwzMzJdfSx7NzozMzMsODoxMTcsOToxOCwxMDoxOSwxMTpbMSwyMF0sMTI6NiwxMzo3LDE0OjgsMTU6OSwxNjoxMCwxNzoxMSwxODoxMiwxOToxMywyMDoxNCwyMToxNSwyMjoxNiwyMzoxNywyNzo2MSwyODpbMSw3Ml0sMjk6NDgsMzA6WzEsNzBdLDMxOlsxLDcxXSwzMjoyMiwzMzpbMSw0OV0sMzQ6WzEsNTBdLDM1OlsxLDUxXSwzNjpbMSw1Ml0sMzc6WzEsNTNdLDM4OlsxLDU0XSwzOToyMSw0NDo2Miw0NTpbMSw0NF0sNDY6WzEsNDVdLDQ3OlsxLDI3XSw1MDoyOCw1MTpbMSw1OV0sNTI6WzEsNjBdLDU4OjQ2LDU5OjQ3LDYxOjM1LDYzOjIzLDY0OjI0LDY1OjI1LDc2OlsxLDY5XSw3OTpbMSw0Ml0sODM6WzEsMjZdLDg4OlsxLDU3XSw4OTpbMSw1OF0sOTA6WzEsNTZdLDk2OlsxLDM3XSwxMDA6WzEsNDNdLDEwMTpbMSw1NV0sMTAzOjM4LDEwNDpbMSw2NF0sMTA2OlsxLDY1XSwxMDc6MzksMTA4OlsxLDY2XSwxMDk6NDAsMTEwOlsxLDY3XSwxMTE6NjgsMTE5OlsxLDQxXSwxMjQ6MzYsMTI1OlsxLDYzXSwxMjc6WzEsMjldLDEyODpbMSwzMF0sMTI5OlsxLDMxXSwxMzA6WzEsMzJdLDEzMTpbMSwzM10sMTMyOlsxLDM0XX0sezc6MzM0LDg6MTE3LDk6MTgsMTA6MTksMTE6WzEsMjBdLDEyOjYsMTM6NywxNDo4LDE1OjksMTY6MTAsMTc6MTEsMTg6MTIsMTk6MTMsMjA6MTQsMjE6MTUsMjI6MTYsMjM6MTcsMjc6NjEsMjg6WzEsNzJdLDI5OjQ4LDMwOlsxLDcwXSwzMTpbMSw3MV0sMzI6MjIsMzM6WzEsNDldLDM0OlsxLDUwXSwzNTpbMSw1MV0sMzY6WzEsNTJdLDM3OlsxLDUzXSwzODpbMSw1NF0sMzk6MjEsNDQ6NjIsNDU6WzEsNDRdLDQ2OlsxLDQ1XSw0NzpbMSwyN10sNTA6MjgsNTE6WzEsNTldLDUyOlsxLDYwXSw1ODo0Niw1OTo0Nyw2MTozNSw2MzoyMyw2NDoyNCw2NToyNSw3NjpbMSw2OV0sNzk6WzEsNDJdLDgzOlsxLDI2XSw4ODpbMSw1N10sODk6WzEsNThdLDkwOlsxLDU2XSw5NjpbMSwzN10sMTAwOlsxLDQzXSwxMDE6WzEsNTVdLDEwMzozOCwxMDQ6WzEsNjRdLDEwNjpbMSw2NV0sMTA3OjM5LDEwODpbMSw2Nl0sMTA5OjQwLDExMDpbMSw2N10sMTExOjY4LDExOTpbMSw0MV0sMTI0OjM2LDEyNTpbMSw2M10sMTI3OlsxLDI5XSwxMjg6WzEsMzBdLDEyOTpbMSwzMV0sMTMwOlsxLDMyXSwxMzE6WzEsMzNdLDEzMjpbMSwzNF19LHs2OlsxLDI4N10sMjU6WzEsMjg4XSwyNjpbMSwzMzVdfSx7NjpbMiw0MF0sMjU6WzIsNDBdLDI2OlsyLDQwXSw1NDpbMiw0MF0sNzg6WzIsNDBdfSx7NjpbMiw1OF0sMjU6WzIsNThdLDI2OlsyLDU4XSw0OTpbMiw1OF0sNTQ6WzIsNThdfSx7MTpbMiwxNzVdLDY6WzIsMTc1XSwyNTpbMiwxNzVdLDI2OlsyLDE3NV0sNDk6WzIsMTc1XSw1NDpbMiwxNzVdLDU3OlsyLDE3NV0sNzM6WzIsMTc1XSw3ODpbMiwxNzVdLDg2OlsyLDE3NV0sOTE6WzIsMTc1XSw5MzpbMiwxNzVdLDEwMjpbMiwxNzVdLDEwNDpbMiwxNzVdLDEwNTpbMiwxNzVdLDEwNjpbMiwxNzVdLDExMDpbMiwxNzVdLDExODpbMiwxNzVdLDEyNjpbMiwxNzVdLDEyOTpbMiwxNzVdLDEzMDpbMiwxNzVdLDEzMzpbMiwxNzVdLDEzNDpbMiwxNzVdLDEzNTpbMiwxNzVdLDEzNjpbMiwxNzVdLDEzNzpbMiwxNzVdLDEzODpbMiwxNzVdLDEzOTpbMiwxNzVdfSx7NjpbMiwxMjhdLDI1OlsyLDEyOF0sMjY6WzIsMTI4XSw1NDpbMiwxMjhdLDg2OlsyLDEyOF0sOTE6WzIsMTI4XX0sezE6WzIsMTcyXSw2OlsyLDE3Ml0sMjU6WzIsMTcyXSwyNjpbMiwxNzJdLDQ5OlsyLDE3Ml0sNTQ6WzIsMTcyXSw1NzpbMiwxNzJdLDczOlsyLDE3Ml0sNzg6WzIsMTcyXSw4NjpbMiwxNzJdLDkxOlsyLDE3Ml0sOTM6WzIsMTcyXSwxMDI6WzIsMTcyXSwxMDM6ODQsMTA0OlsyLDE3Ml0sMTA1OlsyLDE3Ml0sMTA2OlsyLDE3Ml0sMTA5Ojg1LDExMDpbMiwxNzJdLDExMTo2OCwxMTg6WzIsMTcyXSwxMjY6WzIsMTcyXSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMSw4MV0sMTM5OlsxLDgyXX0sezE6WzIsMTczXSw2OlsyLDE3M10sMjU6WzIsMTczXSwyNjpbMiwxNzNdLDQ5OlsyLDE3M10sNTQ6WzIsMTczXSw1NzpbMiwxNzNdLDczOlsyLDE3M10sNzg6WzIsMTczXSw4NjpbMiwxNzNdLDkxOlsyLDE3M10sOTM6WzIsMTczXSwxMDI6WzIsMTczXSwxMDM6ODQsMTA0OlsyLDE3M10sMTA1OlsyLDE3M10sMTA2OlsyLDE3M10sMTA5Ojg1LDExMDpbMiwxNzNdLDExMTo2OCwxMTg6WzIsMTczXSwxMjY6WzIsMTczXSwxMjk6WzEsNzZdLDEzMDpbMSw3NV0sMTMzOlsxLDc0XSwxMzQ6WzEsNzddLDEzNTpbMSw3OF0sMTM2OlsxLDc5XSwxMzc6WzEsODBdLDEzODpbMSw4MV0sMTM5OlsxLDgyXX0sezY6WzIsOTVdLDI1OlsyLDk1XSwyNjpbMiw5NV0sNTQ6WzIsOTVdLDc4OlsyLDk1XX1dLFxuZGVmYXVsdEFjdGlvbnM6IHs1OTpbMiw1MF0sNjA6WzIsNTFdLDkxOlsyLDEwOV0sMTkyOlsyLDg5XX0sXG5wYXJzZUVycm9yOiBmdW5jdGlvbiBwYXJzZUVycm9yKHN0ciwgaGFzaCkge1xuICAgIGlmIChoYXNoLnJlY292ZXJhYmxlKSB7XG4gICAgICAgIHRoaXMudHJhY2Uoc3RyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3Ioc3RyKTtcbiAgICB9XG59LFxucGFyc2U6IGZ1bmN0aW9uIHBhcnNlKGlucHV0KSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzLCBzdGFjayA9IFswXSwgdnN0YWNrID0gW251bGxdLCBsc3RhY2sgPSBbXSwgdGFibGUgPSB0aGlzLnRhYmxlLCB5eXRleHQgPSAnJywgeXlsaW5lbm8gPSAwLCB5eWxlbmcgPSAwLCByZWNvdmVyaW5nID0gMCwgVEVSUk9SID0gMiwgRU9GID0gMTtcbiAgICB2YXIgYXJncyA9IGxzdGFjay5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgdGhpcy5sZXhlci5zZXRJbnB1dChpbnB1dCk7XG4gICAgdGhpcy5sZXhlci55eSA9IHRoaXMueXk7XG4gICAgdGhpcy55eS5sZXhlciA9IHRoaXMubGV4ZXI7XG4gICAgdGhpcy55eS5wYXJzZXIgPSB0aGlzO1xuICAgIGlmICh0eXBlb2YgdGhpcy5sZXhlci55eWxsb2MgPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhpcy5sZXhlci55eWxsb2MgPSB7fTtcbiAgICB9XG4gICAgdmFyIHl5bG9jID0gdGhpcy5sZXhlci55eWxsb2M7XG4gICAgbHN0YWNrLnB1c2goeXlsb2MpO1xuICAgIHZhciByYW5nZXMgPSB0aGlzLmxleGVyLm9wdGlvbnMgJiYgdGhpcy5sZXhlci5vcHRpb25zLnJhbmdlcztcbiAgICBpZiAodHlwZW9mIHRoaXMueXkucGFyc2VFcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnBhcnNlRXJyb3IgPSB0aGlzLnl5LnBhcnNlRXJyb3I7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5wYXJzZUVycm9yID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpLnBhcnNlRXJyb3I7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHBvcFN0YWNrKG4pIHtcbiAgICAgICAgc3RhY2subGVuZ3RoID0gc3RhY2subGVuZ3RoIC0gMiAqIG47XG4gICAgICAgIHZzdGFjay5sZW5ndGggPSB2c3RhY2subGVuZ3RoIC0gbjtcbiAgICAgICAgbHN0YWNrLmxlbmd0aCA9IGxzdGFjay5sZW5ndGggLSBuO1xuICAgIH1cbiAgICBmdW5jdGlvbiBsZXgoKSB7XG4gICAgICAgIHZhciB0b2tlbjtcbiAgICAgICAgdG9rZW4gPSBzZWxmLmxleGVyLmxleCgpIHx8IEVPRjtcbiAgICAgICAgaWYgKHR5cGVvZiB0b2tlbiAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHRva2VuID0gc2VsZi5zeW1ib2xzX1t0b2tlbl0gfHwgdG9rZW47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH1cbiAgICB2YXIgc3ltYm9sLCBwcmVFcnJvclN5bWJvbCwgc3RhdGUsIGFjdGlvbiwgYSwgciwgeXl2YWwgPSB7fSwgcCwgbGVuLCBuZXdTdGF0ZSwgZXhwZWN0ZWQ7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgc3RhdGUgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKHRoaXMuZGVmYXVsdEFjdGlvbnNbc3RhdGVdKSB7XG4gICAgICAgICAgICBhY3Rpb24gPSB0aGlzLmRlZmF1bHRBY3Rpb25zW3N0YXRlXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChzeW1ib2wgPT09IG51bGwgfHwgdHlwZW9mIHN5bWJvbCA9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIHN5bWJvbCA9IGxleCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWN0aW9uID0gdGFibGVbc3RhdGVdICYmIHRhYmxlW3N0YXRlXVtzeW1ib2xdO1xuICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYWN0aW9uID09PSAndW5kZWZpbmVkJyB8fCAhYWN0aW9uLmxlbmd0aCB8fCAhYWN0aW9uWzBdKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVyclN0ciA9ICcnO1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChwIGluIHRhYmxlW3N0YXRlXSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50ZXJtaW5hbHNfW3BdICYmIHAgPiBURVJST1IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkLnB1c2goJ1xcJycgKyB0aGlzLnRlcm1pbmFsc19bcF0gKyAnXFwnJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubGV4ZXIuc2hvd1Bvc2l0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGVyclN0ciA9ICdQYXJzZSBlcnJvciBvbiBsaW5lICcgKyAoeXlsaW5lbm8gKyAxKSArICc6XFxuJyArIHRoaXMubGV4ZXIuc2hvd1Bvc2l0aW9uKCkgKyAnXFxuRXhwZWN0aW5nICcgKyBleHBlY3RlZC5qb2luKCcsICcpICsgJywgZ290IFxcJycgKyAodGhpcy50ZXJtaW5hbHNfW3N5bWJvbF0gfHwgc3ltYm9sKSArICdcXCcnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVyclN0ciA9ICdQYXJzZSBlcnJvciBvbiBsaW5lICcgKyAoeXlsaW5lbm8gKyAxKSArICc6IFVuZXhwZWN0ZWQgJyArIChzeW1ib2wgPT0gRU9GID8gJ2VuZCBvZiBpbnB1dCcgOiAnXFwnJyArICh0aGlzLnRlcm1pbmFsc19bc3ltYm9sXSB8fCBzeW1ib2wpICsgJ1xcJycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnBhcnNlRXJyb3IoZXJyU3RyLCB7XG4gICAgICAgICAgICAgICAgICAgIHRleHQ6IHRoaXMubGV4ZXIubWF0Y2gsXG4gICAgICAgICAgICAgICAgICAgIHRva2VuOiB0aGlzLnRlcm1pbmFsc19bc3ltYm9sXSB8fCBzeW1ib2wsXG4gICAgICAgICAgICAgICAgICAgIGxpbmU6IHRoaXMubGV4ZXIueXlsaW5lbm8sXG4gICAgICAgICAgICAgICAgICAgIGxvYzogeXlsb2MsXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICBpZiAoYWN0aW9uWzBdIGluc3RhbmNlb2YgQXJyYXkgJiYgYWN0aW9uLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGFyc2UgRXJyb3I6IG11bHRpcGxlIGFjdGlvbnMgcG9zc2libGUgYXQgc3RhdGU6ICcgKyBzdGF0ZSArICcsIHRva2VuOiAnICsgc3ltYm9sKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKGFjdGlvblswXSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICBzdGFjay5wdXNoKHN5bWJvbCk7XG4gICAgICAgICAgICB2c3RhY2sucHVzaCh0aGlzLmxleGVyLnl5dGV4dCk7XG4gICAgICAgICAgICBsc3RhY2sucHVzaCh0aGlzLmxleGVyLnl5bGxvYyk7XG4gICAgICAgICAgICBzdGFjay5wdXNoKGFjdGlvblsxXSk7XG4gICAgICAgICAgICBzeW1ib2wgPSBudWxsO1xuICAgICAgICAgICAgaWYgKCFwcmVFcnJvclN5bWJvbCkge1xuICAgICAgICAgICAgICAgIHl5bGVuZyA9IHRoaXMubGV4ZXIueXlsZW5nO1xuICAgICAgICAgICAgICAgIHl5dGV4dCA9IHRoaXMubGV4ZXIueXl0ZXh0O1xuICAgICAgICAgICAgICAgIHl5bGluZW5vID0gdGhpcy5sZXhlci55eWxpbmVubztcbiAgICAgICAgICAgICAgICB5eWxvYyA9IHRoaXMubGV4ZXIueXlsbG9jO1xuICAgICAgICAgICAgICAgIGlmIChyZWNvdmVyaW5nID4gMCkge1xuICAgICAgICAgICAgICAgICAgICByZWNvdmVyaW5nLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzeW1ib2wgPSBwcmVFcnJvclN5bWJvbDtcbiAgICAgICAgICAgICAgICBwcmVFcnJvclN5bWJvbCA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgbGVuID0gdGhpcy5wcm9kdWN0aW9uc19bYWN0aW9uWzFdXVsxXTtcbiAgICAgICAgICAgIHl5dmFsLiQgPSB2c3RhY2tbdnN0YWNrLmxlbmd0aCAtIGxlbl07XG4gICAgICAgICAgICB5eXZhbC5fJCA9IHtcbiAgICAgICAgICAgICAgICBmaXJzdF9saW5lOiBsc3RhY2tbbHN0YWNrLmxlbmd0aCAtIChsZW4gfHwgMSldLmZpcnN0X2xpbmUsXG4gICAgICAgICAgICAgICAgbGFzdF9saW5lOiBsc3RhY2tbbHN0YWNrLmxlbmd0aCAtIDFdLmxhc3RfbGluZSxcbiAgICAgICAgICAgICAgICBmaXJzdF9jb2x1bW46IGxzdGFja1tsc3RhY2subGVuZ3RoIC0gKGxlbiB8fCAxKV0uZmlyc3RfY29sdW1uLFxuICAgICAgICAgICAgICAgIGxhc3RfY29sdW1uOiBsc3RhY2tbbHN0YWNrLmxlbmd0aCAtIDFdLmxhc3RfY29sdW1uXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKHJhbmdlcykge1xuICAgICAgICAgICAgICAgIHl5dmFsLl8kLnJhbmdlID0gW1xuICAgICAgICAgICAgICAgICAgICBsc3RhY2tbbHN0YWNrLmxlbmd0aCAtIChsZW4gfHwgMSldLnJhbmdlWzBdLFxuICAgICAgICAgICAgICAgICAgICBsc3RhY2tbbHN0YWNrLmxlbmd0aCAtIDFdLnJhbmdlWzFdXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHIgPSB0aGlzLnBlcmZvcm1BY3Rpb24uYXBwbHkoeXl2YWwsIFtcbiAgICAgICAgICAgICAgICB5eXRleHQsXG4gICAgICAgICAgICAgICAgeXlsZW5nLFxuICAgICAgICAgICAgICAgIHl5bGluZW5vLFxuICAgICAgICAgICAgICAgIHRoaXMueXksXG4gICAgICAgICAgICAgICAgYWN0aW9uWzFdLFxuICAgICAgICAgICAgICAgIHZzdGFjayxcbiAgICAgICAgICAgICAgICBsc3RhY2tcbiAgICAgICAgICAgIF0uY29uY2F0KGFyZ3MpKTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChsZW4pIHtcbiAgICAgICAgICAgICAgICBzdGFjayA9IHN0YWNrLnNsaWNlKDAsIC0xICogbGVuICogMik7XG4gICAgICAgICAgICAgICAgdnN0YWNrID0gdnN0YWNrLnNsaWNlKDAsIC0xICogbGVuKTtcbiAgICAgICAgICAgICAgICBsc3RhY2sgPSBsc3RhY2suc2xpY2UoMCwgLTEgKiBsZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RhY2sucHVzaCh0aGlzLnByb2R1Y3Rpb25zX1thY3Rpb25bMV1dWzBdKTtcbiAgICAgICAgICAgIHZzdGFjay5wdXNoKHl5dmFsLiQpO1xuICAgICAgICAgICAgbHN0YWNrLnB1c2goeXl2YWwuXyQpO1xuICAgICAgICAgICAgbmV3U3RhdGUgPSB0YWJsZVtzdGFja1tzdGFjay5sZW5ndGggLSAyXV1bc3RhY2tbc3RhY2subGVuZ3RoIC0gMV1dO1xuICAgICAgICAgICAgc3RhY2sucHVzaChuZXdTdGF0ZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59fTtcblxuZnVuY3Rpb24gUGFyc2VyICgpIHtcbiAgdGhpcy55eSA9IHt9O1xufVxuUGFyc2VyLnByb3RvdHlwZSA9IHBhcnNlcjtwYXJzZXIuUGFyc2VyID0gUGFyc2VyO1xucmV0dXJuIG5ldyBQYXJzZXI7XG59KSgpO1xuXG5cbmlmICh0eXBlb2YgcmVxdWlyZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG5leHBvcnRzLnBhcnNlciA9IHBhcnNlcjtcbmV4cG9ydHMuUGFyc2VyID0gcGFyc2VyLlBhcnNlcjtcbmV4cG9ydHMucGFyc2UgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBwYXJzZXIucGFyc2UuYXBwbHkocGFyc2VyLCBhcmd1bWVudHMpOyB9O1xuZXhwb3J0cy5tYWluID0gZnVuY3Rpb24gY29tbW9uanNNYWluKGFyZ3MpIHtcbiAgICBpZiAoIWFyZ3NbMV0pIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1VzYWdlOiAnK2FyZ3NbMF0rJyBGSUxFJyk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG4gICAgdmFyIHNvdXJjZSA9IHJlcXVpcmUoJ2ZzJykucmVhZEZpbGVTeW5jKHJlcXVpcmUoJ3BhdGgnKS5ub3JtYWxpemUoYXJnc1sxXSksIFwidXRmOFwiKTtcbiAgICByZXR1cm4gZXhwb3J0cy5wYXJzZXIucGFyc2Uoc291cmNlKTtcbn07XG5pZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgcmVxdWlyZS5tYWluID09PSBtb2R1bGUpIHtcbiAgZXhwb3J0cy5tYWluKHByb2Nlc3MuYXJndi5zbGljZSgxKSk7XG59XG59XG59KS5jYWxsKHRoaXMscmVxdWlyZShcIjFZaVo1U1wiKSkiLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuOC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBDb2ZmZWVTY3JpcHQsIE1vZHVsZSwgYmluYXJ5LCBjaGlsZF9wcm9jZXNzLCBleHQsIGZpbmRFeHRlbnNpb24sIGZvcmssIGhlbHBlcnMsIGxvYWRGaWxlLCBwYXRoLCBfaSwgX2xlbiwgX3JlZjtcblxuICBDb2ZmZWVTY3JpcHQgPSByZXF1aXJlKCcuL2NvZmZlZS1zY3JpcHQnKTtcblxuICBjaGlsZF9wcm9jZXNzID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpO1xuXG4gIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcblxuICBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuXG4gIGxvYWRGaWxlID0gZnVuY3Rpb24obW9kdWxlLCBmaWxlbmFtZSkge1xuICAgIHZhciBhbnN3ZXI7XG4gICAgYW5zd2VyID0gQ29mZmVlU2NyaXB0Ll9jb21waWxlRmlsZShmaWxlbmFtZSwgZmFsc2UpO1xuICAgIHJldHVybiBtb2R1bGUuX2NvbXBpbGUoYW5zd2VyLCBmaWxlbmFtZSk7XG4gIH07XG5cbiAgaWYgKHJlcXVpcmUuZXh0ZW5zaW9ucykge1xuICAgIF9yZWYgPSBDb2ZmZWVTY3JpcHQuRklMRV9FWFRFTlNJT05TO1xuICAgIGZvciAoX2kgPSAwLCBfbGVuID0gX3JlZi5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgZXh0ID0gX3JlZltfaV07XG4gICAgICByZXF1aXJlLmV4dGVuc2lvbnNbZXh0XSA9IGxvYWRGaWxlO1xuICAgIH1cbiAgICBNb2R1bGUgPSByZXF1aXJlKCdtb2R1bGUnKTtcbiAgICBmaW5kRXh0ZW5zaW9uID0gZnVuY3Rpb24oZmlsZW5hbWUpIHtcbiAgICAgIHZhciBjdXJFeHRlbnNpb24sIGV4dGVuc2lvbnM7XG4gICAgICBleHRlbnNpb25zID0gcGF0aC5iYXNlbmFtZShmaWxlbmFtZSkuc3BsaXQoJy4nKTtcbiAgICAgIGlmIChleHRlbnNpb25zWzBdID09PSAnJykge1xuICAgICAgICBleHRlbnNpb25zLnNoaWZ0KCk7XG4gICAgICB9XG4gICAgICB3aGlsZSAoZXh0ZW5zaW9ucy5zaGlmdCgpKSB7XG4gICAgICAgIGN1ckV4dGVuc2lvbiA9ICcuJyArIGV4dGVuc2lvbnMuam9pbignLicpO1xuICAgICAgICBpZiAoTW9kdWxlLl9leHRlbnNpb25zW2N1ckV4dGVuc2lvbl0pIHtcbiAgICAgICAgICByZXR1cm4gY3VyRXh0ZW5zaW9uO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gJy5qcyc7XG4gICAgfTtcbiAgICBNb2R1bGUucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbihmaWxlbmFtZSkge1xuICAgICAgdmFyIGV4dGVuc2lvbjtcbiAgICAgIHRoaXMuZmlsZW5hbWUgPSBmaWxlbmFtZTtcbiAgICAgIHRoaXMucGF0aHMgPSBNb2R1bGUuX25vZGVNb2R1bGVQYXRocyhwYXRoLmRpcm5hbWUoZmlsZW5hbWUpKTtcbiAgICAgIGV4dGVuc2lvbiA9IGZpbmRFeHRlbnNpb24oZmlsZW5hbWUpO1xuICAgICAgTW9kdWxlLl9leHRlbnNpb25zW2V4dGVuc2lvbl0odGhpcywgZmlsZW5hbWUpO1xuICAgICAgcmV0dXJuIHRoaXMubG9hZGVkID0gdHJ1ZTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKGNoaWxkX3Byb2Nlc3MpIHtcbiAgICBmb3JrID0gY2hpbGRfcHJvY2Vzcy5mb3JrO1xuICAgIGJpbmFyeSA9IHJlcXVpcmUucmVzb2x2ZSgnLi4vLi4vYmluL2NvZmZlZScpO1xuICAgIGNoaWxkX3Byb2Nlc3MuZm9yayA9IGZ1bmN0aW9uKHBhdGgsIGFyZ3MsIG9wdGlvbnMpIHtcbiAgICAgIGlmIChoZWxwZXJzLmlzQ29mZmVlKHBhdGgpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcmdzKSkge1xuICAgICAgICAgIG9wdGlvbnMgPSBhcmdzIHx8IHt9O1xuICAgICAgICAgIGFyZ3MgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBhcmdzID0gW3BhdGhdLmNvbmNhdChhcmdzKTtcbiAgICAgICAgcGF0aCA9IGJpbmFyeTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmb3JrKHBhdGgsIGFyZ3MsIG9wdGlvbnMpO1xuICAgIH07XG4gIH1cblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS44LjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJBTEFOQ0VEX1BBSVJTLCBDQUxMX0NMT1NFUlMsIEVYUFJFU1NJT05fQ0xPU0UsIEVYUFJFU1NJT05fRU5ELCBFWFBSRVNTSU9OX1NUQVJULCBJTVBMSUNJVF9DQUxMLCBJTVBMSUNJVF9FTkQsIElNUExJQ0lUX0ZVTkMsIElNUExJQ0lUX1VOU1BBQ0VEX0NBTEwsIElOVkVSU0VTLCBMSU5FQlJFQUtTLCBTSU5HTEVfQ0xPU0VSUywgU0lOR0xFX0xJTkVSUywgZ2VuZXJhdGUsIGxlZnQsIHJpdGUsIF9pLCBfbGVuLCBfcmVmLFxuICAgIF9faW5kZXhPZiA9IFtdLmluZGV4T2YgfHwgZnVuY3Rpb24oaXRlbSkgeyBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7IGlmIChpIGluIHRoaXMgJiYgdGhpc1tpXSA9PT0gaXRlbSkgcmV0dXJuIGk7IH0gcmV0dXJuIC0xOyB9LFxuICAgIF9fc2xpY2UgPSBbXS5zbGljZTtcblxuICBnZW5lcmF0ZSA9IGZ1bmN0aW9uKHRhZywgdmFsdWUsIG9yaWdpbikge1xuICAgIHZhciB0b2s7XG4gICAgdG9rID0gW3RhZywgdmFsdWVdO1xuICAgIHRvay5nZW5lcmF0ZWQgPSB0cnVlO1xuICAgIGlmIChvcmlnaW4pIHtcbiAgICAgIHRvay5vcmlnaW4gPSBvcmlnaW47XG4gICAgfVxuICAgIHJldHVybiB0b2s7XG4gIH07XG5cbiAgZXhwb3J0cy5SZXdyaXRlciA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBSZXdyaXRlcigpIHt9XG5cbiAgICBSZXdyaXRlci5wcm90b3R5cGUucmV3cml0ZSA9IGZ1bmN0aW9uKHRva2Vucykge1xuICAgICAgdGhpcy50b2tlbnMgPSB0b2tlbnM7XG4gICAgICB0aGlzLnJlbW92ZUxlYWRpbmdOZXdsaW5lcygpO1xuICAgICAgdGhpcy5jbG9zZU9wZW5DYWxscygpO1xuICAgICAgdGhpcy5jbG9zZU9wZW5JbmRleGVzKCk7XG4gICAgICB0aGlzLm5vcm1hbGl6ZUxpbmVzKCk7XG4gICAgICB0aGlzLnRhZ1Bvc3RmaXhDb25kaXRpb25hbHMoKTtcbiAgICAgIHRoaXMuYWRkSW1wbGljaXRCcmFjZXNBbmRQYXJlbnMoKTtcbiAgICAgIHRoaXMuYWRkTG9jYXRpb25EYXRhVG9HZW5lcmF0ZWRUb2tlbnMoKTtcbiAgICAgIHJldHVybiB0aGlzLnRva2VucztcbiAgICB9O1xuXG4gICAgUmV3cml0ZXIucHJvdG90eXBlLnNjYW5Ub2tlbnMgPSBmdW5jdGlvbihibG9jaykge1xuICAgICAgdmFyIGksIHRva2VuLCB0b2tlbnM7XG4gICAgICB0b2tlbnMgPSB0aGlzLnRva2VucztcbiAgICAgIGkgPSAwO1xuICAgICAgd2hpbGUgKHRva2VuID0gdG9rZW5zW2ldKSB7XG4gICAgICAgIGkgKz0gYmxvY2suY2FsbCh0aGlzLCB0b2tlbiwgaSwgdG9rZW5zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG5cbiAgICBSZXdyaXRlci5wcm90b3R5cGUuZGV0ZWN0RW5kID0gZnVuY3Rpb24oaSwgY29uZGl0aW9uLCBhY3Rpb24pIHtcbiAgICAgIHZhciBsZXZlbHMsIHRva2VuLCB0b2tlbnMsIF9yZWYsIF9yZWYxO1xuICAgICAgdG9rZW5zID0gdGhpcy50b2tlbnM7XG4gICAgICBsZXZlbHMgPSAwO1xuICAgICAgd2hpbGUgKHRva2VuID0gdG9rZW5zW2ldKSB7XG4gICAgICAgIGlmIChsZXZlbHMgPT09IDAgJiYgY29uZGl0aW9uLmNhbGwodGhpcywgdG9rZW4sIGkpKSB7XG4gICAgICAgICAgcmV0dXJuIGFjdGlvbi5jYWxsKHRoaXMsIHRva2VuLCBpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRva2VuIHx8IGxldmVscyA8IDApIHtcbiAgICAgICAgICByZXR1cm4gYWN0aW9uLmNhbGwodGhpcywgdG9rZW4sIGkgLSAxKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoX3JlZiA9IHRva2VuWzBdLCBfX2luZGV4T2YuY2FsbChFWFBSRVNTSU9OX1NUQVJULCBfcmVmKSA+PSAwKSB7XG4gICAgICAgICAgbGV2ZWxzICs9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAoX3JlZjEgPSB0b2tlblswXSwgX19pbmRleE9mLmNhbGwoRVhQUkVTU0lPTl9FTkQsIF9yZWYxKSA+PSAwKSB7XG4gICAgICAgICAgbGV2ZWxzIC09IDE7XG4gICAgICAgIH1cbiAgICAgICAgaSArPSAxO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGkgLSAxO1xuICAgIH07XG5cbiAgICBSZXdyaXRlci5wcm90b3R5cGUucmVtb3ZlTGVhZGluZ05ld2xpbmVzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaSwgdGFnLCBfaSwgX2xlbiwgX3JlZjtcbiAgICAgIF9yZWYgPSB0aGlzLnRva2VucztcbiAgICAgIGZvciAoaSA9IF9pID0gMCwgX2xlbiA9IF9yZWYubGVuZ3RoOyBfaSA8IF9sZW47IGkgPSArK19pKSB7XG4gICAgICAgIHRhZyA9IF9yZWZbaV1bMF07XG4gICAgICAgIGlmICh0YWcgIT09ICdURVJNSU5BVE9SJykge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaSkge1xuICAgICAgICByZXR1cm4gdGhpcy50b2tlbnMuc3BsaWNlKDAsIGkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBSZXdyaXRlci5wcm90b3R5cGUuY2xvc2VPcGVuQ2FsbHMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhY3Rpb24sIGNvbmRpdGlvbjtcbiAgICAgIGNvbmRpdGlvbiA9IGZ1bmN0aW9uKHRva2VuLCBpKSB7XG4gICAgICAgIHZhciBfcmVmO1xuICAgICAgICByZXR1cm4gKChfcmVmID0gdG9rZW5bMF0pID09PSAnKScgfHwgX3JlZiA9PT0gJ0NBTExfRU5EJykgfHwgdG9rZW5bMF0gPT09ICdPVVRERU5UJyAmJiB0aGlzLnRhZyhpIC0gMSkgPT09ICcpJztcbiAgICAgIH07XG4gICAgICBhY3Rpb24gPSBmdW5jdGlvbih0b2tlbiwgaSkge1xuICAgICAgICByZXR1cm4gdGhpcy50b2tlbnNbdG9rZW5bMF0gPT09ICdPVVRERU5UJyA/IGkgLSAxIDogaV1bMF0gPSAnQ0FMTF9FTkQnO1xuICAgICAgfTtcbiAgICAgIHJldHVybiB0aGlzLnNjYW5Ub2tlbnMoZnVuY3Rpb24odG9rZW4sIGkpIHtcbiAgICAgICAgaWYgKHRva2VuWzBdID09PSAnQ0FMTF9TVEFSVCcpIHtcbiAgICAgICAgICB0aGlzLmRldGVjdEVuZChpICsgMSwgY29uZGl0aW9uLCBhY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAxO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIFJld3JpdGVyLnByb3RvdHlwZS5jbG9zZU9wZW5JbmRleGVzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYWN0aW9uLCBjb25kaXRpb247XG4gICAgICBjb25kaXRpb24gPSBmdW5jdGlvbih0b2tlbiwgaSkge1xuICAgICAgICB2YXIgX3JlZjtcbiAgICAgICAgcmV0dXJuIChfcmVmID0gdG9rZW5bMF0pID09PSAnXScgfHwgX3JlZiA9PT0gJ0lOREVYX0VORCc7XG4gICAgICB9O1xuICAgICAgYWN0aW9uID0gZnVuY3Rpb24odG9rZW4sIGkpIHtcbiAgICAgICAgcmV0dXJuIHRva2VuWzBdID0gJ0lOREVYX0VORCc7XG4gICAgICB9O1xuICAgICAgcmV0dXJuIHRoaXMuc2NhblRva2VucyhmdW5jdGlvbih0b2tlbiwgaSkge1xuICAgICAgICBpZiAodG9rZW5bMF0gPT09ICdJTkRFWF9TVEFSVCcpIHtcbiAgICAgICAgICB0aGlzLmRldGVjdEVuZChpICsgMSwgY29uZGl0aW9uLCBhY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAxO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIFJld3JpdGVyLnByb3RvdHlwZS5tYXRjaFRhZ3MgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBmdXp6LCBpLCBqLCBwYXR0ZXJuLCBfaSwgX3JlZiwgX3JlZjE7XG4gICAgICBpID0gYXJndW1lbnRzWzBdLCBwYXR0ZXJuID0gMiA8PSBhcmd1bWVudHMubGVuZ3RoID8gX19zbGljZS5jYWxsKGFyZ3VtZW50cywgMSkgOiBbXTtcbiAgICAgIGZ1enogPSAwO1xuICAgICAgZm9yIChqID0gX2kgPSAwLCBfcmVmID0gcGF0dGVybi5sZW5ndGg7IDAgPD0gX3JlZiA/IF9pIDwgX3JlZiA6IF9pID4gX3JlZjsgaiA9IDAgPD0gX3JlZiA/ICsrX2kgOiAtLV9pKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLnRhZyhpICsgaiArIGZ1enopID09PSAnSEVSRUNPTU1FTlQnKSB7XG4gICAgICAgICAgZnV6eiArPSAyO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXR0ZXJuW2pdID09IG51bGwpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhdHRlcm5bal0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgcGF0dGVybltqXSA9IFtwYXR0ZXJuW2pdXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoX3JlZjEgPSB0aGlzLnRhZyhpICsgaiArIGZ1enopLCBfX2luZGV4T2YuY2FsbChwYXR0ZXJuW2pdLCBfcmVmMSkgPCAwKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgUmV3cml0ZXIucHJvdG90eXBlLmxvb2tzT2JqZWN0aXNoID0gZnVuY3Rpb24oaikge1xuICAgICAgcmV0dXJuIHRoaXMubWF0Y2hUYWdzKGosICdAJywgbnVsbCwgJzonKSB8fCB0aGlzLm1hdGNoVGFncyhqLCBudWxsLCAnOicpO1xuICAgIH07XG5cbiAgICBSZXdyaXRlci5wcm90b3R5cGUuZmluZFRhZ3NCYWNrd2FyZHMgPSBmdW5jdGlvbihpLCB0YWdzKSB7XG4gICAgICB2YXIgYmFja1N0YWNrLCBfcmVmLCBfcmVmMSwgX3JlZjIsIF9yZWYzLCBfcmVmNCwgX3JlZjU7XG4gICAgICBiYWNrU3RhY2sgPSBbXTtcbiAgICAgIHdoaWxlIChpID49IDAgJiYgKGJhY2tTdGFjay5sZW5ndGggfHwgKF9yZWYyID0gdGhpcy50YWcoaSksIF9faW5kZXhPZi5jYWxsKHRhZ3MsIF9yZWYyKSA8IDApICYmICgoX3JlZjMgPSB0aGlzLnRhZyhpKSwgX19pbmRleE9mLmNhbGwoRVhQUkVTU0lPTl9TVEFSVCwgX3JlZjMpIDwgMCkgfHwgdGhpcy50b2tlbnNbaV0uZ2VuZXJhdGVkKSAmJiAoX3JlZjQgPSB0aGlzLnRhZyhpKSwgX19pbmRleE9mLmNhbGwoTElORUJSRUFLUywgX3JlZjQpIDwgMCkpKSB7XG4gICAgICAgIGlmIChfcmVmID0gdGhpcy50YWcoaSksIF9faW5kZXhPZi5jYWxsKEVYUFJFU1NJT05fRU5ELCBfcmVmKSA+PSAwKSB7XG4gICAgICAgICAgYmFja1N0YWNrLnB1c2godGhpcy50YWcoaSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoX3JlZjEgPSB0aGlzLnRhZyhpKSwgX19pbmRleE9mLmNhbGwoRVhQUkVTU0lPTl9TVEFSVCwgX3JlZjEpID49IDApICYmIGJhY2tTdGFjay5sZW5ndGgpIHtcbiAgICAgICAgICBiYWNrU3RhY2sucG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgaSAtPSAxO1xuICAgICAgfVxuICAgICAgcmV0dXJuIF9yZWY1ID0gdGhpcy50YWcoaSksIF9faW5kZXhPZi5jYWxsKHRhZ3MsIF9yZWY1KSA+PSAwO1xuICAgIH07XG5cbiAgICBSZXdyaXRlci5wcm90b3R5cGUuYWRkSW1wbGljaXRCcmFjZXNBbmRQYXJlbnMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBzdGFjaztcbiAgICAgIHN0YWNrID0gW107XG4gICAgICByZXR1cm4gdGhpcy5zY2FuVG9rZW5zKGZ1bmN0aW9uKHRva2VuLCBpLCB0b2tlbnMpIHtcbiAgICAgICAgdmFyIGVuZEltcGxpY2l0Q2FsbCwgZW5kSW1wbGljaXRPYmplY3QsIGZvcndhcmQsIGluSW1wbGljaXQsIGluSW1wbGljaXRDYWxsLCBpbkltcGxpY2l0Q29udHJvbCwgaW5JbXBsaWNpdE9iamVjdCwgbmV3TGluZSwgbmV4dFRhZywgb2Zmc2V0LCBwcmV2VGFnLCBwcmV2VG9rZW4sIHMsIHNhbWVMaW5lLCBzdGFja0lkeCwgc3RhY2tUYWcsIHN0YWNrVG9wLCBzdGFydElkeCwgc3RhcnRJbXBsaWNpdENhbGwsIHN0YXJ0SW1wbGljaXRPYmplY3QsIHN0YXJ0c0xpbmUsIHRhZywgX3JlZiwgX3JlZjEsIF9yZWYyLCBfcmVmMywgX3JlZjQsIF9yZWY1O1xuICAgICAgICB0YWcgPSB0b2tlblswXTtcbiAgICAgICAgcHJldlRhZyA9IChwcmV2VG9rZW4gPSBpID4gMCA/IHRva2Vuc1tpIC0gMV0gOiBbXSlbMF07XG4gICAgICAgIG5leHRUYWcgPSAoaSA8IHRva2Vucy5sZW5ndGggLSAxID8gdG9rZW5zW2kgKyAxXSA6IFtdKVswXTtcbiAgICAgICAgc3RhY2tUb3AgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV07XG4gICAgICAgIH07XG4gICAgICAgIHN0YXJ0SWR4ID0gaTtcbiAgICAgICAgZm9yd2FyZCA9IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgICByZXR1cm4gaSAtIHN0YXJ0SWR4ICsgbjtcbiAgICAgICAgfTtcbiAgICAgICAgaW5JbXBsaWNpdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciBfcmVmLCBfcmVmMTtcbiAgICAgICAgICByZXR1cm4gKF9yZWYgPSBzdGFja1RvcCgpKSAhPSBudWxsID8gKF9yZWYxID0gX3JlZlsyXSkgIT0gbnVsbCA/IF9yZWYxLm91cnMgOiB2b2lkIDAgOiB2b2lkIDA7XG4gICAgICAgIH07XG4gICAgICAgIGluSW1wbGljaXRDYWxsID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdmFyIF9yZWY7XG4gICAgICAgICAgcmV0dXJuIGluSW1wbGljaXQoKSAmJiAoKF9yZWYgPSBzdGFja1RvcCgpKSAhPSBudWxsID8gX3JlZlswXSA6IHZvaWQgMCkgPT09ICcoJztcbiAgICAgICAgfTtcbiAgICAgICAgaW5JbXBsaWNpdE9iamVjdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciBfcmVmO1xuICAgICAgICAgIHJldHVybiBpbkltcGxpY2l0KCkgJiYgKChfcmVmID0gc3RhY2tUb3AoKSkgIT0gbnVsbCA/IF9yZWZbMF0gOiB2b2lkIDApID09PSAneyc7XG4gICAgICAgIH07XG4gICAgICAgIGluSW1wbGljaXRDb250cm9sID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdmFyIF9yZWY7XG4gICAgICAgICAgcmV0dXJuIGluSW1wbGljaXQgJiYgKChfcmVmID0gc3RhY2tUb3AoKSkgIT0gbnVsbCA/IF9yZWZbMF0gOiB2b2lkIDApID09PSAnQ09OVFJPTCc7XG4gICAgICAgIH07XG4gICAgICAgIHN0YXJ0SW1wbGljaXRDYWxsID0gZnVuY3Rpb24oaikge1xuICAgICAgICAgIHZhciBpZHg7XG4gICAgICAgICAgaWR4ID0gaiAhPSBudWxsID8gaiA6IGk7XG4gICAgICAgICAgc3RhY2sucHVzaChbXG4gICAgICAgICAgICAnKCcsIGlkeCwge1xuICAgICAgICAgICAgICBvdXJzOiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXSk7XG4gICAgICAgICAgdG9rZW5zLnNwbGljZShpZHgsIDAsIGdlbmVyYXRlKCdDQUxMX1NUQVJUJywgJygnKSk7XG4gICAgICAgICAgaWYgKGogPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGkgKz0gMTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGVuZEltcGxpY2l0Q2FsbCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgIHRva2Vucy5zcGxpY2UoaSwgMCwgZ2VuZXJhdGUoJ0NBTExfRU5EJywgJyknKSk7XG4gICAgICAgICAgcmV0dXJuIGkgKz0gMTtcbiAgICAgICAgfTtcbiAgICAgICAgc3RhcnRJbXBsaWNpdE9iamVjdCA9IGZ1bmN0aW9uKGosIHN0YXJ0c0xpbmUpIHtcbiAgICAgICAgICB2YXIgaWR4O1xuICAgICAgICAgIGlmIChzdGFydHNMaW5lID09IG51bGwpIHtcbiAgICAgICAgICAgIHN0YXJ0c0xpbmUgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZHggPSBqICE9IG51bGwgPyBqIDogaTtcbiAgICAgICAgICBzdGFjay5wdXNoKFtcbiAgICAgICAgICAgICd7JywgaWR4LCB7XG4gICAgICAgICAgICAgIHNhbWVMaW5lOiB0cnVlLFxuICAgICAgICAgICAgICBzdGFydHNMaW5lOiBzdGFydHNMaW5lLFxuICAgICAgICAgICAgICBvdXJzOiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXSk7XG4gICAgICAgICAgdG9rZW5zLnNwbGljZShpZHgsIDAsIGdlbmVyYXRlKCd7JywgZ2VuZXJhdGUobmV3IFN0cmluZygneycpKSwgdG9rZW4pKTtcbiAgICAgICAgICBpZiAoaiA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gaSArPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgZW5kSW1wbGljaXRPYmplY3QgPSBmdW5jdGlvbihqKSB7XG4gICAgICAgICAgaiA9IGogIT0gbnVsbCA/IGogOiBpO1xuICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgIHRva2Vucy5zcGxpY2UoaiwgMCwgZ2VuZXJhdGUoJ30nLCAnfScsIHRva2VuKSk7XG4gICAgICAgICAgcmV0dXJuIGkgKz0gMTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGluSW1wbGljaXRDYWxsKCkgJiYgKHRhZyA9PT0gJ0lGJyB8fCB0YWcgPT09ICdUUlknIHx8IHRhZyA9PT0gJ0ZJTkFMTFknIHx8IHRhZyA9PT0gJ0NBVENIJyB8fCB0YWcgPT09ICdDTEFTUycgfHwgdGFnID09PSAnU1dJVENIJykpIHtcbiAgICAgICAgICBzdGFjay5wdXNoKFtcbiAgICAgICAgICAgICdDT05UUk9MJywgaSwge1xuICAgICAgICAgICAgICBvdXJzOiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXSk7XG4gICAgICAgICAgcmV0dXJuIGZvcndhcmQoMSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhZyA9PT0gJ0lOREVOVCcgJiYgaW5JbXBsaWNpdCgpKSB7XG4gICAgICAgICAgaWYgKHByZXZUYWcgIT09ICc9PicgJiYgcHJldlRhZyAhPT0gJy0+JyAmJiBwcmV2VGFnICE9PSAnWycgJiYgcHJldlRhZyAhPT0gJygnICYmIHByZXZUYWcgIT09ICcsJyAmJiBwcmV2VGFnICE9PSAneycgJiYgcHJldlRhZyAhPT0gJ1RSWScgJiYgcHJldlRhZyAhPT0gJ0VMU0UnICYmIHByZXZUYWcgIT09ICc9Jykge1xuICAgICAgICAgICAgd2hpbGUgKGluSW1wbGljaXRDYWxsKCkpIHtcbiAgICAgICAgICAgICAgZW5kSW1wbGljaXRDYWxsKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChpbkltcGxpY2l0Q29udHJvbCgpKSB7XG4gICAgICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc3RhY2sucHVzaChbdGFnLCBpXSk7XG4gICAgICAgICAgcmV0dXJuIGZvcndhcmQoMSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKF9faW5kZXhPZi5jYWxsKEVYUFJFU1NJT05fU1RBUlQsIHRhZykgPj0gMCkge1xuICAgICAgICAgIHN0YWNrLnB1c2goW3RhZywgaV0pO1xuICAgICAgICAgIHJldHVybiBmb3J3YXJkKDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChfX2luZGV4T2YuY2FsbChFWFBSRVNTSU9OX0VORCwgdGFnKSA+PSAwKSB7XG4gICAgICAgICAgd2hpbGUgKGluSW1wbGljaXQoKSkge1xuICAgICAgICAgICAgaWYgKGluSW1wbGljaXRDYWxsKCkpIHtcbiAgICAgICAgICAgICAgZW5kSW1wbGljaXRDYWxsKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGluSW1wbGljaXRPYmplY3QoKSkge1xuICAgICAgICAgICAgICBlbmRJbXBsaWNpdE9iamVjdCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoX19pbmRleE9mLmNhbGwoSU1QTElDSVRfRlVOQywgdGFnKSA+PSAwICYmIHRva2VuLnNwYWNlZCAmJiAhdG9rZW4uc3RyaW5nRW5kIHx8IHRhZyA9PT0gJz8nICYmIGkgPiAwICYmICF0b2tlbnNbaSAtIDFdLnNwYWNlZCkgJiYgKF9faW5kZXhPZi5jYWxsKElNUExJQ0lUX0NBTEwsIG5leHRUYWcpID49IDAgfHwgX19pbmRleE9mLmNhbGwoSU1QTElDSVRfVU5TUEFDRURfQ0FMTCwgbmV4dFRhZykgPj0gMCAmJiAhKChfcmVmID0gdG9rZW5zW2kgKyAxXSkgIT0gbnVsbCA/IF9yZWYuc3BhY2VkIDogdm9pZCAwKSAmJiAhKChfcmVmMSA9IHRva2Vuc1tpICsgMV0pICE9IG51bGwgPyBfcmVmMS5uZXdMaW5lIDogdm9pZCAwKSkpIHtcbiAgICAgICAgICBpZiAodGFnID09PSAnPycpIHtcbiAgICAgICAgICAgIHRhZyA9IHRva2VuWzBdID0gJ0ZVTkNfRVhJU1QnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzdGFydEltcGxpY2l0Q2FsbChpICsgMSk7XG4gICAgICAgICAgcmV0dXJuIGZvcndhcmQoMik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKF9faW5kZXhPZi5jYWxsKElNUExJQ0lUX0ZVTkMsIHRhZykgPj0gMCAmJiB0aGlzLm1hdGNoVGFncyhpICsgMSwgJ0lOREVOVCcsIG51bGwsICc6JykgJiYgIXRoaXMuZmluZFRhZ3NCYWNrd2FyZHMoaSwgWydDTEFTUycsICdFWFRFTkRTJywgJ0lGJywgJ0NBVENIJywgJ1NXSVRDSCcsICdMRUFESU5HX1dIRU4nLCAnRk9SJywgJ1dISUxFJywgJ1VOVElMJ10pKSB7XG4gICAgICAgICAgc3RhcnRJbXBsaWNpdENhbGwoaSArIDEpO1xuICAgICAgICAgIHN0YWNrLnB1c2goWydJTkRFTlQnLCBpICsgMl0pO1xuICAgICAgICAgIHJldHVybiBmb3J3YXJkKDMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0YWcgPT09ICc6Jykge1xuICAgICAgICAgIGlmICh0aGlzLnRhZyhpIC0gMikgPT09ICdAJykge1xuICAgICAgICAgICAgcyA9IGkgLSAyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzID0gaSAtIDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIHdoaWxlICh0aGlzLnRhZyhzIC0gMikgPT09ICdIRVJFQ09NTUVOVCcpIHtcbiAgICAgICAgICAgIHMgLT0gMjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5pbnNpZGVGb3JEZWNsYXJhdGlvbiA9IG5leHRUYWcgPT09ICdGT1InO1xuICAgICAgICAgIHN0YXJ0c0xpbmUgPSBzID09PSAwIHx8IChfcmVmMiA9IHRoaXMudGFnKHMgLSAxKSwgX19pbmRleE9mLmNhbGwoTElORUJSRUFLUywgX3JlZjIpID49IDApIHx8IHRva2Vuc1tzIC0gMV0ubmV3TGluZTtcbiAgICAgICAgICBpZiAoc3RhY2tUb3AoKSkge1xuICAgICAgICAgICAgX3JlZjMgPSBzdGFja1RvcCgpLCBzdGFja1RhZyA9IF9yZWYzWzBdLCBzdGFja0lkeCA9IF9yZWYzWzFdO1xuICAgICAgICAgICAgaWYgKChzdGFja1RhZyA9PT0gJ3snIHx8IHN0YWNrVGFnID09PSAnSU5ERU5UJyAmJiB0aGlzLnRhZyhzdGFja0lkeCAtIDEpID09PSAneycpICYmIChzdGFydHNMaW5lIHx8IHRoaXMudGFnKHMgLSAxKSA9PT0gJywnIHx8IHRoaXMudGFnKHMgLSAxKSA9PT0gJ3snKSkge1xuICAgICAgICAgICAgICByZXR1cm4gZm9yd2FyZCgxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgc3RhcnRJbXBsaWNpdE9iamVjdChzLCAhIXN0YXJ0c0xpbmUpO1xuICAgICAgICAgIHJldHVybiBmb3J3YXJkKDIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbkltcGxpY2l0T2JqZWN0KCkgJiYgX19pbmRleE9mLmNhbGwoTElORUJSRUFLUywgdGFnKSA+PSAwKSB7XG4gICAgICAgICAgc3RhY2tUb3AoKVsyXS5zYW1lTGluZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIG5ld0xpbmUgPSBwcmV2VGFnID09PSAnT1VUREVOVCcgfHwgcHJldlRva2VuLm5ld0xpbmU7XG4gICAgICAgIGlmIChfX2luZGV4T2YuY2FsbChJTVBMSUNJVF9FTkQsIHRhZykgPj0gMCB8fCBfX2luZGV4T2YuY2FsbChDQUxMX0NMT1NFUlMsIHRhZykgPj0gMCAmJiBuZXdMaW5lKSB7XG4gICAgICAgICAgd2hpbGUgKGluSW1wbGljaXQoKSkge1xuICAgICAgICAgICAgX3JlZjQgPSBzdGFja1RvcCgpLCBzdGFja1RhZyA9IF9yZWY0WzBdLCBzdGFja0lkeCA9IF9yZWY0WzFdLCAoX3JlZjUgPSBfcmVmNFsyXSwgc2FtZUxpbmUgPSBfcmVmNS5zYW1lTGluZSwgc3RhcnRzTGluZSA9IF9yZWY1LnN0YXJ0c0xpbmUpO1xuICAgICAgICAgICAgaWYgKGluSW1wbGljaXRDYWxsKCkgJiYgcHJldlRhZyAhPT0gJywnKSB7XG4gICAgICAgICAgICAgIGVuZEltcGxpY2l0Q2FsbCgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpbkltcGxpY2l0T2JqZWN0KCkgJiYgIXRoaXMuaW5zaWRlRm9yRGVjbGFyYXRpb24gJiYgc2FtZUxpbmUgJiYgdGFnICE9PSAnVEVSTUlOQVRPUicgJiYgcHJldlRhZyAhPT0gJzonICYmIGVuZEltcGxpY2l0T2JqZWN0KCkpIHtcblxuICAgICAgICAgICAgfSBlbHNlIGlmIChpbkltcGxpY2l0T2JqZWN0KCkgJiYgdGFnID09PSAnVEVSTUlOQVRPUicgJiYgcHJldlRhZyAhPT0gJywnICYmICEoc3RhcnRzTGluZSAmJiB0aGlzLmxvb2tzT2JqZWN0aXNoKGkgKyAxKSkpIHtcbiAgICAgICAgICAgICAgZW5kSW1wbGljaXRPYmplY3QoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGFnID09PSAnLCcgJiYgIXRoaXMubG9va3NPYmplY3Rpc2goaSArIDEpICYmIGluSW1wbGljaXRPYmplY3QoKSAmJiAhdGhpcy5pbnNpZGVGb3JEZWNsYXJhdGlvbiAmJiAobmV4dFRhZyAhPT0gJ1RFUk1JTkFUT1InIHx8ICF0aGlzLmxvb2tzT2JqZWN0aXNoKGkgKyAyKSkpIHtcbiAgICAgICAgICBvZmZzZXQgPSBuZXh0VGFnID09PSAnT1VUREVOVCcgPyAxIDogMDtcbiAgICAgICAgICB3aGlsZSAoaW5JbXBsaWNpdE9iamVjdCgpKSB7XG4gICAgICAgICAgICBlbmRJbXBsaWNpdE9iamVjdChpICsgb2Zmc2V0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcndhcmQoMSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgUmV3cml0ZXIucHJvdG90eXBlLmFkZExvY2F0aW9uRGF0YVRvR2VuZXJhdGVkVG9rZW5zID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5zY2FuVG9rZW5zKGZ1bmN0aW9uKHRva2VuLCBpLCB0b2tlbnMpIHtcbiAgICAgICAgdmFyIGNvbHVtbiwgbGluZSwgbmV4dExvY2F0aW9uLCBwcmV2TG9jYXRpb24sIF9yZWYsIF9yZWYxO1xuICAgICAgICBpZiAodG9rZW5bMl0pIHtcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISh0b2tlbi5nZW5lcmF0ZWQgfHwgdG9rZW4uZXhwbGljaXQpKSB7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRva2VuWzBdID09PSAneycgJiYgKG5leHRMb2NhdGlvbiA9IChfcmVmID0gdG9rZW5zW2kgKyAxXSkgIT0gbnVsbCA/IF9yZWZbMl0gOiB2b2lkIDApKSB7XG4gICAgICAgICAgbGluZSA9IG5leHRMb2NhdGlvbi5maXJzdF9saW5lLCBjb2x1bW4gPSBuZXh0TG9jYXRpb24uZmlyc3RfY29sdW1uO1xuICAgICAgICB9IGVsc2UgaWYgKHByZXZMb2NhdGlvbiA9IChfcmVmMSA9IHRva2Vuc1tpIC0gMV0pICE9IG51bGwgPyBfcmVmMVsyXSA6IHZvaWQgMCkge1xuICAgICAgICAgIGxpbmUgPSBwcmV2TG9jYXRpb24ubGFzdF9saW5lLCBjb2x1bW4gPSBwcmV2TG9jYXRpb24ubGFzdF9jb2x1bW47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGluZSA9IGNvbHVtbiA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgdG9rZW5bMl0gPSB7XG4gICAgICAgICAgZmlyc3RfbGluZTogbGluZSxcbiAgICAgICAgICBmaXJzdF9jb2x1bW46IGNvbHVtbixcbiAgICAgICAgICBsYXN0X2xpbmU6IGxpbmUsXG4gICAgICAgICAgbGFzdF9jb2x1bW46IGNvbHVtblxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBSZXdyaXRlci5wcm90b3R5cGUubm9ybWFsaXplTGluZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhY3Rpb24sIGNvbmRpdGlvbiwgaW5kZW50LCBvdXRkZW50LCBzdGFydGVyO1xuICAgICAgc3RhcnRlciA9IGluZGVudCA9IG91dGRlbnQgPSBudWxsO1xuICAgICAgY29uZGl0aW9uID0gZnVuY3Rpb24odG9rZW4sIGkpIHtcbiAgICAgICAgdmFyIF9yZWYsIF9yZWYxLCBfcmVmMiwgX3JlZjM7XG4gICAgICAgIHJldHVybiB0b2tlblsxXSAhPT0gJzsnICYmIChfcmVmID0gdG9rZW5bMF0sIF9faW5kZXhPZi5jYWxsKFNJTkdMRV9DTE9TRVJTLCBfcmVmKSA+PSAwKSAmJiAhKHRva2VuWzBdID09PSAnVEVSTUlOQVRPUicgJiYgKF9yZWYxID0gdGhpcy50YWcoaSArIDEpLCBfX2luZGV4T2YuY2FsbChFWFBSRVNTSU9OX0NMT1NFLCBfcmVmMSkgPj0gMCkpICYmICEodG9rZW5bMF0gPT09ICdFTFNFJyAmJiBzdGFydGVyICE9PSAnVEhFTicpICYmICEoKChfcmVmMiA9IHRva2VuWzBdKSA9PT0gJ0NBVENIJyB8fCBfcmVmMiA9PT0gJ0ZJTkFMTFknKSAmJiAoc3RhcnRlciA9PT0gJy0+JyB8fCBzdGFydGVyID09PSAnPT4nKSkgfHwgKF9yZWYzID0gdG9rZW5bMF0sIF9faW5kZXhPZi5jYWxsKENBTExfQ0xPU0VSUywgX3JlZjMpID49IDApICYmIHRoaXMudG9rZW5zW2kgLSAxXS5uZXdMaW5lO1xuICAgICAgfTtcbiAgICAgIGFjdGlvbiA9IGZ1bmN0aW9uKHRva2VuLCBpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRva2Vucy5zcGxpY2UoKHRoaXMudGFnKGkgLSAxKSA9PT0gJywnID8gaSAtIDEgOiBpKSwgMCwgb3V0ZGVudCk7XG4gICAgICB9O1xuICAgICAgcmV0dXJuIHRoaXMuc2NhblRva2VucyhmdW5jdGlvbih0b2tlbiwgaSwgdG9rZW5zKSB7XG4gICAgICAgIHZhciBqLCB0YWcsIF9pLCBfcmVmLCBfcmVmMSwgX3JlZjI7XG4gICAgICAgIHRhZyA9IHRva2VuWzBdO1xuICAgICAgICBpZiAodGFnID09PSAnVEVSTUlOQVRPUicpIHtcbiAgICAgICAgICBpZiAodGhpcy50YWcoaSArIDEpID09PSAnRUxTRScgJiYgdGhpcy50YWcoaSAtIDEpICE9PSAnT1VUREVOVCcpIHtcbiAgICAgICAgICAgIHRva2Vucy5zcGxpY2UuYXBwbHkodG9rZW5zLCBbaSwgMV0uY29uY2F0KF9fc2xpY2UuY2FsbCh0aGlzLmluZGVudGF0aW9uKCkpKSk7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKF9yZWYgPSB0aGlzLnRhZyhpICsgMSksIF9faW5kZXhPZi5jYWxsKEVYUFJFU1NJT05fQ0xPU0UsIF9yZWYpID49IDApIHtcbiAgICAgICAgICAgIHRva2Vucy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhZyA9PT0gJ0NBVENIJykge1xuICAgICAgICAgIGZvciAoaiA9IF9pID0gMTsgX2kgPD0gMjsgaiA9ICsrX2kpIHtcbiAgICAgICAgICAgIGlmICghKChfcmVmMSA9IHRoaXMudGFnKGkgKyBqKSkgPT09ICdPVVRERU5UJyB8fCBfcmVmMSA9PT0gJ1RFUk1JTkFUT1InIHx8IF9yZWYxID09PSAnRklOQUxMWScpKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9rZW5zLnNwbGljZS5hcHBseSh0b2tlbnMsIFtpICsgaiwgMF0uY29uY2F0KF9fc2xpY2UuY2FsbCh0aGlzLmluZGVudGF0aW9uKCkpKSk7XG4gICAgICAgICAgICByZXR1cm4gMiArIGo7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChfX2luZGV4T2YuY2FsbChTSU5HTEVfTElORVJTLCB0YWcpID49IDAgJiYgdGhpcy50YWcoaSArIDEpICE9PSAnSU5ERU5UJyAmJiAhKHRhZyA9PT0gJ0VMU0UnICYmIHRoaXMudGFnKGkgKyAxKSA9PT0gJ0lGJykpIHtcbiAgICAgICAgICBzdGFydGVyID0gdGFnO1xuICAgICAgICAgIF9yZWYyID0gdGhpcy5pbmRlbnRhdGlvbih0b2tlbnNbaV0pLCBpbmRlbnQgPSBfcmVmMlswXSwgb3V0ZGVudCA9IF9yZWYyWzFdO1xuICAgICAgICAgIGlmIChzdGFydGVyID09PSAnVEhFTicpIHtcbiAgICAgICAgICAgIGluZGVudC5mcm9tVGhlbiA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRva2Vucy5zcGxpY2UoaSArIDEsIDAsIGluZGVudCk7XG4gICAgICAgICAgdGhpcy5kZXRlY3RFbmQoaSArIDIsIGNvbmRpdGlvbiwgYWN0aW9uKTtcbiAgICAgICAgICBpZiAodGFnID09PSAnVEhFTicpIHtcbiAgICAgICAgICAgIHRva2Vucy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAxO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIFJld3JpdGVyLnByb3RvdHlwZS50YWdQb3N0Zml4Q29uZGl0aW9uYWxzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYWN0aW9uLCBjb25kaXRpb24sIG9yaWdpbmFsO1xuICAgICAgb3JpZ2luYWwgPSBudWxsO1xuICAgICAgY29uZGl0aW9uID0gZnVuY3Rpb24odG9rZW4sIGkpIHtcbiAgICAgICAgdmFyIHByZXZUYWcsIHRhZztcbiAgICAgICAgdGFnID0gdG9rZW5bMF07XG4gICAgICAgIHByZXZUYWcgPSB0aGlzLnRva2Vuc1tpIC0gMV1bMF07XG4gICAgICAgIHJldHVybiB0YWcgPT09ICdURVJNSU5BVE9SJyB8fCAodGFnID09PSAnSU5ERU5UJyAmJiBfX2luZGV4T2YuY2FsbChTSU5HTEVfTElORVJTLCBwcmV2VGFnKSA8IDApO1xuICAgICAgfTtcbiAgICAgIGFjdGlvbiA9IGZ1bmN0aW9uKHRva2VuLCBpKSB7XG4gICAgICAgIGlmICh0b2tlblswXSAhPT0gJ0lOREVOVCcgfHwgKHRva2VuLmdlbmVyYXRlZCAmJiAhdG9rZW4uZnJvbVRoZW4pKSB7XG4gICAgICAgICAgcmV0dXJuIG9yaWdpbmFsWzBdID0gJ1BPU1RfJyArIG9yaWdpbmFsWzBdO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgcmV0dXJuIHRoaXMuc2NhblRva2VucyhmdW5jdGlvbih0b2tlbiwgaSkge1xuICAgICAgICBpZiAodG9rZW5bMF0gIT09ICdJRicpIHtcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBvcmlnaW5hbCA9IHRva2VuO1xuICAgICAgICB0aGlzLmRldGVjdEVuZChpICsgMSwgY29uZGl0aW9uLCBhY3Rpb24pO1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBSZXdyaXRlci5wcm90b3R5cGUuaW5kZW50YXRpb24gPSBmdW5jdGlvbihvcmlnaW4pIHtcbiAgICAgIHZhciBpbmRlbnQsIG91dGRlbnQ7XG4gICAgICBpbmRlbnQgPSBbJ0lOREVOVCcsIDJdO1xuICAgICAgb3V0ZGVudCA9IFsnT1VUREVOVCcsIDJdO1xuICAgICAgaWYgKG9yaWdpbikge1xuICAgICAgICBpbmRlbnQuZ2VuZXJhdGVkID0gb3V0ZGVudC5nZW5lcmF0ZWQgPSB0cnVlO1xuICAgICAgICBpbmRlbnQub3JpZ2luID0gb3V0ZGVudC5vcmlnaW4gPSBvcmlnaW47XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbmRlbnQuZXhwbGljaXQgPSBvdXRkZW50LmV4cGxpY2l0ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbaW5kZW50LCBvdXRkZW50XTtcbiAgICB9O1xuXG4gICAgUmV3cml0ZXIucHJvdG90eXBlLmdlbmVyYXRlID0gZ2VuZXJhdGU7XG5cbiAgICBSZXdyaXRlci5wcm90b3R5cGUudGFnID0gZnVuY3Rpb24oaSkge1xuICAgICAgdmFyIF9yZWY7XG4gICAgICByZXR1cm4gKF9yZWYgPSB0aGlzLnRva2Vuc1tpXSkgIT0gbnVsbCA/IF9yZWZbMF0gOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIHJldHVybiBSZXdyaXRlcjtcblxuICB9KSgpO1xuXG4gIEJBTEFOQ0VEX1BBSVJTID0gW1snKCcsICcpJ10sIFsnWycsICddJ10sIFsneycsICd9J10sIFsnSU5ERU5UJywgJ09VVERFTlQnXSwgWydDQUxMX1NUQVJUJywgJ0NBTExfRU5EJ10sIFsnUEFSQU1fU1RBUlQnLCAnUEFSQU1fRU5EJ10sIFsnSU5ERVhfU1RBUlQnLCAnSU5ERVhfRU5EJ11dO1xuXG4gIGV4cG9ydHMuSU5WRVJTRVMgPSBJTlZFUlNFUyA9IHt9O1xuXG4gIEVYUFJFU1NJT05fU1RBUlQgPSBbXTtcblxuICBFWFBSRVNTSU9OX0VORCA9IFtdO1xuXG4gIGZvciAoX2kgPSAwLCBfbGVuID0gQkFMQU5DRURfUEFJUlMubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICBfcmVmID0gQkFMQU5DRURfUEFJUlNbX2ldLCBsZWZ0ID0gX3JlZlswXSwgcml0ZSA9IF9yZWZbMV07XG4gICAgRVhQUkVTU0lPTl9TVEFSVC5wdXNoKElOVkVSU0VTW3JpdGVdID0gbGVmdCk7XG4gICAgRVhQUkVTU0lPTl9FTkQucHVzaChJTlZFUlNFU1tsZWZ0XSA9IHJpdGUpO1xuICB9XG5cbiAgRVhQUkVTU0lPTl9DTE9TRSA9IFsnQ0FUQ0gnLCAnVEhFTicsICdFTFNFJywgJ0ZJTkFMTFknXS5jb25jYXQoRVhQUkVTU0lPTl9FTkQpO1xuXG4gIElNUExJQ0lUX0ZVTkMgPSBbJ0lERU5USUZJRVInLCAnU1VQRVInLCAnKScsICdDQUxMX0VORCcsICddJywgJ0lOREVYX0VORCcsICdAJywgJ1RISVMnXTtcblxuICBJTVBMSUNJVF9DQUxMID0gWydJREVOVElGSUVSJywgJ05VTUJFUicsICdTVFJJTkcnLCAnSlMnLCAnUkVHRVgnLCAnTkVXJywgJ1BBUkFNX1NUQVJUJywgJ0NMQVNTJywgJ0lGJywgJ1RSWScsICdTV0lUQ0gnLCAnVEhJUycsICdCT09MJywgJ05VTEwnLCAnVU5ERUZJTkVEJywgJ1VOQVJZJywgJ1VOQVJZX01BVEgnLCAnU1VQRVInLCAnVEhST1cnLCAnQCcsICctPicsICc9PicsICdbJywgJygnLCAneycsICctLScsICcrKyddO1xuXG4gIElNUExJQ0lUX1VOU1BBQ0VEX0NBTEwgPSBbJysnLCAnLSddO1xuXG4gIElNUExJQ0lUX0VORCA9IFsnUE9TVF9JRicsICdGT1InLCAnV0hJTEUnLCAnVU5USUwnLCAnV0hFTicsICdCWScsICdMT09QJywgJ1RFUk1JTkFUT1InXTtcblxuICBTSU5HTEVfTElORVJTID0gWydFTFNFJywgJy0+JywgJz0+JywgJ1RSWScsICdGSU5BTExZJywgJ1RIRU4nXTtcblxuICBTSU5HTEVfQ0xPU0VSUyA9IFsnVEVSTUlOQVRPUicsICdDQVRDSCcsICdGSU5BTExZJywgJ0VMU0UnLCAnT1VUREVOVCcsICdMRUFESU5HX1dIRU4nXTtcblxuICBMSU5FQlJFQUtTID0gWydURVJNSU5BVE9SJywgJ0lOREVOVCcsICdPVVRERU5UJ107XG5cbiAgQ0FMTF9DTE9TRVJTID0gWycuJywgJz8uJywgJzo6JywgJz86OiddO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjguMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgU2NvcGUsIGV4dGVuZCwgbGFzdCwgX3JlZjtcblxuICBfcmVmID0gcmVxdWlyZSgnLi9oZWxwZXJzJyksIGV4dGVuZCA9IF9yZWYuZXh0ZW5kLCBsYXN0ID0gX3JlZi5sYXN0O1xuXG4gIGV4cG9ydHMuU2NvcGUgPSBTY29wZSA9IChmdW5jdGlvbigpIHtcbiAgICBTY29wZS5yb290ID0gbnVsbDtcblxuICAgIGZ1bmN0aW9uIFNjb3BlKHBhcmVudCwgZXhwcmVzc2lvbnMsIG1ldGhvZCkge1xuICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICB0aGlzLmV4cHJlc3Npb25zID0gZXhwcmVzc2lvbnM7XG4gICAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZDtcbiAgICAgIHRoaXMudmFyaWFibGVzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogJ2FyZ3VtZW50cycsXG4gICAgICAgICAgdHlwZTogJ2FyZ3VtZW50cydcbiAgICAgICAgfVxuICAgICAgXTtcbiAgICAgIHRoaXMucG9zaXRpb25zID0ge307XG4gICAgICBpZiAoIXRoaXMucGFyZW50KSB7XG4gICAgICAgIFNjb3BlLnJvb3QgPSB0aGlzO1xuICAgICAgfVxuICAgIH1cblxuICAgIFNjb3BlLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbihuYW1lLCB0eXBlLCBpbW1lZGlhdGUpIHtcbiAgICAgIGlmICh0aGlzLnNoYXJlZCAmJiAhaW1tZWRpYXRlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmVudC5hZGQobmFtZSwgdHlwZSwgaW1tZWRpYXRlKTtcbiAgICAgIH1cbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5wb3NpdGlvbnMsIG5hbWUpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhcmlhYmxlc1t0aGlzLnBvc2l0aW9uc1tuYW1lXV0udHlwZSA9IHR5cGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbnNbbmFtZV0gPSB0aGlzLnZhcmlhYmxlcy5wdXNoKHtcbiAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgIHR5cGU6IHR5cGVcbiAgICAgICAgfSkgLSAxO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTY29wZS5wcm90b3R5cGUubmFtZWRNZXRob2QgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBfcmVmMTtcbiAgICAgIGlmICgoKF9yZWYxID0gdGhpcy5tZXRob2QpICE9IG51bGwgPyBfcmVmMS5uYW1lIDogdm9pZCAwKSB8fCAhdGhpcy5wYXJlbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWV0aG9kO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMucGFyZW50Lm5hbWVkTWV0aG9kKCk7XG4gICAgfTtcblxuICAgIFNjb3BlLnByb3RvdHlwZS5maW5kID0gZnVuY3Rpb24obmFtZSkge1xuICAgICAgaWYgKHRoaXMuY2hlY2sobmFtZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICB0aGlzLmFkZChuYW1lLCAndmFyJyk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIFNjb3BlLnByb3RvdHlwZS5wYXJhbWV0ZXIgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICBpZiAodGhpcy5zaGFyZWQgJiYgdGhpcy5wYXJlbnQuY2hlY2sobmFtZSwgdHJ1ZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYWRkKG5hbWUsICdwYXJhbScpO1xuICAgIH07XG5cbiAgICBTY29wZS5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICB2YXIgX3JlZjE7XG4gICAgICByZXR1cm4gISEodGhpcy50eXBlKG5hbWUpIHx8ICgoX3JlZjEgPSB0aGlzLnBhcmVudCkgIT0gbnVsbCA/IF9yZWYxLmNoZWNrKG5hbWUpIDogdm9pZCAwKSk7XG4gICAgfTtcblxuICAgIFNjb3BlLnByb3RvdHlwZS50ZW1wb3JhcnkgPSBmdW5jdGlvbihuYW1lLCBpbmRleCkge1xuICAgICAgaWYgKG5hbWUubGVuZ3RoID4gMSkge1xuICAgICAgICByZXR1cm4gJ18nICsgbmFtZSArIChpbmRleCA+IDEgPyBpbmRleCAtIDEgOiAnJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gJ18nICsgKGluZGV4ICsgcGFyc2VJbnQobmFtZSwgMzYpKS50b1N0cmluZygzNikucmVwbGFjZSgvXFxkL2csICdhJyk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFNjb3BlLnByb3RvdHlwZS50eXBlID0gZnVuY3Rpb24obmFtZSkge1xuICAgICAgdmFyIHYsIF9pLCBfbGVuLCBfcmVmMTtcbiAgICAgIF9yZWYxID0gdGhpcy52YXJpYWJsZXM7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYxLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIHYgPSBfcmVmMVtfaV07XG4gICAgICAgIGlmICh2Lm5hbWUgPT09IG5hbWUpIHtcbiAgICAgICAgICByZXR1cm4gdi50eXBlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgU2NvcGUucHJvdG90eXBlLmZyZWVWYXJpYWJsZSA9IGZ1bmN0aW9uKG5hbWUsIHJlc2VydmUpIHtcbiAgICAgIHZhciBpbmRleCwgdGVtcDtcbiAgICAgIGlmIChyZXNlcnZlID09IG51bGwpIHtcbiAgICAgICAgcmVzZXJ2ZSA9IHRydWU7XG4gICAgICB9XG4gICAgICBpbmRleCA9IDA7XG4gICAgICB3aGlsZSAodGhpcy5jaGVjaygodGVtcCA9IHRoaXMudGVtcG9yYXJ5KG5hbWUsIGluZGV4KSkpKSB7XG4gICAgICAgIGluZGV4Kys7XG4gICAgICB9XG4gICAgICBpZiAocmVzZXJ2ZSkge1xuICAgICAgICB0aGlzLmFkZCh0ZW1wLCAndmFyJywgdHJ1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGVtcDtcbiAgICB9O1xuXG4gICAgU2NvcGUucHJvdG90eXBlLmFzc2lnbiA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICB0aGlzLmFkZChuYW1lLCB7XG4gICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgYXNzaWduZWQ6IHRydWVcbiAgICAgIH0sIHRydWUpO1xuICAgICAgcmV0dXJuIHRoaXMuaGFzQXNzaWdubWVudHMgPSB0cnVlO1xuICAgIH07XG5cbiAgICBTY29wZS5wcm90b3R5cGUuaGFzRGVjbGFyYXRpb25zID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gISF0aGlzLmRlY2xhcmVkVmFyaWFibGVzKCkubGVuZ3RoO1xuICAgIH07XG5cbiAgICBTY29wZS5wcm90b3R5cGUuZGVjbGFyZWRWYXJpYWJsZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWFsVmFycywgdGVtcFZhcnMsIHYsIF9pLCBfbGVuLCBfcmVmMTtcbiAgICAgIHJlYWxWYXJzID0gW107XG4gICAgICB0ZW1wVmFycyA9IFtdO1xuICAgICAgX3JlZjEgPSB0aGlzLnZhcmlhYmxlcztcbiAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gX3JlZjEubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgdiA9IF9yZWYxW19pXTtcbiAgICAgICAgaWYgKHYudHlwZSA9PT0gJ3ZhcicpIHtcbiAgICAgICAgICAodi5uYW1lLmNoYXJBdCgwKSA9PT0gJ18nID8gdGVtcFZhcnMgOiByZWFsVmFycykucHVzaCh2Lm5hbWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVhbFZhcnMuc29ydCgpLmNvbmNhdCh0ZW1wVmFycy5zb3J0KCkpO1xuICAgIH07XG5cbiAgICBTY29wZS5wcm90b3R5cGUuYXNzaWduZWRWYXJpYWJsZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB2LCBfaSwgX2xlbiwgX3JlZjEsIF9yZXN1bHRzO1xuICAgICAgX3JlZjEgPSB0aGlzLnZhcmlhYmxlcztcbiAgICAgIF9yZXN1bHRzID0gW107XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYxLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIHYgPSBfcmVmMVtfaV07XG4gICAgICAgIGlmICh2LnR5cGUuYXNzaWduZWQpIHtcbiAgICAgICAgICBfcmVzdWx0cy5wdXNoKFwiXCIgKyB2Lm5hbWUgKyBcIiA9IFwiICsgdi50eXBlLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIF9yZXN1bHRzO1xuICAgIH07XG5cbiAgICByZXR1cm4gU2NvcGU7XG5cbiAgfSkoKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS44LjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIExpbmVNYXAsIFNvdXJjZU1hcDtcblxuICBMaW5lTWFwID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIExpbmVNYXAobGluZSkge1xuICAgICAgdGhpcy5saW5lID0gbGluZTtcbiAgICAgIHRoaXMuY29sdW1ucyA9IFtdO1xuICAgIH1cblxuICAgIExpbmVNYXAucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uKGNvbHVtbiwgX2FyZywgb3B0aW9ucykge1xuICAgICAgdmFyIHNvdXJjZUNvbHVtbiwgc291cmNlTGluZTtcbiAgICAgIHNvdXJjZUxpbmUgPSBfYXJnWzBdLCBzb3VyY2VDb2x1bW4gPSBfYXJnWzFdO1xuICAgICAgaWYgKG9wdGlvbnMgPT0gbnVsbCkge1xuICAgICAgICBvcHRpb25zID0ge307XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5jb2x1bW5zW2NvbHVtbl0gJiYgb3B0aW9ucy5ub1JlcGxhY2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuY29sdW1uc1tjb2x1bW5dID0ge1xuICAgICAgICBsaW5lOiB0aGlzLmxpbmUsXG4gICAgICAgIGNvbHVtbjogY29sdW1uLFxuICAgICAgICBzb3VyY2VMaW5lOiBzb3VyY2VMaW5lLFxuICAgICAgICBzb3VyY2VDb2x1bW46IHNvdXJjZUNvbHVtblxuICAgICAgfTtcbiAgICB9O1xuXG4gICAgTGluZU1hcC5wcm90b3R5cGUuc291cmNlTG9jYXRpb24gPSBmdW5jdGlvbihjb2x1bW4pIHtcbiAgICAgIHZhciBtYXBwaW5nO1xuICAgICAgd2hpbGUgKCEoKG1hcHBpbmcgPSB0aGlzLmNvbHVtbnNbY29sdW1uXSkgfHwgKGNvbHVtbiA8PSAwKSkpIHtcbiAgICAgICAgY29sdW1uLS07XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFwcGluZyAmJiBbbWFwcGluZy5zb3VyY2VMaW5lLCBtYXBwaW5nLnNvdXJjZUNvbHVtbl07XG4gICAgfTtcblxuICAgIHJldHVybiBMaW5lTWFwO1xuXG4gIH0pKCk7XG5cbiAgU291cmNlTWFwID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBCQVNFNjRfQ0hBUlMsIFZMUV9DT05USU5VQVRJT05fQklULCBWTFFfU0hJRlQsIFZMUV9WQUxVRV9NQVNLO1xuXG4gICAgZnVuY3Rpb24gU291cmNlTWFwKCkge1xuICAgICAgdGhpcy5saW5lcyA9IFtdO1xuICAgIH1cblxuICAgIFNvdXJjZU1hcC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24oc291cmNlTG9jYXRpb24sIGdlbmVyYXRlZExvY2F0aW9uLCBvcHRpb25zKSB7XG4gICAgICB2YXIgY29sdW1uLCBsaW5lLCBsaW5lTWFwLCBfYmFzZTtcbiAgICAgIGlmIChvcHRpb25zID09IG51bGwpIHtcbiAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgfVxuICAgICAgbGluZSA9IGdlbmVyYXRlZExvY2F0aW9uWzBdLCBjb2x1bW4gPSBnZW5lcmF0ZWRMb2NhdGlvblsxXTtcbiAgICAgIGxpbmVNYXAgPSAoKF9iYXNlID0gdGhpcy5saW5lcylbbGluZV0gfHwgKF9iYXNlW2xpbmVdID0gbmV3IExpbmVNYXAobGluZSkpKTtcbiAgICAgIHJldHVybiBsaW5lTWFwLmFkZChjb2x1bW4sIHNvdXJjZUxvY2F0aW9uLCBvcHRpb25zKTtcbiAgICB9O1xuXG4gICAgU291cmNlTWFwLnByb3RvdHlwZS5zb3VyY2VMb2NhdGlvbiA9IGZ1bmN0aW9uKF9hcmcpIHtcbiAgICAgIHZhciBjb2x1bW4sIGxpbmUsIGxpbmVNYXA7XG4gICAgICBsaW5lID0gX2FyZ1swXSwgY29sdW1uID0gX2FyZ1sxXTtcbiAgICAgIHdoaWxlICghKChsaW5lTWFwID0gdGhpcy5saW5lc1tsaW5lXSkgfHwgKGxpbmUgPD0gMCkpKSB7XG4gICAgICAgIGxpbmUtLTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBsaW5lTWFwICYmIGxpbmVNYXAuc291cmNlTG9jYXRpb24oY29sdW1uKTtcbiAgICB9O1xuXG4gICAgU291cmNlTWFwLnByb3RvdHlwZS5nZW5lcmF0ZSA9IGZ1bmN0aW9uKG9wdGlvbnMsIGNvZGUpIHtcbiAgICAgIHZhciBidWZmZXIsIGxhc3RDb2x1bW4sIGxhc3RTb3VyY2VDb2x1bW4sIGxhc3RTb3VyY2VMaW5lLCBsaW5lTWFwLCBsaW5lTnVtYmVyLCBtYXBwaW5nLCBuZWVkQ29tbWEsIHYzLCB3cml0aW5nbGluZSwgX2ksIF9qLCBfbGVuLCBfbGVuMSwgX3JlZiwgX3JlZjE7XG4gICAgICBpZiAob3B0aW9ucyA9PSBudWxsKSB7XG4gICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgIH1cbiAgICAgIGlmIChjb2RlID09IG51bGwpIHtcbiAgICAgICAgY29kZSA9IG51bGw7XG4gICAgICB9XG4gICAgICB3cml0aW5nbGluZSA9IDA7XG4gICAgICBsYXN0Q29sdW1uID0gMDtcbiAgICAgIGxhc3RTb3VyY2VMaW5lID0gMDtcbiAgICAgIGxhc3RTb3VyY2VDb2x1bW4gPSAwO1xuICAgICAgbmVlZENvbW1hID0gZmFsc2U7XG4gICAgICBidWZmZXIgPSBcIlwiO1xuICAgICAgX3JlZiA9IHRoaXMubGluZXM7XG4gICAgICBmb3IgKGxpbmVOdW1iZXIgPSBfaSA9IDAsIF9sZW4gPSBfcmVmLmxlbmd0aDsgX2kgPCBfbGVuOyBsaW5lTnVtYmVyID0gKytfaSkge1xuICAgICAgICBsaW5lTWFwID0gX3JlZltsaW5lTnVtYmVyXTtcbiAgICAgICAgaWYgKGxpbmVNYXApIHtcbiAgICAgICAgICBfcmVmMSA9IGxpbmVNYXAuY29sdW1ucztcbiAgICAgICAgICBmb3IgKF9qID0gMCwgX2xlbjEgPSBfcmVmMS5sZW5ndGg7IF9qIDwgX2xlbjE7IF9qKyspIHtcbiAgICAgICAgICAgIG1hcHBpbmcgPSBfcmVmMVtfal07XG4gICAgICAgICAgICBpZiAoIShtYXBwaW5nKSkge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHdoaWxlICh3cml0aW5nbGluZSA8IG1hcHBpbmcubGluZSkge1xuICAgICAgICAgICAgICBsYXN0Q29sdW1uID0gMDtcbiAgICAgICAgICAgICAgbmVlZENvbW1hID0gZmFsc2U7XG4gICAgICAgICAgICAgIGJ1ZmZlciArPSBcIjtcIjtcbiAgICAgICAgICAgICAgd3JpdGluZ2xpbmUrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChuZWVkQ29tbWEpIHtcbiAgICAgICAgICAgICAgYnVmZmVyICs9IFwiLFwiO1xuICAgICAgICAgICAgICBuZWVkQ29tbWEgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJ1ZmZlciArPSB0aGlzLmVuY29kZVZscShtYXBwaW5nLmNvbHVtbiAtIGxhc3RDb2x1bW4pO1xuICAgICAgICAgICAgbGFzdENvbHVtbiA9IG1hcHBpbmcuY29sdW1uO1xuICAgICAgICAgICAgYnVmZmVyICs9IHRoaXMuZW5jb2RlVmxxKDApO1xuICAgICAgICAgICAgYnVmZmVyICs9IHRoaXMuZW5jb2RlVmxxKG1hcHBpbmcuc291cmNlTGluZSAtIGxhc3RTb3VyY2VMaW5lKTtcbiAgICAgICAgICAgIGxhc3RTb3VyY2VMaW5lID0gbWFwcGluZy5zb3VyY2VMaW5lO1xuICAgICAgICAgICAgYnVmZmVyICs9IHRoaXMuZW5jb2RlVmxxKG1hcHBpbmcuc291cmNlQ29sdW1uIC0gbGFzdFNvdXJjZUNvbHVtbik7XG4gICAgICAgICAgICBsYXN0U291cmNlQ29sdW1uID0gbWFwcGluZy5zb3VyY2VDb2x1bW47XG4gICAgICAgICAgICBuZWVkQ29tbWEgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdjMgPSB7XG4gICAgICAgIHZlcnNpb246IDMsXG4gICAgICAgIGZpbGU6IG9wdGlvbnMuZ2VuZXJhdGVkRmlsZSB8fCAnJyxcbiAgICAgICAgc291cmNlUm9vdDogb3B0aW9ucy5zb3VyY2VSb290IHx8ICcnLFxuICAgICAgICBzb3VyY2VzOiBvcHRpb25zLnNvdXJjZUZpbGVzIHx8IFsnJ10sXG4gICAgICAgIG5hbWVzOiBbXSxcbiAgICAgICAgbWFwcGluZ3M6IGJ1ZmZlclxuICAgICAgfTtcbiAgICAgIGlmIChvcHRpb25zLmlubGluZSkge1xuICAgICAgICB2My5zb3VyY2VzQ29udGVudCA9IFtjb2RlXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2MywgbnVsbCwgMik7XG4gICAgfTtcblxuICAgIFZMUV9TSElGVCA9IDU7XG5cbiAgICBWTFFfQ09OVElOVUFUSU9OX0JJVCA9IDEgPDwgVkxRX1NISUZUO1xuXG4gICAgVkxRX1ZBTFVFX01BU0sgPSBWTFFfQ09OVElOVUFUSU9OX0JJVCAtIDE7XG5cbiAgICBTb3VyY2VNYXAucHJvdG90eXBlLmVuY29kZVZscSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICB2YXIgYW5zd2VyLCBuZXh0Q2h1bmssIHNpZ25CaXQsIHZhbHVlVG9FbmNvZGU7XG4gICAgICBhbnN3ZXIgPSAnJztcbiAgICAgIHNpZ25CaXQgPSB2YWx1ZSA8IDAgPyAxIDogMDtcbiAgICAgIHZhbHVlVG9FbmNvZGUgPSAoTWF0aC5hYnModmFsdWUpIDw8IDEpICsgc2lnbkJpdDtcbiAgICAgIHdoaWxlICh2YWx1ZVRvRW5jb2RlIHx8ICFhbnN3ZXIpIHtcbiAgICAgICAgbmV4dENodW5rID0gdmFsdWVUb0VuY29kZSAmIFZMUV9WQUxVRV9NQVNLO1xuICAgICAgICB2YWx1ZVRvRW5jb2RlID0gdmFsdWVUb0VuY29kZSA+PiBWTFFfU0hJRlQ7XG4gICAgICAgIGlmICh2YWx1ZVRvRW5jb2RlKSB7XG4gICAgICAgICAgbmV4dENodW5rIHw9IFZMUV9DT05USU5VQVRJT05fQklUO1xuICAgICAgICB9XG4gICAgICAgIGFuc3dlciArPSB0aGlzLmVuY29kZUJhc2U2NChuZXh0Q2h1bmspO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICB9O1xuXG4gICAgQkFTRTY0X0NIQVJTID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG4gICAgU291cmNlTWFwLnByb3RvdHlwZS5lbmNvZGVCYXNlNjQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIEJBU0U2NF9DSEFSU1t2YWx1ZV0gfHwgKGZ1bmN0aW9uKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgQmFzZTY0IGVuY29kZSB2YWx1ZTogXCIgKyB2YWx1ZSk7XG4gICAgICB9KSgpO1xuICAgIH07XG5cbiAgICByZXR1cm4gU291cmNlTWFwO1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBTb3VyY2VNYXA7XG5cbn0pLmNhbGwodGhpcyk7XG4iLG51bGwsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTJcblxuLyoqXG4gKiBJZiBgQnVmZmVyLl91c2VUeXBlZEFycmF5c2A6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChjb21wYXRpYmxlIGRvd24gdG8gSUU2KVxuICovXG5CdWZmZXIuX3VzZVR5cGVkQXJyYXlzID0gKGZ1bmN0aW9uICgpIHtcbiAgLy8gRGV0ZWN0IGlmIGJyb3dzZXIgc3VwcG9ydHMgVHlwZWQgQXJyYXlzLiBTdXBwb3J0ZWQgYnJvd3NlcnMgYXJlIElFIDEwKywgRmlyZWZveCA0KyxcbiAgLy8gQ2hyb21lIDcrLCBTYWZhcmkgNS4xKywgT3BlcmEgMTEuNissIGlPUyA0LjIrLiBJZiB0aGUgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IGFkZGluZ1xuICAvLyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsIHRoZW4gdGhhdCdzIHRoZSBzYW1lIGFzIG5vIGBVaW50OEFycmF5YCBzdXBwb3J0XG4gIC8vIGJlY2F1c2Ugd2UgbmVlZCB0byBiZSBhYmxlIHRvIGFkZCBhbGwgdGhlIG5vZGUgQnVmZmVyIEFQSSBtZXRob2RzLiBUaGlzIGlzIGFuIGlzc3VlXG4gIC8vIGluIEZpcmVmb3ggNC0yOS4gTm93IGZpeGVkOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzhcbiAgdHJ5IHtcbiAgICB2YXIgYnVmID0gbmV3IEFycmF5QnVmZmVyKDApXG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KGJ1ZilcbiAgICBhcnIuZm9vID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfVxuICAgIHJldHVybiA0MiA9PT0gYXJyLmZvbygpICYmXG4gICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgLy8gQ2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufSkoKVxuXG4vKipcbiAqIENsYXNzOiBCdWZmZXJcbiAqID09PT09PT09PT09PT1cbiAqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGFyZSBhdWdtZW50ZWRcbiAqIHdpdGggZnVuY3Rpb24gcHJvcGVydGllcyBmb3IgYWxsIHRoZSBub2RlIGBCdWZmZXJgIEFQSSBmdW5jdGlvbnMuIFdlIHVzZVxuICogYFVpbnQ4QXJyYXlgIHNvIHRoYXQgc3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXQgcmV0dXJuc1xuICogYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogQnkgYXVnbWVudGluZyB0aGUgaW5zdGFuY2VzLCB3ZSBjYW4gYXZvaWQgbW9kaWZ5aW5nIHRoZSBgVWludDhBcnJheWBcbiAqIHByb3RvdHlwZS5cbiAqL1xuZnVuY3Rpb24gQnVmZmVyIChzdWJqZWN0LCBlbmNvZGluZywgbm9aZXJvKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKVxuICAgIHJldHVybiBuZXcgQnVmZmVyKHN1YmplY3QsIGVuY29kaW5nLCBub1plcm8pXG5cbiAgdmFyIHR5cGUgPSB0eXBlb2Ygc3ViamVjdFxuXG4gIC8vIFdvcmthcm91bmQ6IG5vZGUncyBiYXNlNjQgaW1wbGVtZW50YXRpb24gYWxsb3dzIGZvciBub24tcGFkZGVkIHN0cmluZ3NcbiAgLy8gd2hpbGUgYmFzZTY0LWpzIGRvZXMgbm90LlxuICBpZiAoZW5jb2RpbmcgPT09ICdiYXNlNjQnICYmIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgc3ViamVjdCA9IHN0cmluZ3RyaW0oc3ViamVjdClcbiAgICB3aGlsZSAoc3ViamVjdC5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgICBzdWJqZWN0ID0gc3ViamVjdCArICc9J1xuICAgIH1cbiAgfVxuXG4gIC8vIEZpbmQgdGhlIGxlbmd0aFxuICB2YXIgbGVuZ3RoXG4gIGlmICh0eXBlID09PSAnbnVtYmVyJylcbiAgICBsZW5ndGggPSBjb2VyY2Uoc3ViamVjdClcbiAgZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpXG4gICAgbGVuZ3RoID0gQnVmZmVyLmJ5dGVMZW5ndGgoc3ViamVjdCwgZW5jb2RpbmcpXG4gIGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKVxuICAgIGxlbmd0aCA9IGNvZXJjZShzdWJqZWN0Lmxlbmd0aCkgLy8gYXNzdW1lIHRoYXQgb2JqZWN0IGlzIGFycmF5LWxpa2VcbiAgZWxzZVxuICAgIHRocm93IG5ldyBFcnJvcignRmlyc3QgYXJndW1lbnQgbmVlZHMgdG8gYmUgYSBudW1iZXIsIGFycmF5IG9yIHN0cmluZy4nKVxuXG4gIHZhciBidWZcbiAgaWYgKEJ1ZmZlci5fdXNlVHlwZWRBcnJheXMpIHtcbiAgICAvLyBQcmVmZXJyZWQ6IFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgYnVmID0gQnVmZmVyLl9hdWdtZW50KG5ldyBVaW50OEFycmF5KGxlbmd0aCkpXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBUSElTIGluc3RhbmNlIG9mIEJ1ZmZlciAoY3JlYXRlZCBieSBgbmV3YClcbiAgICBidWYgPSB0aGlzXG4gICAgYnVmLmxlbmd0aCA9IGxlbmd0aFxuICAgIGJ1Zi5faXNCdWZmZXIgPSB0cnVlXG4gIH1cblxuICB2YXIgaVxuICBpZiAoQnVmZmVyLl91c2VUeXBlZEFycmF5cyAmJiB0eXBlb2Ygc3ViamVjdC5ieXRlTGVuZ3RoID09PSAnbnVtYmVyJykge1xuICAgIC8vIFNwZWVkIG9wdGltaXphdGlvbiAtLSB1c2Ugc2V0IGlmIHdlJ3JlIGNvcHlpbmcgZnJvbSBhIHR5cGVkIGFycmF5XG4gICAgYnVmLl9zZXQoc3ViamVjdClcbiAgfSBlbHNlIGlmIChpc0FycmF5aXNoKHN1YmplY3QpKSB7XG4gICAgLy8gVHJlYXQgYXJyYXktaXNoIG9iamVjdHMgYXMgYSBieXRlIGFycmF5XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKHN1YmplY3QpKVxuICAgICAgICBidWZbaV0gPSBzdWJqZWN0LnJlYWRVSW50OChpKVxuICAgICAgZWxzZVxuICAgICAgICBidWZbaV0gPSBzdWJqZWN0W2ldXG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgYnVmLndyaXRlKHN1YmplY3QsIDAsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmICFCdWZmZXIuX3VzZVR5cGVkQXJyYXlzICYmICFub1plcm8pIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGJ1ZltpXSA9IDBcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmXG59XG5cbi8vIFNUQVRJQyBNRVRIT0RTXG4vLyA9PT09PT09PT09PT09PVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAncmF3JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gKGIpIHtcbiAgcmV0dXJuICEhKGIgIT09IG51bGwgJiYgYiAhPT0gdW5kZWZpbmVkICYmIGIuX2lzQnVmZmVyKVxufVxuXG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGZ1bmN0aW9uIChzdHIsIGVuY29kaW5nKSB7XG4gIHZhciByZXRcbiAgc3RyID0gc3RyICsgJydcbiAgc3dpdGNoIChlbmNvZGluZyB8fCAndXRmOCcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0ID0gc3RyLmxlbmd0aCAvIDJcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgICAgcmV0ID0gdXRmOFRvQnl0ZXMoc3RyKS5sZW5ndGhcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAncmF3JzpcbiAgICAgIHJldCA9IHN0ci5sZW5ndGhcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHJldCA9IGJhc2U2NFRvQnl0ZXMoc3RyKS5sZW5ndGhcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldCA9IHN0ci5sZW5ndGggKiAyXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIChsaXN0LCB0b3RhbExlbmd0aCkge1xuICBhc3NlcnQoaXNBcnJheShsaXN0KSwgJ1VzYWdlOiBCdWZmZXIuY29uY2F0KGxpc3QsIFt0b3RhbExlbmd0aF0pXFxuJyArXG4gICAgICAnbGlzdCBzaG91bGQgYmUgYW4gQXJyYXkuJylcblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcigwKVxuICB9IGVsc2UgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIGxpc3RbMF1cbiAgfVxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdG90YWxMZW5ndGggIT09ICdudW1iZXInKSB7XG4gICAgdG90YWxMZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRvdGFsTGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIodG90YWxMZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGl0ZW0gPSBsaXN0W2ldXG4gICAgaXRlbS5jb3B5KGJ1ZiwgcG9zKVxuICAgIHBvcyArPSBpdGVtLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZcbn1cblxuLy8gQlVGRkVSIElOU1RBTkNFIE1FVEhPRFNcbi8vID09PT09PT09PT09PT09PT09PT09PT09XG5cbmZ1bmN0aW9uIF9oZXhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuXG4gIC8vIG11c3QgYmUgYW4gZXZlbiBudW1iZXIgb2YgZGlnaXRzXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGFzc2VydChzdHJMZW4gJSAyID09PSAwLCAnSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGJ5dGUgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgYXNzZXJ0KCFpc05hTihieXRlKSwgJ0ludmFsaWQgaGV4IHN0cmluZycpXG4gICAgYnVmW29mZnNldCArIGldID0gYnl0ZVxuICB9XG4gIEJ1ZmZlci5fY2hhcnNXcml0dGVuID0gaSAqIDJcbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gX3V0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBjaGFyc1dyaXR0ZW4gPSBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9XG4gICAgYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxuICByZXR1cm4gY2hhcnNXcml0dGVuXG59XG5cbmZ1bmN0aW9uIF9hc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IEJ1ZmZlci5fY2hhcnNXcml0dGVuID1cbiAgICBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxuICByZXR1cm4gY2hhcnNXcml0dGVuXG59XG5cbmZ1bmN0aW9uIF9iaW5hcnlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBfYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIF9iYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBjaGFyc1dyaXR0ZW4gPSBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9XG4gICAgYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuZnVuY3Rpb24gX3V0ZjE2bGVXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBjaGFyc1dyaXR0ZW4gPSBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9XG4gICAgYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxuICByZXR1cm4gY2hhcnNXcml0dGVuXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gU3VwcG9ydCBib3RoIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZylcbiAgLy8gYW5kIHRoZSBsZWdhY3kgKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIGlmICghaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgfSBlbHNlIHsgIC8vIGxlZ2FjeVxuICAgIHZhciBzd2FwID0gZW5jb2RpbmdcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIG9mZnNldCA9IGxlbmd0aFxuICAgIGxlbmd0aCA9IHN3YXBcbiAgfVxuXG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cbiAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcgfHwgJ3V0ZjgnKS50b0xvd2VyQ2FzZSgpXG5cbiAgdmFyIHJldFxuICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICAgIHJldCA9IF9oZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXQgPSBfdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIHJldCA9IF9hc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICByZXQgPSBfYmluYXJ5V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHJldCA9IF9iYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0ID0gX3V0ZjE2bGVXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nJylcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcgfHwgJ3V0ZjgnKS50b0xvd2VyQ2FzZSgpXG4gIHN0YXJ0ID0gTnVtYmVyKHN0YXJ0KSB8fCAwXG4gIGVuZCA9IChlbmQgIT09IHVuZGVmaW5lZClcbiAgICA/IE51bWJlcihlbmQpXG4gICAgOiBlbmQgPSBzZWxmLmxlbmd0aFxuXG4gIC8vIEZhc3RwYXRoIGVtcHR5IHN0cmluZ3NcbiAgaWYgKGVuZCA9PT0gc3RhcnQpXG4gICAgcmV0dXJuICcnXG5cbiAgdmFyIHJldFxuICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICAgIHJldCA9IF9oZXhTbGljZShzZWxmLCBzdGFydCwgZW5kKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXQgPSBfdXRmOFNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIHJldCA9IF9hc2NpaVNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICByZXQgPSBfYmluYXJ5U2xpY2Uoc2VsZiwgc3RhcnQsIGVuZClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHJldCA9IF9iYXNlNjRTbGljZShzZWxmLCBzdGFydCwgZW5kKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0ID0gX3V0ZjE2bGVTbGljZShzZWxmLCBzdGFydCwgZW5kKVxuICAgICAgYnJlYWtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nJylcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldF9zdGFydCwgc3RhcnQsIGVuZCkge1xuICB2YXIgc291cmNlID0gdGhpc1xuXG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICghdGFyZ2V0X3N0YXJ0KSB0YXJnZXRfc3RhcnQgPSAwXG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm5cbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgc291cmNlLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBhc3NlcnQoZW5kID49IHN0YXJ0LCAnc291cmNlRW5kIDwgc291cmNlU3RhcnQnKVxuICBhc3NlcnQodGFyZ2V0X3N0YXJ0ID49IDAgJiYgdGFyZ2V0X3N0YXJ0IDwgdGFyZ2V0Lmxlbmd0aCxcbiAgICAgICd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgYXNzZXJ0KHN0YXJ0ID49IDAgJiYgc3RhcnQgPCBzb3VyY2UubGVuZ3RoLCAnc291cmNlU3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGFzc2VydChlbmQgPj0gMCAmJiBlbmQgPD0gc291cmNlLmxlbmd0aCwgJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpXG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRfc3RhcnQgPCBlbmQgLSBzdGFydClcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0X3N0YXJ0ICsgc3RhcnRcblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcblxuICBpZiAobGVuIDwgMTAwIHx8ICFCdWZmZXIuX3VzZVR5cGVkQXJyYXlzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0X3N0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICB9IGVsc2Uge1xuICAgIHRhcmdldC5fc2V0KHRoaXMuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ICsgbGVuKSwgdGFyZ2V0X3N0YXJ0KVxuICB9XG59XG5cbmZ1bmN0aW9uIF9iYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gX3V0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXMgPSAnJ1xuICB2YXIgdG1wID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgaWYgKGJ1ZltpXSA8PSAweDdGKSB7XG4gICAgICByZXMgKz0gZGVjb2RlVXRmOENoYXIodG1wKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICAgICAgdG1wID0gJydcbiAgICB9IGVsc2Uge1xuICAgICAgdG1wICs9ICclJyArIGJ1ZltpXS50b1N0cmluZygxNilcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzICsgZGVjb2RlVXRmOENoYXIodG1wKVxufVxuXG5mdW5jdGlvbiBfYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspXG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIF9iaW5hcnlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHJldHVybiBfYXNjaWlTbGljZShidWYsIHN0YXJ0LCBlbmQpXG59XG5cbmZ1bmN0aW9uIF9oZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIF91dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2krMV0gKiAyNTYpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gY2xhbXAoc3RhcnQsIGxlbiwgMClcbiAgZW5kID0gY2xhbXAoZW5kLCBsZW4sIGxlbilcblxuICBpZiAoQnVmZmVyLl91c2VUeXBlZEFycmF5cykge1xuICAgIHJldHVybiBCdWZmZXIuX2F1Z21lbnQodGhpcy5zdWJhcnJheShzdGFydCwgZW5kKSlcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xpY2VMZW4gPSBlbmQgLSBzdGFydFxuICAgIHZhciBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQsIHRydWUpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgaSsrKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gICAgcmV0dXJuIG5ld0J1ZlxuICB9XG59XG5cbi8vIGBnZXRgIHdpbGwgYmUgcmVtb3ZlZCBpbiBOb2RlIDAuMTMrXG5CdWZmZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChvZmZzZXQpIHtcbiAgY29uc29sZS5sb2coJy5nZXQoKSBpcyBkZXByZWNhdGVkLiBBY2Nlc3MgdXNpbmcgYXJyYXkgaW5kZXhlcyBpbnN0ZWFkLicpXG4gIHJldHVybiB0aGlzLnJlYWRVSW50OChvZmZzZXQpXG59XG5cbi8vIGBzZXRgIHdpbGwgYmUgcmVtb3ZlZCBpbiBOb2RlIDAuMTMrXG5CdWZmZXIucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uICh2LCBvZmZzZXQpIHtcbiAgY29uc29sZS5sb2coJy5zZXQoKSBpcyBkZXByZWNhdGVkLiBBY2Nlc3MgdXNpbmcgYXJyYXkgaW5kZXhlcyBpbnN0ZWFkLicpXG4gIHJldHVybiB0aGlzLndyaXRlVUludDgodiwgb2Zmc2V0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgPCB0aGlzLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gdGhpcy5sZW5ndGgpXG4gICAgcmV0dXJuXG5cbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5mdW5jdGlvbiBfcmVhZFVJbnQxNiAoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAxIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIHZhciB2YWxcbiAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgIHZhbCA9IGJ1ZltvZmZzZXRdXG4gICAgaWYgKG9mZnNldCArIDEgPCBsZW4pXG4gICAgICB2YWwgfD0gYnVmW29mZnNldCArIDFdIDw8IDhcbiAgfSBlbHNlIHtcbiAgICB2YWwgPSBidWZbb2Zmc2V0XSA8PCA4XG4gICAgaWYgKG9mZnNldCArIDEgPCBsZW4pXG4gICAgICB2YWwgfD0gYnVmW29mZnNldCArIDFdXG4gIH1cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZFVJbnQxNih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZFVJbnQxNih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3JlYWRVSW50MzIgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMyA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICB2YXIgdmFsXG4gIGlmIChsaXR0bGVFbmRpYW4pIHtcbiAgICBpZiAob2Zmc2V0ICsgMiA8IGxlbilcbiAgICAgIHZhbCA9IGJ1ZltvZmZzZXQgKyAyXSA8PCAxNlxuICAgIGlmIChvZmZzZXQgKyAxIDwgbGVuKVxuICAgICAgdmFsIHw9IGJ1ZltvZmZzZXQgKyAxXSA8PCA4XG4gICAgdmFsIHw9IGJ1ZltvZmZzZXRdXG4gICAgaWYgKG9mZnNldCArIDMgPCBsZW4pXG4gICAgICB2YWwgPSB2YWwgKyAoYnVmW29mZnNldCArIDNdIDw8IDI0ID4+PiAwKVxuICB9IGVsc2Uge1xuICAgIGlmIChvZmZzZXQgKyAxIDwgbGVuKVxuICAgICAgdmFsID0gYnVmW29mZnNldCArIDFdIDw8IDE2XG4gICAgaWYgKG9mZnNldCArIDIgPCBsZW4pXG4gICAgICB2YWwgfD0gYnVmW29mZnNldCArIDJdIDw8IDhcbiAgICBpZiAob2Zmc2V0ICsgMyA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgM11cbiAgICB2YWwgPSB2YWwgKyAoYnVmW29mZnNldF0gPDwgMjQgPj4+IDApXG4gIH1cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZFVJbnQzMih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZFVJbnQzMih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgPCB0aGlzLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gdGhpcy5sZW5ndGgpXG4gICAgcmV0dXJuXG5cbiAgdmFyIG5lZyA9IHRoaXNbb2Zmc2V0XSAmIDB4ODBcbiAgaWYgKG5lZylcbiAgICByZXR1cm4gKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xXG4gIGVsc2VcbiAgICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbmZ1bmN0aW9uIF9yZWFkSW50MTYgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMSA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICB2YXIgdmFsID0gX3JlYWRVSW50MTYoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgdHJ1ZSlcbiAgdmFyIG5lZyA9IHZhbCAmIDB4ODAwMFxuICBpZiAobmVnKVxuICAgIHJldHVybiAoMHhmZmZmIC0gdmFsICsgMSkgKiAtMVxuICBlbHNlXG4gICAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkSW50MTYodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZEludDE2KHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfcmVhZEludDMyIChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgdmFyIHZhbCA9IF9yZWFkVUludDMyKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIHRydWUpXG4gIHZhciBuZWcgPSB2YWwgJiAweDgwMDAwMDAwXG4gIGlmIChuZWcpXG4gICAgcmV0dXJuICgweGZmZmZmZmZmIC0gdmFsICsgMSkgKiAtMVxuICBlbHNlXG4gICAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkSW50MzIodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZEludDMyKHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfcmVhZEZsb2F0IChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHJldHVybiBpZWVlNzU0LnJlYWQoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRGbG9hdCh0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkRmxvYXQodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF9yZWFkRG91YmxlIChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgKyA3IDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHJldHVybiBpZWVlNzU0LnJlYWQoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkRG91YmxlKHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkRG91YmxlKHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0IDwgdGhpcy5sZW5ndGgsICd0cnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmdWludCh2YWx1ZSwgMHhmZilcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gdGhpcy5sZW5ndGgpIHJldHVyblxuXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG59XG5cbmZ1bmN0aW9uIF93cml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAxIDwgYnVmLmxlbmd0aCwgJ3RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZ1aW50KHZhbHVlLCAweGZmZmYpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGxlbiAtIG9mZnNldCwgMik7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPVxuICAgICAgICAodmFsdWUgJiAoMHhmZiA8PCAoOCAqIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpKSkpID4+PlxuICAgICAgICAgICAgKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkgKiA4XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF93cml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ3RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZ1aW50KHZhbHVlLCAweGZmZmZmZmZmKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihsZW4gLSBvZmZzZXQsIDQpOyBpIDwgajsgaSsrKSB7XG4gICAgYnVmW29mZnNldCArIGldID1cbiAgICAgICAgKHZhbHVlID4+PiAobGl0dGxlRW5kaWFuID8gaSA6IDMgLSBpKSAqIDgpICYgMHhmZlxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgPCB0aGlzLmxlbmd0aCwgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZzaW50KHZhbHVlLCAweDdmLCAtMHg4MClcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gdGhpcy5sZW5ndGgpXG4gICAgcmV0dXJuXG5cbiAgaWYgKHZhbHVlID49IDApXG4gICAgdGhpcy53cml0ZVVJbnQ4KHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KVxuICBlbHNlXG4gICAgdGhpcy53cml0ZVVJbnQ4KDB4ZmYgKyB2YWx1ZSArIDEsIG9mZnNldCwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF93cml0ZUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDEgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnNpbnQodmFsdWUsIDB4N2ZmZiwgLTB4ODAwMClcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGlmICh2YWx1ZSA+PSAwKVxuICAgIF93cml0ZVVJbnQxNihidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpXG4gIGVsc2VcbiAgICBfd3JpdGVVSW50MTYoYnVmLCAweGZmZmYgKyB2YWx1ZSArIDEsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3dyaXRlSW50MzIgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMyA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmc2ludCh2YWx1ZSwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICBpZiAodmFsdWUgPj0gMClcbiAgICBfd3JpdGVVSW50MzIoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KVxuICBlbHNlXG4gICAgX3dyaXRlVUludDMyKGJ1ZiwgMHhmZmZmZmZmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZJRUVFNzU0KHZhbHVlLCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgNyA8IGJ1Zi5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmSUVFRTc1NCh2YWx1ZSwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuLy8gZmlsbCh2YWx1ZSwgc3RhcnQ9MCwgZW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiAodmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCF2YWx1ZSkgdmFsdWUgPSAwXG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCkgZW5kID0gdGhpcy5sZW5ndGhcblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHZhbHVlID0gdmFsdWUuY2hhckNvZGVBdCgwKVxuICB9XG5cbiAgYXNzZXJ0KHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgIWlzTmFOKHZhbHVlKSwgJ3ZhbHVlIGlzIG5vdCBhIG51bWJlcicpXG4gIGFzc2VydChlbmQgPj0gc3RhcnQsICdlbmQgPCBzdGFydCcpXG5cbiAgLy8gRmlsbCAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICBhc3NlcnQoc3RhcnQgPj0gMCAmJiBzdGFydCA8IHRoaXMubGVuZ3RoLCAnc3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGFzc2VydChlbmQgPj0gMCAmJiBlbmQgPD0gdGhpcy5sZW5ndGgsICdlbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICB0aGlzW2ldID0gdmFsdWVcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBvdXQgPSBbXVxuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIG91dFtpXSA9IHRvSGV4KHRoaXNbaV0pXG4gICAgaWYgKGkgPT09IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMpIHtcbiAgICAgIG91dFtpICsgMV0gPSAnLi4uJ1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgcmV0dXJuICc8QnVmZmVyICcgKyBvdXQuam9pbignICcpICsgJz4nXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBgQXJyYXlCdWZmZXJgIHdpdGggdGhlICpjb3BpZWQqIG1lbW9yeSBvZiB0aGUgYnVmZmVyIGluc3RhbmNlLlxuICogQWRkZWQgaW4gTm9kZSAwLjEyLiBPbmx5IGF2YWlsYWJsZSBpbiBicm93c2VycyB0aGF0IHN1cHBvcnQgQXJyYXlCdWZmZXIuXG4gKi9cbkJ1ZmZlci5wcm90b3R5cGUudG9BcnJheUJ1ZmZlciA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmIChCdWZmZXIuX3VzZVR5cGVkQXJyYXlzKSB7XG4gICAgICByZXR1cm4gKG5ldyBCdWZmZXIodGhpcykpLmJ1ZmZlclxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5sZW5ndGgpXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gYnVmLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKVxuICAgICAgICBidWZbaV0gPSB0aGlzW2ldXG4gICAgICByZXR1cm4gYnVmLmJ1ZmZlclxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0J1ZmZlci50b0FycmF5QnVmZmVyIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyJylcbiAgfVxufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbnZhciBCUCA9IEJ1ZmZlci5wcm90b3R5cGVcblxuLyoqXG4gKiBBdWdtZW50IGEgVWludDhBcnJheSAqaW5zdGFuY2UqIChub3QgdGhlIFVpbnQ4QXJyYXkgY2xhc3MhKSB3aXRoIEJ1ZmZlciBtZXRob2RzXG4gKi9cbkJ1ZmZlci5fYXVnbWVudCA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgYXJyLl9pc0J1ZmZlciA9IHRydWVcblxuICAvLyBzYXZlIHJlZmVyZW5jZSB0byBvcmlnaW5hbCBVaW50OEFycmF5IGdldC9zZXQgbWV0aG9kcyBiZWZvcmUgb3ZlcndyaXRpbmdcbiAgYXJyLl9nZXQgPSBhcnIuZ2V0XG4gIGFyci5fc2V0ID0gYXJyLnNldFxuXG4gIC8vIGRlcHJlY2F0ZWQsIHdpbGwgYmUgcmVtb3ZlZCBpbiBub2RlIDAuMTMrXG4gIGFyci5nZXQgPSBCUC5nZXRcbiAgYXJyLnNldCA9IEJQLnNldFxuXG4gIGFyci53cml0ZSA9IEJQLndyaXRlXG4gIGFyci50b1N0cmluZyA9IEJQLnRvU3RyaW5nXG4gIGFyci50b0xvY2FsZVN0cmluZyA9IEJQLnRvU3RyaW5nXG4gIGFyci50b0pTT04gPSBCUC50b0pTT05cbiAgYXJyLmNvcHkgPSBCUC5jb3B5XG4gIGFyci5zbGljZSA9IEJQLnNsaWNlXG4gIGFyci5yZWFkVUludDggPSBCUC5yZWFkVUludDhcbiAgYXJyLnJlYWRVSW50MTZMRSA9IEJQLnJlYWRVSW50MTZMRVxuICBhcnIucmVhZFVJbnQxNkJFID0gQlAucmVhZFVJbnQxNkJFXG4gIGFyci5yZWFkVUludDMyTEUgPSBCUC5yZWFkVUludDMyTEVcbiAgYXJyLnJlYWRVSW50MzJCRSA9IEJQLnJlYWRVSW50MzJCRVxuICBhcnIucmVhZEludDggPSBCUC5yZWFkSW50OFxuICBhcnIucmVhZEludDE2TEUgPSBCUC5yZWFkSW50MTZMRVxuICBhcnIucmVhZEludDE2QkUgPSBCUC5yZWFkSW50MTZCRVxuICBhcnIucmVhZEludDMyTEUgPSBCUC5yZWFkSW50MzJMRVxuICBhcnIucmVhZEludDMyQkUgPSBCUC5yZWFkSW50MzJCRVxuICBhcnIucmVhZEZsb2F0TEUgPSBCUC5yZWFkRmxvYXRMRVxuICBhcnIucmVhZEZsb2F0QkUgPSBCUC5yZWFkRmxvYXRCRVxuICBhcnIucmVhZERvdWJsZUxFID0gQlAucmVhZERvdWJsZUxFXG4gIGFyci5yZWFkRG91YmxlQkUgPSBCUC5yZWFkRG91YmxlQkVcbiAgYXJyLndyaXRlVUludDggPSBCUC53cml0ZVVJbnQ4XG4gIGFyci53cml0ZVVJbnQxNkxFID0gQlAud3JpdGVVSW50MTZMRVxuICBhcnIud3JpdGVVSW50MTZCRSA9IEJQLndyaXRlVUludDE2QkVcbiAgYXJyLndyaXRlVUludDMyTEUgPSBCUC53cml0ZVVJbnQzMkxFXG4gIGFyci53cml0ZVVJbnQzMkJFID0gQlAud3JpdGVVSW50MzJCRVxuICBhcnIud3JpdGVJbnQ4ID0gQlAud3JpdGVJbnQ4XG4gIGFyci53cml0ZUludDE2TEUgPSBCUC53cml0ZUludDE2TEVcbiAgYXJyLndyaXRlSW50MTZCRSA9IEJQLndyaXRlSW50MTZCRVxuICBhcnIud3JpdGVJbnQzMkxFID0gQlAud3JpdGVJbnQzMkxFXG4gIGFyci53cml0ZUludDMyQkUgPSBCUC53cml0ZUludDMyQkVcbiAgYXJyLndyaXRlRmxvYXRMRSA9IEJQLndyaXRlRmxvYXRMRVxuICBhcnIud3JpdGVGbG9hdEJFID0gQlAud3JpdGVGbG9hdEJFXG4gIGFyci53cml0ZURvdWJsZUxFID0gQlAud3JpdGVEb3VibGVMRVxuICBhcnIud3JpdGVEb3VibGVCRSA9IEJQLndyaXRlRG91YmxlQkVcbiAgYXJyLmZpbGwgPSBCUC5maWxsXG4gIGFyci5pbnNwZWN0ID0gQlAuaW5zcGVjdFxuICBhcnIudG9BcnJheUJ1ZmZlciA9IEJQLnRvQXJyYXlCdWZmZXJcblxuICByZXR1cm4gYXJyXG59XG5cbi8vIHNsaWNlKHN0YXJ0LCBlbmQpXG5mdW5jdGlvbiBjbGFtcCAoaW5kZXgsIGxlbiwgZGVmYXVsdFZhbHVlKSB7XG4gIGlmICh0eXBlb2YgaW5kZXggIT09ICdudW1iZXInKSByZXR1cm4gZGVmYXVsdFZhbHVlXG4gIGluZGV4ID0gfn5pbmRleDsgIC8vIENvZXJjZSB0byBpbnRlZ2VyLlxuICBpZiAoaW5kZXggPj0gbGVuKSByZXR1cm4gbGVuXG4gIGlmIChpbmRleCA+PSAwKSByZXR1cm4gaW5kZXhcbiAgaW5kZXggKz0gbGVuXG4gIGlmIChpbmRleCA+PSAwKSByZXR1cm4gaW5kZXhcbiAgcmV0dXJuIDBcbn1cblxuZnVuY3Rpb24gY29lcmNlIChsZW5ndGgpIHtcbiAgLy8gQ29lcmNlIGxlbmd0aCB0byBhIG51bWJlciAocG9zc2libHkgTmFOKSwgcm91bmQgdXBcbiAgLy8gaW4gY2FzZSBpdCdzIGZyYWN0aW9uYWwgKGUuZy4gMTIzLjQ1NikgdGhlbiBkbyBhXG4gIC8vIGRvdWJsZSBuZWdhdGUgdG8gY29lcmNlIGEgTmFOIHRvIDAuIEVhc3ksIHJpZ2h0P1xuICBsZW5ndGggPSB+fk1hdGguY2VpbCgrbGVuZ3RoKVxuICByZXR1cm4gbGVuZ3RoIDwgMCA/IDAgOiBsZW5ndGhcbn1cblxuZnVuY3Rpb24gaXNBcnJheSAoc3ViamVjdCkge1xuICByZXR1cm4gKEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKHN1YmplY3QpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN1YmplY3QpID09PSAnW29iamVjdCBBcnJheV0nXG4gIH0pKHN1YmplY3QpXG59XG5cbmZ1bmN0aW9uIGlzQXJyYXlpc2ggKHN1YmplY3QpIHtcbiAgcmV0dXJuIGlzQXJyYXkoc3ViamVjdCkgfHwgQnVmZmVyLmlzQnVmZmVyKHN1YmplY3QpIHx8XG4gICAgICBzdWJqZWN0ICYmIHR5cGVvZiBzdWJqZWN0ID09PSAnb2JqZWN0JyAmJlxuICAgICAgdHlwZW9mIHN1YmplY3QubGVuZ3RoID09PSAnbnVtYmVyJ1xufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGIgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGlmIChiIDw9IDB4N0YpXG4gICAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSlcbiAgICBlbHNlIHtcbiAgICAgIHZhciBzdGFydCA9IGlcbiAgICAgIGlmIChiID49IDB4RDgwMCAmJiBiIDw9IDB4REZGRikgaSsrXG4gICAgICB2YXIgaCA9IGVuY29kZVVSSUNvbXBvbmVudChzdHIuc2xpY2Uoc3RhcnQsIGkrMSkpLnN1YnN0cigxKS5zcGxpdCgnJScpXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGgubGVuZ3RoOyBqKyspXG4gICAgICAgIGJ5dGVBcnJheS5wdXNoKHBhcnNlSW50KGhbal0sIDE2KSlcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoc3RyKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIHBvc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKVxuICAgICAgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBkZWNvZGVVdGY4Q2hhciAoc3RyKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChzdHIpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkZGRCkgLy8gVVRGIDggaW52YWxpZCBjaGFyXG4gIH1cbn1cblxuLypcbiAqIFdlIGhhdmUgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIHZhbHVlIGlzIGEgdmFsaWQgaW50ZWdlci4gVGhpcyBtZWFucyB0aGF0IGl0XG4gKiBpcyBub24tbmVnYXRpdmUuIEl0IGhhcyBubyBmcmFjdGlvbmFsIGNvbXBvbmVudCBhbmQgdGhhdCBpdCBkb2VzIG5vdFxuICogZXhjZWVkIHRoZSBtYXhpbXVtIGFsbG93ZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIHZlcmlmdWludCAodmFsdWUsIG1heCkge1xuICBhc3NlcnQodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJywgJ2Nhbm5vdCB3cml0ZSBhIG5vbi1udW1iZXIgYXMgYSBudW1iZXInKVxuICBhc3NlcnQodmFsdWUgPj0gMCwgJ3NwZWNpZmllZCBhIG5lZ2F0aXZlIHZhbHVlIGZvciB3cml0aW5nIGFuIHVuc2lnbmVkIHZhbHVlJylcbiAgYXNzZXJ0KHZhbHVlIDw9IG1heCwgJ3ZhbHVlIGlzIGxhcmdlciB0aGFuIG1heGltdW0gdmFsdWUgZm9yIHR5cGUnKVxuICBhc3NlcnQoTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlLCAndmFsdWUgaGFzIGEgZnJhY3Rpb25hbCBjb21wb25lbnQnKVxufVxuXG5mdW5jdGlvbiB2ZXJpZnNpbnQgKHZhbHVlLCBtYXgsIG1pbikge1xuICBhc3NlcnQodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJywgJ2Nhbm5vdCB3cml0ZSBhIG5vbi1udW1iZXIgYXMgYSBudW1iZXInKVxuICBhc3NlcnQodmFsdWUgPD0gbWF4LCAndmFsdWUgbGFyZ2VyIHRoYW4gbWF4aW11bSBhbGxvd2VkIHZhbHVlJylcbiAgYXNzZXJ0KHZhbHVlID49IG1pbiwgJ3ZhbHVlIHNtYWxsZXIgdGhhbiBtaW5pbXVtIGFsbG93ZWQgdmFsdWUnKVxuICBhc3NlcnQoTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlLCAndmFsdWUgaGFzIGEgZnJhY3Rpb25hbCBjb21wb25lbnQnKVxufVxuXG5mdW5jdGlvbiB2ZXJpZklFRUU3NTQgKHZhbHVlLCBtYXgsIG1pbikge1xuICBhc3NlcnQodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJywgJ2Nhbm5vdCB3cml0ZSBhIG5vbi1udW1iZXIgYXMgYSBudW1iZXInKVxuICBhc3NlcnQodmFsdWUgPD0gbWF4LCAndmFsdWUgbGFyZ2VyIHRoYW4gbWF4aW11bSBhbGxvd2VkIHZhbHVlJylcbiAgYXNzZXJ0KHZhbHVlID49IG1pbiwgJ3ZhbHVlIHNtYWxsZXIgdGhhbiBtaW5pbXVtIGFsbG93ZWQgdmFsdWUnKVxufVxuXG5mdW5jdGlvbiBhc3NlcnQgKHRlc3QsIG1lc3NhZ2UpIHtcbiAgaWYgKCF0ZXN0KSB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSB8fCAnRmFpbGVkIGFzc2VydGlvbicpXG59XG4iLCJ2YXIgbG9va3VwID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuICB2YXIgQXJyID0gKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJylcbiAgICA/IFVpbnQ4QXJyYXlcbiAgICA6IEFycmF5XG5cblx0dmFyIFBMVVMgICA9ICcrJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSCAgPSAnLycuY2hhckNvZGVBdCgwKVxuXHR2YXIgTlVNQkVSID0gJzAnLmNoYXJDb2RlQXQoMClcblx0dmFyIExPV0VSICA9ICdhJy5jaGFyQ29kZUF0KDApXG5cdHZhciBVUFBFUiAgPSAnQScuY2hhckNvZGVBdCgwKVxuXG5cdGZ1bmN0aW9uIGRlY29kZSAoZWx0KSB7XG5cdFx0dmFyIGNvZGUgPSBlbHQuY2hhckNvZGVBdCgwKVxuXHRcdGlmIChjb2RlID09PSBQTFVTKVxuXHRcdFx0cmV0dXJuIDYyIC8vICcrJ1xuXHRcdGlmIChjb2RlID09PSBTTEFTSClcblx0XHRcdHJldHVybiA2MyAvLyAnLydcblx0XHRpZiAoY29kZSA8IE5VTUJFUilcblx0XHRcdHJldHVybiAtMSAvL25vIG1hdGNoXG5cdFx0aWYgKGNvZGUgPCBOVU1CRVIgKyAxMClcblx0XHRcdHJldHVybiBjb2RlIC0gTlVNQkVSICsgMjYgKyAyNlxuXHRcdGlmIChjb2RlIDwgVVBQRVIgKyAyNilcblx0XHRcdHJldHVybiBjb2RlIC0gVVBQRVJcblx0XHRpZiAoY29kZSA8IExPV0VSICsgMjYpXG5cdFx0XHRyZXR1cm4gY29kZSAtIExPV0VSICsgMjZcblx0fVxuXG5cdGZ1bmN0aW9uIGI2NFRvQnl0ZUFycmF5IChiNjQpIHtcblx0XHR2YXIgaSwgaiwgbCwgdG1wLCBwbGFjZUhvbGRlcnMsIGFyclxuXG5cdFx0aWYgKGI2NC5sZW5ndGggJSA0ID4gMCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0Jylcblx0XHR9XG5cblx0XHQvLyB0aGUgbnVtYmVyIG9mIGVxdWFsIHNpZ25zIChwbGFjZSBob2xkZXJzKVxuXHRcdC8vIGlmIHRoZXJlIGFyZSB0d28gcGxhY2Vob2xkZXJzLCB0aGFuIHRoZSB0d28gY2hhcmFjdGVycyBiZWZvcmUgaXRcblx0XHQvLyByZXByZXNlbnQgb25lIGJ5dGVcblx0XHQvLyBpZiB0aGVyZSBpcyBvbmx5IG9uZSwgdGhlbiB0aGUgdGhyZWUgY2hhcmFjdGVycyBiZWZvcmUgaXQgcmVwcmVzZW50IDIgYnl0ZXNcblx0XHQvLyB0aGlzIGlzIGp1c3QgYSBjaGVhcCBoYWNrIHRvIG5vdCBkbyBpbmRleE9mIHR3aWNlXG5cdFx0dmFyIGxlbiA9IGI2NC5sZW5ndGhcblx0XHRwbGFjZUhvbGRlcnMgPSAnPScgPT09IGI2NC5jaGFyQXQobGVuIC0gMikgPyAyIDogJz0nID09PSBiNjQuY2hhckF0KGxlbiAtIDEpID8gMSA6IDBcblxuXHRcdC8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuXHRcdGFyciA9IG5ldyBBcnIoYjY0Lmxlbmd0aCAqIDMgLyA0IC0gcGxhY2VIb2xkZXJzKVxuXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuXHRcdGwgPSBwbGFjZUhvbGRlcnMgPiAwID8gYjY0Lmxlbmd0aCAtIDQgOiBiNjQubGVuZ3RoXG5cblx0XHR2YXIgTCA9IDBcblxuXHRcdGZ1bmN0aW9uIHB1c2ggKHYpIHtcblx0XHRcdGFycltMKytdID0gdlxuXHRcdH1cblxuXHRcdGZvciAoaSA9IDAsIGogPSAwOyBpIDwgbDsgaSArPSA0LCBqICs9IDMpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMTgpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPDwgMTIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAyKSkgPDwgNikgfCBkZWNvZGUoYjY0LmNoYXJBdChpICsgMykpXG5cdFx0XHRwdXNoKCh0bXAgJiAweEZGMDAwMCkgPj4gMTYpXG5cdFx0XHRwdXNoKCh0bXAgJiAweEZGMDApID4+IDgpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fVxuXG5cdFx0aWYgKHBsYWNlSG9sZGVycyA9PT0gMikge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAyKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpID4+IDQpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fSBlbHNlIGlmIChwbGFjZUhvbGRlcnMgPT09IDEpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMTApIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPDwgNCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA+PiAyKVxuXHRcdFx0cHVzaCgodG1wID4+IDgpICYgMHhGRilcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9XG5cblx0XHRyZXR1cm4gYXJyXG5cdH1cblxuXHRmdW5jdGlvbiB1aW50OFRvQmFzZTY0ICh1aW50OCkge1xuXHRcdHZhciBpLFxuXHRcdFx0ZXh0cmFCeXRlcyA9IHVpbnQ4Lmxlbmd0aCAlIDMsIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG5cdFx0XHRvdXRwdXQgPSBcIlwiLFxuXHRcdFx0dGVtcCwgbGVuZ3RoXG5cblx0XHRmdW5jdGlvbiBlbmNvZGUgKG51bSkge1xuXHRcdFx0cmV0dXJuIGxvb2t1cC5jaGFyQXQobnVtKVxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG5cdFx0XHRyZXR1cm4gZW5jb2RlKG51bSA+PiAxOCAmIDB4M0YpICsgZW5jb2RlKG51bSA+PiAxMiAmIDB4M0YpICsgZW5jb2RlKG51bSA+PiA2ICYgMHgzRikgKyBlbmNvZGUobnVtICYgMHgzRilcblx0XHR9XG5cblx0XHQvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG5cdFx0Zm9yIChpID0gMCwgbGVuZ3RoID0gdWludDgubGVuZ3RoIC0gZXh0cmFCeXRlczsgaSA8IGxlbmd0aDsgaSArPSAzKSB7XG5cdFx0XHR0ZW1wID0gKHVpbnQ4W2ldIDw8IDE2KSArICh1aW50OFtpICsgMV0gPDwgOCkgKyAodWludDhbaSArIDJdKVxuXHRcdFx0b3V0cHV0ICs9IHRyaXBsZXRUb0Jhc2U2NCh0ZW1wKVxuXHRcdH1cblxuXHRcdC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcblx0XHRzd2l0Y2ggKGV4dHJhQnl0ZXMpIHtcblx0XHRcdGNhc2UgMTpcblx0XHRcdFx0dGVtcCA9IHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUodGVtcCA+PiAyKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wIDw8IDQpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9ICc9PSdcblx0XHRcdFx0YnJlYWtcblx0XHRcdGNhc2UgMjpcblx0XHRcdFx0dGVtcCA9ICh1aW50OFt1aW50OC5sZW5ndGggLSAyXSA8PCA4KSArICh1aW50OFt1aW50OC5sZW5ndGggLSAxXSlcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSh0ZW1wID4+IDEwKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wID4+IDQpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA8PCAyKSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSAnPSdcblx0XHRcdFx0YnJlYWtcblx0XHR9XG5cblx0XHRyZXR1cm4gb3V0cHV0XG5cdH1cblxuXHRleHBvcnRzLnRvQnl0ZUFycmF5ID0gYjY0VG9CeXRlQXJyYXlcblx0ZXhwb3J0cy5mcm9tQnl0ZUFycmF5ID0gdWludDhUb0Jhc2U2NFxufSh0eXBlb2YgZXhwb3J0cyA9PT0gJ3VuZGVmaW5lZCcgPyAodGhpcy5iYXNlNjRqcyA9IHt9KSA6IGV4cG9ydHMpKVxuIiwiZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24oYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSxcbiAgICAgIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDEsXG4gICAgICBlTWF4ID0gKDEgPDwgZUxlbikgLSAxLFxuICAgICAgZUJpYXMgPSBlTWF4ID4+IDEsXG4gICAgICBuQml0cyA9IC03LFxuICAgICAgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwLFxuICAgICAgZCA9IGlzTEUgPyAtMSA6IDEsXG4gICAgICBzID0gYnVmZmVyW29mZnNldCArIGldO1xuXG4gIGkgKz0gZDtcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKTtcbiAgcyA+Pj0gKC1uQml0cyk7XG4gIG5CaXRzICs9IGVMZW47XG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpO1xuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpO1xuICBlID4+PSAoLW5CaXRzKTtcbiAgbkJpdHMgKz0gbUxlbjtcbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCk7XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzO1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSk7XG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKTtcbiAgICBlID0gZSAtIGVCaWFzO1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pO1xufTtcblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjLFxuICAgICAgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMSxcbiAgICAgIGVNYXggPSAoMSA8PCBlTGVuKSAtIDEsXG4gICAgICBlQmlhcyA9IGVNYXggPj4gMSxcbiAgICAgIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKSxcbiAgICAgIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKSxcbiAgICAgIGQgPSBpc0xFID8gMSA6IC0xLFxuICAgICAgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMDtcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKTtcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMDtcbiAgICBlID0gZU1heDtcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMik7XG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tO1xuICAgICAgYyAqPSAyO1xuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gYztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrKztcbiAgICAgIGMgLz0gMjtcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwO1xuICAgICAgZSA9IGVNYXg7XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IGUgKyBlQmlhcztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IDA7XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCk7XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbTtcbiAgZUxlbiArPSBtTGVuO1xuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpO1xuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyODtcbn07XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIihmdW5jdGlvbiAocHJvY2Vzcyl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gcmVzb2x2ZXMgLiBhbmQgLi4gZWxlbWVudHMgaW4gYSBwYXRoIGFycmF5IHdpdGggZGlyZWN0b3J5IG5hbWVzIHRoZXJlXG4vLyBtdXN0IGJlIG5vIHNsYXNoZXMsIGVtcHR5IGVsZW1lbnRzLCBvciBkZXZpY2UgbmFtZXMgKGM6XFwpIGluIHRoZSBhcnJheVxuLy8gKHNvIGFsc28gbm8gbGVhZGluZyBhbmQgdHJhaWxpbmcgc2xhc2hlcyAtIGl0IGRvZXMgbm90IGRpc3Rpbmd1aXNoXG4vLyByZWxhdGl2ZSBhbmQgYWJzb2x1dGUgcGF0aHMpXG5mdW5jdGlvbiBub3JtYWxpemVBcnJheShwYXJ0cywgYWxsb3dBYm92ZVJvb3QpIHtcbiAgLy8gaWYgdGhlIHBhdGggdHJpZXMgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIGB1cGAgZW5kcyB1cCA+IDBcbiAgdmFyIHVwID0gMDtcbiAgZm9yICh2YXIgaSA9IHBhcnRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgdmFyIGxhc3QgPSBwYXJ0c1tpXTtcbiAgICBpZiAobGFzdCA9PT0gJy4nKSB7XG4gICAgICBwYXJ0cy5zcGxpY2UoaSwgMSk7XG4gICAgfSBlbHNlIGlmIChsYXN0ID09PSAnLi4nKSB7XG4gICAgICBwYXJ0cy5zcGxpY2UoaSwgMSk7XG4gICAgICB1cCsrO1xuICAgIH0gZWxzZSBpZiAodXApIHtcbiAgICAgIHBhcnRzLnNwbGljZShpLCAxKTtcbiAgICAgIHVwLS07XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlIHBhdGggaXMgYWxsb3dlZCB0byBnbyBhYm92ZSB0aGUgcm9vdCwgcmVzdG9yZSBsZWFkaW5nIC4uc1xuICBpZiAoYWxsb3dBYm92ZVJvb3QpIHtcbiAgICBmb3IgKDsgdXAtLTsgdXApIHtcbiAgICAgIHBhcnRzLnVuc2hpZnQoJy4uJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBhcnRzO1xufVxuXG4vLyBTcGxpdCBhIGZpbGVuYW1lIGludG8gW3Jvb3QsIGRpciwgYmFzZW5hbWUsIGV4dF0sIHVuaXggdmVyc2lvblxuLy8gJ3Jvb3QnIGlzIGp1c3QgYSBzbGFzaCwgb3Igbm90aGluZy5cbnZhciBzcGxpdFBhdGhSZSA9XG4gICAgL14oXFwvP3wpKFtcXHNcXFNdKj8pKCg/OlxcLnsxLDJ9fFteXFwvXSs/fCkoXFwuW14uXFwvXSp8KSkoPzpbXFwvXSopJC87XG52YXIgc3BsaXRQYXRoID0gZnVuY3Rpb24oZmlsZW5hbWUpIHtcbiAgcmV0dXJuIHNwbGl0UGF0aFJlLmV4ZWMoZmlsZW5hbWUpLnNsaWNlKDEpO1xufTtcblxuLy8gcGF0aC5yZXNvbHZlKFtmcm9tIC4uLl0sIHRvKVxuLy8gcG9zaXggdmVyc2lvblxuZXhwb3J0cy5yZXNvbHZlID0gZnVuY3Rpb24oKSB7XG4gIHZhciByZXNvbHZlZFBhdGggPSAnJyxcbiAgICAgIHJlc29sdmVkQWJzb2x1dGUgPSBmYWxzZTtcblxuICBmb3IgKHZhciBpID0gYXJndW1lbnRzLmxlbmd0aCAtIDE7IGkgPj0gLTEgJiYgIXJlc29sdmVkQWJzb2x1dGU7IGktLSkge1xuICAgIHZhciBwYXRoID0gKGkgPj0gMCkgPyBhcmd1bWVudHNbaV0gOiBwcm9jZXNzLmN3ZCgpO1xuXG4gICAgLy8gU2tpcCBlbXB0eSBhbmQgaW52YWxpZCBlbnRyaWVzXG4gICAgaWYgKHR5cGVvZiBwYXRoICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnRzIHRvIHBhdGgucmVzb2x2ZSBtdXN0IGJlIHN0cmluZ3MnKTtcbiAgICB9IGVsc2UgaWYgKCFwYXRoKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICByZXNvbHZlZFBhdGggPSBwYXRoICsgJy8nICsgcmVzb2x2ZWRQYXRoO1xuICAgIHJlc29sdmVkQWJzb2x1dGUgPSBwYXRoLmNoYXJBdCgwKSA9PT0gJy8nO1xuICB9XG5cbiAgLy8gQXQgdGhpcyBwb2ludCB0aGUgcGF0aCBzaG91bGQgYmUgcmVzb2x2ZWQgdG8gYSBmdWxsIGFic29sdXRlIHBhdGgsIGJ1dFxuICAvLyBoYW5kbGUgcmVsYXRpdmUgcGF0aHMgdG8gYmUgc2FmZSAobWlnaHQgaGFwcGVuIHdoZW4gcHJvY2Vzcy5jd2QoKSBmYWlscylcblxuICAvLyBOb3JtYWxpemUgdGhlIHBhdGhcbiAgcmVzb2x2ZWRQYXRoID0gbm9ybWFsaXplQXJyYXkoZmlsdGVyKHJlc29sdmVkUGF0aC5zcGxpdCgnLycpLCBmdW5jdGlvbihwKSB7XG4gICAgcmV0dXJuICEhcDtcbiAgfSksICFyZXNvbHZlZEFic29sdXRlKS5qb2luKCcvJyk7XG5cbiAgcmV0dXJuICgocmVzb2x2ZWRBYnNvbHV0ZSA/ICcvJyA6ICcnKSArIHJlc29sdmVkUGF0aCkgfHwgJy4nO1xufTtcblxuLy8gcGF0aC5ub3JtYWxpemUocGF0aClcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMubm9ybWFsaXplID0gZnVuY3Rpb24ocGF0aCkge1xuICB2YXIgaXNBYnNvbHV0ZSA9IGV4cG9ydHMuaXNBYnNvbHV0ZShwYXRoKSxcbiAgICAgIHRyYWlsaW5nU2xhc2ggPSBzdWJzdHIocGF0aCwgLTEpID09PSAnLyc7XG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHBhdGggPSBub3JtYWxpemVBcnJheShmaWx0ZXIocGF0aC5zcGxpdCgnLycpLCBmdW5jdGlvbihwKSB7XG4gICAgcmV0dXJuICEhcDtcbiAgfSksICFpc0Fic29sdXRlKS5qb2luKCcvJyk7XG5cbiAgaWYgKCFwYXRoICYmICFpc0Fic29sdXRlKSB7XG4gICAgcGF0aCA9ICcuJztcbiAgfVxuICBpZiAocGF0aCAmJiB0cmFpbGluZ1NsYXNoKSB7XG4gICAgcGF0aCArPSAnLyc7XG4gIH1cblxuICByZXR1cm4gKGlzQWJzb2x1dGUgPyAnLycgOiAnJykgKyBwYXRoO1xufTtcblxuLy8gcG9zaXggdmVyc2lvblxuZXhwb3J0cy5pc0Fic29sdXRlID0gZnVuY3Rpb24ocGF0aCkge1xuICByZXR1cm4gcGF0aC5jaGFyQXQoMCkgPT09ICcvJztcbn07XG5cbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMuam9pbiA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcGF0aHMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuICByZXR1cm4gZXhwb3J0cy5ub3JtYWxpemUoZmlsdGVyKHBhdGhzLCBmdW5jdGlvbihwLCBpbmRleCkge1xuICAgIGlmICh0eXBlb2YgcCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyB0byBwYXRoLmpvaW4gbXVzdCBiZSBzdHJpbmdzJyk7XG4gICAgfVxuICAgIHJldHVybiBwO1xuICB9KS5qb2luKCcvJykpO1xufTtcblxuXG4vLyBwYXRoLnJlbGF0aXZlKGZyb20sIHRvKVxuLy8gcG9zaXggdmVyc2lvblxuZXhwb3J0cy5yZWxhdGl2ZSA9IGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gIGZyb20gPSBleHBvcnRzLnJlc29sdmUoZnJvbSkuc3Vic3RyKDEpO1xuICB0byA9IGV4cG9ydHMucmVzb2x2ZSh0bykuc3Vic3RyKDEpO1xuXG4gIGZ1bmN0aW9uIHRyaW0oYXJyKSB7XG4gICAgdmFyIHN0YXJ0ID0gMDtcbiAgICBmb3IgKDsgc3RhcnQgPCBhcnIubGVuZ3RoOyBzdGFydCsrKSB7XG4gICAgICBpZiAoYXJyW3N0YXJ0XSAhPT0gJycpIGJyZWFrO1xuICAgIH1cblxuICAgIHZhciBlbmQgPSBhcnIubGVuZ3RoIC0gMTtcbiAgICBmb3IgKDsgZW5kID49IDA7IGVuZC0tKSB7XG4gICAgICBpZiAoYXJyW2VuZF0gIT09ICcnKSBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoc3RhcnQgPiBlbmQpIHJldHVybiBbXTtcbiAgICByZXR1cm4gYXJyLnNsaWNlKHN0YXJ0LCBlbmQgLSBzdGFydCArIDEpO1xuICB9XG5cbiAgdmFyIGZyb21QYXJ0cyA9IHRyaW0oZnJvbS5zcGxpdCgnLycpKTtcbiAgdmFyIHRvUGFydHMgPSB0cmltKHRvLnNwbGl0KCcvJykpO1xuXG4gIHZhciBsZW5ndGggPSBNYXRoLm1pbihmcm9tUGFydHMubGVuZ3RoLCB0b1BhcnRzLmxlbmd0aCk7XG4gIHZhciBzYW1lUGFydHNMZW5ndGggPSBsZW5ndGg7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoZnJvbVBhcnRzW2ldICE9PSB0b1BhcnRzW2ldKSB7XG4gICAgICBzYW1lUGFydHNMZW5ndGggPSBpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgdmFyIG91dHB1dFBhcnRzID0gW107XG4gIGZvciAodmFyIGkgPSBzYW1lUGFydHNMZW5ndGg7IGkgPCBmcm9tUGFydHMubGVuZ3RoOyBpKyspIHtcbiAgICBvdXRwdXRQYXJ0cy5wdXNoKCcuLicpO1xuICB9XG5cbiAgb3V0cHV0UGFydHMgPSBvdXRwdXRQYXJ0cy5jb25jYXQodG9QYXJ0cy5zbGljZShzYW1lUGFydHNMZW5ndGgpKTtcblxuICByZXR1cm4gb3V0cHV0UGFydHMuam9pbignLycpO1xufTtcblxuZXhwb3J0cy5zZXAgPSAnLyc7XG5leHBvcnRzLmRlbGltaXRlciA9ICc6JztcblxuZXhwb3J0cy5kaXJuYW1lID0gZnVuY3Rpb24ocGF0aCkge1xuICB2YXIgcmVzdWx0ID0gc3BsaXRQYXRoKHBhdGgpLFxuICAgICAgcm9vdCA9IHJlc3VsdFswXSxcbiAgICAgIGRpciA9IHJlc3VsdFsxXTtcblxuICBpZiAoIXJvb3QgJiYgIWRpcikge1xuICAgIC8vIE5vIGRpcm5hbWUgd2hhdHNvZXZlclxuICAgIHJldHVybiAnLic7XG4gIH1cblxuICBpZiAoZGlyKSB7XG4gICAgLy8gSXQgaGFzIGEgZGlybmFtZSwgc3RyaXAgdHJhaWxpbmcgc2xhc2hcbiAgICBkaXIgPSBkaXIuc3Vic3RyKDAsIGRpci5sZW5ndGggLSAxKTtcbiAgfVxuXG4gIHJldHVybiByb290ICsgZGlyO1xufTtcblxuXG5leHBvcnRzLmJhc2VuYW1lID0gZnVuY3Rpb24ocGF0aCwgZXh0KSB7XG4gIHZhciBmID0gc3BsaXRQYXRoKHBhdGgpWzJdO1xuICAvLyBUT0RPOiBtYWtlIHRoaXMgY29tcGFyaXNvbiBjYXNlLWluc2Vuc2l0aXZlIG9uIHdpbmRvd3M/XG4gIGlmIChleHQgJiYgZi5zdWJzdHIoLTEgKiBleHQubGVuZ3RoKSA9PT0gZXh0KSB7XG4gICAgZiA9IGYuc3Vic3RyKDAsIGYubGVuZ3RoIC0gZXh0Lmxlbmd0aCk7XG4gIH1cbiAgcmV0dXJuIGY7XG59O1xuXG5cbmV4cG9ydHMuZXh0bmFtZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgcmV0dXJuIHNwbGl0UGF0aChwYXRoKVszXTtcbn07XG5cbmZ1bmN0aW9uIGZpbHRlciAoeHMsIGYpIHtcbiAgICBpZiAoeHMuZmlsdGVyKSByZXR1cm4geHMuZmlsdGVyKGYpO1xuICAgIHZhciByZXMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChmKHhzW2ldLCBpLCB4cykpIHJlcy5wdXNoKHhzW2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn1cblxuLy8gU3RyaW5nLnByb3RvdHlwZS5zdWJzdHIgLSBuZWdhdGl2ZSBpbmRleCBkb24ndCB3b3JrIGluIElFOFxudmFyIHN1YnN0ciA9ICdhYicuc3Vic3RyKC0xKSA9PT0gJ2InXG4gICAgPyBmdW5jdGlvbiAoc3RyLCBzdGFydCwgbGVuKSB7IHJldHVybiBzdHIuc3Vic3RyKHN0YXJ0LCBsZW4pIH1cbiAgICA6IGZ1bmN0aW9uIChzdHIsIHN0YXJ0LCBsZW4pIHtcbiAgICAgICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSBzdHIubGVuZ3RoICsgc3RhcnQ7XG4gICAgICAgIHJldHVybiBzdHIuc3Vic3RyKHN0YXJ0LCBsZW4pO1xuICAgIH1cbjtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCIxWWlaNVNcIikpIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxucHJvY2Vzcy5uZXh0VGljayA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNhblNldEltbWVkaWF0ZSA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnNldEltbWVkaWF0ZTtcbiAgICB2YXIgY2FuUG9zdCA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnBvc3RNZXNzYWdlICYmIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyXG4gICAgO1xuXG4gICAgaWYgKGNhblNldEltbWVkaWF0ZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGYpIHsgcmV0dXJuIHdpbmRvdy5zZXRJbW1lZGlhdGUoZikgfTtcbiAgICB9XG5cbiAgICBpZiAoY2FuUG9zdCkge1xuICAgICAgICB2YXIgcXVldWUgPSBbXTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciBzb3VyY2UgPSBldi5zb3VyY2U7XG4gICAgICAgICAgICBpZiAoKHNvdXJjZSA9PT0gd2luZG93IHx8IHNvdXJjZSA9PT0gbnVsbCkgJiYgZXYuZGF0YSA9PT0gJ3Byb2Nlc3MtdGljaycpIHtcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICBpZiAocXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm4gPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdHJ1ZSk7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgICAgICBxdWV1ZS5wdXNoKGZuKTtcbiAgICAgICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgncHJvY2Vzcy10aWNrJywgJyonKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dFRpY2soZm4pIHtcbiAgICAgICAgc2V0VGltZW91dChmbiwgMCk7XG4gICAgfTtcbn0pKCk7XG5cbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufVxuXG4vLyBUT0RPKHNodHlsbWFuKVxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzQnVmZmVyKGFyZykge1xuICByZXR1cm4gYXJnICYmIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnXG4gICAgJiYgdHlwZW9mIGFyZy5jb3B5ID09PSAnZnVuY3Rpb24nXG4gICAgJiYgdHlwZW9mIGFyZy5maWxsID09PSAnZnVuY3Rpb24nXG4gICAgJiYgdHlwZW9mIGFyZy5yZWFkVUludDggPT09ICdmdW5jdGlvbic7XG59IiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIGZvcm1hdFJlZ0V4cCA9IC8lW3NkaiVdL2c7XG5leHBvcnRzLmZvcm1hdCA9IGZ1bmN0aW9uKGYpIHtcbiAgaWYgKCFpc1N0cmluZyhmKSkge1xuICAgIHZhciBvYmplY3RzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9iamVjdHMucHVzaChpbnNwZWN0KGFyZ3VtZW50c1tpXSkpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0cy5qb2luKCcgJyk7XG4gIH1cblxuICB2YXIgaSA9IDE7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICB2YXIgbGVuID0gYXJncy5sZW5ndGg7XG4gIHZhciBzdHIgPSBTdHJpbmcoZikucmVwbGFjZShmb3JtYXRSZWdFeHAsIGZ1bmN0aW9uKHgpIHtcbiAgICBpZiAoeCA9PT0gJyUlJykgcmV0dXJuICclJztcbiAgICBpZiAoaSA+PSBsZW4pIHJldHVybiB4O1xuICAgIHN3aXRjaCAoeCkge1xuICAgICAgY2FzZSAnJXMnOiByZXR1cm4gU3RyaW5nKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclZCc6IHJldHVybiBOdW1iZXIoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVqJzpcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJnc1tpKytdKTtcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB4O1xuICAgIH1cbiAgfSk7XG4gIGZvciAodmFyIHggPSBhcmdzW2ldOyBpIDwgbGVuOyB4ID0gYXJnc1srK2ldKSB7XG4gICAgaWYgKGlzTnVsbCh4KSB8fCAhaXNPYmplY3QoeCkpIHtcbiAgICAgIHN0ciArPSAnICcgKyB4O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJyAnICsgaW5zcGVjdCh4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn07XG5cblxuLy8gTWFyayB0aGF0IGEgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZC5cbi8vIFJldHVybnMgYSBtb2RpZmllZCBmdW5jdGlvbiB3aGljaCB3YXJucyBvbmNlIGJ5IGRlZmF1bHQuXG4vLyBJZiAtLW5vLWRlcHJlY2F0aW9uIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuZXhwb3J0cy5kZXByZWNhdGUgPSBmdW5jdGlvbihmbiwgbXNnKSB7XG4gIC8vIEFsbG93IGZvciBkZXByZWNhdGluZyB0aGluZ3MgaW4gdGhlIHByb2Nlc3Mgb2Ygc3RhcnRpbmcgdXAuXG4gIGlmIChpc1VuZGVmaW5lZChnbG9iYWwucHJvY2VzcykpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZXhwb3J0cy5kZXByZWNhdGUoZm4sIG1zZykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKHByb2Nlc3Mubm9EZXByZWNhdGlvbiA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gZGVwcmVjYXRlZCgpIHtcbiAgICBpZiAoIXdhcm5lZCkge1xuICAgICAgaWYgKHByb2Nlc3MudGhyb3dEZXByZWNhdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy50cmFjZURlcHJlY2F0aW9uKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobXNnKTtcbiAgICAgIH1cbiAgICAgIHdhcm5lZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgcmV0dXJuIGRlcHJlY2F0ZWQ7XG59O1xuXG5cbnZhciBkZWJ1Z3MgPSB7fTtcbnZhciBkZWJ1Z0Vudmlyb247XG5leHBvcnRzLmRlYnVnbG9nID0gZnVuY3Rpb24oc2V0KSB7XG4gIGlmIChpc1VuZGVmaW5lZChkZWJ1Z0Vudmlyb24pKVxuICAgIGRlYnVnRW52aXJvbiA9IHByb2Nlc3MuZW52Lk5PREVfREVCVUcgfHwgJyc7XG4gIHNldCA9IHNldC50b1VwcGVyQ2FzZSgpO1xuICBpZiAoIWRlYnVnc1tzZXRdKSB7XG4gICAgaWYgKG5ldyBSZWdFeHAoJ1xcXFxiJyArIHNldCArICdcXFxcYicsICdpJykudGVzdChkZWJ1Z0Vudmlyb24pKSB7XG4gICAgICB2YXIgcGlkID0gcHJvY2Vzcy5waWQ7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbXNnID0gZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignJXMgJWQ6ICVzJywgc2V0LCBwaWQsIG1zZyk7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge307XG4gICAgfVxuICB9XG4gIHJldHVybiBkZWJ1Z3Nbc2V0XTtcbn07XG5cblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QgdGhhdCBhbHRlcnMgdGhlIG91dHB1dC5cbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIGV4cG9ydHMuX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cbmV4cG9ydHMuaW5zcGVjdCA9IGluc3BlY3Q7XG5cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc3R5bGl6ZU5vQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgcmV0dXJuIHN0cjtcbn1cblxuXG5mdW5jdGlvbiBhcnJheVRvSGFzaChhcnJheSkge1xuICB2YXIgaGFzaCA9IHt9O1xuXG4gIGFycmF5LmZvckVhY2goZnVuY3Rpb24odmFsLCBpZHgpIHtcbiAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuICB9KTtcblxuICByZXR1cm4gaGFzaDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKGN0eC5jdXN0b21JbnNwZWN0ICYmXG4gICAgICB2YWx1ZSAmJlxuICAgICAgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBleHBvcnRzLmluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcywgY3R4KTtcbiAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICB2YXIgdmlzaWJsZUtleXMgPSBhcnJheVRvSGFzaChrZXlzKTtcblxuICBpZiAoY3R4LnNob3dIaWRkZW4pIHtcbiAgICBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gSUUgZG9lc24ndCBtYWtlIGVycm9yIGZpZWxkcyBub24tZW51bWVyYWJsZVxuICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvZHd3NTJzYnQodj12cy45NCkuYXNweFxuICBpZiAoaXNFcnJvcih2YWx1ZSlcbiAgICAgICYmIChrZXlzLmluZGV4T2YoJ21lc3NhZ2UnKSA+PSAwIHx8IGtleXMuaW5kZXhPZignZGVzY3JpcHRpb24nKSA+PSAwKSkge1xuICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgdmFyIG5hbWUgPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW0Z1bmN0aW9uJyArIG5hbWUgKyAnXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfVxuICAgIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdkYXRlJyk7XG4gICAgfVxuICAgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgYmFzZSA9ICcnLCBhcnJheSA9IGZhbHNlLCBicmFjZXMgPSBbJ3snLCAnfSddO1xuXG4gIC8vIE1ha2UgQXJyYXkgc2F5IHRoYXQgdGhleSBhcmUgQXJyYXlcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgYXJyYXkgPSB0cnVlO1xuICAgIGJyYWNlcyA9IFsnWycsICddJ107XG4gIH1cblxuICAvLyBNYWtlIGZ1bmN0aW9ucyBzYXkgdGhhdCB0aGV5IGFyZSBmdW5jdGlvbnNcbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgdmFyIG4gPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICBiYXNlID0gJyBbRnVuY3Rpb24nICsgbiArICddJztcbiAgfVxuXG4gIC8vIE1ha2UgUmVnRXhwcyBzYXkgdGhhdCB0aGV5IGFyZSBSZWdFeHBzXG4gIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZGF0ZXMgd2l0aCBwcm9wZXJ0aWVzIGZpcnN0IHNheSB0aGUgZGF0ZVxuICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZXJyb3Igd2l0aCBtZXNzYWdlIGZpcnN0IHNheSB0aGUgZXJyb3JcbiAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCAmJiAoIWFycmF5IHx8IHZhbHVlLmxlbmd0aCA9PSAwKSkge1xuICAgIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgYnJhY2VzWzFdO1xuICB9XG5cbiAgaWYgKHJlY3Vyc2VUaW1lcyA8IDApIHtcbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tPYmplY3RdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cblxuICBjdHguc2Vlbi5wdXNoKHZhbHVlKTtcblxuICB2YXIgb3V0cHV0O1xuICBpZiAoYXJyYXkpIHtcbiAgICBvdXRwdXQgPSBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRwdXQgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgIHJldHVybiBjdHguc3R5bGl6ZShzaW1wbGUsICdzdHJpbmcnKTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG4gIGlmIChpc0Jvb2xlYW4odmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmIChpc051bGwodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IodmFsdWUpIHtcbiAgcmV0dXJuICdbJyArIEVycm9yLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSArICddJztcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKSB7XG4gIHZhciBvdXRwdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkodmFsdWUsIFN0cmluZyhpKSkpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAgU3RyaW5nKGkpLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0ciwgZGVzYztcbiAgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSkgfHwgeyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoZGVzYy5nZXQpIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmICghaGFzT3duUHJvcGVydHkodmlzaWJsZUtleXMsIGtleSkpIHtcbiAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuICB9XG4gIGlmICghc3RyKSB7XG4gICAgaWYgKGN0eC5zZWVuLmluZGV4T2YoZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cblxuZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcbiAgdmFyIG51bUxpbmVzRXN0ID0gMDtcbiAgdmFyIGxlbmd0aCA9IG91dHB1dC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuICB9LCAwKTtcblxuICBpZiAobGVuZ3RoID4gNjApIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICtcbiAgICAgICAgICAgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIG91dHB1dC5qb2luKCcsXFxuICAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIGJyYWNlc1sxXTtcbiAgfVxuXG4gIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgJyAnICsgb3V0cHV0LmpvaW4oJywgJykgKyAnICcgKyBicmFjZXNbMV07XG59XG5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cbmZ1bmN0aW9uIGlzQXJyYXkoYXIpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXIpO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gaXNPYmplY3QoZCkgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGUpICYmXG4gICAgICAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmV4cG9ydHMuaXNCdWZmZXIgPSByZXF1aXJlKCcuL3N1cHBvcnQvaXNCdWZmZXInKTtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuXG5cbmZ1bmN0aW9uIHBhZChuKSB7XG4gIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuLnRvU3RyaW5nKDEwKSA6IG4udG9TdHJpbmcoMTApO1xufVxuXG5cbnZhciBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJyxcbiAgICAgICAgICAgICAgJ09jdCcsICdOb3YnLCAnRGVjJ107XG5cbi8vIDI2IEZlYiAxNjoxOTozNFxuZnVuY3Rpb24gdGltZXN0YW1wKCkge1xuICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gIHZhciB0aW1lID0gW3BhZChkLmdldEhvdXJzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRNaW51dGVzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRTZWNvbmRzKCkpXS5qb2luKCc6Jyk7XG4gIHJldHVybiBbZC5nZXREYXRlKCksIG1vbnRoc1tkLmdldE1vbnRoKCldLCB0aW1lXS5qb2luKCcgJyk7XG59XG5cblxuLy8gbG9nIGlzIGp1c3QgYSB0aGluIHdyYXBwZXIgdG8gY29uc29sZS5sb2cgdGhhdCBwcmVwZW5kcyBhIHRpbWVzdGFtcFxuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgY29uc29sZS5sb2coJyVzIC0gJXMnLCB0aW1lc3RhbXAoKSwgZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKSk7XG59O1xuXG5cbi8qKlxuICogSW5oZXJpdCB0aGUgcHJvdG90eXBlIG1ldGhvZHMgZnJvbSBvbmUgY29uc3RydWN0b3IgaW50byBhbm90aGVyLlxuICpcbiAqIFRoZSBGdW5jdGlvbi5wcm90b3R5cGUuaW5oZXJpdHMgZnJvbSBsYW5nLmpzIHJld3JpdHRlbiBhcyBhIHN0YW5kYWxvbmVcbiAqIGZ1bmN0aW9uIChub3Qgb24gRnVuY3Rpb24ucHJvdG90eXBlKS4gTk9URTogSWYgdGhpcyBmaWxlIGlzIHRvIGJlIGxvYWRlZFxuICogZHVyaW5nIGJvb3RzdHJhcHBpbmcgdGhpcyBmdW5jdGlvbiBuZWVkcyB0byBiZSByZXdyaXR0ZW4gdXNpbmcgc29tZSBuYXRpdmVcbiAqIGZ1bmN0aW9ucyBhcyBwcm90b3R5cGUgc2V0dXAgdXNpbmcgbm9ybWFsIEphdmFTY3JpcHQgZG9lcyBub3Qgd29yayBhc1xuICogZXhwZWN0ZWQgZHVyaW5nIGJvb3RzdHJhcHBpbmcgKHNlZSBtaXJyb3IuanMgaW4gcjExNDkwMykuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB3aGljaCBuZWVkcyB0byBpbmhlcml0IHRoZVxuICogICAgIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB0byBpbmhlcml0IHByb3RvdHlwZSBmcm9tLlxuICovXG5leHBvcnRzLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZXhwb3J0cy5fZXh0ZW5kID0gZnVuY3Rpb24ob3JpZ2luLCBhZGQpIHtcbiAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGFkZCk7XG4gIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBvcmlnaW5ba2V5c1tpXV0gPSBhZGRba2V5c1tpXV07XG4gIH1cbiAgcmV0dXJuIG9yaWdpbjtcbn07XG5cbmZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwiMVlpWjVTXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSkiLCJ2YXIgaW5kZXhPZiA9IHJlcXVpcmUoJ2luZGV4b2YnKTtcblxudmFyIE9iamVjdF9rZXlzID0gZnVuY3Rpb24gKG9iaikge1xuICAgIGlmIChPYmplY3Qua2V5cykgcmV0dXJuIE9iamVjdC5rZXlzKG9iailcbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIHJlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSByZXMucHVzaChrZXkpXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxufTtcblxudmFyIGZvckVhY2ggPSBmdW5jdGlvbiAoeHMsIGZuKSB7XG4gICAgaWYgKHhzLmZvckVhY2gpIHJldHVybiB4cy5mb3JFYWNoKGZuKVxuICAgIGVsc2UgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBmbih4c1tpXSwgaSwgeHMpO1xuICAgIH1cbn07XG5cbnZhciBkZWZpbmVQcm9wID0gKGZ1bmN0aW9uKCkge1xuICAgIHRyeSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgJ18nLCB7fSk7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihvYmosIG5hbWUsIHZhbHVlKSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBuYW1lLCB7XG4gICAgICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfTtcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iaiwgbmFtZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIG9ialtuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cbn0oKSk7XG5cbnZhciBnbG9iYWxzID0gWydBcnJheScsICdCb29sZWFuJywgJ0RhdGUnLCAnRXJyb3InLCAnRXZhbEVycm9yJywgJ0Z1bmN0aW9uJyxcbidJbmZpbml0eScsICdKU09OJywgJ01hdGgnLCAnTmFOJywgJ051bWJlcicsICdPYmplY3QnLCAnUmFuZ2VFcnJvcicsXG4nUmVmZXJlbmNlRXJyb3InLCAnUmVnRXhwJywgJ1N0cmluZycsICdTeW50YXhFcnJvcicsICdUeXBlRXJyb3InLCAnVVJJRXJyb3InLFxuJ2RlY29kZVVSSScsICdkZWNvZGVVUklDb21wb25lbnQnLCAnZW5jb2RlVVJJJywgJ2VuY29kZVVSSUNvbXBvbmVudCcsICdlc2NhcGUnLFxuJ2V2YWwnLCAnaXNGaW5pdGUnLCAnaXNOYU4nLCAncGFyc2VGbG9hdCcsICdwYXJzZUludCcsICd1bmRlZmluZWQnLCAndW5lc2NhcGUnXTtcblxuZnVuY3Rpb24gQ29udGV4dCgpIHt9XG5Db250ZXh0LnByb3RvdHlwZSA9IHt9O1xuXG52YXIgU2NyaXB0ID0gZXhwb3J0cy5TY3JpcHQgPSBmdW5jdGlvbiBOb2RlU2NyaXB0IChjb2RlKSB7XG4gICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNjcmlwdCkpIHJldHVybiBuZXcgU2NyaXB0KGNvZGUpO1xuICAgIHRoaXMuY29kZSA9IGNvZGU7XG59O1xuXG5TY3JpcHQucHJvdG90eXBlLnJ1bkluQ29udGV4dCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgaWYgKCEoY29udGV4dCBpbnN0YW5jZW9mIENvbnRleHQpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJuZWVkcyBhICdjb250ZXh0JyBhcmd1bWVudC5cIik7XG4gICAgfVxuICAgIFxuICAgIHZhciBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBpZiAoIWlmcmFtZS5zdHlsZSkgaWZyYW1lLnN0eWxlID0ge307XG4gICAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgXG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICAgIFxuICAgIHZhciB3aW4gPSBpZnJhbWUuY29udGVudFdpbmRvdztcbiAgICB2YXIgd0V2YWwgPSB3aW4uZXZhbCwgd0V4ZWNTY3JpcHQgPSB3aW4uZXhlY1NjcmlwdDtcblxuICAgIGlmICghd0V2YWwgJiYgd0V4ZWNTY3JpcHQpIHtcbiAgICAgICAgLy8gd2luLmV2YWwoKSBtYWdpY2FsbHkgYXBwZWFycyB3aGVuIHRoaXMgaXMgY2FsbGVkIGluIElFOlxuICAgICAgICB3RXhlY1NjcmlwdC5jYWxsKHdpbiwgJ251bGwnKTtcbiAgICAgICAgd0V2YWwgPSB3aW4uZXZhbDtcbiAgICB9XG4gICAgXG4gICAgZm9yRWFjaChPYmplY3Rfa2V5cyhjb250ZXh0KSwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB3aW5ba2V5XSA9IGNvbnRleHRba2V5XTtcbiAgICB9KTtcbiAgICBmb3JFYWNoKGdsb2JhbHMsIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKGNvbnRleHRba2V5XSkge1xuICAgICAgICAgICAgd2luW2tleV0gPSBjb250ZXh0W2tleV07XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICB2YXIgd2luS2V5cyA9IE9iamVjdF9rZXlzKHdpbik7XG5cbiAgICB2YXIgcmVzID0gd0V2YWwuY2FsbCh3aW4sIHRoaXMuY29kZSk7XG4gICAgXG4gICAgZm9yRWFjaChPYmplY3Rfa2V5cyh3aW4pLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIC8vIEF2b2lkIGNvcHlpbmcgY2lyY3VsYXIgb2JqZWN0cyBsaWtlIGB0b3BgIGFuZCBgd2luZG93YCBieSBvbmx5XG4gICAgICAgIC8vIHVwZGF0aW5nIGV4aXN0aW5nIGNvbnRleHQgcHJvcGVydGllcyBvciBuZXcgcHJvcGVydGllcyBpbiB0aGUgYHdpbmBcbiAgICAgICAgLy8gdGhhdCB3YXMgb25seSBpbnRyb2R1Y2VkIGFmdGVyIHRoZSBldmFsLlxuICAgICAgICBpZiAoa2V5IGluIGNvbnRleHQgfHwgaW5kZXhPZih3aW5LZXlzLCBrZXkpID09PSAtMSkge1xuICAgICAgICAgICAgY29udGV4dFtrZXldID0gd2luW2tleV07XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGZvckVhY2goZ2xvYmFscywgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoIShrZXkgaW4gY29udGV4dCkpIHtcbiAgICAgICAgICAgIGRlZmluZVByb3AoY29udGV4dCwga2V5LCB3aW5ba2V5XSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGlmcmFtZSk7XG4gICAgXG4gICAgcmV0dXJuIHJlcztcbn07XG5cblNjcmlwdC5wcm90b3R5cGUucnVuSW5UaGlzQ29udGV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZXZhbCh0aGlzLmNvZGUpOyAvLyBtYXliZS4uLlxufTtcblxuU2NyaXB0LnByb3RvdHlwZS5ydW5Jbk5ld0NvbnRleHQgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBjdHggPSBTY3JpcHQuY3JlYXRlQ29udGV4dChjb250ZXh0KTtcbiAgICB2YXIgcmVzID0gdGhpcy5ydW5JbkNvbnRleHQoY3R4KTtcblxuICAgIGZvckVhY2goT2JqZWN0X2tleXMoY3R4KSwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBjb250ZXh0W2tleV0gPSBjdHhba2V5XTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXM7XG59O1xuXG5mb3JFYWNoKE9iamVjdF9rZXlzKFNjcmlwdC5wcm90b3R5cGUpLCBmdW5jdGlvbiAobmFtZSkge1xuICAgIGV4cG9ydHNbbmFtZV0gPSBTY3JpcHRbbmFtZV0gPSBmdW5jdGlvbiAoY29kZSkge1xuICAgICAgICB2YXIgcyA9IFNjcmlwdChjb2RlKTtcbiAgICAgICAgcmV0dXJuIHNbbmFtZV0uYXBwbHkocywgW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTtcbiAgICB9O1xufSk7XG5cbmV4cG9ydHMuY3JlYXRlU2NyaXB0ID0gZnVuY3Rpb24gKGNvZGUpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5TY3JpcHQoY29kZSk7XG59O1xuXG5leHBvcnRzLmNyZWF0ZUNvbnRleHQgPSBTY3JpcHQuY3JlYXRlQ29udGV4dCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgdmFyIGNvcHkgPSBuZXcgQ29udGV4dCgpO1xuICAgIGlmKHR5cGVvZiBjb250ZXh0ID09PSAnb2JqZWN0Jykge1xuICAgICAgICBmb3JFYWNoKE9iamVjdF9rZXlzKGNvbnRleHQpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICBjb3B5W2tleV0gPSBjb250ZXh0W2tleV07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gY29weTtcbn07XG4iLCJcbnZhciBpbmRleE9mID0gW10uaW5kZXhPZjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihhcnIsIG9iail7XG4gIGlmIChpbmRleE9mKSByZXR1cm4gYXJyLmluZGV4T2Yob2JqKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoYXJyW2ldID09PSBvYmopIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn07IiwiLyohXG4gKiBqUXVlcnkgSmF2YVNjcmlwdCBMaWJyYXJ5IHYyLjEuMVxuICogaHR0cDovL2pxdWVyeS5jb20vXG4gKlxuICogSW5jbHVkZXMgU2l6emxlLmpzXG4gKiBodHRwOi8vc2l6emxlanMuY29tL1xuICpcbiAqIENvcHlyaWdodCAyMDA1LCAyMDE0IGpRdWVyeSBGb3VuZGF0aW9uLCBJbmMuIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxuICogaHR0cDovL2pxdWVyeS5vcmcvbGljZW5zZVxuICpcbiAqIERhdGU6IDIwMTQtMDUtMDFUMTc6MTFaXG4gKi9cblxuKGZ1bmN0aW9uKCBnbG9iYWwsIGZhY3RvcnkgKSB7XG5cblx0aWYgKCB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJvYmplY3RcIiApIHtcblx0XHQvLyBGb3IgQ29tbW9uSlMgYW5kIENvbW1vbkpTLWxpa2UgZW52aXJvbm1lbnRzIHdoZXJlIGEgcHJvcGVyIHdpbmRvdyBpcyBwcmVzZW50LFxuXHRcdC8vIGV4ZWN1dGUgdGhlIGZhY3RvcnkgYW5kIGdldCBqUXVlcnlcblx0XHQvLyBGb3IgZW52aXJvbm1lbnRzIHRoYXQgZG8gbm90IGluaGVyZW50bHkgcG9zc2VzIGEgd2luZG93IHdpdGggYSBkb2N1bWVudFxuXHRcdC8vIChzdWNoIGFzIE5vZGUuanMpLCBleHBvc2UgYSBqUXVlcnktbWFraW5nIGZhY3RvcnkgYXMgbW9kdWxlLmV4cG9ydHNcblx0XHQvLyBUaGlzIGFjY2VudHVhdGVzIHRoZSBuZWVkIGZvciB0aGUgY3JlYXRpb24gb2YgYSByZWFsIHdpbmRvd1xuXHRcdC8vIGUuZy4gdmFyIGpRdWVyeSA9IHJlcXVpcmUoXCJqcXVlcnlcIikod2luZG93KTtcblx0XHQvLyBTZWUgdGlja2V0ICMxNDU0OSBmb3IgbW9yZSBpbmZvXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBnbG9iYWwuZG9jdW1lbnQgP1xuXHRcdFx0ZmFjdG9yeSggZ2xvYmFsLCB0cnVlICkgOlxuXHRcdFx0ZnVuY3Rpb24oIHcgKSB7XG5cdFx0XHRcdGlmICggIXcuZG9jdW1lbnQgKSB7XG5cdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCBcImpRdWVyeSByZXF1aXJlcyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1lbnRcIiApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBmYWN0b3J5KCB3ICk7XG5cdFx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdGZhY3RvcnkoIGdsb2JhbCApO1xuXHR9XG5cbi8vIFBhc3MgdGhpcyBpZiB3aW5kb3cgaXMgbm90IGRlZmluZWQgeWV0XG59KHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0aGlzLCBmdW5jdGlvbiggd2luZG93LCBub0dsb2JhbCApIHtcblxuLy8gQ2FuJ3QgZG8gdGhpcyBiZWNhdXNlIHNldmVyYWwgYXBwcyBpbmNsdWRpbmcgQVNQLk5FVCB0cmFjZVxuLy8gdGhlIHN0YWNrIHZpYSBhcmd1bWVudHMuY2FsbGVyLmNhbGxlZSBhbmQgRmlyZWZveCBkaWVzIGlmXG4vLyB5b3UgdHJ5IHRvIHRyYWNlIHRocm91Z2ggXCJ1c2Ugc3RyaWN0XCIgY2FsbCBjaGFpbnMuICgjMTMzMzUpXG4vLyBTdXBwb3J0OiBGaXJlZm94IDE4K1xuLy9cblxudmFyIGFyciA9IFtdO1xuXG52YXIgc2xpY2UgPSBhcnIuc2xpY2U7XG5cbnZhciBjb25jYXQgPSBhcnIuY29uY2F0O1xuXG52YXIgcHVzaCA9IGFyci5wdXNoO1xuXG52YXIgaW5kZXhPZiA9IGFyci5pbmRleE9mO1xuXG52YXIgY2xhc3MydHlwZSA9IHt9O1xuXG52YXIgdG9TdHJpbmcgPSBjbGFzczJ0eXBlLnRvU3RyaW5nO1xuXG52YXIgaGFzT3duID0gY2xhc3MydHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxudmFyIHN1cHBvcnQgPSB7fTtcblxuXG5cbnZhclxuXHQvLyBVc2UgdGhlIGNvcnJlY3QgZG9jdW1lbnQgYWNjb3JkaW5nbHkgd2l0aCB3aW5kb3cgYXJndW1lbnQgKHNhbmRib3gpXG5cdGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50LFxuXG5cdHZlcnNpb24gPSBcIjIuMS4xXCIsXG5cblx0Ly8gRGVmaW5lIGEgbG9jYWwgY29weSBvZiBqUXVlcnlcblx0alF1ZXJ5ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0ICkge1xuXHRcdC8vIFRoZSBqUXVlcnkgb2JqZWN0IGlzIGFjdHVhbGx5IGp1c3QgdGhlIGluaXQgY29uc3RydWN0b3IgJ2VuaGFuY2VkJ1xuXHRcdC8vIE5lZWQgaW5pdCBpZiBqUXVlcnkgaXMgY2FsbGVkIChqdXN0IGFsbG93IGVycm9yIHRvIGJlIHRocm93biBpZiBub3QgaW5jbHVkZWQpXG5cdFx0cmV0dXJuIG5ldyBqUXVlcnkuZm4uaW5pdCggc2VsZWN0b3IsIGNvbnRleHQgKTtcblx0fSxcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMVxuXHQvLyBNYWtlIHN1cmUgd2UgdHJpbSBCT00gYW5kIE5CU1Bcblx0cnRyaW0gPSAvXltcXHNcXHVGRUZGXFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2csXG5cblx0Ly8gTWF0Y2hlcyBkYXNoZWQgc3RyaW5nIGZvciBjYW1lbGl6aW5nXG5cdHJtc1ByZWZpeCA9IC9eLW1zLS8sXG5cdHJkYXNoQWxwaGEgPSAvLShbXFxkYS16XSkvZ2ksXG5cblx0Ly8gVXNlZCBieSBqUXVlcnkuY2FtZWxDYXNlIGFzIGNhbGxiYWNrIHRvIHJlcGxhY2UoKVxuXHRmY2FtZWxDYXNlID0gZnVuY3Rpb24oIGFsbCwgbGV0dGVyICkge1xuXHRcdHJldHVybiBsZXR0ZXIudG9VcHBlckNhc2UoKTtcblx0fTtcblxualF1ZXJ5LmZuID0galF1ZXJ5LnByb3RvdHlwZSA9IHtcblx0Ly8gVGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBqUXVlcnkgYmVpbmcgdXNlZFxuXHRqcXVlcnk6IHZlcnNpb24sXG5cblx0Y29uc3RydWN0b3I6IGpRdWVyeSxcblxuXHQvLyBTdGFydCB3aXRoIGFuIGVtcHR5IHNlbGVjdG9yXG5cdHNlbGVjdG9yOiBcIlwiLFxuXG5cdC8vIFRoZSBkZWZhdWx0IGxlbmd0aCBvZiBhIGpRdWVyeSBvYmplY3QgaXMgMFxuXHRsZW5ndGg6IDAsXG5cblx0dG9BcnJheTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHNsaWNlLmNhbGwoIHRoaXMgKTtcblx0fSxcblxuXHQvLyBHZXQgdGhlIE50aCBlbGVtZW50IGluIHRoZSBtYXRjaGVkIGVsZW1lbnQgc2V0IE9SXG5cdC8vIEdldCB0aGUgd2hvbGUgbWF0Y2hlZCBlbGVtZW50IHNldCBhcyBhIGNsZWFuIGFycmF5XG5cdGdldDogZnVuY3Rpb24oIG51bSApIHtcblx0XHRyZXR1cm4gbnVtICE9IG51bGwgP1xuXG5cdFx0XHQvLyBSZXR1cm4ganVzdCB0aGUgb25lIGVsZW1lbnQgZnJvbSB0aGUgc2V0XG5cdFx0XHQoIG51bSA8IDAgPyB0aGlzWyBudW0gKyB0aGlzLmxlbmd0aCBdIDogdGhpc1sgbnVtIF0gKSA6XG5cblx0XHRcdC8vIFJldHVybiBhbGwgdGhlIGVsZW1lbnRzIGluIGEgY2xlYW4gYXJyYXlcblx0XHRcdHNsaWNlLmNhbGwoIHRoaXMgKTtcblx0fSxcblxuXHQvLyBUYWtlIGFuIGFycmF5IG9mIGVsZW1lbnRzIGFuZCBwdXNoIGl0IG9udG8gdGhlIHN0YWNrXG5cdC8vIChyZXR1cm5pbmcgdGhlIG5ldyBtYXRjaGVkIGVsZW1lbnQgc2V0KVxuXHRwdXNoU3RhY2s6IGZ1bmN0aW9uKCBlbGVtcyApIHtcblxuXHRcdC8vIEJ1aWxkIGEgbmV3IGpRdWVyeSBtYXRjaGVkIGVsZW1lbnQgc2V0XG5cdFx0dmFyIHJldCA9IGpRdWVyeS5tZXJnZSggdGhpcy5jb25zdHJ1Y3RvcigpLCBlbGVtcyApO1xuXG5cdFx0Ly8gQWRkIHRoZSBvbGQgb2JqZWN0IG9udG8gdGhlIHN0YWNrIChhcyBhIHJlZmVyZW5jZSlcblx0XHRyZXQucHJldk9iamVjdCA9IHRoaXM7XG5cdFx0cmV0LmNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG5cblx0XHQvLyBSZXR1cm4gdGhlIG5ld2x5LWZvcm1lZCBlbGVtZW50IHNldFxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0Ly8gRXhlY3V0ZSBhIGNhbGxiYWNrIGZvciBldmVyeSBlbGVtZW50IGluIHRoZSBtYXRjaGVkIHNldC5cblx0Ly8gKFlvdSBjYW4gc2VlZCB0aGUgYXJndW1lbnRzIHdpdGggYW4gYXJyYXkgb2YgYXJncywgYnV0IHRoaXMgaXNcblx0Ly8gb25seSB1c2VkIGludGVybmFsbHkuKVxuXHRlYWNoOiBmdW5jdGlvbiggY2FsbGJhY2ssIGFyZ3MgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5lYWNoKCB0aGlzLCBjYWxsYmFjaywgYXJncyApO1xuXHR9LFxuXG5cdG1hcDogZnVuY3Rpb24oIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5Lm1hcCh0aGlzLCBmdW5jdGlvbiggZWxlbSwgaSApIHtcblx0XHRcdHJldHVybiBjYWxsYmFjay5jYWxsKCBlbGVtLCBpLCBlbGVtICk7XG5cdFx0fSkpO1xuXHR9LFxuXG5cdHNsaWNlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHNsaWNlLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKSApO1xuXHR9LFxuXG5cdGZpcnN0OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lcSggMCApO1xuXHR9LFxuXG5cdGxhc3Q6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVxKCAtMSApO1xuXHR9LFxuXG5cdGVxOiBmdW5jdGlvbiggaSApIHtcblx0XHR2YXIgbGVuID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRqID0gK2kgKyAoIGkgPCAwID8gbGVuIDogMCApO1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggaiA+PSAwICYmIGogPCBsZW4gPyBbIHRoaXNbal0gXSA6IFtdICk7XG5cdH0sXG5cblx0ZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wcmV2T2JqZWN0IHx8IHRoaXMuY29uc3RydWN0b3IobnVsbCk7XG5cdH0sXG5cblx0Ly8gRm9yIGludGVybmFsIHVzZSBvbmx5LlxuXHQvLyBCZWhhdmVzIGxpa2UgYW4gQXJyYXkncyBtZXRob2QsIG5vdCBsaWtlIGEgalF1ZXJ5IG1ldGhvZC5cblx0cHVzaDogcHVzaCxcblx0c29ydDogYXJyLnNvcnQsXG5cdHNwbGljZTogYXJyLnNwbGljZVxufTtcblxualF1ZXJ5LmV4dGVuZCA9IGpRdWVyeS5mbi5leHRlbmQgPSBmdW5jdGlvbigpIHtcblx0dmFyIG9wdGlvbnMsIG5hbWUsIHNyYywgY29weSwgY29weUlzQXJyYXksIGNsb25lLFxuXHRcdHRhcmdldCA9IGFyZ3VtZW50c1swXSB8fCB7fSxcblx0XHRpID0gMSxcblx0XHRsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuXHRcdGRlZXAgPSBmYWxzZTtcblxuXHQvLyBIYW5kbGUgYSBkZWVwIGNvcHkgc2l0dWF0aW9uXG5cdGlmICggdHlwZW9mIHRhcmdldCA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0ZGVlcCA9IHRhcmdldDtcblxuXHRcdC8vIHNraXAgdGhlIGJvb2xlYW4gYW5kIHRoZSB0YXJnZXRcblx0XHR0YXJnZXQgPSBhcmd1bWVudHNbIGkgXSB8fCB7fTtcblx0XHRpKys7XG5cdH1cblxuXHQvLyBIYW5kbGUgY2FzZSB3aGVuIHRhcmdldCBpcyBhIHN0cmluZyBvciBzb21ldGhpbmcgKHBvc3NpYmxlIGluIGRlZXAgY29weSlcblx0aWYgKCB0eXBlb2YgdGFyZ2V0ICE9PSBcIm9iamVjdFwiICYmICFqUXVlcnkuaXNGdW5jdGlvbih0YXJnZXQpICkge1xuXHRcdHRhcmdldCA9IHt9O1xuXHR9XG5cblx0Ly8gZXh0ZW5kIGpRdWVyeSBpdHNlbGYgaWYgb25seSBvbmUgYXJndW1lbnQgaXMgcGFzc2VkXG5cdGlmICggaSA9PT0gbGVuZ3RoICkge1xuXHRcdHRhcmdldCA9IHRoaXM7XG5cdFx0aS0tO1xuXHR9XG5cblx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0Ly8gT25seSBkZWFsIHdpdGggbm9uLW51bGwvdW5kZWZpbmVkIHZhbHVlc1xuXHRcdGlmICggKG9wdGlvbnMgPSBhcmd1bWVudHNbIGkgXSkgIT0gbnVsbCApIHtcblx0XHRcdC8vIEV4dGVuZCB0aGUgYmFzZSBvYmplY3Rcblx0XHRcdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRcdFx0c3JjID0gdGFyZ2V0WyBuYW1lIF07XG5cdFx0XHRcdGNvcHkgPSBvcHRpb25zWyBuYW1lIF07XG5cblx0XHRcdFx0Ly8gUHJldmVudCBuZXZlci1lbmRpbmcgbG9vcFxuXHRcdFx0XHRpZiAoIHRhcmdldCA9PT0gY29weSApIHtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFJlY3Vyc2UgaWYgd2UncmUgbWVyZ2luZyBwbGFpbiBvYmplY3RzIG9yIGFycmF5c1xuXHRcdFx0XHRpZiAoIGRlZXAgJiYgY29weSAmJiAoIGpRdWVyeS5pc1BsYWluT2JqZWN0KGNvcHkpIHx8IChjb3B5SXNBcnJheSA9IGpRdWVyeS5pc0FycmF5KGNvcHkpKSApICkge1xuXHRcdFx0XHRcdGlmICggY29weUlzQXJyYXkgKSB7XG5cdFx0XHRcdFx0XHRjb3B5SXNBcnJheSA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0Y2xvbmUgPSBzcmMgJiYgalF1ZXJ5LmlzQXJyYXkoc3JjKSA/IHNyYyA6IFtdO1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGNsb25lID0gc3JjICYmIGpRdWVyeS5pc1BsYWluT2JqZWN0KHNyYykgPyBzcmMgOiB7fTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBOZXZlciBtb3ZlIG9yaWdpbmFsIG9iamVjdHMsIGNsb25lIHRoZW1cblx0XHRcdFx0XHR0YXJnZXRbIG5hbWUgXSA9IGpRdWVyeS5leHRlbmQoIGRlZXAsIGNsb25lLCBjb3B5ICk7XG5cblx0XHRcdFx0Ly8gRG9uJ3QgYnJpbmcgaW4gdW5kZWZpbmVkIHZhbHVlc1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBjb3B5ICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0dGFyZ2V0WyBuYW1lIF0gPSBjb3B5O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSBtb2RpZmllZCBvYmplY3Rcblx0cmV0dXJuIHRhcmdldDtcbn07XG5cbmpRdWVyeS5leHRlbmQoe1xuXHQvLyBVbmlxdWUgZm9yIGVhY2ggY29weSBvZiBqUXVlcnkgb24gdGhlIHBhZ2Vcblx0ZXhwYW5kbzogXCJqUXVlcnlcIiArICggdmVyc2lvbiArIE1hdGgucmFuZG9tKCkgKS5yZXBsYWNlKCAvXFxEL2csIFwiXCIgKSxcblxuXHQvLyBBc3N1bWUgalF1ZXJ5IGlzIHJlYWR5IHdpdGhvdXQgdGhlIHJlYWR5IG1vZHVsZVxuXHRpc1JlYWR5OiB0cnVlLFxuXG5cdGVycm9yOiBmdW5jdGlvbiggbXNnICkge1xuXHRcdHRocm93IG5ldyBFcnJvciggbXNnICk7XG5cdH0sXG5cblx0bm9vcDogZnVuY3Rpb24oKSB7fSxcblxuXHQvLyBTZWUgdGVzdC91bml0L2NvcmUuanMgZm9yIGRldGFpbHMgY29uY2VybmluZyBpc0Z1bmN0aW9uLlxuXHQvLyBTaW5jZSB2ZXJzaW9uIDEuMywgRE9NIG1ldGhvZHMgYW5kIGZ1bmN0aW9ucyBsaWtlIGFsZXJ0XG5cdC8vIGFyZW4ndCBzdXBwb3J0ZWQuIFRoZXkgcmV0dXJuIGZhbHNlIG9uIElFICgjMjk2OCkuXG5cdGlzRnVuY3Rpb246IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS50eXBlKG9iaikgPT09IFwiZnVuY3Rpb25cIjtcblx0fSxcblxuXHRpc0FycmF5OiBBcnJheS5pc0FycmF5LFxuXG5cdGlzV2luZG93OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdHJldHVybiBvYmogIT0gbnVsbCAmJiBvYmogPT09IG9iai53aW5kb3c7XG5cdH0sXG5cblx0aXNOdW1lcmljOiBmdW5jdGlvbiggb2JqICkge1xuXHRcdC8vIHBhcnNlRmxvYXQgTmFOcyBudW1lcmljLWNhc3QgZmFsc2UgcG9zaXRpdmVzIChudWxsfHRydWV8ZmFsc2V8XCJcIilcblx0XHQvLyAuLi5idXQgbWlzaW50ZXJwcmV0cyBsZWFkaW5nLW51bWJlciBzdHJpbmdzLCBwYXJ0aWN1bGFybHkgaGV4IGxpdGVyYWxzIChcIjB4Li4uXCIpXG5cdFx0Ly8gc3VidHJhY3Rpb24gZm9yY2VzIGluZmluaXRpZXMgdG8gTmFOXG5cdFx0cmV0dXJuICFqUXVlcnkuaXNBcnJheSggb2JqICkgJiYgb2JqIC0gcGFyc2VGbG9hdCggb2JqICkgPj0gMDtcblx0fSxcblxuXHRpc1BsYWluT2JqZWN0OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdC8vIE5vdCBwbGFpbiBvYmplY3RzOlxuXHRcdC8vIC0gQW55IG9iamVjdCBvciB2YWx1ZSB3aG9zZSBpbnRlcm5hbCBbW0NsYXNzXV0gcHJvcGVydHkgaXMgbm90IFwiW29iamVjdCBPYmplY3RdXCJcblx0XHQvLyAtIERPTSBub2Rlc1xuXHRcdC8vIC0gd2luZG93XG5cdFx0aWYgKCBqUXVlcnkudHlwZSggb2JqICkgIT09IFwib2JqZWN0XCIgfHwgb2JqLm5vZGVUeXBlIHx8IGpRdWVyeS5pc1dpbmRvdyggb2JqICkgKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0aWYgKCBvYmouY29uc3RydWN0b3IgJiZcblx0XHRcdFx0IWhhc093bi5jYWxsKCBvYmouY29uc3RydWN0b3IucHJvdG90eXBlLCBcImlzUHJvdG90eXBlT2ZcIiApICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIElmIHRoZSBmdW5jdGlvbiBoYXNuJ3QgcmV0dXJuZWQgYWxyZWFkeSwgd2UncmUgY29uZmlkZW50IHRoYXRcblx0XHQvLyB8b2JqfCBpcyBhIHBsYWluIG9iamVjdCwgY3JlYXRlZCBieSB7fSBvciBjb25zdHJ1Y3RlZCB3aXRoIG5ldyBPYmplY3Rcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSxcblxuXHRpc0VtcHR5T2JqZWN0OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdHZhciBuYW1lO1xuXHRcdGZvciAoIG5hbWUgaW4gb2JqICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSxcblxuXHR0eXBlOiBmdW5jdGlvbiggb2JqICkge1xuXHRcdGlmICggb2JqID09IG51bGwgKSB7XG5cdFx0XHRyZXR1cm4gb2JqICsgXCJcIjtcblx0XHR9XG5cdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8IDQuMCwgaU9TIDwgNiAoZnVuY3Rpb25pc2ggUmVnRXhwKVxuXHRcdHJldHVybiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiA/XG5cdFx0XHRjbGFzczJ0eXBlWyB0b1N0cmluZy5jYWxsKG9iaikgXSB8fCBcIm9iamVjdFwiIDpcblx0XHRcdHR5cGVvZiBvYmo7XG5cdH0sXG5cblx0Ly8gRXZhbHVhdGVzIGEgc2NyaXB0IGluIGEgZ2xvYmFsIGNvbnRleHRcblx0Z2xvYmFsRXZhbDogZnVuY3Rpb24oIGNvZGUgKSB7XG5cdFx0dmFyIHNjcmlwdCxcblx0XHRcdGluZGlyZWN0ID0gZXZhbDtcblxuXHRcdGNvZGUgPSBqUXVlcnkudHJpbSggY29kZSApO1xuXG5cdFx0aWYgKCBjb2RlICkge1xuXHRcdFx0Ly8gSWYgdGhlIGNvZGUgaW5jbHVkZXMgYSB2YWxpZCwgcHJvbG9ndWUgcG9zaXRpb25cblx0XHRcdC8vIHN0cmljdCBtb2RlIHByYWdtYSwgZXhlY3V0ZSBjb2RlIGJ5IGluamVjdGluZyBhXG5cdFx0XHQvLyBzY3JpcHQgdGFnIGludG8gdGhlIGRvY3VtZW50LlxuXHRcdFx0aWYgKCBjb2RlLmluZGV4T2YoXCJ1c2Ugc3RyaWN0XCIpID09PSAxICkge1xuXHRcdFx0XHRzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO1xuXHRcdFx0XHRzY3JpcHQudGV4dCA9IGNvZGU7XG5cdFx0XHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoIHNjcmlwdCApLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHNjcmlwdCApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdC8vIE90aGVyd2lzZSwgYXZvaWQgdGhlIERPTSBub2RlIGNyZWF0aW9uLCBpbnNlcnRpb25cblx0XHRcdC8vIGFuZCByZW1vdmFsIGJ5IHVzaW5nIGFuIGluZGlyZWN0IGdsb2JhbCBldmFsXG5cdFx0XHRcdGluZGlyZWN0KCBjb2RlICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8vIENvbnZlcnQgZGFzaGVkIHRvIGNhbWVsQ2FzZTsgdXNlZCBieSB0aGUgY3NzIGFuZCBkYXRhIG1vZHVsZXNcblx0Ly8gTWljcm9zb2Z0IGZvcmdvdCB0byBodW1wIHRoZWlyIHZlbmRvciBwcmVmaXggKCM5NTcyKVxuXHRjYW1lbENhc2U6IGZ1bmN0aW9uKCBzdHJpbmcgKSB7XG5cdFx0cmV0dXJuIHN0cmluZy5yZXBsYWNlKCBybXNQcmVmaXgsIFwibXMtXCIgKS5yZXBsYWNlKCByZGFzaEFscGhhLCBmY2FtZWxDYXNlICk7XG5cdH0sXG5cblx0bm9kZU5hbWU6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXHRcdHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXHR9LFxuXG5cdC8vIGFyZ3MgaXMgZm9yIGludGVybmFsIHVzYWdlIG9ubHlcblx0ZWFjaDogZnVuY3Rpb24oIG9iaiwgY2FsbGJhY2ssIGFyZ3MgKSB7XG5cdFx0dmFyIHZhbHVlLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsZW5ndGggPSBvYmoubGVuZ3RoLFxuXHRcdFx0aXNBcnJheSA9IGlzQXJyYXlsaWtlKCBvYmogKTtcblxuXHRcdGlmICggYXJncyApIHtcblx0XHRcdGlmICggaXNBcnJheSApIHtcblx0XHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjay5hcHBseSggb2JqWyBpIF0sIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmb3IgKCBpIGluIG9iaiApIHtcblx0XHRcdFx0XHR2YWx1ZSA9IGNhbGxiYWNrLmFwcGx5KCBvYmpbIGkgXSwgYXJncyApO1xuXG5cdFx0XHRcdFx0aWYgKCB2YWx1ZSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEEgc3BlY2lhbCwgZmFzdCwgY2FzZSBmb3IgdGhlIG1vc3QgY29tbW9uIHVzZSBvZiBlYWNoXG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmICggaXNBcnJheSApIHtcblx0XHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjay5jYWxsKCBvYmpbIGkgXSwgaSwgb2JqWyBpIF0gKTtcblxuXHRcdFx0XHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmb3IgKCBpIGluIG9iaiApIHtcblx0XHRcdFx0XHR2YWx1ZSA9IGNhbGxiYWNrLmNhbGwoIG9ialsgaSBdLCBpLCBvYmpbIGkgXSApO1xuXG5cdFx0XHRcdFx0aWYgKCB2YWx1ZSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gb2JqO1xuXHR9LFxuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4xXG5cdHRyaW06IGZ1bmN0aW9uKCB0ZXh0ICkge1xuXHRcdHJldHVybiB0ZXh0ID09IG51bGwgP1xuXHRcdFx0XCJcIiA6XG5cdFx0XHQoIHRleHQgKyBcIlwiICkucmVwbGFjZSggcnRyaW0sIFwiXCIgKTtcblx0fSxcblxuXHQvLyByZXN1bHRzIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XG5cdG1ha2VBcnJheTogZnVuY3Rpb24oIGFyciwgcmVzdWx0cyApIHtcblx0XHR2YXIgcmV0ID0gcmVzdWx0cyB8fCBbXTtcblxuXHRcdGlmICggYXJyICE9IG51bGwgKSB7XG5cdFx0XHRpZiAoIGlzQXJyYXlsaWtlKCBPYmplY3QoYXJyKSApICkge1xuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIHJldCxcblx0XHRcdFx0XHR0eXBlb2YgYXJyID09PSBcInN0cmluZ1wiID9cblx0XHRcdFx0XHRbIGFyciBdIDogYXJyXG5cdFx0XHRcdCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwdXNoLmNhbGwoIHJldCwgYXJyICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHRpbkFycmF5OiBmdW5jdGlvbiggZWxlbSwgYXJyLCBpICkge1xuXHRcdHJldHVybiBhcnIgPT0gbnVsbCA/IC0xIDogaW5kZXhPZi5jYWxsKCBhcnIsIGVsZW0sIGkgKTtcblx0fSxcblxuXHRtZXJnZTogZnVuY3Rpb24oIGZpcnN0LCBzZWNvbmQgKSB7XG5cdFx0dmFyIGxlbiA9ICtzZWNvbmQubGVuZ3RoLFxuXHRcdFx0aiA9IDAsXG5cdFx0XHRpID0gZmlyc3QubGVuZ3RoO1xuXG5cdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XG5cdFx0XHRmaXJzdFsgaSsrIF0gPSBzZWNvbmRbIGogXTtcblx0XHR9XG5cblx0XHRmaXJzdC5sZW5ndGggPSBpO1xuXG5cdFx0cmV0dXJuIGZpcnN0O1xuXHR9LFxuXG5cdGdyZXA6IGZ1bmN0aW9uKCBlbGVtcywgY2FsbGJhY2ssIGludmVydCApIHtcblx0XHR2YXIgY2FsbGJhY2tJbnZlcnNlLFxuXHRcdFx0bWF0Y2hlcyA9IFtdLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsZW5ndGggPSBlbGVtcy5sZW5ndGgsXG5cdFx0XHRjYWxsYmFja0V4cGVjdCA9ICFpbnZlcnQ7XG5cblx0XHQvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgb25seSBzYXZpbmcgdGhlIGl0ZW1zXG5cdFx0Ly8gdGhhdCBwYXNzIHRoZSB2YWxpZGF0b3IgZnVuY3Rpb25cblx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHRcdGNhbGxiYWNrSW52ZXJzZSA9ICFjYWxsYmFjayggZWxlbXNbIGkgXSwgaSApO1xuXHRcdFx0aWYgKCBjYWxsYmFja0ludmVyc2UgIT09IGNhbGxiYWNrRXhwZWN0ICkge1xuXHRcdFx0XHRtYXRjaGVzLnB1c2goIGVsZW1zWyBpIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gbWF0Y2hlcztcblx0fSxcblxuXHQvLyBhcmcgaXMgZm9yIGludGVybmFsIHVzYWdlIG9ubHlcblx0bWFwOiBmdW5jdGlvbiggZWxlbXMsIGNhbGxiYWNrLCBhcmcgKSB7XG5cdFx0dmFyIHZhbHVlLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsZW5ndGggPSBlbGVtcy5sZW5ndGgsXG5cdFx0XHRpc0FycmF5ID0gaXNBcnJheWxpa2UoIGVsZW1zICksXG5cdFx0XHRyZXQgPSBbXTtcblxuXHRcdC8vIEdvIHRocm91Z2ggdGhlIGFycmF5LCB0cmFuc2xhdGluZyBlYWNoIG9mIHRoZSBpdGVtcyB0byB0aGVpciBuZXcgdmFsdWVzXG5cdFx0aWYgKCBpc0FycmF5ICkge1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdHZhbHVlID0gY2FsbGJhY2soIGVsZW1zWyBpIF0sIGksIGFyZyApO1xuXG5cdFx0XHRcdGlmICggdmFsdWUgIT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXQucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0Ly8gR28gdGhyb3VnaCBldmVyeSBrZXkgb24gdGhlIG9iamVjdCxcblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICggaSBpbiBlbGVtcyApIHtcblx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjayggZWxlbXNbIGkgXSwgaSwgYXJnICk7XG5cblx0XHRcdFx0aWYgKCB2YWx1ZSAhPSBudWxsICkge1xuXHRcdFx0XHRcdHJldC5wdXNoKCB2YWx1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xuXHRcdHJldHVybiBjb25jYXQuYXBwbHkoIFtdLCByZXQgKTtcblx0fSxcblxuXHQvLyBBIGdsb2JhbCBHVUlEIGNvdW50ZXIgZm9yIG9iamVjdHNcblx0Z3VpZDogMSxcblxuXHQvLyBCaW5kIGEgZnVuY3Rpb24gdG8gYSBjb250ZXh0LCBvcHRpb25hbGx5IHBhcnRpYWxseSBhcHBseWluZyBhbnlcblx0Ly8gYXJndW1lbnRzLlxuXHRwcm94eTogZnVuY3Rpb24oIGZuLCBjb250ZXh0ICkge1xuXHRcdHZhciB0bXAsIGFyZ3MsIHByb3h5O1xuXG5cdFx0aWYgKCB0eXBlb2YgY29udGV4dCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHRtcCA9IGZuWyBjb250ZXh0IF07XG5cdFx0XHRjb250ZXh0ID0gZm47XG5cdFx0XHRmbiA9IHRtcDtcblx0XHR9XG5cblx0XHQvLyBRdWljayBjaGVjayB0byBkZXRlcm1pbmUgaWYgdGFyZ2V0IGlzIGNhbGxhYmxlLCBpbiB0aGUgc3BlY1xuXHRcdC8vIHRoaXMgdGhyb3dzIGEgVHlwZUVycm9yLCBidXQgd2Ugd2lsbCBqdXN0IHJldHVybiB1bmRlZmluZWQuXG5cdFx0aWYgKCAhalF1ZXJ5LmlzRnVuY3Rpb24oIGZuICkgKSB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdC8vIFNpbXVsYXRlZCBiaW5kXG5cdFx0YXJncyA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cywgMiApO1xuXHRcdHByb3h5ID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gZm4uYXBwbHkoIGNvbnRleHQgfHwgdGhpcywgYXJncy5jb25jYXQoIHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApICkgKTtcblx0XHR9O1xuXG5cdFx0Ly8gU2V0IHRoZSBndWlkIG9mIHVuaXF1ZSBoYW5kbGVyIHRvIHRoZSBzYW1lIG9mIG9yaWdpbmFsIGhhbmRsZXIsIHNvIGl0IGNhbiBiZSByZW1vdmVkXG5cdFx0cHJveHkuZ3VpZCA9IGZuLmd1aWQgPSBmbi5ndWlkIHx8IGpRdWVyeS5ndWlkKys7XG5cblx0XHRyZXR1cm4gcHJveHk7XG5cdH0sXG5cblx0bm93OiBEYXRlLm5vdyxcblxuXHQvLyBqUXVlcnkuc3VwcG9ydCBpcyBub3QgdXNlZCBpbiBDb3JlIGJ1dCBvdGhlciBwcm9qZWN0cyBhdHRhY2ggdGhlaXJcblx0Ly8gcHJvcGVydGllcyB0byBpdCBzbyBpdCBuZWVkcyB0byBleGlzdC5cblx0c3VwcG9ydDogc3VwcG9ydFxufSk7XG5cbi8vIFBvcHVsYXRlIHRoZSBjbGFzczJ0eXBlIG1hcFxualF1ZXJ5LmVhY2goXCJCb29sZWFuIE51bWJlciBTdHJpbmcgRnVuY3Rpb24gQXJyYXkgRGF0ZSBSZWdFeHAgT2JqZWN0IEVycm9yXCIuc3BsaXQoXCIgXCIpLCBmdW5jdGlvbihpLCBuYW1lKSB7XG5cdGNsYXNzMnR5cGVbIFwiW29iamVjdCBcIiArIG5hbWUgKyBcIl1cIiBdID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xufSk7XG5cbmZ1bmN0aW9uIGlzQXJyYXlsaWtlKCBvYmogKSB7XG5cdHZhciBsZW5ndGggPSBvYmoubGVuZ3RoLFxuXHRcdHR5cGUgPSBqUXVlcnkudHlwZSggb2JqICk7XG5cblx0aWYgKCB0eXBlID09PSBcImZ1bmN0aW9uXCIgfHwgalF1ZXJ5LmlzV2luZG93KCBvYmogKSApIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRpZiAoIG9iai5ub2RlVHlwZSA9PT0gMSAmJiBsZW5ndGggKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHRyZXR1cm4gdHlwZSA9PT0gXCJhcnJheVwiIHx8IGxlbmd0aCA9PT0gMCB8fFxuXHRcdHR5cGVvZiBsZW5ndGggPT09IFwibnVtYmVyXCIgJiYgbGVuZ3RoID4gMCAmJiAoIGxlbmd0aCAtIDEgKSBpbiBvYmo7XG59XG52YXIgU2l6emxlID1cbi8qIVxuICogU2l6emxlIENTUyBTZWxlY3RvciBFbmdpbmUgdjEuMTAuMTlcbiAqIGh0dHA6Ly9zaXp6bGVqcy5jb20vXG4gKlxuICogQ29weXJpZ2h0IDIwMTMgalF1ZXJ5IEZvdW5kYXRpb24sIEluYy4gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKiBodHRwOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogRGF0ZTogMjAxNC0wNC0xOFxuICovXG4oZnVuY3Rpb24oIHdpbmRvdyApIHtcblxudmFyIGksXG5cdHN1cHBvcnQsXG5cdEV4cHIsXG5cdGdldFRleHQsXG5cdGlzWE1MLFxuXHR0b2tlbml6ZSxcblx0Y29tcGlsZSxcblx0c2VsZWN0LFxuXHRvdXRlcm1vc3RDb250ZXh0LFxuXHRzb3J0SW5wdXQsXG5cdGhhc0R1cGxpY2F0ZSxcblxuXHQvLyBMb2NhbCBkb2N1bWVudCB2YXJzXG5cdHNldERvY3VtZW50LFxuXHRkb2N1bWVudCxcblx0ZG9jRWxlbSxcblx0ZG9jdW1lbnRJc0hUTUwsXG5cdHJidWdneVFTQSxcblx0cmJ1Z2d5TWF0Y2hlcyxcblx0bWF0Y2hlcyxcblx0Y29udGFpbnMsXG5cblx0Ly8gSW5zdGFuY2Utc3BlY2lmaWMgZGF0YVxuXHRleHBhbmRvID0gXCJzaXp6bGVcIiArIC0obmV3IERhdGUoKSksXG5cdHByZWZlcnJlZERvYyA9IHdpbmRvdy5kb2N1bWVudCxcblx0ZGlycnVucyA9IDAsXG5cdGRvbmUgPSAwLFxuXHRjbGFzc0NhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0dG9rZW5DYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdGNvbXBpbGVyQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHRzb3J0T3JkZXIgPSBmdW5jdGlvbiggYSwgYiApIHtcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gMDtcblx0fSxcblxuXHQvLyBHZW5lcmFsLXB1cnBvc2UgY29uc3RhbnRzXG5cdHN0cnVuZGVmaW5lZCA9IHR5cGVvZiB1bmRlZmluZWQsXG5cdE1BWF9ORUdBVElWRSA9IDEgPDwgMzEsXG5cblx0Ly8gSW5zdGFuY2UgbWV0aG9kc1xuXHRoYXNPd24gPSAoe30pLmhhc093blByb3BlcnR5LFxuXHRhcnIgPSBbXSxcblx0cG9wID0gYXJyLnBvcCxcblx0cHVzaF9uYXRpdmUgPSBhcnIucHVzaCxcblx0cHVzaCA9IGFyci5wdXNoLFxuXHRzbGljZSA9IGFyci5zbGljZSxcblx0Ly8gVXNlIGEgc3RyaXBwZWQtZG93biBpbmRleE9mIGlmIHdlIGNhbid0IHVzZSBhIG5hdGl2ZSBvbmVcblx0aW5kZXhPZiA9IGFyci5pbmRleE9mIHx8IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHZhciBpID0gMCxcblx0XHRcdGxlbiA9IHRoaXMubGVuZ3RoO1xuXHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0aWYgKCB0aGlzW2ldID09PSBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIC0xO1xuXHR9LFxuXG5cdGJvb2xlYW5zID0gXCJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58aXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZFwiLFxuXG5cdC8vIFJlZ3VsYXIgZXhwcmVzc2lvbnNcblxuXHQvLyBXaGl0ZXNwYWNlIGNoYXJhY3RlcnMgaHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy1zZWxlY3RvcnMvI3doaXRlc3BhY2Vcblx0d2hpdGVzcGFjZSA9IFwiW1xcXFx4MjBcXFxcdFxcXFxyXFxcXG5cXFxcZl1cIixcblx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy1zeW50YXgvI2NoYXJhY3RlcnNcblx0Y2hhcmFjdGVyRW5jb2RpbmcgPSBcIig/OlxcXFxcXFxcLnxbXFxcXHctXXxbXlxcXFx4MDAtXFxcXHhhMF0pK1wiLFxuXG5cdC8vIExvb3NlbHkgbW9kZWxlZCBvbiBDU1MgaWRlbnRpZmllciBjaGFyYWN0ZXJzXG5cdC8vIEFuIHVucXVvdGVkIHZhbHVlIHNob3VsZCBiZSBhIENTUyBpZGVudGlmaWVyIGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtc2VsZWN0b3JzLyNhdHRyaWJ1dGUtc2VsZWN0b3JzXG5cdC8vIFByb3BlciBzeW50YXg6IGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCN2YWx1ZS1kZWYtaWRlbnRpZmllclxuXHRpZGVudGlmaWVyID0gY2hhcmFjdGVyRW5jb2RpbmcucmVwbGFjZSggXCJ3XCIsIFwidyNcIiApLFxuXG5cdC8vIEF0dHJpYnV0ZSBzZWxlY3RvcnM6IGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jYXR0cmlidXRlLXNlbGVjdG9yc1xuXHRhdHRyaWJ1dGVzID0gXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKihcIiArIGNoYXJhY3RlckVuY29kaW5nICsgXCIpKD86XCIgKyB3aGl0ZXNwYWNlICtcblx0XHQvLyBPcGVyYXRvciAoY2FwdHVyZSAyKVxuXHRcdFwiKihbKl4kfCF+XT89KVwiICsgd2hpdGVzcGFjZSArXG5cdFx0Ly8gXCJBdHRyaWJ1dGUgdmFsdWVzIG11c3QgYmUgQ1NTIGlkZW50aWZpZXJzIFtjYXB0dXJlIDVdIG9yIHN0cmluZ3MgW2NhcHR1cmUgMyBvciBjYXB0dXJlIDRdXCJcblx0XHRcIiooPzonKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcJ10pKiknfFxcXCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFxcXFwiXSkqKVxcXCJ8KFwiICsgaWRlbnRpZmllciArIFwiKSl8KVwiICsgd2hpdGVzcGFjZSArXG5cdFx0XCIqXFxcXF1cIixcblxuXHRwc2V1ZG9zID0gXCI6KFwiICsgY2hhcmFjdGVyRW5jb2RpbmcgKyBcIikoPzpcXFxcKChcIiArXG5cdFx0Ly8gVG8gcmVkdWNlIHRoZSBudW1iZXIgb2Ygc2VsZWN0b3JzIG5lZWRpbmcgdG9rZW5pemUgaW4gdGhlIHByZUZpbHRlciwgcHJlZmVyIGFyZ3VtZW50czpcblx0XHQvLyAxLiBxdW90ZWQgKGNhcHR1cmUgMzsgY2FwdHVyZSA0IG9yIGNhcHR1cmUgNSlcblx0XHRcIignKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcJ10pKiknfFxcXCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFxcXFwiXSkqKVxcXCIpfFwiICtcblx0XHQvLyAyLiBzaW1wbGUgKGNhcHR1cmUgNilcblx0XHRcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXCgpW1xcXFxdXXxcIiArIGF0dHJpYnV0ZXMgKyBcIikqKXxcIiArXG5cdFx0Ly8gMy4gYW55dGhpbmcgZWxzZSAoY2FwdHVyZSAyKVxuXHRcdFwiLipcIiArXG5cdFx0XCIpXFxcXCl8KVwiLFxuXG5cdC8vIExlYWRpbmcgYW5kIG5vbi1lc2NhcGVkIHRyYWlsaW5nIHdoaXRlc3BhY2UsIGNhcHR1cmluZyBzb21lIG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlcnMgcHJlY2VkaW5nIHRoZSBsYXR0ZXJcblx0cnRyaW0gPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIit8KCg/Ol58W15cXFxcXFxcXF0pKD86XFxcXFxcXFwuKSopXCIgKyB3aGl0ZXNwYWNlICsgXCIrJFwiLCBcImdcIiApLFxuXG5cdHJjb21tYSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKixcIiArIHdoaXRlc3BhY2UgKyBcIipcIiApLFxuXHRyY29tYmluYXRvcnMgPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIiooWz4rfl18XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyB3aGl0ZXNwYWNlICsgXCIqXCIgKSxcblxuXHRyYXR0cmlidXRlUXVvdGVzID0gbmV3IFJlZ0V4cCggXCI9XCIgKyB3aGl0ZXNwYWNlICsgXCIqKFteXFxcXF0nXFxcIl0qPylcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcXVwiLCBcImdcIiApLFxuXG5cdHJwc2V1ZG8gPSBuZXcgUmVnRXhwKCBwc2V1ZG9zICksXG5cdHJpZGVudGlmaWVyID0gbmV3IFJlZ0V4cCggXCJeXCIgKyBpZGVudGlmaWVyICsgXCIkXCIgKSxcblxuXHRtYXRjaEV4cHIgPSB7XG5cdFx0XCJJRFwiOiBuZXcgUmVnRXhwKCBcIl4jKFwiICsgY2hhcmFjdGVyRW5jb2RpbmcgKyBcIilcIiApLFxuXHRcdFwiQ0xBU1NcIjogbmV3IFJlZ0V4cCggXCJeXFxcXC4oXCIgKyBjaGFyYWN0ZXJFbmNvZGluZyArIFwiKVwiICksXG5cdFx0XCJUQUdcIjogbmV3IFJlZ0V4cCggXCJeKFwiICsgY2hhcmFjdGVyRW5jb2RpbmcucmVwbGFjZSggXCJ3XCIsIFwidypcIiApICsgXCIpXCIgKSxcblx0XHRcIkFUVFJcIjogbmV3IFJlZ0V4cCggXCJeXCIgKyBhdHRyaWJ1dGVzICksXG5cdFx0XCJQU0VVRE9cIjogbmV3IFJlZ0V4cCggXCJeXCIgKyBwc2V1ZG9zICksXG5cdFx0XCJDSElMRFwiOiBuZXcgUmVnRXhwKCBcIl46KG9ubHl8Zmlyc3R8bGFzdHxudGh8bnRoLWxhc3QpLShjaGlsZHxvZi10eXBlKSg/OlxcXFwoXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcdFwiKihldmVufG9kZHwoKFsrLV18KShcXFxcZCopbnwpXCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86KFsrLV18KVwiICsgd2hpdGVzcGFjZSArXG5cdFx0XHRcIiooXFxcXGQrKXwpKVwiICsgd2hpdGVzcGFjZSArIFwiKlxcXFwpfClcIiwgXCJpXCIgKSxcblx0XHRcImJvb2xcIjogbmV3IFJlZ0V4cCggXCJeKD86XCIgKyBib29sZWFucyArIFwiKSRcIiwgXCJpXCIgKSxcblx0XHQvLyBGb3IgdXNlIGluIGxpYnJhcmllcyBpbXBsZW1lbnRpbmcgLmlzKClcblx0XHQvLyBXZSB1c2UgdGhpcyBmb3IgUE9TIG1hdGNoaW5nIGluIGBzZWxlY3RgXG5cdFx0XCJuZWVkc0NvbnRleHRcIjogbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIqWz4rfl18OihldmVufG9kZHxlcXxndHxsdHxudGh8Zmlyc3R8bGFzdCkoPzpcXFxcKFwiICtcblx0XHRcdHdoaXRlc3BhY2UgKyBcIiooKD86LVxcXFxkKT9cXFxcZCopXCIgKyB3aGl0ZXNwYWNlICsgXCIqXFxcXCl8KSg/PVteLV18JClcIiwgXCJpXCIgKVxuXHR9LFxuXG5cdHJpbnB1dHMgPSAvXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b24pJC9pLFxuXHRyaGVhZGVyID0gL15oXFxkJC9pLFxuXG5cdHJuYXRpdmUgPSAvXltee10rXFx7XFxzKlxcW25hdGl2ZSBcXHcvLFxuXG5cdC8vIEVhc2lseS1wYXJzZWFibGUvcmV0cmlldmFibGUgSUQgb3IgVEFHIG9yIENMQVNTIHNlbGVjdG9yc1xuXHRycXVpY2tFeHByID0gL14oPzojKFtcXHctXSspfChcXHcrKXxcXC4oW1xcdy1dKykpJC8sXG5cblx0cnNpYmxpbmcgPSAvWyt+XS8sXG5cdHJlc2NhcGUgPSAvJ3xcXFxcL2csXG5cblx0Ly8gQ1NTIGVzY2FwZXMgaHR0cDovL3d3dy53My5vcmcvVFIvQ1NTMjEvc3luZGF0YS5odG1sI2VzY2FwZWQtY2hhcmFjdGVyc1xuXHRydW5lc2NhcGUgPSBuZXcgUmVnRXhwKCBcIlxcXFxcXFxcKFtcXFxcZGEtZl17MSw2fVwiICsgd2hpdGVzcGFjZSArIFwiP3woXCIgKyB3aGl0ZXNwYWNlICsgXCIpfC4pXCIsIFwiaWdcIiApLFxuXHRmdW5lc2NhcGUgPSBmdW5jdGlvbiggXywgZXNjYXBlZCwgZXNjYXBlZFdoaXRlc3BhY2UgKSB7XG5cdFx0dmFyIGhpZ2ggPSBcIjB4XCIgKyBlc2NhcGVkIC0gMHgxMDAwMDtcblx0XHQvLyBOYU4gbWVhbnMgbm9uLWNvZGVwb2ludFxuXHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3g8MjRcblx0XHQvLyBXb3JrYXJvdW5kIGVycm9uZW91cyBudW1lcmljIGludGVycHJldGF0aW9uIG9mICtcIjB4XCJcblx0XHRyZXR1cm4gaGlnaCAhPT0gaGlnaCB8fCBlc2NhcGVkV2hpdGVzcGFjZSA/XG5cdFx0XHRlc2NhcGVkIDpcblx0XHRcdGhpZ2ggPCAwID9cblx0XHRcdFx0Ly8gQk1QIGNvZGVwb2ludFxuXHRcdFx0XHRTdHJpbmcuZnJvbUNoYXJDb2RlKCBoaWdoICsgMHgxMDAwMCApIDpcblx0XHRcdFx0Ly8gU3VwcGxlbWVudGFsIFBsYW5lIGNvZGVwb2ludCAoc3Vycm9nYXRlIHBhaXIpXG5cdFx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoIGhpZ2ggPj4gMTAgfCAweEQ4MDAsIGhpZ2ggJiAweDNGRiB8IDB4REMwMCApO1xuXHR9O1xuXG4vLyBPcHRpbWl6ZSBmb3IgcHVzaC5hcHBseSggXywgTm9kZUxpc3QgKVxudHJ5IHtcblx0cHVzaC5hcHBseShcblx0XHQoYXJyID0gc2xpY2UuY2FsbCggcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMgKSksXG5cdFx0cHJlZmVycmVkRG9jLmNoaWxkTm9kZXNcblx0KTtcblx0Ly8gU3VwcG9ydDogQW5kcm9pZDw0LjBcblx0Ly8gRGV0ZWN0IHNpbGVudGx5IGZhaWxpbmcgcHVzaC5hcHBseVxuXHRhcnJbIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzLmxlbmd0aCBdLm5vZGVUeXBlO1xufSBjYXRjaCAoIGUgKSB7XG5cdHB1c2ggPSB7IGFwcGx5OiBhcnIubGVuZ3RoID9cblxuXHRcdC8vIExldmVyYWdlIHNsaWNlIGlmIHBvc3NpYmxlXG5cdFx0ZnVuY3Rpb24oIHRhcmdldCwgZWxzICkge1xuXHRcdFx0cHVzaF9uYXRpdmUuYXBwbHkoIHRhcmdldCwgc2xpY2UuY2FsbChlbHMpICk7XG5cdFx0fSA6XG5cblx0XHQvLyBTdXBwb3J0OiBJRTw5XG5cdFx0Ly8gT3RoZXJ3aXNlIGFwcGVuZCBkaXJlY3RseVxuXHRcdGZ1bmN0aW9uKCB0YXJnZXQsIGVscyApIHtcblx0XHRcdHZhciBqID0gdGFyZ2V0Lmxlbmd0aCxcblx0XHRcdFx0aSA9IDA7XG5cdFx0XHQvLyBDYW4ndCB0cnVzdCBOb2RlTGlzdC5sZW5ndGhcblx0XHRcdHdoaWxlICggKHRhcmdldFtqKytdID0gZWxzW2krK10pICkge31cblx0XHRcdHRhcmdldC5sZW5ndGggPSBqIC0gMTtcblx0XHR9XG5cdH07XG59XG5cbmZ1bmN0aW9uIFNpenpsZSggc2VsZWN0b3IsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKSB7XG5cdHZhciBtYXRjaCwgZWxlbSwgbSwgbm9kZVR5cGUsXG5cdFx0Ly8gUVNBIHZhcnNcblx0XHRpLCBncm91cHMsIG9sZCwgbmlkLCBuZXdDb250ZXh0LCBuZXdTZWxlY3RvcjtcblxuXHRpZiAoICggY29udGV4dCA/IGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0IDogcHJlZmVycmVkRG9jICkgIT09IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XG5cdH1cblxuXHRjb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDtcblx0cmVzdWx0cyA9IHJlc3VsdHMgfHwgW107XG5cblx0aWYgKCAhc2VsZWN0b3IgfHwgdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiByZXN1bHRzO1xuXHR9XG5cblx0aWYgKCAobm9kZVR5cGUgPSBjb250ZXh0Lm5vZGVUeXBlKSAhPT0gMSAmJiBub2RlVHlwZSAhPT0gOSApIHtcblx0XHRyZXR1cm4gW107XG5cdH1cblxuXHRpZiAoIGRvY3VtZW50SXNIVE1MICYmICFzZWVkICkge1xuXG5cdFx0Ly8gU2hvcnRjdXRzXG5cdFx0aWYgKCAobWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICkpICkge1xuXHRcdFx0Ly8gU3BlZWQtdXA6IFNpenpsZShcIiNJRFwiKVxuXHRcdFx0aWYgKCAobSA9IG1hdGNoWzFdKSApIHtcblx0XHRcdFx0aWYgKCBub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0XHRlbGVtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggbSApO1xuXHRcdFx0XHRcdC8vIENoZWNrIHBhcmVudE5vZGUgdG8gY2F0Y2ggd2hlbiBCbGFja2JlcnJ5IDQuNiByZXR1cm5zXG5cdFx0XHRcdFx0Ly8gbm9kZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIGluIHRoZSBkb2N1bWVudCAoalF1ZXJ5ICM2OTYzKVxuXHRcdFx0XHRcdGlmICggZWxlbSAmJiBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdFx0XHQvLyBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgSUUsIE9wZXJhLCBhbmQgV2Via2l0IHJldHVybiBpdGVtc1xuXHRcdFx0XHRcdFx0Ly8gYnkgbmFtZSBpbnN0ZWFkIG9mIElEXG5cdFx0XHRcdFx0XHRpZiAoIGVsZW0uaWQgPT09IG0gKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIENvbnRleHQgaXMgbm90IGEgZG9jdW1lbnRcblx0XHRcdFx0XHRpZiAoIGNvbnRleHQub3duZXJEb2N1bWVudCAmJiAoZWxlbSA9IGNvbnRleHQub3duZXJEb2N1bWVudC5nZXRFbGVtZW50QnlJZCggbSApKSAmJlxuXHRcdFx0XHRcdFx0Y29udGFpbnMoIGNvbnRleHQsIGVsZW0gKSAmJiBlbGVtLmlkID09PSBtICkge1xuXHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gU3BlZWQtdXA6IFNpenpsZShcIlRBR1wiKVxuXHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbMl0gKSB7XG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHNlbGVjdG9yICkgKTtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cblx0XHRcdC8vIFNwZWVkLXVwOiBTaXp6bGUoXCIuQ0xBU1NcIilcblx0XHRcdH0gZWxzZSBpZiAoIChtID0gbWF0Y2hbM10pICYmIHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAmJiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKSB7XG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggbSApICk7XG5cdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFFTQSBwYXRoXG5cdFx0aWYgKCBzdXBwb3J0LnFzYSAmJiAoIXJidWdneVFTQSB8fCAhcmJ1Z2d5UVNBLnRlc3QoIHNlbGVjdG9yICkpICkge1xuXHRcdFx0bmlkID0gb2xkID0gZXhwYW5kbztcblx0XHRcdG5ld0NvbnRleHQgPSBjb250ZXh0O1xuXHRcdFx0bmV3U2VsZWN0b3IgPSBub2RlVHlwZSA9PT0gOSAmJiBzZWxlY3RvcjtcblxuXHRcdFx0Ly8gcVNBIHdvcmtzIHN0cmFuZ2VseSBvbiBFbGVtZW50LXJvb3RlZCBxdWVyaWVzXG5cdFx0XHQvLyBXZSBjYW4gd29yayBhcm91bmQgdGhpcyBieSBzcGVjaWZ5aW5nIGFuIGV4dHJhIElEIG9uIHRoZSByb290XG5cdFx0XHQvLyBhbmQgd29ya2luZyB1cCBmcm9tIHRoZXJlIChUaGFua3MgdG8gQW5kcmV3IER1cG9udCBmb3IgdGhlIHRlY2huaXF1ZSlcblx0XHRcdC8vIElFIDggZG9lc24ndCB3b3JrIG9uIG9iamVjdCBlbGVtZW50c1xuXHRcdFx0aWYgKCBub2RlVHlwZSA9PT0gMSAmJiBjb250ZXh0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgIT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHRcdGdyb3VwcyA9IHRva2VuaXplKCBzZWxlY3RvciApO1xuXG5cdFx0XHRcdGlmICggKG9sZCA9IGNvbnRleHQuZ2V0QXR0cmlidXRlKFwiaWRcIikpICkge1xuXHRcdFx0XHRcdG5pZCA9IG9sZC5yZXBsYWNlKCByZXNjYXBlLCBcIlxcXFwkJlwiICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y29udGV4dC5zZXRBdHRyaWJ1dGUoIFwiaWRcIiwgbmlkICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0bmlkID0gXCJbaWQ9J1wiICsgbmlkICsgXCInXSBcIjtcblxuXHRcdFx0XHRpID0gZ3JvdXBzLmxlbmd0aDtcblx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0Z3JvdXBzW2ldID0gbmlkICsgdG9TZWxlY3RvciggZ3JvdXBzW2ldICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0bmV3Q29udGV4dCA9IHJzaWJsaW5nLnRlc3QoIHNlbGVjdG9yICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHQ7XG5cdFx0XHRcdG5ld1NlbGVjdG9yID0gZ3JvdXBzLmpvaW4oXCIsXCIpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG5ld1NlbGVjdG9yICkge1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsXG5cdFx0XHRcdFx0XHRuZXdDb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIG5ld1NlbGVjdG9yIClcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHR9IGNhdGNoKHFzYUVycm9yKSB7XG5cdFx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHRcdFx0aWYgKCAhb2xkICkge1xuXHRcdFx0XHRcdFx0Y29udGV4dC5yZW1vdmVBdHRyaWJ1dGUoXCJpZFwiKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBBbGwgb3RoZXJzXG5cdHJldHVybiBzZWxlY3QoIHNlbGVjdG9yLnJlcGxhY2UoIHJ0cmltLCBcIiQxXCIgKSwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApO1xufVxuXG4vKipcbiAqIENyZWF0ZSBrZXktdmFsdWUgY2FjaGVzIG9mIGxpbWl0ZWQgc2l6ZVxuICogQHJldHVybnMge0Z1bmN0aW9uKHN0cmluZywgT2JqZWN0KX0gUmV0dXJucyB0aGUgT2JqZWN0IGRhdGEgYWZ0ZXIgc3RvcmluZyBpdCBvbiBpdHNlbGYgd2l0aFxuICpcdHByb3BlcnR5IG5hbWUgdGhlIChzcGFjZS1zdWZmaXhlZCkgc3RyaW5nIGFuZCAoaWYgdGhlIGNhY2hlIGlzIGxhcmdlciB0aGFuIEV4cHIuY2FjaGVMZW5ndGgpXG4gKlx0ZGVsZXRpbmcgdGhlIG9sZGVzdCBlbnRyeVxuICovXG5mdW5jdGlvbiBjcmVhdGVDYWNoZSgpIHtcblx0dmFyIGtleXMgPSBbXTtcblxuXHRmdW5jdGlvbiBjYWNoZSgga2V5LCB2YWx1ZSApIHtcblx0XHQvLyBVc2UgKGtleSArIFwiIFwiKSB0byBhdm9pZCBjb2xsaXNpb24gd2l0aCBuYXRpdmUgcHJvdG90eXBlIHByb3BlcnRpZXMgKHNlZSBJc3N1ZSAjMTU3KVxuXHRcdGlmICgga2V5cy5wdXNoKCBrZXkgKyBcIiBcIiApID4gRXhwci5jYWNoZUxlbmd0aCApIHtcblx0XHRcdC8vIE9ubHkga2VlcCB0aGUgbW9zdCByZWNlbnQgZW50cmllc1xuXHRcdFx0ZGVsZXRlIGNhY2hlWyBrZXlzLnNoaWZ0KCkgXTtcblx0XHR9XG5cdFx0cmV0dXJuIChjYWNoZVsga2V5ICsgXCIgXCIgXSA9IHZhbHVlKTtcblx0fVxuXHRyZXR1cm4gY2FjaGU7XG59XG5cbi8qKlxuICogTWFyayBhIGZ1bmN0aW9uIGZvciBzcGVjaWFsIHVzZSBieSBTaXp6bGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBtYXJrXG4gKi9cbmZ1bmN0aW9uIG1hcmtGdW5jdGlvbiggZm4gKSB7XG5cdGZuWyBleHBhbmRvIF0gPSB0cnVlO1xuXHRyZXR1cm4gZm47XG59XG5cbi8qKlxuICogU3VwcG9ydCB0ZXN0aW5nIHVzaW5nIGFuIGVsZW1lbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFBhc3NlZCB0aGUgY3JlYXRlZCBkaXYgYW5kIGV4cGVjdHMgYSBib29sZWFuIHJlc3VsdFxuICovXG5mdW5jdGlvbiBhc3NlcnQoIGZuICkge1xuXHR2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblxuXHR0cnkge1xuXHRcdHJldHVybiAhIWZuKCBkaXYgKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fSBmaW5hbGx5IHtcblx0XHQvLyBSZW1vdmUgZnJvbSBpdHMgcGFyZW50IGJ5IGRlZmF1bHRcblx0XHRpZiAoIGRpdi5wYXJlbnROb2RlICkge1xuXHRcdFx0ZGl2LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGRpdiApO1xuXHRcdH1cblx0XHQvLyByZWxlYXNlIG1lbW9yeSBpbiBJRVxuXHRcdGRpdiA9IG51bGw7XG5cdH1cbn1cblxuLyoqXG4gKiBBZGRzIHRoZSBzYW1lIGhhbmRsZXIgZm9yIGFsbCBvZiB0aGUgc3BlY2lmaWVkIGF0dHJzXG4gKiBAcGFyYW0ge1N0cmluZ30gYXR0cnMgUGlwZS1zZXBhcmF0ZWQgbGlzdCBvZiBhdHRyaWJ1dGVzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyIFRoZSBtZXRob2QgdGhhdCB3aWxsIGJlIGFwcGxpZWRcbiAqL1xuZnVuY3Rpb24gYWRkSGFuZGxlKCBhdHRycywgaGFuZGxlciApIHtcblx0dmFyIGFyciA9IGF0dHJzLnNwbGl0KFwifFwiKSxcblx0XHRpID0gYXR0cnMubGVuZ3RoO1xuXG5cdHdoaWxlICggaS0tICkge1xuXHRcdEV4cHIuYXR0ckhhbmRsZVsgYXJyW2ldIF0gPSBoYW5kbGVyO1xuXHR9XG59XG5cbi8qKlxuICogQ2hlY2tzIGRvY3VtZW50IG9yZGVyIG9mIHR3byBzaWJsaW5nc1xuICogQHBhcmFtIHtFbGVtZW50fSBhXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFJldHVybnMgbGVzcyB0aGFuIDAgaWYgYSBwcmVjZWRlcyBiLCBncmVhdGVyIHRoYW4gMCBpZiBhIGZvbGxvd3MgYlxuICovXG5mdW5jdGlvbiBzaWJsaW5nQ2hlY2soIGEsIGIgKSB7XG5cdHZhciBjdXIgPSBiICYmIGEsXG5cdFx0ZGlmZiA9IGN1ciAmJiBhLm5vZGVUeXBlID09PSAxICYmIGIubm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdCggfmIuc291cmNlSW5kZXggfHwgTUFYX05FR0FUSVZFICkgLVxuXHRcdFx0KCB+YS5zb3VyY2VJbmRleCB8fCBNQVhfTkVHQVRJVkUgKTtcblxuXHQvLyBVc2UgSUUgc291cmNlSW5kZXggaWYgYXZhaWxhYmxlIG9uIGJvdGggbm9kZXNcblx0aWYgKCBkaWZmICkge1xuXHRcdHJldHVybiBkaWZmO1xuXHR9XG5cblx0Ly8gQ2hlY2sgaWYgYiBmb2xsb3dzIGFcblx0aWYgKCBjdXIgKSB7XG5cdFx0d2hpbGUgKCAoY3VyID0gY3VyLm5leHRTaWJsaW5nKSApIHtcblx0XHRcdGlmICggY3VyID09PSBiICkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGEgPyAxIDogLTE7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBpbnB1dCB0eXBlc1xuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5wdXRQc2V1ZG8oIHR5cGUgKSB7XG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgbmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRyZXR1cm4gbmFtZSA9PT0gXCJpbnB1dFwiICYmIGVsZW0udHlwZSA9PT0gdHlwZTtcblx0fTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIGJ1dHRvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJ1dHRvblBzZXVkbyggdHlwZSApIHtcblx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdHJldHVybiAobmFtZSA9PT0gXCJpbnB1dFwiIHx8IG5hbWUgPT09IFwiYnV0dG9uXCIpICYmIGVsZW0udHlwZSA9PT0gdHlwZTtcblx0fTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIHBvc2l0aW9uYWxzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICovXG5mdW5jdGlvbiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmbiApIHtcblx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggYXJndW1lbnQgKSB7XG5cdFx0YXJndW1lbnQgPSArYXJndW1lbnQ7XG5cdFx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcblx0XHRcdHZhciBqLFxuXHRcdFx0XHRtYXRjaEluZGV4ZXMgPSBmbiggW10sIHNlZWQubGVuZ3RoLCBhcmd1bWVudCApLFxuXHRcdFx0XHRpID0gbWF0Y2hJbmRleGVzLmxlbmd0aDtcblxuXHRcdFx0Ly8gTWF0Y2ggZWxlbWVudHMgZm91bmQgYXQgdGhlIHNwZWNpZmllZCBpbmRleGVzXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCBzZWVkWyAoaiA9IG1hdGNoSW5kZXhlc1tpXSkgXSApIHtcblx0XHRcdFx0XHRzZWVkW2pdID0gIShtYXRjaGVzW2pdID0gc2VlZFtqXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0fSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGEgbm9kZSBmb3IgdmFsaWRpdHkgYXMgYSBTaXp6bGUgY29udGV4dFxuICogQHBhcmFtIHtFbGVtZW50fE9iamVjdD19IGNvbnRleHRcbiAqIEByZXR1cm5zIHtFbGVtZW50fE9iamVjdHxCb29sZWFufSBUaGUgaW5wdXQgbm9kZSBpZiBhY2NlcHRhYmxlLCBvdGhlcndpc2UgYSBmYWxzeSB2YWx1ZVxuICovXG5mdW5jdGlvbiB0ZXN0Q29udGV4dCggY29udGV4dCApIHtcblx0cmV0dXJuIGNvbnRleHQgJiYgdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IHN0cnVuZGVmaW5lZCAmJiBjb250ZXh0O1xufVxuXG4vLyBFeHBvc2Ugc3VwcG9ydCB2YXJzIGZvciBjb252ZW5pZW5jZVxuc3VwcG9ydCA9IFNpenpsZS5zdXBwb3J0ID0ge307XG5cbi8qKlxuICogRGV0ZWN0cyBYTUwgbm9kZXNcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IGVsZW0gQW4gZWxlbWVudCBvciBhIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZmYgZWxlbSBpcyBhIG5vbi1IVE1MIFhNTCBub2RlXG4gKi9cbmlzWE1MID0gU2l6emxlLmlzWE1MID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdC8vIGRvY3VtZW50RWxlbWVudCBpcyB2ZXJpZmllZCBmb3IgY2FzZXMgd2hlcmUgaXQgZG9lc24ndCB5ZXQgZXhpc3Rcblx0Ly8gKHN1Y2ggYXMgbG9hZGluZyBpZnJhbWVzIGluIElFIC0gIzQ4MzMpXG5cdHZhciBkb2N1bWVudEVsZW1lbnQgPSBlbGVtICYmIChlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSkuZG9jdW1lbnRFbGVtZW50O1xuXHRyZXR1cm4gZG9jdW1lbnRFbGVtZW50ID8gZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lICE9PSBcIkhUTUxcIiA6IGZhbHNlO1xufTtcblxuLyoqXG4gKiBTZXRzIGRvY3VtZW50LXJlbGF0ZWQgdmFyaWFibGVzIG9uY2UgYmFzZWQgb24gdGhlIGN1cnJlbnQgZG9jdW1lbnRcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IFtkb2NdIEFuIGVsZW1lbnQgb3IgZG9jdW1lbnQgb2JqZWN0IHRvIHVzZSB0byBzZXQgdGhlIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjdXJyZW50IGRvY3VtZW50XG4gKi9cbnNldERvY3VtZW50ID0gU2l6emxlLnNldERvY3VtZW50ID0gZnVuY3Rpb24oIG5vZGUgKSB7XG5cdHZhciBoYXNDb21wYXJlLFxuXHRcdGRvYyA9IG5vZGUgPyBub2RlLm93bmVyRG9jdW1lbnQgfHwgbm9kZSA6IHByZWZlcnJlZERvYyxcblx0XHRwYXJlbnQgPSBkb2MuZGVmYXVsdFZpZXc7XG5cblx0Ly8gSWYgbm8gZG9jdW1lbnQgYW5kIGRvY3VtZW50RWxlbWVudCBpcyBhdmFpbGFibGUsIHJldHVyblxuXHRpZiAoIGRvYyA9PT0gZG9jdW1lbnQgfHwgZG9jLm5vZGVUeXBlICE9PSA5IHx8ICFkb2MuZG9jdW1lbnRFbGVtZW50ICkge1xuXHRcdHJldHVybiBkb2N1bWVudDtcblx0fVxuXG5cdC8vIFNldCBvdXIgZG9jdW1lbnRcblx0ZG9jdW1lbnQgPSBkb2M7XG5cdGRvY0VsZW0gPSBkb2MuZG9jdW1lbnRFbGVtZW50O1xuXG5cdC8vIFN1cHBvcnQgdGVzdHNcblx0ZG9jdW1lbnRJc0hUTUwgPSAhaXNYTUwoIGRvYyApO1xuXG5cdC8vIFN1cHBvcnQ6IElFPjhcblx0Ly8gSWYgaWZyYW1lIGRvY3VtZW50IGlzIGFzc2lnbmVkIHRvIFwiZG9jdW1lbnRcIiB2YXJpYWJsZSBhbmQgaWYgaWZyYW1lIGhhcyBiZWVuIHJlbG9hZGVkLFxuXHQvLyBJRSB3aWxsIHRocm93IFwicGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIGFjY2Vzc2luZyBcImRvY3VtZW50XCIgdmFyaWFibGUsIHNlZSBqUXVlcnkgIzEzOTM2XG5cdC8vIElFNi04IGRvIG5vdCBzdXBwb3J0IHRoZSBkZWZhdWx0VmlldyBwcm9wZXJ0eSBzbyBwYXJlbnQgd2lsbCBiZSB1bmRlZmluZWRcblx0aWYgKCBwYXJlbnQgJiYgcGFyZW50ICE9PSBwYXJlbnQudG9wICkge1xuXHRcdC8vIElFMTEgZG9lcyBub3QgaGF2ZSBhdHRhY2hFdmVudCwgc28gYWxsIG11c3Qgc3VmZmVyXG5cdFx0aWYgKCBwYXJlbnQuYWRkRXZlbnRMaXN0ZW5lciApIHtcblx0XHRcdHBhcmVudC5hZGRFdmVudExpc3RlbmVyKCBcInVubG9hZFwiLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0c2V0RG9jdW1lbnQoKTtcblx0XHRcdH0sIGZhbHNlICk7XG5cdFx0fSBlbHNlIGlmICggcGFyZW50LmF0dGFjaEV2ZW50ICkge1xuXHRcdFx0cGFyZW50LmF0dGFjaEV2ZW50KCBcIm9udW5sb2FkXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRzZXREb2N1bWVudCgpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0LyogQXR0cmlidXRlc1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gU3VwcG9ydDogSUU8OFxuXHQvLyBWZXJpZnkgdGhhdCBnZXRBdHRyaWJ1dGUgcmVhbGx5IHJldHVybnMgYXR0cmlidXRlcyBhbmQgbm90IHByb3BlcnRpZXMgKGV4Y2VwdGluZyBJRTggYm9vbGVhbnMpXG5cdHN1cHBvcnQuYXR0cmlidXRlcyA9IGFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRcdGRpdi5jbGFzc05hbWUgPSBcImlcIjtcblx0XHRyZXR1cm4gIWRpdi5nZXRBdHRyaWJ1dGUoXCJjbGFzc05hbWVcIik7XG5cdH0pO1xuXG5cdC8qIGdldEVsZW1lbnQocylCeSpcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIENoZWNrIGlmIGdldEVsZW1lbnRzQnlUYWdOYW1lKFwiKlwiKSByZXR1cm5zIG9ubHkgZWxlbWVudHNcblx0c3VwcG9ydC5nZXRFbGVtZW50c0J5VGFnTmFtZSA9IGFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRcdGRpdi5hcHBlbmRDaGlsZCggZG9jLmNyZWF0ZUNvbW1lbnQoXCJcIikgKTtcblx0XHRyZXR1cm4gIWRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZShcIipcIikubGVuZ3RoO1xuXHR9KTtcblxuXHQvLyBDaGVjayBpZiBnZXRFbGVtZW50c0J5Q2xhc3NOYW1lIGNhbiBiZSB0cnVzdGVkXG5cdHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSA9IHJuYXRpdmUudGVzdCggZG9jLmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKSAmJiBhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRkaXYuaW5uZXJIVE1MID0gXCI8ZGl2IGNsYXNzPSdhJz48L2Rpdj48ZGl2IGNsYXNzPSdhIGknPjwvZGl2PlwiO1xuXG5cdFx0Ly8gU3VwcG9ydDogU2FmYXJpPDRcblx0XHQvLyBDYXRjaCBjbGFzcyBvdmVyLWNhY2hpbmdcblx0XHRkaXYuZmlyc3RDaGlsZC5jbGFzc05hbWUgPSBcImlcIjtcblx0XHQvLyBTdXBwb3J0OiBPcGVyYTwxMFxuXHRcdC8vIENhdGNoIGdFQkNOIGZhaWx1cmUgdG8gZmluZCBub24tbGVhZGluZyBjbGFzc2VzXG5cdFx0cmV0dXJuIGRpdi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiaVwiKS5sZW5ndGggPT09IDI7XG5cdH0pO1xuXG5cdC8vIFN1cHBvcnQ6IElFPDEwXG5cdC8vIENoZWNrIGlmIGdldEVsZW1lbnRCeUlkIHJldHVybnMgZWxlbWVudHMgYnkgbmFtZVxuXHQvLyBUaGUgYnJva2VuIGdldEVsZW1lbnRCeUlkIG1ldGhvZHMgZG9uJ3QgcGljayB1cCBwcm9ncmFtYXRpY2FsbHktc2V0IG5hbWVzLFxuXHQvLyBzbyB1c2UgYSByb3VuZGFib3V0IGdldEVsZW1lbnRzQnlOYW1lIHRlc3Rcblx0c3VwcG9ydC5nZXRCeUlkID0gYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0ZG9jRWxlbS5hcHBlbmRDaGlsZCggZGl2ICkuaWQgPSBleHBhbmRvO1xuXHRcdHJldHVybiAhZG9jLmdldEVsZW1lbnRzQnlOYW1lIHx8ICFkb2MuZ2V0RWxlbWVudHNCeU5hbWUoIGV4cGFuZG8gKS5sZW5ndGg7XG5cdH0pO1xuXG5cdC8vIElEIGZpbmQgYW5kIGZpbHRlclxuXHRpZiAoIHN1cHBvcnQuZ2V0QnlJZCApIHtcblx0XHRFeHByLmZpbmRbXCJJRFwiXSA9IGZ1bmN0aW9uKCBpZCwgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQgIT09IHN0cnVuZGVmaW5lZCAmJiBkb2N1bWVudElzSFRNTCApIHtcblx0XHRcdFx0dmFyIG0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKCBpZCApO1xuXHRcdFx0XHQvLyBDaGVjayBwYXJlbnROb2RlIHRvIGNhdGNoIHdoZW4gQmxhY2tiZXJyeSA0LjYgcmV0dXJuc1xuXHRcdFx0XHQvLyBub2RlcyB0aGF0IGFyZSBubyBsb25nZXIgaW4gdGhlIGRvY3VtZW50ICM2OTYzXG5cdFx0XHRcdHJldHVybiBtICYmIG0ucGFyZW50Tm9kZSA/IFsgbSBdIDogW107XG5cdFx0XHR9XG5cdFx0fTtcblx0XHRFeHByLmZpbHRlcltcIklEXCJdID0gZnVuY3Rpb24oIGlkICkge1xuXHRcdFx0dmFyIGF0dHJJZCA9IGlkLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZShcImlkXCIpID09PSBhdHRySWQ7XG5cdFx0XHR9O1xuXHRcdH07XG5cdH0gZWxzZSB7XG5cdFx0Ly8gU3VwcG9ydDogSUU2Lzdcblx0XHQvLyBnZXRFbGVtZW50QnlJZCBpcyBub3QgcmVsaWFibGUgYXMgYSBmaW5kIHNob3J0Y3V0XG5cdFx0ZGVsZXRlIEV4cHIuZmluZFtcIklEXCJdO1xuXG5cdFx0RXhwci5maWx0ZXJbXCJJRFwiXSA9ICBmdW5jdGlvbiggaWQgKSB7XG5cdFx0XHR2YXIgYXR0cklkID0gaWQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIG5vZGUgPSB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGVOb2RlICE9PSBzdHJ1bmRlZmluZWQgJiYgZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKFwiaWRcIik7XG5cdFx0XHRcdHJldHVybiBub2RlICYmIG5vZGUudmFsdWUgPT09IGF0dHJJZDtcblx0XHRcdH07XG5cdFx0fTtcblx0fVxuXG5cdC8vIFRhZ1xuXHRFeHByLmZpbmRbXCJUQUdcIl0gPSBzdXBwb3J0LmdldEVsZW1lbnRzQnlUYWdOYW1lID9cblx0XHRmdW5jdGlvbiggdGFnLCBjb250ZXh0ICkge1xuXHRcdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gc3RydW5kZWZpbmVkICkge1xuXHRcdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XG5cdFx0XHR9XG5cdFx0fSA6XG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcblx0XHRcdHZhciBlbGVtLFxuXHRcdFx0XHR0bXAgPSBbXSxcblx0XHRcdFx0aSA9IDAsXG5cdFx0XHRcdHJlc3VsdHMgPSBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCB0YWcgKTtcblxuXHRcdFx0Ly8gRmlsdGVyIG91dCBwb3NzaWJsZSBjb21tZW50c1xuXHRcdFx0aWYgKCB0YWcgPT09IFwiKlwiICkge1xuXHRcdFx0XHR3aGlsZSAoIChlbGVtID0gcmVzdWx0c1tpKytdKSApIHtcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRcdFx0XHR0bXAucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB0bXA7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHR9O1xuXG5cdC8vIENsYXNzXG5cdEV4cHIuZmluZFtcIkNMQVNTXCJdID0gc3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICYmIGZ1bmN0aW9uKCBjbGFzc05hbWUsIGNvbnRleHQgKSB7XG5cdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICE9PSBzdHJ1bmRlZmluZWQgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCBjbGFzc05hbWUgKTtcblx0XHR9XG5cdH07XG5cblx0LyogUVNBL21hdGNoZXNTZWxlY3RvclxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gUVNBIGFuZCBtYXRjaGVzU2VsZWN0b3Igc3VwcG9ydFxuXG5cdC8vIG1hdGNoZXNTZWxlY3Rvcig6YWN0aXZlKSByZXBvcnRzIGZhbHNlIHdoZW4gdHJ1ZSAoSUU5L09wZXJhIDExLjUpXG5cdHJidWdneU1hdGNoZXMgPSBbXTtcblxuXHQvLyBxU2EoOmZvY3VzKSByZXBvcnRzIGZhbHNlIHdoZW4gdHJ1ZSAoQ2hyb21lIDIxKVxuXHQvLyBXZSBhbGxvdyB0aGlzIGJlY2F1c2Ugb2YgYSBidWcgaW4gSUU4LzkgdGhhdCB0aHJvd3MgYW4gZXJyb3Jcblx0Ly8gd2hlbmV2ZXIgYGRvY3VtZW50LmFjdGl2ZUVsZW1lbnRgIGlzIGFjY2Vzc2VkIG9uIGFuIGlmcmFtZVxuXHQvLyBTbywgd2UgYWxsb3cgOmZvY3VzIHRvIHBhc3MgdGhyb3VnaCBRU0EgYWxsIHRoZSB0aW1lIHRvIGF2b2lkIHRoZSBJRSBlcnJvclxuXHQvLyBTZWUgaHR0cDovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTMzNzhcblx0cmJ1Z2d5UVNBID0gW107XG5cblx0aWYgKCAoc3VwcG9ydC5xc2EgPSBybmF0aXZlLnRlc3QoIGRvYy5xdWVyeVNlbGVjdG9yQWxsICkpICkge1xuXHRcdC8vIEJ1aWxkIFFTQSByZWdleFxuXHRcdC8vIFJlZ2V4IHN0cmF0ZWd5IGFkb3B0ZWQgZnJvbSBEaWVnbyBQZXJpbmlcblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRcdC8vIFNlbGVjdCBpcyBzZXQgdG8gZW1wdHkgc3RyaW5nIG9uIHB1cnBvc2Vcblx0XHRcdC8vIFRoaXMgaXMgdG8gdGVzdCBJRSdzIHRyZWF0bWVudCBvZiBub3QgZXhwbGljaXRseVxuXHRcdFx0Ly8gc2V0dGluZyBhIGJvb2xlYW4gY29udGVudCBhdHRyaWJ1dGUsXG5cdFx0XHQvLyBzaW5jZSBpdHMgcHJlc2VuY2Ugc2hvdWxkIGJlIGVub3VnaFxuXHRcdFx0Ly8gaHR0cDovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTIzNTlcblx0XHRcdGRpdi5pbm5lckhUTUwgPSBcIjxzZWxlY3QgbXNhbGxvd2NsaXA9Jyc+PG9wdGlvbiBzZWxlY3RlZD0nJz48L29wdGlvbj48L3NlbGVjdD5cIjtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4LCBPcGVyYSAxMS0xMi4xNlxuXHRcdFx0Ly8gTm90aGluZyBzaG91bGQgYmUgc2VsZWN0ZWQgd2hlbiBlbXB0eSBzdHJpbmdzIGZvbGxvdyBePSBvciAkPSBvciAqPVxuXHRcdFx0Ly8gVGhlIHRlc3QgYXR0cmlidXRlIG11c3QgYmUgdW5rbm93biBpbiBPcGVyYSBidXQgXCJzYWZlXCIgZm9yIFdpblJUXG5cdFx0XHQvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvaGg0NjUzODguYXNweCNhdHRyaWJ1dGVfc2VjdGlvblxuXHRcdFx0aWYgKCBkaXYucXVlcnlTZWxlY3RvckFsbChcIlttc2FsbG93Y2xpcF49JyddXCIpLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiWypeJF09XCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86Jyd8XFxcIlxcXCIpXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4XG5cdFx0XHQvLyBCb29sZWFuIGF0dHJpYnV0ZXMgYW5kIFwidmFsdWVcIiBhcmUgbm90IHRyZWF0ZWQgY29ycmVjdGx5XG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIltzZWxlY3RlZF1cIikubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKig/OnZhbHVlfFwiICsgYm9vbGVhbnMgKyBcIilcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBXZWJraXQvT3BlcmEgLSA6Y2hlY2tlZCBzaG91bGQgcmV0dXJuIHNlbGVjdGVkIG9wdGlvbiBlbGVtZW50c1xuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvMjAxMS9SRUMtY3NzMy1zZWxlY3RvcnMtMjAxMTA5MjkvI2NoZWNrZWRcblx0XHRcdC8vIElFOCB0aHJvd3MgZXJyb3IgaGVyZSBhbmQgd2lsbCBub3Qgc2VlIGxhdGVyIHRlc3RzXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIjpjaGVja2VkXCIpLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goXCI6Y2hlY2tlZFwiKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdGFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRcdFx0Ly8gU3VwcG9ydDogV2luZG93cyA4IE5hdGl2ZSBBcHBzXG5cdFx0XHQvLyBUaGUgdHlwZSBhbmQgbmFtZSBhdHRyaWJ1dGVzIGFyZSByZXN0cmljdGVkIGR1cmluZyAuaW5uZXJIVE1MIGFzc2lnbm1lbnRcblx0XHRcdHZhciBpbnB1dCA9IGRvYy5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG5cdFx0XHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCBcImhpZGRlblwiICk7XG5cdFx0XHRkaXYuYXBwZW5kQ2hpbGQoIGlucHV0ICkuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJEXCIgKTtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4XG5cdFx0XHQvLyBFbmZvcmNlIGNhc2Utc2Vuc2l0aXZpdHkgb2YgbmFtZSBhdHRyaWJ1dGVcblx0XHRcdGlmICggZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZT1kXVwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIm5hbWVcIiArIHdoaXRlc3BhY2UgKyBcIipbKl4kfCF+XT89XCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRkYgMy41IC0gOmVuYWJsZWQvOmRpc2FibGVkIGFuZCBoaWRkZW4gZWxlbWVudHMgKGhpZGRlbiBlbGVtZW50cyBhcmUgc3RpbGwgZW5hYmxlZClcblx0XHRcdC8vIElFOCB0aHJvd3MgZXJyb3IgaGVyZSBhbmQgd2lsbCBub3Qgc2VlIGxhdGVyIHRlc3RzXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIjplbmFibGVkXCIpLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiOmVuYWJsZWRcIiwgXCI6ZGlzYWJsZWRcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPcGVyYSAxMC0xMSBkb2VzIG5vdCB0aHJvdyBvbiBwb3N0LWNvbW1hIGludmFsaWQgcHNldWRvc1xuXHRcdFx0ZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCIqLDp4XCIpO1xuXHRcdFx0cmJ1Z2d5UVNBLnB1c2goXCIsLio6XCIpO1xuXHRcdH0pO1xuXHR9XG5cblx0aWYgKCAoc3VwcG9ydC5tYXRjaGVzU2VsZWN0b3IgPSBybmF0aXZlLnRlc3QoIChtYXRjaGVzID0gZG9jRWxlbS5tYXRjaGVzIHx8XG5cdFx0ZG9jRWxlbS53ZWJraXRNYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRkb2NFbGVtLm1vek1hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY0VsZW0ub01hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY0VsZW0ubXNNYXRjaGVzU2VsZWN0b3IpICkpICkge1xuXG5cdFx0YXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0XHQvLyBDaGVjayB0byBzZWUgaWYgaXQncyBwb3NzaWJsZSB0byBkbyBtYXRjaGVzU2VsZWN0b3Jcblx0XHRcdC8vIG9uIGEgZGlzY29ubmVjdGVkIG5vZGUgKElFIDkpXG5cdFx0XHRzdXBwb3J0LmRpc2Nvbm5lY3RlZE1hdGNoID0gbWF0Y2hlcy5jYWxsKCBkaXYsIFwiZGl2XCIgKTtcblxuXHRcdFx0Ly8gVGhpcyBzaG91bGQgZmFpbCB3aXRoIGFuIGV4Y2VwdGlvblxuXHRcdFx0Ly8gR2Vja28gZG9lcyBub3QgZXJyb3IsIHJldHVybnMgZmFsc2UgaW5zdGVhZFxuXHRcdFx0bWF0Y2hlcy5jYWxsKCBkaXYsIFwiW3MhPScnXTp4XCIgKTtcblx0XHRcdHJidWdneU1hdGNoZXMucHVzaCggXCIhPVwiLCBwc2V1ZG9zICk7XG5cdFx0fSk7XG5cdH1cblxuXHRyYnVnZ3lRU0EgPSByYnVnZ3lRU0EubGVuZ3RoICYmIG5ldyBSZWdFeHAoIHJidWdneVFTQS5qb2luKFwifFwiKSApO1xuXHRyYnVnZ3lNYXRjaGVzID0gcmJ1Z2d5TWF0Y2hlcy5sZW5ndGggJiYgbmV3IFJlZ0V4cCggcmJ1Z2d5TWF0Y2hlcy5qb2luKFwifFwiKSApO1xuXG5cdC8qIENvbnRhaW5zXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblx0aGFzQ29tcGFyZSA9IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiApO1xuXG5cdC8vIEVsZW1lbnQgY29udGFpbnMgYW5vdGhlclxuXHQvLyBQdXJwb3NlZnVsbHkgZG9lcyBub3QgaW1wbGVtZW50IGluY2x1c2l2ZSBkZXNjZW5kZW50XG5cdC8vIEFzIGluLCBhbiBlbGVtZW50IGRvZXMgbm90IGNvbnRhaW4gaXRzZWxmXG5cdGNvbnRhaW5zID0gaGFzQ29tcGFyZSB8fCBybmF0aXZlLnRlc3QoIGRvY0VsZW0uY29udGFpbnMgKSA/XG5cdFx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0XHR2YXIgYWRvd24gPSBhLm5vZGVUeXBlID09PSA5ID8gYS5kb2N1bWVudEVsZW1lbnQgOiBhLFxuXHRcdFx0XHRidXAgPSBiICYmIGIucGFyZW50Tm9kZTtcblx0XHRcdHJldHVybiBhID09PSBidXAgfHwgISEoIGJ1cCAmJiBidXAubm9kZVR5cGUgPT09IDEgJiYgKFxuXHRcdFx0XHRhZG93bi5jb250YWlucyA/XG5cdFx0XHRcdFx0YWRvd24uY29udGFpbnMoIGJ1cCApIDpcblx0XHRcdFx0XHRhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uICYmIGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGJ1cCApICYgMTZcblx0XHRcdCkpO1xuXHRcdH0gOlxuXHRcdGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdFx0aWYgKCBiICkge1xuXHRcdFx0XHR3aGlsZSAoIChiID0gYi5wYXJlbnROb2RlKSApIHtcblx0XHRcdFx0XHRpZiAoIGIgPT09IGEgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9O1xuXG5cdC8qIFNvcnRpbmdcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIERvY3VtZW50IG9yZGVyIHNvcnRpbmdcblx0c29ydE9yZGVyID0gaGFzQ29tcGFyZSA/XG5cdGZ1bmN0aW9uKCBhLCBiICkge1xuXG5cdFx0Ly8gRmxhZyBmb3IgZHVwbGljYXRlIHJlbW92YWxcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0Ly8gU29ydCBvbiBtZXRob2QgZXhpc3RlbmNlIGlmIG9ubHkgb25lIGlucHV0IGhhcyBjb21wYXJlRG9jdW1lbnRQb3NpdGlvblxuXHRcdHZhciBjb21wYXJlID0gIWEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gLSAhYi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbjtcblx0XHRpZiAoIGNvbXBhcmUgKSB7XG5cdFx0XHRyZXR1cm4gY29tcGFyZTtcblx0XHR9XG5cblx0XHQvLyBDYWxjdWxhdGUgcG9zaXRpb24gaWYgYm90aCBpbnB1dHMgYmVsb25nIHRvIHRoZSBzYW1lIGRvY3VtZW50XG5cdFx0Y29tcGFyZSA9ICggYS5vd25lckRvY3VtZW50IHx8IGEgKSA9PT0gKCBiLm93bmVyRG9jdW1lbnQgfHwgYiApID9cblx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGIgKSA6XG5cblx0XHRcdC8vIE90aGVyd2lzZSB3ZSBrbm93IHRoZXkgYXJlIGRpc2Nvbm5lY3RlZFxuXHRcdFx0MTtcblxuXHRcdC8vIERpc2Nvbm5lY3RlZCBub2Rlc1xuXHRcdGlmICggY29tcGFyZSAmIDEgfHxcblx0XHRcdCghc3VwcG9ydC5zb3J0RGV0YWNoZWQgJiYgYi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYSApID09PSBjb21wYXJlKSApIHtcblxuXHRcdFx0Ly8gQ2hvb3NlIHRoZSBmaXJzdCBlbGVtZW50IHRoYXQgaXMgcmVsYXRlZCB0byBvdXIgcHJlZmVycmVkIGRvY3VtZW50XG5cdFx0XHRpZiAoIGEgPT09IGRvYyB8fCBhLm93bmVyRG9jdW1lbnQgPT09IHByZWZlcnJlZERvYyAmJiBjb250YWlucyhwcmVmZXJyZWREb2MsIGEpICkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIGIgPT09IGRvYyB8fCBiLm93bmVyRG9jdW1lbnQgPT09IHByZWZlcnJlZERvYyAmJiBjb250YWlucyhwcmVmZXJyZWREb2MsIGIpICkge1xuXHRcdFx0XHRyZXR1cm4gMTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFpbnRhaW4gb3JpZ2luYWwgb3JkZXJcblx0XHRcdHJldHVybiBzb3J0SW5wdXQgP1xuXHRcdFx0XHQoIGluZGV4T2YuY2FsbCggc29ydElucHV0LCBhICkgLSBpbmRleE9mLmNhbGwoIHNvcnRJbnB1dCwgYiApICkgOlxuXHRcdFx0XHQwO1xuXHRcdH1cblxuXHRcdHJldHVybiBjb21wYXJlICYgNCA/IC0xIDogMTtcblx0fSA6XG5cdGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdC8vIEV4aXQgZWFybHkgaWYgdGhlIG5vZGVzIGFyZSBpZGVudGljYWxcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0dmFyIGN1cixcblx0XHRcdGkgPSAwLFxuXHRcdFx0YXVwID0gYS5wYXJlbnROb2RlLFxuXHRcdFx0YnVwID0gYi5wYXJlbnROb2RlLFxuXHRcdFx0YXAgPSBbIGEgXSxcblx0XHRcdGJwID0gWyBiIF07XG5cblx0XHQvLyBQYXJlbnRsZXNzIG5vZGVzIGFyZSBlaXRoZXIgZG9jdW1lbnRzIG9yIGRpc2Nvbm5lY3RlZFxuXHRcdGlmICggIWF1cCB8fCAhYnVwICkge1xuXHRcdFx0cmV0dXJuIGEgPT09IGRvYyA/IC0xIDpcblx0XHRcdFx0YiA9PT0gZG9jID8gMSA6XG5cdFx0XHRcdGF1cCA/IC0xIDpcblx0XHRcdFx0YnVwID8gMSA6XG5cdFx0XHRcdHNvcnRJbnB1dCA/XG5cdFx0XHRcdCggaW5kZXhPZi5jYWxsKCBzb3J0SW5wdXQsIGEgKSAtIGluZGV4T2YuY2FsbCggc29ydElucHV0LCBiICkgKSA6XG5cdFx0XHRcdDA7XG5cblx0XHQvLyBJZiB0aGUgbm9kZXMgYXJlIHNpYmxpbmdzLCB3ZSBjYW4gZG8gYSBxdWljayBjaGVja1xuXHRcdH0gZWxzZSBpZiAoIGF1cCA9PT0gYnVwICkge1xuXHRcdFx0cmV0dXJuIHNpYmxpbmdDaGVjayggYSwgYiApO1xuXHRcdH1cblxuXHRcdC8vIE90aGVyd2lzZSB3ZSBuZWVkIGZ1bGwgbGlzdHMgb2YgdGhlaXIgYW5jZXN0b3JzIGZvciBjb21wYXJpc29uXG5cdFx0Y3VyID0gYTtcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIucGFyZW50Tm9kZSkgKSB7XG5cdFx0XHRhcC51bnNoaWZ0KCBjdXIgKTtcblx0XHR9XG5cdFx0Y3VyID0gYjtcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIucGFyZW50Tm9kZSkgKSB7XG5cdFx0XHRicC51bnNoaWZ0KCBjdXIgKTtcblx0XHR9XG5cblx0XHQvLyBXYWxrIGRvd24gdGhlIHRyZWUgbG9va2luZyBmb3IgYSBkaXNjcmVwYW5jeVxuXHRcdHdoaWxlICggYXBbaV0gPT09IGJwW2ldICkge1xuXHRcdFx0aSsrO1xuXHRcdH1cblxuXHRcdHJldHVybiBpID9cblx0XHRcdC8vIERvIGEgc2libGluZyBjaGVjayBpZiB0aGUgbm9kZXMgaGF2ZSBhIGNvbW1vbiBhbmNlc3RvclxuXHRcdFx0c2libGluZ0NoZWNrKCBhcFtpXSwgYnBbaV0gKSA6XG5cblx0XHRcdC8vIE90aGVyd2lzZSBub2RlcyBpbiBvdXIgZG9jdW1lbnQgc29ydCBmaXJzdFxuXHRcdFx0YXBbaV0gPT09IHByZWZlcnJlZERvYyA/IC0xIDpcblx0XHRcdGJwW2ldID09PSBwcmVmZXJyZWREb2MgPyAxIDpcblx0XHRcdDA7XG5cdH07XG5cblx0cmV0dXJuIGRvYztcbn07XG5cblNpenpsZS5tYXRjaGVzID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1lbnRzICkge1xuXHRyZXR1cm4gU2l6emxlKCBleHByLCBudWxsLCBudWxsLCBlbGVtZW50cyApO1xufTtcblxuU2l6emxlLm1hdGNoZXNTZWxlY3RvciA9IGZ1bmN0aW9uKCBlbGVtLCBleHByICkge1xuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcblx0aWYgKCAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkgIT09IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBlbGVtICk7XG5cdH1cblxuXHQvLyBNYWtlIHN1cmUgdGhhdCBhdHRyaWJ1dGUgc2VsZWN0b3JzIGFyZSBxdW90ZWRcblx0ZXhwciA9IGV4cHIucmVwbGFjZSggcmF0dHJpYnV0ZVF1b3RlcywgXCI9JyQxJ11cIiApO1xuXG5cdGlmICggc3VwcG9ydC5tYXRjaGVzU2VsZWN0b3IgJiYgZG9jdW1lbnRJc0hUTUwgJiZcblx0XHQoICFyYnVnZ3lNYXRjaGVzIHx8ICFyYnVnZ3lNYXRjaGVzLnRlc3QoIGV4cHIgKSApICYmXG5cdFx0KCAhcmJ1Z2d5UVNBICAgICB8fCAhcmJ1Z2d5UVNBLnRlc3QoIGV4cHIgKSApICkge1xuXG5cdFx0dHJ5IHtcblx0XHRcdHZhciByZXQgPSBtYXRjaGVzLmNhbGwoIGVsZW0sIGV4cHIgKTtcblxuXHRcdFx0Ly8gSUUgOSdzIG1hdGNoZXNTZWxlY3RvciByZXR1cm5zIGZhbHNlIG9uIGRpc2Nvbm5lY3RlZCBub2Rlc1xuXHRcdFx0aWYgKCByZXQgfHwgc3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCB8fFxuXHRcdFx0XHRcdC8vIEFzIHdlbGwsIGRpc2Nvbm5lY3RlZCBub2RlcyBhcmUgc2FpZCB0byBiZSBpbiBhIGRvY3VtZW50XG5cdFx0XHRcdFx0Ly8gZnJhZ21lbnQgaW4gSUUgOVxuXHRcdFx0XHRcdGVsZW0uZG9jdW1lbnQgJiYgZWxlbS5kb2N1bWVudC5ub2RlVHlwZSAhPT0gMTEgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cdFx0fSBjYXRjaChlKSB7fVxuXHR9XG5cblx0cmV0dXJuIFNpenpsZSggZXhwciwgZG9jdW1lbnQsIG51bGwsIFsgZWxlbSBdICkubGVuZ3RoID4gMDtcbn07XG5cblNpenpsZS5jb250YWlucyA9IGZ1bmN0aW9uKCBjb250ZXh0LCBlbGVtICkge1xuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcblx0aWYgKCAoIGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0ICkgIT09IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XG5cdH1cblx0cmV0dXJuIGNvbnRhaW5zKCBjb250ZXh0LCBlbGVtICk7XG59O1xuXG5TaXp6bGUuYXR0ciA9IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcblx0aWYgKCAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkgIT09IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBlbGVtICk7XG5cdH1cblxuXHR2YXIgZm4gPSBFeHByLmF0dHJIYW5kbGVbIG5hbWUudG9Mb3dlckNhc2UoKSBdLFxuXHRcdC8vIERvbid0IGdldCBmb29sZWQgYnkgT2JqZWN0LnByb3RvdHlwZSBwcm9wZXJ0aWVzIChqUXVlcnkgIzEzODA3KVxuXHRcdHZhbCA9IGZuICYmIGhhc093bi5jYWxsKCBFeHByLmF0dHJIYW5kbGUsIG5hbWUudG9Mb3dlckNhc2UoKSApID9cblx0XHRcdGZuKCBlbGVtLCBuYW1lLCAhZG9jdW1lbnRJc0hUTUwgKSA6XG5cdFx0XHR1bmRlZmluZWQ7XG5cblx0cmV0dXJuIHZhbCAhPT0gdW5kZWZpbmVkID9cblx0XHR2YWwgOlxuXHRcdHN1cHBvcnQuYXR0cmlidXRlcyB8fCAhZG9jdW1lbnRJc0hUTUwgP1xuXHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKSA6XG5cdFx0XHQodmFsID0gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKG5hbWUpKSAmJiB2YWwuc3BlY2lmaWVkID9cblx0XHRcdFx0dmFsLnZhbHVlIDpcblx0XHRcdFx0bnVsbDtcbn07XG5cblNpenpsZS5lcnJvciA9IGZ1bmN0aW9uKCBtc2cgKSB7XG5cdHRocm93IG5ldyBFcnJvciggXCJTeW50YXggZXJyb3IsIHVucmVjb2duaXplZCBleHByZXNzaW9uOiBcIiArIG1zZyApO1xufTtcblxuLyoqXG4gKiBEb2N1bWVudCBzb3J0aW5nIGFuZCByZW1vdmluZyBkdXBsaWNhdGVzXG4gKiBAcGFyYW0ge0FycmF5TGlrZX0gcmVzdWx0c1xuICovXG5TaXp6bGUudW5pcXVlU29ydCA9IGZ1bmN0aW9uKCByZXN1bHRzICkge1xuXHR2YXIgZWxlbSxcblx0XHRkdXBsaWNhdGVzID0gW10sXG5cdFx0aiA9IDAsXG5cdFx0aSA9IDA7XG5cblx0Ly8gVW5sZXNzIHdlICprbm93KiB3ZSBjYW4gZGV0ZWN0IGR1cGxpY2F0ZXMsIGFzc3VtZSB0aGVpciBwcmVzZW5jZVxuXHRoYXNEdXBsaWNhdGUgPSAhc3VwcG9ydC5kZXRlY3REdXBsaWNhdGVzO1xuXHRzb3J0SW5wdXQgPSAhc3VwcG9ydC5zb3J0U3RhYmxlICYmIHJlc3VsdHMuc2xpY2UoIDAgKTtcblx0cmVzdWx0cy5zb3J0KCBzb3J0T3JkZXIgKTtcblxuXHRpZiAoIGhhc0R1cGxpY2F0ZSApIHtcblx0XHR3aGlsZSAoIChlbGVtID0gcmVzdWx0c1tpKytdKSApIHtcblx0XHRcdGlmICggZWxlbSA9PT0gcmVzdWx0c1sgaSBdICkge1xuXHRcdFx0XHRqID0gZHVwbGljYXRlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0cmVzdWx0cy5zcGxpY2UoIGR1cGxpY2F0ZXNbIGogXSwgMSApO1xuXHRcdH1cblx0fVxuXG5cdC8vIENsZWFyIGlucHV0IGFmdGVyIHNvcnRpbmcgdG8gcmVsZWFzZSBvYmplY3RzXG5cdC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L3NpenpsZS9wdWxsLzIyNVxuXHRzb3J0SW5wdXQgPSBudWxsO1xuXG5cdHJldHVybiByZXN1bHRzO1xufTtcblxuLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9uIGZvciByZXRyaWV2aW5nIHRoZSB0ZXh0IHZhbHVlIG9mIGFuIGFycmF5IG9mIERPTSBub2Rlc1xuICogQHBhcmFtIHtBcnJheXxFbGVtZW50fSBlbGVtXG4gKi9cbmdldFRleHQgPSBTaXp6bGUuZ2V0VGV4dCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHR2YXIgbm9kZSxcblx0XHRyZXQgPSBcIlwiLFxuXHRcdGkgPSAwLFxuXHRcdG5vZGVUeXBlID0gZWxlbS5ub2RlVHlwZTtcblxuXHRpZiAoICFub2RlVHlwZSApIHtcblx0XHQvLyBJZiBubyBub2RlVHlwZSwgdGhpcyBpcyBleHBlY3RlZCB0byBiZSBhbiBhcnJheVxuXHRcdHdoaWxlICggKG5vZGUgPSBlbGVtW2krK10pICkge1xuXHRcdFx0Ly8gRG8gbm90IHRyYXZlcnNlIGNvbW1lbnQgbm9kZXNcblx0XHRcdHJldCArPSBnZXRUZXh0KCBub2RlICk7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKCBub2RlVHlwZSA9PT0gMSB8fCBub2RlVHlwZSA9PT0gOSB8fCBub2RlVHlwZSA9PT0gMTEgKSB7XG5cdFx0Ly8gVXNlIHRleHRDb250ZW50IGZvciBlbGVtZW50c1xuXHRcdC8vIGlubmVyVGV4dCB1c2FnZSByZW1vdmVkIGZvciBjb25zaXN0ZW5jeSBvZiBuZXcgbGluZXMgKGpRdWVyeSAjMTExNTMpXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS50ZXh0Q29udGVudCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBlbGVtLnRleHRDb250ZW50O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBUcmF2ZXJzZSBpdHMgY2hpbGRyZW5cblx0XHRcdGZvciAoIGVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7IGVsZW07IGVsZW0gPSBlbGVtLm5leHRTaWJsaW5nICkge1xuXHRcdFx0XHRyZXQgKz0gZ2V0VGV4dCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBlbHNlIGlmICggbm9kZVR5cGUgPT09IDMgfHwgbm9kZVR5cGUgPT09IDQgKSB7XG5cdFx0cmV0dXJuIGVsZW0ubm9kZVZhbHVlO1xuXHR9XG5cdC8vIERvIG5vdCBpbmNsdWRlIGNvbW1lbnQgb3IgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBub2Rlc1xuXG5cdHJldHVybiByZXQ7XG59O1xuXG5FeHByID0gU2l6emxlLnNlbGVjdG9ycyA9IHtcblxuXHQvLyBDYW4gYmUgYWRqdXN0ZWQgYnkgdGhlIHVzZXJcblx0Y2FjaGVMZW5ndGg6IDUwLFxuXG5cdGNyZWF0ZVBzZXVkbzogbWFya0Z1bmN0aW9uLFxuXG5cdG1hdGNoOiBtYXRjaEV4cHIsXG5cblx0YXR0ckhhbmRsZToge30sXG5cblx0ZmluZDoge30sXG5cblx0cmVsYXRpdmU6IHtcblx0XHRcIj5cIjogeyBkaXI6IFwicGFyZW50Tm9kZVwiLCBmaXJzdDogdHJ1ZSB9LFxuXHRcdFwiIFwiOiB7IGRpcjogXCJwYXJlbnROb2RlXCIgfSxcblx0XHRcIitcIjogeyBkaXI6IFwicHJldmlvdXNTaWJsaW5nXCIsIGZpcnN0OiB0cnVlIH0sXG5cdFx0XCJ+XCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiIH1cblx0fSxcblxuXHRwcmVGaWx0ZXI6IHtcblx0XHRcIkFUVFJcIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0bWF0Y2hbMV0gPSBtYXRjaFsxXS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXG5cdFx0XHQvLyBNb3ZlIHRoZSBnaXZlbiB2YWx1ZSB0byBtYXRjaFszXSB3aGV0aGVyIHF1b3RlZCBvciB1bnF1b3RlZFxuXHRcdFx0bWF0Y2hbM10gPSAoIG1hdGNoWzNdIHx8IG1hdGNoWzRdIHx8IG1hdGNoWzVdIHx8IFwiXCIgKS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXG5cdFx0XHRpZiAoIG1hdGNoWzJdID09PSBcIn49XCIgKSB7XG5cdFx0XHRcdG1hdGNoWzNdID0gXCIgXCIgKyBtYXRjaFszXSArIFwiIFwiO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbWF0Y2guc2xpY2UoIDAsIDQgKTtcblx0XHR9LFxuXG5cdFx0XCJDSElMRFwiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XG5cdFx0XHQvKiBtYXRjaGVzIGZyb20gbWF0Y2hFeHByW1wiQ0hJTERcIl1cblx0XHRcdFx0MSB0eXBlIChvbmx5fG50aHwuLi4pXG5cdFx0XHRcdDIgd2hhdCAoY2hpbGR8b2YtdHlwZSlcblx0XHRcdFx0MyBhcmd1bWVudCAoZXZlbnxvZGR8XFxkKnxcXGQqbihbKy1dXFxkKyk/fC4uLilcblx0XHRcdFx0NCB4bi1jb21wb25lbnQgb2YgeG4reSBhcmd1bWVudCAoWystXT9cXGQqbnwpXG5cdFx0XHRcdDUgc2lnbiBvZiB4bi1jb21wb25lbnRcblx0XHRcdFx0NiB4IG9mIHhuLWNvbXBvbmVudFxuXHRcdFx0XHQ3IHNpZ24gb2YgeS1jb21wb25lbnRcblx0XHRcdFx0OCB5IG9mIHktY29tcG9uZW50XG5cdFx0XHQqL1xuXHRcdFx0bWF0Y2hbMV0gPSBtYXRjaFsxXS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0XHRpZiAoIG1hdGNoWzFdLnNsaWNlKCAwLCAzICkgPT09IFwibnRoXCIgKSB7XG5cdFx0XHRcdC8vIG50aC0qIHJlcXVpcmVzIGFyZ3VtZW50XG5cdFx0XHRcdGlmICggIW1hdGNoWzNdICkge1xuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggbWF0Y2hbMF0gKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIG51bWVyaWMgeCBhbmQgeSBwYXJhbWV0ZXJzIGZvciBFeHByLmZpbHRlci5DSElMRFxuXHRcdFx0XHQvLyByZW1lbWJlciB0aGF0IGZhbHNlL3RydWUgY2FzdCByZXNwZWN0aXZlbHkgdG8gMC8xXG5cdFx0XHRcdG1hdGNoWzRdID0gKyggbWF0Y2hbNF0gPyBtYXRjaFs1XSArIChtYXRjaFs2XSB8fCAxKSA6IDIgKiAoIG1hdGNoWzNdID09PSBcImV2ZW5cIiB8fCBtYXRjaFszXSA9PT0gXCJvZGRcIiApICk7XG5cdFx0XHRcdG1hdGNoWzVdID0gKyggKCBtYXRjaFs3XSArIG1hdGNoWzhdICkgfHwgbWF0Y2hbM10gPT09IFwib2RkXCIgKTtcblxuXHRcdFx0Ly8gb3RoZXIgdHlwZXMgcHJvaGliaXQgYXJndW1lbnRzXG5cdFx0XHR9IGVsc2UgaWYgKCBtYXRjaFszXSApIHtcblx0XHRcdFx0U2l6emxlLmVycm9yKCBtYXRjaFswXSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbWF0Y2g7XG5cdFx0fSxcblxuXHRcdFwiUFNFVURPXCI6IGZ1bmN0aW9uKCBtYXRjaCApIHtcblx0XHRcdHZhciBleGNlc3MsXG5cdFx0XHRcdHVucXVvdGVkID0gIW1hdGNoWzZdICYmIG1hdGNoWzJdO1xuXG5cdFx0XHRpZiAoIG1hdGNoRXhwcltcIkNISUxEXCJdLnRlc3QoIG1hdGNoWzBdICkgKSB7XG5cdFx0XHRcdHJldHVybiBudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBY2NlcHQgcXVvdGVkIGFyZ3VtZW50cyBhcy1pc1xuXHRcdFx0aWYgKCBtYXRjaFszXSApIHtcblx0XHRcdFx0bWF0Y2hbMl0gPSBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCBcIlwiO1xuXG5cdFx0XHQvLyBTdHJpcCBleGNlc3MgY2hhcmFjdGVycyBmcm9tIHVucXVvdGVkIGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggdW5xdW90ZWQgJiYgcnBzZXVkby50ZXN0KCB1bnF1b3RlZCApICYmXG5cdFx0XHRcdC8vIEdldCBleGNlc3MgZnJvbSB0b2tlbml6ZSAocmVjdXJzaXZlbHkpXG5cdFx0XHRcdChleGNlc3MgPSB0b2tlbml6ZSggdW5xdW90ZWQsIHRydWUgKSkgJiZcblx0XHRcdFx0Ly8gYWR2YW5jZSB0byB0aGUgbmV4dCBjbG9zaW5nIHBhcmVudGhlc2lzXG5cdFx0XHRcdChleGNlc3MgPSB1bnF1b3RlZC5pbmRleE9mKCBcIilcIiwgdW5xdW90ZWQubGVuZ3RoIC0gZXhjZXNzICkgLSB1bnF1b3RlZC5sZW5ndGgpICkge1xuXG5cdFx0XHRcdC8vIGV4Y2VzcyBpcyBhIG5lZ2F0aXZlIGluZGV4XG5cdFx0XHRcdG1hdGNoWzBdID0gbWF0Y2hbMF0uc2xpY2UoIDAsIGV4Y2VzcyApO1xuXHRcdFx0XHRtYXRjaFsyXSA9IHVucXVvdGVkLnNsaWNlKCAwLCBleGNlc3MgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUmV0dXJuIG9ubHkgY2FwdHVyZXMgbmVlZGVkIGJ5IHRoZSBwc2V1ZG8gZmlsdGVyIG1ldGhvZCAodHlwZSBhbmQgYXJndW1lbnQpXG5cdFx0XHRyZXR1cm4gbWF0Y2guc2xpY2UoIDAsIDMgKTtcblx0XHR9XG5cdH0sXG5cblx0ZmlsdGVyOiB7XG5cblx0XHRcIlRBR1wiOiBmdW5jdGlvbiggbm9kZU5hbWVTZWxlY3RvciApIHtcblx0XHRcdHZhciBub2RlTmFtZSA9IG5vZGVOYW1lU2VsZWN0b3IucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIG5vZGVOYW1lU2VsZWN0b3IgPT09IFwiKlwiID9cblx0XHRcdFx0ZnVuY3Rpb24oKSB7IHJldHVybiB0cnVlOyB9IDpcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGVsZW0ubm9kZU5hbWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBub2RlTmFtZTtcblx0XHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJDTEFTU1wiOiBmdW5jdGlvbiggY2xhc3NOYW1lICkge1xuXHRcdFx0dmFyIHBhdHRlcm4gPSBjbGFzc0NhY2hlWyBjbGFzc05hbWUgKyBcIiBcIiBdO1xuXG5cdFx0XHRyZXR1cm4gcGF0dGVybiB8fFxuXHRcdFx0XHQocGF0dGVybiA9IG5ldyBSZWdFeHAoIFwiKF58XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyBjbGFzc05hbWUgKyBcIihcIiArIHdoaXRlc3BhY2UgKyBcInwkKVwiICkpICYmXG5cdFx0XHRcdGNsYXNzQ2FjaGUoIGNsYXNzTmFtZSwgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHBhdHRlcm4udGVzdCggdHlwZW9mIGVsZW0uY2xhc3NOYW1lID09PSBcInN0cmluZ1wiICYmIGVsZW0uY2xhc3NOYW1lIHx8IHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZSAhPT0gc3RydW5kZWZpbmVkICYmIGVsZW0uZ2V0QXR0cmlidXRlKFwiY2xhc3NcIikgfHwgXCJcIiApO1xuXHRcdFx0XHR9KTtcblx0XHR9LFxuXG5cdFx0XCJBVFRSXCI6IGZ1bmN0aW9uKCBuYW1lLCBvcGVyYXRvciwgY2hlY2sgKSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBTaXp6bGUuYXR0ciggZWxlbSwgbmFtZSApO1xuXG5cdFx0XHRcdGlmICggcmVzdWx0ID09IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9wZXJhdG9yID09PSBcIiE9XCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCAhb3BlcmF0b3IgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXN1bHQgKz0gXCJcIjtcblxuXHRcdFx0XHRyZXR1cm4gb3BlcmF0b3IgPT09IFwiPVwiID8gcmVzdWx0ID09PSBjaGVjayA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiIT1cIiA/IHJlc3VsdCAhPT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIl49XCIgPyBjaGVjayAmJiByZXN1bHQuaW5kZXhPZiggY2hlY2sgKSA9PT0gMCA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiKj1cIiA/IGNoZWNrICYmIHJlc3VsdC5pbmRleE9mKCBjaGVjayApID4gLTEgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIiQ9XCIgPyBjaGVjayAmJiByZXN1bHQuc2xpY2UoIC1jaGVjay5sZW5ndGggKSA9PT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIn49XCIgPyAoIFwiIFwiICsgcmVzdWx0ICsgXCIgXCIgKS5pbmRleE9mKCBjaGVjayApID4gLTEgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcInw9XCIgPyByZXN1bHQgPT09IGNoZWNrIHx8IHJlc3VsdC5zbGljZSggMCwgY2hlY2subGVuZ3RoICsgMSApID09PSBjaGVjayArIFwiLVwiIDpcblx0XHRcdFx0XHRmYWxzZTtcblx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIHR5cGUsIHdoYXQsIGFyZ3VtZW50LCBmaXJzdCwgbGFzdCApIHtcblx0XHRcdHZhciBzaW1wbGUgPSB0eXBlLnNsaWNlKCAwLCAzICkgIT09IFwibnRoXCIsXG5cdFx0XHRcdGZvcndhcmQgPSB0eXBlLnNsaWNlKCAtNCApICE9PSBcImxhc3RcIixcblx0XHRcdFx0b2ZUeXBlID0gd2hhdCA9PT0gXCJvZi10eXBlXCI7XG5cblx0XHRcdHJldHVybiBmaXJzdCA9PT0gMSAmJiBsYXN0ID09PSAwID9cblxuXHRcdFx0XHQvLyBTaG9ydGN1dCBmb3IgOm50aC0qKG4pXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdHJldHVybiAhIWVsZW0ucGFyZW50Tm9kZTtcblx0XHRcdFx0fSA6XG5cblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdFx0XHR2YXIgY2FjaGUsIG91dGVyQ2FjaGUsIG5vZGUsIGRpZmYsIG5vZGVJbmRleCwgc3RhcnQsXG5cdFx0XHRcdFx0XHRkaXIgPSBzaW1wbGUgIT09IGZvcndhcmQgPyBcIm5leHRTaWJsaW5nXCIgOiBcInByZXZpb3VzU2libGluZ1wiLFxuXHRcdFx0XHRcdFx0cGFyZW50ID0gZWxlbS5wYXJlbnROb2RlLFxuXHRcdFx0XHRcdFx0bmFtZSA9IG9mVHlwZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCksXG5cdFx0XHRcdFx0XHR1c2VDYWNoZSA9ICF4bWwgJiYgIW9mVHlwZTtcblxuXHRcdFx0XHRcdGlmICggcGFyZW50ICkge1xuXG5cdFx0XHRcdFx0XHQvLyA6KGZpcnN0fGxhc3R8b25seSktKGNoaWxkfG9mLXR5cGUpXG5cdFx0XHRcdFx0XHRpZiAoIHNpbXBsZSApIHtcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCBkaXIgKSB7XG5cdFx0XHRcdFx0XHRcdFx0bm9kZSA9IGVsZW07XG5cdFx0XHRcdFx0XHRcdFx0d2hpbGUgKCAobm9kZSA9IG5vZGVbIGRpciBdKSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggb2ZUeXBlID8gbm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBuYW1lIDogbm9kZS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHQvLyBSZXZlcnNlIGRpcmVjdGlvbiBmb3IgOm9ubHktKiAoaWYgd2UgaGF2ZW4ndCB5ZXQgZG9uZSBzbylcblx0XHRcdFx0XHRcdFx0XHRzdGFydCA9IGRpciA9IHR5cGUgPT09IFwib25seVwiICYmICFzdGFydCAmJiBcIm5leHRTaWJsaW5nXCI7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHN0YXJ0ID0gWyBmb3J3YXJkID8gcGFyZW50LmZpcnN0Q2hpbGQgOiBwYXJlbnQubGFzdENoaWxkIF07XG5cblx0XHRcdFx0XHRcdC8vIG5vbi14bWwgOm50aC1jaGlsZCguLi4pIHN0b3JlcyBjYWNoZSBkYXRhIG9uIGBwYXJlbnRgXG5cdFx0XHRcdFx0XHRpZiAoIGZvcndhcmQgJiYgdXNlQ2FjaGUgKSB7XG5cdFx0XHRcdFx0XHRcdC8vIFNlZWsgYGVsZW1gIGZyb20gYSBwcmV2aW91c2x5LWNhY2hlZCBpbmRleFxuXHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gcGFyZW50WyBleHBhbmRvIF0gfHwgKHBhcmVudFsgZXhwYW5kbyBdID0ge30pO1xuXHRcdFx0XHRcdFx0XHRjYWNoZSA9IG91dGVyQ2FjaGVbIHR5cGUgXSB8fCBbXTtcblx0XHRcdFx0XHRcdFx0bm9kZUluZGV4ID0gY2FjaGVbMF0gPT09IGRpcnJ1bnMgJiYgY2FjaGVbMV07XG5cdFx0XHRcdFx0XHRcdGRpZmYgPSBjYWNoZVswXSA9PT0gZGlycnVucyAmJiBjYWNoZVsyXTtcblx0XHRcdFx0XHRcdFx0bm9kZSA9IG5vZGVJbmRleCAmJiBwYXJlbnQuY2hpbGROb2Rlc1sgbm9kZUluZGV4IF07XG5cblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAobm9kZSA9ICsrbm9kZUluZGV4ICYmIG5vZGUgJiYgbm9kZVsgZGlyIF0gfHxcblxuXHRcdFx0XHRcdFx0XHRcdC8vIEZhbGxiYWNrIHRvIHNlZWtpbmcgYGVsZW1gIGZyb20gdGhlIHN0YXJ0XG5cdFx0XHRcdFx0XHRcdFx0KGRpZmYgPSBub2RlSW5kZXggPSAwKSB8fCBzdGFydC5wb3AoKSkgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBXaGVuIGZvdW5kLCBjYWNoZSBpbmRleGVzIG9uIGBwYXJlbnRgIGFuZCBicmVha1xuXHRcdFx0XHRcdFx0XHRcdGlmICggbm9kZS5ub2RlVHlwZSA9PT0gMSAmJiArK2RpZmYgJiYgbm9kZSA9PT0gZWxlbSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGVbIHR5cGUgXSA9IFsgZGlycnVucywgbm9kZUluZGV4LCBkaWZmIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gVXNlIHByZXZpb3VzbHktY2FjaGVkIGVsZW1lbnQgaW5kZXggaWYgYXZhaWxhYmxlXG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCB1c2VDYWNoZSAmJiAoY2FjaGUgPSAoZWxlbVsgZXhwYW5kbyBdIHx8IChlbGVtWyBleHBhbmRvIF0gPSB7fSkpWyB0eXBlIF0pICYmIGNhY2hlWzBdID09PSBkaXJydW5zICkge1xuXHRcdFx0XHRcdFx0XHRkaWZmID0gY2FjaGVbMV07XG5cblx0XHRcdFx0XHRcdC8vIHhtbCA6bnRoLWNoaWxkKC4uLikgb3IgOm50aC1sYXN0LWNoaWxkKC4uLikgb3IgOm50aCgtbGFzdCk/LW9mLXR5cGUoLi4uKVxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Ly8gVXNlIHRoZSBzYW1lIGxvb3AgYXMgYWJvdmUgdG8gc2VlayBgZWxlbWAgZnJvbSB0aGUgc3RhcnRcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAobm9kZSA9ICsrbm9kZUluZGV4ICYmIG5vZGUgJiYgbm9kZVsgZGlyIF0gfHxcblx0XHRcdFx0XHRcdFx0XHQoZGlmZiA9IG5vZGVJbmRleCA9IDApIHx8IHN0YXJ0LnBvcCgpKSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdGlmICggKCBvZlR5cGUgPyBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUgOiBub2RlLm5vZGVUeXBlID09PSAxICkgJiYgKytkaWZmICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gQ2FjaGUgdGhlIGluZGV4IG9mIGVhY2ggZW5jb3VudGVyZWQgZWxlbWVudFxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCB1c2VDYWNoZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0KG5vZGVbIGV4cGFuZG8gXSB8fCAobm9kZVsgZXhwYW5kbyBdID0ge30pKVsgdHlwZSBdID0gWyBkaXJydW5zLCBkaWZmIF07XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdGlmICggbm9kZSA9PT0gZWxlbSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIEluY29ycG9yYXRlIHRoZSBvZmZzZXQsIHRoZW4gY2hlY2sgYWdhaW5zdCBjeWNsZSBzaXplXG5cdFx0XHRcdFx0XHRkaWZmIC09IGxhc3Q7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZGlmZiA9PT0gZmlyc3QgfHwgKCBkaWZmICUgZmlyc3QgPT09IDAgJiYgZGlmZiAvIGZpcnN0ID49IDAgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiUFNFVURPXCI6IGZ1bmN0aW9uKCBwc2V1ZG8sIGFyZ3VtZW50ICkge1xuXHRcdFx0Ly8gcHNldWRvLWNsYXNzIG5hbWVzIGFyZSBjYXNlLWluc2Vuc2l0aXZlXG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI3BzZXVkby1jbGFzc2VzXG5cdFx0XHQvLyBQcmlvcml0aXplIGJ5IGNhc2Ugc2Vuc2l0aXZpdHkgaW4gY2FzZSBjdXN0b20gcHNldWRvcyBhcmUgYWRkZWQgd2l0aCB1cHBlcmNhc2UgbGV0dGVyc1xuXHRcdFx0Ly8gUmVtZW1iZXIgdGhhdCBzZXRGaWx0ZXJzIGluaGVyaXRzIGZyb20gcHNldWRvc1xuXHRcdFx0dmFyIGFyZ3MsXG5cdFx0XHRcdGZuID0gRXhwci5wc2V1ZG9zWyBwc2V1ZG8gXSB8fCBFeHByLnNldEZpbHRlcnNbIHBzZXVkby50b0xvd2VyQ2FzZSgpIF0gfHxcblx0XHRcdFx0XHRTaXp6bGUuZXJyb3IoIFwidW5zdXBwb3J0ZWQgcHNldWRvOiBcIiArIHBzZXVkbyApO1xuXG5cdFx0XHQvLyBUaGUgdXNlciBtYXkgdXNlIGNyZWF0ZVBzZXVkbyB0byBpbmRpY2F0ZSB0aGF0XG5cdFx0XHQvLyBhcmd1bWVudHMgYXJlIG5lZWRlZCB0byBjcmVhdGUgdGhlIGZpbHRlciBmdW5jdGlvblxuXHRcdFx0Ly8ganVzdCBhcyBTaXp6bGUgZG9lc1xuXHRcdFx0aWYgKCBmblsgZXhwYW5kbyBdICkge1xuXHRcdFx0XHRyZXR1cm4gZm4oIGFyZ3VtZW50ICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEJ1dCBtYWludGFpbiBzdXBwb3J0IGZvciBvbGQgc2lnbmF0dXJlc1xuXHRcdFx0aWYgKCBmbi5sZW5ndGggPiAxICkge1xuXHRcdFx0XHRhcmdzID0gWyBwc2V1ZG8sIHBzZXVkbywgXCJcIiwgYXJndW1lbnQgXTtcblx0XHRcdFx0cmV0dXJuIEV4cHIuc2V0RmlsdGVycy5oYXNPd25Qcm9wZXJ0eSggcHNldWRvLnRvTG93ZXJDYXNlKCkgKSA/XG5cdFx0XHRcdFx0bWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWVkLCBtYXRjaGVzICkge1xuXHRcdFx0XHRcdFx0dmFyIGlkeCxcblx0XHRcdFx0XHRcdFx0bWF0Y2hlZCA9IGZuKCBzZWVkLCBhcmd1bWVudCApLFxuXHRcdFx0XHRcdFx0XHRpID0gbWF0Y2hlZC5sZW5ndGg7XG5cdFx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdFx0aWR4ID0gaW5kZXhPZi5jYWxsKCBzZWVkLCBtYXRjaGVkW2ldICk7XG5cdFx0XHRcdFx0XHRcdHNlZWRbIGlkeCBdID0gISggbWF0Y2hlc1sgaWR4IF0gPSBtYXRjaGVkW2ldICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSkgOlxuXHRcdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZuKCBlbGVtLCAwLCBhcmdzICk7XG5cdFx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZuO1xuXHRcdH1cblx0fSxcblxuXHRwc2V1ZG9zOiB7XG5cdFx0Ly8gUG90ZW50aWFsbHkgY29tcGxleCBwc2V1ZG9zXG5cdFx0XCJub3RcIjogbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRcdC8vIFRyaW0gdGhlIHNlbGVjdG9yIHBhc3NlZCB0byBjb21waWxlXG5cdFx0XHQvLyB0byBhdm9pZCB0cmVhdGluZyBsZWFkaW5nIGFuZCB0cmFpbGluZ1xuXHRcdFx0Ly8gc3BhY2VzIGFzIGNvbWJpbmF0b3JzXG5cdFx0XHR2YXIgaW5wdXQgPSBbXSxcblx0XHRcdFx0cmVzdWx0cyA9IFtdLFxuXHRcdFx0XHRtYXRjaGVyID0gY29tcGlsZSggc2VsZWN0b3IucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApICk7XG5cblx0XHRcdHJldHVybiBtYXRjaGVyWyBleHBhbmRvIF0gP1xuXHRcdFx0XHRtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMsIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdFx0XHR2YXIgZWxlbSxcblx0XHRcdFx0XHRcdHVubWF0Y2hlZCA9IG1hdGNoZXIoIHNlZWQsIG51bGwsIHhtbCwgW10gKSxcblx0XHRcdFx0XHRcdGkgPSBzZWVkLmxlbmd0aDtcblxuXHRcdFx0XHRcdC8vIE1hdGNoIGVsZW1lbnRzIHVubWF0Y2hlZCBieSBgbWF0Y2hlcmBcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdGlmICggKGVsZW0gPSB1bm1hdGNoZWRbaV0pICkge1xuXHRcdFx0XHRcdFx0XHRzZWVkW2ldID0gIShtYXRjaGVzW2ldID0gZWxlbSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0aW5wdXRbMF0gPSBlbGVtO1xuXHRcdFx0XHRcdG1hdGNoZXIoIGlucHV0LCBudWxsLCB4bWwsIHJlc3VsdHMgKTtcblx0XHRcdFx0XHRyZXR1cm4gIXJlc3VsdHMucG9wKCk7XG5cdFx0XHRcdH07XG5cdFx0fSksXG5cblx0XHRcImhhc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gU2l6emxlKCBzZWxlY3RvciwgZWxlbSApLmxlbmd0aCA+IDA7XG5cdFx0XHR9O1xuXHRcdH0pLFxuXG5cdFx0XCJjb250YWluc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHRleHQgKSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiAoIGVsZW0udGV4dENvbnRlbnQgfHwgZWxlbS5pbm5lclRleHQgfHwgZ2V0VGV4dCggZWxlbSApICkuaW5kZXhPZiggdGV4dCApID4gLTE7XG5cdFx0XHR9O1xuXHRcdH0pLFxuXG5cdFx0Ly8gXCJXaGV0aGVyIGFuIGVsZW1lbnQgaXMgcmVwcmVzZW50ZWQgYnkgYSA6bGFuZygpIHNlbGVjdG9yXG5cdFx0Ly8gaXMgYmFzZWQgc29sZWx5IG9uIHRoZSBlbGVtZW50J3MgbGFuZ3VhZ2UgdmFsdWVcblx0XHQvLyBiZWluZyBlcXVhbCB0byB0aGUgaWRlbnRpZmllciBDLFxuXHRcdC8vIG9yIGJlZ2lubmluZyB3aXRoIHRoZSBpZGVudGlmaWVyIEMgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgXCItXCIuXG5cdFx0Ly8gVGhlIG1hdGNoaW5nIG9mIEMgYWdhaW5zdCB0aGUgZWxlbWVudCdzIGxhbmd1YWdlIHZhbHVlIGlzIHBlcmZvcm1lZCBjYXNlLWluc2Vuc2l0aXZlbHkuXG5cdFx0Ly8gVGhlIGlkZW50aWZpZXIgQyBkb2VzIG5vdCBoYXZlIHRvIGJlIGEgdmFsaWQgbGFuZ3VhZ2UgbmFtZS5cIlxuXHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jbGFuZy1wc2V1ZG9cblx0XHRcImxhbmdcIjogbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggbGFuZyApIHtcblx0XHRcdC8vIGxhbmcgdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGlkZW50aWZpZXJcblx0XHRcdGlmICggIXJpZGVudGlmaWVyLnRlc3QobGFuZyB8fCBcIlwiKSApIHtcblx0XHRcdFx0U2l6emxlLmVycm9yKCBcInVuc3VwcG9ydGVkIGxhbmc6IFwiICsgbGFuZyApO1xuXHRcdFx0fVxuXHRcdFx0bGFuZyA9IGxhbmcucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgZWxlbUxhbmc7XG5cdFx0XHRcdGRvIHtcblx0XHRcdFx0XHRpZiAoIChlbGVtTGFuZyA9IGRvY3VtZW50SXNIVE1MID9cblx0XHRcdFx0XHRcdGVsZW0ubGFuZyA6XG5cdFx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZShcInhtbDpsYW5nXCIpIHx8IGVsZW0uZ2V0QXR0cmlidXRlKFwibGFuZ1wiKSkgKSB7XG5cblx0XHRcdFx0XHRcdGVsZW1MYW5nID0gZWxlbUxhbmcudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtTGFuZyA9PT0gbGFuZyB8fCBlbGVtTGFuZy5pbmRleE9mKCBsYW5nICsgXCItXCIgKSA9PT0gMDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gd2hpbGUgKCAoZWxlbSA9IGVsZW0ucGFyZW50Tm9kZSkgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApO1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9O1xuXHRcdH0pLFxuXG5cdFx0Ly8gTWlzY2VsbGFuZW91c1xuXHRcdFwidGFyZ2V0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIGhhc2ggPSB3aW5kb3cubG9jYXRpb24gJiYgd2luZG93LmxvY2F0aW9uLmhhc2g7XG5cdFx0XHRyZXR1cm4gaGFzaCAmJiBoYXNoLnNsaWNlKCAxICkgPT09IGVsZW0uaWQ7XG5cdFx0fSxcblxuXHRcdFwicm9vdFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBkb2NFbGVtO1xuXHRcdH0sXG5cblx0XHRcImZvY3VzXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0gPT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgKCFkb2N1bWVudC5oYXNGb2N1cyB8fCBkb2N1bWVudC5oYXNGb2N1cygpKSAmJiAhIShlbGVtLnR5cGUgfHwgZWxlbS5ocmVmIHx8IH5lbGVtLnRhYkluZGV4KTtcblx0XHR9LFxuXG5cdFx0Ly8gQm9vbGVhbiBwcm9wZXJ0aWVzXG5cdFx0XCJlbmFibGVkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IGZhbHNlO1xuXHRcdH0sXG5cblx0XHRcImRpc2FibGVkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IHRydWU7XG5cdFx0fSxcblxuXHRcdFwiY2hlY2tlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdC8vIEluIENTUzMsIDpjaGVja2VkIHNob3VsZCByZXR1cm4gYm90aCBjaGVja2VkIGFuZCBzZWxlY3RlZCBlbGVtZW50c1xuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvMjAxMS9SRUMtY3NzMy1zZWxlY3RvcnMtMjAxMTA5MjkvI2NoZWNrZWRcblx0XHRcdHZhciBub2RlTmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiAobm9kZU5hbWUgPT09IFwiaW5wdXRcIiAmJiAhIWVsZW0uY2hlY2tlZCkgfHwgKG5vZGVOYW1lID09PSBcIm9wdGlvblwiICYmICEhZWxlbS5zZWxlY3RlZCk7XG5cdFx0fSxcblxuXHRcdFwic2VsZWN0ZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHQvLyBBY2Nlc3NpbmcgdGhpcyBwcm9wZXJ0eSBtYWtlcyBzZWxlY3RlZC1ieS1kZWZhdWx0XG5cdFx0XHQvLyBvcHRpb25zIGluIFNhZmFyaSB3b3JrIHByb3Blcmx5XG5cdFx0XHRpZiAoIGVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0ZWxlbS5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXg7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBlbGVtLnNlbGVjdGVkID09PSB0cnVlO1xuXHRcdH0sXG5cblx0XHQvLyBDb250ZW50c1xuXHRcdFwiZW1wdHlcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2VtcHR5LXBzZXVkb1xuXHRcdFx0Ly8gOmVtcHR5IGlzIG5lZ2F0ZWQgYnkgZWxlbWVudCAoMSkgb3IgY29udGVudCBub2RlcyAodGV4dDogMzsgY2RhdGE6IDQ7IGVudGl0eSByZWY6IDUpLFxuXHRcdFx0Ly8gICBidXQgbm90IGJ5IG90aGVycyAoY29tbWVudDogODsgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbjogNzsgZXRjLilcblx0XHRcdC8vIG5vZGVUeXBlIDwgNiB3b3JrcyBiZWNhdXNlIGF0dHJpYnV0ZXMgKDIpIGRvIG5vdCBhcHBlYXIgYXMgY2hpbGRyZW5cblx0XHRcdGZvciAoIGVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7IGVsZW07IGVsZW0gPSBlbGVtLm5leHRTaWJsaW5nICkge1xuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPCA2ICkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblxuXHRcdFwicGFyZW50XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuICFFeHByLnBzZXVkb3NbXCJlbXB0eVwiXSggZWxlbSApO1xuXHRcdH0sXG5cblx0XHQvLyBFbGVtZW50L2lucHV0IHR5cGVzXG5cdFx0XCJoZWFkZXJcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gcmhlYWRlci50ZXN0KCBlbGVtLm5vZGVOYW1lICk7XG5cdFx0fSxcblxuXHRcdFwiaW5wdXRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gcmlucHV0cy50ZXN0KCBlbGVtLm5vZGVOYW1lICk7XG5cdFx0fSxcblxuXHRcdFwiYnV0dG9uXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gbmFtZSA9PT0gXCJpbnB1dFwiICYmIGVsZW0udHlwZSA9PT0gXCJidXR0b25cIiB8fCBuYW1lID09PSBcImJ1dHRvblwiO1xuXHRcdH0sXG5cblx0XHRcInRleHRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgYXR0cjtcblx0XHRcdHJldHVybiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiaW5wdXRcIiAmJlxuXHRcdFx0XHRlbGVtLnR5cGUgPT09IFwidGV4dFwiICYmXG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogSUU8OFxuXHRcdFx0XHQvLyBOZXcgSFRNTDUgYXR0cmlidXRlIHZhbHVlcyAoZS5nLiwgXCJzZWFyY2hcIikgYXBwZWFyIHdpdGggZWxlbS50eXBlID09PSBcInRleHRcIlxuXHRcdFx0XHQoIChhdHRyID0gZWxlbS5nZXRBdHRyaWJ1dGUoXCJ0eXBlXCIpKSA9PSBudWxsIHx8IGF0dHIudG9Mb3dlckNhc2UoKSA9PT0gXCJ0ZXh0XCIgKTtcblx0XHR9LFxuXG5cdFx0Ly8gUG9zaXRpb24taW4tY29sbGVjdGlvblxuXHRcdFwiZmlyc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBbIDAgXTtcblx0XHR9KSxcblxuXHRcdFwibGFzdFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHJldHVybiBbIGxlbmd0aCAtIDEgXTtcblx0XHR9KSxcblxuXHRcdFwiZXFcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xuXHRcdFx0cmV0dXJuIFsgYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudCBdO1xuXHRcdH0pLFxuXG5cdFx0XCJldmVuXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xuXHRcdFx0dmFyIGkgPSAwO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpICs9IDIgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0pLFxuXG5cdFx0XCJvZGRcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHR2YXIgaSA9IDE7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkgKz0gMiApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSksXG5cblx0XHRcImx0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpID0gYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudDtcblx0XHRcdGZvciAoIDsgLS1pID49IDA7ICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9KSxcblxuXHRcdFwiZ3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xuXHRcdFx0dmFyIGkgPSBhcmd1bWVudCA8IDAgPyBhcmd1bWVudCArIGxlbmd0aCA6IGFyZ3VtZW50O1xuXHRcdFx0Zm9yICggOyArK2kgPCBsZW5ndGg7ICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9KVxuXHR9XG59O1xuXG5FeHByLnBzZXVkb3NbXCJudGhcIl0gPSBFeHByLnBzZXVkb3NbXCJlcVwiXTtcblxuLy8gQWRkIGJ1dHRvbi9pbnB1dCB0eXBlIHBzZXVkb3NcbmZvciAoIGkgaW4geyByYWRpbzogdHJ1ZSwgY2hlY2tib3g6IHRydWUsIGZpbGU6IHRydWUsIHBhc3N3b3JkOiB0cnVlLCBpbWFnZTogdHJ1ZSB9ICkge1xuXHRFeHByLnBzZXVkb3NbIGkgXSA9IGNyZWF0ZUlucHV0UHNldWRvKCBpICk7XG59XG5mb3IgKCBpIGluIHsgc3VibWl0OiB0cnVlLCByZXNldDogdHJ1ZSB9ICkge1xuXHRFeHByLnBzZXVkb3NbIGkgXSA9IGNyZWF0ZUJ1dHRvblBzZXVkbyggaSApO1xufVxuXG4vLyBFYXN5IEFQSSBmb3IgY3JlYXRpbmcgbmV3IHNldEZpbHRlcnNcbmZ1bmN0aW9uIHNldEZpbHRlcnMoKSB7fVxuc2V0RmlsdGVycy5wcm90b3R5cGUgPSBFeHByLmZpbHRlcnMgPSBFeHByLnBzZXVkb3M7XG5FeHByLnNldEZpbHRlcnMgPSBuZXcgc2V0RmlsdGVycygpO1xuXG50b2tlbml6ZSA9IFNpenpsZS50b2tlbml6ZSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgcGFyc2VPbmx5ICkge1xuXHR2YXIgbWF0Y2hlZCwgbWF0Y2gsIHRva2VucywgdHlwZSxcblx0XHRzb0ZhciwgZ3JvdXBzLCBwcmVGaWx0ZXJzLFxuXHRcdGNhY2hlZCA9IHRva2VuQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXTtcblxuXHRpZiAoIGNhY2hlZCApIHtcblx0XHRyZXR1cm4gcGFyc2VPbmx5ID8gMCA6IGNhY2hlZC5zbGljZSggMCApO1xuXHR9XG5cblx0c29GYXIgPSBzZWxlY3Rvcjtcblx0Z3JvdXBzID0gW107XG5cdHByZUZpbHRlcnMgPSBFeHByLnByZUZpbHRlcjtcblxuXHR3aGlsZSAoIHNvRmFyICkge1xuXG5cdFx0Ly8gQ29tbWEgYW5kIGZpcnN0IHJ1blxuXHRcdGlmICggIW1hdGNoZWQgfHwgKG1hdGNoID0gcmNvbW1hLmV4ZWMoIHNvRmFyICkpICkge1xuXHRcdFx0aWYgKCBtYXRjaCApIHtcblx0XHRcdFx0Ly8gRG9uJ3QgY29uc3VtZSB0cmFpbGluZyBjb21tYXMgYXMgdmFsaWRcblx0XHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hbMF0ubGVuZ3RoICkgfHwgc29GYXI7XG5cdFx0XHR9XG5cdFx0XHRncm91cHMucHVzaCggKHRva2VucyA9IFtdKSApO1xuXHRcdH1cblxuXHRcdG1hdGNoZWQgPSBmYWxzZTtcblxuXHRcdC8vIENvbWJpbmF0b3JzXG5cdFx0aWYgKCAobWF0Y2ggPSByY29tYmluYXRvcnMuZXhlYyggc29GYXIgKSkgKSB7XG5cdFx0XHRtYXRjaGVkID0gbWF0Y2guc2hpZnQoKTtcblx0XHRcdHRva2Vucy5wdXNoKHtcblx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXG5cdFx0XHRcdC8vIENhc3QgZGVzY2VuZGFudCBjb21iaW5hdG9ycyB0byBzcGFjZVxuXHRcdFx0XHR0eXBlOiBtYXRjaFswXS5yZXBsYWNlKCBydHJpbSwgXCIgXCIgKVxuXHRcdFx0fSk7XG5cdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaGVkLmxlbmd0aCApO1xuXHRcdH1cblxuXHRcdC8vIEZpbHRlcnNcblx0XHRmb3IgKCB0eXBlIGluIEV4cHIuZmlsdGVyICkge1xuXHRcdFx0aWYgKCAobWF0Y2ggPSBtYXRjaEV4cHJbIHR5cGUgXS5leGVjKCBzb0ZhciApKSAmJiAoIXByZUZpbHRlcnNbIHR5cGUgXSB8fFxuXHRcdFx0XHQobWF0Y2ggPSBwcmVGaWx0ZXJzWyB0eXBlIF0oIG1hdGNoICkpKSApIHtcblx0XHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XG5cdFx0XHRcdHRva2Vucy5wdXNoKHtcblx0XHRcdFx0XHR2YWx1ZTogbWF0Y2hlZCxcblx0XHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRcdG1hdGNoZXM6IG1hdGNoXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaGVkLmxlbmd0aCApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggIW1hdGNoZWQgKSB7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgaW52YWxpZCBleGNlc3Ncblx0Ly8gaWYgd2UncmUganVzdCBwYXJzaW5nXG5cdC8vIE90aGVyd2lzZSwgdGhyb3cgYW4gZXJyb3Igb3IgcmV0dXJuIHRva2Vuc1xuXHRyZXR1cm4gcGFyc2VPbmx5ID9cblx0XHRzb0Zhci5sZW5ndGggOlxuXHRcdHNvRmFyID9cblx0XHRcdFNpenpsZS5lcnJvciggc2VsZWN0b3IgKSA6XG5cdFx0XHQvLyBDYWNoZSB0aGUgdG9rZW5zXG5cdFx0XHR0b2tlbkNhY2hlKCBzZWxlY3RvciwgZ3JvdXBzICkuc2xpY2UoIDAgKTtcbn07XG5cbmZ1bmN0aW9uIHRvU2VsZWN0b3IoIHRva2VucyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IHRva2Vucy5sZW5ndGgsXG5cdFx0c2VsZWN0b3IgPSBcIlwiO1xuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRzZWxlY3RvciArPSB0b2tlbnNbaV0udmFsdWU7XG5cdH1cblx0cmV0dXJuIHNlbGVjdG9yO1xufVxuXG5mdW5jdGlvbiBhZGRDb21iaW5hdG9yKCBtYXRjaGVyLCBjb21iaW5hdG9yLCBiYXNlICkge1xuXHR2YXIgZGlyID0gY29tYmluYXRvci5kaXIsXG5cdFx0Y2hlY2tOb25FbGVtZW50cyA9IGJhc2UgJiYgZGlyID09PSBcInBhcmVudE5vZGVcIixcblx0XHRkb25lTmFtZSA9IGRvbmUrKztcblxuXHRyZXR1cm4gY29tYmluYXRvci5maXJzdCA/XG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBjbG9zZXN0IGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50XG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xuXHRcdFx0XHRcdHJldHVybiBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gOlxuXG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBhbGwgYW5jZXN0b3IvcHJlY2VkaW5nIGVsZW1lbnRzXG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciBvbGRDYWNoZSwgb3V0ZXJDYWNoZSxcblx0XHRcdFx0bmV3Q2FjaGUgPSBbIGRpcnJ1bnMsIGRvbmVOYW1lIF07XG5cblx0XHRcdC8vIFdlIGNhbid0IHNldCBhcmJpdHJhcnkgZGF0YSBvbiBYTUwgbm9kZXMsIHNvIHRoZXkgZG9uJ3QgYmVuZWZpdCBmcm9tIGRpciBjYWNoaW5nXG5cdFx0XHRpZiAoIHhtbCApIHtcblx0XHRcdFx0d2hpbGUgKCAoZWxlbSA9IGVsZW1bIGRpciBdKSApIHtcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0d2hpbGUgKCAoZWxlbSA9IGVsZW1bIGRpciBdKSApIHtcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBlbGVtWyBleHBhbmRvIF0gfHwgKGVsZW1bIGV4cGFuZG8gXSA9IHt9KTtcblx0XHRcdFx0XHRcdGlmICggKG9sZENhY2hlID0gb3V0ZXJDYWNoZVsgZGlyIF0pICYmXG5cdFx0XHRcdFx0XHRcdG9sZENhY2hlWyAwIF0gPT09IGRpcnJ1bnMgJiYgb2xkQ2FjaGVbIDEgXSA9PT0gZG9uZU5hbWUgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQXNzaWduIHRvIG5ld0NhY2hlIHNvIHJlc3VsdHMgYmFjay1wcm9wYWdhdGUgdG8gcHJldmlvdXMgZWxlbWVudHNcblx0XHRcdFx0XHRcdFx0cmV0dXJuIChuZXdDYWNoZVsgMiBdID0gb2xkQ2FjaGVbIDIgXSk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHQvLyBSZXVzZSBuZXdjYWNoZSBzbyByZXN1bHRzIGJhY2stcHJvcGFnYXRlIHRvIHByZXZpb3VzIGVsZW1lbnRzXG5cdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGVbIGRpciBdID0gbmV3Q2FjaGU7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQSBtYXRjaCBtZWFucyB3ZSdyZSBkb25lOyBhIGZhaWwgbWVhbnMgd2UgaGF2ZSB0byBrZWVwIGNoZWNraW5nXG5cdFx0XHRcdFx0XHRcdGlmICggKG5ld0NhY2hlWyAyIF0gPSBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xufVxuXG5mdW5jdGlvbiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSB7XG5cdHJldHVybiBtYXRjaGVycy5sZW5ndGggPiAxID9cblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0dmFyIGkgPSBtYXRjaGVycy5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCAhbWF0Y2hlcnNbaV0oIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSA6XG5cdFx0bWF0Y2hlcnNbMF07XG59XG5cbmZ1bmN0aW9uIG11bHRpcGxlQ29udGV4dHMoIHNlbGVjdG9yLCBjb250ZXh0cywgcmVzdWx0cyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IGNvbnRleHRzLmxlbmd0aDtcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0U2l6emxlKCBzZWxlY3RvciwgY29udGV4dHNbaV0sIHJlc3VsdHMgKTtcblx0fVxuXHRyZXR1cm4gcmVzdWx0cztcbn1cblxuZnVuY3Rpb24gY29uZGVuc2UoIHVubWF0Y2hlZCwgbWFwLCBmaWx0ZXIsIGNvbnRleHQsIHhtbCApIHtcblx0dmFyIGVsZW0sXG5cdFx0bmV3VW5tYXRjaGVkID0gW10sXG5cdFx0aSA9IDAsXG5cdFx0bGVuID0gdW5tYXRjaGVkLmxlbmd0aCxcblx0XHRtYXBwZWQgPSBtYXAgIT0gbnVsbDtcblxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRpZiAoIChlbGVtID0gdW5tYXRjaGVkW2ldKSApIHtcblx0XHRcdGlmICggIWZpbHRlciB8fCBmaWx0ZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRuZXdVbm1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0XHRpZiAoIG1hcHBlZCApIHtcblx0XHRcdFx0XHRtYXAucHVzaCggaSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIG5ld1VubWF0Y2hlZDtcbn1cblxuZnVuY3Rpb24gc2V0TWF0Y2hlciggcHJlRmlsdGVyLCBzZWxlY3RvciwgbWF0Y2hlciwgcG9zdEZpbHRlciwgcG9zdEZpbmRlciwgcG9zdFNlbGVjdG9yICkge1xuXHRpZiAoIHBvc3RGaWx0ZXIgJiYgIXBvc3RGaWx0ZXJbIGV4cGFuZG8gXSApIHtcblx0XHRwb3N0RmlsdGVyID0gc2V0TWF0Y2hlciggcG9zdEZpbHRlciApO1xuXHR9XG5cdGlmICggcG9zdEZpbmRlciAmJiAhcG9zdEZpbmRlclsgZXhwYW5kbyBdICkge1xuXHRcdHBvc3RGaW5kZXIgPSBzZXRNYXRjaGVyKCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKTtcblx0fVxuXHRyZXR1cm4gbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWVkLCByZXN1bHRzLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0dmFyIHRlbXAsIGksIGVsZW0sXG5cdFx0XHRwcmVNYXAgPSBbXSxcblx0XHRcdHBvc3RNYXAgPSBbXSxcblx0XHRcdHByZWV4aXN0aW5nID0gcmVzdWx0cy5sZW5ndGgsXG5cblx0XHRcdC8vIEdldCBpbml0aWFsIGVsZW1lbnRzIGZyb20gc2VlZCBvciBjb250ZXh0XG5cdFx0XHRlbGVtcyA9IHNlZWQgfHwgbXVsdGlwbGVDb250ZXh0cyggc2VsZWN0b3IgfHwgXCIqXCIsIGNvbnRleHQubm9kZVR5cGUgPyBbIGNvbnRleHQgXSA6IGNvbnRleHQsIFtdICksXG5cblx0XHRcdC8vIFByZWZpbHRlciB0byBnZXQgbWF0Y2hlciBpbnB1dCwgcHJlc2VydmluZyBhIG1hcCBmb3Igc2VlZC1yZXN1bHRzIHN5bmNocm9uaXphdGlvblxuXHRcdFx0bWF0Y2hlckluID0gcHJlRmlsdGVyICYmICggc2VlZCB8fCAhc2VsZWN0b3IgKSA/XG5cdFx0XHRcdGNvbmRlbnNlKCBlbGVtcywgcHJlTWFwLCBwcmVGaWx0ZXIsIGNvbnRleHQsIHhtbCApIDpcblx0XHRcdFx0ZWxlbXMsXG5cblx0XHRcdG1hdGNoZXJPdXQgPSBtYXRjaGVyID9cblx0XHRcdFx0Ly8gSWYgd2UgaGF2ZSBhIHBvc3RGaW5kZXIsIG9yIGZpbHRlcmVkIHNlZWQsIG9yIG5vbi1zZWVkIHBvc3RGaWx0ZXIgb3IgcHJlZXhpc3RpbmcgcmVzdWx0cyxcblx0XHRcdFx0cG9zdEZpbmRlciB8fCAoIHNlZWQgPyBwcmVGaWx0ZXIgOiBwcmVleGlzdGluZyB8fCBwb3N0RmlsdGVyICkgP1xuXG5cdFx0XHRcdFx0Ly8gLi4uaW50ZXJtZWRpYXRlIHByb2Nlc3NpbmcgaXMgbmVjZXNzYXJ5XG5cdFx0XHRcdFx0W10gOlxuXG5cdFx0XHRcdFx0Ly8gLi4ub3RoZXJ3aXNlIHVzZSByZXN1bHRzIGRpcmVjdGx5XG5cdFx0XHRcdFx0cmVzdWx0cyA6XG5cdFx0XHRcdG1hdGNoZXJJbjtcblxuXHRcdC8vIEZpbmQgcHJpbWFyeSBtYXRjaGVzXG5cdFx0aWYgKCBtYXRjaGVyICkge1xuXHRcdFx0bWF0Y2hlciggbWF0Y2hlckluLCBtYXRjaGVyT3V0LCBjb250ZXh0LCB4bWwgKTtcblx0XHR9XG5cblx0XHQvLyBBcHBseSBwb3N0RmlsdGVyXG5cdFx0aWYgKCBwb3N0RmlsdGVyICkge1xuXHRcdFx0dGVtcCA9IGNvbmRlbnNlKCBtYXRjaGVyT3V0LCBwb3N0TWFwICk7XG5cdFx0XHRwb3N0RmlsdGVyKCB0ZW1wLCBbXSwgY29udGV4dCwgeG1sICk7XG5cblx0XHRcdC8vIFVuLW1hdGNoIGZhaWxpbmcgZWxlbWVudHMgYnkgbW92aW5nIHRoZW0gYmFjayB0byBtYXRjaGVySW5cblx0XHRcdGkgPSB0ZW1wLmxlbmd0aDtcblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRpZiAoIChlbGVtID0gdGVtcFtpXSkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlck91dFsgcG9zdE1hcFtpXSBdID0gIShtYXRjaGVySW5bIHBvc3RNYXBbaV0gXSA9IGVsZW0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBzZWVkICkge1xuXHRcdFx0aWYgKCBwb3N0RmluZGVyIHx8IHByZUZpbHRlciApIHtcblx0XHRcdFx0aWYgKCBwb3N0RmluZGVyICkge1xuXHRcdFx0XHRcdC8vIEdldCB0aGUgZmluYWwgbWF0Y2hlck91dCBieSBjb25kZW5zaW5nIHRoaXMgaW50ZXJtZWRpYXRlIGludG8gcG9zdEZpbmRlciBjb250ZXh0c1xuXHRcdFx0XHRcdHRlbXAgPSBbXTtcblx0XHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRpZiAoIChlbGVtID0gbWF0Y2hlck91dFtpXSkgKSB7XG5cdFx0XHRcdFx0XHRcdC8vIFJlc3RvcmUgbWF0Y2hlckluIHNpbmNlIGVsZW0gaXMgbm90IHlldCBhIGZpbmFsIG1hdGNoXG5cdFx0XHRcdFx0XHRcdHRlbXAucHVzaCggKG1hdGNoZXJJbltpXSA9IGVsZW0pICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHBvc3RGaW5kZXIoIG51bGwsIChtYXRjaGVyT3V0ID0gW10pLCB0ZW1wLCB4bWwgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIE1vdmUgbWF0Y2hlZCBlbGVtZW50cyBmcm9tIHNlZWQgdG8gcmVzdWx0cyB0byBrZWVwIHRoZW0gc3luY2hyb25pemVkXG5cdFx0XHRcdGkgPSBtYXRjaGVyT3V0Lmxlbmd0aDtcblx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0aWYgKCAoZWxlbSA9IG1hdGNoZXJPdXRbaV0pICYmXG5cdFx0XHRcdFx0XHQodGVtcCA9IHBvc3RGaW5kZXIgPyBpbmRleE9mLmNhbGwoIHNlZWQsIGVsZW0gKSA6IHByZU1hcFtpXSkgPiAtMSApIHtcblxuXHRcdFx0XHRcdFx0c2VlZFt0ZW1wXSA9ICEocmVzdWx0c1t0ZW1wXSA9IGVsZW0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0Ly8gQWRkIGVsZW1lbnRzIHRvIHJlc3VsdHMsIHRocm91Z2ggcG9zdEZpbmRlciBpZiBkZWZpbmVkXG5cdFx0fSBlbHNlIHtcblx0XHRcdG1hdGNoZXJPdXQgPSBjb25kZW5zZShcblx0XHRcdFx0bWF0Y2hlck91dCA9PT0gcmVzdWx0cyA/XG5cdFx0XHRcdFx0bWF0Y2hlck91dC5zcGxpY2UoIHByZWV4aXN0aW5nLCBtYXRjaGVyT3V0Lmxlbmd0aCApIDpcblx0XHRcdFx0XHRtYXRjaGVyT3V0XG5cdFx0XHQpO1xuXHRcdFx0aWYgKCBwb3N0RmluZGVyICkge1xuXHRcdFx0XHRwb3N0RmluZGVyKCBudWxsLCByZXN1bHRzLCBtYXRjaGVyT3V0LCB4bWwgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIG1hdGNoZXJPdXQgKTtcblx0XHRcdH1cblx0XHR9XG5cdH0pO1xufVxuXG5mdW5jdGlvbiBtYXRjaGVyRnJvbVRva2VucyggdG9rZW5zICkge1xuXHR2YXIgY2hlY2tDb250ZXh0LCBtYXRjaGVyLCBqLFxuXHRcdGxlbiA9IHRva2Vucy5sZW5ndGgsXG5cdFx0bGVhZGluZ1JlbGF0aXZlID0gRXhwci5yZWxhdGl2ZVsgdG9rZW5zWzBdLnR5cGUgXSxcblx0XHRpbXBsaWNpdFJlbGF0aXZlID0gbGVhZGluZ1JlbGF0aXZlIHx8IEV4cHIucmVsYXRpdmVbXCIgXCJdLFxuXHRcdGkgPSBsZWFkaW5nUmVsYXRpdmUgPyAxIDogMCxcblxuXHRcdC8vIFRoZSBmb3VuZGF0aW9uYWwgbWF0Y2hlciBlbnN1cmVzIHRoYXQgZWxlbWVudHMgYXJlIHJlYWNoYWJsZSBmcm9tIHRvcC1sZXZlbCBjb250ZXh0KHMpXG5cdFx0bWF0Y2hDb250ZXh0ID0gYWRkQ29tYmluYXRvciggZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gY2hlY2tDb250ZXh0O1xuXHRcdH0sIGltcGxpY2l0UmVsYXRpdmUsIHRydWUgKSxcblx0XHRtYXRjaEFueUNvbnRleHQgPSBhZGRDb21iaW5hdG9yKCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBpbmRleE9mLmNhbGwoIGNoZWNrQ29udGV4dCwgZWxlbSApID4gLTE7XG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxuXHRcdG1hdGNoZXJzID0gWyBmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0cmV0dXJuICggIWxlYWRpbmdSZWxhdGl2ZSAmJiAoIHhtbCB8fCBjb250ZXh0ICE9PSBvdXRlcm1vc3RDb250ZXh0ICkgKSB8fCAoXG5cdFx0XHRcdChjaGVja0NvbnRleHQgPSBjb250ZXh0KS5ub2RlVHlwZSA/XG5cdFx0XHRcdFx0bWF0Y2hDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSA6XG5cdFx0XHRcdFx0bWF0Y2hBbnlDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSApO1xuXHRcdH0gXTtcblxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRpZiAoIChtYXRjaGVyID0gRXhwci5yZWxhdGl2ZVsgdG9rZW5zW2ldLnR5cGUgXSkgKSB7XG5cdFx0XHRtYXRjaGVycyA9IFsgYWRkQ29tYmluYXRvcihlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSwgbWF0Y2hlcikgXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bWF0Y2hlciA9IEV4cHIuZmlsdGVyWyB0b2tlbnNbaV0udHlwZSBdLmFwcGx5KCBudWxsLCB0b2tlbnNbaV0ubWF0Y2hlcyApO1xuXG5cdFx0XHQvLyBSZXR1cm4gc3BlY2lhbCB1cG9uIHNlZWluZyBhIHBvc2l0aW9uYWwgbWF0Y2hlclxuXHRcdFx0aWYgKCBtYXRjaGVyWyBleHBhbmRvIF0gKSB7XG5cdFx0XHRcdC8vIEZpbmQgdGhlIG5leHQgcmVsYXRpdmUgb3BlcmF0b3IgKGlmIGFueSkgZm9yIHByb3BlciBoYW5kbGluZ1xuXHRcdFx0XHRqID0gKytpO1xuXHRcdFx0XHRmb3IgKCA7IGogPCBsZW47IGorKyApIHtcblx0XHRcdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbIHRva2Vuc1tqXS50eXBlIF0gKSB7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHNldE1hdGNoZXIoXG5cdFx0XHRcdFx0aSA+IDEgJiYgZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICksXG5cdFx0XHRcdFx0aSA+IDEgJiYgdG9TZWxlY3Rvcihcblx0XHRcdFx0XHRcdC8vIElmIHRoZSBwcmVjZWRpbmcgdG9rZW4gd2FzIGEgZGVzY2VuZGFudCBjb21iaW5hdG9yLCBpbnNlcnQgYW4gaW1wbGljaXQgYW55LWVsZW1lbnQgYCpgXG5cdFx0XHRcdFx0XHR0b2tlbnMuc2xpY2UoIDAsIGkgLSAxICkuY29uY2F0KHsgdmFsdWU6IHRva2Vuc1sgaSAtIDIgXS50eXBlID09PSBcIiBcIiA/IFwiKlwiIDogXCJcIiB9KVxuXHRcdFx0XHRcdCkucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApLFxuXHRcdFx0XHRcdG1hdGNoZXIsXG5cdFx0XHRcdFx0aSA8IGogJiYgbWF0Y2hlckZyb21Ub2tlbnMoIHRva2Vucy5zbGljZSggaSwgaiApICksXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiBtYXRjaGVyRnJvbVRva2VucyggKHRva2VucyA9IHRva2Vucy5zbGljZSggaiApKSApLFxuXHRcdFx0XHRcdGogPCBsZW4gJiYgdG9TZWxlY3RvciggdG9rZW5zIClcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHRcdG1hdGNoZXJzLnB1c2goIG1hdGNoZXIgKTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXJGcm9tR3JvdXBNYXRjaGVycyggZWxlbWVudE1hdGNoZXJzLCBzZXRNYXRjaGVycyApIHtcblx0dmFyIGJ5U2V0ID0gc2V0TWF0Y2hlcnMubGVuZ3RoID4gMCxcblx0XHRieUVsZW1lbnQgPSBlbGVtZW50TWF0Y2hlcnMubGVuZ3RoID4gMCxcblx0XHRzdXBlck1hdGNoZXIgPSBmdW5jdGlvbiggc2VlZCwgY29udGV4dCwgeG1sLCByZXN1bHRzLCBvdXRlcm1vc3QgKSB7XG5cdFx0XHR2YXIgZWxlbSwgaiwgbWF0Y2hlcixcblx0XHRcdFx0bWF0Y2hlZENvdW50ID0gMCxcblx0XHRcdFx0aSA9IFwiMFwiLFxuXHRcdFx0XHR1bm1hdGNoZWQgPSBzZWVkICYmIFtdLFxuXHRcdFx0XHRzZXRNYXRjaGVkID0gW10sXG5cdFx0XHRcdGNvbnRleHRCYWNrdXAgPSBvdXRlcm1vc3RDb250ZXh0LFxuXHRcdFx0XHQvLyBXZSBtdXN0IGFsd2F5cyBoYXZlIGVpdGhlciBzZWVkIGVsZW1lbnRzIG9yIG91dGVybW9zdCBjb250ZXh0XG5cdFx0XHRcdGVsZW1zID0gc2VlZCB8fCBieUVsZW1lbnQgJiYgRXhwci5maW5kW1wiVEFHXCJdKCBcIipcIiwgb3V0ZXJtb3N0ICksXG5cdFx0XHRcdC8vIFVzZSBpbnRlZ2VyIGRpcnJ1bnMgaWZmIHRoaXMgaXMgdGhlIG91dGVybW9zdCBtYXRjaGVyXG5cdFx0XHRcdGRpcnJ1bnNVbmlxdWUgPSAoZGlycnVucyArPSBjb250ZXh0QmFja3VwID09IG51bGwgPyAxIDogTWF0aC5yYW5kb20oKSB8fCAwLjEpLFxuXHRcdFx0XHRsZW4gPSBlbGVtcy5sZW5ndGg7XG5cblx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dCAhPT0gZG9jdW1lbnQgJiYgY29udGV4dDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIGVsZW1lbnRzIHBhc3NpbmcgZWxlbWVudE1hdGNoZXJzIGRpcmVjdGx5IHRvIHJlc3VsdHNcblx0XHRcdC8vIEtlZXAgYGlgIGEgc3RyaW5nIGlmIHRoZXJlIGFyZSBubyBlbGVtZW50cyBzbyBgbWF0Y2hlZENvdW50YCB3aWxsIGJlIFwiMDBcIiBiZWxvd1xuXHRcdFx0Ly8gU3VwcG9ydDogSUU8OSwgU2FmYXJpXG5cdFx0XHQvLyBUb2xlcmF0ZSBOb2RlTGlzdCBwcm9wZXJ0aWVzIChJRTogXCJsZW5ndGhcIjsgU2FmYXJpOiA8bnVtYmVyPikgbWF0Y2hpbmcgZWxlbWVudHMgYnkgaWRcblx0XHRcdGZvciAoIDsgaSAhPT0gbGVuICYmIChlbGVtID0gZWxlbXNbaV0pICE9IG51bGw7IGkrKyApIHtcblx0XHRcdFx0aWYgKCBieUVsZW1lbnQgJiYgZWxlbSApIHtcblx0XHRcdFx0XHRqID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoIChtYXRjaGVyID0gZWxlbWVudE1hdGNoZXJzW2orK10pICkge1xuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblx0XHRcdFx0XHRcdGRpcnJ1bnMgPSBkaXJydW5zVW5pcXVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFRyYWNrIHVubWF0Y2hlZCBlbGVtZW50cyBmb3Igc2V0IGZpbHRlcnNcblx0XHRcdFx0aWYgKCBieVNldCApIHtcblx0XHRcdFx0XHQvLyBUaGV5IHdpbGwgaGF2ZSBnb25lIHRocm91Z2ggYWxsIHBvc3NpYmxlIG1hdGNoZXJzXG5cdFx0XHRcdFx0aWYgKCAoZWxlbSA9ICFtYXRjaGVyICYmIGVsZW0pICkge1xuXHRcdFx0XHRcdFx0bWF0Y2hlZENvdW50LS07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gTGVuZ3RoZW4gdGhlIGFycmF5IGZvciBldmVyeSBlbGVtZW50LCBtYXRjaGVkIG9yIG5vdFxuXHRcdFx0XHRcdGlmICggc2VlZCApIHtcblx0XHRcdFx0XHRcdHVubWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFwcGx5IHNldCBmaWx0ZXJzIHRvIHVubWF0Y2hlZCBlbGVtZW50c1xuXHRcdFx0bWF0Y2hlZENvdW50ICs9IGk7XG5cdFx0XHRpZiAoIGJ5U2V0ICYmIGkgIT09IG1hdGNoZWRDb3VudCApIHtcblx0XHRcdFx0aiA9IDA7XG5cdFx0XHRcdHdoaWxlICggKG1hdGNoZXIgPSBzZXRNYXRjaGVyc1tqKytdKSApIHtcblx0XHRcdFx0XHRtYXRjaGVyKCB1bm1hdGNoZWQsIHNldE1hdGNoZWQsIGNvbnRleHQsIHhtbCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBzZWVkICkge1xuXHRcdFx0XHRcdC8vIFJlaW50ZWdyYXRlIGVsZW1lbnQgbWF0Y2hlcyB0byBlbGltaW5hdGUgdGhlIG5lZWQgZm9yIHNvcnRpbmdcblx0XHRcdFx0XHRpZiAoIG1hdGNoZWRDb3VudCA+IDAgKSB7XG5cdFx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCAhKHVubWF0Y2hlZFtpXSB8fCBzZXRNYXRjaGVkW2ldKSApIHtcblx0XHRcdFx0XHRcdFx0XHRzZXRNYXRjaGVkW2ldID0gcG9wLmNhbGwoIHJlc3VsdHMgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIERpc2NhcmQgaW5kZXggcGxhY2Vob2xkZXIgdmFsdWVzIHRvIGdldCBvbmx5IGFjdHVhbCBtYXRjaGVzXG5cdFx0XHRcdFx0c2V0TWF0Y2hlZCA9IGNvbmRlbnNlKCBzZXRNYXRjaGVkICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBZGQgbWF0Y2hlcyB0byByZXN1bHRzXG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIHNldE1hdGNoZWQgKTtcblxuXHRcdFx0XHQvLyBTZWVkbGVzcyBzZXQgbWF0Y2hlcyBzdWNjZWVkaW5nIG11bHRpcGxlIHN1Y2Nlc3NmdWwgbWF0Y2hlcnMgc3RpcHVsYXRlIHNvcnRpbmdcblx0XHRcdFx0aWYgKCBvdXRlcm1vc3QgJiYgIXNlZWQgJiYgc2V0TWF0Y2hlZC5sZW5ndGggPiAwICYmXG5cdFx0XHRcdFx0KCBtYXRjaGVkQ291bnQgKyBzZXRNYXRjaGVycy5sZW5ndGggKSA+IDEgKSB7XG5cblx0XHRcdFx0XHRTaXp6bGUudW5pcXVlU29ydCggcmVzdWx0cyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIE92ZXJyaWRlIG1hbmlwdWxhdGlvbiBvZiBnbG9iYWxzIGJ5IG5lc3RlZCBtYXRjaGVyc1xuXHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cdFx0XHRcdGRpcnJ1bnMgPSBkaXJydW5zVW5pcXVlO1xuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dEJhY2t1cDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHVubWF0Y2hlZDtcblx0XHR9O1xuXG5cdHJldHVybiBieVNldCA/XG5cdFx0bWFya0Z1bmN0aW9uKCBzdXBlck1hdGNoZXIgKSA6XG5cdFx0c3VwZXJNYXRjaGVyO1xufVxuXG5jb21waWxlID0gU2l6emxlLmNvbXBpbGUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIG1hdGNoIC8qIEludGVybmFsIFVzZSBPbmx5ICovICkge1xuXHR2YXIgaSxcblx0XHRzZXRNYXRjaGVycyA9IFtdLFxuXHRcdGVsZW1lbnRNYXRjaGVycyA9IFtdLFxuXHRcdGNhY2hlZCA9IGNvbXBpbGVyQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXTtcblxuXHRpZiAoICFjYWNoZWQgKSB7XG5cdFx0Ly8gR2VuZXJhdGUgYSBmdW5jdGlvbiBvZiByZWN1cnNpdmUgZnVuY3Rpb25zIHRoYXQgY2FuIGJlIHVzZWQgdG8gY2hlY2sgZWFjaCBlbGVtZW50XG5cdFx0aWYgKCAhbWF0Y2ggKSB7XG5cdFx0XHRtYXRjaCA9IHRva2VuaXplKCBzZWxlY3RvciApO1xuXHRcdH1cblx0XHRpID0gbWF0Y2gubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0Y2FjaGVkID0gbWF0Y2hlckZyb21Ub2tlbnMoIG1hdGNoW2ldICk7XG5cdFx0XHRpZiAoIGNhY2hlZFsgZXhwYW5kbyBdICkge1xuXHRcdFx0XHRzZXRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1lbnRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWNoZSB0aGUgY29tcGlsZWQgZnVuY3Rpb25cblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlKCBzZWxlY3RvciwgbWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzICkgKTtcblxuXHRcdC8vIFNhdmUgc2VsZWN0b3IgYW5kIHRva2VuaXphdGlvblxuXHRcdGNhY2hlZC5zZWxlY3RvciA9IHNlbGVjdG9yO1xuXHR9XG5cdHJldHVybiBjYWNoZWQ7XG59O1xuXG4vKipcbiAqIEEgbG93LWxldmVsIHNlbGVjdGlvbiBmdW5jdGlvbiB0aGF0IHdvcmtzIHdpdGggU2l6emxlJ3MgY29tcGlsZWRcbiAqICBzZWxlY3RvciBmdW5jdGlvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBzZWxlY3RvciBBIHNlbGVjdG9yIG9yIGEgcHJlLWNvbXBpbGVkXG4gKiAgc2VsZWN0b3IgZnVuY3Rpb24gYnVpbHQgd2l0aCBTaXp6bGUuY29tcGlsZVxuICogQHBhcmFtIHtFbGVtZW50fSBjb250ZXh0XG4gKiBAcGFyYW0ge0FycmF5fSBbcmVzdWx0c11cbiAqIEBwYXJhbSB7QXJyYXl9IFtzZWVkXSBBIHNldCBvZiBlbGVtZW50cyB0byBtYXRjaCBhZ2FpbnN0XG4gKi9cbnNlbGVjdCA9IFNpenpsZS5zZWxlY3QgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKSB7XG5cdHZhciBpLCB0b2tlbnMsIHRva2VuLCB0eXBlLCBmaW5kLFxuXHRcdGNvbXBpbGVkID0gdHlwZW9mIHNlbGVjdG9yID09PSBcImZ1bmN0aW9uXCIgJiYgc2VsZWN0b3IsXG5cdFx0bWF0Y2ggPSAhc2VlZCAmJiB0b2tlbml6ZSggKHNlbGVjdG9yID0gY29tcGlsZWQuc2VsZWN0b3IgfHwgc2VsZWN0b3IpICk7XG5cblx0cmVzdWx0cyA9IHJlc3VsdHMgfHwgW107XG5cblx0Ly8gVHJ5IHRvIG1pbmltaXplIG9wZXJhdGlvbnMgaWYgdGhlcmUgaXMgbm8gc2VlZCBhbmQgb25seSBvbmUgZ3JvdXBcblx0aWYgKCBtYXRjaC5sZW5ndGggPT09IDEgKSB7XG5cblx0XHQvLyBUYWtlIGEgc2hvcnRjdXQgYW5kIHNldCB0aGUgY29udGV4dCBpZiB0aGUgcm9vdCBzZWxlY3RvciBpcyBhbiBJRFxuXHRcdHRva2VucyA9IG1hdGNoWzBdID0gbWF0Y2hbMF0uc2xpY2UoIDAgKTtcblx0XHRpZiAoIHRva2Vucy5sZW5ndGggPiAyICYmICh0b2tlbiA9IHRva2Vuc1swXSkudHlwZSA9PT0gXCJJRFwiICYmXG5cdFx0XHRcdHN1cHBvcnQuZ2V0QnlJZCAmJiBjb250ZXh0Lm5vZGVUeXBlID09PSA5ICYmIGRvY3VtZW50SXNIVE1MICYmXG5cdFx0XHRcdEV4cHIucmVsYXRpdmVbIHRva2Vuc1sxXS50eXBlIF0gKSB7XG5cblx0XHRcdGNvbnRleHQgPSAoIEV4cHIuZmluZFtcIklEXCJdKCB0b2tlbi5tYXRjaGVzWzBdLnJlcGxhY2UocnVuZXNjYXBlLCBmdW5lc2NhcGUpLCBjb250ZXh0ICkgfHwgW10gKVswXTtcblx0XHRcdGlmICggIWNvbnRleHQgKSB7XG5cdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXG5cdFx0XHQvLyBQcmVjb21waWxlZCBtYXRjaGVycyB3aWxsIHN0aWxsIHZlcmlmeSBhbmNlc3RyeSwgc28gc3RlcCB1cCBhIGxldmVsXG5cdFx0XHR9IGVsc2UgaWYgKCBjb21waWxlZCApIHtcblx0XHRcdFx0Y29udGV4dCA9IGNvbnRleHQucGFyZW50Tm9kZTtcblx0XHRcdH1cblxuXHRcdFx0c2VsZWN0b3IgPSBzZWxlY3Rvci5zbGljZSggdG9rZW5zLnNoaWZ0KCkudmFsdWUubGVuZ3RoICk7XG5cdFx0fVxuXG5cdFx0Ly8gRmV0Y2ggYSBzZWVkIHNldCBmb3IgcmlnaHQtdG8tbGVmdCBtYXRjaGluZ1xuXHRcdGkgPSBtYXRjaEV4cHJbXCJuZWVkc0NvbnRleHRcIl0udGVzdCggc2VsZWN0b3IgKSA/IDAgOiB0b2tlbnMubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0dG9rZW4gPSB0b2tlbnNbaV07XG5cblx0XHRcdC8vIEFib3J0IGlmIHdlIGhpdCBhIGNvbWJpbmF0b3Jcblx0XHRcdGlmICggRXhwci5yZWxhdGl2ZVsgKHR5cGUgPSB0b2tlbi50eXBlKSBdICkge1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGlmICggKGZpbmQgPSBFeHByLmZpbmRbIHR5cGUgXSkgKSB7XG5cdFx0XHRcdC8vIFNlYXJjaCwgZXhwYW5kaW5nIGNvbnRleHQgZm9yIGxlYWRpbmcgc2libGluZyBjb21iaW5hdG9yc1xuXHRcdFx0XHRpZiAoIChzZWVkID0gZmluZChcblx0XHRcdFx0XHR0b2tlbi5tYXRjaGVzWzBdLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICksXG5cdFx0XHRcdFx0cnNpYmxpbmcudGVzdCggdG9rZW5zWzBdLnR5cGUgKSAmJiB0ZXN0Q29udGV4dCggY29udGV4dC5wYXJlbnROb2RlICkgfHwgY29udGV4dFxuXHRcdFx0XHQpKSApIHtcblxuXHRcdFx0XHRcdC8vIElmIHNlZWQgaXMgZW1wdHkgb3Igbm8gdG9rZW5zIHJlbWFpbiwgd2UgY2FuIHJldHVybiBlYXJseVxuXHRcdFx0XHRcdHRva2Vucy5zcGxpY2UoIGksIDEgKTtcblx0XHRcdFx0XHRzZWxlY3RvciA9IHNlZWQubGVuZ3RoICYmIHRvU2VsZWN0b3IoIHRva2VucyApO1xuXHRcdFx0XHRcdGlmICggIXNlbGVjdG9yICkge1xuXHRcdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgc2VlZCApO1xuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBDb21waWxlIGFuZCBleGVjdXRlIGEgZmlsdGVyaW5nIGZ1bmN0aW9uIGlmIG9uZSBpcyBub3QgcHJvdmlkZWRcblx0Ly8gUHJvdmlkZSBgbWF0Y2hgIHRvIGF2b2lkIHJldG9rZW5pemF0aW9uIGlmIHdlIG1vZGlmaWVkIHRoZSBzZWxlY3RvciBhYm92ZVxuXHQoIGNvbXBpbGVkIHx8IGNvbXBpbGUoIHNlbGVjdG9yLCBtYXRjaCApICkoXG5cdFx0c2VlZCxcblx0XHRjb250ZXh0LFxuXHRcdCFkb2N1bWVudElzSFRNTCxcblx0XHRyZXN1bHRzLFxuXHRcdHJzaWJsaW5nLnRlc3QoIHNlbGVjdG9yICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHRcblx0KTtcblx0cmV0dXJuIHJlc3VsdHM7XG59O1xuXG4vLyBPbmUtdGltZSBhc3NpZ25tZW50c1xuXG4vLyBTb3J0IHN0YWJpbGl0eVxuc3VwcG9ydC5zb3J0U3RhYmxlID0gZXhwYW5kby5zcGxpdChcIlwiKS5zb3J0KCBzb3J0T3JkZXIgKS5qb2luKFwiXCIpID09PSBleHBhbmRvO1xuXG4vLyBTdXBwb3J0OiBDaHJvbWU8MTRcbi8vIEFsd2F5cyBhc3N1bWUgZHVwbGljYXRlcyBpZiB0aGV5IGFyZW4ndCBwYXNzZWQgdG8gdGhlIGNvbXBhcmlzb24gZnVuY3Rpb25cbnN1cHBvcnQuZGV0ZWN0RHVwbGljYXRlcyA9ICEhaGFzRHVwbGljYXRlO1xuXG4vLyBJbml0aWFsaXplIGFnYWluc3QgdGhlIGRlZmF1bHQgZG9jdW1lbnRcbnNldERvY3VtZW50KCk7XG5cbi8vIFN1cHBvcnQ6IFdlYmtpdDw1MzcuMzIgLSBTYWZhcmkgNi4wLjMvQ2hyb21lIDI1IChmaXhlZCBpbiBDaHJvbWUgMjcpXG4vLyBEZXRhY2hlZCBub2RlcyBjb25mb3VuZGluZ2x5IGZvbGxvdyAqZWFjaCBvdGhlcipcbnN1cHBvcnQuc29ydERldGFjaGVkID0gYXNzZXJ0KGZ1bmN0aW9uKCBkaXYxICkge1xuXHQvLyBTaG91bGQgcmV0dXJuIDEsIGJ1dCByZXR1cm5zIDQgKGZvbGxvd2luZylcblx0cmV0dXJuIGRpdjEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIikgKSAmIDE7XG59KTtcblxuLy8gU3VwcG9ydDogSUU8OFxuLy8gUHJldmVudCBhdHRyaWJ1dGUvcHJvcGVydHkgXCJpbnRlcnBvbGF0aW9uXCJcbi8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNjQyOSUyOFZTLjg1JTI5LmFzcHhcbmlmICggIWFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRkaXYuaW5uZXJIVE1MID0gXCI8YSBocmVmPScjJz48L2E+XCI7XG5cdHJldHVybiBkaXYuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpID09PSBcIiNcIiA7XG59KSApIHtcblx0YWRkSGFuZGxlKCBcInR5cGV8aHJlZnxoZWlnaHR8d2lkdGhcIiwgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkge1xuXHRcdGlmICggIWlzWE1MICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lLCBuYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwidHlwZVwiID8gMSA6IDIgKTtcblx0XHR9XG5cdH0pO1xufVxuXG4vLyBTdXBwb3J0OiBJRTw5XG4vLyBVc2UgZGVmYXVsdFZhbHVlIGluIHBsYWNlIG9mIGdldEF0dHJpYnV0ZShcInZhbHVlXCIpXG5pZiAoICFzdXBwb3J0LmF0dHJpYnV0ZXMgfHwgIWFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRkaXYuaW5uZXJIVE1MID0gXCI8aW5wdXQvPlwiO1xuXHRkaXYuZmlyc3RDaGlsZC5zZXRBdHRyaWJ1dGUoIFwidmFsdWVcIiwgXCJcIiApO1xuXHRyZXR1cm4gZGl2LmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKCBcInZhbHVlXCIgKSA9PT0gXCJcIjtcbn0pICkge1xuXHRhZGRIYW5kbGUoIFwidmFsdWVcIiwgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkge1xuXHRcdGlmICggIWlzWE1MICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJpbnB1dFwiICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGVmYXVsdFZhbHVlO1xuXHRcdH1cblx0fSk7XG59XG5cbi8vIFN1cHBvcnQ6IElFPDlcbi8vIFVzZSBnZXRBdHRyaWJ1dGVOb2RlIHRvIGZldGNoIGJvb2xlYW5zIHdoZW4gZ2V0QXR0cmlidXRlIGxpZXNcbmlmICggIWFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRyZXR1cm4gZGl2LmdldEF0dHJpYnV0ZShcImRpc2FibGVkXCIpID09IG51bGw7XG59KSApIHtcblx0YWRkSGFuZGxlKCBib29sZWFucywgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkge1xuXHRcdHZhciB2YWw7XG5cdFx0aWYgKCAhaXNYTUwgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbVsgbmFtZSBdID09PSB0cnVlID8gbmFtZS50b0xvd2VyQ2FzZSgpIDpcblx0XHRcdFx0XHQodmFsID0gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCBuYW1lICkpICYmIHZhbC5zcGVjaWZpZWQgP1xuXHRcdFx0XHRcdHZhbC52YWx1ZSA6XG5cdFx0XHRcdG51bGw7XG5cdFx0fVxuXHR9KTtcbn1cblxucmV0dXJuIFNpenpsZTtcblxufSkoIHdpbmRvdyApO1xuXG5cblxualF1ZXJ5LmZpbmQgPSBTaXp6bGU7XG5qUXVlcnkuZXhwciA9IFNpenpsZS5zZWxlY3RvcnM7XG5qUXVlcnkuZXhwcltcIjpcIl0gPSBqUXVlcnkuZXhwci5wc2V1ZG9zO1xualF1ZXJ5LnVuaXF1ZSA9IFNpenpsZS51bmlxdWVTb3J0O1xualF1ZXJ5LnRleHQgPSBTaXp6bGUuZ2V0VGV4dDtcbmpRdWVyeS5pc1hNTERvYyA9IFNpenpsZS5pc1hNTDtcbmpRdWVyeS5jb250YWlucyA9IFNpenpsZS5jb250YWlucztcblxuXG5cbnZhciBybmVlZHNDb250ZXh0ID0galF1ZXJ5LmV4cHIubWF0Y2gubmVlZHNDb250ZXh0O1xuXG52YXIgcnNpbmdsZVRhZyA9ICgvXjwoXFx3KylcXHMqXFwvPz4oPzo8XFwvXFwxPnwpJC8pO1xuXG5cblxudmFyIHJpc1NpbXBsZSA9IC9eLlteOiNcXFtcXC4sXSokLztcblxuLy8gSW1wbGVtZW50IHRoZSBpZGVudGljYWwgZnVuY3Rpb25hbGl0eSBmb3IgZmlsdGVyIGFuZCBub3RcbmZ1bmN0aW9uIHdpbm5vdyggZWxlbWVudHMsIHF1YWxpZmllciwgbm90ICkge1xuXHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBxdWFsaWZpZXIgKSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdyZXAoIGVsZW1lbnRzLCBmdW5jdGlvbiggZWxlbSwgaSApIHtcblx0XHRcdC8qIGpzaGludCAtVzAxOCAqL1xuXHRcdFx0cmV0dXJuICEhcXVhbGlmaWVyLmNhbGwoIGVsZW0sIGksIGVsZW0gKSAhPT0gbm90O1xuXHRcdH0pO1xuXG5cdH1cblxuXHRpZiAoIHF1YWxpZmllci5ub2RlVHlwZSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdyZXAoIGVsZW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiAoIGVsZW0gPT09IHF1YWxpZmllciApICE9PSBub3Q7XG5cdFx0fSk7XG5cblx0fVxuXG5cdGlmICggdHlwZW9mIHF1YWxpZmllciA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRpZiAoIHJpc1NpbXBsZS50ZXN0KCBxdWFsaWZpZXIgKSApIHtcblx0XHRcdHJldHVybiBqUXVlcnkuZmlsdGVyKCBxdWFsaWZpZXIsIGVsZW1lbnRzLCBub3QgKTtcblx0XHR9XG5cblx0XHRxdWFsaWZpZXIgPSBqUXVlcnkuZmlsdGVyKCBxdWFsaWZpZXIsIGVsZW1lbnRzICk7XG5cdH1cblxuXHRyZXR1cm4galF1ZXJ5LmdyZXAoIGVsZW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gKCBpbmRleE9mLmNhbGwoIHF1YWxpZmllciwgZWxlbSApID49IDAgKSAhPT0gbm90O1xuXHR9KTtcbn1cblxualF1ZXJ5LmZpbHRlciA9IGZ1bmN0aW9uKCBleHByLCBlbGVtcywgbm90ICkge1xuXHR2YXIgZWxlbSA9IGVsZW1zWyAwIF07XG5cblx0aWYgKCBub3QgKSB7XG5cdFx0ZXhwciA9IFwiOm5vdChcIiArIGV4cHIgKyBcIilcIjtcblx0fVxuXG5cdHJldHVybiBlbGVtcy5sZW5ndGggPT09IDEgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSA/XG5cdFx0alF1ZXJ5LmZpbmQubWF0Y2hlc1NlbGVjdG9yKCBlbGVtLCBleHByICkgPyBbIGVsZW0gXSA6IFtdIDpcblx0XHRqUXVlcnkuZmluZC5tYXRjaGVzKCBleHByLCBqUXVlcnkuZ3JlcCggZWxlbXMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0ubm9kZVR5cGUgPT09IDE7XG5cdFx0fSkpO1xufTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGZpbmQ6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHR2YXIgaSxcblx0XHRcdGxlbiA9IHRoaXMubGVuZ3RoLFxuXHRcdFx0cmV0ID0gW10sXG5cdFx0XHRzZWxmID0gdGhpcztcblxuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkoIHNlbGVjdG9yICkuZmlsdGVyKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRcdGlmICggalF1ZXJ5LmNvbnRhaW5zKCBzZWxmWyBpIF0sIHRoaXMgKSApIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSkgKTtcblx0XHR9XG5cblx0XHRmb3IgKCBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0alF1ZXJ5LmZpbmQoIHNlbGVjdG9yLCBzZWxmWyBpIF0sIHJldCApO1xuXHRcdH1cblxuXHRcdC8vIE5lZWRlZCBiZWNhdXNlICQoIHNlbGVjdG9yLCBjb250ZXh0ICkgYmVjb21lcyAkKCBjb250ZXh0ICkuZmluZCggc2VsZWN0b3IgKVxuXHRcdHJldCA9IHRoaXMucHVzaFN0YWNrKCBsZW4gPiAxID8galF1ZXJ5LnVuaXF1ZSggcmV0ICkgOiByZXQgKTtcblx0XHRyZXQuc2VsZWN0b3IgPSB0aGlzLnNlbGVjdG9yID8gdGhpcy5zZWxlY3RvciArIFwiIFwiICsgc2VsZWN0b3IgOiBzZWxlY3Rvcjtcblx0XHRyZXR1cm4gcmV0O1xuXHR9LFxuXHRmaWx0ZXI6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHdpbm5vdyh0aGlzLCBzZWxlY3RvciB8fCBbXSwgZmFsc2UpICk7XG5cdH0sXG5cdG5vdDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggd2lubm93KHRoaXMsIHNlbGVjdG9yIHx8IFtdLCB0cnVlKSApO1xuXHR9LFxuXHRpczogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiAhIXdpbm5vdyhcblx0XHRcdHRoaXMsXG5cblx0XHRcdC8vIElmIHRoaXMgaXMgYSBwb3NpdGlvbmFsL3JlbGF0aXZlIHNlbGVjdG9yLCBjaGVjayBtZW1iZXJzaGlwIGluIHRoZSByZXR1cm5lZCBzZXRcblx0XHRcdC8vIHNvICQoXCJwOmZpcnN0XCIpLmlzKFwicDpsYXN0XCIpIHdvbid0IHJldHVybiB0cnVlIGZvciBhIGRvYyB3aXRoIHR3byBcInBcIi5cblx0XHRcdHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiAmJiBybmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9yICkgP1xuXHRcdFx0XHRqUXVlcnkoIHNlbGVjdG9yICkgOlxuXHRcdFx0XHRzZWxlY3RvciB8fCBbXSxcblx0XHRcdGZhbHNlXG5cdFx0KS5sZW5ndGg7XG5cdH1cbn0pO1xuXG5cbi8vIEluaXRpYWxpemUgYSBqUXVlcnkgb2JqZWN0XG5cblxuLy8gQSBjZW50cmFsIHJlZmVyZW5jZSB0byB0aGUgcm9vdCBqUXVlcnkoZG9jdW1lbnQpXG52YXIgcm9vdGpRdWVyeSxcblxuXHQvLyBBIHNpbXBsZSB3YXkgdG8gY2hlY2sgZm9yIEhUTUwgc3RyaW5nc1xuXHQvLyBQcmlvcml0aXplICNpZCBvdmVyIDx0YWc+IHRvIGF2b2lkIFhTUyB2aWEgbG9jYXRpb24uaGFzaCAoIzk1MjEpXG5cdC8vIFN0cmljdCBIVE1MIHJlY29nbml0aW9uICgjMTEyOTA6IG11c3Qgc3RhcnQgd2l0aCA8KVxuXHRycXVpY2tFeHByID0gL14oPzpcXHMqKDxbXFx3XFxXXSs+KVtePl0qfCMoW1xcdy1dKikpJC8sXG5cblx0aW5pdCA9IGpRdWVyeS5mbi5pbml0ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0ICkge1xuXHRcdHZhciBtYXRjaCwgZWxlbTtcblxuXHRcdC8vIEhBTkRMRTogJChcIlwiKSwgJChudWxsKSwgJCh1bmRlZmluZWQpLCAkKGZhbHNlKVxuXHRcdGlmICggIXNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0Ly8gSGFuZGxlIEhUTUwgc3RyaW5nc1xuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0aWYgKCBzZWxlY3RvclswXSA9PT0gXCI8XCIgJiYgc2VsZWN0b3JbIHNlbGVjdG9yLmxlbmd0aCAtIDEgXSA9PT0gXCI+XCIgJiYgc2VsZWN0b3IubGVuZ3RoID49IDMgKSB7XG5cdFx0XHRcdC8vIEFzc3VtZSB0aGF0IHN0cmluZ3MgdGhhdCBzdGFydCBhbmQgZW5kIHdpdGggPD4gYXJlIEhUTUwgYW5kIHNraXAgdGhlIHJlZ2V4IGNoZWNrXG5cdFx0XHRcdG1hdGNoID0gWyBudWxsLCBzZWxlY3RvciwgbnVsbCBdO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWF0Y2ggaHRtbCBvciBtYWtlIHN1cmUgbm8gY29udGV4dCBpcyBzcGVjaWZpZWQgZm9yICNpZFxuXHRcdFx0aWYgKCBtYXRjaCAmJiAobWF0Y2hbMV0gfHwgIWNvbnRleHQpICkge1xuXG5cdFx0XHRcdC8vIEhBTkRMRTogJChodG1sKSAtPiAkKGFycmF5KVxuXHRcdFx0XHRpZiAoIG1hdGNoWzFdICkge1xuXHRcdFx0XHRcdGNvbnRleHQgPSBjb250ZXh0IGluc3RhbmNlb2YgalF1ZXJ5ID8gY29udGV4dFswXSA6IGNvbnRleHQ7XG5cblx0XHRcdFx0XHQvLyBzY3JpcHRzIGlzIHRydWUgZm9yIGJhY2stY29tcGF0XG5cdFx0XHRcdFx0Ly8gSW50ZW50aW9uYWxseSBsZXQgdGhlIGVycm9yIGJlIHRocm93biBpZiBwYXJzZUhUTUwgaXMgbm90IHByZXNlbnRcblx0XHRcdFx0XHRqUXVlcnkubWVyZ2UoIHRoaXMsIGpRdWVyeS5wYXJzZUhUTUwoXG5cdFx0XHRcdFx0XHRtYXRjaFsxXSxcblx0XHRcdFx0XHRcdGNvbnRleHQgJiYgY29udGV4dC5ub2RlVHlwZSA/IGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0IDogZG9jdW1lbnQsXG5cdFx0XHRcdFx0XHR0cnVlXG5cdFx0XHRcdFx0KSApO1xuXG5cdFx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwsIHByb3BzKVxuXHRcdFx0XHRcdGlmICggcnNpbmdsZVRhZy50ZXN0KCBtYXRjaFsxXSApICYmIGpRdWVyeS5pc1BsYWluT2JqZWN0KCBjb250ZXh0ICkgKSB7XG5cdFx0XHRcdFx0XHRmb3IgKCBtYXRjaCBpbiBjb250ZXh0ICkge1xuXHRcdFx0XHRcdFx0XHQvLyBQcm9wZXJ0aWVzIG9mIGNvbnRleHQgYXJlIGNhbGxlZCBhcyBtZXRob2RzIGlmIHBvc3NpYmxlXG5cdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHRoaXNbIG1hdGNoIF0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzWyBtYXRjaCBdKCBjb250ZXh0WyBtYXRjaCBdICk7XG5cblx0XHRcdFx0XHRcdFx0Ly8gLi4uYW5kIG90aGVyd2lzZSBzZXQgYXMgYXR0cmlidXRlc1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuYXR0ciggbWF0Y2gsIGNvbnRleHRbIG1hdGNoIF0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0XHRcdC8vIEhBTkRMRTogJCgjaWQpXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBtYXRjaFsyXSApO1xuXG5cdFx0XHRcdFx0Ly8gQ2hlY2sgcGFyZW50Tm9kZSB0byBjYXRjaCB3aGVuIEJsYWNrYmVycnkgNC42IHJldHVybnNcblx0XHRcdFx0XHQvLyBub2RlcyB0aGF0IGFyZSBubyBsb25nZXIgaW4gdGhlIGRvY3VtZW50ICM2OTYzXG5cdFx0XHRcdFx0aWYgKCBlbGVtICYmIGVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0XHRcdC8vIEluamVjdCB0aGUgZWxlbWVudCBkaXJlY3RseSBpbnRvIHRoZSBqUXVlcnkgb2JqZWN0XG5cdFx0XHRcdFx0XHR0aGlzLmxlbmd0aCA9IDE7XG5cdFx0XHRcdFx0XHR0aGlzWzBdID0gZWxlbTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR0aGlzLmNvbnRleHQgPSBkb2N1bWVudDtcblx0XHRcdFx0XHR0aGlzLnNlbGVjdG9yID0gc2VsZWN0b3I7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gSEFORExFOiAkKGV4cHIsICQoLi4uKSlcblx0XHRcdH0gZWxzZSBpZiAoICFjb250ZXh0IHx8IGNvbnRleHQuanF1ZXJ5ICkge1xuXHRcdFx0XHRyZXR1cm4gKCBjb250ZXh0IHx8IHJvb3RqUXVlcnkgKS5maW5kKCBzZWxlY3RvciApO1xuXG5cdFx0XHQvLyBIQU5ETEU6ICQoZXhwciwgY29udGV4dClcblx0XHRcdC8vICh3aGljaCBpcyBqdXN0IGVxdWl2YWxlbnQgdG86ICQoY29udGV4dCkuZmluZChleHByKVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIHRoaXMuY29uc3RydWN0b3IoIGNvbnRleHQgKS5maW5kKCBzZWxlY3RvciApO1xuXHRcdFx0fVxuXG5cdFx0Ly8gSEFORExFOiAkKERPTUVsZW1lbnQpXG5cdFx0fSBlbHNlIGlmICggc2VsZWN0b3Iubm9kZVR5cGUgKSB7XG5cdFx0XHR0aGlzLmNvbnRleHQgPSB0aGlzWzBdID0gc2VsZWN0b3I7XG5cdFx0XHR0aGlzLmxlbmd0aCA9IDE7XG5cdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdC8vIEhBTkRMRTogJChmdW5jdGlvbilcblx0XHQvLyBTaG9ydGN1dCBmb3IgZG9jdW1lbnQgcmVhZHlcblx0XHR9IGVsc2UgaWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggc2VsZWN0b3IgKSApIHtcblx0XHRcdHJldHVybiB0eXBlb2Ygcm9vdGpRdWVyeS5yZWFkeSAhPT0gXCJ1bmRlZmluZWRcIiA/XG5cdFx0XHRcdHJvb3RqUXVlcnkucmVhZHkoIHNlbGVjdG9yICkgOlxuXHRcdFx0XHQvLyBFeGVjdXRlIGltbWVkaWF0ZWx5IGlmIHJlYWR5IGlzIG5vdCBwcmVzZW50XG5cdFx0XHRcdHNlbGVjdG9yKCBqUXVlcnkgKTtcblx0XHR9XG5cblx0XHRpZiAoIHNlbGVjdG9yLnNlbGVjdG9yICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR0aGlzLnNlbGVjdG9yID0gc2VsZWN0b3Iuc2VsZWN0b3I7XG5cdFx0XHR0aGlzLmNvbnRleHQgPSBzZWxlY3Rvci5jb250ZXh0O1xuXHRcdH1cblxuXHRcdHJldHVybiBqUXVlcnkubWFrZUFycmF5KCBzZWxlY3RvciwgdGhpcyApO1xuXHR9O1xuXG4vLyBHaXZlIHRoZSBpbml0IGZ1bmN0aW9uIHRoZSBqUXVlcnkgcHJvdG90eXBlIGZvciBsYXRlciBpbnN0YW50aWF0aW9uXG5pbml0LnByb3RvdHlwZSA9IGpRdWVyeS5mbjtcblxuLy8gSW5pdGlhbGl6ZSBjZW50cmFsIHJlZmVyZW5jZVxucm9vdGpRdWVyeSA9IGpRdWVyeSggZG9jdW1lbnQgKTtcblxuXG52YXIgcnBhcmVudHNwcmV2ID0gL14oPzpwYXJlbnRzfHByZXYoPzpVbnRpbHxBbGwpKS8sXG5cdC8vIG1ldGhvZHMgZ3VhcmFudGVlZCB0byBwcm9kdWNlIGEgdW5pcXVlIHNldCB3aGVuIHN0YXJ0aW5nIGZyb20gYSB1bmlxdWUgc2V0XG5cdGd1YXJhbnRlZWRVbmlxdWUgPSB7XG5cdFx0Y2hpbGRyZW46IHRydWUsXG5cdFx0Y29udGVudHM6IHRydWUsXG5cdFx0bmV4dDogdHJ1ZSxcblx0XHRwcmV2OiB0cnVlXG5cdH07XG5cbmpRdWVyeS5leHRlbmQoe1xuXHRkaXI6IGZ1bmN0aW9uKCBlbGVtLCBkaXIsIHVudGlsICkge1xuXHRcdHZhciBtYXRjaGVkID0gW10sXG5cdFx0XHR0cnVuY2F0ZSA9IHVudGlsICE9PSB1bmRlZmluZWQ7XG5cblx0XHR3aGlsZSAoIChlbGVtID0gZWxlbVsgZGlyIF0pICYmIGVsZW0ubm9kZVR5cGUgIT09IDkgKSB7XG5cdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRcdGlmICggdHJ1bmNhdGUgJiYgalF1ZXJ5KCBlbGVtICkuaXMoIHVudGlsICkgKSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdFx0bWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBtYXRjaGVkO1xuXHR9LFxuXG5cdHNpYmxpbmc6IGZ1bmN0aW9uKCBuLCBlbGVtICkge1xuXHRcdHZhciBtYXRjaGVkID0gW107XG5cblx0XHRmb3IgKCA7IG47IG4gPSBuLm5leHRTaWJsaW5nICkge1xuXHRcdFx0aWYgKCBuLm5vZGVUeXBlID09PSAxICYmIG4gIT09IGVsZW0gKSB7XG5cdFx0XHRcdG1hdGNoZWQucHVzaCggbiApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBtYXRjaGVkO1xuXHR9XG59KTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGhhczogZnVuY3Rpb24oIHRhcmdldCApIHtcblx0XHR2YXIgdGFyZ2V0cyA9IGpRdWVyeSggdGFyZ2V0LCB0aGlzICksXG5cdFx0XHRsID0gdGFyZ2V0cy5sZW5ndGg7XG5cblx0XHRyZXR1cm4gdGhpcy5maWx0ZXIoZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgaSA9IDA7XG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdGlmICggalF1ZXJ5LmNvbnRhaW5zKCB0aGlzLCB0YXJnZXRzW2ldICkgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRjbG9zZXN0OiBmdW5jdGlvbiggc2VsZWN0b3JzLCBjb250ZXh0ICkge1xuXHRcdHZhciBjdXIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSB0aGlzLmxlbmd0aCxcblx0XHRcdG1hdGNoZWQgPSBbXSxcblx0XHRcdHBvcyA9IHJuZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3JzICkgfHwgdHlwZW9mIHNlbGVjdG9ycyAhPT0gXCJzdHJpbmdcIiA/XG5cdFx0XHRcdGpRdWVyeSggc2VsZWN0b3JzLCBjb250ZXh0IHx8IHRoaXMuY29udGV4dCApIDpcblx0XHRcdFx0MDtcblxuXHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdGZvciAoIGN1ciA9IHRoaXNbaV07IGN1ciAmJiBjdXIgIT09IGNvbnRleHQ7IGN1ciA9IGN1ci5wYXJlbnROb2RlICkge1xuXHRcdFx0XHQvLyBBbHdheXMgc2tpcCBkb2N1bWVudCBmcmFnbWVudHNcblx0XHRcdFx0aWYgKCBjdXIubm9kZVR5cGUgPCAxMSAmJiAocG9zID9cblx0XHRcdFx0XHRwb3MuaW5kZXgoY3VyKSA+IC0xIDpcblxuXHRcdFx0XHRcdC8vIERvbid0IHBhc3Mgbm9uLWVsZW1lbnRzIHRvIFNpenpsZVxuXHRcdFx0XHRcdGN1ci5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0XHRcdFx0alF1ZXJ5LmZpbmQubWF0Y2hlc1NlbGVjdG9yKGN1ciwgc2VsZWN0b3JzKSkgKSB7XG5cblx0XHRcdFx0XHRtYXRjaGVkLnB1c2goIGN1ciApO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBtYXRjaGVkLmxlbmd0aCA+IDEgPyBqUXVlcnkudW5pcXVlKCBtYXRjaGVkICkgOiBtYXRjaGVkICk7XG5cdH0sXG5cblx0Ly8gRGV0ZXJtaW5lIHRoZSBwb3NpdGlvbiBvZiBhbiBlbGVtZW50IHdpdGhpblxuXHQvLyB0aGUgbWF0Y2hlZCBzZXQgb2YgZWxlbWVudHNcblx0aW5kZXg6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gTm8gYXJndW1lbnQsIHJldHVybiBpbmRleCBpbiBwYXJlbnRcblx0XHRpZiAoICFlbGVtICkge1xuXHRcdFx0cmV0dXJuICggdGhpc1sgMCBdICYmIHRoaXNbIDAgXS5wYXJlbnROb2RlICkgPyB0aGlzLmZpcnN0KCkucHJldkFsbCgpLmxlbmd0aCA6IC0xO1xuXHRcdH1cblxuXHRcdC8vIGluZGV4IGluIHNlbGVjdG9yXG5cdFx0aWYgKCB0eXBlb2YgZWxlbSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBpbmRleE9mLmNhbGwoIGpRdWVyeSggZWxlbSApLCB0aGlzWyAwIF0gKTtcblx0XHR9XG5cblx0XHQvLyBMb2NhdGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBkZXNpcmVkIGVsZW1lbnRcblx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCB0aGlzLFxuXG5cdFx0XHQvLyBJZiBpdCByZWNlaXZlcyBhIGpRdWVyeSBvYmplY3QsIHRoZSBmaXJzdCBlbGVtZW50IGlzIHVzZWRcblx0XHRcdGVsZW0uanF1ZXJ5ID8gZWxlbVsgMCBdIDogZWxlbVxuXHRcdCk7XG5cdH0sXG5cblx0YWRkOiBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKFxuXHRcdFx0alF1ZXJ5LnVuaXF1ZShcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCB0aGlzLmdldCgpLCBqUXVlcnkoIHNlbGVjdG9yLCBjb250ZXh0ICkgKVxuXHRcdFx0KVxuXHRcdCk7XG5cdH0sXG5cblx0YWRkQmFjazogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiB0aGlzLmFkZCggc2VsZWN0b3IgPT0gbnVsbCA/XG5cdFx0XHR0aGlzLnByZXZPYmplY3QgOiB0aGlzLnByZXZPYmplY3QuZmlsdGVyKHNlbGVjdG9yKVxuXHRcdCk7XG5cdH1cbn0pO1xuXG5mdW5jdGlvbiBzaWJsaW5nKCBjdXIsIGRpciApIHtcblx0d2hpbGUgKCAoY3VyID0gY3VyW2Rpcl0pICYmIGN1ci5ub2RlVHlwZSAhPT0gMSApIHt9XG5cdHJldHVybiBjdXI7XG59XG5cbmpRdWVyeS5lYWNoKHtcblx0cGFyZW50OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdHJldHVybiBwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlICE9PSAxMSA/IHBhcmVudCA6IG51bGw7XG5cdH0sXG5cdHBhcmVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBqUXVlcnkuZGlyKCBlbGVtLCBcInBhcmVudE5vZGVcIiApO1xuXHR9LFxuXHRwYXJlbnRzVW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBpLCB1bnRpbCApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmRpciggZWxlbSwgXCJwYXJlbnROb2RlXCIsIHVudGlsICk7XG5cdH0sXG5cdG5leHQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBzaWJsaW5nKCBlbGVtLCBcIm5leHRTaWJsaW5nXCIgKTtcblx0fSxcblx0cHJldjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIHNpYmxpbmcoIGVsZW0sIFwicHJldmlvdXNTaWJsaW5nXCIgKTtcblx0fSxcblx0bmV4dEFsbDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5kaXIoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiApO1xuXHR9LFxuXHRwcmV2QWxsOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiApO1xuXHR9LFxuXHRuZXh0VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBpLCB1bnRpbCApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmRpciggZWxlbSwgXCJuZXh0U2libGluZ1wiLCB1bnRpbCApO1xuXHR9LFxuXHRwcmV2VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBpLCB1bnRpbCApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiwgdW50aWwgKTtcblx0fSxcblx0c2libGluZ3M6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBqUXVlcnkuc2libGluZyggKCBlbGVtLnBhcmVudE5vZGUgfHwge30gKS5maXJzdENoaWxkLCBlbGVtICk7XG5cdH0sXG5cdGNoaWxkcmVuOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LnNpYmxpbmcoIGVsZW0uZmlyc3RDaGlsZCApO1xuXHR9LFxuXHRjb250ZW50czogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGVsZW0uY29udGVudERvY3VtZW50IHx8IGpRdWVyeS5tZXJnZSggW10sIGVsZW0uY2hpbGROb2RlcyApO1xuXHR9XG59LCBmdW5jdGlvbiggbmFtZSwgZm4gKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHVudGlsLCBzZWxlY3RvciApIHtcblx0XHR2YXIgbWF0Y2hlZCA9IGpRdWVyeS5tYXAoIHRoaXMsIGZuLCB1bnRpbCApO1xuXG5cdFx0aWYgKCBuYW1lLnNsaWNlKCAtNSApICE9PSBcIlVudGlsXCIgKSB7XG5cdFx0XHRzZWxlY3RvciA9IHVudGlsO1xuXHRcdH1cblxuXHRcdGlmICggc2VsZWN0b3IgJiYgdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0bWF0Y2hlZCA9IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCBtYXRjaGVkICk7XG5cdFx0fVxuXG5cdFx0aWYgKCB0aGlzLmxlbmd0aCA+IDEgKSB7XG5cdFx0XHQvLyBSZW1vdmUgZHVwbGljYXRlc1xuXHRcdFx0aWYgKCAhZ3VhcmFudGVlZFVuaXF1ZVsgbmFtZSBdICkge1xuXHRcdFx0XHRqUXVlcnkudW5pcXVlKCBtYXRjaGVkICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJldmVyc2Ugb3JkZXIgZm9yIHBhcmVudHMqIGFuZCBwcmV2LWRlcml2YXRpdmVzXG5cdFx0XHRpZiAoIHJwYXJlbnRzcHJldi50ZXN0KCBuYW1lICkgKSB7XG5cdFx0XHRcdG1hdGNoZWQucmV2ZXJzZSgpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZCApO1xuXHR9O1xufSk7XG52YXIgcm5vdHdoaXRlID0gKC9cXFMrL2cpO1xuXG5cblxuLy8gU3RyaW5nIHRvIE9iamVjdCBvcHRpb25zIGZvcm1hdCBjYWNoZVxudmFyIG9wdGlvbnNDYWNoZSA9IHt9O1xuXG4vLyBDb252ZXJ0IFN0cmluZy1mb3JtYXR0ZWQgb3B0aW9ucyBpbnRvIE9iamVjdC1mb3JtYXR0ZWQgb25lcyBhbmQgc3RvcmUgaW4gY2FjaGVcbmZ1bmN0aW9uIGNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSB7XG5cdHZhciBvYmplY3QgPSBvcHRpb25zQ2FjaGVbIG9wdGlvbnMgXSA9IHt9O1xuXHRqUXVlcnkuZWFjaCggb3B0aW9ucy5tYXRjaCggcm5vdHdoaXRlICkgfHwgW10sIGZ1bmN0aW9uKCBfLCBmbGFnICkge1xuXHRcdG9iamVjdFsgZmxhZyBdID0gdHJ1ZTtcblx0fSk7XG5cdHJldHVybiBvYmplY3Q7XG59XG5cbi8qXG4gKiBDcmVhdGUgYSBjYWxsYmFjayBsaXN0IHVzaW5nIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczpcbiAqXG4gKlx0b3B0aW9uczogYW4gb3B0aW9uYWwgbGlzdCBvZiBzcGFjZS1zZXBhcmF0ZWQgb3B0aW9ucyB0aGF0IHdpbGwgY2hhbmdlIGhvd1xuICpcdFx0XHR0aGUgY2FsbGJhY2sgbGlzdCBiZWhhdmVzIG9yIGEgbW9yZSB0cmFkaXRpb25hbCBvcHRpb24gb2JqZWN0XG4gKlxuICogQnkgZGVmYXVsdCBhIGNhbGxiYWNrIGxpc3Qgd2lsbCBhY3QgbGlrZSBhbiBldmVudCBjYWxsYmFjayBsaXN0IGFuZCBjYW4gYmVcbiAqIFwiZmlyZWRcIiBtdWx0aXBsZSB0aW1lcy5cbiAqXG4gKiBQb3NzaWJsZSBvcHRpb25zOlxuICpcbiAqXHRvbmNlOlx0XHRcdHdpbGwgZW5zdXJlIHRoZSBjYWxsYmFjayBsaXN0IGNhbiBvbmx5IGJlIGZpcmVkIG9uY2UgKGxpa2UgYSBEZWZlcnJlZClcbiAqXG4gKlx0bWVtb3J5Olx0XHRcdHdpbGwga2VlcCB0cmFjayBvZiBwcmV2aW91cyB2YWx1ZXMgYW5kIHdpbGwgY2FsbCBhbnkgY2FsbGJhY2sgYWRkZWRcbiAqXHRcdFx0XHRcdGFmdGVyIHRoZSBsaXN0IGhhcyBiZWVuIGZpcmVkIHJpZ2h0IGF3YXkgd2l0aCB0aGUgbGF0ZXN0IFwibWVtb3JpemVkXCJcbiAqXHRcdFx0XHRcdHZhbHVlcyAobGlrZSBhIERlZmVycmVkKVxuICpcbiAqXHR1bmlxdWU6XHRcdFx0d2lsbCBlbnN1cmUgYSBjYWxsYmFjayBjYW4gb25seSBiZSBhZGRlZCBvbmNlIChubyBkdXBsaWNhdGUgaW4gdGhlIGxpc3QpXG4gKlxuICpcdHN0b3BPbkZhbHNlOlx0aW50ZXJydXB0IGNhbGxpbmdzIHdoZW4gYSBjYWxsYmFjayByZXR1cm5zIGZhbHNlXG4gKlxuICovXG5qUXVlcnkuQ2FsbGJhY2tzID0gZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cblx0Ly8gQ29udmVydCBvcHRpb25zIGZyb20gU3RyaW5nLWZvcm1hdHRlZCB0byBPYmplY3QtZm9ybWF0dGVkIGlmIG5lZWRlZFxuXHQvLyAod2UgY2hlY2sgaW4gY2FjaGUgZmlyc3QpXG5cdG9wdGlvbnMgPSB0eXBlb2Ygb3B0aW9ucyA9PT0gXCJzdHJpbmdcIiA/XG5cdFx0KCBvcHRpb25zQ2FjaGVbIG9wdGlvbnMgXSB8fCBjcmVhdGVPcHRpb25zKCBvcHRpb25zICkgKSA6XG5cdFx0alF1ZXJ5LmV4dGVuZCgge30sIG9wdGlvbnMgKTtcblxuXHR2YXIgLy8gTGFzdCBmaXJlIHZhbHVlIChmb3Igbm9uLWZvcmdldHRhYmxlIGxpc3RzKVxuXHRcdG1lbW9yeSxcblx0XHQvLyBGbGFnIHRvIGtub3cgaWYgbGlzdCB3YXMgYWxyZWFkeSBmaXJlZFxuXHRcdGZpcmVkLFxuXHRcdC8vIEZsYWcgdG8ga25vdyBpZiBsaXN0IGlzIGN1cnJlbnRseSBmaXJpbmdcblx0XHRmaXJpbmcsXG5cdFx0Ly8gRmlyc3QgY2FsbGJhY2sgdG8gZmlyZSAodXNlZCBpbnRlcm5hbGx5IGJ5IGFkZCBhbmQgZmlyZVdpdGgpXG5cdFx0ZmlyaW5nU3RhcnQsXG5cdFx0Ly8gRW5kIG9mIHRoZSBsb29wIHdoZW4gZmlyaW5nXG5cdFx0ZmlyaW5nTGVuZ3RoLFxuXHRcdC8vIEluZGV4IG9mIGN1cnJlbnRseSBmaXJpbmcgY2FsbGJhY2sgKG1vZGlmaWVkIGJ5IHJlbW92ZSBpZiBuZWVkZWQpXG5cdFx0ZmlyaW5nSW5kZXgsXG5cdFx0Ly8gQWN0dWFsIGNhbGxiYWNrIGxpc3Rcblx0XHRsaXN0ID0gW10sXG5cdFx0Ly8gU3RhY2sgb2YgZmlyZSBjYWxscyBmb3IgcmVwZWF0YWJsZSBsaXN0c1xuXHRcdHN0YWNrID0gIW9wdGlvbnMub25jZSAmJiBbXSxcblx0XHQvLyBGaXJlIGNhbGxiYWNrc1xuXHRcdGZpcmUgPSBmdW5jdGlvbiggZGF0YSApIHtcblx0XHRcdG1lbW9yeSA9IG9wdGlvbnMubWVtb3J5ICYmIGRhdGE7XG5cdFx0XHRmaXJlZCA9IHRydWU7XG5cdFx0XHRmaXJpbmdJbmRleCA9IGZpcmluZ1N0YXJ0IHx8IDA7XG5cdFx0XHRmaXJpbmdTdGFydCA9IDA7XG5cdFx0XHRmaXJpbmdMZW5ndGggPSBsaXN0Lmxlbmd0aDtcblx0XHRcdGZpcmluZyA9IHRydWU7XG5cdFx0XHRmb3IgKCA7IGxpc3QgJiYgZmlyaW5nSW5kZXggPCBmaXJpbmdMZW5ndGg7IGZpcmluZ0luZGV4KysgKSB7XG5cdFx0XHRcdGlmICggbGlzdFsgZmlyaW5nSW5kZXggXS5hcHBseSggZGF0YVsgMCBdLCBkYXRhWyAxIF0gKSA9PT0gZmFsc2UgJiYgb3B0aW9ucy5zdG9wT25GYWxzZSApIHtcblx0XHRcdFx0XHRtZW1vcnkgPSBmYWxzZTsgLy8gVG8gcHJldmVudCBmdXJ0aGVyIGNhbGxzIHVzaW5nIGFkZFxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRmaXJpbmcgPSBmYWxzZTtcblx0XHRcdGlmICggbGlzdCApIHtcblx0XHRcdFx0aWYgKCBzdGFjayApIHtcblx0XHRcdFx0XHRpZiAoIHN0YWNrLmxlbmd0aCApIHtcblx0XHRcdFx0XHRcdGZpcmUoIHN0YWNrLnNoaWZ0KCkgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSBpZiAoIG1lbW9yeSApIHtcblx0XHRcdFx0XHRsaXN0ID0gW107XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c2VsZi5kaXNhYmxlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXHRcdC8vIEFjdHVhbCBDYWxsYmFja3Mgb2JqZWN0XG5cdFx0c2VsZiA9IHtcblx0XHRcdC8vIEFkZCBhIGNhbGxiYWNrIG9yIGEgY29sbGVjdGlvbiBvZiBjYWxsYmFja3MgdG8gdGhlIGxpc3Rcblx0XHRcdGFkZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblx0XHRcdFx0XHQvLyBGaXJzdCwgd2Ugc2F2ZSB0aGUgY3VycmVudCBsZW5ndGhcblx0XHRcdFx0XHR2YXIgc3RhcnQgPSBsaXN0Lmxlbmd0aDtcblx0XHRcdFx0XHQoZnVuY3Rpb24gYWRkKCBhcmdzICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5LmVhY2goIGFyZ3MsIGZ1bmN0aW9uKCBfLCBhcmcgKSB7XG5cdFx0XHRcdFx0XHRcdHZhciB0eXBlID0galF1ZXJ5LnR5cGUoIGFyZyApO1xuXHRcdFx0XHRcdFx0XHRpZiAoIHR5cGUgPT09IFwiZnVuY3Rpb25cIiApIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoICFvcHRpb25zLnVuaXF1ZSB8fCAhc2VsZi5oYXMoIGFyZyApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0bGlzdC5wdXNoKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGFyZyAmJiBhcmcubGVuZ3RoICYmIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly8gSW5zcGVjdCByZWN1cnNpdmVseVxuXHRcdFx0XHRcdFx0XHRcdGFkZCggYXJnICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH0pKCBhcmd1bWVudHMgKTtcblx0XHRcdFx0XHQvLyBEbyB3ZSBuZWVkIHRvIGFkZCB0aGUgY2FsbGJhY2tzIHRvIHRoZVxuXHRcdFx0XHRcdC8vIGN1cnJlbnQgZmlyaW5nIGJhdGNoP1xuXHRcdFx0XHRcdGlmICggZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0ZmlyaW5nTGVuZ3RoID0gbGlzdC5sZW5ndGg7XG5cdFx0XHRcdFx0Ly8gV2l0aCBtZW1vcnksIGlmIHdlJ3JlIG5vdCBmaXJpbmcgdGhlblxuXHRcdFx0XHRcdC8vIHdlIHNob3VsZCBjYWxsIHJpZ2h0IGF3YXlcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBtZW1vcnkgKSB7XG5cdFx0XHRcdFx0XHRmaXJpbmdTdGFydCA9IHN0YXJ0O1xuXHRcdFx0XHRcdFx0ZmlyZSggbWVtb3J5ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIFJlbW92ZSBhIGNhbGxiYWNrIGZyb20gdGhlIGxpc3Rcblx0XHRcdHJlbW92ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblx0XHRcdFx0XHRqUXVlcnkuZWFjaCggYXJndW1lbnRzLCBmdW5jdGlvbiggXywgYXJnICkge1xuXHRcdFx0XHRcdFx0dmFyIGluZGV4O1xuXHRcdFx0XHRcdFx0d2hpbGUgKCAoIGluZGV4ID0galF1ZXJ5LmluQXJyYXkoIGFyZywgbGlzdCwgaW5kZXggKSApID4gLTEgKSB7XG5cdFx0XHRcdFx0XHRcdGxpc3Quc3BsaWNlKCBpbmRleCwgMSApO1xuXHRcdFx0XHRcdFx0XHQvLyBIYW5kbGUgZmlyaW5nIGluZGV4ZXNcblx0XHRcdFx0XHRcdFx0aWYgKCBmaXJpbmcgKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBpbmRleCA8PSBmaXJpbmdMZW5ndGggKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRmaXJpbmdMZW5ndGgtLTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBpbmRleCA8PSBmaXJpbmdJbmRleCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGZpcmluZ0luZGV4LS07XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gQ2hlY2sgaWYgYSBnaXZlbiBjYWxsYmFjayBpcyBpbiB0aGUgbGlzdC5cblx0XHRcdC8vIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCByZXR1cm4gd2hldGhlciBvciBub3QgbGlzdCBoYXMgY2FsbGJhY2tzIGF0dGFjaGVkLlxuXHRcdFx0aGFzOiBmdW5jdGlvbiggZm4gKSB7XG5cdFx0XHRcdHJldHVybiBmbiA/IGpRdWVyeS5pbkFycmF5KCBmbiwgbGlzdCApID4gLTEgOiAhISggbGlzdCAmJiBsaXN0Lmxlbmd0aCApO1xuXHRcdFx0fSxcblx0XHRcdC8vIFJlbW92ZSBhbGwgY2FsbGJhY2tzIGZyb20gdGhlIGxpc3Rcblx0XHRcdGVtcHR5OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0bGlzdCA9IFtdO1xuXHRcdFx0XHRmaXJpbmdMZW5ndGggPSAwO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBIYXZlIHRoZSBsaXN0IGRvIG5vdGhpbmcgYW55bW9yZVxuXHRcdFx0ZGlzYWJsZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGxpc3QgPSBzdGFjayA9IG1lbW9yeSA9IHVuZGVmaW5lZDtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gSXMgaXQgZGlzYWJsZWQ/XG5cdFx0XHRkaXNhYmxlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhbGlzdDtcblx0XHRcdH0sXG5cdFx0XHQvLyBMb2NrIHRoZSBsaXN0IGluIGl0cyBjdXJyZW50IHN0YXRlXG5cdFx0XHRsb2NrOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0c3RhY2sgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdGlmICggIW1lbW9yeSApIHtcblx0XHRcdFx0XHRzZWxmLmRpc2FibGUoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBJcyBpdCBsb2NrZWQ/XG5cdFx0XHRsb2NrZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gIXN0YWNrO1xuXHRcdFx0fSxcblx0XHRcdC8vIENhbGwgYWxsIGNhbGxiYWNrcyB3aXRoIHRoZSBnaXZlbiBjb250ZXh0IGFuZCBhcmd1bWVudHNcblx0XHRcdGZpcmVXaXRoOiBmdW5jdGlvbiggY29udGV4dCwgYXJncyApIHtcblx0XHRcdFx0aWYgKCBsaXN0ICYmICggIWZpcmVkIHx8IHN0YWNrICkgKSB7XG5cdFx0XHRcdFx0YXJncyA9IGFyZ3MgfHwgW107XG5cdFx0XHRcdFx0YXJncyA9IFsgY29udGV4dCwgYXJncy5zbGljZSA/IGFyZ3Muc2xpY2UoKSA6IGFyZ3MgXTtcblx0XHRcdFx0XHRpZiAoIGZpcmluZyApIHtcblx0XHRcdFx0XHRcdHN0YWNrLnB1c2goIGFyZ3MgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0ZmlyZSggYXJncyApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBDYWxsIGFsbCB0aGUgY2FsbGJhY2tzIHdpdGggdGhlIGdpdmVuIGFyZ3VtZW50c1xuXHRcdFx0ZmlyZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHNlbGYuZmlyZVdpdGgoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBUbyBrbm93IGlmIHRoZSBjYWxsYmFja3MgaGF2ZSBhbHJlYWR5IGJlZW4gY2FsbGVkIGF0IGxlYXN0IG9uY2Vcblx0XHRcdGZpcmVkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICEhZmlyZWQ7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRyZXR1cm4gc2VsZjtcbn07XG5cblxualF1ZXJ5LmV4dGVuZCh7XG5cblx0RGVmZXJyZWQ6IGZ1bmN0aW9uKCBmdW5jICkge1xuXHRcdHZhciB0dXBsZXMgPSBbXG5cdFx0XHRcdC8vIGFjdGlvbiwgYWRkIGxpc3RlbmVyLCBsaXN0ZW5lciBsaXN0LCBmaW5hbCBzdGF0ZVxuXHRcdFx0XHRbIFwicmVzb2x2ZVwiLCBcImRvbmVcIiwgalF1ZXJ5LkNhbGxiYWNrcyhcIm9uY2UgbWVtb3J5XCIpLCBcInJlc29sdmVkXCIgXSxcblx0XHRcdFx0WyBcInJlamVjdFwiLCBcImZhaWxcIiwgalF1ZXJ5LkNhbGxiYWNrcyhcIm9uY2UgbWVtb3J5XCIpLCBcInJlamVjdGVkXCIgXSxcblx0XHRcdFx0WyBcIm5vdGlmeVwiLCBcInByb2dyZXNzXCIsIGpRdWVyeS5DYWxsYmFja3MoXCJtZW1vcnlcIikgXVxuXHRcdFx0XSxcblx0XHRcdHN0YXRlID0gXCJwZW5kaW5nXCIsXG5cdFx0XHRwcm9taXNlID0ge1xuXHRcdFx0XHRzdGF0ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHN0YXRlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRhbHdheXM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGRlZmVycmVkLmRvbmUoIGFyZ3VtZW50cyApLmZhaWwoIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR0aGVuOiBmdW5jdGlvbiggLyogZm5Eb25lLCBmbkZhaWwsIGZuUHJvZ3Jlc3MgKi8gKSB7XG5cdFx0XHRcdFx0dmFyIGZucyA9IGFyZ3VtZW50cztcblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKGZ1bmN0aW9uKCBuZXdEZWZlciApIHtcblx0XHRcdFx0XHRcdGpRdWVyeS5lYWNoKCB0dXBsZXMsIGZ1bmN0aW9uKCBpLCB0dXBsZSApIHtcblx0XHRcdFx0XHRcdFx0dmFyIGZuID0galF1ZXJ5LmlzRnVuY3Rpb24oIGZuc1sgaSBdICkgJiYgZm5zWyBpIF07XG5cdFx0XHRcdFx0XHRcdC8vIGRlZmVycmVkWyBkb25lIHwgZmFpbCB8IHByb2dyZXNzIF0gZm9yIGZvcndhcmRpbmcgYWN0aW9ucyB0byBuZXdEZWZlclxuXHRcdFx0XHRcdFx0XHRkZWZlcnJlZFsgdHVwbGVbMV0gXShmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHR2YXIgcmV0dXJuZWQgPSBmbiAmJiBmbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCByZXR1cm5lZCAmJiBqUXVlcnkuaXNGdW5jdGlvbiggcmV0dXJuZWQucHJvbWlzZSApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQucHJvbWlzZSgpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5kb25lKCBuZXdEZWZlci5yZXNvbHZlIClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmZhaWwoIG5ld0RlZmVyLnJlamVjdCApXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5wcm9ncmVzcyggbmV3RGVmZXIubm90aWZ5ICk7XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdG5ld0RlZmVyWyB0dXBsZVsgMCBdICsgXCJXaXRoXCIgXSggdGhpcyA9PT0gcHJvbWlzZSA/IG5ld0RlZmVyLnByb21pc2UoKSA6IHRoaXMsIGZuID8gWyByZXR1cm5lZCBdIDogYXJndW1lbnRzICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0Zm5zID0gbnVsbDtcblx0XHRcdFx0XHR9KS5wcm9taXNlKCk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdC8vIEdldCBhIHByb21pc2UgZm9yIHRoaXMgZGVmZXJyZWRcblx0XHRcdFx0Ly8gSWYgb2JqIGlzIHByb3ZpZGVkLCB0aGUgcHJvbWlzZSBhc3BlY3QgaXMgYWRkZWQgdG8gdGhlIG9iamVjdFxuXHRcdFx0XHRwcm9taXNlOiBmdW5jdGlvbiggb2JqICkge1xuXHRcdFx0XHRcdHJldHVybiBvYmogIT0gbnVsbCA/IGpRdWVyeS5leHRlbmQoIG9iaiwgcHJvbWlzZSApIDogcHJvbWlzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGRlZmVycmVkID0ge307XG5cblx0XHQvLyBLZWVwIHBpcGUgZm9yIGJhY2stY29tcGF0XG5cdFx0cHJvbWlzZS5waXBlID0gcHJvbWlzZS50aGVuO1xuXG5cdFx0Ly8gQWRkIGxpc3Qtc3BlY2lmaWMgbWV0aG9kc1xuXHRcdGpRdWVyeS5lYWNoKCB0dXBsZXMsIGZ1bmN0aW9uKCBpLCB0dXBsZSApIHtcblx0XHRcdHZhciBsaXN0ID0gdHVwbGVbIDIgXSxcblx0XHRcdFx0c3RhdGVTdHJpbmcgPSB0dXBsZVsgMyBdO1xuXG5cdFx0XHQvLyBwcm9taXNlWyBkb25lIHwgZmFpbCB8IHByb2dyZXNzIF0gPSBsaXN0LmFkZFxuXHRcdFx0cHJvbWlzZVsgdHVwbGVbMV0gXSA9IGxpc3QuYWRkO1xuXG5cdFx0XHQvLyBIYW5kbGUgc3RhdGVcblx0XHRcdGlmICggc3RhdGVTdHJpbmcgKSB7XG5cdFx0XHRcdGxpc3QuYWRkKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdC8vIHN0YXRlID0gWyByZXNvbHZlZCB8IHJlamVjdGVkIF1cblx0XHRcdFx0XHRzdGF0ZSA9IHN0YXRlU3RyaW5nO1xuXG5cdFx0XHRcdC8vIFsgcmVqZWN0X2xpc3QgfCByZXNvbHZlX2xpc3QgXS5kaXNhYmxlOyBwcm9ncmVzc19saXN0LmxvY2tcblx0XHRcdFx0fSwgdHVwbGVzWyBpIF4gMSBdWyAyIF0uZGlzYWJsZSwgdHVwbGVzWyAyIF1bIDIgXS5sb2NrICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGRlZmVycmVkWyByZXNvbHZlIHwgcmVqZWN0IHwgbm90aWZ5IF1cblx0XHRcdGRlZmVycmVkWyB0dXBsZVswXSBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGRlZmVycmVkWyB0dXBsZVswXSArIFwiV2l0aFwiIF0oIHRoaXMgPT09IGRlZmVycmVkID8gcHJvbWlzZSA6IHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH07XG5cdFx0XHRkZWZlcnJlZFsgdHVwbGVbMF0gKyBcIldpdGhcIiBdID0gbGlzdC5maXJlV2l0aDtcblx0XHR9KTtcblxuXHRcdC8vIE1ha2UgdGhlIGRlZmVycmVkIGEgcHJvbWlzZVxuXHRcdHByb21pc2UucHJvbWlzZSggZGVmZXJyZWQgKTtcblxuXHRcdC8vIENhbGwgZ2l2ZW4gZnVuYyBpZiBhbnlcblx0XHRpZiAoIGZ1bmMgKSB7XG5cdFx0XHRmdW5jLmNhbGwoIGRlZmVycmVkLCBkZWZlcnJlZCApO1xuXHRcdH1cblxuXHRcdC8vIEFsbCBkb25lIVxuXHRcdHJldHVybiBkZWZlcnJlZDtcblx0fSxcblxuXHQvLyBEZWZlcnJlZCBoZWxwZXJcblx0d2hlbjogZnVuY3Rpb24oIHN1Ym9yZGluYXRlIC8qICwgLi4uLCBzdWJvcmRpbmF0ZU4gKi8gKSB7XG5cdFx0dmFyIGkgPSAwLFxuXHRcdFx0cmVzb2x2ZVZhbHVlcyA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApLFxuXHRcdFx0bGVuZ3RoID0gcmVzb2x2ZVZhbHVlcy5sZW5ndGgsXG5cblx0XHRcdC8vIHRoZSBjb3VudCBvZiB1bmNvbXBsZXRlZCBzdWJvcmRpbmF0ZXNcblx0XHRcdHJlbWFpbmluZyA9IGxlbmd0aCAhPT0gMSB8fCAoIHN1Ym9yZGluYXRlICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCBzdWJvcmRpbmF0ZS5wcm9taXNlICkgKSA/IGxlbmd0aCA6IDAsXG5cblx0XHRcdC8vIHRoZSBtYXN0ZXIgRGVmZXJyZWQuIElmIHJlc29sdmVWYWx1ZXMgY29uc2lzdCBvZiBvbmx5IGEgc2luZ2xlIERlZmVycmVkLCBqdXN0IHVzZSB0aGF0LlxuXHRcdFx0ZGVmZXJyZWQgPSByZW1haW5pbmcgPT09IDEgPyBzdWJvcmRpbmF0ZSA6IGpRdWVyeS5EZWZlcnJlZCgpLFxuXG5cdFx0XHQvLyBVcGRhdGUgZnVuY3Rpb24gZm9yIGJvdGggcmVzb2x2ZSBhbmQgcHJvZ3Jlc3MgdmFsdWVzXG5cdFx0XHR1cGRhdGVGdW5jID0gZnVuY3Rpb24oIGksIGNvbnRleHRzLCB2YWx1ZXMgKSB7XG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0Y29udGV4dHNbIGkgXSA9IHRoaXM7XG5cdFx0XHRcdFx0dmFsdWVzWyBpIF0gPSBhcmd1bWVudHMubGVuZ3RoID4gMSA/IHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApIDogdmFsdWU7XG5cdFx0XHRcdFx0aWYgKCB2YWx1ZXMgPT09IHByb2dyZXNzVmFsdWVzICkge1xuXHRcdFx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggY29udGV4dHMsIHZhbHVlcyApO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoICEoIC0tcmVtYWluaW5nICkgKSB7XG5cdFx0XHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggY29udGV4dHMsIHZhbHVlcyApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdH0sXG5cblx0XHRcdHByb2dyZXNzVmFsdWVzLCBwcm9ncmVzc0NvbnRleHRzLCByZXNvbHZlQ29udGV4dHM7XG5cblx0XHQvLyBhZGQgbGlzdGVuZXJzIHRvIERlZmVycmVkIHN1Ym9yZGluYXRlczsgdHJlYXQgb3RoZXJzIGFzIHJlc29sdmVkXG5cdFx0aWYgKCBsZW5ndGggPiAxICkge1xuXHRcdFx0cHJvZ3Jlc3NWYWx1ZXMgPSBuZXcgQXJyYXkoIGxlbmd0aCApO1xuXHRcdFx0cHJvZ3Jlc3NDb250ZXh0cyA9IG5ldyBBcnJheSggbGVuZ3RoICk7XG5cdFx0XHRyZXNvbHZlQ29udGV4dHMgPSBuZXcgQXJyYXkoIGxlbmd0aCApO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdGlmICggcmVzb2x2ZVZhbHVlc1sgaSBdICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCByZXNvbHZlVmFsdWVzWyBpIF0ucHJvbWlzZSApICkge1xuXHRcdFx0XHRcdHJlc29sdmVWYWx1ZXNbIGkgXS5wcm9taXNlKClcblx0XHRcdFx0XHRcdC5kb25lKCB1cGRhdGVGdW5jKCBpLCByZXNvbHZlQ29udGV4dHMsIHJlc29sdmVWYWx1ZXMgKSApXG5cdFx0XHRcdFx0XHQuZmFpbCggZGVmZXJyZWQucmVqZWN0IClcblx0XHRcdFx0XHRcdC5wcm9ncmVzcyggdXBkYXRlRnVuYyggaSwgcHJvZ3Jlc3NDb250ZXh0cywgcHJvZ3Jlc3NWYWx1ZXMgKSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC0tcmVtYWluaW5nO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gaWYgd2UncmUgbm90IHdhaXRpbmcgb24gYW55dGhpbmcsIHJlc29sdmUgdGhlIG1hc3RlclxuXHRcdGlmICggIXJlbWFpbmluZyApIHtcblx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCByZXNvbHZlQ29udGV4dHMsIHJlc29sdmVWYWx1ZXMgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGVmZXJyZWQucHJvbWlzZSgpO1xuXHR9XG59KTtcblxuXG4vLyBUaGUgZGVmZXJyZWQgdXNlZCBvbiBET00gcmVhZHlcbnZhciByZWFkeUxpc3Q7XG5cbmpRdWVyeS5mbi5yZWFkeSA9IGZ1bmN0aW9uKCBmbiApIHtcblx0Ly8gQWRkIHRoZSBjYWxsYmFja1xuXHRqUXVlcnkucmVhZHkucHJvbWlzZSgpLmRvbmUoIGZuICk7XG5cblx0cmV0dXJuIHRoaXM7XG59O1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0Ly8gSXMgdGhlIERPTSByZWFkeSB0byBiZSB1c2VkPyBTZXQgdG8gdHJ1ZSBvbmNlIGl0IG9jY3Vycy5cblx0aXNSZWFkeTogZmFsc2UsXG5cblx0Ly8gQSBjb3VudGVyIHRvIHRyYWNrIGhvdyBtYW55IGl0ZW1zIHRvIHdhaXQgZm9yIGJlZm9yZVxuXHQvLyB0aGUgcmVhZHkgZXZlbnQgZmlyZXMuIFNlZSAjNjc4MVxuXHRyZWFkeVdhaXQ6IDEsXG5cblx0Ly8gSG9sZCAob3IgcmVsZWFzZSkgdGhlIHJlYWR5IGV2ZW50XG5cdGhvbGRSZWFkeTogZnVuY3Rpb24oIGhvbGQgKSB7XG5cdFx0aWYgKCBob2xkICkge1xuXHRcdFx0alF1ZXJ5LnJlYWR5V2FpdCsrO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRqUXVlcnkucmVhZHkoIHRydWUgKTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gSGFuZGxlIHdoZW4gdGhlIERPTSBpcyByZWFkeVxuXHRyZWFkeTogZnVuY3Rpb24oIHdhaXQgKSB7XG5cblx0XHQvLyBBYm9ydCBpZiB0aGVyZSBhcmUgcGVuZGluZyBob2xkcyBvciB3ZSdyZSBhbHJlYWR5IHJlYWR5XG5cdFx0aWYgKCB3YWl0ID09PSB0cnVlID8gLS1qUXVlcnkucmVhZHlXYWl0IDogalF1ZXJ5LmlzUmVhZHkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gUmVtZW1iZXIgdGhhdCB0aGUgRE9NIGlzIHJlYWR5XG5cdFx0alF1ZXJ5LmlzUmVhZHkgPSB0cnVlO1xuXG5cdFx0Ly8gSWYgYSBub3JtYWwgRE9NIFJlYWR5IGV2ZW50IGZpcmVkLCBkZWNyZW1lbnQsIGFuZCB3YWl0IGlmIG5lZWQgYmVcblx0XHRpZiAoIHdhaXQgIT09IHRydWUgJiYgLS1qUXVlcnkucmVhZHlXYWl0ID4gMCApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBJZiB0aGVyZSBhcmUgZnVuY3Rpb25zIGJvdW5kLCB0byBleGVjdXRlXG5cdFx0cmVhZHlMaXN0LnJlc29sdmVXaXRoKCBkb2N1bWVudCwgWyBqUXVlcnkgXSApO1xuXG5cdFx0Ly8gVHJpZ2dlciBhbnkgYm91bmQgcmVhZHkgZXZlbnRzXG5cdFx0aWYgKCBqUXVlcnkuZm4udHJpZ2dlckhhbmRsZXIgKSB7XG5cdFx0XHRqUXVlcnkoIGRvY3VtZW50ICkudHJpZ2dlckhhbmRsZXIoIFwicmVhZHlcIiApO1xuXHRcdFx0alF1ZXJ5KCBkb2N1bWVudCApLm9mZiggXCJyZWFkeVwiICk7XG5cdFx0fVxuXHR9XG59KTtcblxuLyoqXG4gKiBUaGUgcmVhZHkgZXZlbnQgaGFuZGxlciBhbmQgc2VsZiBjbGVhbnVwIG1ldGhvZFxuICovXG5mdW5jdGlvbiBjb21wbGV0ZWQoKSB7XG5cdGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoIFwiRE9NQ29udGVudExvYWRlZFwiLCBjb21wbGV0ZWQsIGZhbHNlICk7XG5cdHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCBcImxvYWRcIiwgY29tcGxldGVkLCBmYWxzZSApO1xuXHRqUXVlcnkucmVhZHkoKTtcbn1cblxualF1ZXJ5LnJlYWR5LnByb21pc2UgPSBmdW5jdGlvbiggb2JqICkge1xuXHRpZiAoICFyZWFkeUxpc3QgKSB7XG5cblx0XHRyZWFkeUxpc3QgPSBqUXVlcnkuRGVmZXJyZWQoKTtcblxuXHRcdC8vIENhdGNoIGNhc2VzIHdoZXJlICQoZG9jdW1lbnQpLnJlYWR5KCkgaXMgY2FsbGVkIGFmdGVyIHRoZSBicm93c2VyIGV2ZW50IGhhcyBhbHJlYWR5IG9jY3VycmVkLlxuXHRcdC8vIHdlIG9uY2UgdHJpZWQgdG8gdXNlIHJlYWR5U3RhdGUgXCJpbnRlcmFjdGl2ZVwiIGhlcmUsIGJ1dCBpdCBjYXVzZWQgaXNzdWVzIGxpa2UgdGhlIG9uZVxuXHRcdC8vIGRpc2NvdmVyZWQgYnkgQ2hyaXNTIGhlcmU6IGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEyMjgyI2NvbW1lbnQ6MTVcblx0XHRpZiAoIGRvY3VtZW50LnJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIiApIHtcblx0XHRcdC8vIEhhbmRsZSBpdCBhc3luY2hyb25vdXNseSB0byBhbGxvdyBzY3JpcHRzIHRoZSBvcHBvcnR1bml0eSB0byBkZWxheSByZWFkeVxuXHRcdFx0c2V0VGltZW91dCggalF1ZXJ5LnJlYWR5ICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBVc2UgdGhlIGhhbmR5IGV2ZW50IGNhbGxiYWNrXG5cdFx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCBcIkRPTUNvbnRlbnRMb2FkZWRcIiwgY29tcGxldGVkLCBmYWxzZSApO1xuXG5cdFx0XHQvLyBBIGZhbGxiYWNrIHRvIHdpbmRvdy5vbmxvYWQsIHRoYXQgd2lsbCBhbHdheXMgd29ya1xuXHRcdFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIFwibG9hZFwiLCBjb21wbGV0ZWQsIGZhbHNlICk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiByZWFkeUxpc3QucHJvbWlzZSggb2JqICk7XG59O1xuXG4vLyBLaWNrIG9mZiB0aGUgRE9NIHJlYWR5IGNoZWNrIGV2ZW4gaWYgdGhlIHVzZXIgZG9lcyBub3RcbmpRdWVyeS5yZWFkeS5wcm9taXNlKCk7XG5cblxuXG5cbi8vIE11bHRpZnVuY3Rpb25hbCBtZXRob2QgdG8gZ2V0IGFuZCBzZXQgdmFsdWVzIG9mIGEgY29sbGVjdGlvblxuLy8gVGhlIHZhbHVlL3MgY2FuIG9wdGlvbmFsbHkgYmUgZXhlY3V0ZWQgaWYgaXQncyBhIGZ1bmN0aW9uXG52YXIgYWNjZXNzID0galF1ZXJ5LmFjY2VzcyA9IGZ1bmN0aW9uKCBlbGVtcywgZm4sIGtleSwgdmFsdWUsIGNoYWluYWJsZSwgZW1wdHlHZXQsIHJhdyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IGVsZW1zLmxlbmd0aCxcblx0XHRidWxrID0ga2V5ID09IG51bGw7XG5cblx0Ly8gU2V0cyBtYW55IHZhbHVlc1xuXHRpZiAoIGpRdWVyeS50eXBlKCBrZXkgKSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRjaGFpbmFibGUgPSB0cnVlO1xuXHRcdGZvciAoIGkgaW4ga2V5ICkge1xuXHRcdFx0alF1ZXJ5LmFjY2VzcyggZWxlbXMsIGZuLCBpLCBrZXlbaV0sIHRydWUsIGVtcHR5R2V0LCByYXcgKTtcblx0XHR9XG5cblx0Ly8gU2V0cyBvbmUgdmFsdWVcblx0fSBlbHNlIGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRjaGFpbmFibGUgPSB0cnVlO1xuXG5cdFx0aWYgKCAhalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyYXcgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGlmICggYnVsayApIHtcblx0XHRcdC8vIEJ1bGsgb3BlcmF0aW9ucyBydW4gYWdhaW5zdCB0aGUgZW50aXJlIHNldFxuXHRcdFx0aWYgKCByYXcgKSB7XG5cdFx0XHRcdGZuLmNhbGwoIGVsZW1zLCB2YWx1ZSApO1xuXHRcdFx0XHRmbiA9IG51bGw7XG5cblx0XHRcdC8vIC4uLmV4Y2VwdCB3aGVuIGV4ZWN1dGluZyBmdW5jdGlvbiB2YWx1ZXNcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGJ1bGsgPSBmbjtcblx0XHRcdFx0Zm4gPSBmdW5jdGlvbiggZWxlbSwga2V5LCB2YWx1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gYnVsay5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdmFsdWUgKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIGZuICkge1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdGZuKCBlbGVtc1tpXSwga2V5LCByYXcgPyB2YWx1ZSA6IHZhbHVlLmNhbGwoIGVsZW1zW2ldLCBpLCBmbiggZWxlbXNbaV0sIGtleSApICkgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gY2hhaW5hYmxlID9cblx0XHRlbGVtcyA6XG5cblx0XHQvLyBHZXRzXG5cdFx0YnVsayA/XG5cdFx0XHRmbi5jYWxsKCBlbGVtcyApIDpcblx0XHRcdGxlbiA/IGZuKCBlbGVtc1swXSwga2V5ICkgOiBlbXB0eUdldDtcbn07XG5cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgYW4gb2JqZWN0IGNhbiBoYXZlIGRhdGFcbiAqL1xualF1ZXJ5LmFjY2VwdERhdGEgPSBmdW5jdGlvbiggb3duZXIgKSB7XG5cdC8vIEFjY2VwdHMgb25seTpcblx0Ly8gIC0gTm9kZVxuXHQvLyAgICAtIE5vZGUuRUxFTUVOVF9OT0RFXG5cdC8vICAgIC0gTm9kZS5ET0NVTUVOVF9OT0RFXG5cdC8vICAtIE9iamVjdFxuXHQvLyAgICAtIEFueVxuXHQvKiBqc2hpbnQgLVcwMTggKi9cblx0cmV0dXJuIG93bmVyLm5vZGVUeXBlID09PSAxIHx8IG93bmVyLm5vZGVUeXBlID09PSA5IHx8ICEoICtvd25lci5ub2RlVHlwZSApO1xufTtcblxuXG5mdW5jdGlvbiBEYXRhKCkge1xuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDwgNCxcblx0Ly8gT2xkIFdlYktpdCBkb2VzIG5vdCBoYXZlIE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucy9mcmVlemUgbWV0aG9kLFxuXHQvLyByZXR1cm4gbmV3IGVtcHR5IG9iamVjdCBpbnN0ZWFkIHdpdGggbm8gW1tzZXRdXSBhY2Nlc3NvclxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoIHRoaXMuY2FjaGUgPSB7fSwgMCwge1xuXHRcdGdldDogZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4ge307XG5cdFx0fVxuXHR9KTtcblxuXHR0aGlzLmV4cGFuZG8gPSBqUXVlcnkuZXhwYW5kbyArIE1hdGgucmFuZG9tKCk7XG59XG5cbkRhdGEudWlkID0gMTtcbkRhdGEuYWNjZXB0cyA9IGpRdWVyeS5hY2NlcHREYXRhO1xuXG5EYXRhLnByb3RvdHlwZSA9IHtcblx0a2V5OiBmdW5jdGlvbiggb3duZXIgKSB7XG5cdFx0Ly8gV2UgY2FuIGFjY2VwdCBkYXRhIGZvciBub24tZWxlbWVudCBub2RlcyBpbiBtb2Rlcm4gYnJvd3NlcnMsXG5cdFx0Ly8gYnV0IHdlIHNob3VsZCBub3QsIHNlZSAjODMzNS5cblx0XHQvLyBBbHdheXMgcmV0dXJuIHRoZSBrZXkgZm9yIGEgZnJvemVuIG9iamVjdC5cblx0XHRpZiAoICFEYXRhLmFjY2VwdHMoIG93bmVyICkgKSB7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHR2YXIgZGVzY3JpcHRvciA9IHt9LFxuXHRcdFx0Ly8gQ2hlY2sgaWYgdGhlIG93bmVyIG9iamVjdCBhbHJlYWR5IGhhcyBhIGNhY2hlIGtleVxuXHRcdFx0dW5sb2NrID0gb3duZXJbIHRoaXMuZXhwYW5kbyBdO1xuXG5cdFx0Ly8gSWYgbm90LCBjcmVhdGUgb25lXG5cdFx0aWYgKCAhdW5sb2NrICkge1xuXHRcdFx0dW5sb2NrID0gRGF0YS51aWQrKztcblxuXHRcdFx0Ly8gU2VjdXJlIGl0IGluIGEgbm9uLWVudW1lcmFibGUsIG5vbi13cml0YWJsZSBwcm9wZXJ0eVxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0ZGVzY3JpcHRvclsgdGhpcy5leHBhbmRvIF0gPSB7IHZhbHVlOiB1bmxvY2sgfTtcblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIG93bmVyLCBkZXNjcmlwdG9yICk7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPCA0XG5cdFx0XHQvLyBGYWxsYmFjayB0byBhIGxlc3Mgc2VjdXJlIGRlZmluaXRpb25cblx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0XHRkZXNjcmlwdG9yWyB0aGlzLmV4cGFuZG8gXSA9IHVubG9jaztcblx0XHRcdFx0alF1ZXJ5LmV4dGVuZCggb3duZXIsIGRlc2NyaXB0b3IgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBFbnN1cmUgdGhlIGNhY2hlIG9iamVjdFxuXHRcdGlmICggIXRoaXMuY2FjaGVbIHVubG9jayBdICkge1xuXHRcdFx0dGhpcy5jYWNoZVsgdW5sb2NrIF0gPSB7fTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdW5sb2NrO1xuXHR9LFxuXHRzZXQ6IGZ1bmN0aW9uKCBvd25lciwgZGF0YSwgdmFsdWUgKSB7XG5cdFx0dmFyIHByb3AsXG5cdFx0XHQvLyBUaGVyZSBtYXkgYmUgYW4gdW5sb2NrIGFzc2lnbmVkIHRvIHRoaXMgbm9kZSxcblx0XHRcdC8vIGlmIHRoZXJlIGlzIG5vIGVudHJ5IGZvciB0aGlzIFwib3duZXJcIiwgY3JlYXRlIG9uZSBpbmxpbmVcblx0XHRcdC8vIGFuZCBzZXQgdGhlIHVubG9jayBhcyB0aG91Z2ggYW4gb3duZXIgZW50cnkgaGFkIGFsd2F5cyBleGlzdGVkXG5cdFx0XHR1bmxvY2sgPSB0aGlzLmtleSggb3duZXIgKSxcblx0XHRcdGNhY2hlID0gdGhpcy5jYWNoZVsgdW5sb2NrIF07XG5cblx0XHQvLyBIYW5kbGU6IFsgb3duZXIsIGtleSwgdmFsdWUgXSBhcmdzXG5cdFx0aWYgKCB0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGNhY2hlWyBkYXRhIF0gPSB2YWx1ZTtcblxuXHRcdC8vIEhhbmRsZTogWyBvd25lciwgeyBwcm9wZXJ0aWVzIH0gXSBhcmdzXG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEZyZXNoIGFzc2lnbm1lbnRzIGJ5IG9iamVjdCBhcmUgc2hhbGxvdyBjb3BpZWRcblx0XHRcdGlmICggalF1ZXJ5LmlzRW1wdHlPYmplY3QoIGNhY2hlICkgKSB7XG5cdFx0XHRcdGpRdWVyeS5leHRlbmQoIHRoaXMuY2FjaGVbIHVubG9jayBdLCBkYXRhICk7XG5cdFx0XHQvLyBPdGhlcndpc2UsIGNvcHkgdGhlIHByb3BlcnRpZXMgb25lLWJ5LW9uZSB0byB0aGUgY2FjaGUgb2JqZWN0XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmb3IgKCBwcm9wIGluIGRhdGEgKSB7XG5cdFx0XHRcdFx0Y2FjaGVbIHByb3AgXSA9IGRhdGFbIHByb3AgXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gY2FjaGU7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24oIG93bmVyLCBrZXkgKSB7XG5cdFx0Ly8gRWl0aGVyIGEgdmFsaWQgY2FjaGUgaXMgZm91bmQsIG9yIHdpbGwgYmUgY3JlYXRlZC5cblx0XHQvLyBOZXcgY2FjaGVzIHdpbGwgYmUgY3JlYXRlZCBhbmQgdGhlIHVubG9jayByZXR1cm5lZCxcblx0XHQvLyBhbGxvd2luZyBkaXJlY3QgYWNjZXNzIHRvIHRoZSBuZXdseSBjcmVhdGVkXG5cdFx0Ly8gZW1wdHkgZGF0YSBvYmplY3QuIEEgdmFsaWQgb3duZXIgb2JqZWN0IG11c3QgYmUgcHJvdmlkZWQuXG5cdFx0dmFyIGNhY2hlID0gdGhpcy5jYWNoZVsgdGhpcy5rZXkoIG93bmVyICkgXTtcblxuXHRcdHJldHVybiBrZXkgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRjYWNoZSA6IGNhY2hlWyBrZXkgXTtcblx0fSxcblx0YWNjZXNzOiBmdW5jdGlvbiggb3duZXIsIGtleSwgdmFsdWUgKSB7XG5cdFx0dmFyIHN0b3JlZDtcblx0XHQvLyBJbiBjYXNlcyB3aGVyZSBlaXRoZXI6XG5cdFx0Ly9cblx0XHQvLyAgIDEuIE5vIGtleSB3YXMgc3BlY2lmaWVkXG5cdFx0Ly8gICAyLiBBIHN0cmluZyBrZXkgd2FzIHNwZWNpZmllZCwgYnV0IG5vIHZhbHVlIHByb3ZpZGVkXG5cdFx0Ly9cblx0XHQvLyBUYWtlIHRoZSBcInJlYWRcIiBwYXRoIGFuZCBhbGxvdyB0aGUgZ2V0IG1ldGhvZCB0byBkZXRlcm1pbmVcblx0XHQvLyB3aGljaCB2YWx1ZSB0byByZXR1cm4sIHJlc3BlY3RpdmVseSBlaXRoZXI6XG5cdFx0Ly9cblx0XHQvLyAgIDEuIFRoZSBlbnRpcmUgY2FjaGUgb2JqZWN0XG5cdFx0Ly8gICAyLiBUaGUgZGF0YSBzdG9yZWQgYXQgdGhlIGtleVxuXHRcdC8vXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCB8fFxuXHRcdFx0XHQoKGtleSAmJiB0eXBlb2Yga2V5ID09PSBcInN0cmluZ1wiKSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkKSApIHtcblxuXHRcdFx0c3RvcmVkID0gdGhpcy5nZXQoIG93bmVyLCBrZXkgKTtcblxuXHRcdFx0cmV0dXJuIHN0b3JlZCAhPT0gdW5kZWZpbmVkID9cblx0XHRcdFx0c3RvcmVkIDogdGhpcy5nZXQoIG93bmVyLCBqUXVlcnkuY2FtZWxDYXNlKGtleSkgKTtcblx0XHR9XG5cblx0XHQvLyBbKl1XaGVuIHRoZSBrZXkgaXMgbm90IGEgc3RyaW5nLCBvciBib3RoIGEga2V5IGFuZCB2YWx1ZVxuXHRcdC8vIGFyZSBzcGVjaWZpZWQsIHNldCBvciBleHRlbmQgKGV4aXN0aW5nIG9iamVjdHMpIHdpdGggZWl0aGVyOlxuXHRcdC8vXG5cdFx0Ly8gICAxLiBBbiBvYmplY3Qgb2YgcHJvcGVydGllc1xuXHRcdC8vICAgMi4gQSBrZXkgYW5kIHZhbHVlXG5cdFx0Ly9cblx0XHR0aGlzLnNldCggb3duZXIsIGtleSwgdmFsdWUgKTtcblxuXHRcdC8vIFNpbmNlIHRoZSBcInNldFwiIHBhdGggY2FuIGhhdmUgdHdvIHBvc3NpYmxlIGVudHJ5IHBvaW50c1xuXHRcdC8vIHJldHVybiB0aGUgZXhwZWN0ZWQgZGF0YSBiYXNlZCBvbiB3aGljaCBwYXRoIHdhcyB0YWtlblsqXVxuXHRcdHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkID8gdmFsdWUgOiBrZXk7XG5cdH0sXG5cdHJlbW92ZTogZnVuY3Rpb24oIG93bmVyLCBrZXkgKSB7XG5cdFx0dmFyIGksIG5hbWUsIGNhbWVsLFxuXHRcdFx0dW5sb2NrID0gdGhpcy5rZXkoIG93bmVyICksXG5cdFx0XHRjYWNoZSA9IHRoaXMuY2FjaGVbIHVubG9jayBdO1xuXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHRoaXMuY2FjaGVbIHVubG9jayBdID0ge307XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gU3VwcG9ydCBhcnJheSBvciBzcGFjZSBzZXBhcmF0ZWQgc3RyaW5nIG9mIGtleXNcblx0XHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIGtleSApICkge1xuXHRcdFx0XHQvLyBJZiBcIm5hbWVcIiBpcyBhbiBhcnJheSBvZiBrZXlzLi4uXG5cdFx0XHRcdC8vIFdoZW4gZGF0YSBpcyBpbml0aWFsbHkgY3JlYXRlZCwgdmlhIChcImtleVwiLCBcInZhbFwiKSBzaWduYXR1cmUsXG5cdFx0XHRcdC8vIGtleXMgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gY2FtZWxDYXNlLlxuXHRcdFx0XHQvLyBTaW5jZSB0aGVyZSBpcyBubyB3YXkgdG8gdGVsbCBfaG93XyBhIGtleSB3YXMgYWRkZWQsIHJlbW92ZVxuXHRcdFx0XHQvLyBib3RoIHBsYWluIGtleSBhbmQgY2FtZWxDYXNlIGtleS4gIzEyNzg2XG5cdFx0XHRcdC8vIFRoaXMgd2lsbCBvbmx5IHBlbmFsaXplIHRoZSBhcnJheSBhcmd1bWVudCBwYXRoLlxuXHRcdFx0XHRuYW1lID0ga2V5LmNvbmNhdCgga2V5Lm1hcCggalF1ZXJ5LmNhbWVsQ2FzZSApICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjYW1lbCA9IGpRdWVyeS5jYW1lbENhc2UoIGtleSApO1xuXHRcdFx0XHQvLyBUcnkgdGhlIHN0cmluZyBhcyBhIGtleSBiZWZvcmUgYW55IG1hbmlwdWxhdGlvblxuXHRcdFx0XHRpZiAoIGtleSBpbiBjYWNoZSApIHtcblx0XHRcdFx0XHRuYW1lID0gWyBrZXksIGNhbWVsIF07XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gSWYgYSBrZXkgd2l0aCB0aGUgc3BhY2VzIGV4aXN0cywgdXNlIGl0LlxuXHRcdFx0XHRcdC8vIE90aGVyd2lzZSwgY3JlYXRlIGFuIGFycmF5IGJ5IG1hdGNoaW5nIG5vbi13aGl0ZXNwYWNlXG5cdFx0XHRcdFx0bmFtZSA9IGNhbWVsO1xuXHRcdFx0XHRcdG5hbWUgPSBuYW1lIGluIGNhY2hlID9cblx0XHRcdFx0XHRcdFsgbmFtZSBdIDogKCBuYW1lLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGkgPSBuYW1lLmxlbmd0aDtcblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRkZWxldGUgY2FjaGVbIG5hbWVbIGkgXSBdO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblx0aGFzRGF0YTogZnVuY3Rpb24oIG93bmVyICkge1xuXHRcdHJldHVybiAhalF1ZXJ5LmlzRW1wdHlPYmplY3QoXG5cdFx0XHR0aGlzLmNhY2hlWyBvd25lclsgdGhpcy5leHBhbmRvIF0gXSB8fCB7fVxuXHRcdCk7XG5cdH0sXG5cdGRpc2NhcmQ6IGZ1bmN0aW9uKCBvd25lciApIHtcblx0XHRpZiAoIG93bmVyWyB0aGlzLmV4cGFuZG8gXSApIHtcblx0XHRcdGRlbGV0ZSB0aGlzLmNhY2hlWyBvd25lclsgdGhpcy5leHBhbmRvIF0gXTtcblx0XHR9XG5cdH1cbn07XG52YXIgZGF0YV9wcml2ID0gbmV3IERhdGEoKTtcblxudmFyIGRhdGFfdXNlciA9IG5ldyBEYXRhKCk7XG5cblxuXG4vKlxuXHRJbXBsZW1lbnRhdGlvbiBTdW1tYXJ5XG5cblx0MS4gRW5mb3JjZSBBUEkgc3VyZmFjZSBhbmQgc2VtYW50aWMgY29tcGF0aWJpbGl0eSB3aXRoIDEuOS54IGJyYW5jaFxuXHQyLiBJbXByb3ZlIHRoZSBtb2R1bGUncyBtYWludGFpbmFiaWxpdHkgYnkgcmVkdWNpbmcgdGhlIHN0b3JhZ2Vcblx0XHRwYXRocyB0byBhIHNpbmdsZSBtZWNoYW5pc20uXG5cdDMuIFVzZSB0aGUgc2FtZSBzaW5nbGUgbWVjaGFuaXNtIHRvIHN1cHBvcnQgXCJwcml2YXRlXCIgYW5kIFwidXNlclwiIGRhdGEuXG5cdDQuIF9OZXZlcl8gZXhwb3NlIFwicHJpdmF0ZVwiIGRhdGEgdG8gdXNlciBjb2RlIChUT0RPOiBEcm9wIF9kYXRhLCBfcmVtb3ZlRGF0YSlcblx0NS4gQXZvaWQgZXhwb3NpbmcgaW1wbGVtZW50YXRpb24gZGV0YWlscyBvbiB1c2VyIG9iamVjdHMgKGVnLiBleHBhbmRvIHByb3BlcnRpZXMpXG5cdDYuIFByb3ZpZGUgYSBjbGVhciBwYXRoIGZvciBpbXBsZW1lbnRhdGlvbiB1cGdyYWRlIHRvIFdlYWtNYXAgaW4gMjAxNFxuKi9cbnZhciByYnJhY2UgPSAvXig/Olxce1tcXHdcXFddKlxcfXxcXFtbXFx3XFxXXSpcXF0pJC8sXG5cdHJtdWx0aURhc2ggPSAvKFtBLVpdKS9nO1xuXG5mdW5jdGlvbiBkYXRhQXR0ciggZWxlbSwga2V5LCBkYXRhICkge1xuXHR2YXIgbmFtZTtcblxuXHQvLyBJZiBub3RoaW5nIHdhcyBmb3VuZCBpbnRlcm5hbGx5LCB0cnkgdG8gZmV0Y2ggYW55XG5cdC8vIGRhdGEgZnJvbSB0aGUgSFRNTDUgZGF0YS0qIGF0dHJpYnV0ZVxuXHRpZiAoIGRhdGEgPT09IHVuZGVmaW5lZCAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdG5hbWUgPSBcImRhdGEtXCIgKyBrZXkucmVwbGFjZSggcm11bHRpRGFzaCwgXCItJDFcIiApLnRvTG93ZXJDYXNlKCk7XG5cdFx0ZGF0YSA9IGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lICk7XG5cblx0XHRpZiAoIHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0ZGF0YSA9IGRhdGEgPT09IFwidHJ1ZVwiID8gdHJ1ZSA6XG5cdFx0XHRcdFx0ZGF0YSA9PT0gXCJmYWxzZVwiID8gZmFsc2UgOlxuXHRcdFx0XHRcdGRhdGEgPT09IFwibnVsbFwiID8gbnVsbCA6XG5cdFx0XHRcdFx0Ly8gT25seSBjb252ZXJ0IHRvIGEgbnVtYmVyIGlmIGl0IGRvZXNuJ3QgY2hhbmdlIHRoZSBzdHJpbmdcblx0XHRcdFx0XHQrZGF0YSArIFwiXCIgPT09IGRhdGEgPyArZGF0YSA6XG5cdFx0XHRcdFx0cmJyYWNlLnRlc3QoIGRhdGEgKSA/IGpRdWVyeS5wYXJzZUpTT04oIGRhdGEgKSA6XG5cdFx0XHRcdFx0ZGF0YTtcblx0XHRcdH0gY2F0Y2goIGUgKSB7fVxuXG5cdFx0XHQvLyBNYWtlIHN1cmUgd2Ugc2V0IHRoZSBkYXRhIHNvIGl0IGlzbid0IGNoYW5nZWQgbGF0ZXJcblx0XHRcdGRhdGFfdXNlci5zZXQoIGVsZW0sIGtleSwgZGF0YSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkYXRhID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZGF0YTtcbn1cblxualF1ZXJ5LmV4dGVuZCh7XG5cdGhhc0RhdGE6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBkYXRhX3VzZXIuaGFzRGF0YSggZWxlbSApIHx8IGRhdGFfcHJpdi5oYXNEYXRhKCBlbGVtICk7XG5cdH0sXG5cblx0ZGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGRhdGEgKSB7XG5cdFx0cmV0dXJuIGRhdGFfdXNlci5hY2Nlc3MoIGVsZW0sIG5hbWUsIGRhdGEgKTtcblx0fSxcblxuXHRyZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0XHRkYXRhX3VzZXIucmVtb3ZlKCBlbGVtLCBuYW1lICk7XG5cdH0sXG5cblx0Ly8gVE9ETzogTm93IHRoYXQgYWxsIGNhbGxzIHRvIF9kYXRhIGFuZCBfcmVtb3ZlRGF0YSBoYXZlIGJlZW4gcmVwbGFjZWRcblx0Ly8gd2l0aCBkaXJlY3QgY2FsbHMgdG8gZGF0YV9wcml2IG1ldGhvZHMsIHRoZXNlIGNhbiBiZSBkZXByZWNhdGVkLlxuXHRfZGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGRhdGEgKSB7XG5cdFx0cmV0dXJuIGRhdGFfcHJpdi5hY2Nlc3MoIGVsZW0sIG5hbWUsIGRhdGEgKTtcblx0fSxcblxuXHRfcmVtb3ZlRGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XG5cdFx0ZGF0YV9wcml2LnJlbW92ZSggZWxlbSwgbmFtZSApO1xuXHR9XG59KTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGRhdGE6IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xuXHRcdHZhciBpLCBuYW1lLCBkYXRhLFxuXHRcdFx0ZWxlbSA9IHRoaXNbIDAgXSxcblx0XHRcdGF0dHJzID0gZWxlbSAmJiBlbGVtLmF0dHJpYnV0ZXM7XG5cblx0XHQvLyBHZXRzIGFsbCB2YWx1ZXNcblx0XHRpZiAoIGtleSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0aWYgKCB0aGlzLmxlbmd0aCApIHtcblx0XHRcdFx0ZGF0YSA9IGRhdGFfdXNlci5nZXQoIGVsZW0gKTtcblxuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgIWRhdGFfcHJpdi5nZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIgKSApIHtcblx0XHRcdFx0XHRpID0gYXR0cnMubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRTExK1xuXHRcdFx0XHRcdFx0Ly8gVGhlIGF0dHJzIGVsZW1lbnRzIGNhbiBiZSBudWxsICgjMTQ4OTQpXG5cdFx0XHRcdFx0XHRpZiAoIGF0dHJzWyBpIF0gKSB7XG5cdFx0XHRcdFx0XHRcdG5hbWUgPSBhdHRyc1sgaSBdLm5hbWU7XG5cdFx0XHRcdFx0XHRcdGlmICggbmFtZS5pbmRleE9mKCBcImRhdGEtXCIgKSA9PT0gMCApIHtcblx0XHRcdFx0XHRcdFx0XHRuYW1lID0galF1ZXJ5LmNhbWVsQ2FzZSggbmFtZS5zbGljZSg1KSApO1xuXHRcdFx0XHRcdFx0XHRcdGRhdGFBdHRyKCBlbGVtLCBuYW1lLCBkYXRhWyBuYW1lIF0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRkYXRhX3ByaXYuc2V0KCBlbGVtLCBcImhhc0RhdGFBdHRyc1wiLCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGRhdGE7XG5cdFx0fVxuXG5cdFx0Ly8gU2V0cyBtdWx0aXBsZSB2YWx1ZXNcblx0XHRpZiAoIHR5cGVvZiBrZXkgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkYXRhX3VzZXIuc2V0KCB0aGlzLCBrZXkgKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBkYXRhLFxuXHRcdFx0XHRjYW1lbEtleSA9IGpRdWVyeS5jYW1lbENhc2UoIGtleSApO1xuXG5cdFx0XHQvLyBUaGUgY2FsbGluZyBqUXVlcnkgb2JqZWN0IChlbGVtZW50IG1hdGNoZXMpIGlzIG5vdCBlbXB0eVxuXHRcdFx0Ly8gKGFuZCB0aGVyZWZvcmUgaGFzIGFuIGVsZW1lbnQgYXBwZWFycyBhdCB0aGlzWyAwIF0pIGFuZCB0aGVcblx0XHRcdC8vIGB2YWx1ZWAgcGFyYW1ldGVyIHdhcyBub3QgdW5kZWZpbmVkLiBBbiBlbXB0eSBqUXVlcnkgb2JqZWN0XG5cdFx0XHQvLyB3aWxsIHJlc3VsdCBpbiBgdW5kZWZpbmVkYCBmb3IgZWxlbSA9IHRoaXNbIDAgXSB3aGljaCB3aWxsXG5cdFx0XHQvLyB0aHJvdyBhbiBleGNlcHRpb24gaWYgYW4gYXR0ZW1wdCB0byByZWFkIGEgZGF0YSBjYWNoZSBpcyBtYWRlLlxuXHRcdFx0aWYgKCBlbGVtICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdC8vIEF0dGVtcHQgdG8gZ2V0IGRhdGEgZnJvbSB0aGUgY2FjaGVcblx0XHRcdFx0Ly8gd2l0aCB0aGUga2V5IGFzLWlzXG5cdFx0XHRcdGRhdGEgPSBkYXRhX3VzZXIuZ2V0KCBlbGVtLCBrZXkgKTtcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGRhdGE7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBdHRlbXB0IHRvIGdldCBkYXRhIGZyb20gdGhlIGNhY2hlXG5cdFx0XHRcdC8vIHdpdGggdGhlIGtleSBjYW1lbGl6ZWRcblx0XHRcdFx0ZGF0YSA9IGRhdGFfdXNlci5nZXQoIGVsZW0sIGNhbWVsS2V5ICk7XG5cdFx0XHRcdGlmICggZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQXR0ZW1wdCB0byBcImRpc2NvdmVyXCIgdGhlIGRhdGEgaW5cblx0XHRcdFx0Ly8gSFRNTDUgY3VzdG9tIGRhdGEtKiBhdHRyc1xuXHRcdFx0XHRkYXRhID0gZGF0YUF0dHIoIGVsZW0sIGNhbWVsS2V5LCB1bmRlZmluZWQgKTtcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGRhdGE7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBXZSB0cmllZCByZWFsbHkgaGFyZCwgYnV0IHRoZSBkYXRhIGRvZXNuJ3QgZXhpc3QuXG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2V0IHRoZSBkYXRhLi4uXG5cdFx0XHR0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdC8vIEZpcnN0LCBhdHRlbXB0IHRvIHN0b3JlIGEgY29weSBvciByZWZlcmVuY2Ugb2YgYW55XG5cdFx0XHRcdC8vIGRhdGEgdGhhdCBtaWdodCd2ZSBiZWVuIHN0b3JlIHdpdGggYSBjYW1lbENhc2VkIGtleS5cblx0XHRcdFx0dmFyIGRhdGEgPSBkYXRhX3VzZXIuZ2V0KCB0aGlzLCBjYW1lbEtleSApO1xuXG5cdFx0XHRcdC8vIEZvciBIVE1MNSBkYXRhLSogYXR0cmlidXRlIGludGVyb3AsIHdlIGhhdmUgdG9cblx0XHRcdFx0Ly8gc3RvcmUgcHJvcGVydHkgbmFtZXMgd2l0aCBkYXNoZXMgaW4gYSBjYW1lbENhc2UgZm9ybS5cblx0XHRcdFx0Ly8gVGhpcyBtaWdodCBub3QgYXBwbHkgdG8gYWxsIHByb3BlcnRpZXMuLi4qXG5cdFx0XHRcdGRhdGFfdXNlci5zZXQoIHRoaXMsIGNhbWVsS2V5LCB2YWx1ZSApO1xuXG5cdFx0XHRcdC8vICouLi4gSW4gdGhlIGNhc2Ugb2YgcHJvcGVydGllcyB0aGF0IG1pZ2h0IF9hY3R1YWxseV9cblx0XHRcdFx0Ly8gaGF2ZSBkYXNoZXMsIHdlIG5lZWQgdG8gYWxzbyBzdG9yZSBhIGNvcHkgb2YgdGhhdFxuXHRcdFx0XHQvLyB1bmNoYW5nZWQgcHJvcGVydHkuXG5cdFx0XHRcdGlmICgga2V5LmluZGV4T2YoXCItXCIpICE9PSAtMSAmJiBkYXRhICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0ZGF0YV91c2VyLnNldCggdGhpcywga2V5LCB2YWx1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEsIG51bGwsIHRydWUgKTtcblx0fSxcblxuXHRyZW1vdmVEYXRhOiBmdW5jdGlvbigga2V5ICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRkYXRhX3VzZXIucmVtb3ZlKCB0aGlzLCBrZXkgKTtcblx0XHR9KTtcblx0fVxufSk7XG5cblxualF1ZXJ5LmV4dGVuZCh7XG5cdHF1ZXVlOiBmdW5jdGlvbiggZWxlbSwgdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgcXVldWU7XG5cblx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHR0eXBlID0gKCB0eXBlIHx8IFwiZnhcIiApICsgXCJxdWV1ZVwiO1xuXHRcdFx0cXVldWUgPSBkYXRhX3ByaXYuZ2V0KCBlbGVtLCB0eXBlICk7XG5cblx0XHRcdC8vIFNwZWVkIHVwIGRlcXVldWUgYnkgZ2V0dGluZyBvdXQgcXVpY2tseSBpZiB0aGlzIGlzIGp1c3QgYSBsb29rdXBcblx0XHRcdGlmICggZGF0YSApIHtcblx0XHRcdFx0aWYgKCAhcXVldWUgfHwgalF1ZXJ5LmlzQXJyYXkoIGRhdGEgKSApIHtcblx0XHRcdFx0XHRxdWV1ZSA9IGRhdGFfcHJpdi5hY2Nlc3MoIGVsZW0sIHR5cGUsIGpRdWVyeS5tYWtlQXJyYXkoZGF0YSkgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRxdWV1ZS5wdXNoKCBkYXRhICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBxdWV1ZSB8fCBbXTtcblx0XHR9XG5cdH0sXG5cblx0ZGVxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUgKSB7XG5cdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXG5cdFx0dmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCBlbGVtLCB0eXBlICksXG5cdFx0XHRzdGFydExlbmd0aCA9IHF1ZXVlLmxlbmd0aCxcblx0XHRcdGZuID0gcXVldWUuc2hpZnQoKSxcblx0XHRcdGhvb2tzID0galF1ZXJ5Ll9xdWV1ZUhvb2tzKCBlbGVtLCB0eXBlICksXG5cdFx0XHRuZXh0ID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCBlbGVtLCB0eXBlICk7XG5cdFx0XHR9O1xuXG5cdFx0Ly8gSWYgdGhlIGZ4IHF1ZXVlIGlzIGRlcXVldWVkLCBhbHdheXMgcmVtb3ZlIHRoZSBwcm9ncmVzcyBzZW50aW5lbFxuXHRcdGlmICggZm4gPT09IFwiaW5wcm9ncmVzc1wiICkge1xuXHRcdFx0Zm4gPSBxdWV1ZS5zaGlmdCgpO1xuXHRcdFx0c3RhcnRMZW5ndGgtLTtcblx0XHR9XG5cblx0XHRpZiAoIGZuICkge1xuXG5cdFx0XHQvLyBBZGQgYSBwcm9ncmVzcyBzZW50aW5lbCB0byBwcmV2ZW50IHRoZSBmeCBxdWV1ZSBmcm9tIGJlaW5nXG5cdFx0XHQvLyBhdXRvbWF0aWNhbGx5IGRlcXVldWVkXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwiZnhcIiApIHtcblx0XHRcdFx0cXVldWUudW5zaGlmdCggXCJpbnByb2dyZXNzXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gY2xlYXIgdXAgdGhlIGxhc3QgcXVldWUgc3RvcCBmdW5jdGlvblxuXHRcdFx0ZGVsZXRlIGhvb2tzLnN0b3A7XG5cdFx0XHRmbi5jYWxsKCBlbGVtLCBuZXh0LCBob29rcyApO1xuXHRcdH1cblxuXHRcdGlmICggIXN0YXJ0TGVuZ3RoICYmIGhvb2tzICkge1xuXHRcdFx0aG9va3MuZW1wdHkuZmlyZSgpO1xuXHRcdH1cblx0fSxcblxuXHQvLyBub3QgaW50ZW5kZWQgZm9yIHB1YmxpYyBjb25zdW1wdGlvbiAtIGdlbmVyYXRlcyBhIHF1ZXVlSG9va3Mgb2JqZWN0LCBvciByZXR1cm5zIHRoZSBjdXJyZW50IG9uZVxuXHRfcXVldWVIb29rczogZnVuY3Rpb24oIGVsZW0sIHR5cGUgKSB7XG5cdFx0dmFyIGtleSA9IHR5cGUgKyBcInF1ZXVlSG9va3NcIjtcblx0XHRyZXR1cm4gZGF0YV9wcml2LmdldCggZWxlbSwga2V5ICkgfHwgZGF0YV9wcml2LmFjY2VzcyggZWxlbSwga2V5LCB7XG5cdFx0XHRlbXB0eTogalF1ZXJ5LkNhbGxiYWNrcyhcIm9uY2UgbWVtb3J5XCIpLmFkZChmdW5jdGlvbigpIHtcblx0XHRcdFx0ZGF0YV9wcml2LnJlbW92ZSggZWxlbSwgWyB0eXBlICsgXCJxdWV1ZVwiLCBrZXkgXSApO1xuXHRcdFx0fSlcblx0XHR9KTtcblx0fVxufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRxdWV1ZTogZnVuY3Rpb24oIHR5cGUsIGRhdGEgKSB7XG5cdFx0dmFyIHNldHRlciA9IDI7XG5cblx0XHRpZiAoIHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0ZGF0YSA9IHR5cGU7XG5cdFx0XHR0eXBlID0gXCJmeFwiO1xuXHRcdFx0c2V0dGVyLS07XG5cdFx0fVxuXG5cdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoIDwgc2V0dGVyICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5xdWV1ZSggdGhpc1swXSwgdHlwZSApO1xuXHRcdH1cblxuXHRcdHJldHVybiBkYXRhID09PSB1bmRlZmluZWQgP1xuXHRcdFx0dGhpcyA6XG5cdFx0XHR0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBxdWV1ZSA9IGpRdWVyeS5xdWV1ZSggdGhpcywgdHlwZSwgZGF0YSApO1xuXG5cdFx0XHRcdC8vIGVuc3VyZSBhIGhvb2tzIGZvciB0aGlzIHF1ZXVlXG5cdFx0XHRcdGpRdWVyeS5fcXVldWVIb29rcyggdGhpcywgdHlwZSApO1xuXG5cdFx0XHRcdGlmICggdHlwZSA9PT0gXCJmeFwiICYmIHF1ZXVlWzBdICE9PSBcImlucHJvZ3Jlc3NcIiApIHtcblx0XHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0fSxcblx0ZGVxdWV1ZTogZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0fSk7XG5cdH0sXG5cdGNsZWFyUXVldWU6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdHJldHVybiB0aGlzLnF1ZXVlKCB0eXBlIHx8IFwiZnhcIiwgW10gKTtcblx0fSxcblx0Ly8gR2V0IGEgcHJvbWlzZSByZXNvbHZlZCB3aGVuIHF1ZXVlcyBvZiBhIGNlcnRhaW4gdHlwZVxuXHQvLyBhcmUgZW1wdGllZCAoZnggaXMgdGhlIHR5cGUgYnkgZGVmYXVsdClcblx0cHJvbWlzZTogZnVuY3Rpb24oIHR5cGUsIG9iaiApIHtcblx0XHR2YXIgdG1wLFxuXHRcdFx0Y291bnQgPSAxLFxuXHRcdFx0ZGVmZXIgPSBqUXVlcnkuRGVmZXJyZWQoKSxcblx0XHRcdGVsZW1lbnRzID0gdGhpcyxcblx0XHRcdGkgPSB0aGlzLmxlbmd0aCxcblx0XHRcdHJlc29sdmUgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCAhKCAtLWNvdW50ICkgKSB7XG5cdFx0XHRcdFx0ZGVmZXIucmVzb2x2ZVdpdGgoIGVsZW1lbnRzLCBbIGVsZW1lbnRzIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRvYmogPSB0eXBlO1xuXHRcdFx0dHlwZSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHR0bXAgPSBkYXRhX3ByaXYuZ2V0KCBlbGVtZW50c1sgaSBdLCB0eXBlICsgXCJxdWV1ZUhvb2tzXCIgKTtcblx0XHRcdGlmICggdG1wICYmIHRtcC5lbXB0eSApIHtcblx0XHRcdFx0Y291bnQrKztcblx0XHRcdFx0dG1wLmVtcHR5LmFkZCggcmVzb2x2ZSApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXNvbHZlKCk7XG5cdFx0cmV0dXJuIGRlZmVyLnByb21pc2UoIG9iaiApO1xuXHR9XG59KTtcbnZhciBwbnVtID0gKC9bKy1dPyg/OlxcZCpcXC58KVxcZCsoPzpbZUVdWystXT9cXGQrfCkvKS5zb3VyY2U7XG5cbnZhciBjc3NFeHBhbmQgPSBbIFwiVG9wXCIsIFwiUmlnaHRcIiwgXCJCb3R0b21cIiwgXCJMZWZ0XCIgXTtcblxudmFyIGlzSGlkZGVuID0gZnVuY3Rpb24oIGVsZW0sIGVsICkge1xuXHRcdC8vIGlzSGlkZGVuIG1pZ2h0IGJlIGNhbGxlZCBmcm9tIGpRdWVyeSNmaWx0ZXIgZnVuY3Rpb247XG5cdFx0Ly8gaW4gdGhhdCBjYXNlLCBlbGVtZW50IHdpbGwgYmUgc2Vjb25kIGFyZ3VtZW50XG5cdFx0ZWxlbSA9IGVsIHx8IGVsZW07XG5cdFx0cmV0dXJuIGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICkgPT09IFwibm9uZVwiIHx8ICFqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApO1xuXHR9O1xuXG52YXIgcmNoZWNrYWJsZVR5cGUgPSAoL14oPzpjaGVja2JveHxyYWRpbykkL2kpO1xuXG5cblxuKGZ1bmN0aW9uKCkge1xuXHR2YXIgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksXG5cdFx0ZGl2ID0gZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApLFxuXHRcdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cblx0Ly8gIzExMjE3IC0gV2ViS2l0IGxvc2VzIGNoZWNrIHdoZW4gdGhlIG5hbWUgaXMgYWZ0ZXIgdGhlIGNoZWNrZWQgYXR0cmlidXRlXG5cdC8vIFN1cHBvcnQ6IFdpbmRvd3MgV2ViIEFwcHMgKFdXQSlcblx0Ly8gYG5hbWVgIGFuZCBgdHlwZWAgbmVlZCAuc2V0QXR0cmlidXRlIGZvciBXV0Fcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgXCJyYWRpb1wiICk7XG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJjaGVja2VkXCIsIFwiY2hlY2tlZFwiICk7XG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJuYW1lXCIsIFwidFwiICk7XG5cblx0ZGl2LmFwcGVuZENoaWxkKCBpbnB1dCApO1xuXG5cdC8vIFN1cHBvcnQ6IFNhZmFyaSA1LjEsIGlPUyA1LjEsIEFuZHJvaWQgNC54LCBBbmRyb2lkIDIuM1xuXHQvLyBvbGQgV2ViS2l0IGRvZXNuJ3QgY2xvbmUgY2hlY2tlZCBzdGF0ZSBjb3JyZWN0bHkgaW4gZnJhZ21lbnRzXG5cdHN1cHBvcnQuY2hlY2tDbG9uZSA9IGRpdi5jbG9uZU5vZGUoIHRydWUgKS5jbG9uZU5vZGUoIHRydWUgKS5sYXN0Q2hpbGQuY2hlY2tlZDtcblxuXHQvLyBNYWtlIHN1cmUgdGV4dGFyZWEgKGFuZCBjaGVja2JveCkgZGVmYXVsdFZhbHVlIGlzIHByb3Blcmx5IGNsb25lZFxuXHQvLyBTdXBwb3J0OiBJRTktSUUxMStcblx0ZGl2LmlubmVySFRNTCA9IFwiPHRleHRhcmVhPng8L3RleHRhcmVhPlwiO1xuXHRzdXBwb3J0Lm5vQ2xvbmVDaGVja2VkID0gISFkaXYuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmRlZmF1bHRWYWx1ZTtcbn0pKCk7XG52YXIgc3RydW5kZWZpbmVkID0gdHlwZW9mIHVuZGVmaW5lZDtcblxuXG5cbnN1cHBvcnQuZm9jdXNpbkJ1YmJsZXMgPSBcIm9uZm9jdXNpblwiIGluIHdpbmRvdztcblxuXG52YXJcblx0cmtleUV2ZW50ID0gL15rZXkvLFxuXHRybW91c2VFdmVudCA9IC9eKD86bW91c2V8cG9pbnRlcnxjb250ZXh0bWVudSl8Y2xpY2svLFxuXHRyZm9jdXNNb3JwaCA9IC9eKD86Zm9jdXNpbmZvY3VzfGZvY3Vzb3V0Ymx1cikkLyxcblx0cnR5cGVuYW1lc3BhY2UgPSAvXihbXi5dKikoPzpcXC4oLispfCkkLztcblxuZnVuY3Rpb24gcmV0dXJuVHJ1ZSgpIHtcblx0cmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHJldHVybkZhbHNlKCkge1xuXHRyZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHNhZmVBY3RpdmVFbGVtZW50KCkge1xuXHR0cnkge1xuXHRcdHJldHVybiBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuXHR9IGNhdGNoICggZXJyICkgeyB9XG59XG5cbi8qXG4gKiBIZWxwZXIgZnVuY3Rpb25zIGZvciBtYW5hZ2luZyBldmVudHMgLS0gbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBpbnRlcmZhY2UuXG4gKiBQcm9wcyB0byBEZWFuIEVkd2FyZHMnIGFkZEV2ZW50IGxpYnJhcnkgZm9yIG1hbnkgb2YgdGhlIGlkZWFzLlxuICovXG5qUXVlcnkuZXZlbnQgPSB7XG5cblx0Z2xvYmFsOiB7fSxcblxuXHRhZGQ6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlcywgaGFuZGxlciwgZGF0YSwgc2VsZWN0b3IgKSB7XG5cblx0XHR2YXIgaGFuZGxlT2JqSW4sIGV2ZW50SGFuZGxlLCB0bXAsXG5cdFx0XHRldmVudHMsIHQsIGhhbmRsZU9iaixcblx0XHRcdHNwZWNpYWwsIGhhbmRsZXJzLCB0eXBlLCBuYW1lc3BhY2VzLCBvcmlnVHlwZSxcblx0XHRcdGVsZW1EYXRhID0gZGF0YV9wcml2LmdldCggZWxlbSApO1xuXG5cdFx0Ly8gRG9uJ3QgYXR0YWNoIGV2ZW50cyB0byBub0RhdGEgb3IgdGV4dC9jb21tZW50IG5vZGVzIChidXQgYWxsb3cgcGxhaW4gb2JqZWN0cylcblx0XHRpZiAoICFlbGVtRGF0YSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBDYWxsZXIgY2FuIHBhc3MgaW4gYW4gb2JqZWN0IG9mIGN1c3RvbSBkYXRhIGluIGxpZXUgb2YgdGhlIGhhbmRsZXJcblx0XHRpZiAoIGhhbmRsZXIuaGFuZGxlciApIHtcblx0XHRcdGhhbmRsZU9iakluID0gaGFuZGxlcjtcblx0XHRcdGhhbmRsZXIgPSBoYW5kbGVPYmpJbi5oYW5kbGVyO1xuXHRcdFx0c2VsZWN0b3IgPSBoYW5kbGVPYmpJbi5zZWxlY3Rvcjtcblx0XHR9XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB0aGUgaGFuZGxlciBoYXMgYSB1bmlxdWUgSUQsIHVzZWQgdG8gZmluZC9yZW1vdmUgaXQgbGF0ZXJcblx0XHRpZiAoICFoYW5kbGVyLmd1aWQgKSB7XG5cdFx0XHRoYW5kbGVyLmd1aWQgPSBqUXVlcnkuZ3VpZCsrO1xuXHRcdH1cblxuXHRcdC8vIEluaXQgdGhlIGVsZW1lbnQncyBldmVudCBzdHJ1Y3R1cmUgYW5kIG1haW4gaGFuZGxlciwgaWYgdGhpcyBpcyB0aGUgZmlyc3Rcblx0XHRpZiAoICEoZXZlbnRzID0gZWxlbURhdGEuZXZlbnRzKSApIHtcblx0XHRcdGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyA9IHt9O1xuXHRcdH1cblx0XHRpZiAoICEoZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUpICkge1xuXHRcdFx0ZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUgPSBmdW5jdGlvbiggZSApIHtcblx0XHRcdFx0Ly8gRGlzY2FyZCB0aGUgc2Vjb25kIGV2ZW50IG9mIGEgalF1ZXJ5LmV2ZW50LnRyaWdnZXIoKSBhbmRcblx0XHRcdFx0Ly8gd2hlbiBhbiBldmVudCBpcyBjYWxsZWQgYWZ0ZXIgYSBwYWdlIGhhcyB1bmxvYWRlZFxuXHRcdFx0XHRyZXR1cm4gdHlwZW9mIGpRdWVyeSAhPT0gc3RydW5kZWZpbmVkICYmIGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgIT09IGUudHlwZSA/XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LmRpc3BhdGNoLmFwcGx5KCBlbGVtLCBhcmd1bWVudHMgKSA6IHVuZGVmaW5lZDtcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gSGFuZGxlIG11bHRpcGxlIGV2ZW50cyBzZXBhcmF0ZWQgYnkgYSBzcGFjZVxuXHRcdHR5cGVzID0gKCB0eXBlcyB8fCBcIlwiICkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFsgXCJcIiBdO1xuXHRcdHQgPSB0eXBlcy5sZW5ndGg7XG5cdFx0d2hpbGUgKCB0LS0gKSB7XG5cdFx0XHR0bXAgPSBydHlwZW5hbWVzcGFjZS5leGVjKCB0eXBlc1t0XSApIHx8IFtdO1xuXHRcdFx0dHlwZSA9IG9yaWdUeXBlID0gdG1wWzFdO1xuXHRcdFx0bmFtZXNwYWNlcyA9ICggdG1wWzJdIHx8IFwiXCIgKS5zcGxpdCggXCIuXCIgKS5zb3J0KCk7XG5cblx0XHRcdC8vIFRoZXJlICptdXN0KiBiZSBhIHR5cGUsIG5vIGF0dGFjaGluZyBuYW1lc3BhY2Utb25seSBoYW5kbGVyc1xuXHRcdFx0aWYgKCAhdHlwZSApIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIGV2ZW50IGNoYW5nZXMgaXRzIHR5cGUsIHVzZSB0aGUgc3BlY2lhbCBldmVudCBoYW5kbGVycyBmb3IgdGhlIGNoYW5nZWQgdHlwZVxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cblx0XHRcdC8vIElmIHNlbGVjdG9yIGRlZmluZWQsIGRldGVybWluZSBzcGVjaWFsIGV2ZW50IGFwaSB0eXBlLCBvdGhlcndpc2UgZ2l2ZW4gdHlwZVxuXHRcdFx0dHlwZSA9ICggc2VsZWN0b3IgPyBzcGVjaWFsLmRlbGVnYXRlVHlwZSA6IHNwZWNpYWwuYmluZFR5cGUgKSB8fCB0eXBlO1xuXG5cdFx0XHQvLyBVcGRhdGUgc3BlY2lhbCBiYXNlZCBvbiBuZXdseSByZXNldCB0eXBlXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblxuXHRcdFx0Ly8gaGFuZGxlT2JqIGlzIHBhc3NlZCB0byBhbGwgZXZlbnQgaGFuZGxlcnNcblx0XHRcdGhhbmRsZU9iaiA9IGpRdWVyeS5leHRlbmQoe1xuXHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRvcmlnVHlwZTogb3JpZ1R5cGUsXG5cdFx0XHRcdGRhdGE6IGRhdGEsXG5cdFx0XHRcdGhhbmRsZXI6IGhhbmRsZXIsXG5cdFx0XHRcdGd1aWQ6IGhhbmRsZXIuZ3VpZCxcblx0XHRcdFx0c2VsZWN0b3I6IHNlbGVjdG9yLFxuXHRcdFx0XHRuZWVkc0NvbnRleHQ6IHNlbGVjdG9yICYmIGpRdWVyeS5leHByLm1hdGNoLm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvciApLFxuXHRcdFx0XHRuYW1lc3BhY2U6IG5hbWVzcGFjZXMuam9pbihcIi5cIilcblx0XHRcdH0sIGhhbmRsZU9iakluICk7XG5cblx0XHRcdC8vIEluaXQgdGhlIGV2ZW50IGhhbmRsZXIgcXVldWUgaWYgd2UncmUgdGhlIGZpcnN0XG5cdFx0XHRpZiAoICEoaGFuZGxlcnMgPSBldmVudHNbIHR5cGUgXSkgKSB7XG5cdFx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gPSBbXTtcblx0XHRcdFx0aGFuZGxlcnMuZGVsZWdhdGVDb3VudCA9IDA7XG5cblx0XHRcdFx0Ly8gT25seSB1c2UgYWRkRXZlbnRMaXN0ZW5lciBpZiB0aGUgc3BlY2lhbCBldmVudHMgaGFuZGxlciByZXR1cm5zIGZhbHNlXG5cdFx0XHRcdGlmICggIXNwZWNpYWwuc2V0dXAgfHwgc3BlY2lhbC5zZXR1cC5jYWxsKCBlbGVtLCBkYXRhLCBuYW1lc3BhY2VzLCBldmVudEhhbmRsZSApID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRpZiAoIGVsZW0uYWRkRXZlbnRMaXN0ZW5lciApIHtcblx0XHRcdFx0XHRcdGVsZW0uYWRkRXZlbnRMaXN0ZW5lciggdHlwZSwgZXZlbnRIYW5kbGUsIGZhbHNlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmICggc3BlY2lhbC5hZGQgKSB7XG5cdFx0XHRcdHNwZWNpYWwuYWRkLmNhbGwoIGVsZW0sIGhhbmRsZU9iaiApO1xuXG5cdFx0XHRcdGlmICggIWhhbmRsZU9iai5oYW5kbGVyLmd1aWQgKSB7XG5cdFx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXIuZ3VpZCA9IGhhbmRsZXIuZ3VpZDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgdG8gdGhlIGVsZW1lbnQncyBoYW5kbGVyIGxpc3QsIGRlbGVnYXRlcyBpbiBmcm9udFxuXHRcdFx0aWYgKCBzZWxlY3RvciApIHtcblx0XHRcdFx0aGFuZGxlcnMuc3BsaWNlKCBoYW5kbGVycy5kZWxlZ2F0ZUNvdW50KyssIDAsIGhhbmRsZU9iaiApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aGFuZGxlcnMucHVzaCggaGFuZGxlT2JqICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEtlZXAgdHJhY2sgb2Ygd2hpY2ggZXZlbnRzIGhhdmUgZXZlciBiZWVuIHVzZWQsIGZvciBldmVudCBvcHRpbWl6YXRpb25cblx0XHRcdGpRdWVyeS5ldmVudC5nbG9iYWxbIHR5cGUgXSA9IHRydWU7XG5cdFx0fVxuXG5cdH0sXG5cblx0Ly8gRGV0YWNoIGFuIGV2ZW50IG9yIHNldCBvZiBldmVudHMgZnJvbSBhbiBlbGVtZW50XG5cdHJlbW92ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBzZWxlY3RvciwgbWFwcGVkVHlwZXMgKSB7XG5cblx0XHR2YXIgaiwgb3JpZ0NvdW50LCB0bXAsXG5cdFx0XHRldmVudHMsIHQsIGhhbmRsZU9iaixcblx0XHRcdHNwZWNpYWwsIGhhbmRsZXJzLCB0eXBlLCBuYW1lc3BhY2VzLCBvcmlnVHlwZSxcblx0XHRcdGVsZW1EYXRhID0gZGF0YV9wcml2Lmhhc0RhdGEoIGVsZW0gKSAmJiBkYXRhX3ByaXYuZ2V0KCBlbGVtICk7XG5cblx0XHRpZiAoICFlbGVtRGF0YSB8fCAhKGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cykgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gT25jZSBmb3IgZWFjaCB0eXBlLm5hbWVzcGFjZSBpbiB0eXBlczsgdHlwZSBtYXkgYmUgb21pdHRlZFxuXHRcdHR5cGVzID0gKCB0eXBlcyB8fCBcIlwiICkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFsgXCJcIiBdO1xuXHRcdHQgPSB0eXBlcy5sZW5ndGg7XG5cdFx0d2hpbGUgKCB0LS0gKSB7XG5cdFx0XHR0bXAgPSBydHlwZW5hbWVzcGFjZS5leGVjKCB0eXBlc1t0XSApIHx8IFtdO1xuXHRcdFx0dHlwZSA9IG9yaWdUeXBlID0gdG1wWzFdO1xuXHRcdFx0bmFtZXNwYWNlcyA9ICggdG1wWzJdIHx8IFwiXCIgKS5zcGxpdCggXCIuXCIgKS5zb3J0KCk7XG5cblx0XHRcdC8vIFVuYmluZCBhbGwgZXZlbnRzIChvbiB0aGlzIG5hbWVzcGFjZSwgaWYgcHJvdmlkZWQpIGZvciB0aGUgZWxlbWVudFxuXHRcdFx0aWYgKCAhdHlwZSApIHtcblx0XHRcdFx0Zm9yICggdHlwZSBpbiBldmVudHMgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggZWxlbSwgdHlwZSArIHR5cGVzWyB0IF0sIGhhbmRsZXIsIHNlbGVjdG9yLCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXHRcdFx0dHlwZSA9ICggc2VsZWN0b3IgPyBzcGVjaWFsLmRlbGVnYXRlVHlwZSA6IHNwZWNpYWwuYmluZFR5cGUgKSB8fCB0eXBlO1xuXHRcdFx0aGFuZGxlcnMgPSBldmVudHNbIHR5cGUgXSB8fCBbXTtcblx0XHRcdHRtcCA9IHRtcFsyXSAmJiBuZXcgUmVnRXhwKCBcIihefFxcXFwuKVwiICsgbmFtZXNwYWNlcy5qb2luKFwiXFxcXC4oPzouKlxcXFwufClcIikgKyBcIihcXFxcLnwkKVwiICk7XG5cblx0XHRcdC8vIFJlbW92ZSBtYXRjaGluZyBldmVudHNcblx0XHRcdG9yaWdDb3VudCA9IGogPSBoYW5kbGVycy5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGotLSApIHtcblx0XHRcdFx0aGFuZGxlT2JqID0gaGFuZGxlcnNbIGogXTtcblxuXHRcdFx0XHRpZiAoICggbWFwcGVkVHlwZXMgfHwgb3JpZ1R5cGUgPT09IGhhbmRsZU9iai5vcmlnVHlwZSApICYmXG5cdFx0XHRcdFx0KCAhaGFuZGxlciB8fCBoYW5kbGVyLmd1aWQgPT09IGhhbmRsZU9iai5ndWlkICkgJiZcblx0XHRcdFx0XHQoICF0bXAgfHwgdG1wLnRlc3QoIGhhbmRsZU9iai5uYW1lc3BhY2UgKSApICYmXG5cdFx0XHRcdFx0KCAhc2VsZWN0b3IgfHwgc2VsZWN0b3IgPT09IGhhbmRsZU9iai5zZWxlY3RvciB8fCBzZWxlY3RvciA9PT0gXCIqKlwiICYmIGhhbmRsZU9iai5zZWxlY3RvciApICkge1xuXHRcdFx0XHRcdGhhbmRsZXJzLnNwbGljZSggaiwgMSApO1xuXG5cdFx0XHRcdFx0aWYgKCBoYW5kbGVPYmouc2VsZWN0b3IgKSB7XG5cdFx0XHRcdFx0XHRoYW5kbGVycy5kZWxlZ2F0ZUNvdW50LS07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggc3BlY2lhbC5yZW1vdmUgKSB7XG5cdFx0XHRcdFx0XHRzcGVjaWFsLnJlbW92ZS5jYWxsKCBlbGVtLCBoYW5kbGVPYmogKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gUmVtb3ZlIGdlbmVyaWMgZXZlbnQgaGFuZGxlciBpZiB3ZSByZW1vdmVkIHNvbWV0aGluZyBhbmQgbm8gbW9yZSBoYW5kbGVycyBleGlzdFxuXHRcdFx0Ly8gKGF2b2lkcyBwb3RlbnRpYWwgZm9yIGVuZGxlc3MgcmVjdXJzaW9uIGR1cmluZyByZW1vdmFsIG9mIHNwZWNpYWwgZXZlbnQgaGFuZGxlcnMpXG5cdFx0XHRpZiAoIG9yaWdDb3VudCAmJiAhaGFuZGxlcnMubGVuZ3RoICkge1xuXHRcdFx0XHRpZiAoICFzcGVjaWFsLnRlYXJkb3duIHx8IHNwZWNpYWwudGVhcmRvd24uY2FsbCggZWxlbSwgbmFtZXNwYWNlcywgZWxlbURhdGEuaGFuZGxlICkgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdGpRdWVyeS5yZW1vdmVFdmVudCggZWxlbSwgdHlwZSwgZWxlbURhdGEuaGFuZGxlICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRkZWxldGUgZXZlbnRzWyB0eXBlIF07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUmVtb3ZlIHRoZSBleHBhbmRvIGlmIGl0J3Mgbm8gbG9uZ2VyIHVzZWRcblx0XHRpZiAoIGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBldmVudHMgKSApIHtcblx0XHRcdGRlbGV0ZSBlbGVtRGF0YS5oYW5kbGU7XG5cdFx0XHRkYXRhX3ByaXYucmVtb3ZlKCBlbGVtLCBcImV2ZW50c1wiICk7XG5cdFx0fVxuXHR9LFxuXG5cdHRyaWdnZXI6IGZ1bmN0aW9uKCBldmVudCwgZGF0YSwgZWxlbSwgb25seUhhbmRsZXJzICkge1xuXG5cdFx0dmFyIGksIGN1ciwgdG1wLCBidWJibGVUeXBlLCBvbnR5cGUsIGhhbmRsZSwgc3BlY2lhbCxcblx0XHRcdGV2ZW50UGF0aCA9IFsgZWxlbSB8fCBkb2N1bWVudCBdLFxuXHRcdFx0dHlwZSA9IGhhc093bi5jYWxsKCBldmVudCwgXCJ0eXBlXCIgKSA/IGV2ZW50LnR5cGUgOiBldmVudCxcblx0XHRcdG5hbWVzcGFjZXMgPSBoYXNPd24uY2FsbCggZXZlbnQsIFwibmFtZXNwYWNlXCIgKSA/IGV2ZW50Lm5hbWVzcGFjZS5zcGxpdChcIi5cIikgOiBbXTtcblxuXHRcdGN1ciA9IHRtcCA9IGVsZW0gPSBlbGVtIHx8IGRvY3VtZW50O1xuXG5cdFx0Ly8gRG9uJ3QgZG8gZXZlbnRzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcblx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBmb2N1cy9ibHVyIG1vcnBocyB0byBmb2N1c2luL291dDsgZW5zdXJlIHdlJ3JlIG5vdCBmaXJpbmcgdGhlbSByaWdodCBub3dcblx0XHRpZiAoIHJmb2N1c01vcnBoLnRlc3QoIHR5cGUgKyBqUXVlcnkuZXZlbnQudHJpZ2dlcmVkICkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCB0eXBlLmluZGV4T2YoXCIuXCIpID49IDAgKSB7XG5cdFx0XHQvLyBOYW1lc3BhY2VkIHRyaWdnZXI7IGNyZWF0ZSBhIHJlZ2V4cCB0byBtYXRjaCBldmVudCB0eXBlIGluIGhhbmRsZSgpXG5cdFx0XHRuYW1lc3BhY2VzID0gdHlwZS5zcGxpdChcIi5cIik7XG5cdFx0XHR0eXBlID0gbmFtZXNwYWNlcy5zaGlmdCgpO1xuXHRcdFx0bmFtZXNwYWNlcy5zb3J0KCk7XG5cdFx0fVxuXHRcdG9udHlwZSA9IHR5cGUuaW5kZXhPZihcIjpcIikgPCAwICYmIFwib25cIiArIHR5cGU7XG5cblx0XHQvLyBDYWxsZXIgY2FuIHBhc3MgaW4gYSBqUXVlcnkuRXZlbnQgb2JqZWN0LCBPYmplY3QsIG9yIGp1c3QgYW4gZXZlbnQgdHlwZSBzdHJpbmdcblx0XHRldmVudCA9IGV2ZW50WyBqUXVlcnkuZXhwYW5kbyBdID9cblx0XHRcdGV2ZW50IDpcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoIHR5cGUsIHR5cGVvZiBldmVudCA9PT0gXCJvYmplY3RcIiAmJiBldmVudCApO1xuXG5cdFx0Ly8gVHJpZ2dlciBiaXRtYXNrOiAmIDEgZm9yIG5hdGl2ZSBoYW5kbGVyczsgJiAyIGZvciBqUXVlcnkgKGFsd2F5cyB0cnVlKVxuXHRcdGV2ZW50LmlzVHJpZ2dlciA9IG9ubHlIYW5kbGVycyA/IDIgOiAzO1xuXHRcdGV2ZW50Lm5hbWVzcGFjZSA9IG5hbWVzcGFjZXMuam9pbihcIi5cIik7XG5cdFx0ZXZlbnQubmFtZXNwYWNlX3JlID0gZXZlbnQubmFtZXNwYWNlID9cblx0XHRcdG5ldyBSZWdFeHAoIFwiKF58XFxcXC4pXCIgKyBuYW1lc3BhY2VzLmpvaW4oXCJcXFxcLig/Oi4qXFxcXC58KVwiKSArIFwiKFxcXFwufCQpXCIgKSA6XG5cdFx0XHRudWxsO1xuXG5cdFx0Ly8gQ2xlYW4gdXAgdGhlIGV2ZW50IGluIGNhc2UgaXQgaXMgYmVpbmcgcmV1c2VkXG5cdFx0ZXZlbnQucmVzdWx0ID0gdW5kZWZpbmVkO1xuXHRcdGlmICggIWV2ZW50LnRhcmdldCApIHtcblx0XHRcdGV2ZW50LnRhcmdldCA9IGVsZW07XG5cdFx0fVxuXG5cdFx0Ly8gQ2xvbmUgYW55IGluY29taW5nIGRhdGEgYW5kIHByZXBlbmQgdGhlIGV2ZW50LCBjcmVhdGluZyB0aGUgaGFuZGxlciBhcmcgbGlzdFxuXHRcdGRhdGEgPSBkYXRhID09IG51bGwgP1xuXHRcdFx0WyBldmVudCBdIDpcblx0XHRcdGpRdWVyeS5tYWtlQXJyYXkoIGRhdGEsIFsgZXZlbnQgXSApO1xuXG5cdFx0Ly8gQWxsb3cgc3BlY2lhbCBldmVudHMgdG8gZHJhdyBvdXRzaWRlIHRoZSBsaW5lc1xuXHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiBzcGVjaWFsLnRyaWdnZXIgJiYgc3BlY2lhbC50cmlnZ2VyLmFwcGx5KCBlbGVtLCBkYXRhICkgPT09IGZhbHNlICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIERldGVybWluZSBldmVudCBwcm9wYWdhdGlvbiBwYXRoIGluIGFkdmFuY2UsIHBlciBXM0MgZXZlbnRzIHNwZWMgKCM5OTUxKVxuXHRcdC8vIEJ1YmJsZSB1cCB0byBkb2N1bWVudCwgdGhlbiB0byB3aW5kb3c7IHdhdGNoIGZvciBhIGdsb2JhbCBvd25lckRvY3VtZW50IHZhciAoIzk3MjQpXG5cdFx0aWYgKCAhb25seUhhbmRsZXJzICYmICFzcGVjaWFsLm5vQnViYmxlICYmICFqUXVlcnkuaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0YnViYmxlVHlwZSA9IHNwZWNpYWwuZGVsZWdhdGVUeXBlIHx8IHR5cGU7XG5cdFx0XHRpZiAoICFyZm9jdXNNb3JwaC50ZXN0KCBidWJibGVUeXBlICsgdHlwZSApICkge1xuXHRcdFx0XHRjdXIgPSBjdXIucGFyZW50Tm9kZTtcblx0XHRcdH1cblx0XHRcdGZvciAoIDsgY3VyOyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0ZXZlbnRQYXRoLnB1c2goIGN1ciApO1xuXHRcdFx0XHR0bXAgPSBjdXI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE9ubHkgYWRkIHdpbmRvdyBpZiB3ZSBnb3QgdG8gZG9jdW1lbnQgKGUuZy4sIG5vdCBwbGFpbiBvYmogb3IgZGV0YWNoZWQgRE9NKVxuXHRcdFx0aWYgKCB0bXAgPT09IChlbGVtLm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQpICkge1xuXHRcdFx0XHRldmVudFBhdGgucHVzaCggdG1wLmRlZmF1bHRWaWV3IHx8IHRtcC5wYXJlbnRXaW5kb3cgfHwgd2luZG93ICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRmlyZSBoYW5kbGVycyBvbiB0aGUgZXZlbnQgcGF0aFxuXHRcdGkgPSAwO1xuXHRcdHdoaWxlICggKGN1ciA9IGV2ZW50UGF0aFtpKytdKSAmJiAhZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblxuXHRcdFx0ZXZlbnQudHlwZSA9IGkgPiAxID9cblx0XHRcdFx0YnViYmxlVHlwZSA6XG5cdFx0XHRcdHNwZWNpYWwuYmluZFR5cGUgfHwgdHlwZTtcblxuXHRcdFx0Ly8galF1ZXJ5IGhhbmRsZXJcblx0XHRcdGhhbmRsZSA9ICggZGF0YV9wcml2LmdldCggY3VyLCBcImV2ZW50c1wiICkgfHwge30gKVsgZXZlbnQudHlwZSBdICYmIGRhdGFfcHJpdi5nZXQoIGN1ciwgXCJoYW5kbGVcIiApO1xuXHRcdFx0aWYgKCBoYW5kbGUgKSB7XG5cdFx0XHRcdGhhbmRsZS5hcHBseSggY3VyLCBkYXRhICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE5hdGl2ZSBoYW5kbGVyXG5cdFx0XHRoYW5kbGUgPSBvbnR5cGUgJiYgY3VyWyBvbnR5cGUgXTtcblx0XHRcdGlmICggaGFuZGxlICYmIGhhbmRsZS5hcHBseSAmJiBqUXVlcnkuYWNjZXB0RGF0YSggY3VyICkgKSB7XG5cdFx0XHRcdGV2ZW50LnJlc3VsdCA9IGhhbmRsZS5hcHBseSggY3VyLCBkYXRhICk7XG5cdFx0XHRcdGlmICggZXZlbnQucmVzdWx0ID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGV2ZW50LnR5cGUgPSB0eXBlO1xuXG5cdFx0Ly8gSWYgbm9ib2R5IHByZXZlbnRlZCB0aGUgZGVmYXVsdCBhY3Rpb24sIGRvIGl0IG5vd1xuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiAhZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkgKSB7XG5cblx0XHRcdGlmICggKCFzcGVjaWFsLl9kZWZhdWx0IHx8IHNwZWNpYWwuX2RlZmF1bHQuYXBwbHkoIGV2ZW50UGF0aC5wb3AoKSwgZGF0YSApID09PSBmYWxzZSkgJiZcblx0XHRcdFx0alF1ZXJ5LmFjY2VwdERhdGEoIGVsZW0gKSApIHtcblxuXHRcdFx0XHQvLyBDYWxsIGEgbmF0aXZlIERPTSBtZXRob2Qgb24gdGhlIHRhcmdldCB3aXRoIHRoZSBzYW1lIG5hbWUgbmFtZSBhcyB0aGUgZXZlbnQuXG5cdFx0XHRcdC8vIERvbid0IGRvIGRlZmF1bHQgYWN0aW9ucyBvbiB3aW5kb3csIHRoYXQncyB3aGVyZSBnbG9iYWwgdmFyaWFibGVzIGJlICgjNjE3MClcblx0XHRcdFx0aWYgKCBvbnR5cGUgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIGVsZW1bIHR5cGUgXSApICYmICFqUXVlcnkuaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0XHRcdC8vIERvbid0IHJlLXRyaWdnZXIgYW4gb25GT08gZXZlbnQgd2hlbiB3ZSBjYWxsIGl0cyBGT08oKSBtZXRob2Rcblx0XHRcdFx0XHR0bXAgPSBlbGVtWyBvbnR5cGUgXTtcblxuXHRcdFx0XHRcdGlmICggdG1wICkge1xuXHRcdFx0XHRcdFx0ZWxlbVsgb250eXBlIF0gPSBudWxsO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFByZXZlbnQgcmUtdHJpZ2dlcmluZyBvZiB0aGUgc2FtZSBldmVudCwgc2luY2Ugd2UgYWxyZWFkeSBidWJibGVkIGl0IGFib3ZlXG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCA9IHR5cGU7XG5cdFx0XHRcdFx0ZWxlbVsgdHlwZSBdKCk7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCA9IHVuZGVmaW5lZDtcblxuXHRcdFx0XHRcdGlmICggdG1wICkge1xuXHRcdFx0XHRcdFx0ZWxlbVsgb250eXBlIF0gPSB0bXA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV2ZW50LnJlc3VsdDtcblx0fSxcblxuXHRkaXNwYXRjaDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXG5cdFx0Ly8gTWFrZSBhIHdyaXRhYmxlIGpRdWVyeS5FdmVudCBmcm9tIHRoZSBuYXRpdmUgZXZlbnQgb2JqZWN0XG5cdFx0ZXZlbnQgPSBqUXVlcnkuZXZlbnQuZml4KCBldmVudCApO1xuXG5cdFx0dmFyIGksIGosIHJldCwgbWF0Y2hlZCwgaGFuZGxlT2JqLFxuXHRcdFx0aGFuZGxlclF1ZXVlID0gW10sXG5cdFx0XHRhcmdzID0gc2xpY2UuY2FsbCggYXJndW1lbnRzICksXG5cdFx0XHRoYW5kbGVycyA9ICggZGF0YV9wcml2LmdldCggdGhpcywgXCJldmVudHNcIiApIHx8IHt9IClbIGV2ZW50LnR5cGUgXSB8fCBbXSxcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgZXZlbnQudHlwZSBdIHx8IHt9O1xuXG5cdFx0Ly8gVXNlIHRoZSBmaXgtZWQgalF1ZXJ5LkV2ZW50IHJhdGhlciB0aGFuIHRoZSAocmVhZC1vbmx5KSBuYXRpdmUgZXZlbnRcblx0XHRhcmdzWzBdID0gZXZlbnQ7XG5cdFx0ZXZlbnQuZGVsZWdhdGVUYXJnZXQgPSB0aGlzO1xuXG5cdFx0Ly8gQ2FsbCB0aGUgcHJlRGlzcGF0Y2ggaG9vayBmb3IgdGhlIG1hcHBlZCB0eXBlLCBhbmQgbGV0IGl0IGJhaWwgaWYgZGVzaXJlZFxuXHRcdGlmICggc3BlY2lhbC5wcmVEaXNwYXRjaCAmJiBzcGVjaWFsLnByZURpc3BhdGNoLmNhbGwoIHRoaXMsIGV2ZW50ICkgPT09IGZhbHNlICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIERldGVybWluZSBoYW5kbGVyc1xuXHRcdGhhbmRsZXJRdWV1ZSA9IGpRdWVyeS5ldmVudC5oYW5kbGVycy5jYWxsKCB0aGlzLCBldmVudCwgaGFuZGxlcnMgKTtcblxuXHRcdC8vIFJ1biBkZWxlZ2F0ZXMgZmlyc3Q7IHRoZXkgbWF5IHdhbnQgdG8gc3RvcCBwcm9wYWdhdGlvbiBiZW5lYXRoIHVzXG5cdFx0aSA9IDA7XG5cdFx0d2hpbGUgKCAobWF0Y2hlZCA9IGhhbmRsZXJRdWV1ZVsgaSsrIF0pICYmICFldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXHRcdFx0ZXZlbnQuY3VycmVudFRhcmdldCA9IG1hdGNoZWQuZWxlbTtcblxuXHRcdFx0aiA9IDA7XG5cdFx0XHR3aGlsZSAoIChoYW5kbGVPYmogPSBtYXRjaGVkLmhhbmRsZXJzWyBqKysgXSkgJiYgIWV2ZW50LmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cblx0XHRcdFx0Ly8gVHJpZ2dlcmVkIGV2ZW50IG11c3QgZWl0aGVyIDEpIGhhdmUgbm8gbmFtZXNwYWNlLCBvclxuXHRcdFx0XHQvLyAyKSBoYXZlIG5hbWVzcGFjZShzKSBhIHN1YnNldCBvciBlcXVhbCB0byB0aG9zZSBpbiB0aGUgYm91bmQgZXZlbnQgKGJvdGggY2FuIGhhdmUgbm8gbmFtZXNwYWNlKS5cblx0XHRcdFx0aWYgKCAhZXZlbnQubmFtZXNwYWNlX3JlIHx8IGV2ZW50Lm5hbWVzcGFjZV9yZS50ZXN0KCBoYW5kbGVPYmoubmFtZXNwYWNlICkgKSB7XG5cblx0XHRcdFx0XHRldmVudC5oYW5kbGVPYmogPSBoYW5kbGVPYmo7XG5cdFx0XHRcdFx0ZXZlbnQuZGF0YSA9IGhhbmRsZU9iai5kYXRhO1xuXG5cdFx0XHRcdFx0cmV0ID0gKCAoalF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGhhbmRsZU9iai5vcmlnVHlwZSBdIHx8IHt9KS5oYW5kbGUgfHwgaGFuZGxlT2JqLmhhbmRsZXIgKVxuXHRcdFx0XHRcdFx0XHQuYXBwbHkoIG1hdGNoZWQuZWxlbSwgYXJncyApO1xuXG5cdFx0XHRcdFx0aWYgKCByZXQgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRcdGlmICggKGV2ZW50LnJlc3VsdCA9IHJldCkgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWxsIHRoZSBwb3N0RGlzcGF0Y2ggaG9vayBmb3IgdGhlIG1hcHBlZCB0eXBlXG5cdFx0aWYgKCBzcGVjaWFsLnBvc3REaXNwYXRjaCApIHtcblx0XHRcdHNwZWNpYWwucG9zdERpc3BhdGNoLmNhbGwoIHRoaXMsIGV2ZW50ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV2ZW50LnJlc3VsdDtcblx0fSxcblxuXHRoYW5kbGVyczogZnVuY3Rpb24oIGV2ZW50LCBoYW5kbGVycyApIHtcblx0XHR2YXIgaSwgbWF0Y2hlcywgc2VsLCBoYW5kbGVPYmosXG5cdFx0XHRoYW5kbGVyUXVldWUgPSBbXSxcblx0XHRcdGRlbGVnYXRlQ291bnQgPSBoYW5kbGVycy5kZWxlZ2F0ZUNvdW50LFxuXHRcdFx0Y3VyID0gZXZlbnQudGFyZ2V0O1xuXG5cdFx0Ly8gRmluZCBkZWxlZ2F0ZSBoYW5kbGVyc1xuXHRcdC8vIEJsYWNrLWhvbGUgU1ZHIDx1c2U+IGluc3RhbmNlIHRyZWVzICgjMTMxODApXG5cdFx0Ly8gQXZvaWQgbm9uLWxlZnQtY2xpY2sgYnViYmxpbmcgaW4gRmlyZWZveCAoIzM4NjEpXG5cdFx0aWYgKCBkZWxlZ2F0ZUNvdW50ICYmIGN1ci5ub2RlVHlwZSAmJiAoIWV2ZW50LmJ1dHRvbiB8fCBldmVudC50eXBlICE9PSBcImNsaWNrXCIpICkge1xuXG5cdFx0XHRmb3IgKCA7IGN1ciAhPT0gdGhpczsgY3VyID0gY3VyLnBhcmVudE5vZGUgfHwgdGhpcyApIHtcblxuXHRcdFx0XHQvLyBEb24ndCBwcm9jZXNzIGNsaWNrcyBvbiBkaXNhYmxlZCBlbGVtZW50cyAoIzY5MTEsICM4MTY1LCAjMTEzODIsICMxMTc2NClcblx0XHRcdFx0aWYgKCBjdXIuZGlzYWJsZWQgIT09IHRydWUgfHwgZXZlbnQudHlwZSAhPT0gXCJjbGlja1wiICkge1xuXHRcdFx0XHRcdG1hdGNoZXMgPSBbXTtcblx0XHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGRlbGVnYXRlQ291bnQ7IGkrKyApIHtcblx0XHRcdFx0XHRcdGhhbmRsZU9iaiA9IGhhbmRsZXJzWyBpIF07XG5cblx0XHRcdFx0XHRcdC8vIERvbid0IGNvbmZsaWN0IHdpdGggT2JqZWN0LnByb3RvdHlwZSBwcm9wZXJ0aWVzICgjMTMyMDMpXG5cdFx0XHRcdFx0XHRzZWwgPSBoYW5kbGVPYmouc2VsZWN0b3IgKyBcIiBcIjtcblxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVzWyBzZWwgXSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdFx0XHRtYXRjaGVzWyBzZWwgXSA9IGhhbmRsZU9iai5uZWVkc0NvbnRleHQgP1xuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeSggc2VsLCB0aGlzICkuaW5kZXgoIGN1ciApID49IDAgOlxuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5maW5kKCBzZWwsIHRoaXMsIG51bGwsIFsgY3VyIF0gKS5sZW5ndGg7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXNbIHNlbCBdICkge1xuXHRcdFx0XHRcdFx0XHRtYXRjaGVzLnB1c2goIGhhbmRsZU9iaiApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIG1hdGNoZXMubGVuZ3RoICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlclF1ZXVlLnB1c2goeyBlbGVtOiBjdXIsIGhhbmRsZXJzOiBtYXRjaGVzIH0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEFkZCB0aGUgcmVtYWluaW5nIChkaXJlY3RseS1ib3VuZCkgaGFuZGxlcnNcblx0XHRpZiAoIGRlbGVnYXRlQ291bnQgPCBoYW5kbGVycy5sZW5ndGggKSB7XG5cdFx0XHRoYW5kbGVyUXVldWUucHVzaCh7IGVsZW06IHRoaXMsIGhhbmRsZXJzOiBoYW5kbGVycy5zbGljZSggZGVsZWdhdGVDb3VudCApIH0pO1xuXHRcdH1cblxuXHRcdHJldHVybiBoYW5kbGVyUXVldWU7XG5cdH0sXG5cblx0Ly8gSW5jbHVkZXMgc29tZSBldmVudCBwcm9wcyBzaGFyZWQgYnkgS2V5RXZlbnQgYW5kIE1vdXNlRXZlbnRcblx0cHJvcHM6IFwiYWx0S2V5IGJ1YmJsZXMgY2FuY2VsYWJsZSBjdHJsS2V5IGN1cnJlbnRUYXJnZXQgZXZlbnRQaGFzZSBtZXRhS2V5IHJlbGF0ZWRUYXJnZXQgc2hpZnRLZXkgdGFyZ2V0IHRpbWVTdGFtcCB2aWV3IHdoaWNoXCIuc3BsaXQoXCIgXCIpLFxuXG5cdGZpeEhvb2tzOiB7fSxcblxuXHRrZXlIb29rczoge1xuXHRcdHByb3BzOiBcImNoYXIgY2hhckNvZGUga2V5IGtleUNvZGVcIi5zcGxpdChcIiBcIiksXG5cdFx0ZmlsdGVyOiBmdW5jdGlvbiggZXZlbnQsIG9yaWdpbmFsICkge1xuXG5cdFx0XHQvLyBBZGQgd2hpY2ggZm9yIGtleSBldmVudHNcblx0XHRcdGlmICggZXZlbnQud2hpY2ggPT0gbnVsbCApIHtcblx0XHRcdFx0ZXZlbnQud2hpY2ggPSBvcmlnaW5hbC5jaGFyQ29kZSAhPSBudWxsID8gb3JpZ2luYWwuY2hhckNvZGUgOiBvcmlnaW5hbC5rZXlDb2RlO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZXZlbnQ7XG5cdFx0fVxuXHR9LFxuXG5cdG1vdXNlSG9va3M6IHtcblx0XHRwcm9wczogXCJidXR0b24gYnV0dG9ucyBjbGllbnRYIGNsaWVudFkgb2Zmc2V0WCBvZmZzZXRZIHBhZ2VYIHBhZ2VZIHNjcmVlblggc2NyZWVuWSB0b0VsZW1lbnRcIi5zcGxpdChcIiBcIiksXG5cdFx0ZmlsdGVyOiBmdW5jdGlvbiggZXZlbnQsIG9yaWdpbmFsICkge1xuXHRcdFx0dmFyIGV2ZW50RG9jLCBkb2MsIGJvZHksXG5cdFx0XHRcdGJ1dHRvbiA9IG9yaWdpbmFsLmJ1dHRvbjtcblxuXHRcdFx0Ly8gQ2FsY3VsYXRlIHBhZ2VYL1kgaWYgbWlzc2luZyBhbmQgY2xpZW50WC9ZIGF2YWlsYWJsZVxuXHRcdFx0aWYgKCBldmVudC5wYWdlWCA9PSBudWxsICYmIG9yaWdpbmFsLmNsaWVudFggIT0gbnVsbCApIHtcblx0XHRcdFx0ZXZlbnREb2MgPSBldmVudC50YXJnZXQub3duZXJEb2N1bWVudCB8fCBkb2N1bWVudDtcblx0XHRcdFx0ZG9jID0gZXZlbnREb2MuZG9jdW1lbnRFbGVtZW50O1xuXHRcdFx0XHRib2R5ID0gZXZlbnREb2MuYm9keTtcblxuXHRcdFx0XHRldmVudC5wYWdlWCA9IG9yaWdpbmFsLmNsaWVudFggKyAoIGRvYyAmJiBkb2Muc2Nyb2xsTGVmdCB8fCBib2R5ICYmIGJvZHkuc2Nyb2xsTGVmdCB8fCAwICkgLSAoIGRvYyAmJiBkb2MuY2xpZW50TGVmdCB8fCBib2R5ICYmIGJvZHkuY2xpZW50TGVmdCB8fCAwICk7XG5cdFx0XHRcdGV2ZW50LnBhZ2VZID0gb3JpZ2luYWwuY2xpZW50WSArICggZG9jICYmIGRvYy5zY3JvbGxUb3AgIHx8IGJvZHkgJiYgYm9keS5zY3JvbGxUb3AgIHx8IDAgKSAtICggZG9jICYmIGRvYy5jbGllbnRUb3AgIHx8IGJvZHkgJiYgYm9keS5jbGllbnRUb3AgIHx8IDAgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIHdoaWNoIGZvciBjbGljazogMSA9PT0gbGVmdDsgMiA9PT0gbWlkZGxlOyAzID09PSByaWdodFxuXHRcdFx0Ly8gTm90ZTogYnV0dG9uIGlzIG5vdCBub3JtYWxpemVkLCBzbyBkb24ndCB1c2UgaXRcblx0XHRcdGlmICggIWV2ZW50LndoaWNoICYmIGJ1dHRvbiAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRldmVudC53aGljaCA9ICggYnV0dG9uICYgMSA/IDEgOiAoIGJ1dHRvbiAmIDIgPyAzIDogKCBidXR0b24gJiA0ID8gMiA6IDAgKSApICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBldmVudDtcblx0XHR9XG5cdH0sXG5cblx0Zml4OiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0aWYgKCBldmVudFsgalF1ZXJ5LmV4cGFuZG8gXSApIHtcblx0XHRcdHJldHVybiBldmVudDtcblx0XHR9XG5cblx0XHQvLyBDcmVhdGUgYSB3cml0YWJsZSBjb3B5IG9mIHRoZSBldmVudCBvYmplY3QgYW5kIG5vcm1hbGl6ZSBzb21lIHByb3BlcnRpZXNcblx0XHR2YXIgaSwgcHJvcCwgY29weSxcblx0XHRcdHR5cGUgPSBldmVudC50eXBlLFxuXHRcdFx0b3JpZ2luYWxFdmVudCA9IGV2ZW50LFxuXHRcdFx0Zml4SG9vayA9IHRoaXMuZml4SG9va3NbIHR5cGUgXTtcblxuXHRcdGlmICggIWZpeEhvb2sgKSB7XG5cdFx0XHR0aGlzLmZpeEhvb2tzWyB0eXBlIF0gPSBmaXhIb29rID1cblx0XHRcdFx0cm1vdXNlRXZlbnQudGVzdCggdHlwZSApID8gdGhpcy5tb3VzZUhvb2tzIDpcblx0XHRcdFx0cmtleUV2ZW50LnRlc3QoIHR5cGUgKSA/IHRoaXMua2V5SG9va3MgOlxuXHRcdFx0XHR7fTtcblx0XHR9XG5cdFx0Y29weSA9IGZpeEhvb2sucHJvcHMgPyB0aGlzLnByb3BzLmNvbmNhdCggZml4SG9vay5wcm9wcyApIDogdGhpcy5wcm9wcztcblxuXHRcdGV2ZW50ID0gbmV3IGpRdWVyeS5FdmVudCggb3JpZ2luYWxFdmVudCApO1xuXG5cdFx0aSA9IGNvcHkubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0cHJvcCA9IGNvcHlbIGkgXTtcblx0XHRcdGV2ZW50WyBwcm9wIF0gPSBvcmlnaW5hbEV2ZW50WyBwcm9wIF07XG5cdFx0fVxuXG5cdFx0Ly8gU3VwcG9ydDogQ29yZG92YSAyLjUgKFdlYktpdCkgKCMxMzI1NSlcblx0XHQvLyBBbGwgZXZlbnRzIHNob3VsZCBoYXZlIGEgdGFyZ2V0OyBDb3Jkb3ZhIGRldmljZXJlYWR5IGRvZXNuJ3Rcblx0XHRpZiAoICFldmVudC50YXJnZXQgKSB7XG5cdFx0XHRldmVudC50YXJnZXQgPSBkb2N1bWVudDtcblx0XHR9XG5cblx0XHQvLyBTdXBwb3J0OiBTYWZhcmkgNi4wKywgQ2hyb21lIDwgMjhcblx0XHQvLyBUYXJnZXQgc2hvdWxkIG5vdCBiZSBhIHRleHQgbm9kZSAoIzUwNCwgIzEzMTQzKVxuXHRcdGlmICggZXZlbnQudGFyZ2V0Lm5vZGVUeXBlID09PSAzICkge1xuXHRcdFx0ZXZlbnQudGFyZ2V0ID0gZXZlbnQudGFyZ2V0LnBhcmVudE5vZGU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZpeEhvb2suZmlsdGVyID8gZml4SG9vay5maWx0ZXIoIGV2ZW50LCBvcmlnaW5hbEV2ZW50ICkgOiBldmVudDtcblx0fSxcblxuXHRzcGVjaWFsOiB7XG5cdFx0bG9hZDoge1xuXHRcdFx0Ly8gUHJldmVudCB0cmlnZ2VyZWQgaW1hZ2UubG9hZCBldmVudHMgZnJvbSBidWJibGluZyB0byB3aW5kb3cubG9hZFxuXHRcdFx0bm9CdWJibGU6IHRydWVcblx0XHR9LFxuXHRcdGZvY3VzOiB7XG5cdFx0XHQvLyBGaXJlIG5hdGl2ZSBldmVudCBpZiBwb3NzaWJsZSBzbyBibHVyL2ZvY3VzIHNlcXVlbmNlIGlzIGNvcnJlY3Rcblx0XHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIHRoaXMgIT09IHNhZmVBY3RpdmVFbGVtZW50KCkgJiYgdGhpcy5mb2N1cyApIHtcblx0XHRcdFx0XHR0aGlzLmZvY3VzKCk7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0ZGVsZWdhdGVUeXBlOiBcImZvY3VzaW5cIlxuXHRcdH0sXG5cdFx0Ymx1cjoge1xuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggdGhpcyA9PT0gc2FmZUFjdGl2ZUVsZW1lbnQoKSAmJiB0aGlzLmJsdXIgKSB7XG5cdFx0XHRcdFx0dGhpcy5ibHVyKCk7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0ZGVsZWdhdGVUeXBlOiBcImZvY3Vzb3V0XCJcblx0XHR9LFxuXHRcdGNsaWNrOiB7XG5cdFx0XHQvLyBGb3IgY2hlY2tib3gsIGZpcmUgbmF0aXZlIGV2ZW50IHNvIGNoZWNrZWQgc3RhdGUgd2lsbCBiZSByaWdodFxuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggdGhpcy50eXBlID09PSBcImNoZWNrYm94XCIgJiYgdGhpcy5jbGljayAmJiBqUXVlcnkubm9kZU5hbWUoIHRoaXMsIFwiaW5wdXRcIiApICkge1xuXHRcdFx0XHRcdHRoaXMuY2xpY2soKTtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cblx0XHRcdC8vIEZvciBjcm9zcy1icm93c2VyIGNvbnNpc3RlbmN5LCBkb24ndCBmaXJlIG5hdGl2ZSAuY2xpY2soKSBvbiBsaW5rc1xuXHRcdFx0X2RlZmF1bHQ6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0cmV0dXJuIGpRdWVyeS5ub2RlTmFtZSggZXZlbnQudGFyZ2V0LCBcImFcIiApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRiZWZvcmV1bmxvYWQ6IHtcblx0XHRcdHBvc3REaXNwYXRjaDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggMjArXG5cdFx0XHRcdC8vIEZpcmVmb3ggZG9lc24ndCBhbGVydCBpZiB0aGUgcmV0dXJuVmFsdWUgZmllbGQgaXMgbm90IHNldC5cblx0XHRcdFx0aWYgKCBldmVudC5yZXN1bHQgIT09IHVuZGVmaW5lZCAmJiBldmVudC5vcmlnaW5hbEV2ZW50ICkge1xuXHRcdFx0XHRcdGV2ZW50Lm9yaWdpbmFsRXZlbnQucmV0dXJuVmFsdWUgPSBldmVudC5yZXN1bHQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0c2ltdWxhdGU6IGZ1bmN0aW9uKCB0eXBlLCBlbGVtLCBldmVudCwgYnViYmxlICkge1xuXHRcdC8vIFBpZ2d5YmFjayBvbiBhIGRvbm9yIGV2ZW50IHRvIHNpbXVsYXRlIGEgZGlmZmVyZW50IG9uZS5cblx0XHQvLyBGYWtlIG9yaWdpbmFsRXZlbnQgdG8gYXZvaWQgZG9ub3IncyBzdG9wUHJvcGFnYXRpb24sIGJ1dCBpZiB0aGVcblx0XHQvLyBzaW11bGF0ZWQgZXZlbnQgcHJldmVudHMgZGVmYXVsdCB0aGVuIHdlIGRvIHRoZSBzYW1lIG9uIHRoZSBkb25vci5cblx0XHR2YXIgZSA9IGpRdWVyeS5leHRlbmQoXG5cdFx0XHRuZXcgalF1ZXJ5LkV2ZW50KCksXG5cdFx0XHRldmVudCxcblx0XHRcdHtcblx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0aXNTaW11bGF0ZWQ6IHRydWUsXG5cdFx0XHRcdG9yaWdpbmFsRXZlbnQ6IHt9XG5cdFx0XHR9XG5cdFx0KTtcblx0XHRpZiAoIGJ1YmJsZSApIHtcblx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKCBlLCBudWxsLCBlbGVtICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGpRdWVyeS5ldmVudC5kaXNwYXRjaC5jYWxsKCBlbGVtLCBlICk7XG5cdFx0fVxuXHRcdGlmICggZS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSApIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9XG59O1xuXG5qUXVlcnkucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiggZWxlbSwgdHlwZSwgaGFuZGxlICkge1xuXHRpZiAoIGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciApIHtcblx0XHRlbGVtLnJlbW92ZUV2ZW50TGlzdGVuZXIoIHR5cGUsIGhhbmRsZSwgZmFsc2UgKTtcblx0fVxufTtcblxualF1ZXJ5LkV2ZW50ID0gZnVuY3Rpb24oIHNyYywgcHJvcHMgKSB7XG5cdC8vIEFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCB0aGUgJ25ldycga2V5d29yZFxuXHRpZiAoICEodGhpcyBpbnN0YW5jZW9mIGpRdWVyeS5FdmVudCkgKSB7XG5cdFx0cmV0dXJuIG5ldyBqUXVlcnkuRXZlbnQoIHNyYywgcHJvcHMgKTtcblx0fVxuXG5cdC8vIEV2ZW50IG9iamVjdFxuXHRpZiAoIHNyYyAmJiBzcmMudHlwZSApIHtcblx0XHR0aGlzLm9yaWdpbmFsRXZlbnQgPSBzcmM7XG5cdFx0dGhpcy50eXBlID0gc3JjLnR5cGU7XG5cblx0XHQvLyBFdmVudHMgYnViYmxpbmcgdXAgdGhlIGRvY3VtZW50IG1heSBoYXZlIGJlZW4gbWFya2VkIGFzIHByZXZlbnRlZFxuXHRcdC8vIGJ5IGEgaGFuZGxlciBsb3dlciBkb3duIHRoZSB0cmVlOyByZWZsZWN0IHRoZSBjb3JyZWN0IHZhbHVlLlxuXHRcdHRoaXMuaXNEZWZhdWx0UHJldmVudGVkID0gc3JjLmRlZmF1bHRQcmV2ZW50ZWQgfHxcblx0XHRcdFx0c3JjLmRlZmF1bHRQcmV2ZW50ZWQgPT09IHVuZGVmaW5lZCAmJlxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDwgNC4wXG5cdFx0XHRcdHNyYy5yZXR1cm5WYWx1ZSA9PT0gZmFsc2UgP1xuXHRcdFx0cmV0dXJuVHJ1ZSA6XG5cdFx0XHRyZXR1cm5GYWxzZTtcblxuXHQvLyBFdmVudCB0eXBlXG5cdH0gZWxzZSB7XG5cdFx0dGhpcy50eXBlID0gc3JjO1xuXHR9XG5cblx0Ly8gUHV0IGV4cGxpY2l0bHkgcHJvdmlkZWQgcHJvcGVydGllcyBvbnRvIHRoZSBldmVudCBvYmplY3Rcblx0aWYgKCBwcm9wcyApIHtcblx0XHRqUXVlcnkuZXh0ZW5kKCB0aGlzLCBwcm9wcyApO1xuXHR9XG5cblx0Ly8gQ3JlYXRlIGEgdGltZXN0YW1wIGlmIGluY29taW5nIGV2ZW50IGRvZXNuJ3QgaGF2ZSBvbmVcblx0dGhpcy50aW1lU3RhbXAgPSBzcmMgJiYgc3JjLnRpbWVTdGFtcCB8fCBqUXVlcnkubm93KCk7XG5cblx0Ly8gTWFyayBpdCBhcyBmaXhlZFxuXHR0aGlzWyBqUXVlcnkuZXhwYW5kbyBdID0gdHJ1ZTtcbn07XG5cbi8vIGpRdWVyeS5FdmVudCBpcyBiYXNlZCBvbiBET00zIEV2ZW50cyBhcyBzcGVjaWZpZWQgYnkgdGhlIEVDTUFTY3JpcHQgTGFuZ3VhZ2UgQmluZGluZ1xuLy8gaHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9XRC1ET00tTGV2ZWwtMy1FdmVudHMtMjAwMzAzMzEvZWNtYS1zY3JpcHQtYmluZGluZy5odG1sXG5qUXVlcnkuRXZlbnQucHJvdG90eXBlID0ge1xuXHRpc0RlZmF1bHRQcmV2ZW50ZWQ6IHJldHVybkZhbHNlLFxuXHRpc1Byb3BhZ2F0aW9uU3RvcHBlZDogcmV0dXJuRmFsc2UsXG5cdGlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOiByZXR1cm5GYWxzZSxcblxuXHRwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgZS5wcmV2ZW50RGVmYXVsdCApIHtcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cdH0sXG5cdHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gcmV0dXJuVHJ1ZTtcblxuXHRcdGlmICggZSAmJiBlLnN0b3BQcm9wYWdhdGlvbiApIHtcblx0XHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0fVxuXHR9LFxuXHRzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gKSB7XG5cdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdH1cblxuXHRcdHRoaXMuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdH1cbn07XG5cbi8vIENyZWF0ZSBtb3VzZWVudGVyL2xlYXZlIGV2ZW50cyB1c2luZyBtb3VzZW92ZXIvb3V0IGFuZCBldmVudC10aW1lIGNoZWNrc1xuLy8gU3VwcG9ydDogQ2hyb21lIDE1K1xualF1ZXJ5LmVhY2goe1xuXHRtb3VzZWVudGVyOiBcIm1vdXNlb3ZlclwiLFxuXHRtb3VzZWxlYXZlOiBcIm1vdXNlb3V0XCIsXG5cdHBvaW50ZXJlbnRlcjogXCJwb2ludGVyb3ZlclwiLFxuXHRwb2ludGVybGVhdmU6IFwicG9pbnRlcm91dFwiXG59LCBmdW5jdGlvbiggb3JpZywgZml4ICkge1xuXHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgb3JpZyBdID0ge1xuXHRcdGRlbGVnYXRlVHlwZTogZml4LFxuXHRcdGJpbmRUeXBlOiBmaXgsXG5cblx0XHRoYW5kbGU6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdHZhciByZXQsXG5cdFx0XHRcdHRhcmdldCA9IHRoaXMsXG5cdFx0XHRcdHJlbGF0ZWQgPSBldmVudC5yZWxhdGVkVGFyZ2V0LFxuXHRcdFx0XHRoYW5kbGVPYmogPSBldmVudC5oYW5kbGVPYmo7XG5cblx0XHRcdC8vIEZvciBtb3VzZW50ZXIvbGVhdmUgY2FsbCB0aGUgaGFuZGxlciBpZiByZWxhdGVkIGlzIG91dHNpZGUgdGhlIHRhcmdldC5cblx0XHRcdC8vIE5COiBObyByZWxhdGVkVGFyZ2V0IGlmIHRoZSBtb3VzZSBsZWZ0L2VudGVyZWQgdGhlIGJyb3dzZXIgd2luZG93XG5cdFx0XHRpZiAoICFyZWxhdGVkIHx8IChyZWxhdGVkICE9PSB0YXJnZXQgJiYgIWpRdWVyeS5jb250YWlucyggdGFyZ2V0LCByZWxhdGVkICkpICkge1xuXHRcdFx0XHRldmVudC50eXBlID0gaGFuZGxlT2JqLm9yaWdUeXBlO1xuXHRcdFx0XHRyZXQgPSBoYW5kbGVPYmouaGFuZGxlci5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdGV2ZW50LnR5cGUgPSBmaXg7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH1cblx0fTtcbn0pO1xuXG4vLyBDcmVhdGUgXCJidWJibGluZ1wiIGZvY3VzIGFuZCBibHVyIGV2ZW50c1xuLy8gU3VwcG9ydDogRmlyZWZveCwgQ2hyb21lLCBTYWZhcmlcbmlmICggIXN1cHBvcnQuZm9jdXNpbkJ1YmJsZXMgKSB7XG5cdGpRdWVyeS5lYWNoKHsgZm9jdXM6IFwiZm9jdXNpblwiLCBibHVyOiBcImZvY3Vzb3V0XCIgfSwgZnVuY3Rpb24oIG9yaWcsIGZpeCApIHtcblxuXHRcdC8vIEF0dGFjaCBhIHNpbmdsZSBjYXB0dXJpbmcgaGFuZGxlciBvbiB0aGUgZG9jdW1lbnQgd2hpbGUgc29tZW9uZSB3YW50cyBmb2N1c2luL2ZvY3Vzb3V0XG5cdFx0dmFyIGhhbmRsZXIgPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdGpRdWVyeS5ldmVudC5zaW11bGF0ZSggZml4LCBldmVudC50YXJnZXQsIGpRdWVyeS5ldmVudC5maXgoIGV2ZW50ICksIHRydWUgKTtcblx0XHRcdH07XG5cblx0XHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgZml4IF0gPSB7XG5cdFx0XHRzZXR1cDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBkb2MgPSB0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcyxcblx0XHRcdFx0XHRhdHRhY2hlcyA9IGRhdGFfcHJpdi5hY2Nlc3MoIGRvYywgZml4ICk7XG5cblx0XHRcdFx0aWYgKCAhYXR0YWNoZXMgKSB7XG5cdFx0XHRcdFx0ZG9jLmFkZEV2ZW50TGlzdGVuZXIoIG9yaWcsIGhhbmRsZXIsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkYXRhX3ByaXYuYWNjZXNzKCBkb2MsIGZpeCwgKCBhdHRhY2hlcyB8fCAwICkgKyAxICk7XG5cdFx0XHR9LFxuXHRcdFx0dGVhcmRvd246IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZG9jID0gdGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMsXG5cdFx0XHRcdFx0YXR0YWNoZXMgPSBkYXRhX3ByaXYuYWNjZXNzKCBkb2MsIGZpeCApIC0gMTtcblxuXHRcdFx0XHRpZiAoICFhdHRhY2hlcyApIHtcblx0XHRcdFx0XHRkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lciggb3JpZywgaGFuZGxlciwgdHJ1ZSApO1xuXHRcdFx0XHRcdGRhdGFfcHJpdi5yZW1vdmUoIGRvYywgZml4ICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkYXRhX3ByaXYuYWNjZXNzKCBkb2MsIGZpeCwgYXR0YWNoZXMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cdH0pO1xufVxuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblxuXHRvbjogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIC8qSU5URVJOQUwqLyBvbmUgKSB7XG5cdFx0dmFyIG9yaWdGbiwgdHlwZTtcblxuXHRcdC8vIFR5cGVzIGNhbiBiZSBhIG1hcCBvZiB0eXBlcy9oYW5kbGVyc1xuXHRcdGlmICggdHlwZW9mIHR5cGVzID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0Ly8gKCB0eXBlcy1PYmplY3QsIHNlbGVjdG9yLCBkYXRhIClcblx0XHRcdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0XHQvLyAoIHR5cGVzLU9iamVjdCwgZGF0YSApXG5cdFx0XHRcdGRhdGEgPSBkYXRhIHx8IHNlbGVjdG9yO1xuXHRcdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGZvciAoIHR5cGUgaW4gdHlwZXMgKSB7XG5cdFx0XHRcdHRoaXMub24oIHR5cGUsIHNlbGVjdG9yLCBkYXRhLCB0eXBlc1sgdHlwZSBdLCBvbmUgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdGlmICggZGF0YSA9PSBudWxsICYmIGZuID09IG51bGwgKSB7XG5cdFx0XHQvLyAoIHR5cGVzLCBmbiApXG5cdFx0XHRmbiA9IHNlbGVjdG9yO1xuXHRcdFx0ZGF0YSA9IHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdH0gZWxzZSBpZiAoIGZuID09IG51bGwgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0Ly8gKCB0eXBlcywgc2VsZWN0b3IsIGZuIClcblx0XHRcdFx0Zm4gPSBkYXRhO1xuXHRcdFx0XHRkYXRhID0gdW5kZWZpbmVkO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gKCB0eXBlcywgZGF0YSwgZm4gKVxuXHRcdFx0XHRmbiA9IGRhdGE7XG5cdFx0XHRcdGRhdGEgPSBzZWxlY3Rvcjtcblx0XHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICggZm4gPT09IGZhbHNlICkge1xuXHRcdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0XHR9IGVsc2UgaWYgKCAhZm4gKSB7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cblx0XHRpZiAoIG9uZSA9PT0gMSApIHtcblx0XHRcdG9yaWdGbiA9IGZuO1xuXHRcdFx0Zm4gPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdC8vIENhbiB1c2UgYW4gZW1wdHkgc2V0LCBzaW5jZSBldmVudCBjb250YWlucyB0aGUgaW5mb1xuXHRcdFx0XHRqUXVlcnkoKS5vZmYoIGV2ZW50ICk7XG5cdFx0XHRcdHJldHVybiBvcmlnRm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0fTtcblx0XHRcdC8vIFVzZSBzYW1lIGd1aWQgc28gY2FsbGVyIGNhbiByZW1vdmUgdXNpbmcgb3JpZ0ZuXG5cdFx0XHRmbi5ndWlkID0gb3JpZ0ZuLmd1aWQgfHwgKCBvcmlnRm4uZ3VpZCA9IGpRdWVyeS5ndWlkKysgKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQuYWRkKCB0aGlzLCB0eXBlcywgZm4sIGRhdGEsIHNlbGVjdG9yICk7XG5cdFx0fSk7XG5cdH0sXG5cdG9uZTogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIDEgKTtcblx0fSxcblx0b2ZmOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBmbiApIHtcblx0XHR2YXIgaGFuZGxlT2JqLCB0eXBlO1xuXHRcdGlmICggdHlwZXMgJiYgdHlwZXMucHJldmVudERlZmF1bHQgJiYgdHlwZXMuaGFuZGxlT2JqICkge1xuXHRcdFx0Ly8gKCBldmVudCApICBkaXNwYXRjaGVkIGpRdWVyeS5FdmVudFxuXHRcdFx0aGFuZGxlT2JqID0gdHlwZXMuaGFuZGxlT2JqO1xuXHRcdFx0alF1ZXJ5KCB0eXBlcy5kZWxlZ2F0ZVRhcmdldCApLm9mZihcblx0XHRcdFx0aGFuZGxlT2JqLm5hbWVzcGFjZSA/IGhhbmRsZU9iai5vcmlnVHlwZSArIFwiLlwiICsgaGFuZGxlT2JqLm5hbWVzcGFjZSA6IGhhbmRsZU9iai5vcmlnVHlwZSxcblx0XHRcdFx0aGFuZGxlT2JqLnNlbGVjdG9yLFxuXHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlclxuXHRcdFx0KTtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblx0XHRpZiAoIHR5cGVvZiB0eXBlcyA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdC8vICggdHlwZXMtb2JqZWN0IFssIHNlbGVjdG9yXSApXG5cdFx0XHRmb3IgKCB0eXBlIGluIHR5cGVzICkge1xuXHRcdFx0XHR0aGlzLm9mZiggdHlwZSwgc2VsZWN0b3IsIHR5cGVzWyB0eXBlIF0gKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblx0XHRpZiAoIHNlbGVjdG9yID09PSBmYWxzZSB8fCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwiZnVuY3Rpb25cIiApIHtcblx0XHRcdC8vICggdHlwZXMgWywgZm5dIClcblx0XHRcdGZuID0gc2VsZWN0b3I7XG5cdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0aWYgKCBmbiA9PT0gZmFsc2UgKSB7XG5cdFx0XHRmbiA9IHJldHVybkZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggdGhpcywgdHlwZXMsIGZuLCBzZWxlY3RvciApO1xuXHRcdH0pO1xuXHR9LFxuXG5cdHRyaWdnZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggdHlwZSwgZGF0YSwgdGhpcyApO1xuXHRcdH0pO1xuXHR9LFxuXHR0cmlnZ2VySGFuZGxlcjogZnVuY3Rpb24oIHR5cGUsIGRhdGEgKSB7XG5cdFx0dmFyIGVsZW0gPSB0aGlzWzBdO1xuXHRcdGlmICggZWxlbSApIHtcblx0XHRcdHJldHVybiBqUXVlcnkuZXZlbnQudHJpZ2dlciggdHlwZSwgZGF0YSwgZWxlbSwgdHJ1ZSApO1xuXHRcdH1cblx0fVxufSk7XG5cblxudmFyXG5cdHJ4aHRtbFRhZyA9IC88KD8hYXJlYXxicnxjb2x8ZW1iZWR8aHJ8aW1nfGlucHV0fGxpbmt8bWV0YXxwYXJhbSkoKFtcXHc6XSspW14+XSopXFwvPi9naSxcblx0cnRhZ05hbWUgPSAvPChbXFx3Ol0rKS8sXG5cdHJodG1sID0gLzx8JiM/XFx3KzsvLFxuXHRybm9Jbm5lcmh0bWwgPSAvPCg/OnNjcmlwdHxzdHlsZXxsaW5rKS9pLFxuXHQvLyBjaGVja2VkPVwiY2hlY2tlZFwiIG9yIGNoZWNrZWRcblx0cmNoZWNrZWQgPSAvY2hlY2tlZFxccyooPzpbXj1dfD1cXHMqLmNoZWNrZWQuKS9pLFxuXHRyc2NyaXB0VHlwZSA9IC9eJHxcXC8oPzpqYXZhfGVjbWEpc2NyaXB0L2ksXG5cdHJzY3JpcHRUeXBlTWFza2VkID0gL150cnVlXFwvKC4qKS8sXG5cdHJjbGVhblNjcmlwdCA9IC9eXFxzKjwhKD86XFxbQ0RBVEFcXFt8LS0pfCg/OlxcXVxcXXwtLSk+XFxzKiQvZyxcblxuXHQvLyBXZSBoYXZlIHRvIGNsb3NlIHRoZXNlIHRhZ3MgdG8gc3VwcG9ydCBYSFRNTCAoIzEzMjAwKVxuXHR3cmFwTWFwID0ge1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgOVxuXHRcdG9wdGlvbjogWyAxLCBcIjxzZWxlY3QgbXVsdGlwbGU9J211bHRpcGxlJz5cIiwgXCI8L3NlbGVjdD5cIiBdLFxuXG5cdFx0dGhlYWQ6IFsgMSwgXCI8dGFibGU+XCIsIFwiPC90YWJsZT5cIiBdLFxuXHRcdGNvbDogWyAyLCBcIjx0YWJsZT48Y29sZ3JvdXA+XCIsIFwiPC9jb2xncm91cD48L3RhYmxlPlwiIF0sXG5cdFx0dHI6IFsgMiwgXCI8dGFibGU+PHRib2R5PlwiLCBcIjwvdGJvZHk+PC90YWJsZT5cIiBdLFxuXHRcdHRkOiBbIDMsIFwiPHRhYmxlPjx0Ym9keT48dHI+XCIsIFwiPC90cj48L3Rib2R5PjwvdGFibGU+XCIgXSxcblxuXHRcdF9kZWZhdWx0OiBbIDAsIFwiXCIsIFwiXCIgXVxuXHR9O1xuXG4vLyBTdXBwb3J0OiBJRSA5XG53cmFwTWFwLm9wdGdyb3VwID0gd3JhcE1hcC5vcHRpb247XG5cbndyYXBNYXAudGJvZHkgPSB3cmFwTWFwLnRmb290ID0gd3JhcE1hcC5jb2xncm91cCA9IHdyYXBNYXAuY2FwdGlvbiA9IHdyYXBNYXAudGhlYWQ7XG53cmFwTWFwLnRoID0gd3JhcE1hcC50ZDtcblxuLy8gU3VwcG9ydDogMS54IGNvbXBhdGliaWxpdHlcbi8vIE1hbmlwdWxhdGluZyB0YWJsZXMgcmVxdWlyZXMgYSB0Ym9keVxuZnVuY3Rpb24gbWFuaXB1bGF0aW9uVGFyZ2V0KCBlbGVtLCBjb250ZW50ICkge1xuXHRyZXR1cm4galF1ZXJ5Lm5vZGVOYW1lKCBlbGVtLCBcInRhYmxlXCIgKSAmJlxuXHRcdGpRdWVyeS5ub2RlTmFtZSggY29udGVudC5ub2RlVHlwZSAhPT0gMTEgPyBjb250ZW50IDogY29udGVudC5maXJzdENoaWxkLCBcInRyXCIgKSA/XG5cblx0XHRlbGVtLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwidGJvZHlcIilbMF0gfHxcblx0XHRcdGVsZW0uYXBwZW5kQ2hpbGQoIGVsZW0ub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGJvZHlcIikgKSA6XG5cdFx0ZWxlbTtcbn1cblxuLy8gUmVwbGFjZS9yZXN0b3JlIHRoZSB0eXBlIGF0dHJpYnV0ZSBvZiBzY3JpcHQgZWxlbWVudHMgZm9yIHNhZmUgRE9NIG1hbmlwdWxhdGlvblxuZnVuY3Rpb24gZGlzYWJsZVNjcmlwdCggZWxlbSApIHtcblx0ZWxlbS50eXBlID0gKGVsZW0uZ2V0QXR0cmlidXRlKFwidHlwZVwiKSAhPT0gbnVsbCkgKyBcIi9cIiArIGVsZW0udHlwZTtcblx0cmV0dXJuIGVsZW07XG59XG5mdW5jdGlvbiByZXN0b3JlU2NyaXB0KCBlbGVtICkge1xuXHR2YXIgbWF0Y2ggPSByc2NyaXB0VHlwZU1hc2tlZC5leGVjKCBlbGVtLnR5cGUgKTtcblxuXHRpZiAoIG1hdGNoICkge1xuXHRcdGVsZW0udHlwZSA9IG1hdGNoWyAxIF07XG5cdH0gZWxzZSB7XG5cdFx0ZWxlbS5yZW1vdmVBdHRyaWJ1dGUoXCJ0eXBlXCIpO1xuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbi8vIE1hcmsgc2NyaXB0cyBhcyBoYXZpbmcgYWxyZWFkeSBiZWVuIGV2YWx1YXRlZFxuZnVuY3Rpb24gc2V0R2xvYmFsRXZhbCggZWxlbXMsIHJlZkVsZW1lbnRzICkge1xuXHR2YXIgaSA9IDAsXG5cdFx0bCA9IGVsZW1zLmxlbmd0aDtcblxuXHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0ZGF0YV9wcml2LnNldChcblx0XHRcdGVsZW1zWyBpIF0sIFwiZ2xvYmFsRXZhbFwiLCAhcmVmRWxlbWVudHMgfHwgZGF0YV9wcml2LmdldCggcmVmRWxlbWVudHNbIGkgXSwgXCJnbG9iYWxFdmFsXCIgKVxuXHRcdCk7XG5cdH1cbn1cblxuZnVuY3Rpb24gY2xvbmVDb3B5RXZlbnQoIHNyYywgZGVzdCApIHtcblx0dmFyIGksIGwsIHR5cGUsIHBkYXRhT2xkLCBwZGF0YUN1ciwgdWRhdGFPbGQsIHVkYXRhQ3VyLCBldmVudHM7XG5cblx0aWYgKCBkZXN0Lm5vZGVUeXBlICE9PSAxICkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIDEuIENvcHkgcHJpdmF0ZSBkYXRhOiBldmVudHMsIGhhbmRsZXJzLCBldGMuXG5cdGlmICggZGF0YV9wcml2Lmhhc0RhdGEoIHNyYyApICkge1xuXHRcdHBkYXRhT2xkID0gZGF0YV9wcml2LmFjY2Vzcyggc3JjICk7XG5cdFx0cGRhdGFDdXIgPSBkYXRhX3ByaXYuc2V0KCBkZXN0LCBwZGF0YU9sZCApO1xuXHRcdGV2ZW50cyA9IHBkYXRhT2xkLmV2ZW50cztcblxuXHRcdGlmICggZXZlbnRzICkge1xuXHRcdFx0ZGVsZXRlIHBkYXRhQ3VyLmhhbmRsZTtcblx0XHRcdHBkYXRhQ3VyLmV2ZW50cyA9IHt9O1xuXG5cdFx0XHRmb3IgKCB0eXBlIGluIGV2ZW50cyApIHtcblx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSBldmVudHNbIHR5cGUgXS5sZW5ndGg7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LmFkZCggZGVzdCwgdHlwZSwgZXZlbnRzWyB0eXBlIF1bIGkgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gMi4gQ29weSB1c2VyIGRhdGFcblx0aWYgKCBkYXRhX3VzZXIuaGFzRGF0YSggc3JjICkgKSB7XG5cdFx0dWRhdGFPbGQgPSBkYXRhX3VzZXIuYWNjZXNzKCBzcmMgKTtcblx0XHR1ZGF0YUN1ciA9IGpRdWVyeS5leHRlbmQoIHt9LCB1ZGF0YU9sZCApO1xuXG5cdFx0ZGF0YV91c2VyLnNldCggZGVzdCwgdWRhdGFDdXIgKTtcblx0fVxufVxuXG5mdW5jdGlvbiBnZXRBbGwoIGNvbnRleHQsIHRhZyApIHtcblx0dmFyIHJldCA9IGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgPyBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCB0YWcgfHwgXCIqXCIgKSA6XG5cdFx0XHRjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwgPyBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIHRhZyB8fCBcIipcIiApIDpcblx0XHRcdFtdO1xuXG5cdHJldHVybiB0YWcgPT09IHVuZGVmaW5lZCB8fCB0YWcgJiYgalF1ZXJ5Lm5vZGVOYW1lKCBjb250ZXh0LCB0YWcgKSA/XG5cdFx0alF1ZXJ5Lm1lcmdlKCBbIGNvbnRleHQgXSwgcmV0ICkgOlxuXHRcdHJldDtcbn1cblxuLy8gU3VwcG9ydDogSUUgPj0gOVxuZnVuY3Rpb24gZml4SW5wdXQoIHNyYywgZGVzdCApIHtcblx0dmFyIG5vZGVOYW1lID0gZGVzdC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXG5cdC8vIEZhaWxzIHRvIHBlcnNpc3QgdGhlIGNoZWNrZWQgc3RhdGUgb2YgYSBjbG9uZWQgY2hlY2tib3ggb3IgcmFkaW8gYnV0dG9uLlxuXHRpZiAoIG5vZGVOYW1lID09PSBcImlucHV0XCIgJiYgcmNoZWNrYWJsZVR5cGUudGVzdCggc3JjLnR5cGUgKSApIHtcblx0XHRkZXN0LmNoZWNrZWQgPSBzcmMuY2hlY2tlZDtcblxuXHQvLyBGYWlscyB0byByZXR1cm4gdGhlIHNlbGVjdGVkIG9wdGlvbiB0byB0aGUgZGVmYXVsdCBzZWxlY3RlZCBzdGF0ZSB3aGVuIGNsb25pbmcgb3B0aW9uc1xuXHR9IGVsc2UgaWYgKCBub2RlTmFtZSA9PT0gXCJpbnB1dFwiIHx8IG5vZGVOYW1lID09PSBcInRleHRhcmVhXCIgKSB7XG5cdFx0ZGVzdC5kZWZhdWx0VmFsdWUgPSBzcmMuZGVmYXVsdFZhbHVlO1xuXHR9XG59XG5cbmpRdWVyeS5leHRlbmQoe1xuXHRjbG9uZTogZnVuY3Rpb24oIGVsZW0sIGRhdGFBbmRFdmVudHMsIGRlZXBEYXRhQW5kRXZlbnRzICkge1xuXHRcdHZhciBpLCBsLCBzcmNFbGVtZW50cywgZGVzdEVsZW1lbnRzLFxuXHRcdFx0Y2xvbmUgPSBlbGVtLmNsb25lTm9kZSggdHJ1ZSApLFxuXHRcdFx0aW5QYWdlID0galF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKTtcblxuXHRcdC8vIFN1cHBvcnQ6IElFID49IDlcblx0XHQvLyBGaXggQ2xvbmluZyBpc3N1ZXNcblx0XHRpZiAoICFzdXBwb3J0Lm5vQ2xvbmVDaGVja2VkICYmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBlbGVtLm5vZGVUeXBlID09PSAxMSApICYmXG5cdFx0XHRcdCFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKSApIHtcblxuXHRcdFx0Ly8gV2UgZXNjaGV3IFNpenpsZSBoZXJlIGZvciBwZXJmb3JtYW5jZSByZWFzb25zOiBodHRwOi8vanNwZXJmLmNvbS9nZXRhbGwtdnMtc2l6emxlLzJcblx0XHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUgKTtcblx0XHRcdHNyY0VsZW1lbnRzID0gZ2V0QWxsKCBlbGVtICk7XG5cblx0XHRcdGZvciAoIGkgPSAwLCBsID0gc3JjRWxlbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRmaXhJbnB1dCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDb3B5IHRoZSBldmVudHMgZnJvbSB0aGUgb3JpZ2luYWwgdG8gdGhlIGNsb25lXG5cdFx0aWYgKCBkYXRhQW5kRXZlbnRzICkge1xuXHRcdFx0aWYgKCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHRcdFx0c3JjRWxlbWVudHMgPSBzcmNFbGVtZW50cyB8fCBnZXRBbGwoIGVsZW0gKTtcblx0XHRcdFx0ZGVzdEVsZW1lbnRzID0gZGVzdEVsZW1lbnRzIHx8IGdldEFsbCggY2xvbmUgKTtcblxuXHRcdFx0XHRmb3IgKCBpID0gMCwgbCA9IHNyY0VsZW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRjbG9uZUNvcHlFdmVudCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2xvbmVDb3B5RXZlbnQoIGVsZW0sIGNsb25lICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUHJlc2VydmUgc2NyaXB0IGV2YWx1YXRpb24gaGlzdG9yeVxuXHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUsIFwic2NyaXB0XCIgKTtcblx0XHRpZiAoIGRlc3RFbGVtZW50cy5sZW5ndGggPiAwICkge1xuXHRcdFx0c2V0R2xvYmFsRXZhbCggZGVzdEVsZW1lbnRzLCAhaW5QYWdlICYmIGdldEFsbCggZWxlbSwgXCJzY3JpcHRcIiApICk7XG5cdFx0fVxuXG5cdFx0Ly8gUmV0dXJuIHRoZSBjbG9uZWQgc2V0XG5cdFx0cmV0dXJuIGNsb25lO1xuXHR9LFxuXG5cdGJ1aWxkRnJhZ21lbnQ6IGZ1bmN0aW9uKCBlbGVtcywgY29udGV4dCwgc2NyaXB0cywgc2VsZWN0aW9uICkge1xuXHRcdHZhciBlbGVtLCB0bXAsIHRhZywgd3JhcCwgY29udGFpbnMsIGosXG5cdFx0XHRmcmFnbWVudCA9IGNvbnRleHQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxuXHRcdFx0bm9kZXMgPSBbXSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bCA9IGVsZW1zLmxlbmd0aDtcblxuXHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdGVsZW0gPSBlbGVtc1sgaSBdO1xuXG5cdFx0XHRpZiAoIGVsZW0gfHwgZWxlbSA9PT0gMCApIHtcblxuXHRcdFx0XHQvLyBBZGQgbm9kZXMgZGlyZWN0bHlcblx0XHRcdFx0aWYgKCBqUXVlcnkudHlwZSggZWxlbSApID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFF0V2ViS2l0XG5cdFx0XHRcdFx0Ly8galF1ZXJ5Lm1lcmdlIGJlY2F1c2UgcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93c1xuXHRcdFx0XHRcdGpRdWVyeS5tZXJnZSggbm9kZXMsIGVsZW0ubm9kZVR5cGUgPyBbIGVsZW0gXSA6IGVsZW0gKTtcblxuXHRcdFx0XHQvLyBDb252ZXJ0IG5vbi1odG1sIGludG8gYSB0ZXh0IG5vZGVcblx0XHRcdFx0fSBlbHNlIGlmICggIXJodG1sLnRlc3QoIGVsZW0gKSApIHtcblx0XHRcdFx0XHRub2Rlcy5wdXNoKCBjb250ZXh0LmNyZWF0ZVRleHROb2RlKCBlbGVtICkgKTtcblxuXHRcdFx0XHQvLyBDb252ZXJ0IGh0bWwgaW50byBET00gbm9kZXNcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0bXAgPSB0bXAgfHwgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGNvbnRleHQuY3JlYXRlRWxlbWVudChcImRpdlwiKSApO1xuXG5cdFx0XHRcdFx0Ly8gRGVzZXJpYWxpemUgYSBzdGFuZGFyZCByZXByZXNlbnRhdGlvblxuXHRcdFx0XHRcdHRhZyA9ICggcnRhZ05hbWUuZXhlYyggZWxlbSApIHx8IFsgXCJcIiwgXCJcIiBdIClbIDEgXS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdHdyYXAgPSB3cmFwTWFwWyB0YWcgXSB8fCB3cmFwTWFwLl9kZWZhdWx0O1xuXHRcdFx0XHRcdHRtcC5pbm5lckhUTUwgPSB3cmFwWyAxIF0gKyBlbGVtLnJlcGxhY2UoIHJ4aHRtbFRhZywgXCI8JDE+PC8kMj5cIiApICsgd3JhcFsgMiBdO1xuXG5cdFx0XHRcdFx0Ly8gRGVzY2VuZCB0aHJvdWdoIHdyYXBwZXJzIHRvIHRoZSByaWdodCBjb250ZW50XG5cdFx0XHRcdFx0aiA9IHdyYXBbIDAgXTtcblx0XHRcdFx0XHR3aGlsZSAoIGotLSApIHtcblx0XHRcdFx0XHRcdHRtcCA9IHRtcC5sYXN0Q2hpbGQ7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogUXRXZWJLaXRcblx0XHRcdFx0XHQvLyBqUXVlcnkubWVyZ2UgYmVjYXVzZSBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzXG5cdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgdG1wLmNoaWxkTm9kZXMgKTtcblxuXHRcdFx0XHRcdC8vIFJlbWVtYmVyIHRoZSB0b3AtbGV2ZWwgY29udGFpbmVyXG5cdFx0XHRcdFx0dG1wID0gZnJhZ21lbnQuZmlyc3RDaGlsZDtcblxuXHRcdFx0XHRcdC8vIEZpeGVzICMxMjM0NlxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFdlYmtpdCwgSUVcblx0XHRcdFx0XHR0bXAudGV4dENvbnRlbnQgPSBcIlwiO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUmVtb3ZlIHdyYXBwZXIgZnJvbSBmcmFnbWVudFxuXHRcdGZyYWdtZW50LnRleHRDb250ZW50ID0gXCJcIjtcblxuXHRcdGkgPSAwO1xuXHRcdHdoaWxlICggKGVsZW0gPSBub2Rlc1sgaSsrIF0pICkge1xuXG5cdFx0XHQvLyAjNDA4NyAtIElmIG9yaWdpbiBhbmQgZGVzdGluYXRpb24gZWxlbWVudHMgYXJlIHRoZSBzYW1lLCBhbmQgdGhpcyBpc1xuXHRcdFx0Ly8gdGhhdCBlbGVtZW50LCBkbyBub3QgZG8gYW55dGhpbmdcblx0XHRcdGlmICggc2VsZWN0aW9uICYmIGpRdWVyeS5pbkFycmF5KCBlbGVtLCBzZWxlY3Rpb24gKSAhPT0gLTEgKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRjb250YWlucyA9IGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XG5cblx0XHRcdC8vIEFwcGVuZCB0byBmcmFnbWVudFxuXHRcdFx0dG1wID0gZ2V0QWxsKCBmcmFnbWVudC5hcHBlbmRDaGlsZCggZWxlbSApLCBcInNjcmlwdFwiICk7XG5cblx0XHRcdC8vIFByZXNlcnZlIHNjcmlwdCBldmFsdWF0aW9uIGhpc3Rvcnlcblx0XHRcdGlmICggY29udGFpbnMgKSB7XG5cdFx0XHRcdHNldEdsb2JhbEV2YWwoIHRtcCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDYXB0dXJlIGV4ZWN1dGFibGVzXG5cdFx0XHRpZiAoIHNjcmlwdHMgKSB7XG5cdFx0XHRcdGogPSAwO1xuXHRcdFx0XHR3aGlsZSAoIChlbGVtID0gdG1wWyBqKysgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCByc2NyaXB0VHlwZS50ZXN0KCBlbGVtLnR5cGUgfHwgXCJcIiApICkge1xuXHRcdFx0XHRcdFx0c2NyaXB0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZyYWdtZW50O1xuXHR9LFxuXG5cdGNsZWFuRGF0YTogZnVuY3Rpb24oIGVsZW1zICkge1xuXHRcdHZhciBkYXRhLCBlbGVtLCB0eXBlLCBrZXksXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWwsXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKGVsZW0gPSBlbGVtc1sgaSBdKSAhPT0gdW5kZWZpbmVkOyBpKysgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5hY2NlcHREYXRhKCBlbGVtICkgKSB7XG5cdFx0XHRcdGtleSA9IGVsZW1bIGRhdGFfcHJpdi5leHBhbmRvIF07XG5cblx0XHRcdFx0aWYgKCBrZXkgJiYgKGRhdGEgPSBkYXRhX3ByaXYuY2FjaGVbIGtleSBdKSApIHtcblx0XHRcdFx0XHRpZiAoIGRhdGEuZXZlbnRzICkge1xuXHRcdFx0XHRcdFx0Zm9yICggdHlwZSBpbiBkYXRhLmV2ZW50cyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsWyB0eXBlIF0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIFRoaXMgaXMgYSBzaG9ydGN1dCB0byBhdm9pZCBqUXVlcnkuZXZlbnQucmVtb3ZlJ3Mgb3ZlcmhlYWRcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGRhdGEuaGFuZGxlICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBkYXRhX3ByaXYuY2FjaGVbIGtleSBdICkge1xuXHRcdFx0XHRcdFx0Ly8gRGlzY2FyZCBhbnkgcmVtYWluaW5nIGBwcml2YXRlYCBkYXRhXG5cdFx0XHRcdFx0XHRkZWxldGUgZGF0YV9wcml2LmNhY2hlWyBrZXkgXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdC8vIERpc2NhcmQgYW55IHJlbWFpbmluZyBgdXNlcmAgZGF0YVxuXHRcdFx0ZGVsZXRlIGRhdGFfdXNlci5jYWNoZVsgZWxlbVsgZGF0YV91c2VyLmV4cGFuZG8gXSBdO1xuXHRcdH1cblx0fVxufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHR0ZXh0OiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0cmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRqUXVlcnkudGV4dCggdGhpcyApIDpcblx0XHRcdFx0dGhpcy5lbXB0eSgpLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRleHRDb250ZW50ID0gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApO1xuXHR9LFxuXG5cdGFwcGVuZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZG9tTWFuaXAoIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IG1hbmlwdWxhdGlvblRhcmdldCggdGhpcywgZWxlbSApO1xuXHRcdFx0XHR0YXJnZXQuYXBwZW5kQ2hpbGQoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRwcmVwZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5kb21NYW5pcCggYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHR2YXIgdGFyZ2V0ID0gbWFuaXB1bGF0aW9uVGFyZ2V0KCB0aGlzLCBlbGVtICk7XG5cdFx0XHRcdHRhcmdldC5pbnNlcnRCZWZvcmUoIGVsZW0sIHRhcmdldC5maXJzdENoaWxkICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0YmVmb3JlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5kb21NYW5pcCggYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0YWZ0ZXI6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmRvbU1hbmlwKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0aWYgKCB0aGlzLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdHRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoIGVsZW0sIHRoaXMubmV4dFNpYmxpbmcgKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBzZWxlY3Rvciwga2VlcERhdGEgLyogSW50ZXJuYWwgVXNlIE9ubHkgKi8gKSB7XG5cdFx0dmFyIGVsZW0sXG5cdFx0XHRlbGVtcyA9IHNlbGVjdG9yID8galF1ZXJ5LmZpbHRlciggc2VsZWN0b3IsIHRoaXMgKSA6IHRoaXMsXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKGVsZW0gPSBlbGVtc1tpXSkgIT0gbnVsbDsgaSsrICkge1xuXHRcdFx0aWYgKCAha2VlcERhdGEgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtICkgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdGlmICgga2VlcERhdGEgJiYgalF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKSApIHtcblx0XHRcdFx0XHRzZXRHbG9iYWxFdmFsKCBnZXRBbGwoIGVsZW0sIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsZW0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdGVtcHR5OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgZWxlbSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0Zm9yICggOyAoZWxlbSA9IHRoaXNbaV0pICE9IG51bGw7IGkrKyApIHtcblx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblxuXHRcdFx0XHQvLyBQcmV2ZW50IG1lbW9yeSBsZWFrc1xuXHRcdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIGVsZW0sIGZhbHNlICkgKTtcblxuXHRcdFx0XHQvLyBSZW1vdmUgYW55IHJlbWFpbmluZyBub2Rlc1xuXHRcdFx0XHRlbGVtLnRleHRDb250ZW50ID0gXCJcIjtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24oIGRhdGFBbmRFdmVudHMsIGRlZXBEYXRhQW5kRXZlbnRzICkge1xuXHRcdGRhdGFBbmRFdmVudHMgPSBkYXRhQW5kRXZlbnRzID09IG51bGwgPyBmYWxzZSA6IGRhdGFBbmRFdmVudHM7XG5cdFx0ZGVlcERhdGFBbmRFdmVudHMgPSBkZWVwRGF0YUFuZEV2ZW50cyA9PSBudWxsID8gZGF0YUFuZEV2ZW50cyA6IGRlZXBEYXRhQW5kRXZlbnRzO1xuXG5cdFx0cmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5jbG9uZSggdGhpcywgZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKTtcblx0XHR9KTtcblx0fSxcblxuXHRodG1sOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0dmFyIGVsZW0gPSB0aGlzWyAwIF0gfHwge30sXG5cdFx0XHRcdGkgPSAwLFxuXHRcdFx0XHRsID0gdGhpcy5sZW5ndGg7XG5cblx0XHRcdGlmICggdmFsdWUgPT09IHVuZGVmaW5lZCAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5pbm5lckhUTUw7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNlZSBpZiB3ZSBjYW4gdGFrZSBhIHNob3J0Y3V0IGFuZCBqdXN0IHVzZSBpbm5lckhUTUxcblx0XHRcdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmICFybm9Jbm5lcmh0bWwudGVzdCggdmFsdWUgKSAmJlxuXHRcdFx0XHQhd3JhcE1hcFsgKCBydGFnTmFtZS5leGVjKCB2YWx1ZSApIHx8IFsgXCJcIiwgXCJcIiBdIClbIDEgXS50b0xvd2VyQ2FzZSgpIF0gKSB7XG5cblx0XHRcdFx0dmFsdWUgPSB2YWx1ZS5yZXBsYWNlKCByeGh0bWxUYWcsIFwiPCQxPjwvJDI+XCIgKTtcblxuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRcdGVsZW0gPSB0aGlzWyBpIF0gfHwge307XG5cblx0XHRcdFx0XHRcdC8vIFJlbW92ZSBlbGVtZW50IG5vZGVzIGFuZCBwcmV2ZW50IG1lbW9yeSBsZWFrc1xuXHRcdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRcdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIGVsZW0sIGZhbHNlICkgKTtcblx0XHRcdFx0XHRcdFx0ZWxlbS5pbm5lckhUTUwgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRlbGVtID0gMDtcblxuXHRcdFx0XHQvLyBJZiB1c2luZyBpbm5lckhUTUwgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgdXNlIHRoZSBmYWxsYmFjayBtZXRob2Rcblx0XHRcdFx0fSBjYXRjaCggZSApIHt9XG5cdFx0XHR9XG5cblx0XHRcdGlmICggZWxlbSApIHtcblx0XHRcdFx0dGhpcy5lbXB0eSgpLmFwcGVuZCggdmFsdWUgKTtcblx0XHRcdH1cblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApO1xuXHR9LFxuXG5cdHJlcGxhY2VXaXRoOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgYXJnID0gYXJndW1lbnRzWyAwIF07XG5cblx0XHQvLyBNYWtlIHRoZSBjaGFuZ2VzLCByZXBsYWNpbmcgZWFjaCBjb250ZXh0IGVsZW1lbnQgd2l0aCB0aGUgbmV3IGNvbnRlbnRcblx0XHR0aGlzLmRvbU1hbmlwKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0YXJnID0gdGhpcy5wYXJlbnROb2RlO1xuXG5cdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIHRoaXMgKSApO1xuXG5cdFx0XHRpZiAoIGFyZyApIHtcblx0XHRcdFx0YXJnLnJlcGxhY2VDaGlsZCggZWxlbSwgdGhpcyApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0Ly8gRm9yY2UgcmVtb3ZhbCBpZiB0aGVyZSB3YXMgbm8gbmV3IGNvbnRlbnQgKGUuZy4sIGZyb20gZW1wdHkgYXJndW1lbnRzKVxuXHRcdHJldHVybiBhcmcgJiYgKGFyZy5sZW5ndGggfHwgYXJnLm5vZGVUeXBlKSA/IHRoaXMgOiB0aGlzLnJlbW92ZSgpO1xuXHR9LFxuXG5cdGRldGFjaDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiB0aGlzLnJlbW92ZSggc2VsZWN0b3IsIHRydWUgKTtcblx0fSxcblxuXHRkb21NYW5pcDogZnVuY3Rpb24oIGFyZ3MsIGNhbGxiYWNrICkge1xuXG5cdFx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xuXHRcdGFyZ3MgPSBjb25jYXQuYXBwbHkoIFtdLCBhcmdzICk7XG5cblx0XHR2YXIgZnJhZ21lbnQsIGZpcnN0LCBzY3JpcHRzLCBoYXNTY3JpcHRzLCBub2RlLCBkb2MsXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSB0aGlzLmxlbmd0aCxcblx0XHRcdHNldCA9IHRoaXMsXG5cdFx0XHRpTm9DbG9uZSA9IGwgLSAxLFxuXHRcdFx0dmFsdWUgPSBhcmdzWyAwIF0sXG5cdFx0XHRpc0Z1bmN0aW9uID0galF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICk7XG5cblx0XHQvLyBXZSBjYW4ndCBjbG9uZU5vZGUgZnJhZ21lbnRzIHRoYXQgY29udGFpbiBjaGVja2VkLCBpbiBXZWJLaXRcblx0XHRpZiAoIGlzRnVuY3Rpb24gfHxcblx0XHRcdFx0KCBsID4gMSAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiZcblx0XHRcdFx0XHQhc3VwcG9ydC5jaGVja0Nsb25lICYmIHJjaGVja2VkLnRlc3QoIHZhbHVlICkgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oIGluZGV4ICkge1xuXHRcdFx0XHR2YXIgc2VsZiA9IHNldC5lcSggaW5kZXggKTtcblx0XHRcdFx0aWYgKCBpc0Z1bmN0aW9uICkge1xuXHRcdFx0XHRcdGFyZ3NbIDAgXSA9IHZhbHVlLmNhbGwoIHRoaXMsIGluZGV4LCBzZWxmLmh0bWwoKSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHNlbGYuZG9tTWFuaXAoIGFyZ3MsIGNhbGxiYWNrICk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRpZiAoIGwgKSB7XG5cdFx0XHRmcmFnbWVudCA9IGpRdWVyeS5idWlsZEZyYWdtZW50KCBhcmdzLCB0aGlzWyAwIF0ub3duZXJEb2N1bWVudCwgZmFsc2UsIHRoaXMgKTtcblx0XHRcdGZpcnN0ID0gZnJhZ21lbnQuZmlyc3RDaGlsZDtcblxuXHRcdFx0aWYgKCBmcmFnbWVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMSApIHtcblx0XHRcdFx0ZnJhZ21lbnQgPSBmaXJzdDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBmaXJzdCApIHtcblx0XHRcdFx0c2NyaXB0cyA9IGpRdWVyeS5tYXAoIGdldEFsbCggZnJhZ21lbnQsIFwic2NyaXB0XCIgKSwgZGlzYWJsZVNjcmlwdCApO1xuXHRcdFx0XHRoYXNTY3JpcHRzID0gc2NyaXB0cy5sZW5ndGg7XG5cblx0XHRcdFx0Ly8gVXNlIHRoZSBvcmlnaW5hbCBmcmFnbWVudCBmb3IgdGhlIGxhc3QgaXRlbSBpbnN0ZWFkIG9mIHRoZSBmaXJzdCBiZWNhdXNlIGl0IGNhbiBlbmQgdXBcblx0XHRcdFx0Ly8gYmVpbmcgZW1wdGllZCBpbmNvcnJlY3RseSBpbiBjZXJ0YWluIHNpdHVhdGlvbnMgKCM4MDcwKS5cblx0XHRcdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRcdG5vZGUgPSBmcmFnbWVudDtcblxuXHRcdFx0XHRcdGlmICggaSAhPT0gaU5vQ2xvbmUgKSB7XG5cdFx0XHRcdFx0XHRub2RlID0galF1ZXJ5LmNsb25lKCBub2RlLCB0cnVlLCB0cnVlICk7XG5cblx0XHRcdFx0XHRcdC8vIEtlZXAgcmVmZXJlbmNlcyB0byBjbG9uZWQgc2NyaXB0cyBmb3IgbGF0ZXIgcmVzdG9yYXRpb25cblx0XHRcdFx0XHRcdGlmICggaGFzU2NyaXB0cyApIHtcblx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUXRXZWJLaXRcblx0XHRcdFx0XHRcdFx0Ly8galF1ZXJ5Lm1lcmdlIGJlY2F1c2UgcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93c1xuXHRcdFx0XHRcdFx0XHRqUXVlcnkubWVyZ2UoIHNjcmlwdHMsIGdldEFsbCggbm9kZSwgXCJzY3JpcHRcIiApICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Y2FsbGJhY2suY2FsbCggdGhpc1sgaSBdLCBub2RlLCBpICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cdFx0XHRcdFx0ZG9jID0gc2NyaXB0c1sgc2NyaXB0cy5sZW5ndGggLSAxIF0ub3duZXJEb2N1bWVudDtcblxuXHRcdFx0XHRcdC8vIFJlZW5hYmxlIHNjcmlwdHNcblx0XHRcdFx0XHRqUXVlcnkubWFwKCBzY3JpcHRzLCByZXN0b3JlU2NyaXB0ICk7XG5cblx0XHRcdFx0XHQvLyBFdmFsdWF0ZSBleGVjdXRhYmxlIHNjcmlwdHMgb24gZmlyc3QgZG9jdW1lbnQgaW5zZXJ0aW9uXG5cdFx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBoYXNTY3JpcHRzOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRub2RlID0gc2NyaXB0c1sgaSBdO1xuXHRcdFx0XHRcdFx0aWYgKCByc2NyaXB0VHlwZS50ZXN0KCBub2RlLnR5cGUgfHwgXCJcIiApICYmXG5cdFx0XHRcdFx0XHRcdCFkYXRhX3ByaXYuYWNjZXNzKCBub2RlLCBcImdsb2JhbEV2YWxcIiApICYmIGpRdWVyeS5jb250YWlucyggZG9jLCBub2RlICkgKSB7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCBub2RlLnNyYyApIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBPcHRpb25hbCBBSkFYIGRlcGVuZGVuY3ksIGJ1dCB3b24ndCBydW4gc2NyaXB0cyBpZiBub3QgcHJlc2VudFxuXHRcdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5Ll9ldmFsVXJsICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0alF1ZXJ5Ll9ldmFsVXJsKCBub2RlLnNyYyApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuZ2xvYmFsRXZhbCggbm9kZS50ZXh0Q29udGVudC5yZXBsYWNlKCByY2xlYW5TY3JpcHQsIFwiXCIgKSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZWFjaCh7XG5cdGFwcGVuZFRvOiBcImFwcGVuZFwiLFxuXHRwcmVwZW5kVG86IFwicHJlcGVuZFwiLFxuXHRpbnNlcnRCZWZvcmU6IFwiYmVmb3JlXCIsXG5cdGluc2VydEFmdGVyOiBcImFmdGVyXCIsXG5cdHJlcGxhY2VBbGw6IFwicmVwbGFjZVdpdGhcIlxufSwgZnVuY3Rpb24oIG5hbWUsIG9yaWdpbmFsICkge1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHR2YXIgZWxlbXMsXG5cdFx0XHRyZXQgPSBbXSxcblx0XHRcdGluc2VydCA9IGpRdWVyeSggc2VsZWN0b3IgKSxcblx0XHRcdGxhc3QgPSBpbnNlcnQubGVuZ3RoIC0gMSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0Zm9yICggOyBpIDw9IGxhc3Q7IGkrKyApIHtcblx0XHRcdGVsZW1zID0gaSA9PT0gbGFzdCA/IHRoaXMgOiB0aGlzLmNsb25lKCB0cnVlICk7XG5cdFx0XHRqUXVlcnkoIGluc2VydFsgaSBdIClbIG9yaWdpbmFsIF0oIGVsZW1zICk7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IFF0V2ViS2l0XG5cdFx0XHQvLyAuZ2V0KCkgYmVjYXVzZSBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzXG5cdFx0XHRwdXNoLmFwcGx5KCByZXQsIGVsZW1zLmdldCgpICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCByZXQgKTtcblx0fTtcbn0pO1xuXG5cbnZhciBpZnJhbWUsXG5cdGVsZW1kaXNwbGF5ID0ge307XG5cbi8qKlxuICogUmV0cmlldmUgdGhlIGFjdHVhbCBkaXNwbGF5IG9mIGEgZWxlbWVudFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgbm9kZU5hbWUgb2YgdGhlIGVsZW1lbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBkb2MgRG9jdW1lbnQgb2JqZWN0XG4gKi9cbi8vIENhbGxlZCBvbmx5IGZyb20gd2l0aGluIGRlZmF1bHREaXNwbGF5XG5mdW5jdGlvbiBhY3R1YWxEaXNwbGF5KCBuYW1lLCBkb2MgKSB7XG5cdHZhciBzdHlsZSxcblx0XHRlbGVtID0galF1ZXJ5KCBkb2MuY3JlYXRlRWxlbWVudCggbmFtZSApICkuYXBwZW5kVG8oIGRvYy5ib2R5ICksXG5cblx0XHQvLyBnZXREZWZhdWx0Q29tcHV0ZWRTdHlsZSBtaWdodCBiZSByZWxpYWJseSB1c2VkIG9ubHkgb24gYXR0YWNoZWQgZWxlbWVudFxuXHRcdGRpc3BsYXkgPSB3aW5kb3cuZ2V0RGVmYXVsdENvbXB1dGVkU3R5bGUgJiYgKCBzdHlsZSA9IHdpbmRvdy5nZXREZWZhdWx0Q29tcHV0ZWRTdHlsZSggZWxlbVsgMCBdICkgKSA/XG5cblx0XHRcdC8vIFVzZSBvZiB0aGlzIG1ldGhvZCBpcyBhIHRlbXBvcmFyeSBmaXggKG1vcmUgbGlrZSBvcHRtaXphdGlvbikgdW50aWwgc29tZXRoaW5nIGJldHRlciBjb21lcyBhbG9uZyxcblx0XHRcdC8vIHNpbmNlIGl0IHdhcyByZW1vdmVkIGZyb20gc3BlY2lmaWNhdGlvbiBhbmQgc3VwcG9ydGVkIG9ubHkgaW4gRkZcblx0XHRcdHN0eWxlLmRpc3BsYXkgOiBqUXVlcnkuY3NzKCBlbGVtWyAwIF0sIFwiZGlzcGxheVwiICk7XG5cblx0Ly8gV2UgZG9uJ3QgaGF2ZSBhbnkgZGF0YSBzdG9yZWQgb24gdGhlIGVsZW1lbnQsXG5cdC8vIHNvIHVzZSBcImRldGFjaFwiIG1ldGhvZCBhcyBmYXN0IHdheSB0byBnZXQgcmlkIG9mIHRoZSBlbGVtZW50XG5cdGVsZW0uZGV0YWNoKCk7XG5cblx0cmV0dXJuIGRpc3BsYXk7XG59XG5cbi8qKlxuICogVHJ5IHRvIGRldGVybWluZSB0aGUgZGVmYXVsdCBkaXNwbGF5IHZhbHVlIG9mIGFuIGVsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nfSBub2RlTmFtZVxuICovXG5mdW5jdGlvbiBkZWZhdWx0RGlzcGxheSggbm9kZU5hbWUgKSB7XG5cdHZhciBkb2MgPSBkb2N1bWVudCxcblx0XHRkaXNwbGF5ID0gZWxlbWRpc3BsYXlbIG5vZGVOYW1lIF07XG5cblx0aWYgKCAhZGlzcGxheSApIHtcblx0XHRkaXNwbGF5ID0gYWN0dWFsRGlzcGxheSggbm9kZU5hbWUsIGRvYyApO1xuXG5cdFx0Ly8gSWYgdGhlIHNpbXBsZSB3YXkgZmFpbHMsIHJlYWQgZnJvbSBpbnNpZGUgYW4gaWZyYW1lXG5cdFx0aWYgKCBkaXNwbGF5ID09PSBcIm5vbmVcIiB8fCAhZGlzcGxheSApIHtcblxuXHRcdFx0Ly8gVXNlIHRoZSBhbHJlYWR5LWNyZWF0ZWQgaWZyYW1lIGlmIHBvc3NpYmxlXG5cdFx0XHRpZnJhbWUgPSAoaWZyYW1lIHx8IGpRdWVyeSggXCI8aWZyYW1lIGZyYW1lYm9yZGVyPScwJyB3aWR0aD0nMCcgaGVpZ2h0PScwJy8+XCIgKSkuYXBwZW5kVG8oIGRvYy5kb2N1bWVudEVsZW1lbnQgKTtcblxuXHRcdFx0Ly8gQWx3YXlzIHdyaXRlIGEgbmV3IEhUTUwgc2tlbGV0b24gc28gV2Via2l0IGFuZCBGaXJlZm94IGRvbid0IGNob2tlIG9uIHJldXNlXG5cdFx0XHRkb2MgPSBpZnJhbWVbIDAgXS5jb250ZW50RG9jdW1lbnQ7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFXG5cdFx0XHRkb2Mud3JpdGUoKTtcblx0XHRcdGRvYy5jbG9zZSgpO1xuXG5cdFx0XHRkaXNwbGF5ID0gYWN0dWFsRGlzcGxheSggbm9kZU5hbWUsIGRvYyApO1xuXHRcdFx0aWZyYW1lLmRldGFjaCgpO1xuXHRcdH1cblxuXHRcdC8vIFN0b3JlIHRoZSBjb3JyZWN0IGRlZmF1bHQgZGlzcGxheVxuXHRcdGVsZW1kaXNwbGF5WyBub2RlTmFtZSBdID0gZGlzcGxheTtcblx0fVxuXG5cdHJldHVybiBkaXNwbGF5O1xufVxudmFyIHJtYXJnaW4gPSAoL15tYXJnaW4vKTtcblxudmFyIHJudW1ub25weCA9IG5ldyBSZWdFeHAoIFwiXihcIiArIHBudW0gKyBcIikoPyFweClbYS16JV0rJFwiLCBcImlcIiApO1xuXG52YXIgZ2V0U3R5bGVzID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGVsZW0ub3duZXJEb2N1bWVudC5kZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlKCBlbGVtLCBudWxsICk7XG5cdH07XG5cblxuXG5mdW5jdGlvbiBjdXJDU1MoIGVsZW0sIG5hbWUsIGNvbXB1dGVkICkge1xuXHR2YXIgd2lkdGgsIG1pbldpZHRoLCBtYXhXaWR0aCwgcmV0LFxuXHRcdHN0eWxlID0gZWxlbS5zdHlsZTtcblxuXHRjb21wdXRlZCA9IGNvbXB1dGVkIHx8IGdldFN0eWxlcyggZWxlbSApO1xuXG5cdC8vIFN1cHBvcnQ6IElFOVxuXHQvLyBnZXRQcm9wZXJ0eVZhbHVlIGlzIG9ubHkgbmVlZGVkIGZvciAuY3NzKCdmaWx0ZXInKSBpbiBJRTksIHNlZSAjMTI1Mzdcblx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRyZXQgPSBjb21wdXRlZC5nZXRQcm9wZXJ0eVZhbHVlKCBuYW1lICkgfHwgY29tcHV0ZWRbIG5hbWUgXTtcblx0fVxuXG5cdGlmICggY29tcHV0ZWQgKSB7XG5cblx0XHRpZiAoIHJldCA9PT0gXCJcIiAmJiAhalF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKSApIHtcblx0XHRcdHJldCA9IGpRdWVyeS5zdHlsZSggZWxlbSwgbmFtZSApO1xuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IGlPUyA8IDZcblx0XHQvLyBBIHRyaWJ1dGUgdG8gdGhlIFwiYXdlc29tZSBoYWNrIGJ5IERlYW4gRWR3YXJkc1wiXG5cdFx0Ly8gaU9TIDwgNiAoYXQgbGVhc3QpIHJldHVybnMgcGVyY2VudGFnZSBmb3IgYSBsYXJnZXIgc2V0IG9mIHZhbHVlcywgYnV0IHdpZHRoIHNlZW1zIHRvIGJlIHJlbGlhYmx5IHBpeGVsc1xuXHRcdC8vIHRoaXMgaXMgYWdhaW5zdCB0aGUgQ1NTT00gZHJhZnQgc3BlYzogaHR0cDovL2Rldi53My5vcmcvY3Nzd2cvY3Nzb20vI3Jlc29sdmVkLXZhbHVlc1xuXHRcdGlmICggcm51bW5vbnB4LnRlc3QoIHJldCApICYmIHJtYXJnaW4udGVzdCggbmFtZSApICkge1xuXG5cdFx0XHQvLyBSZW1lbWJlciB0aGUgb3JpZ2luYWwgdmFsdWVzXG5cdFx0XHR3aWR0aCA9IHN0eWxlLndpZHRoO1xuXHRcdFx0bWluV2lkdGggPSBzdHlsZS5taW5XaWR0aDtcblx0XHRcdG1heFdpZHRoID0gc3R5bGUubWF4V2lkdGg7XG5cblx0XHRcdC8vIFB1dCBpbiB0aGUgbmV3IHZhbHVlcyB0byBnZXQgYSBjb21wdXRlZCB2YWx1ZSBvdXRcblx0XHRcdHN0eWxlLm1pbldpZHRoID0gc3R5bGUubWF4V2lkdGggPSBzdHlsZS53aWR0aCA9IHJldDtcblx0XHRcdHJldCA9IGNvbXB1dGVkLndpZHRoO1xuXG5cdFx0XHQvLyBSZXZlcnQgdGhlIGNoYW5nZWQgdmFsdWVzXG5cdFx0XHRzdHlsZS53aWR0aCA9IHdpZHRoO1xuXHRcdFx0c3R5bGUubWluV2lkdGggPSBtaW5XaWR0aDtcblx0XHRcdHN0eWxlLm1heFdpZHRoID0gbWF4V2lkdGg7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHJldCAhPT0gdW5kZWZpbmVkID9cblx0XHQvLyBTdXBwb3J0OiBJRVxuXHRcdC8vIElFIHJldHVybnMgekluZGV4IHZhbHVlIGFzIGFuIGludGVnZXIuXG5cdFx0cmV0ICsgXCJcIiA6XG5cdFx0cmV0O1xufVxuXG5cbmZ1bmN0aW9uIGFkZEdldEhvb2tJZiggY29uZGl0aW9uRm4sIGhvb2tGbiApIHtcblx0Ly8gRGVmaW5lIHRoZSBob29rLCB3ZSdsbCBjaGVjayBvbiB0aGUgZmlyc3QgcnVuIGlmIGl0J3MgcmVhbGx5IG5lZWRlZC5cblx0cmV0dXJuIHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBjb25kaXRpb25GbigpICkge1xuXHRcdFx0XHQvLyBIb29rIG5vdCBuZWVkZWQgKG9yIGl0J3Mgbm90IHBvc3NpYmxlIHRvIHVzZSBpdCBkdWUgdG8gbWlzc2luZyBkZXBlbmRlbmN5KSxcblx0XHRcdFx0Ly8gcmVtb3ZlIGl0LlxuXHRcdFx0XHQvLyBTaW5jZSB0aGVyZSBhcmUgbm8gb3RoZXIgaG9va3MgZm9yIG1hcmdpblJpZ2h0LCByZW1vdmUgdGhlIHdob2xlIG9iamVjdC5cblx0XHRcdFx0ZGVsZXRlIHRoaXMuZ2V0O1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIEhvb2sgbmVlZGVkOyByZWRlZmluZSBpdCBzbyB0aGF0IHRoZSBzdXBwb3J0IHRlc3QgaXMgbm90IGV4ZWN1dGVkIGFnYWluLlxuXG5cdFx0XHRyZXR1cm4gKHRoaXMuZ2V0ID0gaG9va0ZuKS5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0fVxuXHR9O1xufVxuXG5cbihmdW5jdGlvbigpIHtcblx0dmFyIHBpeGVsUG9zaXRpb25WYWwsIGJveFNpemluZ1JlbGlhYmxlVmFsLFxuXHRcdGRvY0VsZW0gPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsXG5cdFx0Y29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApLFxuXHRcdGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblxuXHRpZiAoICFkaXYuc3R5bGUgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0ZGl2LnN0eWxlLmJhY2tncm91bmRDbGlwID0gXCJjb250ZW50LWJveFwiO1xuXHRkaXYuY2xvbmVOb2RlKCB0cnVlICkuc3R5bGUuYmFja2dyb3VuZENsaXAgPSBcIlwiO1xuXHRzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSA9IGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9PT0gXCJjb250ZW50LWJveFwiO1xuXG5cdGNvbnRhaW5lci5zdHlsZS5jc3NUZXh0ID0gXCJib3JkZXI6MDt3aWR0aDowO2hlaWdodDowO3RvcDowO2xlZnQ6LTk5OTlweDttYXJnaW4tdG9wOjFweDtcIiArXG5cdFx0XCJwb3NpdGlvbjphYnNvbHV0ZVwiO1xuXHRjb250YWluZXIuYXBwZW5kQ2hpbGQoIGRpdiApO1xuXG5cdC8vIEV4ZWN1dGluZyBib3RoIHBpeGVsUG9zaXRpb24gJiBib3hTaXppbmdSZWxpYWJsZSB0ZXN0cyByZXF1aXJlIG9ubHkgb25lIGxheW91dFxuXHQvLyBzbyB0aGV5J3JlIGV4ZWN1dGVkIGF0IHRoZSBzYW1lIHRpbWUgdG8gc2F2ZSB0aGUgc2Vjb25kIGNvbXB1dGF0aW9uLlxuXHRmdW5jdGlvbiBjb21wdXRlUGl4ZWxQb3NpdGlvbkFuZEJveFNpemluZ1JlbGlhYmxlKCkge1xuXHRcdGRpdi5zdHlsZS5jc3NUZXh0ID1cblx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3g8MjksIEFuZHJvaWQgMi4zXG5cdFx0XHQvLyBWZW5kb3ItcHJlZml4IGJveC1zaXppbmdcblx0XHRcdFwiLXdlYmtpdC1ib3gtc2l6aW5nOmJvcmRlci1ib3g7LW1vei1ib3gtc2l6aW5nOmJvcmRlci1ib3g7XCIgK1xuXHRcdFx0XCJib3gtc2l6aW5nOmJvcmRlci1ib3g7ZGlzcGxheTpibG9jazttYXJnaW4tdG9wOjElO3RvcDoxJTtcIiArXG5cdFx0XHRcImJvcmRlcjoxcHg7cGFkZGluZzoxcHg7d2lkdGg6NHB4O3Bvc2l0aW9uOmFic29sdXRlXCI7XG5cdFx0ZGl2LmlubmVySFRNTCA9IFwiXCI7XG5cdFx0ZG9jRWxlbS5hcHBlbmRDaGlsZCggY29udGFpbmVyICk7XG5cblx0XHR2YXIgZGl2U3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSggZGl2LCBudWxsICk7XG5cdFx0cGl4ZWxQb3NpdGlvblZhbCA9IGRpdlN0eWxlLnRvcCAhPT0gXCIxJVwiO1xuXHRcdGJveFNpemluZ1JlbGlhYmxlVmFsID0gZGl2U3R5bGUud2lkdGggPT09IFwiNHB4XCI7XG5cblx0XHRkb2NFbGVtLnJlbW92ZUNoaWxkKCBjb250YWluZXIgKTtcblx0fVxuXG5cdC8vIFN1cHBvcnQ6IG5vZGUuanMganNkb21cblx0Ly8gRG9uJ3QgYXNzdW1lIHRoYXQgZ2V0Q29tcHV0ZWRTdHlsZSBpcyBhIHByb3BlcnR5IG9mIHRoZSBnbG9iYWwgb2JqZWN0XG5cdGlmICggd2luZG93LmdldENvbXB1dGVkU3R5bGUgKSB7XG5cdFx0alF1ZXJ5LmV4dGVuZCggc3VwcG9ydCwge1xuXHRcdFx0cGl4ZWxQb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdC8vIFRoaXMgdGVzdCBpcyBleGVjdXRlZCBvbmx5IG9uY2UgYnV0IHdlIHN0aWxsIGRvIG1lbW9pemluZ1xuXHRcdFx0XHQvLyBzaW5jZSB3ZSBjYW4gdXNlIHRoZSBib3hTaXppbmdSZWxpYWJsZSBwcmUtY29tcHV0aW5nLlxuXHRcdFx0XHQvLyBObyBuZWVkIHRvIGNoZWNrIGlmIHRoZSB0ZXN0IHdhcyBhbHJlYWR5IHBlcmZvcm1lZCwgdGhvdWdoLlxuXHRcdFx0XHRjb21wdXRlUGl4ZWxQb3NpdGlvbkFuZEJveFNpemluZ1JlbGlhYmxlKCk7XG5cdFx0XHRcdHJldHVybiBwaXhlbFBvc2l0aW9uVmFsO1xuXHRcdFx0fSxcblx0XHRcdGJveFNpemluZ1JlbGlhYmxlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBib3hTaXppbmdSZWxpYWJsZVZhbCA9PSBudWxsICkge1xuXHRcdFx0XHRcdGNvbXB1dGVQaXhlbFBvc2l0aW9uQW5kQm94U2l6aW5nUmVsaWFibGUoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gYm94U2l6aW5nUmVsaWFibGVWYWw7XG5cdFx0XHR9LFxuXHRcdFx0cmVsaWFibGVNYXJnaW5SaWdodDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgMi4zXG5cdFx0XHRcdC8vIENoZWNrIGlmIGRpdiB3aXRoIGV4cGxpY2l0IHdpZHRoIGFuZCBubyBtYXJnaW4tcmlnaHQgaW5jb3JyZWN0bHlcblx0XHRcdFx0Ly8gZ2V0cyBjb21wdXRlZCBtYXJnaW4tcmlnaHQgYmFzZWQgb24gd2lkdGggb2YgY29udGFpbmVyLiAoIzMzMzMpXG5cdFx0XHRcdC8vIFdlYktpdCBCdWcgMTMzNDMgLSBnZXRDb21wdXRlZFN0eWxlIHJldHVybnMgd3JvbmcgdmFsdWUgZm9yIG1hcmdpbi1yaWdodFxuXHRcdFx0XHQvLyBUaGlzIHN1cHBvcnQgZnVuY3Rpb24gaXMgb25seSBleGVjdXRlZCBvbmNlIHNvIG5vIG1lbW9pemluZyBpcyBuZWVkZWQuXG5cdFx0XHRcdHZhciByZXQsXG5cdFx0XHRcdFx0bWFyZ2luRGl2ID0gZGl2LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkgKTtcblxuXHRcdFx0XHQvLyBSZXNldCBDU1M6IGJveC1zaXppbmc7IGRpc3BsYXk7IG1hcmdpbjsgYm9yZGVyOyBwYWRkaW5nXG5cdFx0XHRcdG1hcmdpbkRpdi5zdHlsZS5jc3NUZXh0ID0gZGl2LnN0eWxlLmNzc1RleHQgPVxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3g8MjksIEFuZHJvaWQgMi4zXG5cdFx0XHRcdFx0Ly8gVmVuZG9yLXByZWZpeCBib3gtc2l6aW5nXG5cdFx0XHRcdFx0XCItd2Via2l0LWJveC1zaXppbmc6Y29udGVudC1ib3g7LW1vei1ib3gtc2l6aW5nOmNvbnRlbnQtYm94O1wiICtcblx0XHRcdFx0XHRcImJveC1zaXppbmc6Y29udGVudC1ib3g7ZGlzcGxheTpibG9jazttYXJnaW46MDtib3JkZXI6MDtwYWRkaW5nOjBcIjtcblx0XHRcdFx0bWFyZ2luRGl2LnN0eWxlLm1hcmdpblJpZ2h0ID0gbWFyZ2luRGl2LnN0eWxlLndpZHRoID0gXCIwXCI7XG5cdFx0XHRcdGRpdi5zdHlsZS53aWR0aCA9IFwiMXB4XCI7XG5cdFx0XHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGNvbnRhaW5lciApO1xuXG5cdFx0XHRcdHJldCA9ICFwYXJzZUZsb2F0KCB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSggbWFyZ2luRGl2LCBudWxsICkubWFyZ2luUmlnaHQgKTtcblxuXHRcdFx0XHRkb2NFbGVtLnJlbW92ZUNoaWxkKCBjb250YWluZXIgKTtcblxuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59KSgpO1xuXG5cbi8vIEEgbWV0aG9kIGZvciBxdWlja2x5IHN3YXBwaW5nIGluL291dCBDU1MgcHJvcGVydGllcyB0byBnZXQgY29ycmVjdCBjYWxjdWxhdGlvbnMuXG5qUXVlcnkuc3dhcCA9IGZ1bmN0aW9uKCBlbGVtLCBvcHRpb25zLCBjYWxsYmFjaywgYXJncyApIHtcblx0dmFyIHJldCwgbmFtZSxcblx0XHRvbGQgPSB7fTtcblxuXHQvLyBSZW1lbWJlciB0aGUgb2xkIHZhbHVlcywgYW5kIGluc2VydCB0aGUgbmV3IG9uZXNcblx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdG9sZFsgbmFtZSBdID0gZWxlbS5zdHlsZVsgbmFtZSBdO1xuXHRcdGVsZW0uc3R5bGVbIG5hbWUgXSA9IG9wdGlvbnNbIG5hbWUgXTtcblx0fVxuXG5cdHJldCA9IGNhbGxiYWNrLmFwcGx5KCBlbGVtLCBhcmdzIHx8IFtdICk7XG5cblx0Ly8gUmV2ZXJ0IHRoZSBvbGQgdmFsdWVzXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRlbGVtLnN0eWxlWyBuYW1lIF0gPSBvbGRbIG5hbWUgXTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59O1xuXG5cbnZhclxuXHQvLyBzd2FwcGFibGUgaWYgZGlzcGxheSBpcyBub25lIG9yIHN0YXJ0cyB3aXRoIHRhYmxlIGV4Y2VwdCBcInRhYmxlXCIsIFwidGFibGUtY2VsbFwiLCBvciBcInRhYmxlLWNhcHRpb25cIlxuXHQvLyBzZWUgaGVyZSBmb3IgZGlzcGxheSB2YWx1ZXM6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvQ1NTL2Rpc3BsYXlcblx0cmRpc3BsYXlzd2FwID0gL14obm9uZXx0YWJsZSg/IS1jW2VhXSkuKykvLFxuXHRybnVtc3BsaXQgPSBuZXcgUmVnRXhwKCBcIl4oXCIgKyBwbnVtICsgXCIpKC4qKSRcIiwgXCJpXCIgKSxcblx0cnJlbE51bSA9IG5ldyBSZWdFeHAoIFwiXihbKy1dKT0oXCIgKyBwbnVtICsgXCIpXCIsIFwiaVwiICksXG5cblx0Y3NzU2hvdyA9IHsgcG9zaXRpb246IFwiYWJzb2x1dGVcIiwgdmlzaWJpbGl0eTogXCJoaWRkZW5cIiwgZGlzcGxheTogXCJibG9ja1wiIH0sXG5cdGNzc05vcm1hbFRyYW5zZm9ybSA9IHtcblx0XHRsZXR0ZXJTcGFjaW5nOiBcIjBcIixcblx0XHRmb250V2VpZ2h0OiBcIjQwMFwiXG5cdH0sXG5cblx0Y3NzUHJlZml4ZXMgPSBbIFwiV2Via2l0XCIsIFwiT1wiLCBcIk1velwiLCBcIm1zXCIgXTtcblxuLy8gcmV0dXJuIGEgY3NzIHByb3BlcnR5IG1hcHBlZCB0byBhIHBvdGVudGlhbGx5IHZlbmRvciBwcmVmaXhlZCBwcm9wZXJ0eVxuZnVuY3Rpb24gdmVuZG9yUHJvcE5hbWUoIHN0eWxlLCBuYW1lICkge1xuXG5cdC8vIHNob3J0Y3V0IGZvciBuYW1lcyB0aGF0IGFyZSBub3QgdmVuZG9yIHByZWZpeGVkXG5cdGlmICggbmFtZSBpbiBzdHlsZSApIHtcblx0XHRyZXR1cm4gbmFtZTtcblx0fVxuXG5cdC8vIGNoZWNrIGZvciB2ZW5kb3IgcHJlZml4ZWQgbmFtZXNcblx0dmFyIGNhcE5hbWUgPSBuYW1lWzBdLnRvVXBwZXJDYXNlKCkgKyBuYW1lLnNsaWNlKDEpLFxuXHRcdG9yaWdOYW1lID0gbmFtZSxcblx0XHRpID0gY3NzUHJlZml4ZXMubGVuZ3RoO1xuXG5cdHdoaWxlICggaS0tICkge1xuXHRcdG5hbWUgPSBjc3NQcmVmaXhlc1sgaSBdICsgY2FwTmFtZTtcblx0XHRpZiAoIG5hbWUgaW4gc3R5bGUgKSB7XG5cdFx0XHRyZXR1cm4gbmFtZTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gb3JpZ05hbWU7XG59XG5cbmZ1bmN0aW9uIHNldFBvc2l0aXZlTnVtYmVyKCBlbGVtLCB2YWx1ZSwgc3VidHJhY3QgKSB7XG5cdHZhciBtYXRjaGVzID0gcm51bXNwbGl0LmV4ZWMoIHZhbHVlICk7XG5cdHJldHVybiBtYXRjaGVzID9cblx0XHQvLyBHdWFyZCBhZ2FpbnN0IHVuZGVmaW5lZCBcInN1YnRyYWN0XCIsIGUuZy4sIHdoZW4gdXNlZCBhcyBpbiBjc3NIb29rc1xuXHRcdE1hdGgubWF4KCAwLCBtYXRjaGVzWyAxIF0gLSAoIHN1YnRyYWN0IHx8IDAgKSApICsgKCBtYXRjaGVzWyAyIF0gfHwgXCJweFwiICkgOlxuXHRcdHZhbHVlO1xufVxuXG5mdW5jdGlvbiBhdWdtZW50V2lkdGhPckhlaWdodCggZWxlbSwgbmFtZSwgZXh0cmEsIGlzQm9yZGVyQm94LCBzdHlsZXMgKSB7XG5cdHZhciBpID0gZXh0cmEgPT09ICggaXNCb3JkZXJCb3ggPyBcImJvcmRlclwiIDogXCJjb250ZW50XCIgKSA/XG5cdFx0Ly8gSWYgd2UgYWxyZWFkeSBoYXZlIHRoZSByaWdodCBtZWFzdXJlbWVudCwgYXZvaWQgYXVnbWVudGF0aW9uXG5cdFx0NCA6XG5cdFx0Ly8gT3RoZXJ3aXNlIGluaXRpYWxpemUgZm9yIGhvcml6b250YWwgb3IgdmVydGljYWwgcHJvcGVydGllc1xuXHRcdG5hbWUgPT09IFwid2lkdGhcIiA/IDEgOiAwLFxuXG5cdFx0dmFsID0gMDtcblxuXHRmb3IgKCA7IGkgPCA0OyBpICs9IDIgKSB7XG5cdFx0Ly8gYm90aCBib3ggbW9kZWxzIGV4Y2x1ZGUgbWFyZ2luLCBzbyBhZGQgaXQgaWYgd2Ugd2FudCBpdFxuXHRcdGlmICggZXh0cmEgPT09IFwibWFyZ2luXCIgKSB7XG5cdFx0XHR2YWwgKz0galF1ZXJ5LmNzcyggZWxlbSwgZXh0cmEgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBpc0JvcmRlckJveCApIHtcblx0XHRcdC8vIGJvcmRlci1ib3ggaW5jbHVkZXMgcGFkZGluZywgc28gcmVtb3ZlIGl0IGlmIHdlIHdhbnQgY29udGVudFxuXHRcdFx0aWYgKCBleHRyYSA9PT0gXCJjb250ZW50XCIgKSB7XG5cdFx0XHRcdHZhbCAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gYXQgdGhpcyBwb2ludCwgZXh0cmEgaXNuJ3QgYm9yZGVyIG5vciBtYXJnaW4sIHNvIHJlbW92ZSBib3JkZXJcblx0XHRcdGlmICggZXh0cmEgIT09IFwibWFyZ2luXCIgKSB7XG5cdFx0XHRcdHZhbCAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBhdCB0aGlzIHBvaW50LCBleHRyYSBpc24ndCBjb250ZW50LCBzbyBhZGQgcGFkZGluZ1xuXHRcdFx0dmFsICs9IGpRdWVyeS5jc3MoIGVsZW0sIFwicGFkZGluZ1wiICsgY3NzRXhwYW5kWyBpIF0sIHRydWUsIHN0eWxlcyApO1xuXG5cdFx0XHQvLyBhdCB0aGlzIHBvaW50LCBleHRyYSBpc24ndCBjb250ZW50IG5vciBwYWRkaW5nLCBzbyBhZGQgYm9yZGVyXG5cdFx0XHRpZiAoIGV4dHJhICE9PSBcInBhZGRpbmdcIiApIHtcblx0XHRcdFx0dmFsICs9IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm9yZGVyXCIgKyBjc3NFeHBhbmRbIGkgXSArIFwiV2lkdGhcIiwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHZhbDtcbn1cblxuZnVuY3Rpb24gZ2V0V2lkdGhPckhlaWdodCggZWxlbSwgbmFtZSwgZXh0cmEgKSB7XG5cblx0Ly8gU3RhcnQgd2l0aCBvZmZzZXQgcHJvcGVydHksIHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8gdGhlIGJvcmRlci1ib3ggdmFsdWVcblx0dmFyIHZhbHVlSXNCb3JkZXJCb3ggPSB0cnVlLFxuXHRcdHZhbCA9IG5hbWUgPT09IFwid2lkdGhcIiA/IGVsZW0ub2Zmc2V0V2lkdGggOiBlbGVtLm9mZnNldEhlaWdodCxcblx0XHRzdHlsZXMgPSBnZXRTdHlsZXMoIGVsZW0gKSxcblx0XHRpc0JvcmRlckJveCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCI7XG5cblx0Ly8gc29tZSBub24taHRtbCBlbGVtZW50cyByZXR1cm4gdW5kZWZpbmVkIGZvciBvZmZzZXRXaWR0aCwgc28gY2hlY2sgZm9yIG51bGwvdW5kZWZpbmVkXG5cdC8vIHN2ZyAtIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY0OTI4NVxuXHQvLyBNYXRoTUwgLSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD00OTE2Njhcblx0aWYgKCB2YWwgPD0gMCB8fCB2YWwgPT0gbnVsbCApIHtcblx0XHQvLyBGYWxsIGJhY2sgdG8gY29tcHV0ZWQgdGhlbiB1bmNvbXB1dGVkIGNzcyBpZiBuZWNlc3Nhcnlcblx0XHR2YWwgPSBjdXJDU1MoIGVsZW0sIG5hbWUsIHN0eWxlcyApO1xuXHRcdGlmICggdmFsIDwgMCB8fCB2YWwgPT0gbnVsbCApIHtcblx0XHRcdHZhbCA9IGVsZW0uc3R5bGVbIG5hbWUgXTtcblx0XHR9XG5cblx0XHQvLyBDb21wdXRlZCB1bml0IGlzIG5vdCBwaXhlbHMuIFN0b3AgaGVyZSBhbmQgcmV0dXJuLlxuXHRcdGlmICggcm51bW5vbnB4LnRlc3QodmFsKSApIHtcblx0XHRcdHJldHVybiB2YWw7XG5cdFx0fVxuXG5cdFx0Ly8gd2UgbmVlZCB0aGUgY2hlY2sgZm9yIHN0eWxlIGluIGNhc2UgYSBicm93c2VyIHdoaWNoIHJldHVybnMgdW5yZWxpYWJsZSB2YWx1ZXNcblx0XHQvLyBmb3IgZ2V0Q29tcHV0ZWRTdHlsZSBzaWxlbnRseSBmYWxscyBiYWNrIHRvIHRoZSByZWxpYWJsZSBlbGVtLnN0eWxlXG5cdFx0dmFsdWVJc0JvcmRlckJveCA9IGlzQm9yZGVyQm94ICYmXG5cdFx0XHQoIHN1cHBvcnQuYm94U2l6aW5nUmVsaWFibGUoKSB8fCB2YWwgPT09IGVsZW0uc3R5bGVbIG5hbWUgXSApO1xuXG5cdFx0Ly8gTm9ybWFsaXplIFwiXCIsIGF1dG8sIGFuZCBwcmVwYXJlIGZvciBleHRyYVxuXHRcdHZhbCA9IHBhcnNlRmxvYXQoIHZhbCApIHx8IDA7XG5cdH1cblxuXHQvLyB1c2UgdGhlIGFjdGl2ZSBib3gtc2l6aW5nIG1vZGVsIHRvIGFkZC9zdWJ0cmFjdCBpcnJlbGV2YW50IHN0eWxlc1xuXHRyZXR1cm4gKCB2YWwgK1xuXHRcdGF1Z21lbnRXaWR0aE9ySGVpZ2h0KFxuXHRcdFx0ZWxlbSxcblx0XHRcdG5hbWUsXG5cdFx0XHRleHRyYSB8fCAoIGlzQm9yZGVyQm94ID8gXCJib3JkZXJcIiA6IFwiY29udGVudFwiICksXG5cdFx0XHR2YWx1ZUlzQm9yZGVyQm94LFxuXHRcdFx0c3R5bGVzXG5cdFx0KVxuXHQpICsgXCJweFwiO1xufVxuXG5mdW5jdGlvbiBzaG93SGlkZSggZWxlbWVudHMsIHNob3cgKSB7XG5cdHZhciBkaXNwbGF5LCBlbGVtLCBoaWRkZW4sXG5cdFx0dmFsdWVzID0gW10sXG5cdFx0aW5kZXggPSAwLFxuXHRcdGxlbmd0aCA9IGVsZW1lbnRzLmxlbmd0aDtcblxuXHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdGVsZW0gPSBlbGVtZW50c1sgaW5kZXggXTtcblx0XHRpZiAoICFlbGVtLnN0eWxlICkge1xuXHRcdFx0Y29udGludWU7XG5cdFx0fVxuXG5cdFx0dmFsdWVzWyBpbmRleCBdID0gZGF0YV9wcml2LmdldCggZWxlbSwgXCJvbGRkaXNwbGF5XCIgKTtcblx0XHRkaXNwbGF5ID0gZWxlbS5zdHlsZS5kaXNwbGF5O1xuXHRcdGlmICggc2hvdyApIHtcblx0XHRcdC8vIFJlc2V0IHRoZSBpbmxpbmUgZGlzcGxheSBvZiB0aGlzIGVsZW1lbnQgdG8gbGVhcm4gaWYgaXQgaXNcblx0XHRcdC8vIGJlaW5nIGhpZGRlbiBieSBjYXNjYWRlZCBydWxlcyBvciBub3Rcblx0XHRcdGlmICggIXZhbHVlc1sgaW5kZXggXSAmJiBkaXNwbGF5ID09PSBcIm5vbmVcIiApIHtcblx0XHRcdFx0ZWxlbS5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2V0IGVsZW1lbnRzIHdoaWNoIGhhdmUgYmVlbiBvdmVycmlkZGVuIHdpdGggZGlzcGxheTogbm9uZVxuXHRcdFx0Ly8gaW4gYSBzdHlsZXNoZWV0IHRvIHdoYXRldmVyIHRoZSBkZWZhdWx0IGJyb3dzZXIgc3R5bGUgaXNcblx0XHRcdC8vIGZvciBzdWNoIGFuIGVsZW1lbnRcblx0XHRcdGlmICggZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICYmIGlzSGlkZGVuKCBlbGVtICkgKSB7XG5cdFx0XHRcdHZhbHVlc1sgaW5kZXggXSA9IGRhdGFfcHJpdi5hY2Nlc3MoIGVsZW0sIFwib2xkZGlzcGxheVwiLCBkZWZhdWx0RGlzcGxheShlbGVtLm5vZGVOYW1lKSApO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRoaWRkZW4gPSBpc0hpZGRlbiggZWxlbSApO1xuXG5cdFx0XHRpZiAoIGRpc3BsYXkgIT09IFwibm9uZVwiIHx8ICFoaWRkZW4gKSB7XG5cdFx0XHRcdGRhdGFfcHJpdi5zZXQoIGVsZW0sIFwib2xkZGlzcGxheVwiLCBoaWRkZW4gPyBkaXNwbGF5IDogalF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIFNldCB0aGUgZGlzcGxheSBvZiBtb3N0IG9mIHRoZSBlbGVtZW50cyBpbiBhIHNlY29uZCBsb29wXG5cdC8vIHRvIGF2b2lkIHRoZSBjb25zdGFudCByZWZsb3dcblx0Zm9yICggaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRlbGVtID0gZWxlbWVudHNbIGluZGV4IF07XG5cdFx0aWYgKCAhZWxlbS5zdHlsZSApIHtcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblx0XHRpZiAoICFzaG93IHx8IGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJub25lXCIgfHwgZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICkge1xuXHRcdFx0ZWxlbS5zdHlsZS5kaXNwbGF5ID0gc2hvdyA/IHZhbHVlc1sgaW5kZXggXSB8fCBcIlwiIDogXCJub25lXCI7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW1lbnRzO1xufVxuXG5qUXVlcnkuZXh0ZW5kKHtcblx0Ly8gQWRkIGluIHN0eWxlIHByb3BlcnR5IGhvb2tzIGZvciBvdmVycmlkaW5nIHRoZSBkZWZhdWx0XG5cdC8vIGJlaGF2aW9yIG9mIGdldHRpbmcgYW5kIHNldHRpbmcgYSBzdHlsZSBwcm9wZXJ0eVxuXHRjc3NIb29rczoge1xuXHRcdG9wYWNpdHk6IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkge1xuXHRcdFx0XHRpZiAoIGNvbXB1dGVkICkge1xuXHRcdFx0XHRcdC8vIFdlIHNob3VsZCBhbHdheXMgZ2V0IGEgbnVtYmVyIGJhY2sgZnJvbSBvcGFjaXR5XG5cdFx0XHRcdFx0dmFyIHJldCA9IGN1ckNTUyggZWxlbSwgXCJvcGFjaXR5XCIgKTtcblx0XHRcdFx0XHRyZXR1cm4gcmV0ID09PSBcIlwiID8gXCIxXCIgOiByZXQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0Ly8gRG9uJ3QgYXV0b21hdGljYWxseSBhZGQgXCJweFwiIHRvIHRoZXNlIHBvc3NpYmx5LXVuaXRsZXNzIHByb3BlcnRpZXNcblx0Y3NzTnVtYmVyOiB7XG5cdFx0XCJjb2x1bW5Db3VudFwiOiB0cnVlLFxuXHRcdFwiZmlsbE9wYWNpdHlcIjogdHJ1ZSxcblx0XHRcImZsZXhHcm93XCI6IHRydWUsXG5cdFx0XCJmbGV4U2hyaW5rXCI6IHRydWUsXG5cdFx0XCJmb250V2VpZ2h0XCI6IHRydWUsXG5cdFx0XCJsaW5lSGVpZ2h0XCI6IHRydWUsXG5cdFx0XCJvcGFjaXR5XCI6IHRydWUsXG5cdFx0XCJvcmRlclwiOiB0cnVlLFxuXHRcdFwib3JwaGFuc1wiOiB0cnVlLFxuXHRcdFwid2lkb3dzXCI6IHRydWUsXG5cdFx0XCJ6SW5kZXhcIjogdHJ1ZSxcblx0XHRcInpvb21cIjogdHJ1ZVxuXHR9LFxuXG5cdC8vIEFkZCBpbiBwcm9wZXJ0aWVzIHdob3NlIG5hbWVzIHlvdSB3aXNoIHRvIGZpeCBiZWZvcmVcblx0Ly8gc2V0dGluZyBvciBnZXR0aW5nIHRoZSB2YWx1ZVxuXHRjc3NQcm9wczoge1xuXHRcdC8vIG5vcm1hbGl6ZSBmbG9hdCBjc3MgcHJvcGVydHlcblx0XHRcImZsb2F0XCI6IFwiY3NzRmxvYXRcIlxuXHR9LFxuXG5cdC8vIEdldCBhbmQgc2V0IHRoZSBzdHlsZSBwcm9wZXJ0eSBvbiBhIERPTSBOb2RlXG5cdHN0eWxlOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUsIGV4dHJhICkge1xuXHRcdC8vIERvbid0IHNldCBzdHlsZXMgb24gdGV4dCBhbmQgY29tbWVudCBub2Rlc1xuXHRcdGlmICggIWVsZW0gfHwgZWxlbS5ub2RlVHlwZSA9PT0gMyB8fCBlbGVtLm5vZGVUeXBlID09PSA4IHx8ICFlbGVtLnN0eWxlICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHdlJ3JlIHdvcmtpbmcgd2l0aCB0aGUgcmlnaHQgbmFtZVxuXHRcdHZhciByZXQsIHR5cGUsIGhvb2tzLFxuXHRcdFx0b3JpZ05hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBuYW1lICksXG5cdFx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0XHRuYW1lID0galF1ZXJ5LmNzc1Byb3BzWyBvcmlnTmFtZSBdIHx8ICggalF1ZXJ5LmNzc1Byb3BzWyBvcmlnTmFtZSBdID0gdmVuZG9yUHJvcE5hbWUoIHN0eWxlLCBvcmlnTmFtZSApICk7XG5cblx0XHQvLyBnZXRzIGhvb2sgZm9yIHRoZSBwcmVmaXhlZCB2ZXJzaW9uXG5cdFx0Ly8gZm9sbG93ZWQgYnkgdGhlIHVucHJlZml4ZWQgdmVyc2lvblxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF0gfHwgalF1ZXJ5LmNzc0hvb2tzWyBvcmlnTmFtZSBdO1xuXG5cdFx0Ly8gQ2hlY2sgaWYgd2UncmUgc2V0dGluZyBhIHZhbHVlXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0dHlwZSA9IHR5cGVvZiB2YWx1ZTtcblxuXHRcdFx0Ly8gY29udmVydCByZWxhdGl2ZSBudW1iZXIgc3RyaW5ncyAoKz0gb3IgLT0pIHRvIHJlbGF0aXZlIG51bWJlcnMuICM3MzQ1XG5cdFx0XHRpZiAoIHR5cGUgPT09IFwic3RyaW5nXCIgJiYgKHJldCA9IHJyZWxOdW0uZXhlYyggdmFsdWUgKSkgKSB7XG5cdFx0XHRcdHZhbHVlID0gKCByZXRbMV0gKyAxICkgKiByZXRbMl0gKyBwYXJzZUZsb2F0KCBqUXVlcnkuY3NzKCBlbGVtLCBuYW1lICkgKTtcblx0XHRcdFx0Ly8gRml4ZXMgYnVnICM5MjM3XG5cdFx0XHRcdHR5cGUgPSBcIm51bWJlclwiO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBNYWtlIHN1cmUgdGhhdCBudWxsIGFuZCBOYU4gdmFsdWVzIGFyZW4ndCBzZXQuIFNlZTogIzcxMTZcblx0XHRcdGlmICggdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSAhPT0gdmFsdWUgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgYSBudW1iZXIgd2FzIHBhc3NlZCBpbiwgYWRkICdweCcgdG8gdGhlIChleGNlcHQgZm9yIGNlcnRhaW4gQ1NTIHByb3BlcnRpZXMpXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwibnVtYmVyXCIgJiYgIWpRdWVyeS5jc3NOdW1iZXJbIG9yaWdOYW1lIF0gKSB7XG5cdFx0XHRcdHZhbHVlICs9IFwicHhcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRml4ZXMgIzg5MDgsIGl0IGNhbiBiZSBkb25lIG1vcmUgY29ycmVjdGx5IGJ5IHNwZWNpZnlpbmcgc2V0dGVycyBpbiBjc3NIb29rcyxcblx0XHRcdC8vIGJ1dCBpdCB3b3VsZCBtZWFuIHRvIGRlZmluZSBlaWdodCAoZm9yIGV2ZXJ5IHByb2JsZW1hdGljIHByb3BlcnR5KSBpZGVudGljYWwgZnVuY3Rpb25zXG5cdFx0XHRpZiAoICFzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSAmJiB2YWx1ZSA9PT0gXCJcIiAmJiBuYW1lLmluZGV4T2YoIFwiYmFja2dyb3VuZFwiICkgPT09IDAgKSB7XG5cdFx0XHRcdHN0eWxlWyBuYW1lIF0gPSBcImluaGVyaXRcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCwgdXNlIHRoYXQgdmFsdWUsIG90aGVyd2lzZSBqdXN0IHNldCB0aGUgc3BlY2lmaWVkIHZhbHVlXG5cdFx0XHRpZiAoICFob29rcyB8fCAhKFwic2V0XCIgaW4gaG9va3MpIHx8ICh2YWx1ZSA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIGV4dHJhICkpICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHN0eWxlWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkIGdldCB0aGUgbm9uLWNvbXB1dGVkIHZhbHVlIGZyb20gdGhlcmVcblx0XHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAocmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBmYWxzZSwgZXh0cmEgKSkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIGp1c3QgZ2V0IHRoZSB2YWx1ZSBmcm9tIHRoZSBzdHlsZSBvYmplY3Rcblx0XHRcdHJldHVybiBzdHlsZVsgbmFtZSBdO1xuXHRcdH1cblx0fSxcblxuXHRjc3M6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBleHRyYSwgc3R5bGVzICkge1xuXHRcdHZhciB2YWwsIG51bSwgaG9va3MsXG5cdFx0XHRvcmlnTmFtZSA9IGpRdWVyeS5jYW1lbENhc2UoIG5hbWUgKTtcblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHdlJ3JlIHdvcmtpbmcgd2l0aCB0aGUgcmlnaHQgbmFtZVxuXHRcdG5hbWUgPSBqUXVlcnkuY3NzUHJvcHNbIG9yaWdOYW1lIF0gfHwgKCBqUXVlcnkuY3NzUHJvcHNbIG9yaWdOYW1lIF0gPSB2ZW5kb3JQcm9wTmFtZSggZWxlbS5zdHlsZSwgb3JpZ05hbWUgKSApO1xuXG5cdFx0Ly8gZ2V0cyBob29rIGZvciB0aGUgcHJlZml4ZWQgdmVyc2lvblxuXHRcdC8vIGZvbGxvd2VkIGJ5IHRoZSB1bnByZWZpeGVkIHZlcnNpb25cblx0XHRob29rcyA9IGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdIHx8IGpRdWVyeS5jc3NIb29rc1sgb3JpZ05hbWUgXTtcblxuXHRcdC8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQgZ2V0IHRoZSBjb21wdXRlZCB2YWx1ZSBmcm9tIHRoZXJlXG5cdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICkge1xuXHRcdFx0dmFsID0gaG9va3MuZ2V0KCBlbGVtLCB0cnVlLCBleHRyYSApO1xuXHRcdH1cblxuXHRcdC8vIE90aGVyd2lzZSwgaWYgYSB3YXkgdG8gZ2V0IHRoZSBjb21wdXRlZCB2YWx1ZSBleGlzdHMsIHVzZSB0aGF0XG5cdFx0aWYgKCB2YWwgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHZhbCA9IGN1ckNTUyggZWxlbSwgbmFtZSwgc3R5bGVzICk7XG5cdFx0fVxuXG5cdFx0Ly9jb252ZXJ0IFwibm9ybWFsXCIgdG8gY29tcHV0ZWQgdmFsdWVcblx0XHRpZiAoIHZhbCA9PT0gXCJub3JtYWxcIiAmJiBuYW1lIGluIGNzc05vcm1hbFRyYW5zZm9ybSApIHtcblx0XHRcdHZhbCA9IGNzc05vcm1hbFRyYW5zZm9ybVsgbmFtZSBdO1xuXHRcdH1cblxuXHRcdC8vIFJldHVybiwgY29udmVydGluZyB0byBudW1iZXIgaWYgZm9yY2VkIG9yIGEgcXVhbGlmaWVyIHdhcyBwcm92aWRlZCBhbmQgdmFsIGxvb2tzIG51bWVyaWNcblx0XHRpZiAoIGV4dHJhID09PSBcIlwiIHx8IGV4dHJhICkge1xuXHRcdFx0bnVtID0gcGFyc2VGbG9hdCggdmFsICk7XG5cdFx0XHRyZXR1cm4gZXh0cmEgPT09IHRydWUgfHwgalF1ZXJ5LmlzTnVtZXJpYyggbnVtICkgPyBudW0gfHwgMCA6IHZhbDtcblx0XHR9XG5cdFx0cmV0dXJuIHZhbDtcblx0fVxufSk7XG5cbmpRdWVyeS5lYWNoKFsgXCJoZWlnaHRcIiwgXCJ3aWR0aFwiIF0sIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSA9IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCwgZXh0cmEgKSB7XG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xuXHRcdFx0XHQvLyBjZXJ0YWluIGVsZW1lbnRzIGNhbiBoYXZlIGRpbWVuc2lvbiBpbmZvIGlmIHdlIGludmlzaWJseSBzaG93IHRoZW1cblx0XHRcdFx0Ly8gaG93ZXZlciwgaXQgbXVzdCBoYXZlIGEgY3VycmVudCBkaXNwbGF5IHN0eWxlIHRoYXQgd291bGQgYmVuZWZpdCBmcm9tIHRoaXNcblx0XHRcdFx0cmV0dXJuIHJkaXNwbGF5c3dhcC50ZXN0KCBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApICkgJiYgZWxlbS5vZmZzZXRXaWR0aCA9PT0gMCA/XG5cdFx0XHRcdFx0alF1ZXJ5LnN3YXAoIGVsZW0sIGNzc1Nob3csIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhICk7XG5cdFx0XHRcdFx0fSkgOlxuXHRcdFx0XHRcdGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhICk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlLCBleHRyYSApIHtcblx0XHRcdHZhciBzdHlsZXMgPSBleHRyYSAmJiBnZXRTdHlsZXMoIGVsZW0gKTtcblx0XHRcdHJldHVybiBzZXRQb3NpdGl2ZU51bWJlciggZWxlbSwgdmFsdWUsIGV4dHJhID9cblx0XHRcdFx0YXVnbWVudFdpZHRoT3JIZWlnaHQoXG5cdFx0XHRcdFx0ZWxlbSxcblx0XHRcdFx0XHRuYW1lLFxuXHRcdFx0XHRcdGV4dHJhLFxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCIsXG5cdFx0XHRcdFx0c3R5bGVzXG5cdFx0XHRcdCkgOiAwXG5cdFx0XHQpO1xuXHRcdH1cblx0fTtcbn0pO1xuXG4vLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xualF1ZXJ5LmNzc0hvb2tzLm1hcmdpblJpZ2h0ID0gYWRkR2V0SG9va0lmKCBzdXBwb3J0LnJlbGlhYmxlTWFyZ2luUmlnaHQsXG5cdGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRpZiAoIGNvbXB1dGVkICkge1xuXHRcdFx0Ly8gV2ViS2l0IEJ1ZyAxMzM0MyAtIGdldENvbXB1dGVkU3R5bGUgcmV0dXJucyB3cm9uZyB2YWx1ZSBmb3IgbWFyZ2luLXJpZ2h0XG5cdFx0XHQvLyBXb3JrIGFyb3VuZCBieSB0ZW1wb3JhcmlseSBzZXR0aW5nIGVsZW1lbnQgZGlzcGxheSB0byBpbmxpbmUtYmxvY2tcblx0XHRcdHJldHVybiBqUXVlcnkuc3dhcCggZWxlbSwgeyBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIiB9LFxuXHRcdFx0XHRjdXJDU1MsIFsgZWxlbSwgXCJtYXJnaW5SaWdodFwiIF0gKTtcblx0XHR9XG5cdH1cbik7XG5cbi8vIFRoZXNlIGhvb2tzIGFyZSB1c2VkIGJ5IGFuaW1hdGUgdG8gZXhwYW5kIHByb3BlcnRpZXNcbmpRdWVyeS5lYWNoKHtcblx0bWFyZ2luOiBcIlwiLFxuXHRwYWRkaW5nOiBcIlwiLFxuXHRib3JkZXI6IFwiV2lkdGhcIlxufSwgZnVuY3Rpb24oIHByZWZpeCwgc3VmZml4ICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIHByZWZpeCArIHN1ZmZpeCBdID0ge1xuXHRcdGV4cGFuZDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0dmFyIGkgPSAwLFxuXHRcdFx0XHRleHBhbmRlZCA9IHt9LFxuXG5cdFx0XHRcdC8vIGFzc3VtZXMgYSBzaW5nbGUgbnVtYmVyIGlmIG5vdCBhIHN0cmluZ1xuXHRcdFx0XHRwYXJ0cyA9IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHZhbHVlLnNwbGl0KFwiIFwiKSA6IFsgdmFsdWUgXTtcblxuXHRcdFx0Zm9yICggOyBpIDwgNDsgaSsrICkge1xuXHRcdFx0XHRleHBhbmRlZFsgcHJlZml4ICsgY3NzRXhwYW5kWyBpIF0gKyBzdWZmaXggXSA9XG5cdFx0XHRcdFx0cGFydHNbIGkgXSB8fCBwYXJ0c1sgaSAtIDIgXSB8fCBwYXJ0c1sgMCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZXhwYW5kZWQ7XG5cdFx0fVxuXHR9O1xuXG5cdGlmICggIXJtYXJnaW4udGVzdCggcHJlZml4ICkgKSB7XG5cdFx0alF1ZXJ5LmNzc0hvb2tzWyBwcmVmaXggKyBzdWZmaXggXS5zZXQgPSBzZXRQb3NpdGl2ZU51bWJlcjtcblx0fVxufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRjc3M6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7XG5cdFx0XHR2YXIgc3R5bGVzLCBsZW4sXG5cdFx0XHRcdG1hcCA9IHt9LFxuXHRcdFx0XHRpID0gMDtcblxuXHRcdFx0aWYgKCBqUXVlcnkuaXNBcnJheSggbmFtZSApICkge1xuXHRcdFx0XHRzdHlsZXMgPSBnZXRTdHlsZXMoIGVsZW0gKTtcblx0XHRcdFx0bGVuID0gbmFtZS5sZW5ndGg7XG5cblx0XHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdFx0bWFwWyBuYW1lWyBpIF0gXSA9IGpRdWVyeS5jc3MoIGVsZW0sIG5hbWVbIGkgXSwgZmFsc2UsIHN0eWxlcyApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIG1hcDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIG5hbWUsIHZhbHVlICkgOlxuXHRcdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCBuYW1lICk7XG5cdFx0fSwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XG5cdH0sXG5cdHNob3c6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzaG93SGlkZSggdGhpcywgdHJ1ZSApO1xuXHR9LFxuXHRoaWRlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gc2hvd0hpZGUoIHRoaXMgKTtcblx0fSxcblx0dG9nZ2xlOiBmdW5jdGlvbiggc3RhdGUgKSB7XG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGUgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdFx0cmV0dXJuIHN0YXRlID8gdGhpcy5zaG93KCkgOiB0aGlzLmhpZGUoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBpc0hpZGRlbiggdGhpcyApICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5zaG93KCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5oaWRlKCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5cbmZ1bmN0aW9uIFR3ZWVuKCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApIHtcblx0cmV0dXJuIG5ldyBUd2Vlbi5wcm90b3R5cGUuaW5pdCggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcgKTtcbn1cbmpRdWVyeS5Ud2VlbiA9IFR3ZWVuO1xuXG5Ud2Vlbi5wcm90b3R5cGUgPSB7XG5cdGNvbnN0cnVjdG9yOiBUd2Vlbixcblx0aW5pdDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nLCB1bml0ICkge1xuXHRcdHRoaXMuZWxlbSA9IGVsZW07XG5cdFx0dGhpcy5wcm9wID0gcHJvcDtcblx0XHR0aGlzLmVhc2luZyA9IGVhc2luZyB8fCBcInN3aW5nXCI7XG5cdFx0dGhpcy5vcHRpb25zID0gb3B0aW9ucztcblx0XHR0aGlzLnN0YXJ0ID0gdGhpcy5ub3cgPSB0aGlzLmN1cigpO1xuXHRcdHRoaXMuZW5kID0gZW5kO1xuXHRcdHRoaXMudW5pdCA9IHVuaXQgfHwgKCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gPyBcIlwiIDogXCJweFwiICk7XG5cdH0sXG5cdGN1cjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGhvb2tzID0gVHdlZW4ucHJvcEhvb2tzWyB0aGlzLnByb3AgXTtcblxuXHRcdHJldHVybiBob29rcyAmJiBob29rcy5nZXQgP1xuXHRcdFx0aG9va3MuZ2V0KCB0aGlzICkgOlxuXHRcdFx0VHdlZW4ucHJvcEhvb2tzLl9kZWZhdWx0LmdldCggdGhpcyApO1xuXHR9LFxuXHRydW46IGZ1bmN0aW9uKCBwZXJjZW50ICkge1xuXHRcdHZhciBlYXNlZCxcblx0XHRcdGhvb2tzID0gVHdlZW4ucHJvcEhvb2tzWyB0aGlzLnByb3AgXTtcblxuXHRcdGlmICggdGhpcy5vcHRpb25zLmR1cmF0aW9uICkge1xuXHRcdFx0dGhpcy5wb3MgPSBlYXNlZCA9IGpRdWVyeS5lYXNpbmdbIHRoaXMuZWFzaW5nIF0oXG5cdFx0XHRcdHBlcmNlbnQsIHRoaXMub3B0aW9ucy5kdXJhdGlvbiAqIHBlcmNlbnQsIDAsIDEsIHRoaXMub3B0aW9ucy5kdXJhdGlvblxuXHRcdFx0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5wb3MgPSBlYXNlZCA9IHBlcmNlbnQ7XG5cdFx0fVxuXHRcdHRoaXMubm93ID0gKCB0aGlzLmVuZCAtIHRoaXMuc3RhcnQgKSAqIGVhc2VkICsgdGhpcy5zdGFydDtcblxuXHRcdGlmICggdGhpcy5vcHRpb25zLnN0ZXAgKSB7XG5cdFx0XHR0aGlzLm9wdGlvbnMuc3RlcC5jYWxsKCB0aGlzLmVsZW0sIHRoaXMubm93LCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBob29rcyAmJiBob29rcy5zZXQgKSB7XG5cdFx0XHRob29rcy5zZXQoIHRoaXMgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0VHdlZW4ucHJvcEhvb2tzLl9kZWZhdWx0LnNldCggdGhpcyApO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxufTtcblxuVHdlZW4ucHJvdG90eXBlLmluaXQucHJvdG90eXBlID0gVHdlZW4ucHJvdG90eXBlO1xuXG5Ud2Vlbi5wcm9wSG9va3MgPSB7XG5cdF9kZWZhdWx0OiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggdHdlZW4gKSB7XG5cdFx0XHR2YXIgcmVzdWx0O1xuXG5cdFx0XHRpZiAoIHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSAhPSBudWxsICYmXG5cdFx0XHRcdCghdHdlZW4uZWxlbS5zdHlsZSB8fCB0d2Vlbi5lbGVtLnN0eWxlWyB0d2Vlbi5wcm9wIF0gPT0gbnVsbCkgKSB7XG5cdFx0XHRcdHJldHVybiB0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF07XG5cdFx0XHR9XG5cblx0XHRcdC8vIHBhc3NpbmcgYW4gZW1wdHkgc3RyaW5nIGFzIGEgM3JkIHBhcmFtZXRlciB0byAuY3NzIHdpbGwgYXV0b21hdGljYWxseVxuXHRcdFx0Ly8gYXR0ZW1wdCBhIHBhcnNlRmxvYXQgYW5kIGZhbGxiYWNrIHRvIGEgc3RyaW5nIGlmIHRoZSBwYXJzZSBmYWlsc1xuXHRcdFx0Ly8gc28sIHNpbXBsZSB2YWx1ZXMgc3VjaCBhcyBcIjEwcHhcIiBhcmUgcGFyc2VkIHRvIEZsb2F0LlxuXHRcdFx0Ly8gY29tcGxleCB2YWx1ZXMgc3VjaCBhcyBcInJvdGF0ZSgxcmFkKVwiIGFyZSByZXR1cm5lZCBhcyBpcy5cblx0XHRcdHJlc3VsdCA9IGpRdWVyeS5jc3MoIHR3ZWVuLmVsZW0sIHR3ZWVuLnByb3AsIFwiXCIgKTtcblx0XHRcdC8vIEVtcHR5IHN0cmluZ3MsIG51bGwsIHVuZGVmaW5lZCBhbmQgXCJhdXRvXCIgYXJlIGNvbnZlcnRlZCB0byAwLlxuXHRcdFx0cmV0dXJuICFyZXN1bHQgfHwgcmVzdWx0ID09PSBcImF1dG9cIiA/IDAgOiByZXN1bHQ7XG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcblx0XHRcdC8vIHVzZSBzdGVwIGhvb2sgZm9yIGJhY2sgY29tcGF0IC0gdXNlIGNzc0hvb2sgaWYgaXRzIHRoZXJlIC0gdXNlIC5zdHlsZSBpZiBpdHNcblx0XHRcdC8vIGF2YWlsYWJsZSBhbmQgdXNlIHBsYWluIHByb3BlcnRpZXMgd2hlcmUgYXZhaWxhYmxlXG5cdFx0XHRpZiAoIGpRdWVyeS5meC5zdGVwWyB0d2Vlbi5wcm9wIF0gKSB7XG5cdFx0XHRcdGpRdWVyeS5meC5zdGVwWyB0d2Vlbi5wcm9wIF0oIHR3ZWVuICk7XG5cdFx0XHR9IGVsc2UgaWYgKCB0d2Vlbi5lbGVtLnN0eWxlICYmICggdHdlZW4uZWxlbS5zdHlsZVsgalF1ZXJ5LmNzc1Byb3BzWyB0d2Vlbi5wcm9wIF0gXSAhPSBudWxsIHx8IGpRdWVyeS5jc3NIb29rc1sgdHdlZW4ucHJvcCBdICkgKSB7XG5cdFx0XHRcdGpRdWVyeS5zdHlsZSggdHdlZW4uZWxlbSwgdHdlZW4ucHJvcCwgdHdlZW4ubm93ICsgdHdlZW4udW5pdCApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdID0gdHdlZW4ubm93O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufTtcblxuLy8gU3VwcG9ydDogSUU5XG4vLyBQYW5pYyBiYXNlZCBhcHByb2FjaCB0byBzZXR0aW5nIHRoaW5ncyBvbiBkaXNjb25uZWN0ZWQgbm9kZXNcblxuVHdlZW4ucHJvcEhvb2tzLnNjcm9sbFRvcCA9IFR3ZWVuLnByb3BIb29rcy5zY3JvbGxMZWZ0ID0ge1xuXHRzZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcblx0XHRpZiAoIHR3ZWVuLmVsZW0ubm9kZVR5cGUgJiYgdHdlZW4uZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0dHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdID0gdHdlZW4ubm93O1xuXHRcdH1cblx0fVxufTtcblxualF1ZXJ5LmVhc2luZyA9IHtcblx0bGluZWFyOiBmdW5jdGlvbiggcCApIHtcblx0XHRyZXR1cm4gcDtcblx0fSxcblx0c3dpbmc6IGZ1bmN0aW9uKCBwICkge1xuXHRcdHJldHVybiAwLjUgLSBNYXRoLmNvcyggcCAqIE1hdGguUEkgKSAvIDI7XG5cdH1cbn07XG5cbmpRdWVyeS5meCA9IFR3ZWVuLnByb3RvdHlwZS5pbml0O1xuXG4vLyBCYWNrIENvbXBhdCA8MS44IGV4dGVuc2lvbiBwb2ludFxualF1ZXJ5LmZ4LnN0ZXAgPSB7fTtcblxuXG5cblxudmFyXG5cdGZ4Tm93LCB0aW1lcklkLFxuXHRyZnh0eXBlcyA9IC9eKD86dG9nZ2xlfHNob3d8aGlkZSkkLyxcblx0cmZ4bnVtID0gbmV3IFJlZ0V4cCggXCJeKD86KFsrLV0pPXwpKFwiICsgcG51bSArIFwiKShbYS16JV0qKSRcIiwgXCJpXCIgKSxcblx0cnJ1biA9IC9xdWV1ZUhvb2tzJC8sXG5cdGFuaW1hdGlvblByZWZpbHRlcnMgPSBbIGRlZmF1bHRQcmVmaWx0ZXIgXSxcblx0dHdlZW5lcnMgPSB7XG5cdFx0XCIqXCI6IFsgZnVuY3Rpb24oIHByb3AsIHZhbHVlICkge1xuXHRcdFx0dmFyIHR3ZWVuID0gdGhpcy5jcmVhdGVUd2VlbiggcHJvcCwgdmFsdWUgKSxcblx0XHRcdFx0dGFyZ2V0ID0gdHdlZW4uY3VyKCksXG5cdFx0XHRcdHBhcnRzID0gcmZ4bnVtLmV4ZWMoIHZhbHVlICksXG5cdFx0XHRcdHVuaXQgPSBwYXJ0cyAmJiBwYXJ0c1sgMyBdIHx8ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdID8gXCJcIiA6IFwicHhcIiApLFxuXG5cdFx0XHRcdC8vIFN0YXJ0aW5nIHZhbHVlIGNvbXB1dGF0aW9uIGlzIHJlcXVpcmVkIGZvciBwb3RlbnRpYWwgdW5pdCBtaXNtYXRjaGVzXG5cdFx0XHRcdHN0YXJ0ID0gKCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gfHwgdW5pdCAhPT0gXCJweFwiICYmICt0YXJnZXQgKSAmJlxuXHRcdFx0XHRcdHJmeG51bS5leGVjKCBqUXVlcnkuY3NzKCB0d2Vlbi5lbGVtLCBwcm9wICkgKSxcblx0XHRcdFx0c2NhbGUgPSAxLFxuXHRcdFx0XHRtYXhJdGVyYXRpb25zID0gMjA7XG5cblx0XHRcdGlmICggc3RhcnQgJiYgc3RhcnRbIDMgXSAhPT0gdW5pdCApIHtcblx0XHRcdFx0Ly8gVHJ1c3QgdW5pdHMgcmVwb3J0ZWQgYnkgalF1ZXJ5LmNzc1xuXHRcdFx0XHR1bml0ID0gdW5pdCB8fCBzdGFydFsgMyBdO1xuXG5cdFx0XHRcdC8vIE1ha2Ugc3VyZSB3ZSB1cGRhdGUgdGhlIHR3ZWVuIHByb3BlcnRpZXMgbGF0ZXIgb25cblx0XHRcdFx0cGFydHMgPSBwYXJ0cyB8fCBbXTtcblxuXHRcdFx0XHQvLyBJdGVyYXRpdmVseSBhcHByb3hpbWF0ZSBmcm9tIGEgbm9uemVybyBzdGFydGluZyBwb2ludFxuXHRcdFx0XHRzdGFydCA9ICt0YXJnZXQgfHwgMTtcblxuXHRcdFx0XHRkbyB7XG5cdFx0XHRcdFx0Ly8gSWYgcHJldmlvdXMgaXRlcmF0aW9uIHplcm9lZCBvdXQsIGRvdWJsZSB1bnRpbCB3ZSBnZXQgKnNvbWV0aGluZypcblx0XHRcdFx0XHQvLyBVc2UgYSBzdHJpbmcgZm9yIGRvdWJsaW5nIGZhY3RvciBzbyB3ZSBkb24ndCBhY2NpZGVudGFsbHkgc2VlIHNjYWxlIGFzIHVuY2hhbmdlZCBiZWxvd1xuXHRcdFx0XHRcdHNjYWxlID0gc2NhbGUgfHwgXCIuNVwiO1xuXG5cdFx0XHRcdFx0Ly8gQWRqdXN0IGFuZCBhcHBseVxuXHRcdFx0XHRcdHN0YXJ0ID0gc3RhcnQgLyBzY2FsZTtcblx0XHRcdFx0XHRqUXVlcnkuc3R5bGUoIHR3ZWVuLmVsZW0sIHByb3AsIHN0YXJ0ICsgdW5pdCApO1xuXG5cdFx0XHRcdC8vIFVwZGF0ZSBzY2FsZSwgdG9sZXJhdGluZyB6ZXJvIG9yIE5hTiBmcm9tIHR3ZWVuLmN1cigpXG5cdFx0XHRcdC8vIEFuZCBicmVha2luZyB0aGUgbG9vcCBpZiBzY2FsZSBpcyB1bmNoYW5nZWQgb3IgcGVyZmVjdCwgb3IgaWYgd2UndmUganVzdCBoYWQgZW5vdWdoXG5cdFx0XHRcdH0gd2hpbGUgKCBzY2FsZSAhPT0gKHNjYWxlID0gdHdlZW4uY3VyKCkgLyB0YXJnZXQpICYmIHNjYWxlICE9PSAxICYmIC0tbWF4SXRlcmF0aW9ucyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBVcGRhdGUgdHdlZW4gcHJvcGVydGllc1xuXHRcdFx0aWYgKCBwYXJ0cyApIHtcblx0XHRcdFx0c3RhcnQgPSB0d2Vlbi5zdGFydCA9ICtzdGFydCB8fCArdGFyZ2V0IHx8IDA7XG5cdFx0XHRcdHR3ZWVuLnVuaXQgPSB1bml0O1xuXHRcdFx0XHQvLyBJZiBhICs9Ly09IHRva2VuIHdhcyBwcm92aWRlZCwgd2UncmUgZG9pbmcgYSByZWxhdGl2ZSBhbmltYXRpb25cblx0XHRcdFx0dHdlZW4uZW5kID0gcGFydHNbIDEgXSA/XG5cdFx0XHRcdFx0c3RhcnQgKyAoIHBhcnRzWyAxIF0gKyAxICkgKiBwYXJ0c1sgMiBdIDpcblx0XHRcdFx0XHQrcGFydHNbIDIgXTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdH0gXVxuXHR9O1xuXG4vLyBBbmltYXRpb25zIGNyZWF0ZWQgc3luY2hyb25vdXNseSB3aWxsIHJ1biBzeW5jaHJvbm91c2x5XG5mdW5jdGlvbiBjcmVhdGVGeE5vdygpIHtcblx0c2V0VGltZW91dChmdW5jdGlvbigpIHtcblx0XHRmeE5vdyA9IHVuZGVmaW5lZDtcblx0fSk7XG5cdHJldHVybiAoIGZ4Tm93ID0galF1ZXJ5Lm5vdygpICk7XG59XG5cbi8vIEdlbmVyYXRlIHBhcmFtZXRlcnMgdG8gY3JlYXRlIGEgc3RhbmRhcmQgYW5pbWF0aW9uXG5mdW5jdGlvbiBnZW5GeCggdHlwZSwgaW5jbHVkZVdpZHRoICkge1xuXHR2YXIgd2hpY2gsXG5cdFx0aSA9IDAsXG5cdFx0YXR0cnMgPSB7IGhlaWdodDogdHlwZSB9O1xuXG5cdC8vIGlmIHdlIGluY2x1ZGUgd2lkdGgsIHN0ZXAgdmFsdWUgaXMgMSB0byBkbyBhbGwgY3NzRXhwYW5kIHZhbHVlcyxcblx0Ly8gaWYgd2UgZG9uJ3QgaW5jbHVkZSB3aWR0aCwgc3RlcCB2YWx1ZSBpcyAyIHRvIHNraXAgb3ZlciBMZWZ0IGFuZCBSaWdodFxuXHRpbmNsdWRlV2lkdGggPSBpbmNsdWRlV2lkdGggPyAxIDogMDtcblx0Zm9yICggOyBpIDwgNCA7IGkgKz0gMiAtIGluY2x1ZGVXaWR0aCApIHtcblx0XHR3aGljaCA9IGNzc0V4cGFuZFsgaSBdO1xuXHRcdGF0dHJzWyBcIm1hcmdpblwiICsgd2hpY2ggXSA9IGF0dHJzWyBcInBhZGRpbmdcIiArIHdoaWNoIF0gPSB0eXBlO1xuXHR9XG5cblx0aWYgKCBpbmNsdWRlV2lkdGggKSB7XG5cdFx0YXR0cnMub3BhY2l0eSA9IGF0dHJzLndpZHRoID0gdHlwZTtcblx0fVxuXG5cdHJldHVybiBhdHRycztcbn1cblxuZnVuY3Rpb24gY3JlYXRlVHdlZW4oIHZhbHVlLCBwcm9wLCBhbmltYXRpb24gKSB7XG5cdHZhciB0d2Vlbixcblx0XHRjb2xsZWN0aW9uID0gKCB0d2VlbmVyc1sgcHJvcCBdIHx8IFtdICkuY29uY2F0KCB0d2VlbmVyc1sgXCIqXCIgXSApLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aDtcblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRpZiAoICh0d2VlbiA9IGNvbGxlY3Rpb25bIGluZGV4IF0uY2FsbCggYW5pbWF0aW9uLCBwcm9wLCB2YWx1ZSApKSApIHtcblxuXHRcdFx0Ly8gd2UncmUgZG9uZSB3aXRoIHRoaXMgcHJvcGVydHlcblx0XHRcdHJldHVybiB0d2Vlbjtcblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gZGVmYXVsdFByZWZpbHRlciggZWxlbSwgcHJvcHMsIG9wdHMgKSB7XG5cdC8qIGpzaGludCB2YWxpZHRoaXM6IHRydWUgKi9cblx0dmFyIHByb3AsIHZhbHVlLCB0b2dnbGUsIHR3ZWVuLCBob29rcywgb2xkZmlyZSwgZGlzcGxheSwgY2hlY2tEaXNwbGF5LFxuXHRcdGFuaW0gPSB0aGlzLFxuXHRcdG9yaWcgPSB7fSxcblx0XHRzdHlsZSA9IGVsZW0uc3R5bGUsXG5cdFx0aGlkZGVuID0gZWxlbS5ub2RlVHlwZSAmJiBpc0hpZGRlbiggZWxlbSApLFxuXHRcdGRhdGFTaG93ID0gZGF0YV9wcml2LmdldCggZWxlbSwgXCJmeHNob3dcIiApO1xuXG5cdC8vIGhhbmRsZSBxdWV1ZTogZmFsc2UgcHJvbWlzZXNcblx0aWYgKCAhb3B0cy5xdWV1ZSApIHtcblx0XHRob29rcyA9IGpRdWVyeS5fcXVldWVIb29rcyggZWxlbSwgXCJmeFwiICk7XG5cdFx0aWYgKCBob29rcy51bnF1ZXVlZCA9PSBudWxsICkge1xuXHRcdFx0aG9va3MudW5xdWV1ZWQgPSAwO1xuXHRcdFx0b2xkZmlyZSA9IGhvb2tzLmVtcHR5LmZpcmU7XG5cdFx0XHRob29rcy5lbXB0eS5maXJlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggIWhvb2tzLnVucXVldWVkICkge1xuXHRcdFx0XHRcdG9sZGZpcmUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHR9XG5cdFx0aG9va3MudW5xdWV1ZWQrKztcblxuXHRcdGFuaW0uYWx3YXlzKGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8gZG9pbmcgdGhpcyBtYWtlcyBzdXJlIHRoYXQgdGhlIGNvbXBsZXRlIGhhbmRsZXIgd2lsbCBiZSBjYWxsZWRcblx0XHRcdC8vIGJlZm9yZSB0aGlzIGNvbXBsZXRlc1xuXHRcdFx0YW5pbS5hbHdheXMoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGhvb2tzLnVucXVldWVkLS07XG5cdFx0XHRcdGlmICggIWpRdWVyeS5xdWV1ZSggZWxlbSwgXCJmeFwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRcdGhvb2tzLmVtcHR5LmZpcmUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHQvLyBoZWlnaHQvd2lkdGggb3ZlcmZsb3cgcGFzc1xuXHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKCBcImhlaWdodFwiIGluIHByb3BzIHx8IFwid2lkdGhcIiBpbiBwcm9wcyApICkge1xuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IG5vdGhpbmcgc25lYWtzIG91dFxuXHRcdC8vIFJlY29yZCBhbGwgMyBvdmVyZmxvdyBhdHRyaWJ1dGVzIGJlY2F1c2UgSUU5LTEwIGRvIG5vdFxuXHRcdC8vIGNoYW5nZSB0aGUgb3ZlcmZsb3cgYXR0cmlidXRlIHdoZW4gb3ZlcmZsb3dYIGFuZFxuXHRcdC8vIG92ZXJmbG93WSBhcmUgc2V0IHRvIHRoZSBzYW1lIHZhbHVlXG5cdFx0b3B0cy5vdmVyZmxvdyA9IFsgc3R5bGUub3ZlcmZsb3csIHN0eWxlLm92ZXJmbG93WCwgc3R5bGUub3ZlcmZsb3dZIF07XG5cblx0XHQvLyBTZXQgZGlzcGxheSBwcm9wZXJ0eSB0byBpbmxpbmUtYmxvY2sgZm9yIGhlaWdodC93aWR0aFxuXHRcdC8vIGFuaW1hdGlvbnMgb24gaW5saW5lIGVsZW1lbnRzIHRoYXQgYXJlIGhhdmluZyB3aWR0aC9oZWlnaHQgYW5pbWF0ZWRcblx0XHRkaXNwbGF5ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKTtcblxuXHRcdC8vIFRlc3QgZGVmYXVsdCBkaXNwbGF5IGlmIGRpc3BsYXkgaXMgY3VycmVudGx5IFwibm9uZVwiXG5cdFx0Y2hlY2tEaXNwbGF5ID0gZGlzcGxheSA9PT0gXCJub25lXCIgP1xuXHRcdFx0ZGF0YV9wcml2LmdldCggZWxlbSwgXCJvbGRkaXNwbGF5XCIgKSB8fCBkZWZhdWx0RGlzcGxheSggZWxlbS5ub2RlTmFtZSApIDogZGlzcGxheTtcblxuXHRcdGlmICggY2hlY2tEaXNwbGF5ID09PSBcImlubGluZVwiICYmIGpRdWVyeS5jc3MoIGVsZW0sIFwiZmxvYXRcIiApID09PSBcIm5vbmVcIiApIHtcblx0XHRcdHN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiO1xuXHRcdH1cblx0fVxuXG5cdGlmICggb3B0cy5vdmVyZmxvdyApIHtcblx0XHRzdHlsZS5vdmVyZmxvdyA9IFwiaGlkZGVuXCI7XG5cdFx0YW5pbS5hbHdheXMoZnVuY3Rpb24oKSB7XG5cdFx0XHRzdHlsZS5vdmVyZmxvdyA9IG9wdHMub3ZlcmZsb3dbIDAgXTtcblx0XHRcdHN0eWxlLm92ZXJmbG93WCA9IG9wdHMub3ZlcmZsb3dbIDEgXTtcblx0XHRcdHN0eWxlLm92ZXJmbG93WSA9IG9wdHMub3ZlcmZsb3dbIDIgXTtcblx0XHR9KTtcblx0fVxuXG5cdC8vIHNob3cvaGlkZSBwYXNzXG5cdGZvciAoIHByb3AgaW4gcHJvcHMgKSB7XG5cdFx0dmFsdWUgPSBwcm9wc1sgcHJvcCBdO1xuXHRcdGlmICggcmZ4dHlwZXMuZXhlYyggdmFsdWUgKSApIHtcblx0XHRcdGRlbGV0ZSBwcm9wc1sgcHJvcCBdO1xuXHRcdFx0dG9nZ2xlID0gdG9nZ2xlIHx8IHZhbHVlID09PSBcInRvZ2dsZVwiO1xuXHRcdFx0aWYgKCB2YWx1ZSA9PT0gKCBoaWRkZW4gPyBcImhpZGVcIiA6IFwic2hvd1wiICkgKSB7XG5cblx0XHRcdFx0Ly8gSWYgdGhlcmUgaXMgZGF0YVNob3cgbGVmdCBvdmVyIGZyb20gYSBzdG9wcGVkIGhpZGUgb3Igc2hvdyBhbmQgd2UgYXJlIGdvaW5nIHRvIHByb2NlZWQgd2l0aCBzaG93LCB3ZSBzaG91bGQgcHJldGVuZCB0byBiZSBoaWRkZW5cblx0XHRcdFx0aWYgKCB2YWx1ZSA9PT0gXCJzaG93XCIgJiYgZGF0YVNob3cgJiYgZGF0YVNob3dbIHByb3AgXSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdGhpZGRlbiA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdG9yaWdbIHByb3AgXSA9IGRhdGFTaG93ICYmIGRhdGFTaG93WyBwcm9wIF0gfHwgalF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wICk7XG5cblx0XHQvLyBBbnkgbm9uLWZ4IHZhbHVlIHN0b3BzIHVzIGZyb20gcmVzdG9yaW5nIHRoZSBvcmlnaW5hbCBkaXNwbGF5IHZhbHVlXG5cdFx0fSBlbHNlIHtcblx0XHRcdGRpc3BsYXkgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHR9XG5cblx0aWYgKCAhalF1ZXJ5LmlzRW1wdHlPYmplY3QoIG9yaWcgKSApIHtcblx0XHRpZiAoIGRhdGFTaG93ICkge1xuXHRcdFx0aWYgKCBcImhpZGRlblwiIGluIGRhdGFTaG93ICkge1xuXHRcdFx0XHRoaWRkZW4gPSBkYXRhU2hvdy5oaWRkZW47XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRhdGFTaG93ID0gZGF0YV9wcml2LmFjY2VzcyggZWxlbSwgXCJmeHNob3dcIiwge30gKTtcblx0XHR9XG5cblx0XHQvLyBzdG9yZSBzdGF0ZSBpZiBpdHMgdG9nZ2xlIC0gZW5hYmxlcyAuc3RvcCgpLnRvZ2dsZSgpIHRvIFwicmV2ZXJzZVwiXG5cdFx0aWYgKCB0b2dnbGUgKSB7XG5cdFx0XHRkYXRhU2hvdy5oaWRkZW4gPSAhaGlkZGVuO1xuXHRcdH1cblx0XHRpZiAoIGhpZGRlbiApIHtcblx0XHRcdGpRdWVyeSggZWxlbSApLnNob3coKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0YW5pbS5kb25lKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRqUXVlcnkoIGVsZW0gKS5oaWRlKCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0YW5pbS5kb25lKGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHByb3A7XG5cblx0XHRcdGRhdGFfcHJpdi5yZW1vdmUoIGVsZW0sIFwiZnhzaG93XCIgKTtcblx0XHRcdGZvciAoIHByb3AgaW4gb3JpZyApIHtcblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wLCBvcmlnWyBwcm9wIF0gKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRmb3IgKCBwcm9wIGluIG9yaWcgKSB7XG5cdFx0XHR0d2VlbiA9IGNyZWF0ZVR3ZWVuKCBoaWRkZW4gPyBkYXRhU2hvd1sgcHJvcCBdIDogMCwgcHJvcCwgYW5pbSApO1xuXG5cdFx0XHRpZiAoICEoIHByb3AgaW4gZGF0YVNob3cgKSApIHtcblx0XHRcdFx0ZGF0YVNob3dbIHByb3AgXSA9IHR3ZWVuLnN0YXJ0O1xuXHRcdFx0XHRpZiAoIGhpZGRlbiApIHtcblx0XHRcdFx0XHR0d2Vlbi5lbmQgPSB0d2Vlbi5zdGFydDtcblx0XHRcdFx0XHR0d2Vlbi5zdGFydCA9IHByb3AgPT09IFwid2lkdGhcIiB8fCBwcm9wID09PSBcImhlaWdodFwiID8gMSA6IDA7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0Ly8gSWYgdGhpcyBpcyBhIG5vb3AgbGlrZSAuaGlkZSgpLmhpZGUoKSwgcmVzdG9yZSBhbiBvdmVyd3JpdHRlbiBkaXNwbGF5IHZhbHVlXG5cdH0gZWxzZSBpZiAoIChkaXNwbGF5ID09PSBcIm5vbmVcIiA/IGRlZmF1bHREaXNwbGF5KCBlbGVtLm5vZGVOYW1lICkgOiBkaXNwbGF5KSA9PT0gXCJpbmxpbmVcIiApIHtcblx0XHRzdHlsZS5kaXNwbGF5ID0gZGlzcGxheTtcblx0fVxufVxuXG5mdW5jdGlvbiBwcm9wRmlsdGVyKCBwcm9wcywgc3BlY2lhbEVhc2luZyApIHtcblx0dmFyIGluZGV4LCBuYW1lLCBlYXNpbmcsIHZhbHVlLCBob29rcztcblxuXHQvLyBjYW1lbENhc2UsIHNwZWNpYWxFYXNpbmcgYW5kIGV4cGFuZCBjc3NIb29rIHBhc3Ncblx0Zm9yICggaW5kZXggaW4gcHJvcHMgKSB7XG5cdFx0bmFtZSA9IGpRdWVyeS5jYW1lbENhc2UoIGluZGV4ICk7XG5cdFx0ZWFzaW5nID0gc3BlY2lhbEVhc2luZ1sgbmFtZSBdO1xuXHRcdHZhbHVlID0gcHJvcHNbIGluZGV4IF07XG5cdFx0aWYgKCBqUXVlcnkuaXNBcnJheSggdmFsdWUgKSApIHtcblx0XHRcdGVhc2luZyA9IHZhbHVlWyAxIF07XG5cdFx0XHR2YWx1ZSA9IHByb3BzWyBpbmRleCBdID0gdmFsdWVbIDAgXTtcblx0XHR9XG5cblx0XHRpZiAoIGluZGV4ICE9PSBuYW1lICkge1xuXHRcdFx0cHJvcHNbIG5hbWUgXSA9IHZhbHVlO1xuXHRcdFx0ZGVsZXRlIHByb3BzWyBpbmRleCBdO1xuXHRcdH1cblxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF07XG5cdFx0aWYgKCBob29rcyAmJiBcImV4cGFuZFwiIGluIGhvb2tzICkge1xuXHRcdFx0dmFsdWUgPSBob29rcy5leHBhbmQoIHZhbHVlICk7XG5cdFx0XHRkZWxldGUgcHJvcHNbIG5hbWUgXTtcblxuXHRcdFx0Ly8gbm90IHF1aXRlICQuZXh0ZW5kLCB0aGlzIHdvbnQgb3ZlcndyaXRlIGtleXMgYWxyZWFkeSBwcmVzZW50LlxuXHRcdFx0Ly8gYWxzbyAtIHJldXNpbmcgJ2luZGV4JyBmcm9tIGFib3ZlIGJlY2F1c2Ugd2UgaGF2ZSB0aGUgY29ycmVjdCBcIm5hbWVcIlxuXHRcdFx0Zm9yICggaW5kZXggaW4gdmFsdWUgKSB7XG5cdFx0XHRcdGlmICggISggaW5kZXggaW4gcHJvcHMgKSApIHtcblx0XHRcdFx0XHRwcm9wc1sgaW5kZXggXSA9IHZhbHVlWyBpbmRleCBdO1xuXHRcdFx0XHRcdHNwZWNpYWxFYXNpbmdbIGluZGV4IF0gPSBlYXNpbmc7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0c3BlY2lhbEVhc2luZ1sgbmFtZSBdID0gZWFzaW5nO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBBbmltYXRpb24oIGVsZW0sIHByb3BlcnRpZXMsIG9wdGlvbnMgKSB7XG5cdHZhciByZXN1bHQsXG5cdFx0c3RvcHBlZCxcblx0XHRpbmRleCA9IDAsXG5cdFx0bGVuZ3RoID0gYW5pbWF0aW9uUHJlZmlsdGVycy5sZW5ndGgsXG5cdFx0ZGVmZXJyZWQgPSBqUXVlcnkuRGVmZXJyZWQoKS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8gZG9uJ3QgbWF0Y2ggZWxlbSBpbiB0aGUgOmFuaW1hdGVkIHNlbGVjdG9yXG5cdFx0XHRkZWxldGUgdGljay5lbGVtO1xuXHRcdH0pLFxuXHRcdHRpY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggc3RvcHBlZCApIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0dmFyIGN1cnJlbnRUaW1lID0gZnhOb3cgfHwgY3JlYXRlRnhOb3coKSxcblx0XHRcdFx0cmVtYWluaW5nID0gTWF0aC5tYXgoIDAsIGFuaW1hdGlvbi5zdGFydFRpbWUgKyBhbmltYXRpb24uZHVyYXRpb24gLSBjdXJyZW50VGltZSApLFxuXHRcdFx0XHQvLyBhcmNoYWljIGNyYXNoIGJ1ZyB3b24ndCBhbGxvdyB1cyB0byB1c2UgMSAtICggMC41IHx8IDAgKSAoIzEyNDk3KVxuXHRcdFx0XHR0ZW1wID0gcmVtYWluaW5nIC8gYW5pbWF0aW9uLmR1cmF0aW9uIHx8IDAsXG5cdFx0XHRcdHBlcmNlbnQgPSAxIC0gdGVtcCxcblx0XHRcdFx0aW5kZXggPSAwLFxuXHRcdFx0XHRsZW5ndGggPSBhbmltYXRpb24udHdlZW5zLmxlbmd0aDtcblxuXHRcdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XG5cdFx0XHRcdGFuaW1hdGlvbi50d2VlbnNbIGluZGV4IF0ucnVuKCBwZXJjZW50ICk7XG5cdFx0XHR9XG5cblx0XHRcdGRlZmVycmVkLm5vdGlmeVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBwZXJjZW50LCByZW1haW5pbmcgXSk7XG5cblx0XHRcdGlmICggcGVyY2VudCA8IDEgJiYgbGVuZ3RoICkge1xuXHRcdFx0XHRyZXR1cm4gcmVtYWluaW5nO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uIF0gKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0YW5pbWF0aW9uID0gZGVmZXJyZWQucHJvbWlzZSh7XG5cdFx0XHRlbGVtOiBlbGVtLFxuXHRcdFx0cHJvcHM6IGpRdWVyeS5leHRlbmQoIHt9LCBwcm9wZXJ0aWVzICksXG5cdFx0XHRvcHRzOiBqUXVlcnkuZXh0ZW5kKCB0cnVlLCB7IHNwZWNpYWxFYXNpbmc6IHt9IH0sIG9wdGlvbnMgKSxcblx0XHRcdG9yaWdpbmFsUHJvcGVydGllczogcHJvcGVydGllcyxcblx0XHRcdG9yaWdpbmFsT3B0aW9uczogb3B0aW9ucyxcblx0XHRcdHN0YXJ0VGltZTogZnhOb3cgfHwgY3JlYXRlRnhOb3coKSxcblx0XHRcdGR1cmF0aW9uOiBvcHRpb25zLmR1cmF0aW9uLFxuXHRcdFx0dHdlZW5zOiBbXSxcblx0XHRcdGNyZWF0ZVR3ZWVuOiBmdW5jdGlvbiggcHJvcCwgZW5kICkge1xuXHRcdFx0XHR2YXIgdHdlZW4gPSBqUXVlcnkuVHdlZW4oIGVsZW0sIGFuaW1hdGlvbi5vcHRzLCBwcm9wLCBlbmQsXG5cdFx0XHRcdFx0XHRhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nWyBwcm9wIF0gfHwgYW5pbWF0aW9uLm9wdHMuZWFzaW5nICk7XG5cdFx0XHRcdGFuaW1hdGlvbi50d2VlbnMucHVzaCggdHdlZW4gKTtcblx0XHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdFx0fSxcblx0XHRcdHN0b3A6IGZ1bmN0aW9uKCBnb3RvRW5kICkge1xuXHRcdFx0XHR2YXIgaW5kZXggPSAwLFxuXHRcdFx0XHRcdC8vIGlmIHdlIGFyZSBnb2luZyB0byB0aGUgZW5kLCB3ZSB3YW50IHRvIHJ1biBhbGwgdGhlIHR3ZWVuc1xuXHRcdFx0XHRcdC8vIG90aGVyd2lzZSB3ZSBza2lwIHRoaXMgcGFydFxuXHRcdFx0XHRcdGxlbmd0aCA9IGdvdG9FbmQgPyBhbmltYXRpb24udHdlZW5zLmxlbmd0aCA6IDA7XG5cdFx0XHRcdGlmICggc3RvcHBlZCApIHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fVxuXHRcdFx0XHRzdG9wcGVkID0gdHJ1ZTtcblx0XHRcdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XG5cdFx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVuc1sgaW5kZXggXS5ydW4oIDEgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIHJlc29sdmUgd2hlbiB3ZSBwbGF5ZWQgdGhlIGxhc3QgZnJhbWVcblx0XHRcdFx0Ly8gb3RoZXJ3aXNlLCByZWplY3Rcblx0XHRcdFx0aWYgKCBnb3RvRW5kICkge1xuXHRcdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgZ290b0VuZCBdICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZGVmZXJyZWQucmVqZWN0V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIGdvdG9FbmQgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fVxuXHRcdH0pLFxuXHRcdHByb3BzID0gYW5pbWF0aW9uLnByb3BzO1xuXG5cdHByb3BGaWx0ZXIoIHByb3BzLCBhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nICk7XG5cblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XG5cdFx0cmVzdWx0ID0gYW5pbWF0aW9uUHJlZmlsdGVyc1sgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIGVsZW0sIHByb3BzLCBhbmltYXRpb24ub3B0cyApO1xuXHRcdGlmICggcmVzdWx0ICkge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdH1cblxuXHRqUXVlcnkubWFwKCBwcm9wcywgY3JlYXRlVHdlZW4sIGFuaW1hdGlvbiApO1xuXG5cdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGFuaW1hdGlvbi5vcHRzLnN0YXJ0ICkgKSB7XG5cdFx0YW5pbWF0aW9uLm9wdHMuc3RhcnQuY2FsbCggZWxlbSwgYW5pbWF0aW9uICk7XG5cdH1cblxuXHRqUXVlcnkuZngudGltZXIoXG5cdFx0alF1ZXJ5LmV4dGVuZCggdGljaywge1xuXHRcdFx0ZWxlbTogZWxlbSxcblx0XHRcdGFuaW06IGFuaW1hdGlvbixcblx0XHRcdHF1ZXVlOiBhbmltYXRpb24ub3B0cy5xdWV1ZVxuXHRcdH0pXG5cdCk7XG5cblx0Ly8gYXR0YWNoIGNhbGxiYWNrcyBmcm9tIG9wdGlvbnNcblx0cmV0dXJuIGFuaW1hdGlvbi5wcm9ncmVzcyggYW5pbWF0aW9uLm9wdHMucHJvZ3Jlc3MgKVxuXHRcdC5kb25lKCBhbmltYXRpb24ub3B0cy5kb25lLCBhbmltYXRpb24ub3B0cy5jb21wbGV0ZSApXG5cdFx0LmZhaWwoIGFuaW1hdGlvbi5vcHRzLmZhaWwgKVxuXHRcdC5hbHdheXMoIGFuaW1hdGlvbi5vcHRzLmFsd2F5cyApO1xufVxuXG5qUXVlcnkuQW5pbWF0aW9uID0galF1ZXJ5LmV4dGVuZCggQW5pbWF0aW9uLCB7XG5cblx0dHdlZW5lcjogZnVuY3Rpb24oIHByb3BzLCBjYWxsYmFjayApIHtcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBwcm9wcyApICkge1xuXHRcdFx0Y2FsbGJhY2sgPSBwcm9wcztcblx0XHRcdHByb3BzID0gWyBcIipcIiBdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwcm9wcyA9IHByb3BzLnNwbGl0KFwiIFwiKTtcblx0XHR9XG5cblx0XHR2YXIgcHJvcCxcblx0XHRcdGluZGV4ID0gMCxcblx0XHRcdGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuXHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xuXHRcdFx0cHJvcCA9IHByb3BzWyBpbmRleCBdO1xuXHRcdFx0dHdlZW5lcnNbIHByb3AgXSA9IHR3ZWVuZXJzWyBwcm9wIF0gfHwgW107XG5cdFx0XHR0d2VlbmVyc1sgcHJvcCBdLnVuc2hpZnQoIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9LFxuXG5cdHByZWZpbHRlcjogZnVuY3Rpb24oIGNhbGxiYWNrLCBwcmVwZW5kICkge1xuXHRcdGlmICggcHJlcGVuZCApIHtcblx0XHRcdGFuaW1hdGlvblByZWZpbHRlcnMudW5zaGlmdCggY2FsbGJhY2sgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0YW5pbWF0aW9uUHJlZmlsdGVycy5wdXNoKCBjYWxsYmFjayApO1xuXHRcdH1cblx0fVxufSk7XG5cbmpRdWVyeS5zcGVlZCA9IGZ1bmN0aW9uKCBzcGVlZCwgZWFzaW5nLCBmbiApIHtcblx0dmFyIG9wdCA9IHNwZWVkICYmIHR5cGVvZiBzcGVlZCA9PT0gXCJvYmplY3RcIiA/IGpRdWVyeS5leHRlbmQoIHt9LCBzcGVlZCApIDoge1xuXHRcdGNvbXBsZXRlOiBmbiB8fCAhZm4gJiYgZWFzaW5nIHx8XG5cdFx0XHRqUXVlcnkuaXNGdW5jdGlvbiggc3BlZWQgKSAmJiBzcGVlZCxcblx0XHRkdXJhdGlvbjogc3BlZWQsXG5cdFx0ZWFzaW5nOiBmbiAmJiBlYXNpbmcgfHwgZWFzaW5nICYmICFqUXVlcnkuaXNGdW5jdGlvbiggZWFzaW5nICkgJiYgZWFzaW5nXG5cdH07XG5cblx0b3B0LmR1cmF0aW9uID0galF1ZXJ5LmZ4Lm9mZiA/IDAgOiB0eXBlb2Ygb3B0LmR1cmF0aW9uID09PSBcIm51bWJlclwiID8gb3B0LmR1cmF0aW9uIDpcblx0XHRvcHQuZHVyYXRpb24gaW4galF1ZXJ5LmZ4LnNwZWVkcyA/IGpRdWVyeS5meC5zcGVlZHNbIG9wdC5kdXJhdGlvbiBdIDogalF1ZXJ5LmZ4LnNwZWVkcy5fZGVmYXVsdDtcblxuXHQvLyBub3JtYWxpemUgb3B0LnF1ZXVlIC0gdHJ1ZS91bmRlZmluZWQvbnVsbCAtPiBcImZ4XCJcblx0aWYgKCBvcHQucXVldWUgPT0gbnVsbCB8fCBvcHQucXVldWUgPT09IHRydWUgKSB7XG5cdFx0b3B0LnF1ZXVlID0gXCJmeFwiO1xuXHR9XG5cblx0Ly8gUXVldWVpbmdcblx0b3B0Lm9sZCA9IG9wdC5jb21wbGV0ZTtcblxuXHRvcHQuY29tcGxldGUgPSBmdW5jdGlvbigpIHtcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBvcHQub2xkICkgKSB7XG5cdFx0XHRvcHQub2xkLmNhbGwoIHRoaXMgKTtcblx0XHR9XG5cblx0XHRpZiAoIG9wdC5xdWV1ZSApIHtcblx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCBvcHQucXVldWUgKTtcblx0XHR9XG5cdH07XG5cblx0cmV0dXJuIG9wdDtcbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRmYWRlVG86IGZ1bmN0aW9uKCBzcGVlZCwgdG8sIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cblx0XHQvLyBzaG93IGFueSBoaWRkZW4gZWxlbWVudHMgYWZ0ZXIgc2V0dGluZyBvcGFjaXR5IHRvIDBcblx0XHRyZXR1cm4gdGhpcy5maWx0ZXIoIGlzSGlkZGVuICkuY3NzKCBcIm9wYWNpdHlcIiwgMCApLnNob3coKVxuXG5cdFx0XHQvLyBhbmltYXRlIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWRcblx0XHRcdC5lbmQoKS5hbmltYXRlKHsgb3BhY2l0eTogdG8gfSwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcblx0fSxcblx0YW5pbWF0ZTogZnVuY3Rpb24oIHByb3AsIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHZhciBlbXB0eSA9IGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBwcm9wICksXG5cdFx0XHRvcHRhbGwgPSBqUXVlcnkuc3BlZWQoIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICksXG5cdFx0XHRkb0FuaW1hdGlvbiA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQvLyBPcGVyYXRlIG9uIGEgY29weSBvZiBwcm9wIHNvIHBlci1wcm9wZXJ0eSBlYXNpbmcgd29uJ3QgYmUgbG9zdFxuXHRcdFx0XHR2YXIgYW5pbSA9IEFuaW1hdGlvbiggdGhpcywgalF1ZXJ5LmV4dGVuZCgge30sIHByb3AgKSwgb3B0YWxsICk7XG5cblx0XHRcdFx0Ly8gRW1wdHkgYW5pbWF0aW9ucywgb3IgZmluaXNoaW5nIHJlc29sdmVzIGltbWVkaWF0ZWx5XG5cdFx0XHRcdGlmICggZW1wdHkgfHwgZGF0YV9wcml2LmdldCggdGhpcywgXCJmaW5pc2hcIiApICkge1xuXHRcdFx0XHRcdGFuaW0uc3RvcCggdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdFx0ZG9BbmltYXRpb24uZmluaXNoID0gZG9BbmltYXRpb247XG5cblx0XHRyZXR1cm4gZW1wdHkgfHwgb3B0YWxsLnF1ZXVlID09PSBmYWxzZSA/XG5cdFx0XHR0aGlzLmVhY2goIGRvQW5pbWF0aW9uICkgOlxuXHRcdFx0dGhpcy5xdWV1ZSggb3B0YWxsLnF1ZXVlLCBkb0FuaW1hdGlvbiApO1xuXHR9LFxuXHRzdG9wOiBmdW5jdGlvbiggdHlwZSwgY2xlYXJRdWV1ZSwgZ290b0VuZCApIHtcblx0XHR2YXIgc3RvcFF1ZXVlID0gZnVuY3Rpb24oIGhvb2tzICkge1xuXHRcdFx0dmFyIHN0b3AgPSBob29rcy5zdG9wO1xuXHRcdFx0ZGVsZXRlIGhvb2tzLnN0b3A7XG5cdFx0XHRzdG9wKCBnb3RvRW5kICk7XG5cdFx0fTtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRnb3RvRW5kID0gY2xlYXJRdWV1ZTtcblx0XHRcdGNsZWFyUXVldWUgPSB0eXBlO1xuXHRcdFx0dHlwZSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0aWYgKCBjbGVhclF1ZXVlICYmIHR5cGUgIT09IGZhbHNlICkge1xuXHRcdFx0dGhpcy5xdWV1ZSggdHlwZSB8fCBcImZ4XCIsIFtdICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdHZhciBkZXF1ZXVlID0gdHJ1ZSxcblx0XHRcdFx0aW5kZXggPSB0eXBlICE9IG51bGwgJiYgdHlwZSArIFwicXVldWVIb29rc1wiLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRkYXRhID0gZGF0YV9wcml2LmdldCggdGhpcyApO1xuXG5cdFx0XHRpZiAoIGluZGV4ICkge1xuXHRcdFx0XHRpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICkge1xuXHRcdFx0XHRcdHN0b3BRdWV1ZSggZGF0YVsgaW5kZXggXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmb3IgKCBpbmRleCBpbiBkYXRhICkge1xuXHRcdFx0XHRcdGlmICggZGF0YVsgaW5kZXggXSAmJiBkYXRhWyBpbmRleCBdLnN0b3AgJiYgcnJ1bi50ZXN0KCBpbmRleCApICkge1xuXHRcdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGZvciAoIGluZGV4ID0gdGltZXJzLmxlbmd0aDsgaW5kZXgtLTsgKSB7XG5cdFx0XHRcdGlmICggdGltZXJzWyBpbmRleCBdLmVsZW0gPT09IHRoaXMgJiYgKHR5cGUgPT0gbnVsbCB8fCB0aW1lcnNbIGluZGV4IF0ucXVldWUgPT09IHR5cGUpICkge1xuXHRcdFx0XHRcdHRpbWVyc1sgaW5kZXggXS5hbmltLnN0b3AoIGdvdG9FbmQgKTtcblx0XHRcdFx0XHRkZXF1ZXVlID0gZmFsc2U7XG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBzdGFydCB0aGUgbmV4dCBpbiB0aGUgcXVldWUgaWYgdGhlIGxhc3Qgc3RlcCB3YXNuJ3QgZm9yY2VkXG5cdFx0XHQvLyB0aW1lcnMgY3VycmVudGx5IHdpbGwgY2FsbCB0aGVpciBjb21wbGV0ZSBjYWxsYmFja3MsIHdoaWNoIHdpbGwgZGVxdWV1ZVxuXHRcdFx0Ly8gYnV0IG9ubHkgaWYgdGhleSB3ZXJlIGdvdG9FbmRcblx0XHRcdGlmICggZGVxdWV1ZSB8fCAhZ290b0VuZCApIHtcblx0XHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblx0ZmluaXNoOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRpZiAoIHR5cGUgIT09IGZhbHNlICkge1xuXHRcdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGluZGV4LFxuXHRcdFx0XHRkYXRhID0gZGF0YV9wcml2LmdldCggdGhpcyApLFxuXHRcdFx0XHRxdWV1ZSA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlXCIgXSxcblx0XHRcdFx0aG9va3MgPSBkYXRhWyB0eXBlICsgXCJxdWV1ZUhvb2tzXCIgXSxcblx0XHRcdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycyxcblx0XHRcdFx0bGVuZ3RoID0gcXVldWUgPyBxdWV1ZS5sZW5ndGggOiAwO1xuXG5cdFx0XHQvLyBlbmFibGUgZmluaXNoaW5nIGZsYWcgb24gcHJpdmF0ZSBkYXRhXG5cdFx0XHRkYXRhLmZpbmlzaCA9IHRydWU7XG5cblx0XHRcdC8vIGVtcHR5IHRoZSBxdWV1ZSBmaXJzdFxuXHRcdFx0alF1ZXJ5LnF1ZXVlKCB0aGlzLCB0eXBlLCBbXSApO1xuXG5cdFx0XHRpZiAoIGhvb2tzICYmIGhvb2tzLnN0b3AgKSB7XG5cdFx0XHRcdGhvb2tzLnN0b3AuY2FsbCggdGhpcywgdHJ1ZSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBsb29rIGZvciBhbnkgYWN0aXZlIGFuaW1hdGlvbnMsIGFuZCBmaW5pc2ggdGhlbVxuXHRcdFx0Zm9yICggaW5kZXggPSB0aW1lcnMubGVuZ3RoOyBpbmRleC0tOyApIHtcblx0XHRcdFx0aWYgKCB0aW1lcnNbIGluZGV4IF0uZWxlbSA9PT0gdGhpcyAmJiB0aW1lcnNbIGluZGV4IF0ucXVldWUgPT09IHR5cGUgKSB7XG5cdFx0XHRcdFx0dGltZXJzWyBpbmRleCBdLmFuaW0uc3RvcCggdHJ1ZSApO1xuXHRcdFx0XHRcdHRpbWVycy5zcGxpY2UoIGluZGV4LCAxICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gbG9vayBmb3IgYW55IGFuaW1hdGlvbnMgaW4gdGhlIG9sZCBxdWV1ZSBhbmQgZmluaXNoIHRoZW1cblx0XHRcdGZvciAoIGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0XHRcdGlmICggcXVldWVbIGluZGV4IF0gJiYgcXVldWVbIGluZGV4IF0uZmluaXNoICkge1xuXHRcdFx0XHRcdHF1ZXVlWyBpbmRleCBdLmZpbmlzaC5jYWxsKCB0aGlzICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gdHVybiBvZmYgZmluaXNoaW5nIGZsYWdcblx0XHRcdGRlbGV0ZSBkYXRhLmZpbmlzaDtcblx0XHR9KTtcblx0fVxufSk7XG5cbmpRdWVyeS5lYWNoKFsgXCJ0b2dnbGVcIiwgXCJzaG93XCIsIFwiaGlkZVwiIF0sIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xuXHR2YXIgY3NzRm4gPSBqUXVlcnkuZm5bIG5hbWUgXTtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIHNwZWVkID09IG51bGwgfHwgdHlwZW9mIHNwZWVkID09PSBcImJvb2xlYW5cIiA/XG5cdFx0XHRjc3NGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICkgOlxuXHRcdFx0dGhpcy5hbmltYXRlKCBnZW5GeCggbmFtZSwgdHJ1ZSApLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9O1xufSk7XG5cbi8vIEdlbmVyYXRlIHNob3J0Y3V0cyBmb3IgY3VzdG9tIGFuaW1hdGlvbnNcbmpRdWVyeS5lYWNoKHtcblx0c2xpZGVEb3duOiBnZW5GeChcInNob3dcIiksXG5cdHNsaWRlVXA6IGdlbkZ4KFwiaGlkZVwiKSxcblx0c2xpZGVUb2dnbGU6IGdlbkZ4KFwidG9nZ2xlXCIpLFxuXHRmYWRlSW46IHsgb3BhY2l0eTogXCJzaG93XCIgfSxcblx0ZmFkZU91dDogeyBvcGFjaXR5OiBcImhpZGVcIiB9LFxuXHRmYWRlVG9nZ2xlOiB7IG9wYWNpdHk6IFwidG9nZ2xlXCIgfVxufSwgZnVuY3Rpb24oIG5hbWUsIHByb3BzICkge1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4gdGhpcy5hbmltYXRlKCBwcm9wcywgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcblx0fTtcbn0pO1xuXG5qUXVlcnkudGltZXJzID0gW107XG5qUXVlcnkuZngudGljayA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgdGltZXIsXG5cdFx0aSA9IDAsXG5cdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycztcblxuXHRmeE5vdyA9IGpRdWVyeS5ub3coKTtcblxuXHRmb3IgKCA7IGkgPCB0aW1lcnMubGVuZ3RoOyBpKysgKSB7XG5cdFx0dGltZXIgPSB0aW1lcnNbIGkgXTtcblx0XHQvLyBDaGVja3MgdGhlIHRpbWVyIGhhcyBub3QgYWxyZWFkeSBiZWVuIHJlbW92ZWRcblx0XHRpZiAoICF0aW1lcigpICYmIHRpbWVyc1sgaSBdID09PSB0aW1lciApIHtcblx0XHRcdHRpbWVycy5zcGxpY2UoIGktLSwgMSApO1xuXHRcdH1cblx0fVxuXG5cdGlmICggIXRpbWVycy5sZW5ndGggKSB7XG5cdFx0alF1ZXJ5LmZ4LnN0b3AoKTtcblx0fVxuXHRmeE5vdyA9IHVuZGVmaW5lZDtcbn07XG5cbmpRdWVyeS5meC50aW1lciA9IGZ1bmN0aW9uKCB0aW1lciApIHtcblx0alF1ZXJ5LnRpbWVycy5wdXNoKCB0aW1lciApO1xuXHRpZiAoIHRpbWVyKCkgKSB7XG5cdFx0alF1ZXJ5LmZ4LnN0YXJ0KCk7XG5cdH0gZWxzZSB7XG5cdFx0alF1ZXJ5LnRpbWVycy5wb3AoKTtcblx0fVxufTtcblxualF1ZXJ5LmZ4LmludGVydmFsID0gMTM7XG5cbmpRdWVyeS5meC5zdGFydCA9IGZ1bmN0aW9uKCkge1xuXHRpZiAoICF0aW1lcklkICkge1xuXHRcdHRpbWVySWQgPSBzZXRJbnRlcnZhbCggalF1ZXJ5LmZ4LnRpY2ssIGpRdWVyeS5meC5pbnRlcnZhbCApO1xuXHR9XG59O1xuXG5qUXVlcnkuZnguc3RvcCA9IGZ1bmN0aW9uKCkge1xuXHRjbGVhckludGVydmFsKCB0aW1lcklkICk7XG5cdHRpbWVySWQgPSBudWxsO1xufTtcblxualF1ZXJ5LmZ4LnNwZWVkcyA9IHtcblx0c2xvdzogNjAwLFxuXHRmYXN0OiAyMDAsXG5cdC8vIERlZmF1bHQgc3BlZWRcblx0X2RlZmF1bHQ6IDQwMFxufTtcblxuXG4vLyBCYXNlZCBvZmYgb2YgdGhlIHBsdWdpbiBieSBDbGludCBIZWxmZXJzLCB3aXRoIHBlcm1pc3Npb24uXG4vLyBodHRwOi8vYmxpbmRzaWduYWxzLmNvbS9pbmRleC5waHAvMjAwOS8wNy9qcXVlcnktZGVsYXkvXG5qUXVlcnkuZm4uZGVsYXkgPSBmdW5jdGlvbiggdGltZSwgdHlwZSApIHtcblx0dGltZSA9IGpRdWVyeS5meCA/IGpRdWVyeS5meC5zcGVlZHNbIHRpbWUgXSB8fCB0aW1lIDogdGltZTtcblx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXG5cdHJldHVybiB0aGlzLnF1ZXVlKCB0eXBlLCBmdW5jdGlvbiggbmV4dCwgaG9va3MgKSB7XG5cdFx0dmFyIHRpbWVvdXQgPSBzZXRUaW1lb3V0KCBuZXh0LCB0aW1lICk7XG5cdFx0aG9va3Muc3RvcCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0Y2xlYXJUaW1lb3V0KCB0aW1lb3V0ICk7XG5cdFx0fTtcblx0fSk7XG59O1xuXG5cbihmdW5jdGlvbigpIHtcblx0dmFyIGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICksXG5cdFx0c2VsZWN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJzZWxlY3RcIiApLFxuXHRcdG9wdCA9IHNlbGVjdC5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJvcHRpb25cIiApICk7XG5cblx0aW5wdXQudHlwZSA9IFwiY2hlY2tib3hcIjtcblxuXHQvLyBTdXBwb3J0OiBpT1MgNS4xLCBBbmRyb2lkIDQueCwgQW5kcm9pZCAyLjNcblx0Ly8gQ2hlY2sgdGhlIGRlZmF1bHQgY2hlY2tib3gvcmFkaW8gdmFsdWUgKFwiXCIgb24gb2xkIFdlYktpdDsgXCJvblwiIGVsc2V3aGVyZSlcblx0c3VwcG9ydC5jaGVja09uID0gaW5wdXQudmFsdWUgIT09IFwiXCI7XG5cblx0Ly8gTXVzdCBhY2Nlc3MgdGhlIHBhcmVudCB0byBtYWtlIGFuIG9wdGlvbiBzZWxlY3QgcHJvcGVybHlcblx0Ly8gU3VwcG9ydDogSUU5LCBJRTEwXG5cdHN1cHBvcnQub3B0U2VsZWN0ZWQgPSBvcHQuc2VsZWN0ZWQ7XG5cblx0Ly8gTWFrZSBzdXJlIHRoYXQgdGhlIG9wdGlvbnMgaW5zaWRlIGRpc2FibGVkIHNlbGVjdHMgYXJlbid0IG1hcmtlZCBhcyBkaXNhYmxlZFxuXHQvLyAoV2ViS2l0IG1hcmtzIHRoZW0gYXMgZGlzYWJsZWQpXG5cdHNlbGVjdC5kaXNhYmxlZCA9IHRydWU7XG5cdHN1cHBvcnQub3B0RGlzYWJsZWQgPSAhb3B0LmRpc2FibGVkO1xuXG5cdC8vIENoZWNrIGlmIGFuIGlucHV0IG1haW50YWlucyBpdHMgdmFsdWUgYWZ0ZXIgYmVjb21pbmcgYSByYWRpb1xuXHQvLyBTdXBwb3J0OiBJRTksIElFMTBcblx0aW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcblx0aW5wdXQudmFsdWUgPSBcInRcIjtcblx0aW5wdXQudHlwZSA9IFwicmFkaW9cIjtcblx0c3VwcG9ydC5yYWRpb1ZhbHVlID0gaW5wdXQudmFsdWUgPT09IFwidFwiO1xufSkoKTtcblxuXG52YXIgbm9kZUhvb2ssIGJvb2xIb29rLFxuXHRhdHRySGFuZGxlID0galF1ZXJ5LmV4cHIuYXR0ckhhbmRsZTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGF0dHI6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBqUXVlcnkuYXR0ciwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XG5cdH0sXG5cblx0cmVtb3ZlQXR0cjogZnVuY3Rpb24oIG5hbWUgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCB0aGlzLCBuYW1lICk7XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0YXR0cjogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xuXHRcdHZhciBob29rcywgcmV0LFxuXHRcdFx0blR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdFx0Ly8gZG9uJ3QgZ2V0L3NldCBhdHRyaWJ1dGVzIG9uIHRleHQsIGNvbW1lbnQgYW5kIGF0dHJpYnV0ZSBub2Rlc1xuXHRcdGlmICggIWVsZW0gfHwgblR5cGUgPT09IDMgfHwgblR5cGUgPT09IDggfHwgblR5cGUgPT09IDIgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRmFsbGJhY2sgdG8gcHJvcCB3aGVuIGF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcblx0XHRpZiAoIHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZSA9PT0gc3RydW5kZWZpbmVkICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5wcm9wKCBlbGVtLCBuYW1lLCB2YWx1ZSApO1xuXHRcdH1cblxuXHRcdC8vIEFsbCBhdHRyaWJ1dGVzIGFyZSBsb3dlcmNhc2Vcblx0XHQvLyBHcmFiIG5lY2Vzc2FyeSBob29rIGlmIG9uZSBpcyBkZWZpbmVkXG5cdFx0aWYgKCBuVHlwZSAhPT0gMSB8fCAhalF1ZXJ5LmlzWE1MRG9jKCBlbGVtICkgKSB7XG5cdFx0XHRuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0aG9va3MgPSBqUXVlcnkuYXR0ckhvb2tzWyBuYW1lIF0gfHxcblx0XHRcdFx0KCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnRlc3QoIG5hbWUgKSA/IGJvb2xIb29rIDogbm9kZUhvb2sgKTtcblx0XHR9XG5cblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGlmICggdmFsdWUgPT09IG51bGwgKSB7XG5cdFx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHRcdH0gZWxzZSBpZiAoIGhvb2tzICYmIFwic2V0XCIgaW4gaG9va3MgJiYgKHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHJldDtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIHZhbHVlICsgXCJcIiApO1xuXHRcdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgaWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmIChyZXQgPSBob29rcy5nZXQoIGVsZW0sIG5hbWUgKSkgIT09IG51bGwgKSB7XG5cdFx0XHRyZXR1cm4gcmV0O1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIG5hbWUgKTtcblxuXHRcdFx0Ly8gTm9uLWV4aXN0ZW50IGF0dHJpYnV0ZXMgcmV0dXJuIG51bGwsIHdlIG5vcm1hbGl6ZSB0byB1bmRlZmluZWRcblx0XHRcdHJldHVybiByZXQgPT0gbnVsbCA/XG5cdFx0XHRcdHVuZGVmaW5lZCA6XG5cdFx0XHRcdHJldDtcblx0XHR9XG5cdH0sXG5cblx0cmVtb3ZlQXR0cjogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdHZhciBuYW1lLCBwcm9wTmFtZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0YXR0ck5hbWVzID0gdmFsdWUgJiYgdmFsdWUubWF0Y2goIHJub3R3aGl0ZSApO1xuXG5cdFx0aWYgKCBhdHRyTmFtZXMgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdHdoaWxlICggKG5hbWUgPSBhdHRyTmFtZXNbaSsrXSkgKSB7XG5cdFx0XHRcdHByb3BOYW1lID0galF1ZXJ5LnByb3BGaXhbIG5hbWUgXSB8fCBuYW1lO1xuXG5cdFx0XHRcdC8vIEJvb2xlYW4gYXR0cmlidXRlcyBnZXQgc3BlY2lhbCB0cmVhdG1lbnQgKCMxMDg3MClcblx0XHRcdFx0aWYgKCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnRlc3QoIG5hbWUgKSApIHtcblx0XHRcdFx0XHQvLyBTZXQgY29ycmVzcG9uZGluZyBwcm9wZXJ0eSB0byBmYWxzZVxuXHRcdFx0XHRcdGVsZW1bIHByb3BOYW1lIF0gPSBmYWxzZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBuYW1lICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdGF0dHJIb29rczoge1xuXHRcdHR5cGU6IHtcblx0XHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdFx0XHRpZiAoICFzdXBwb3J0LnJhZGlvVmFsdWUgJiYgdmFsdWUgPT09IFwicmFkaW9cIiAmJlxuXHRcdFx0XHRcdGpRdWVyeS5ub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgKSB7XG5cdFx0XHRcdFx0Ly8gU2V0dGluZyB0aGUgdHlwZSBvbiBhIHJhZGlvIGJ1dHRvbiBhZnRlciB0aGUgdmFsdWUgcmVzZXRzIHRoZSB2YWx1ZSBpbiBJRTYtOVxuXHRcdFx0XHRcdC8vIFJlc2V0IHZhbHVlIHRvIGRlZmF1bHQgaW4gY2FzZSB0eXBlIGlzIHNldCBhZnRlciB2YWx1ZSBkdXJpbmcgY3JlYXRpb25cblx0XHRcdFx0XHR2YXIgdmFsID0gZWxlbS52YWx1ZTtcblx0XHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIHZhbHVlICk7XG5cdFx0XHRcdFx0aWYgKCB2YWwgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLnZhbHVlID0gdmFsO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cbn0pO1xuXG4vLyBIb29rcyBmb3IgYm9vbGVhbiBhdHRyaWJ1dGVzXG5ib29sSG9vayA9IHtcblx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUsIG5hbWUgKSB7XG5cdFx0aWYgKCB2YWx1ZSA9PT0gZmFsc2UgKSB7XG5cdFx0XHQvLyBSZW1vdmUgYm9vbGVhbiBhdHRyaWJ1dGVzIHdoZW4gc2V0IHRvIGZhbHNlXG5cdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggZWxlbSwgbmFtZSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggbmFtZSwgbmFtZSApO1xuXHRcdH1cblx0XHRyZXR1cm4gbmFtZTtcblx0fVxufTtcbmpRdWVyeS5lYWNoKCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnNvdXJjZS5tYXRjaCggL1xcdysvZyApLCBmdW5jdGlvbiggaSwgbmFtZSApIHtcblx0dmFyIGdldHRlciA9IGF0dHJIYW5kbGVbIG5hbWUgXSB8fCBqUXVlcnkuZmluZC5hdHRyO1xuXG5cdGF0dHJIYW5kbGVbIG5hbWUgXSA9IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHR2YXIgcmV0LCBoYW5kbGU7XG5cdFx0aWYgKCAhaXNYTUwgKSB7XG5cdFx0XHQvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wIGJ5IHRlbXBvcmFyaWx5IHJlbW92aW5nIHRoaXMgZnVuY3Rpb24gZnJvbSB0aGUgZ2V0dGVyXG5cdFx0XHRoYW5kbGUgPSBhdHRySGFuZGxlWyBuYW1lIF07XG5cdFx0XHRhdHRySGFuZGxlWyBuYW1lIF0gPSByZXQ7XG5cdFx0XHRyZXQgPSBnZXR0ZXIoIGVsZW0sIG5hbWUsIGlzWE1MICkgIT0gbnVsbCA/XG5cdFx0XHRcdG5hbWUudG9Mb3dlckNhc2UoKSA6XG5cdFx0XHRcdG51bGw7XG5cdFx0XHRhdHRySGFuZGxlWyBuYW1lIF0gPSBoYW5kbGU7XG5cdFx0fVxuXHRcdHJldHVybiByZXQ7XG5cdH07XG59KTtcblxuXG5cblxudmFyIHJmb2N1c2FibGUgPSAvXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b24pJC9pO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0cHJvcDogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGpRdWVyeS5wcm9wLCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fSxcblxuXHRyZW1vdmVQcm9wOiBmdW5jdGlvbiggbmFtZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0ZGVsZXRlIHRoaXNbIGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZSBdO1xuXHRcdH0pO1xuXHR9XG59KTtcblxualF1ZXJ5LmV4dGVuZCh7XG5cdHByb3BGaXg6IHtcblx0XHRcImZvclwiOiBcImh0bWxGb3JcIixcblx0XHRcImNsYXNzXCI6IFwiY2xhc3NOYW1lXCJcblx0fSxcblxuXHRwcm9wOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7XG5cdFx0dmFyIHJldCwgaG9va3MsIG5vdHhtbCxcblx0XHRcdG5UeXBlID0gZWxlbS5ub2RlVHlwZTtcblxuXHRcdC8vIGRvbid0IGdldC9zZXQgcHJvcGVydGllcyBvbiB0ZXh0LCBjb21tZW50IGFuZCBhdHRyaWJ1dGUgbm9kZXNcblx0XHRpZiAoICFlbGVtIHx8IG5UeXBlID09PSAzIHx8IG5UeXBlID09PSA4IHx8IG5UeXBlID09PSAyICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdG5vdHhtbCA9IG5UeXBlICE9PSAxIHx8ICFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKTtcblxuXHRcdGlmICggbm90eG1sICkge1xuXHRcdFx0Ly8gRml4IG5hbWUgYW5kIGF0dGFjaCBob29rc1xuXHRcdFx0bmFtZSA9IGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZTtcblx0XHRcdGhvb2tzID0galF1ZXJ5LnByb3BIb29rc1sgbmFtZSBdO1xuXHRcdH1cblxuXHRcdGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHJldHVybiBob29rcyAmJiBcInNldFwiIGluIGhvb2tzICYmIChyZXQgPSBob29rcy5zZXQoIGVsZW0sIHZhbHVlLCBuYW1lICkpICE9PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRyZXQgOlxuXHRcdFx0XHQoIGVsZW1bIG5hbWUgXSA9IHZhbHVlICk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiYgKHJldCA9IGhvb2tzLmdldCggZWxlbSwgbmFtZSApKSAhPT0gbnVsbCA/XG5cdFx0XHRcdHJldCA6XG5cdFx0XHRcdGVsZW1bIG5hbWUgXTtcblx0XHR9XG5cdH0sXG5cblx0cHJvcEhvb2tzOiB7XG5cdFx0dGFiSW5kZXg6IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiBlbGVtLmhhc0F0dHJpYnV0ZSggXCJ0YWJpbmRleFwiICkgfHwgcmZvY3VzYWJsZS50ZXN0KCBlbGVtLm5vZGVOYW1lICkgfHwgZWxlbS5ocmVmID9cblx0XHRcdFx0XHRlbGVtLnRhYkluZGV4IDpcblx0XHRcdFx0XHQtMTtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn0pO1xuXG4vLyBTdXBwb3J0OiBJRTkrXG4vLyBTZWxlY3RlZG5lc3MgZm9yIGFuIG9wdGlvbiBpbiBhbiBvcHRncm91cCBjYW4gYmUgaW5hY2N1cmF0ZVxuaWYgKCAhc3VwcG9ydC5vcHRTZWxlY3RlZCApIHtcblx0alF1ZXJ5LnByb3BIb29rcy5zZWxlY3RlZCA9IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcblx0XHRcdGlmICggcGFyZW50ICYmIHBhcmVudC5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRwYXJlbnQucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXHR9O1xufVxuXG5qUXVlcnkuZWFjaChbXG5cdFwidGFiSW5kZXhcIixcblx0XCJyZWFkT25seVwiLFxuXHRcIm1heExlbmd0aFwiLFxuXHRcImNlbGxTcGFjaW5nXCIsXG5cdFwiY2VsbFBhZGRpbmdcIixcblx0XCJyb3dTcGFuXCIsXG5cdFwiY29sU3BhblwiLFxuXHRcInVzZU1hcFwiLFxuXHRcImZyYW1lQm9yZGVyXCIsXG5cdFwiY29udGVudEVkaXRhYmxlXCJcbl0sIGZ1bmN0aW9uKCkge1xuXHRqUXVlcnkucHJvcEZpeFsgdGhpcy50b0xvd2VyQ2FzZSgpIF0gPSB0aGlzO1xufSk7XG5cblxuXG5cbnZhciByY2xhc3MgPSAvW1xcdFxcclxcblxcZl0vZztcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGFkZENsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dmFyIGNsYXNzZXMsIGVsZW0sIGN1ciwgY2xhenosIGosIGZpbmFsVmFsdWUsXG5cdFx0XHRwcm9jZWVkID0gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIHZhbHVlLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsZW4gPSB0aGlzLmxlbmd0aDtcblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBqICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5hZGRDbGFzcyggdmFsdWUuY2FsbCggdGhpcywgaiwgdGhpcy5jbGFzc05hbWUgKSApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0aWYgKCBwcm9jZWVkICkge1xuXHRcdFx0Ly8gVGhlIGRpc2p1bmN0aW9uIGhlcmUgaXMgZm9yIGJldHRlciBjb21wcmVzc2liaWxpdHkgKHNlZSByZW1vdmVDbGFzcylcblx0XHRcdGNsYXNzZXMgPSAoIHZhbHVlIHx8IFwiXCIgKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgW107XG5cblx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRlbGVtID0gdGhpc1sgaSBdO1xuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmICggZWxlbS5jbGFzc05hbWUgP1xuXHRcdFx0XHRcdCggXCIgXCIgKyBlbGVtLmNsYXNzTmFtZSArIFwiIFwiICkucmVwbGFjZSggcmNsYXNzLCBcIiBcIiApIDpcblx0XHRcdFx0XHRcIiBcIlxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdGlmICggY3VyICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKGNsYXp6ID0gY2xhc3Nlc1tqKytdKSApIHtcblx0XHRcdFx0XHRcdGlmICggY3VyLmluZGV4T2YoIFwiIFwiICsgY2xhenogKyBcIiBcIiApIDwgMCApIHtcblx0XHRcdFx0XHRcdFx0Y3VyICs9IGNsYXp6ICsgXCIgXCI7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gb25seSBhc3NpZ24gaWYgZGlmZmVyZW50IHRvIGF2b2lkIHVubmVlZGVkIHJlbmRlcmluZy5cblx0XHRcdFx0XHRmaW5hbFZhbHVlID0galF1ZXJ5LnRyaW0oIGN1ciApO1xuXHRcdFx0XHRcdGlmICggZWxlbS5jbGFzc05hbWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmNsYXNzTmFtZSA9IGZpbmFsVmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0cmVtb3ZlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjbGF6eiwgaiwgZmluYWxWYWx1ZSxcblx0XHRcdHByb2NlZWQgPSBhcmd1bWVudHMubGVuZ3RoID09PSAwIHx8IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuID0gdGhpcy5sZW5ndGg7XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaiApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkucmVtb3ZlQ2xhc3MoIHZhbHVlLmNhbGwoIHRoaXMsIGosIHRoaXMuY2xhc3NOYW1lICkgKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRpZiAoIHByb2NlZWQgKSB7XG5cdFx0XHRjbGFzc2VzID0gKCB2YWx1ZSB8fCBcIlwiICkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xuXG5cdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0ZWxlbSA9IHRoaXNbIGkgXTtcblx0XHRcdFx0Ly8gVGhpcyBleHByZXNzaW9uIGlzIGhlcmUgZm9yIGJldHRlciBjb21wcmVzc2liaWxpdHkgKHNlZSBhZGRDbGFzcylcblx0XHRcdFx0Y3VyID0gZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAoIGVsZW0uY2xhc3NOYW1lID9cblx0XHRcdFx0XHQoIFwiIFwiICsgZWxlbS5jbGFzc05hbWUgKyBcIiBcIiApLnJlcGxhY2UoIHJjbGFzcywgXCIgXCIgKSA6XG5cdFx0XHRcdFx0XCJcIlxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdGlmICggY3VyICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKGNsYXp6ID0gY2xhc3Nlc1tqKytdKSApIHtcblx0XHRcdFx0XHRcdC8vIFJlbW92ZSAqYWxsKiBpbnN0YW5jZXNcblx0XHRcdFx0XHRcdHdoaWxlICggY3VyLmluZGV4T2YoIFwiIFwiICsgY2xhenogKyBcIiBcIiApID49IDAgKSB7XG5cdFx0XHRcdFx0XHRcdGN1ciA9IGN1ci5yZXBsYWNlKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIsIFwiIFwiICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gb25seSBhc3NpZ24gaWYgZGlmZmVyZW50IHRvIGF2b2lkIHVubmVlZGVkIHJlbmRlcmluZy5cblx0XHRcdFx0XHRmaW5hbFZhbHVlID0gdmFsdWUgPyBqUXVlcnkudHJpbSggY3VyICkgOiBcIlwiO1xuXHRcdFx0XHRcdGlmICggZWxlbS5jbGFzc05hbWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmNsYXNzTmFtZSA9IGZpbmFsVmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0dG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSwgc3RhdGVWYWwgKSB7XG5cdFx0dmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG5cblx0XHRpZiAoIHR5cGVvZiBzdGF0ZVZhbCA9PT0gXCJib29sZWFuXCIgJiYgdHlwZSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBzdGF0ZVZhbCA/IHRoaXMuYWRkQ2xhc3MoIHZhbHVlICkgOiB0aGlzLnJlbW92ZUNsYXNzKCB2YWx1ZSApO1xuXHRcdH1cblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS50b2dnbGVDbGFzcyggdmFsdWUuY2FsbCh0aGlzLCBpLCB0aGlzLmNsYXNzTmFtZSwgc3RhdGVWYWwpLCBzdGF0ZVZhbCApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGlmICggdHlwZSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0Ly8gdG9nZ2xlIGluZGl2aWR1YWwgY2xhc3MgbmFtZXNcblx0XHRcdFx0dmFyIGNsYXNzTmFtZSxcblx0XHRcdFx0XHRpID0gMCxcblx0XHRcdFx0XHRzZWxmID0galF1ZXJ5KCB0aGlzICksXG5cdFx0XHRcdFx0Y2xhc3NOYW1lcyA9IHZhbHVlLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXTtcblxuXHRcdFx0XHR3aGlsZSAoIChjbGFzc05hbWUgPSBjbGFzc05hbWVzWyBpKysgXSkgKSB7XG5cdFx0XHRcdFx0Ly8gY2hlY2sgZWFjaCBjbGFzc05hbWUgZ2l2ZW4sIHNwYWNlIHNlcGFyYXRlZCBsaXN0XG5cdFx0XHRcdFx0aWYgKCBzZWxmLmhhc0NsYXNzKCBjbGFzc05hbWUgKSApIHtcblx0XHRcdFx0XHRcdHNlbGYucmVtb3ZlQ2xhc3MoIGNsYXNzTmFtZSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRzZWxmLmFkZENsYXNzKCBjbGFzc05hbWUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gVG9nZ2xlIHdob2xlIGNsYXNzIG5hbWVcblx0XHRcdH0gZWxzZSBpZiAoIHR5cGUgPT09IHN0cnVuZGVmaW5lZCB8fCB0eXBlID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRcdFx0aWYgKCB0aGlzLmNsYXNzTmFtZSApIHtcblx0XHRcdFx0XHQvLyBzdG9yZSBjbGFzc05hbWUgaWYgc2V0XG5cdFx0XHRcdFx0ZGF0YV9wcml2LnNldCggdGhpcywgXCJfX2NsYXNzTmFtZV9fXCIsIHRoaXMuY2xhc3NOYW1lICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBJZiB0aGUgZWxlbWVudCBoYXMgYSBjbGFzcyBuYW1lIG9yIGlmIHdlJ3JlIHBhc3NlZCBcImZhbHNlXCIsXG5cdFx0XHRcdC8vIHRoZW4gcmVtb3ZlIHRoZSB3aG9sZSBjbGFzc25hbWUgKGlmIHRoZXJlIHdhcyBvbmUsIHRoZSBhYm92ZSBzYXZlZCBpdCkuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBicmluZyBiYWNrIHdoYXRldmVyIHdhcyBwcmV2aW91c2x5IHNhdmVkIChpZiBhbnl0aGluZyksXG5cdFx0XHRcdC8vIGZhbGxpbmcgYmFjayB0byB0aGUgZW1wdHkgc3RyaW5nIGlmIG5vdGhpbmcgd2FzIHN0b3JlZC5cblx0XHRcdFx0dGhpcy5jbGFzc05hbWUgPSB0aGlzLmNsYXNzTmFtZSB8fCB2YWx1ZSA9PT0gZmFsc2UgPyBcIlwiIDogZGF0YV9wcml2LmdldCggdGhpcywgXCJfX2NsYXNzTmFtZV9fXCIgKSB8fCBcIlwiO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdGhhc0NsYXNzOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGNsYXNzTmFtZSA9IFwiIFwiICsgc2VsZWN0b3IgKyBcIiBcIixcblx0XHRcdGkgPSAwLFxuXHRcdFx0bCA9IHRoaXMubGVuZ3RoO1xuXHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdGlmICggdGhpc1tpXS5ub2RlVHlwZSA9PT0gMSAmJiAoXCIgXCIgKyB0aGlzW2ldLmNsYXNzTmFtZSArIFwiIFwiKS5yZXBsYWNlKHJjbGFzcywgXCIgXCIpLmluZGV4T2YoIGNsYXNzTmFtZSApID49IDAgKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufSk7XG5cblxuXG5cbnZhciBycmV0dXJuID0gL1xcci9nO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0dmFsOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dmFyIGhvb2tzLCByZXQsIGlzRnVuY3Rpb24sXG5cdFx0XHRlbGVtID0gdGhpc1swXTtcblxuXHRcdGlmICggIWFyZ3VtZW50cy5sZW5ndGggKSB7XG5cdFx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRcdGhvb2tzID0galF1ZXJ5LnZhbEhvb2tzWyBlbGVtLnR5cGUgXSB8fCBqUXVlcnkudmFsSG9va3NbIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSBdO1xuXG5cdFx0XHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAocmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBcInZhbHVlXCIgKSkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0ID0gZWxlbS52YWx1ZTtcblxuXHRcdFx0XHRyZXR1cm4gdHlwZW9mIHJldCA9PT0gXCJzdHJpbmdcIiA/XG5cdFx0XHRcdFx0Ly8gaGFuZGxlIG1vc3QgY29tbW9uIHN0cmluZyBjYXNlc1xuXHRcdFx0XHRcdHJldC5yZXBsYWNlKHJyZXR1cm4sIFwiXCIpIDpcblx0XHRcdFx0XHQvLyBoYW5kbGUgY2FzZXMgd2hlcmUgdmFsdWUgaXMgbnVsbC91bmRlZiBvciBudW1iZXJcblx0XHRcdFx0XHRyZXQgPT0gbnVsbCA/IFwiXCIgOiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpc0Z1bmN0aW9uID0galF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICk7XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0dmFyIHZhbDtcblxuXHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlICE9PSAxICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmICggaXNGdW5jdGlvbiApIHtcblx0XHRcdFx0dmFsID0gdmFsdWUuY2FsbCggdGhpcywgaSwgalF1ZXJ5KCB0aGlzICkudmFsKCkgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHZhbCA9IHZhbHVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBUcmVhdCBudWxsL3VuZGVmaW5lZCBhcyBcIlwiOyBjb252ZXJ0IG51bWJlcnMgdG8gc3RyaW5nXG5cdFx0XHRpZiAoIHZhbCA9PSBudWxsICkge1xuXHRcdFx0XHR2YWwgPSBcIlwiO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCB0eXBlb2YgdmFsID09PSBcIm51bWJlclwiICkge1xuXHRcdFx0XHR2YWwgKz0gXCJcIjtcblxuXHRcdFx0fSBlbHNlIGlmICggalF1ZXJ5LmlzQXJyYXkoIHZhbCApICkge1xuXHRcdFx0XHR2YWwgPSBqUXVlcnkubWFwKCB2YWwsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSArIFwiXCI7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHRob29rcyA9IGpRdWVyeS52YWxIb29rc1sgdGhpcy50eXBlIF0gfHwgalF1ZXJ5LnZhbEhvb2tzWyB0aGlzLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgXTtcblxuXHRcdFx0Ly8gSWYgc2V0IHJldHVybnMgdW5kZWZpbmVkLCBmYWxsIGJhY2sgdG8gbm9ybWFsIHNldHRpbmdcblx0XHRcdGlmICggIWhvb2tzIHx8ICEoXCJzZXRcIiBpbiBob29rcykgfHwgaG9va3Muc2V0KCB0aGlzLCB2YWwsIFwidmFsdWVcIiApID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHRoaXMudmFsdWUgPSB2YWw7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0dmFsSG9va3M6IHtcblx0XHRvcHRpb246IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciB2YWwgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBcInZhbHVlXCIgKTtcblx0XHRcdFx0cmV0dXJuIHZhbCAhPSBudWxsID9cblx0XHRcdFx0XHR2YWwgOlxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFMTAtMTErXG5cdFx0XHRcdFx0Ly8gb3B0aW9uLnRleHQgdGhyb3dzIGV4Y2VwdGlvbnMgKCMxNDY4NiwgIzE0ODU4KVxuXHRcdFx0XHRcdGpRdWVyeS50cmltKCBqUXVlcnkudGV4dCggZWxlbSApICk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRzZWxlY3Q6IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciB2YWx1ZSwgb3B0aW9uLFxuXHRcdFx0XHRcdG9wdGlvbnMgPSBlbGVtLm9wdGlvbnMsXG5cdFx0XHRcdFx0aW5kZXggPSBlbGVtLnNlbGVjdGVkSW5kZXgsXG5cdFx0XHRcdFx0b25lID0gZWxlbS50eXBlID09PSBcInNlbGVjdC1vbmVcIiB8fCBpbmRleCA8IDAsXG5cdFx0XHRcdFx0dmFsdWVzID0gb25lID8gbnVsbCA6IFtdLFxuXHRcdFx0XHRcdG1heCA9IG9uZSA/IGluZGV4ICsgMSA6IG9wdGlvbnMubGVuZ3RoLFxuXHRcdFx0XHRcdGkgPSBpbmRleCA8IDAgP1xuXHRcdFx0XHRcdFx0bWF4IDpcblx0XHRcdFx0XHRcdG9uZSA/IGluZGV4IDogMDtcblxuXHRcdFx0XHQvLyBMb29wIHRocm91Z2ggYWxsIHRoZSBzZWxlY3RlZCBvcHRpb25zXG5cdFx0XHRcdGZvciAoIDsgaSA8IG1heDsgaSsrICkge1xuXHRcdFx0XHRcdG9wdGlvbiA9IG9wdGlvbnNbIGkgXTtcblxuXHRcdFx0XHRcdC8vIElFNi05IGRvZXNuJ3QgdXBkYXRlIHNlbGVjdGVkIGFmdGVyIGZvcm0gcmVzZXQgKCMyNTUxKVxuXHRcdFx0XHRcdGlmICggKCBvcHRpb24uc2VsZWN0ZWQgfHwgaSA9PT0gaW5kZXggKSAmJlxuXHRcdFx0XHRcdFx0XHQvLyBEb24ndCByZXR1cm4gb3B0aW9ucyB0aGF0IGFyZSBkaXNhYmxlZCBvciBpbiBhIGRpc2FibGVkIG9wdGdyb3VwXG5cdFx0XHRcdFx0XHRcdCggc3VwcG9ydC5vcHREaXNhYmxlZCA/ICFvcHRpb24uZGlzYWJsZWQgOiBvcHRpb24uZ2V0QXR0cmlidXRlKCBcImRpc2FibGVkXCIgKSA9PT0gbnVsbCApICYmXG5cdFx0XHRcdFx0XHRcdCggIW9wdGlvbi5wYXJlbnROb2RlLmRpc2FibGVkIHx8ICFqUXVlcnkubm9kZU5hbWUoIG9wdGlvbi5wYXJlbnROb2RlLCBcIm9wdGdyb3VwXCIgKSApICkge1xuXG5cdFx0XHRcdFx0XHQvLyBHZXQgdGhlIHNwZWNpZmljIHZhbHVlIGZvciB0aGUgb3B0aW9uXG5cdFx0XHRcdFx0XHR2YWx1ZSA9IGpRdWVyeSggb3B0aW9uICkudmFsKCk7XG5cblx0XHRcdFx0XHRcdC8vIFdlIGRvbid0IG5lZWQgYW4gYXJyYXkgZm9yIG9uZSBzZWxlY3RzXG5cdFx0XHRcdFx0XHRpZiAoIG9uZSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBNdWx0aS1TZWxlY3RzIHJldHVybiBhbiBhcnJheVxuXHRcdFx0XHRcdFx0dmFsdWVzLnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHRcdH0sXG5cblx0XHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgb3B0aW9uU2V0LCBvcHRpb24sXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcblx0XHRcdFx0XHR2YWx1ZXMgPSBqUXVlcnkubWFrZUFycmF5KCB2YWx1ZSApLFxuXHRcdFx0XHRcdGkgPSBvcHRpb25zLmxlbmd0aDtcblxuXHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRvcHRpb24gPSBvcHRpb25zWyBpIF07XG5cdFx0XHRcdFx0aWYgKCAob3B0aW9uLnNlbGVjdGVkID0galF1ZXJ5LmluQXJyYXkoIG9wdGlvbi52YWx1ZSwgdmFsdWVzICkgPj0gMCkgKSB7XG5cdFx0XHRcdFx0XHRvcHRpb25TZXQgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIGZvcmNlIGJyb3dzZXJzIHRvIGJlaGF2ZSBjb25zaXN0ZW50bHkgd2hlbiBub24tbWF0Y2hpbmcgdmFsdWUgaXMgc2V0XG5cdFx0XHRcdGlmICggIW9wdGlvblNldCApIHtcblx0XHRcdFx0XHRlbGVtLnNlbGVjdGVkSW5kZXggPSAtMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdmFsdWVzO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufSk7XG5cbi8vIFJhZGlvcyBhbmQgY2hlY2tib3hlcyBnZXR0ZXIvc2V0dGVyXG5qUXVlcnkuZWFjaChbIFwicmFkaW9cIiwgXCJjaGVja2JveFwiIF0sIGZ1bmN0aW9uKCkge1xuXHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXSA9IHtcblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIHZhbHVlICkgKSB7XG5cdFx0XHRcdHJldHVybiAoIGVsZW0uY2hlY2tlZCA9IGpRdWVyeS5pbkFycmF5KCBqUXVlcnkoZWxlbSkudmFsKCksIHZhbHVlICkgPj0gMCApO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0aWYgKCAhc3VwcG9ydC5jaGVja09uICkge1xuXHRcdGpRdWVyeS52YWxIb29rc1sgdGhpcyBdLmdldCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0Ly8gU3VwcG9ydDogV2Via2l0XG5cdFx0XHQvLyBcIlwiIGlzIHJldHVybmVkIGluc3RlYWQgb2YgXCJvblwiIGlmIGEgdmFsdWUgaXNuJ3Qgc3BlY2lmaWVkXG5cdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiKSA9PT0gbnVsbCA/IFwib25cIiA6IGVsZW0udmFsdWU7XG5cdFx0fTtcblx0fVxufSk7XG5cblxuXG5cbi8vIFJldHVybiBqUXVlcnkgZm9yIGF0dHJpYnV0ZXMtb25seSBpbmNsdXNpb25cblxuXG5qUXVlcnkuZWFjaCggKFwiYmx1ciBmb2N1cyBmb2N1c2luIGZvY3Vzb3V0IGxvYWQgcmVzaXplIHNjcm9sbCB1bmxvYWQgY2xpY2sgZGJsY2xpY2sgXCIgK1xuXHRcIm1vdXNlZG93biBtb3VzZXVwIG1vdXNlbW92ZSBtb3VzZW92ZXIgbW91c2VvdXQgbW91c2VlbnRlciBtb3VzZWxlYXZlIFwiICtcblx0XCJjaGFuZ2Ugc2VsZWN0IHN1Ym1pdCBrZXlkb3duIGtleXByZXNzIGtleXVwIGVycm9yIGNvbnRleHRtZW51XCIpLnNwbGl0KFwiIFwiKSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cblx0Ly8gSGFuZGxlIGV2ZW50IGJpbmRpbmdcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPiAwID9cblx0XHRcdHRoaXMub24oIG5hbWUsIG51bGwsIGRhdGEsIGZuICkgOlxuXHRcdFx0dGhpcy50cmlnZ2VyKCBuYW1lICk7XG5cdH07XG59KTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGhvdmVyOiBmdW5jdGlvbiggZm5PdmVyLCBmbk91dCApIHtcblx0XHRyZXR1cm4gdGhpcy5tb3VzZWVudGVyKCBmbk92ZXIgKS5tb3VzZWxlYXZlKCBmbk91dCB8fCBmbk92ZXIgKTtcblx0fSxcblxuXHRiaW5kOiBmdW5jdGlvbiggdHlwZXMsIGRhdGEsIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlcywgbnVsbCwgZGF0YSwgZm4gKTtcblx0fSxcblx0dW5iaW5kOiBmdW5jdGlvbiggdHlwZXMsIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9mZiggdHlwZXMsIG51bGwsIGZuICk7XG5cdH0sXG5cblx0ZGVsZWdhdGU6IGZ1bmN0aW9uKCBzZWxlY3RvciwgdHlwZXMsIGRhdGEsIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuICk7XG5cdH0sXG5cdHVuZGVsZWdhdGU6IGZ1bmN0aW9uKCBzZWxlY3RvciwgdHlwZXMsIGZuICkge1xuXHRcdC8vICggbmFtZXNwYWNlICkgb3IgKCBzZWxlY3RvciwgdHlwZXMgWywgZm5dIClcblx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/IHRoaXMub2ZmKCBzZWxlY3RvciwgXCIqKlwiICkgOiB0aGlzLm9mZiggdHlwZXMsIHNlbGVjdG9yIHx8IFwiKipcIiwgZm4gKTtcblx0fVxufSk7XG5cblxudmFyIG5vbmNlID0galF1ZXJ5Lm5vdygpO1xuXG52YXIgcnF1ZXJ5ID0gKC9cXD8vKTtcblxuXG5cbi8vIFN1cHBvcnQ6IEFuZHJvaWQgMi4zXG4vLyBXb3JrYXJvdW5kIGZhaWx1cmUgdG8gc3RyaW5nLWNhc3QgbnVsbCBpbnB1dFxualF1ZXJ5LnBhcnNlSlNPTiA9IGZ1bmN0aW9uKCBkYXRhICkge1xuXHRyZXR1cm4gSlNPTi5wYXJzZSggZGF0YSArIFwiXCIgKTtcbn07XG5cblxuLy8gQ3Jvc3MtYnJvd3NlciB4bWwgcGFyc2luZ1xualF1ZXJ5LnBhcnNlWE1MID0gZnVuY3Rpb24oIGRhdGEgKSB7XG5cdHZhciB4bWwsIHRtcDtcblx0aWYgKCAhZGF0YSB8fCB0eXBlb2YgZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIFN1cHBvcnQ6IElFOVxuXHR0cnkge1xuXHRcdHRtcCA9IG5ldyBET01QYXJzZXIoKTtcblx0XHR4bWwgPSB0bXAucGFyc2VGcm9tU3RyaW5nKCBkYXRhLCBcInRleHQveG1sXCIgKTtcblx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0eG1sID0gdW5kZWZpbmVkO1xuXHR9XG5cblx0aWYgKCAheG1sIHx8IHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJwYXJzZXJlcnJvclwiICkubGVuZ3RoICkge1xuXHRcdGpRdWVyeS5lcnJvciggXCJJbnZhbGlkIFhNTDogXCIgKyBkYXRhICk7XG5cdH1cblx0cmV0dXJuIHhtbDtcbn07XG5cblxudmFyXG5cdC8vIERvY3VtZW50IGxvY2F0aW9uXG5cdGFqYXhMb2NQYXJ0cyxcblx0YWpheExvY2F0aW9uLFxuXG5cdHJoYXNoID0gLyMuKiQvLFxuXHRydHMgPSAvKFs/Jl0pXz1bXiZdKi8sXG5cdHJoZWFkZXJzID0gL14oLio/KTpbIFxcdF0qKFteXFxyXFxuXSopJC9tZyxcblx0Ly8gIzc2NTMsICM4MTI1LCAjODE1MjogbG9jYWwgcHJvdG9jb2wgZGV0ZWN0aW9uXG5cdHJsb2NhbFByb3RvY29sID0gL14oPzphYm91dHxhcHB8YXBwLXN0b3JhZ2V8ListZXh0ZW5zaW9ufGZpbGV8cmVzfHdpZGdldCk6JC8sXG5cdHJub0NvbnRlbnQgPSAvXig/OkdFVHxIRUFEKSQvLFxuXHRycHJvdG9jb2wgPSAvXlxcL1xcLy8sXG5cdHJ1cmwgPSAvXihbXFx3ListXSs6KSg/OlxcL1xcLyg/OlteXFwvPyNdKkB8KShbXlxcLz8jOl0qKSg/OjooXFxkKyl8KXwpLyxcblxuXHQvKiBQcmVmaWx0ZXJzXG5cdCAqIDEpIFRoZXkgYXJlIHVzZWZ1bCB0byBpbnRyb2R1Y2UgY3VzdG9tIGRhdGFUeXBlcyAoc2VlIGFqYXgvanNvbnAuanMgZm9yIGFuIGV4YW1wbGUpXG5cdCAqIDIpIFRoZXNlIGFyZSBjYWxsZWQ6XG5cdCAqICAgIC0gQkVGT1JFIGFza2luZyBmb3IgYSB0cmFuc3BvcnRcblx0ICogICAgLSBBRlRFUiBwYXJhbSBzZXJpYWxpemF0aW9uIChzLmRhdGEgaXMgYSBzdHJpbmcgaWYgcy5wcm9jZXNzRGF0YSBpcyB0cnVlKVxuXHQgKiAzKSBrZXkgaXMgdGhlIGRhdGFUeXBlXG5cdCAqIDQpIHRoZSBjYXRjaGFsbCBzeW1ib2wgXCIqXCIgY2FuIGJlIHVzZWRcblx0ICogNSkgZXhlY3V0aW9uIHdpbGwgc3RhcnQgd2l0aCB0cmFuc3BvcnQgZGF0YVR5cGUgYW5kIFRIRU4gY29udGludWUgZG93biB0byBcIipcIiBpZiBuZWVkZWRcblx0ICovXG5cdHByZWZpbHRlcnMgPSB7fSxcblxuXHQvKiBUcmFuc3BvcnRzIGJpbmRpbmdzXG5cdCAqIDEpIGtleSBpcyB0aGUgZGF0YVR5cGVcblx0ICogMikgdGhlIGNhdGNoYWxsIHN5bWJvbCBcIipcIiBjYW4gYmUgdXNlZFxuXHQgKiAzKSBzZWxlY3Rpb24gd2lsbCBzdGFydCB3aXRoIHRyYW5zcG9ydCBkYXRhVHlwZSBhbmQgVEhFTiBnbyB0byBcIipcIiBpZiBuZWVkZWRcblx0ICovXG5cdHRyYW5zcG9ydHMgPSB7fSxcblxuXHQvLyBBdm9pZCBjb21tZW50LXByb2xvZyBjaGFyIHNlcXVlbmNlICgjMTAwOTgpOyBtdXN0IGFwcGVhc2UgbGludCBhbmQgZXZhZGUgY29tcHJlc3Npb25cblx0YWxsVHlwZXMgPSBcIiovXCIuY29uY2F0KFwiKlwiKTtcblxuLy8gIzgxMzgsIElFIG1heSB0aHJvdyBhbiBleGNlcHRpb24gd2hlbiBhY2Nlc3Npbmdcbi8vIGEgZmllbGQgZnJvbSB3aW5kb3cubG9jYXRpb24gaWYgZG9jdW1lbnQuZG9tYWluIGhhcyBiZWVuIHNldFxudHJ5IHtcblx0YWpheExvY2F0aW9uID0gbG9jYXRpb24uaHJlZjtcbn0gY2F0Y2goIGUgKSB7XG5cdC8vIFVzZSB0aGUgaHJlZiBhdHRyaWJ1dGUgb2YgYW4gQSBlbGVtZW50XG5cdC8vIHNpbmNlIElFIHdpbGwgbW9kaWZ5IGl0IGdpdmVuIGRvY3VtZW50LmxvY2F0aW9uXG5cdGFqYXhMb2NhdGlvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiYVwiICk7XG5cdGFqYXhMb2NhdGlvbi5ocmVmID0gXCJcIjtcblx0YWpheExvY2F0aW9uID0gYWpheExvY2F0aW9uLmhyZWY7XG59XG5cbi8vIFNlZ21lbnQgbG9jYXRpb24gaW50byBwYXJ0c1xuYWpheExvY1BhcnRzID0gcnVybC5leGVjKCBhamF4TG9jYXRpb24udG9Mb3dlckNhc2UoKSApIHx8IFtdO1xuXG4vLyBCYXNlIFwiY29uc3RydWN0b3JcIiBmb3IgalF1ZXJ5LmFqYXhQcmVmaWx0ZXIgYW5kIGpRdWVyeS5hamF4VHJhbnNwb3J0XG5mdW5jdGlvbiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHN0cnVjdHVyZSApIHtcblxuXHQvLyBkYXRhVHlwZUV4cHJlc3Npb24gaXMgb3B0aW9uYWwgYW5kIGRlZmF1bHRzIHRvIFwiKlwiXG5cdHJldHVybiBmdW5jdGlvbiggZGF0YVR5cGVFeHByZXNzaW9uLCBmdW5jICkge1xuXG5cdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVFeHByZXNzaW9uICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0ZnVuYyA9IGRhdGFUeXBlRXhwcmVzc2lvbjtcblx0XHRcdGRhdGFUeXBlRXhwcmVzc2lvbiA9IFwiKlwiO1xuXHRcdH1cblxuXHRcdHZhciBkYXRhVHlwZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0ZGF0YVR5cGVzID0gZGF0YVR5cGVFeHByZXNzaW9uLnRvTG93ZXJDYXNlKCkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xuXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggZnVuYyApICkge1xuXHRcdFx0Ly8gRm9yIGVhY2ggZGF0YVR5cGUgaW4gdGhlIGRhdGFUeXBlRXhwcmVzc2lvblxuXHRcdFx0d2hpbGUgKCAoZGF0YVR5cGUgPSBkYXRhVHlwZXNbaSsrXSkgKSB7XG5cdFx0XHRcdC8vIFByZXBlbmQgaWYgcmVxdWVzdGVkXG5cdFx0XHRcdGlmICggZGF0YVR5cGVbMF0gPT09IFwiK1wiICkge1xuXHRcdFx0XHRcdGRhdGFUeXBlID0gZGF0YVR5cGUuc2xpY2UoIDEgKSB8fCBcIipcIjtcblx0XHRcdFx0XHQoc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdKS51bnNoaWZ0KCBmdW5jICk7XG5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIGFwcGVuZFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdChzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gPSBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10pLnB1c2goIGZ1bmMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fTtcbn1cblxuLy8gQmFzZSBpbnNwZWN0aW9uIGZ1bmN0aW9uIGZvciBwcmVmaWx0ZXJzIGFuZCB0cmFuc3BvcnRzXG5mdW5jdGlvbiBpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggc3RydWN0dXJlLCBvcHRpb25zLCBvcmlnaW5hbE9wdGlvbnMsIGpxWEhSICkge1xuXG5cdHZhciBpbnNwZWN0ZWQgPSB7fSxcblx0XHRzZWVraW5nVHJhbnNwb3J0ID0gKCBzdHJ1Y3R1cmUgPT09IHRyYW5zcG9ydHMgKTtcblxuXHRmdW5jdGlvbiBpbnNwZWN0KCBkYXRhVHlwZSApIHtcblx0XHR2YXIgc2VsZWN0ZWQ7XG5cdFx0aW5zcGVjdGVkWyBkYXRhVHlwZSBdID0gdHJ1ZTtcblx0XHRqUXVlcnkuZWFjaCggc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdLCBmdW5jdGlvbiggXywgcHJlZmlsdGVyT3JGYWN0b3J5ICkge1xuXHRcdFx0dmFyIGRhdGFUeXBlT3JUcmFuc3BvcnQgPSBwcmVmaWx0ZXJPckZhY3RvcnkoIG9wdGlvbnMsIG9yaWdpbmFsT3B0aW9ucywganFYSFIgKTtcblx0XHRcdGlmICggdHlwZW9mIGRhdGFUeXBlT3JUcmFuc3BvcnQgPT09IFwic3RyaW5nXCIgJiYgIXNlZWtpbmdUcmFuc3BvcnQgJiYgIWluc3BlY3RlZFsgZGF0YVR5cGVPclRyYW5zcG9ydCBdICkge1xuXHRcdFx0XHRvcHRpb25zLmRhdGFUeXBlcy51bnNoaWZ0KCBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7XG5cdFx0XHRcdGluc3BlY3QoIGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fSBlbHNlIGlmICggc2Vla2luZ1RyYW5zcG9ydCApIHtcblx0XHRcdFx0cmV0dXJuICEoIHNlbGVjdGVkID0gZGF0YVR5cGVPclRyYW5zcG9ydCApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdHJldHVybiBzZWxlY3RlZDtcblx0fVxuXG5cdHJldHVybiBpbnNwZWN0KCBvcHRpb25zLmRhdGFUeXBlc1sgMCBdICkgfHwgIWluc3BlY3RlZFsgXCIqXCIgXSAmJiBpbnNwZWN0KCBcIipcIiApO1xufVxuXG4vLyBBIHNwZWNpYWwgZXh0ZW5kIGZvciBhamF4IG9wdGlvbnNcbi8vIHRoYXQgdGFrZXMgXCJmbGF0XCIgb3B0aW9ucyAobm90IHRvIGJlIGRlZXAgZXh0ZW5kZWQpXG4vLyBGaXhlcyAjOTg4N1xuZnVuY3Rpb24gYWpheEV4dGVuZCggdGFyZ2V0LCBzcmMgKSB7XG5cdHZhciBrZXksIGRlZXAsXG5cdFx0ZmxhdE9wdGlvbnMgPSBqUXVlcnkuYWpheFNldHRpbmdzLmZsYXRPcHRpb25zIHx8IHt9O1xuXG5cdGZvciAoIGtleSBpbiBzcmMgKSB7XG5cdFx0aWYgKCBzcmNbIGtleSBdICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHQoIGZsYXRPcHRpb25zWyBrZXkgXSA/IHRhcmdldCA6ICggZGVlcCB8fCAoZGVlcCA9IHt9KSApIClbIGtleSBdID0gc3JjWyBrZXkgXTtcblx0XHR9XG5cdH1cblx0aWYgKCBkZWVwICkge1xuXHRcdGpRdWVyeS5leHRlbmQoIHRydWUsIHRhcmdldCwgZGVlcCApO1xuXHR9XG5cblx0cmV0dXJuIHRhcmdldDtcbn1cblxuLyogSGFuZGxlcyByZXNwb25zZXMgdG8gYW4gYWpheCByZXF1ZXN0OlxuICogLSBmaW5kcyB0aGUgcmlnaHQgZGF0YVR5cGUgKG1lZGlhdGVzIGJldHdlZW4gY29udGVudC10eXBlIGFuZCBleHBlY3RlZCBkYXRhVHlwZSlcbiAqIC0gcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZVxuICovXG5mdW5jdGlvbiBhamF4SGFuZGxlUmVzcG9uc2VzKCBzLCBqcVhIUiwgcmVzcG9uc2VzICkge1xuXG5cdHZhciBjdCwgdHlwZSwgZmluYWxEYXRhVHlwZSwgZmlyc3REYXRhVHlwZSxcblx0XHRjb250ZW50cyA9IHMuY29udGVudHMsXG5cdFx0ZGF0YVR5cGVzID0gcy5kYXRhVHlwZXM7XG5cblx0Ly8gUmVtb3ZlIGF1dG8gZGF0YVR5cGUgYW5kIGdldCBjb250ZW50LXR5cGUgaW4gdGhlIHByb2Nlc3Ncblx0d2hpbGUgKCBkYXRhVHlwZXNbIDAgXSA9PT0gXCIqXCIgKSB7XG5cdFx0ZGF0YVR5cGVzLnNoaWZ0KCk7XG5cdFx0aWYgKCBjdCA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0Y3QgPSBzLm1pbWVUeXBlIHx8IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xuXHRcdH1cblx0fVxuXG5cdC8vIENoZWNrIGlmIHdlJ3JlIGRlYWxpbmcgd2l0aCBhIGtub3duIGNvbnRlbnQtdHlwZVxuXHRpZiAoIGN0ICkge1xuXHRcdGZvciAoIHR5cGUgaW4gY29udGVudHMgKSB7XG5cdFx0XHRpZiAoIGNvbnRlbnRzWyB0eXBlIF0gJiYgY29udGVudHNbIHR5cGUgXS50ZXN0KCBjdCApICkge1xuXHRcdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggdHlwZSApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBDaGVjayB0byBzZWUgaWYgd2UgaGF2ZSBhIHJlc3BvbnNlIGZvciB0aGUgZXhwZWN0ZWQgZGF0YVR5cGVcblx0aWYgKCBkYXRhVHlwZXNbIDAgXSBpbiByZXNwb25zZXMgKSB7XG5cdFx0ZmluYWxEYXRhVHlwZSA9IGRhdGFUeXBlc1sgMCBdO1xuXHR9IGVsc2Uge1xuXHRcdC8vIFRyeSBjb252ZXJ0aWJsZSBkYXRhVHlwZXNcblx0XHRmb3IgKCB0eXBlIGluIHJlc3BvbnNlcyApIHtcblx0XHRcdGlmICggIWRhdGFUeXBlc1sgMCBdIHx8IHMuY29udmVydGVyc1sgdHlwZSArIFwiIFwiICsgZGF0YVR5cGVzWzBdIF0gKSB7XG5cdFx0XHRcdGZpbmFsRGF0YVR5cGUgPSB0eXBlO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGlmICggIWZpcnN0RGF0YVR5cGUgKSB7XG5cdFx0XHRcdGZpcnN0RGF0YVR5cGUgPSB0eXBlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHQvLyBPciBqdXN0IHVzZSBmaXJzdCBvbmVcblx0XHRmaW5hbERhdGFUeXBlID0gZmluYWxEYXRhVHlwZSB8fCBmaXJzdERhdGFUeXBlO1xuXHR9XG5cblx0Ly8gSWYgd2UgZm91bmQgYSBkYXRhVHlwZVxuXHQvLyBXZSBhZGQgdGhlIGRhdGFUeXBlIHRvIHRoZSBsaXN0IGlmIG5lZWRlZFxuXHQvLyBhbmQgcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIHJlc3BvbnNlXG5cdGlmICggZmluYWxEYXRhVHlwZSApIHtcblx0XHRpZiAoIGZpbmFsRGF0YVR5cGUgIT09IGRhdGFUeXBlc1sgMCBdICkge1xuXHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIGZpbmFsRGF0YVR5cGUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIHJlc3BvbnNlc1sgZmluYWxEYXRhVHlwZSBdO1xuXHR9XG59XG5cbi8qIENoYWluIGNvbnZlcnNpb25zIGdpdmVuIHRoZSByZXF1ZXN0IGFuZCB0aGUgb3JpZ2luYWwgcmVzcG9uc2VcbiAqIEFsc28gc2V0cyB0aGUgcmVzcG9uc2VYWFggZmllbGRzIG9uIHRoZSBqcVhIUiBpbnN0YW5jZVxuICovXG5mdW5jdGlvbiBhamF4Q29udmVydCggcywgcmVzcG9uc2UsIGpxWEhSLCBpc1N1Y2Nlc3MgKSB7XG5cdHZhciBjb252MiwgY3VycmVudCwgY29udiwgdG1wLCBwcmV2LFxuXHRcdGNvbnZlcnRlcnMgPSB7fSxcblx0XHQvLyBXb3JrIHdpdGggYSBjb3B5IG9mIGRhdGFUeXBlcyBpbiBjYXNlIHdlIG5lZWQgdG8gbW9kaWZ5IGl0IGZvciBjb252ZXJzaW9uXG5cdFx0ZGF0YVR5cGVzID0gcy5kYXRhVHlwZXMuc2xpY2UoKTtcblxuXHQvLyBDcmVhdGUgY29udmVydGVycyBtYXAgd2l0aCBsb3dlcmNhc2VkIGtleXNcblx0aWYgKCBkYXRhVHlwZXNbIDEgXSApIHtcblx0XHRmb3IgKCBjb252IGluIHMuY29udmVydGVycyApIHtcblx0XHRcdGNvbnZlcnRlcnNbIGNvbnYudG9Mb3dlckNhc2UoKSBdID0gcy5jb252ZXJ0ZXJzWyBjb252IF07XG5cdFx0fVxuXHR9XG5cblx0Y3VycmVudCA9IGRhdGFUeXBlcy5zaGlmdCgpO1xuXG5cdC8vIENvbnZlcnQgdG8gZWFjaCBzZXF1ZW50aWFsIGRhdGFUeXBlXG5cdHdoaWxlICggY3VycmVudCApIHtcblxuXHRcdGlmICggcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdICkge1xuXHRcdFx0anFYSFJbIHMucmVzcG9uc2VGaWVsZHNbIGN1cnJlbnQgXSBdID0gcmVzcG9uc2U7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgdGhlIGRhdGFGaWx0ZXIgaWYgcHJvdmlkZWRcblx0XHRpZiAoICFwcmV2ICYmIGlzU3VjY2VzcyAmJiBzLmRhdGFGaWx0ZXIgKSB7XG5cdFx0XHRyZXNwb25zZSA9IHMuZGF0YUZpbHRlciggcmVzcG9uc2UsIHMuZGF0YVR5cGUgKTtcblx0XHR9XG5cblx0XHRwcmV2ID0gY3VycmVudDtcblx0XHRjdXJyZW50ID0gZGF0YVR5cGVzLnNoaWZ0KCk7XG5cblx0XHRpZiAoIGN1cnJlbnQgKSB7XG5cblx0XHQvLyBUaGVyZSdzIG9ubHkgd29yayB0byBkbyBpZiBjdXJyZW50IGRhdGFUeXBlIGlzIG5vbi1hdXRvXG5cdFx0XHRpZiAoIGN1cnJlbnQgPT09IFwiKlwiICkge1xuXG5cdFx0XHRcdGN1cnJlbnQgPSBwcmV2O1xuXG5cdFx0XHQvLyBDb252ZXJ0IHJlc3BvbnNlIGlmIHByZXYgZGF0YVR5cGUgaXMgbm9uLWF1dG8gYW5kIGRpZmZlcnMgZnJvbSBjdXJyZW50XG5cdFx0XHR9IGVsc2UgaWYgKCBwcmV2ICE9PSBcIipcIiAmJiBwcmV2ICE9PSBjdXJyZW50ICkge1xuXG5cdFx0XHRcdC8vIFNlZWsgYSBkaXJlY3QgY29udmVydGVyXG5cdFx0XHRcdGNvbnYgPSBjb252ZXJ0ZXJzWyBwcmV2ICsgXCIgXCIgKyBjdXJyZW50IF0gfHwgY29udmVydGVyc1sgXCIqIFwiICsgY3VycmVudCBdO1xuXG5cdFx0XHRcdC8vIElmIG5vbmUgZm91bmQsIHNlZWsgYSBwYWlyXG5cdFx0XHRcdGlmICggIWNvbnYgKSB7XG5cdFx0XHRcdFx0Zm9yICggY29udjIgaW4gY29udmVydGVycyApIHtcblxuXHRcdFx0XHRcdFx0Ly8gSWYgY29udjIgb3V0cHV0cyBjdXJyZW50XG5cdFx0XHRcdFx0XHR0bXAgPSBjb252Mi5zcGxpdCggXCIgXCIgKTtcblx0XHRcdFx0XHRcdGlmICggdG1wWyAxIF0gPT09IGN1cnJlbnQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gSWYgcHJldiBjYW4gYmUgY29udmVydGVkIHRvIGFjY2VwdGVkIGlucHV0XG5cdFx0XHRcdFx0XHRcdGNvbnYgPSBjb252ZXJ0ZXJzWyBwcmV2ICsgXCIgXCIgKyB0bXBbIDAgXSBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0Y29udmVydGVyc1sgXCIqIFwiICsgdG1wWyAwIF0gXTtcblx0XHRcdFx0XHRcdFx0aWYgKCBjb252ICkge1xuXHRcdFx0XHRcdFx0XHRcdC8vIENvbmRlbnNlIGVxdWl2YWxlbmNlIGNvbnZlcnRlcnNcblx0XHRcdFx0XHRcdFx0XHRpZiAoIGNvbnYgPT09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgY29udjIgXTtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIE90aGVyd2lzZSwgaW5zZXJ0IHRoZSBpbnRlcm1lZGlhdGUgZGF0YVR5cGVcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBjb252ZXJ0ZXJzWyBjb252MiBdICE9PSB0cnVlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y3VycmVudCA9IHRtcFsgMCBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIHRtcFsgMSBdICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQXBwbHkgY29udmVydGVyIChpZiBub3QgYW4gZXF1aXZhbGVuY2UpXG5cdFx0XHRcdGlmICggY29udiAhPT0gdHJ1ZSApIHtcblxuXHRcdFx0XHRcdC8vIFVubGVzcyBlcnJvcnMgYXJlIGFsbG93ZWQgdG8gYnViYmxlLCBjYXRjaCBhbmQgcmV0dXJuIHRoZW1cblx0XHRcdFx0XHRpZiAoIGNvbnYgJiYgc1sgXCJ0aHJvd3NcIiBdICkge1xuXHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBjb252KCByZXNwb25zZSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRyZXNwb25zZSA9IGNvbnYoIHJlc3BvbnNlICk7XG5cdFx0XHRcdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHsgc3RhdGU6IFwicGFyc2VyZXJyb3JcIiwgZXJyb3I6IGNvbnYgPyBlIDogXCJObyBjb252ZXJzaW9uIGZyb20gXCIgKyBwcmV2ICsgXCIgdG8gXCIgKyBjdXJyZW50IH07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHsgc3RhdGU6IFwic3VjY2Vzc1wiLCBkYXRhOiByZXNwb25zZSB9O1xufVxuXG5qUXVlcnkuZXh0ZW5kKHtcblxuXHQvLyBDb3VudGVyIGZvciBob2xkaW5nIHRoZSBudW1iZXIgb2YgYWN0aXZlIHF1ZXJpZXNcblx0YWN0aXZlOiAwLFxuXG5cdC8vIExhc3QtTW9kaWZpZWQgaGVhZGVyIGNhY2hlIGZvciBuZXh0IHJlcXVlc3Rcblx0bGFzdE1vZGlmaWVkOiB7fSxcblx0ZXRhZzoge30sXG5cblx0YWpheFNldHRpbmdzOiB7XG5cdFx0dXJsOiBhamF4TG9jYXRpb24sXG5cdFx0dHlwZTogXCJHRVRcIixcblx0XHRpc0xvY2FsOiBybG9jYWxQcm90b2NvbC50ZXN0KCBhamF4TG9jUGFydHNbIDEgXSApLFxuXHRcdGdsb2JhbDogdHJ1ZSxcblx0XHRwcm9jZXNzRGF0YTogdHJ1ZSxcblx0XHRhc3luYzogdHJ1ZSxcblx0XHRjb250ZW50VHlwZTogXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7IGNoYXJzZXQ9VVRGLThcIixcblx0XHQvKlxuXHRcdHRpbWVvdXQ6IDAsXG5cdFx0ZGF0YTogbnVsbCxcblx0XHRkYXRhVHlwZTogbnVsbCxcblx0XHR1c2VybmFtZTogbnVsbCxcblx0XHRwYXNzd29yZDogbnVsbCxcblx0XHRjYWNoZTogbnVsbCxcblx0XHR0aHJvd3M6IGZhbHNlLFxuXHRcdHRyYWRpdGlvbmFsOiBmYWxzZSxcblx0XHRoZWFkZXJzOiB7fSxcblx0XHQqL1xuXG5cdFx0YWNjZXB0czoge1xuXHRcdFx0XCIqXCI6IGFsbFR5cGVzLFxuXHRcdFx0dGV4dDogXCJ0ZXh0L3BsYWluXCIsXG5cdFx0XHRodG1sOiBcInRleHQvaHRtbFwiLFxuXHRcdFx0eG1sOiBcImFwcGxpY2F0aW9uL3htbCwgdGV4dC94bWxcIixcblx0XHRcdGpzb246IFwiYXBwbGljYXRpb24vanNvbiwgdGV4dC9qYXZhc2NyaXB0XCJcblx0XHR9LFxuXG5cdFx0Y29udGVudHM6IHtcblx0XHRcdHhtbDogL3htbC8sXG5cdFx0XHRodG1sOiAvaHRtbC8sXG5cdFx0XHRqc29uOiAvanNvbi9cblx0XHR9LFxuXG5cdFx0cmVzcG9uc2VGaWVsZHM6IHtcblx0XHRcdHhtbDogXCJyZXNwb25zZVhNTFwiLFxuXHRcdFx0dGV4dDogXCJyZXNwb25zZVRleHRcIixcblx0XHRcdGpzb246IFwicmVzcG9uc2VKU09OXCJcblx0XHR9LFxuXG5cdFx0Ly8gRGF0YSBjb252ZXJ0ZXJzXG5cdFx0Ly8gS2V5cyBzZXBhcmF0ZSBzb3VyY2UgKG9yIGNhdGNoYWxsIFwiKlwiKSBhbmQgZGVzdGluYXRpb24gdHlwZXMgd2l0aCBhIHNpbmdsZSBzcGFjZVxuXHRcdGNvbnZlcnRlcnM6IHtcblxuXHRcdFx0Ly8gQ29udmVydCBhbnl0aGluZyB0byB0ZXh0XG5cdFx0XHRcIiogdGV4dFwiOiBTdHJpbmcsXG5cblx0XHRcdC8vIFRleHQgdG8gaHRtbCAodHJ1ZSA9IG5vIHRyYW5zZm9ybWF0aW9uKVxuXHRcdFx0XCJ0ZXh0IGh0bWxcIjogdHJ1ZSxcblxuXHRcdFx0Ly8gRXZhbHVhdGUgdGV4dCBhcyBhIGpzb24gZXhwcmVzc2lvblxuXHRcdFx0XCJ0ZXh0IGpzb25cIjogalF1ZXJ5LnBhcnNlSlNPTixcblxuXHRcdFx0Ly8gUGFyc2UgdGV4dCBhcyB4bWxcblx0XHRcdFwidGV4dCB4bWxcIjogalF1ZXJ5LnBhcnNlWE1MXG5cdFx0fSxcblxuXHRcdC8vIEZvciBvcHRpb25zIHRoYXQgc2hvdWxkbid0IGJlIGRlZXAgZXh0ZW5kZWQ6XG5cdFx0Ly8geW91IGNhbiBhZGQgeW91ciBvd24gY3VzdG9tIG9wdGlvbnMgaGVyZSBpZlxuXHRcdC8vIGFuZCB3aGVuIHlvdSBjcmVhdGUgb25lIHRoYXQgc2hvdWxkbid0IGJlXG5cdFx0Ly8gZGVlcCBleHRlbmRlZCAoc2VlIGFqYXhFeHRlbmQpXG5cdFx0ZmxhdE9wdGlvbnM6IHtcblx0XHRcdHVybDogdHJ1ZSxcblx0XHRcdGNvbnRleHQ6IHRydWVcblx0XHR9XG5cdH0sXG5cblx0Ly8gQ3JlYXRlcyBhIGZ1bGwgZmxlZGdlZCBzZXR0aW5ncyBvYmplY3QgaW50byB0YXJnZXRcblx0Ly8gd2l0aCBib3RoIGFqYXhTZXR0aW5ncyBhbmQgc2V0dGluZ3MgZmllbGRzLlxuXHQvLyBJZiB0YXJnZXQgaXMgb21pdHRlZCwgd3JpdGVzIGludG8gYWpheFNldHRpbmdzLlxuXHRhamF4U2V0dXA6IGZ1bmN0aW9uKCB0YXJnZXQsIHNldHRpbmdzICkge1xuXHRcdHJldHVybiBzZXR0aW5ncyA/XG5cblx0XHRcdC8vIEJ1aWxkaW5nIGEgc2V0dGluZ3Mgb2JqZWN0XG5cdFx0XHRhamF4RXh0ZW5kKCBhamF4RXh0ZW5kKCB0YXJnZXQsIGpRdWVyeS5hamF4U2V0dGluZ3MgKSwgc2V0dGluZ3MgKSA6XG5cblx0XHRcdC8vIEV4dGVuZGluZyBhamF4U2V0dGluZ3Ncblx0XHRcdGFqYXhFeHRlbmQoIGpRdWVyeS5hamF4U2V0dGluZ3MsIHRhcmdldCApO1xuXHR9LFxuXG5cdGFqYXhQcmVmaWx0ZXI6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggcHJlZmlsdGVycyApLFxuXHRhamF4VHJhbnNwb3J0OiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHRyYW5zcG9ydHMgKSxcblxuXHQvLyBNYWluIG1ldGhvZFxuXHRhamF4OiBmdW5jdGlvbiggdXJsLCBvcHRpb25zICkge1xuXG5cdFx0Ly8gSWYgdXJsIGlzIGFuIG9iamVjdCwgc2ltdWxhdGUgcHJlLTEuNSBzaWduYXR1cmVcblx0XHRpZiAoIHR5cGVvZiB1cmwgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHRvcHRpb25zID0gdXJsO1xuXHRcdFx0dXJsID0gdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdC8vIEZvcmNlIG9wdGlvbnMgdG8gYmUgYW4gb2JqZWN0XG5cdFx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cblx0XHR2YXIgdHJhbnNwb3J0LFxuXHRcdFx0Ly8gVVJMIHdpdGhvdXQgYW50aS1jYWNoZSBwYXJhbVxuXHRcdFx0Y2FjaGVVUkwsXG5cdFx0XHQvLyBSZXNwb25zZSBoZWFkZXJzXG5cdFx0XHRyZXNwb25zZUhlYWRlcnNTdHJpbmcsXG5cdFx0XHRyZXNwb25zZUhlYWRlcnMsXG5cdFx0XHQvLyB0aW1lb3V0IGhhbmRsZVxuXHRcdFx0dGltZW91dFRpbWVyLFxuXHRcdFx0Ly8gQ3Jvc3MtZG9tYWluIGRldGVjdGlvbiB2YXJzXG5cdFx0XHRwYXJ0cyxcblx0XHRcdC8vIFRvIGtub3cgaWYgZ2xvYmFsIGV2ZW50cyBhcmUgdG8gYmUgZGlzcGF0Y2hlZFxuXHRcdFx0ZmlyZUdsb2JhbHMsXG5cdFx0XHQvLyBMb29wIHZhcmlhYmxlXG5cdFx0XHRpLFxuXHRcdFx0Ly8gQ3JlYXRlIHRoZSBmaW5hbCBvcHRpb25zIG9iamVjdFxuXHRcdFx0cyA9IGpRdWVyeS5hamF4U2V0dXAoIHt9LCBvcHRpb25zICksXG5cdFx0XHQvLyBDYWxsYmFja3MgY29udGV4dFxuXHRcdFx0Y2FsbGJhY2tDb250ZXh0ID0gcy5jb250ZXh0IHx8IHMsXG5cdFx0XHQvLyBDb250ZXh0IGZvciBnbG9iYWwgZXZlbnRzIGlzIGNhbGxiYWNrQ29udGV4dCBpZiBpdCBpcyBhIERPTSBub2RlIG9yIGpRdWVyeSBjb2xsZWN0aW9uXG5cdFx0XHRnbG9iYWxFdmVudENvbnRleHQgPSBzLmNvbnRleHQgJiYgKCBjYWxsYmFja0NvbnRleHQubm9kZVR5cGUgfHwgY2FsbGJhY2tDb250ZXh0LmpxdWVyeSApID9cblx0XHRcdFx0alF1ZXJ5KCBjYWxsYmFja0NvbnRleHQgKSA6XG5cdFx0XHRcdGpRdWVyeS5ldmVudCxcblx0XHRcdC8vIERlZmVycmVkc1xuXHRcdFx0ZGVmZXJyZWQgPSBqUXVlcnkuRGVmZXJyZWQoKSxcblx0XHRcdGNvbXBsZXRlRGVmZXJyZWQgPSBqUXVlcnkuQ2FsbGJhY2tzKFwib25jZSBtZW1vcnlcIiksXG5cdFx0XHQvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrc1xuXHRcdFx0c3RhdHVzQ29kZSA9IHMuc3RhdHVzQ29kZSB8fCB7fSxcblx0XHRcdC8vIEhlYWRlcnMgKHRoZXkgYXJlIHNlbnQgYWxsIGF0IG9uY2UpXG5cdFx0XHRyZXF1ZXN0SGVhZGVycyA9IHt9LFxuXHRcdFx0cmVxdWVzdEhlYWRlcnNOYW1lcyA9IHt9LFxuXHRcdFx0Ly8gVGhlIGpxWEhSIHN0YXRlXG5cdFx0XHRzdGF0ZSA9IDAsXG5cdFx0XHQvLyBEZWZhdWx0IGFib3J0IG1lc3NhZ2Vcblx0XHRcdHN0ckFib3J0ID0gXCJjYW5jZWxlZFwiLFxuXHRcdFx0Ly8gRmFrZSB4aHJcblx0XHRcdGpxWEhSID0ge1xuXHRcdFx0XHRyZWFkeVN0YXRlOiAwLFxuXG5cdFx0XHRcdC8vIEJ1aWxkcyBoZWFkZXJzIGhhc2h0YWJsZSBpZiBuZWVkZWRcblx0XHRcdFx0Z2V0UmVzcG9uc2VIZWFkZXI6IGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0XHRcdFx0dmFyIG1hdGNoO1xuXHRcdFx0XHRcdGlmICggc3RhdGUgPT09IDIgKSB7XG5cdFx0XHRcdFx0XHRpZiAoICFyZXNwb25zZUhlYWRlcnMgKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3BvbnNlSGVhZGVycyA9IHt9O1xuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIChtYXRjaCA9IHJoZWFkZXJzLmV4ZWMoIHJlc3BvbnNlSGVhZGVyc1N0cmluZyApKSApIHtcblx0XHRcdFx0XHRcdFx0XHRyZXNwb25zZUhlYWRlcnNbIG1hdGNoWzFdLnRvTG93ZXJDYXNlKCkgXSA9IG1hdGNoWyAyIF07XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdG1hdGNoID0gcmVzcG9uc2VIZWFkZXJzWyBrZXkudG9Mb3dlckNhc2UoKSBdO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gbWF0Y2ggPT0gbnVsbCA/IG51bGwgOiBtYXRjaDtcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBSYXcgc3RyaW5nXG5cdFx0XHRcdGdldEFsbFJlc3BvbnNlSGVhZGVyczogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHN0YXRlID09PSAyID8gcmVzcG9uc2VIZWFkZXJzU3RyaW5nIDogbnVsbDtcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBDYWNoZXMgdGhlIGhlYWRlclxuXHRcdFx0XHRzZXRSZXF1ZXN0SGVhZGVyOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0XHRcdFx0dmFyIGxuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdGlmICggIXN0YXRlICkge1xuXHRcdFx0XHRcdFx0bmFtZSA9IHJlcXVlc3RIZWFkZXJzTmFtZXNbIGxuYW1lIF0gPSByZXF1ZXN0SGVhZGVyc05hbWVzWyBsbmFtZSBdIHx8IG5hbWU7XG5cdFx0XHRcdFx0XHRyZXF1ZXN0SGVhZGVyc1sgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIE92ZXJyaWRlcyByZXNwb25zZSBjb250ZW50LXR5cGUgaGVhZGVyXG5cdFx0XHRcdG92ZXJyaWRlTWltZVR5cGU6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdFx0XHRcdGlmICggIXN0YXRlICkge1xuXHRcdFx0XHRcdFx0cy5taW1lVHlwZSA9IHR5cGU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXG5cdFx0XHRcdHN0YXR1c0NvZGU6IGZ1bmN0aW9uKCBtYXAgKSB7XG5cdFx0XHRcdFx0dmFyIGNvZGU7XG5cdFx0XHRcdFx0aWYgKCBtYXAgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIHN0YXRlIDwgMiApIHtcblx0XHRcdFx0XHRcdFx0Zm9yICggY29kZSBpbiBtYXAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly8gTGF6eS1hZGQgdGhlIG5ldyBjYWxsYmFjayBpbiBhIHdheSB0aGF0IHByZXNlcnZlcyBvbGQgb25lc1xuXHRcdFx0XHRcdFx0XHRcdHN0YXR1c0NvZGVbIGNvZGUgXSA9IFsgc3RhdHVzQ29kZVsgY29kZSBdLCBtYXBbIGNvZGUgXSBdO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHQvLyBFeGVjdXRlIHRoZSBhcHByb3ByaWF0ZSBjYWxsYmFja3Ncblx0XHRcdFx0XHRcdFx0anFYSFIuYWx3YXlzKCBtYXBbIGpxWEhSLnN0YXR1cyBdICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIENhbmNlbCB0aGUgcmVxdWVzdFxuXHRcdFx0XHRhYm9ydDogZnVuY3Rpb24oIHN0YXR1c1RleHQgKSB7XG5cdFx0XHRcdFx0dmFyIGZpbmFsVGV4dCA9IHN0YXR1c1RleHQgfHwgc3RyQWJvcnQ7XG5cdFx0XHRcdFx0aWYgKCB0cmFuc3BvcnQgKSB7XG5cdFx0XHRcdFx0XHR0cmFuc3BvcnQuYWJvcnQoIGZpbmFsVGV4dCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRkb25lKCAwLCBmaW5hbFRleHQgKTtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdC8vIEF0dGFjaCBkZWZlcnJlZHNcblx0XHRkZWZlcnJlZC5wcm9taXNlKCBqcVhIUiApLmNvbXBsZXRlID0gY29tcGxldGVEZWZlcnJlZC5hZGQ7XG5cdFx0anFYSFIuc3VjY2VzcyA9IGpxWEhSLmRvbmU7XG5cdFx0anFYSFIuZXJyb3IgPSBqcVhIUi5mYWlsO1xuXG5cdFx0Ly8gUmVtb3ZlIGhhc2ggY2hhcmFjdGVyICgjNzUzMTogYW5kIHN0cmluZyBwcm9tb3Rpb24pXG5cdFx0Ly8gQWRkIHByb3RvY29sIGlmIG5vdCBwcm92aWRlZCAocHJlZmlsdGVycyBtaWdodCBleHBlY3QgaXQpXG5cdFx0Ly8gSGFuZGxlIGZhbHN5IHVybCBpbiB0aGUgc2V0dGluZ3Mgb2JqZWN0ICgjMTAwOTM6IGNvbnNpc3RlbmN5IHdpdGggb2xkIHNpZ25hdHVyZSlcblx0XHQvLyBXZSBhbHNvIHVzZSB0aGUgdXJsIHBhcmFtZXRlciBpZiBhdmFpbGFibGVcblx0XHRzLnVybCA9ICggKCB1cmwgfHwgcy51cmwgfHwgYWpheExvY2F0aW9uICkgKyBcIlwiICkucmVwbGFjZSggcmhhc2gsIFwiXCIgKVxuXHRcdFx0LnJlcGxhY2UoIHJwcm90b2NvbCwgYWpheExvY1BhcnRzWyAxIF0gKyBcIi8vXCIgKTtcblxuXHRcdC8vIEFsaWFzIG1ldGhvZCBvcHRpb24gdG8gdHlwZSBhcyBwZXIgdGlja2V0ICMxMjAwNFxuXHRcdHMudHlwZSA9IG9wdGlvbnMubWV0aG9kIHx8IG9wdGlvbnMudHlwZSB8fCBzLm1ldGhvZCB8fCBzLnR5cGU7XG5cblx0XHQvLyBFeHRyYWN0IGRhdGFUeXBlcyBsaXN0XG5cdFx0cy5kYXRhVHlwZXMgPSBqUXVlcnkudHJpbSggcy5kYXRhVHlwZSB8fCBcIipcIiApLnRvTG93ZXJDYXNlKCkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFsgXCJcIiBdO1xuXG5cdFx0Ly8gQSBjcm9zcy1kb21haW4gcmVxdWVzdCBpcyBpbiBvcmRlciB3aGVuIHdlIGhhdmUgYSBwcm90b2NvbDpob3N0OnBvcnQgbWlzbWF0Y2hcblx0XHRpZiAoIHMuY3Jvc3NEb21haW4gPT0gbnVsbCApIHtcblx0XHRcdHBhcnRzID0gcnVybC5leGVjKCBzLnVybC50b0xvd2VyQ2FzZSgpICk7XG5cdFx0XHRzLmNyb3NzRG9tYWluID0gISEoIHBhcnRzICYmXG5cdFx0XHRcdCggcGFydHNbIDEgXSAhPT0gYWpheExvY1BhcnRzWyAxIF0gfHwgcGFydHNbIDIgXSAhPT0gYWpheExvY1BhcnRzWyAyIF0gfHxcblx0XHRcdFx0XHQoIHBhcnRzWyAzIF0gfHwgKCBwYXJ0c1sgMSBdID09PSBcImh0dHA6XCIgPyBcIjgwXCIgOiBcIjQ0M1wiICkgKSAhPT1cblx0XHRcdFx0XHRcdCggYWpheExvY1BhcnRzWyAzIF0gfHwgKCBhamF4TG9jUGFydHNbIDEgXSA9PT0gXCJodHRwOlwiID8gXCI4MFwiIDogXCI0NDNcIiApICkgKVxuXHRcdFx0KTtcblx0XHR9XG5cblx0XHQvLyBDb252ZXJ0IGRhdGEgaWYgbm90IGFscmVhZHkgYSBzdHJpbmdcblx0XHRpZiAoIHMuZGF0YSAmJiBzLnByb2Nlc3NEYXRhICYmIHR5cGVvZiBzLmRhdGEgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRzLmRhdGEgPSBqUXVlcnkucGFyYW0oIHMuZGF0YSwgcy50cmFkaXRpb25hbCApO1xuXHRcdH1cblxuXHRcdC8vIEFwcGx5IHByZWZpbHRlcnNcblx0XHRpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggcHJlZmlsdGVycywgcywgb3B0aW9ucywganFYSFIgKTtcblxuXHRcdC8vIElmIHJlcXVlc3Qgd2FzIGFib3J0ZWQgaW5zaWRlIGEgcHJlZmlsdGVyLCBzdG9wIHRoZXJlXG5cdFx0aWYgKCBzdGF0ZSA9PT0gMiApIHtcblx0XHRcdHJldHVybiBqcVhIUjtcblx0XHR9XG5cblx0XHQvLyBXZSBjYW4gZmlyZSBnbG9iYWwgZXZlbnRzIGFzIG9mIG5vdyBpZiBhc2tlZCB0b1xuXHRcdGZpcmVHbG9iYWxzID0gcy5nbG9iYWw7XG5cblx0XHQvLyBXYXRjaCBmb3IgYSBuZXcgc2V0IG9mIHJlcXVlc3RzXG5cdFx0aWYgKCBmaXJlR2xvYmFscyAmJiBqUXVlcnkuYWN0aXZlKysgPT09IDAgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcihcImFqYXhTdGFydFwiKTtcblx0XHR9XG5cblx0XHQvLyBVcHBlcmNhc2UgdGhlIHR5cGVcblx0XHRzLnR5cGUgPSBzLnR5cGUudG9VcHBlckNhc2UoKTtcblxuXHRcdC8vIERldGVybWluZSBpZiByZXF1ZXN0IGhhcyBjb250ZW50XG5cdFx0cy5oYXNDb250ZW50ID0gIXJub0NvbnRlbnQudGVzdCggcy50eXBlICk7XG5cblx0XHQvLyBTYXZlIHRoZSBVUkwgaW4gY2FzZSB3ZSdyZSB0b3lpbmcgd2l0aCB0aGUgSWYtTW9kaWZpZWQtU2luY2Vcblx0XHQvLyBhbmQvb3IgSWYtTm9uZS1NYXRjaCBoZWFkZXIgbGF0ZXIgb25cblx0XHRjYWNoZVVSTCA9IHMudXJsO1xuXG5cdFx0Ly8gTW9yZSBvcHRpb25zIGhhbmRsaW5nIGZvciByZXF1ZXN0cyB3aXRoIG5vIGNvbnRlbnRcblx0XHRpZiAoICFzLmhhc0NvbnRlbnQgKSB7XG5cblx0XHRcdC8vIElmIGRhdGEgaXMgYXZhaWxhYmxlLCBhcHBlbmQgZGF0YSB0byB1cmxcblx0XHRcdGlmICggcy5kYXRhICkge1xuXHRcdFx0XHRjYWNoZVVSTCA9ICggcy51cmwgKz0gKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuZGF0YSApO1xuXHRcdFx0XHQvLyAjOTY4MjogcmVtb3ZlIGRhdGEgc28gdGhhdCBpdCdzIG5vdCB1c2VkIGluIGFuIGV2ZW50dWFsIHJldHJ5XG5cdFx0XHRcdGRlbGV0ZSBzLmRhdGE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBhbnRpLWNhY2hlIGluIHVybCBpZiBuZWVkZWRcblx0XHRcdGlmICggcy5jYWNoZSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdHMudXJsID0gcnRzLnRlc3QoIGNhY2hlVVJMICkgP1xuXG5cdFx0XHRcdFx0Ly8gSWYgdGhlcmUgaXMgYWxyZWFkeSBhICdfJyBwYXJhbWV0ZXIsIHNldCBpdHMgdmFsdWVcblx0XHRcdFx0XHRjYWNoZVVSTC5yZXBsYWNlKCBydHMsIFwiJDFfPVwiICsgbm9uY2UrKyApIDpcblxuXHRcdFx0XHRcdC8vIE90aGVyd2lzZSBhZGQgb25lIHRvIHRoZSBlbmRcblx0XHRcdFx0XHRjYWNoZVVSTCArICggcnF1ZXJ5LnRlc3QoIGNhY2hlVVJMICkgPyBcIiZcIiA6IFwiP1wiICkgKyBcIl89XCIgKyBub25jZSsrO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgSWYtTW9kaWZpZWQtU2luY2UgYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyLCBpZiBpbiBpZk1vZGlmaWVkIG1vZGUuXG5cdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gKSB7XG5cdFx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiSWYtTW9kaWZpZWQtU2luY2VcIiwgalF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSApO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSApIHtcblx0XHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJJZi1Ob25lLU1hdGNoXCIsIGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHRoZSBjb3JyZWN0IGhlYWRlciwgaWYgZGF0YSBpcyBiZWluZyBzZW50XG5cdFx0aWYgKCBzLmRhdGEgJiYgcy5oYXNDb250ZW50ICYmIHMuY29udGVudFR5cGUgIT09IGZhbHNlIHx8IG9wdGlvbnMuY29udGVudFR5cGUgKSB7XG5cdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIkNvbnRlbnQtVHlwZVwiLCBzLmNvbnRlbnRUeXBlICk7XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHRoZSBBY2NlcHRzIGhlYWRlciBmb3IgdGhlIHNlcnZlciwgZGVwZW5kaW5nIG9uIHRoZSBkYXRhVHlwZVxuXHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoXG5cdFx0XHRcIkFjY2VwdFwiLFxuXHRcdFx0cy5kYXRhVHlwZXNbIDAgXSAmJiBzLmFjY2VwdHNbIHMuZGF0YVR5cGVzWzBdIF0gP1xuXHRcdFx0XHRzLmFjY2VwdHNbIHMuZGF0YVR5cGVzWzBdIF0gKyAoIHMuZGF0YVR5cGVzWyAwIF0gIT09IFwiKlwiID8gXCIsIFwiICsgYWxsVHlwZXMgKyBcIjsgcT0wLjAxXCIgOiBcIlwiICkgOlxuXHRcdFx0XHRzLmFjY2VwdHNbIFwiKlwiIF1cblx0XHQpO1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIGhlYWRlcnMgb3B0aW9uXG5cdFx0Zm9yICggaSBpbiBzLmhlYWRlcnMgKSB7XG5cdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBpLCBzLmhlYWRlcnNbIGkgXSApO1xuXHRcdH1cblxuXHRcdC8vIEFsbG93IGN1c3RvbSBoZWFkZXJzL21pbWV0eXBlcyBhbmQgZWFybHkgYWJvcnRcblx0XHRpZiAoIHMuYmVmb3JlU2VuZCAmJiAoIHMuYmVmb3JlU2VuZC5jYWxsKCBjYWxsYmFja0NvbnRleHQsIGpxWEhSLCBzICkgPT09IGZhbHNlIHx8IHN0YXRlID09PSAyICkgKSB7XG5cdFx0XHQvLyBBYm9ydCBpZiBub3QgZG9uZSBhbHJlYWR5IGFuZCByZXR1cm5cblx0XHRcdHJldHVybiBqcVhIUi5hYm9ydCgpO1xuXHRcdH1cblxuXHRcdC8vIGFib3J0aW5nIGlzIG5vIGxvbmdlciBhIGNhbmNlbGxhdGlvblxuXHRcdHN0ckFib3J0ID0gXCJhYm9ydFwiO1xuXG5cdFx0Ly8gSW5zdGFsbCBjYWxsYmFja3Mgb24gZGVmZXJyZWRzXG5cdFx0Zm9yICggaSBpbiB7IHN1Y2Nlc3M6IDEsIGVycm9yOiAxLCBjb21wbGV0ZTogMSB9ICkge1xuXHRcdFx0anFYSFJbIGkgXSggc1sgaSBdICk7XG5cdFx0fVxuXG5cdFx0Ly8gR2V0IHRyYW5zcG9ydFxuXHRcdHRyYW5zcG9ydCA9IGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCB0cmFuc3BvcnRzLCBzLCBvcHRpb25zLCBqcVhIUiApO1xuXG5cdFx0Ly8gSWYgbm8gdHJhbnNwb3J0LCB3ZSBhdXRvLWFib3J0XG5cdFx0aWYgKCAhdHJhbnNwb3J0ICkge1xuXHRcdFx0ZG9uZSggLTEsIFwiTm8gVHJhbnNwb3J0XCIgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0anFYSFIucmVhZHlTdGF0ZSA9IDE7XG5cblx0XHRcdC8vIFNlbmQgZ2xvYmFsIGV2ZW50XG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xuXHRcdFx0XHRnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggXCJhamF4U2VuZFwiLCBbIGpxWEhSLCBzIF0gKTtcblx0XHRcdH1cblx0XHRcdC8vIFRpbWVvdXRcblx0XHRcdGlmICggcy5hc3luYyAmJiBzLnRpbWVvdXQgPiAwICkge1xuXHRcdFx0XHR0aW1lb3V0VGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGpxWEhSLmFib3J0KFwidGltZW91dFwiKTtcblx0XHRcdFx0fSwgcy50aW1lb3V0ICk7XG5cdFx0XHR9XG5cblx0XHRcdHRyeSB7XG5cdFx0XHRcdHN0YXRlID0gMTtcblx0XHRcdFx0dHJhbnNwb3J0LnNlbmQoIHJlcXVlc3RIZWFkZXJzLCBkb25lICk7XG5cdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0Ly8gUHJvcGFnYXRlIGV4Y2VwdGlvbiBhcyBlcnJvciBpZiBub3QgZG9uZVxuXHRcdFx0XHRpZiAoIHN0YXRlIDwgMiApIHtcblx0XHRcdFx0XHRkb25lKCAtMSwgZSApO1xuXHRcdFx0XHQvLyBTaW1wbHkgcmV0aHJvdyBvdGhlcndpc2Vcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0aHJvdyBlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsbGJhY2sgZm9yIHdoZW4gZXZlcnl0aGluZyBpcyBkb25lXG5cdFx0ZnVuY3Rpb24gZG9uZSggc3RhdHVzLCBuYXRpdmVTdGF0dXNUZXh0LCByZXNwb25zZXMsIGhlYWRlcnMgKSB7XG5cdFx0XHR2YXIgaXNTdWNjZXNzLCBzdWNjZXNzLCBlcnJvciwgcmVzcG9uc2UsIG1vZGlmaWVkLFxuXHRcdFx0XHRzdGF0dXNUZXh0ID0gbmF0aXZlU3RhdHVzVGV4dDtcblxuXHRcdFx0Ly8gQ2FsbGVkIG9uY2Vcblx0XHRcdGlmICggc3RhdGUgPT09IDIgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3RhdGUgaXMgXCJkb25lXCIgbm93XG5cdFx0XHRzdGF0ZSA9IDI7XG5cblx0XHRcdC8vIENsZWFyIHRpbWVvdXQgaWYgaXQgZXhpc3RzXG5cdFx0XHRpZiAoIHRpbWVvdXRUaW1lciApIHtcblx0XHRcdFx0Y2xlYXJUaW1lb3V0KCB0aW1lb3V0VGltZXIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRGVyZWZlcmVuY2UgdHJhbnNwb3J0IGZvciBlYXJseSBnYXJiYWdlIGNvbGxlY3Rpb25cblx0XHRcdC8vIChubyBtYXR0ZXIgaG93IGxvbmcgdGhlIGpxWEhSIG9iamVjdCB3aWxsIGJlIHVzZWQpXG5cdFx0XHR0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG5cblx0XHRcdC8vIENhY2hlIHJlc3BvbnNlIGhlYWRlcnNcblx0XHRcdHJlc3BvbnNlSGVhZGVyc1N0cmluZyA9IGhlYWRlcnMgfHwgXCJcIjtcblxuXHRcdFx0Ly8gU2V0IHJlYWR5U3RhdGVcblx0XHRcdGpxWEhSLnJlYWR5U3RhdGUgPSBzdGF0dXMgPiAwID8gNCA6IDA7XG5cblx0XHRcdC8vIERldGVybWluZSBpZiBzdWNjZXNzZnVsXG5cdFx0XHRpc1N1Y2Nlc3MgPSBzdGF0dXMgPj0gMjAwICYmIHN0YXR1cyA8IDMwMCB8fCBzdGF0dXMgPT09IDMwNDtcblxuXHRcdFx0Ly8gR2V0IHJlc3BvbnNlIGRhdGFcblx0XHRcdGlmICggcmVzcG9uc2VzICkge1xuXHRcdFx0XHRyZXNwb25zZSA9IGFqYXhIYW5kbGVSZXNwb25zZXMoIHMsIGpxWEhSLCByZXNwb25zZXMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29udmVydCBubyBtYXR0ZXIgd2hhdCAodGhhdCB3YXkgcmVzcG9uc2VYWFggZmllbGRzIGFyZSBhbHdheXMgc2V0KVxuXHRcdFx0cmVzcG9uc2UgPSBhamF4Q29udmVydCggcywgcmVzcG9uc2UsIGpxWEhSLCBpc1N1Y2Nlc3MgKTtcblxuXHRcdFx0Ly8gSWYgc3VjY2Vzc2Z1bCwgaGFuZGxlIHR5cGUgY2hhaW5pbmdcblx0XHRcdGlmICggaXNTdWNjZXNzICkge1xuXG5cdFx0XHRcdC8vIFNldCB0aGUgSWYtTW9kaWZpZWQtU2luY2UgYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyLCBpZiBpbiBpZk1vZGlmaWVkIG1vZGUuXG5cdFx0XHRcdGlmICggcy5pZk1vZGlmaWVkICkge1xuXHRcdFx0XHRcdG1vZGlmaWVkID0ganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoXCJMYXN0LU1vZGlmaWVkXCIpO1xuXHRcdFx0XHRcdGlmICggbW9kaWZpZWQgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkubGFzdE1vZGlmaWVkWyBjYWNoZVVSTCBdID0gbW9kaWZpZWQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdG1vZGlmaWVkID0ganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoXCJldGFnXCIpO1xuXHRcdFx0XHRcdGlmICggbW9kaWZpZWQgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSA9IG1vZGlmaWVkO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIGlmIG5vIGNvbnRlbnRcblx0XHRcdFx0aWYgKCBzdGF0dXMgPT09IDIwNCB8fCBzLnR5cGUgPT09IFwiSEVBRFwiICkge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSBcIm5vY29udGVudFwiO1xuXG5cdFx0XHRcdC8vIGlmIG5vdCBtb2RpZmllZFxuXHRcdFx0XHR9IGVsc2UgaWYgKCBzdGF0dXMgPT09IDMwNCApIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJub3Rtb2RpZmllZFwiO1xuXG5cdFx0XHRcdC8vIElmIHdlIGhhdmUgZGF0YSwgbGV0J3MgY29udmVydCBpdFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSByZXNwb25zZS5zdGF0ZTtcblx0XHRcdFx0XHRzdWNjZXNzID0gcmVzcG9uc2UuZGF0YTtcblx0XHRcdFx0XHRlcnJvciA9IHJlc3BvbnNlLmVycm9yO1xuXHRcdFx0XHRcdGlzU3VjY2VzcyA9ICFlcnJvcjtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gV2UgZXh0cmFjdCBlcnJvciBmcm9tIHN0YXR1c1RleHRcblx0XHRcdFx0Ly8gdGhlbiBub3JtYWxpemUgc3RhdHVzVGV4dCBhbmQgc3RhdHVzIGZvciBub24tYWJvcnRzXG5cdFx0XHRcdGVycm9yID0gc3RhdHVzVGV4dDtcblx0XHRcdFx0aWYgKCBzdGF0dXMgfHwgIXN0YXR1c1RleHQgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwiZXJyb3JcIjtcblx0XHRcdFx0XHRpZiAoIHN0YXR1cyA8IDAgKSB7XG5cdFx0XHRcdFx0XHRzdGF0dXMgPSAwO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgZGF0YSBmb3IgdGhlIGZha2UgeGhyIG9iamVjdFxuXHRcdFx0anFYSFIuc3RhdHVzID0gc3RhdHVzO1xuXHRcdFx0anFYSFIuc3RhdHVzVGV4dCA9ICggbmF0aXZlU3RhdHVzVGV4dCB8fCBzdGF0dXNUZXh0ICkgKyBcIlwiO1xuXG5cdFx0XHQvLyBTdWNjZXNzL0Vycm9yXG5cdFx0XHRpZiAoIGlzU3VjY2VzcyApIHtcblx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBzdWNjZXNzLCBzdGF0dXNUZXh0LCBqcVhIUiBdICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsganFYSFIsIHN0YXR1c1RleHQsIGVycm9yIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdGpxWEhSLnN0YXR1c0NvZGUoIHN0YXR1c0NvZGUgKTtcblx0XHRcdHN0YXR1c0NvZGUgPSB1bmRlZmluZWQ7XG5cblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBpc1N1Y2Nlc3MgPyBcImFqYXhTdWNjZXNzXCIgOiBcImFqYXhFcnJvclwiLFxuXHRcdFx0XHRcdFsganFYSFIsIHMsIGlzU3VjY2VzcyA/IHN1Y2Nlc3MgOiBlcnJvciBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbXBsZXRlXG5cdFx0XHRjb21wbGV0ZURlZmVycmVkLmZpcmVXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsganFYSFIsIHN0YXR1c1RleHQgXSApO1xuXG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xuXHRcdFx0XHRnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggXCJhamF4Q29tcGxldGVcIiwgWyBqcVhIUiwgcyBdICk7XG5cdFx0XHRcdC8vIEhhbmRsZSB0aGUgZ2xvYmFsIEFKQVggY291bnRlclxuXHRcdFx0XHRpZiAoICEoIC0talF1ZXJ5LmFjdGl2ZSApICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKFwiYWpheFN0b3BcIik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4ganFYSFI7XG5cdH0sXG5cblx0Z2V0SlNPTjogZnVuY3Rpb24oIHVybCwgZGF0YSwgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5nZXQoIHVybCwgZGF0YSwgY2FsbGJhY2ssIFwianNvblwiICk7XG5cdH0sXG5cblx0Z2V0U2NyaXB0OiBmdW5jdGlvbiggdXJsLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdldCggdXJsLCB1bmRlZmluZWQsIGNhbGxiYWNrLCBcInNjcmlwdFwiICk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZWFjaCggWyBcImdldFwiLCBcInBvc3RcIiBdLCBmdW5jdGlvbiggaSwgbWV0aG9kICkge1xuXHRqUXVlcnlbIG1ldGhvZCBdID0gZnVuY3Rpb24oIHVybCwgZGF0YSwgY2FsbGJhY2ssIHR5cGUgKSB7XG5cdFx0Ly8gc2hpZnQgYXJndW1lbnRzIGlmIGRhdGEgYXJndW1lbnQgd2FzIG9taXR0ZWRcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBkYXRhICkgKSB7XG5cdFx0XHR0eXBlID0gdHlwZSB8fCBjYWxsYmFjaztcblx0XHRcdGNhbGxiYWNrID0gZGF0YTtcblx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpRdWVyeS5hamF4KHtcblx0XHRcdHVybDogdXJsLFxuXHRcdFx0dHlwZTogbWV0aG9kLFxuXHRcdFx0ZGF0YVR5cGU6IHR5cGUsXG5cdFx0XHRkYXRhOiBkYXRhLFxuXHRcdFx0c3VjY2VzczogY2FsbGJhY2tcblx0XHR9KTtcblx0fTtcbn0pO1xuXG4vLyBBdHRhY2ggYSBidW5jaCBvZiBmdW5jdGlvbnMgZm9yIGhhbmRsaW5nIGNvbW1vbiBBSkFYIGV2ZW50c1xualF1ZXJ5LmVhY2goIFsgXCJhamF4U3RhcnRcIiwgXCJhamF4U3RvcFwiLCBcImFqYXhDb21wbGV0ZVwiLCBcImFqYXhFcnJvclwiLCBcImFqYXhTdWNjZXNzXCIsIFwiYWpheFNlbmRcIiBdLCBmdW5jdGlvbiggaSwgdHlwZSApIHtcblx0alF1ZXJ5LmZuWyB0eXBlIF0gPSBmdW5jdGlvbiggZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub24oIHR5cGUsIGZuICk7XG5cdH07XG59KTtcblxuXG5qUXVlcnkuX2V2YWxVcmwgPSBmdW5jdGlvbiggdXJsICkge1xuXHRyZXR1cm4galF1ZXJ5LmFqYXgoe1xuXHRcdHVybDogdXJsLFxuXHRcdHR5cGU6IFwiR0VUXCIsXG5cdFx0ZGF0YVR5cGU6IFwic2NyaXB0XCIsXG5cdFx0YXN5bmM6IGZhbHNlLFxuXHRcdGdsb2JhbDogZmFsc2UsXG5cdFx0XCJ0aHJvd3NcIjogdHJ1ZVxuXHR9KTtcbn07XG5cblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdHdyYXBBbGw6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHZhciB3cmFwO1xuXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggaHRtbCApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcEFsbCggaHRtbC5jYWxsKHRoaXMsIGkpICk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRpZiAoIHRoaXNbIDAgXSApIHtcblxuXHRcdFx0Ly8gVGhlIGVsZW1lbnRzIHRvIHdyYXAgdGhlIHRhcmdldCBhcm91bmRcblx0XHRcdHdyYXAgPSBqUXVlcnkoIGh0bWwsIHRoaXNbIDAgXS5vd25lckRvY3VtZW50ICkuZXEoIDAgKS5jbG9uZSggdHJ1ZSApO1xuXG5cdFx0XHRpZiAoIHRoaXNbIDAgXS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR3cmFwLmluc2VydEJlZm9yZSggdGhpc1sgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHdyYXAubWFwKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZWxlbSA9IHRoaXM7XG5cblx0XHRcdFx0d2hpbGUgKCBlbGVtLmZpcnN0RWxlbWVudENoaWxkICkge1xuXHRcdFx0XHRcdGVsZW0gPSBlbGVtLmZpcnN0RWxlbWVudENoaWxkO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIGVsZW07XG5cdFx0XHR9KS5hcHBlbmQoIHRoaXMgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHR3cmFwSW5uZXI6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGh0bWwgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLndyYXBJbm5lciggaHRtbC5jYWxsKHRoaXMsIGkpICk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHNlbGYgPSBqUXVlcnkoIHRoaXMgKSxcblx0XHRcdFx0Y29udGVudHMgPSBzZWxmLmNvbnRlbnRzKCk7XG5cblx0XHRcdGlmICggY29udGVudHMubGVuZ3RoICkge1xuXHRcdFx0XHRjb250ZW50cy53cmFwQWxsKCBodG1sICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNlbGYuYXBwZW5kKCBodG1sICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0d3JhcDogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0dmFyIGlzRnVuY3Rpb24gPSBqUXVlcnkuaXNGdW5jdGlvbiggaHRtbCApO1xuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaSApIHtcblx0XHRcdGpRdWVyeSggdGhpcyApLndyYXBBbGwoIGlzRnVuY3Rpb24gPyBodG1sLmNhbGwodGhpcywgaSkgOiBodG1sICk7XG5cdFx0fSk7XG5cdH0sXG5cblx0dW53cmFwOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wYXJlbnQoKS5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCAhalF1ZXJ5Lm5vZGVOYW1lKCB0aGlzLCBcImJvZHlcIiApICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5yZXBsYWNlV2l0aCggdGhpcy5jaGlsZE5vZGVzICk7XG5cdFx0XHR9XG5cdFx0fSkuZW5kKCk7XG5cdH1cbn0pO1xuXG5cbmpRdWVyeS5leHByLmZpbHRlcnMuaGlkZGVuID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdC8vIFN1cHBvcnQ6IE9wZXJhIDw9IDEyLjEyXG5cdC8vIE9wZXJhIHJlcG9ydHMgb2Zmc2V0V2lkdGhzIGFuZCBvZmZzZXRIZWlnaHRzIGxlc3MgdGhhbiB6ZXJvIG9uIHNvbWUgZWxlbWVudHNcblx0cmV0dXJuIGVsZW0ub2Zmc2V0V2lkdGggPD0gMCAmJiBlbGVtLm9mZnNldEhlaWdodCA8PSAwO1xufTtcbmpRdWVyeS5leHByLmZpbHRlcnMudmlzaWJsZSA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRyZXR1cm4gIWpRdWVyeS5leHByLmZpbHRlcnMuaGlkZGVuKCBlbGVtICk7XG59O1xuXG5cblxuXG52YXIgcjIwID0gLyUyMC9nLFxuXHRyYnJhY2tldCA9IC9cXFtcXF0kLyxcblx0ckNSTEYgPSAvXFxyP1xcbi9nLFxuXHRyc3VibWl0dGVyVHlwZXMgPSAvXig/OnN1Ym1pdHxidXR0b258aW1hZ2V8cmVzZXR8ZmlsZSkkL2ksXG5cdHJzdWJtaXR0YWJsZSA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGtleWdlbikvaTtcblxuZnVuY3Rpb24gYnVpbGRQYXJhbXMoIHByZWZpeCwgb2JqLCB0cmFkaXRpb25hbCwgYWRkICkge1xuXHR2YXIgbmFtZTtcblxuXHRpZiAoIGpRdWVyeS5pc0FycmF5KCBvYmogKSApIHtcblx0XHQvLyBTZXJpYWxpemUgYXJyYXkgaXRlbS5cblx0XHRqUXVlcnkuZWFjaCggb2JqLCBmdW5jdGlvbiggaSwgdiApIHtcblx0XHRcdGlmICggdHJhZGl0aW9uYWwgfHwgcmJyYWNrZXQudGVzdCggcHJlZml4ICkgKSB7XG5cdFx0XHRcdC8vIFRyZWF0IGVhY2ggYXJyYXkgaXRlbSBhcyBhIHNjYWxhci5cblx0XHRcdFx0YWRkKCBwcmVmaXgsIHYgKTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gSXRlbSBpcyBub24tc2NhbGFyIChhcnJheSBvciBvYmplY3QpLCBlbmNvZGUgaXRzIG51bWVyaWMgaW5kZXguXG5cdFx0XHRcdGJ1aWxkUGFyYW1zKCBwcmVmaXggKyBcIltcIiArICggdHlwZW9mIHYgPT09IFwib2JqZWN0XCIgPyBpIDogXCJcIiApICsgXCJdXCIsIHYsIHRyYWRpdGlvbmFsLCBhZGQgKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHR9IGVsc2UgaWYgKCAhdHJhZGl0aW9uYWwgJiYgalF1ZXJ5LnR5cGUoIG9iaiApID09PSBcIm9iamVjdFwiICkge1xuXHRcdC8vIFNlcmlhbGl6ZSBvYmplY3QgaXRlbS5cblx0XHRmb3IgKCBuYW1lIGluIG9iaiApIHtcblx0XHRcdGJ1aWxkUGFyYW1zKCBwcmVmaXggKyBcIltcIiArIG5hbWUgKyBcIl1cIiwgb2JqWyBuYW1lIF0sIHRyYWRpdGlvbmFsLCBhZGQgKTtcblx0XHR9XG5cblx0fSBlbHNlIHtcblx0XHQvLyBTZXJpYWxpemUgc2NhbGFyIGl0ZW0uXG5cdFx0YWRkKCBwcmVmaXgsIG9iaiApO1xuXHR9XG59XG5cbi8vIFNlcmlhbGl6ZSBhbiBhcnJheSBvZiBmb3JtIGVsZW1lbnRzIG9yIGEgc2V0IG9mXG4vLyBrZXkvdmFsdWVzIGludG8gYSBxdWVyeSBzdHJpbmdcbmpRdWVyeS5wYXJhbSA9IGZ1bmN0aW9uKCBhLCB0cmFkaXRpb25hbCApIHtcblx0dmFyIHByZWZpeCxcblx0XHRzID0gW10sXG5cdFx0YWRkID0gZnVuY3Rpb24oIGtleSwgdmFsdWUgKSB7XG5cdFx0XHQvLyBJZiB2YWx1ZSBpcyBhIGZ1bmN0aW9uLCBpbnZva2UgaXQgYW5kIHJldHVybiBpdHMgdmFsdWVcblx0XHRcdHZhbHVlID0galF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgPyB2YWx1ZSgpIDogKCB2YWx1ZSA9PSBudWxsID8gXCJcIiA6IHZhbHVlICk7XG5cdFx0XHRzWyBzLmxlbmd0aCBdID0gZW5jb2RlVVJJQ29tcG9uZW50KCBrZXkgKSArIFwiPVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KCB2YWx1ZSApO1xuXHRcdH07XG5cblx0Ly8gU2V0IHRyYWRpdGlvbmFsIHRvIHRydWUgZm9yIGpRdWVyeSA8PSAxLjMuMiBiZWhhdmlvci5cblx0aWYgKCB0cmFkaXRpb25hbCA9PT0gdW5kZWZpbmVkICkge1xuXHRcdHRyYWRpdGlvbmFsID0galF1ZXJ5LmFqYXhTZXR0aW5ncyAmJiBqUXVlcnkuYWpheFNldHRpbmdzLnRyYWRpdGlvbmFsO1xuXHR9XG5cblx0Ly8gSWYgYW4gYXJyYXkgd2FzIHBhc3NlZCBpbiwgYXNzdW1lIHRoYXQgaXQgaXMgYW4gYXJyYXkgb2YgZm9ybSBlbGVtZW50cy5cblx0aWYgKCBqUXVlcnkuaXNBcnJheSggYSApIHx8ICggYS5qcXVlcnkgJiYgIWpRdWVyeS5pc1BsYWluT2JqZWN0KCBhICkgKSApIHtcblx0XHQvLyBTZXJpYWxpemUgdGhlIGZvcm0gZWxlbWVudHNcblx0XHRqUXVlcnkuZWFjaCggYSwgZnVuY3Rpb24oKSB7XG5cdFx0XHRhZGQoIHRoaXMubmFtZSwgdGhpcy52YWx1ZSApO1xuXHRcdH0pO1xuXG5cdH0gZWxzZSB7XG5cdFx0Ly8gSWYgdHJhZGl0aW9uYWwsIGVuY29kZSB0aGUgXCJvbGRcIiB3YXkgKHRoZSB3YXkgMS4zLjIgb3Igb2xkZXJcblx0XHQvLyBkaWQgaXQpLCBvdGhlcndpc2UgZW5jb2RlIHBhcmFtcyByZWN1cnNpdmVseS5cblx0XHRmb3IgKCBwcmVmaXggaW4gYSApIHtcblx0XHRcdGJ1aWxkUGFyYW1zKCBwcmVmaXgsIGFbIHByZWZpeCBdLCB0cmFkaXRpb25hbCwgYWRkICk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSByZXN1bHRpbmcgc2VyaWFsaXphdGlvblxuXHRyZXR1cm4gcy5qb2luKCBcIiZcIiApLnJlcGxhY2UoIHIyMCwgXCIrXCIgKTtcbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRzZXJpYWxpemU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBqUXVlcnkucGFyYW0oIHRoaXMuc2VyaWFsaXplQXJyYXkoKSApO1xuXHR9LFxuXHRzZXJpYWxpemVBcnJheTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8gQ2FuIGFkZCBwcm9wSG9vayBmb3IgXCJlbGVtZW50c1wiIHRvIGZpbHRlciBvciBhZGQgZm9ybSBlbGVtZW50c1xuXHRcdFx0dmFyIGVsZW1lbnRzID0galF1ZXJ5LnByb3AoIHRoaXMsIFwiZWxlbWVudHNcIiApO1xuXHRcdFx0cmV0dXJuIGVsZW1lbnRzID8galF1ZXJ5Lm1ha2VBcnJheSggZWxlbWVudHMgKSA6IHRoaXM7XG5cdFx0fSlcblx0XHQuZmlsdGVyKGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHR5cGUgPSB0aGlzLnR5cGU7XG5cblx0XHRcdC8vIFVzZSAuaXMoIFwiOmRpc2FibGVkXCIgKSBzbyB0aGF0IGZpZWxkc2V0W2Rpc2FibGVkXSB3b3Jrc1xuXHRcdFx0cmV0dXJuIHRoaXMubmFtZSAmJiAhalF1ZXJ5KCB0aGlzICkuaXMoIFwiOmRpc2FibGVkXCIgKSAmJlxuXHRcdFx0XHRyc3VibWl0dGFibGUudGVzdCggdGhpcy5ub2RlTmFtZSApICYmICFyc3VibWl0dGVyVHlwZXMudGVzdCggdHlwZSApICYmXG5cdFx0XHRcdCggdGhpcy5jaGVja2VkIHx8ICFyY2hlY2thYmxlVHlwZS50ZXN0KCB0eXBlICkgKTtcblx0XHR9KVxuXHRcdC5tYXAoZnVuY3Rpb24oIGksIGVsZW0gKSB7XG5cdFx0XHR2YXIgdmFsID0galF1ZXJ5KCB0aGlzICkudmFsKCk7XG5cblx0XHRcdHJldHVybiB2YWwgPT0gbnVsbCA/XG5cdFx0XHRcdG51bGwgOlxuXHRcdFx0XHRqUXVlcnkuaXNBcnJheSggdmFsICkgP1xuXHRcdFx0XHRcdGpRdWVyeS5tYXAoIHZhbCwgZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdFx0XHRcdHJldHVybiB7IG5hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbC5yZXBsYWNlKCByQ1JMRiwgXCJcXHJcXG5cIiApIH07XG5cdFx0XHRcdFx0fSkgOlxuXHRcdFx0XHRcdHsgbmFtZTogZWxlbS5uYW1lLCB2YWx1ZTogdmFsLnJlcGxhY2UoIHJDUkxGLCBcIlxcclxcblwiICkgfTtcblx0XHR9KS5nZXQoKTtcblx0fVxufSk7XG5cblxualF1ZXJ5LmFqYXhTZXR0aW5ncy54aHIgPSBmdW5jdGlvbigpIHtcblx0dHJ5IHtcblx0XHRyZXR1cm4gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cdH0gY2F0Y2goIGUgKSB7fVxufTtcblxudmFyIHhocklkID0gMCxcblx0eGhyQ2FsbGJhY2tzID0ge30sXG5cdHhoclN1Y2Nlc3NTdGF0dXMgPSB7XG5cdFx0Ly8gZmlsZSBwcm90b2NvbCBhbHdheXMgeWllbGRzIHN0YXR1cyBjb2RlIDAsIGFzc3VtZSAyMDBcblx0XHQwOiAyMDAsXG5cdFx0Ly8gU3VwcG9ydDogSUU5XG5cdFx0Ly8gIzE0NTA6IHNvbWV0aW1lcyBJRSByZXR1cm5zIDEyMjMgd2hlbiBpdCBzaG91bGQgYmUgMjA0XG5cdFx0MTIyMzogMjA0XG5cdH0sXG5cdHhoclN1cHBvcnRlZCA9IGpRdWVyeS5hamF4U2V0dGluZ3MueGhyKCk7XG5cbi8vIFN1cHBvcnQ6IElFOVxuLy8gT3BlbiByZXF1ZXN0cyBtdXN0IGJlIG1hbnVhbGx5IGFib3J0ZWQgb24gdW5sb2FkICgjNTI4MClcbmlmICggd2luZG93LkFjdGl2ZVhPYmplY3QgKSB7XG5cdGpRdWVyeSggd2luZG93ICkub24oIFwidW5sb2FkXCIsIGZ1bmN0aW9uKCkge1xuXHRcdGZvciAoIHZhciBrZXkgaW4geGhyQ2FsbGJhY2tzICkge1xuXHRcdFx0eGhyQ2FsbGJhY2tzWyBrZXkgXSgpO1xuXHRcdH1cblx0fSk7XG59XG5cbnN1cHBvcnQuY29ycyA9ICEheGhyU3VwcG9ydGVkICYmICggXCJ3aXRoQ3JlZGVudGlhbHNcIiBpbiB4aHJTdXBwb3J0ZWQgKTtcbnN1cHBvcnQuYWpheCA9IHhoclN1cHBvcnRlZCA9ICEheGhyU3VwcG9ydGVkO1xuXG5qUXVlcnkuYWpheFRyYW5zcG9ydChmdW5jdGlvbiggb3B0aW9ucyApIHtcblx0dmFyIGNhbGxiYWNrO1xuXG5cdC8vIENyb3NzIGRvbWFpbiBvbmx5IGFsbG93ZWQgaWYgc3VwcG9ydGVkIHRocm91Z2ggWE1MSHR0cFJlcXVlc3Rcblx0aWYgKCBzdXBwb3J0LmNvcnMgfHwgeGhyU3VwcG9ydGVkICYmICFvcHRpb25zLmNyb3NzRG9tYWluICkge1xuXHRcdHJldHVybiB7XG5cdFx0XHRzZW5kOiBmdW5jdGlvbiggaGVhZGVycywgY29tcGxldGUgKSB7XG5cdFx0XHRcdHZhciBpLFxuXHRcdFx0XHRcdHhociA9IG9wdGlvbnMueGhyKCksXG5cdFx0XHRcdFx0aWQgPSArK3hocklkO1xuXG5cdFx0XHRcdHhoci5vcGVuKCBvcHRpb25zLnR5cGUsIG9wdGlvbnMudXJsLCBvcHRpb25zLmFzeW5jLCBvcHRpb25zLnVzZXJuYW1lLCBvcHRpb25zLnBhc3N3b3JkICk7XG5cblx0XHRcdFx0Ly8gQXBwbHkgY3VzdG9tIGZpZWxkcyBpZiBwcm92aWRlZFxuXHRcdFx0XHRpZiAoIG9wdGlvbnMueGhyRmllbGRzICkge1xuXHRcdFx0XHRcdGZvciAoIGkgaW4gb3B0aW9ucy54aHJGaWVsZHMgKSB7XG5cdFx0XHRcdFx0XHR4aHJbIGkgXSA9IG9wdGlvbnMueGhyRmllbGRzWyBpIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gT3ZlcnJpZGUgbWltZSB0eXBlIGlmIG5lZWRlZFxuXHRcdFx0XHRpZiAoIG9wdGlvbnMubWltZVR5cGUgJiYgeGhyLm92ZXJyaWRlTWltZVR5cGUgKSB7XG5cdFx0XHRcdFx0eGhyLm92ZXJyaWRlTWltZVR5cGUoIG9wdGlvbnMubWltZVR5cGUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFgtUmVxdWVzdGVkLVdpdGggaGVhZGVyXG5cdFx0XHRcdC8vIEZvciBjcm9zcy1kb21haW4gcmVxdWVzdHMsIHNlZWluZyBhcyBjb25kaXRpb25zIGZvciBhIHByZWZsaWdodCBhcmVcblx0XHRcdFx0Ly8gYWtpbiB0byBhIGppZ3NhdyBwdXp6bGUsIHdlIHNpbXBseSBuZXZlciBzZXQgaXQgdG8gYmUgc3VyZS5cblx0XHRcdFx0Ly8gKGl0IGNhbiBhbHdheXMgYmUgc2V0IG9uIGEgcGVyLXJlcXVlc3QgYmFzaXMgb3IgZXZlbiB1c2luZyBhamF4U2V0dXApXG5cdFx0XHRcdC8vIEZvciBzYW1lLWRvbWFpbiByZXF1ZXN0cywgd29uJ3QgY2hhbmdlIGhlYWRlciBpZiBhbHJlYWR5IHByb3ZpZGVkLlxuXHRcdFx0XHRpZiAoICFvcHRpb25zLmNyb3NzRG9tYWluICYmICFoZWFkZXJzW1wiWC1SZXF1ZXN0ZWQtV2l0aFwiXSApIHtcblx0XHRcdFx0XHRoZWFkZXJzW1wiWC1SZXF1ZXN0ZWQtV2l0aFwiXSA9IFwiWE1MSHR0cFJlcXVlc3RcIjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFNldCBoZWFkZXJzXG5cdFx0XHRcdGZvciAoIGkgaW4gaGVhZGVycyApIHtcblx0XHRcdFx0XHR4aHIuc2V0UmVxdWVzdEhlYWRlciggaSwgaGVhZGVyc1sgaSBdICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBDYWxsYmFja1xuXHRcdFx0XHRjYWxsYmFjayA9IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdFx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0XHRcdGRlbGV0ZSB4aHJDYWxsYmFja3NbIGlkIF07XG5cdFx0XHRcdFx0XHRcdGNhbGxiYWNrID0geGhyLm9ubG9hZCA9IHhoci5vbmVycm9yID0gbnVsbDtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIHR5cGUgPT09IFwiYWJvcnRcIiApIHtcblx0XHRcdFx0XHRcdFx0XHR4aHIuYWJvcnQoKTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggdHlwZSA9PT0gXCJlcnJvclwiICkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbXBsZXRlKFxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gZmlsZTogcHJvdG9jb2wgYWx3YXlzIHlpZWxkcyBzdGF0dXMgMDsgc2VlICM4NjA1LCAjMTQyMDdcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXMsXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzVGV4dFxuXHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHJTdWNjZXNzU3RhdHVzWyB4aHIuc3RhdHVzIF0gfHwgeGhyLnN0YXR1cyxcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXNUZXh0LFxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUU5XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBBY2Nlc3NpbmcgYmluYXJ5LWRhdGEgcmVzcG9uc2VUZXh0IHRocm93cyBhbiBleGNlcHRpb25cblx0XHRcdFx0XHRcdFx0XHRcdC8vICgjMTE0MjYpXG5cdFx0XHRcdFx0XHRcdFx0XHR0eXBlb2YgeGhyLnJlc3BvbnNlVGV4dCA9PT0gXCJzdHJpbmdcIiA/IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGV4dDogeGhyLnJlc3BvbnNlVGV4dFxuXHRcdFx0XHRcdFx0XHRcdFx0fSA6IHVuZGVmaW5lZCxcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKVxuXHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9O1xuXG5cdFx0XHRcdC8vIExpc3RlbiB0byBldmVudHNcblx0XHRcdFx0eGhyLm9ubG9hZCA9IGNhbGxiYWNrKCk7XG5cdFx0XHRcdHhoci5vbmVycm9yID0gY2FsbGJhY2soXCJlcnJvclwiKTtcblxuXHRcdFx0XHQvLyBDcmVhdGUgdGhlIGFib3J0IGNhbGxiYWNrXG5cdFx0XHRcdGNhbGxiYWNrID0geGhyQ2FsbGJhY2tzWyBpZCBdID0gY2FsbGJhY2soXCJhYm9ydFwiKTtcblxuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdC8vIERvIHNlbmQgdGhlIHJlcXVlc3QgKHRoaXMgbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbilcblx0XHRcdFx0XHR4aHIuc2VuZCggb3B0aW9ucy5oYXNDb250ZW50ICYmIG9wdGlvbnMuZGF0YSB8fCBudWxsICk7XG5cdFx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0XHRcdC8vICMxNDY4MzogT25seSByZXRocm93IGlmIHRoaXMgaGFzbid0IGJlZW4gbm90aWZpZWQgYXMgYW4gZXJyb3IgeWV0XG5cdFx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRcdHRocm93IGU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXG5cdFx0XHRhYm9ydDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0Y2FsbGJhY2soKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cdH1cbn0pO1xuXG5cblxuXG4vLyBJbnN0YWxsIHNjcmlwdCBkYXRhVHlwZVxualF1ZXJ5LmFqYXhTZXR1cCh7XG5cdGFjY2VwdHM6IHtcblx0XHRzY3JpcHQ6IFwidGV4dC9qYXZhc2NyaXB0LCBhcHBsaWNhdGlvbi9qYXZhc2NyaXB0LCBhcHBsaWNhdGlvbi9lY21hc2NyaXB0LCBhcHBsaWNhdGlvbi94LWVjbWFzY3JpcHRcIlxuXHR9LFxuXHRjb250ZW50czoge1xuXHRcdHNjcmlwdDogLyg/OmphdmF8ZWNtYSlzY3JpcHQvXG5cdH0sXG5cdGNvbnZlcnRlcnM6IHtcblx0XHRcInRleHQgc2NyaXB0XCI6IGZ1bmN0aW9uKCB0ZXh0ICkge1xuXHRcdFx0alF1ZXJ5Lmdsb2JhbEV2YWwoIHRleHQgKTtcblx0XHRcdHJldHVybiB0ZXh0O1xuXHRcdH1cblx0fVxufSk7XG5cbi8vIEhhbmRsZSBjYWNoZSdzIHNwZWNpYWwgY2FzZSBhbmQgY3Jvc3NEb21haW5cbmpRdWVyeS5hamF4UHJlZmlsdGVyKCBcInNjcmlwdFwiLCBmdW5jdGlvbiggcyApIHtcblx0aWYgKCBzLmNhY2hlID09PSB1bmRlZmluZWQgKSB7XG5cdFx0cy5jYWNoZSA9IGZhbHNlO1xuXHR9XG5cdGlmICggcy5jcm9zc0RvbWFpbiApIHtcblx0XHRzLnR5cGUgPSBcIkdFVFwiO1xuXHR9XG59KTtcblxuLy8gQmluZCBzY3JpcHQgdGFnIGhhY2sgdHJhbnNwb3J0XG5qUXVlcnkuYWpheFRyYW5zcG9ydCggXCJzY3JpcHRcIiwgZnVuY3Rpb24oIHMgKSB7XG5cdC8vIFRoaXMgdHJhbnNwb3J0IG9ubHkgZGVhbHMgd2l0aCBjcm9zcyBkb21haW4gcmVxdWVzdHNcblx0aWYgKCBzLmNyb3NzRG9tYWluICkge1xuXHRcdHZhciBzY3JpcHQsIGNhbGxiYWNrO1xuXHRcdHJldHVybiB7XG5cdFx0XHRzZW5kOiBmdW5jdGlvbiggXywgY29tcGxldGUgKSB7XG5cdFx0XHRcdHNjcmlwdCA9IGpRdWVyeShcIjxzY3JpcHQ+XCIpLnByb3Aoe1xuXHRcdFx0XHRcdGFzeW5jOiB0cnVlLFxuXHRcdFx0XHRcdGNoYXJzZXQ6IHMuc2NyaXB0Q2hhcnNldCxcblx0XHRcdFx0XHRzcmM6IHMudXJsXG5cdFx0XHRcdH0pLm9uKFxuXHRcdFx0XHRcdFwibG9hZCBlcnJvclwiLFxuXHRcdFx0XHRcdGNhbGxiYWNrID0gZnVuY3Rpb24oIGV2dCApIHtcblx0XHRcdFx0XHRcdHNjcmlwdC5yZW1vdmUoKTtcblx0XHRcdFx0XHRcdGNhbGxiYWNrID0gbnVsbDtcblx0XHRcdFx0XHRcdGlmICggZXZ0ICkge1xuXHRcdFx0XHRcdFx0XHRjb21wbGV0ZSggZXZ0LnR5cGUgPT09IFwiZXJyb3JcIiA/IDQwNCA6IDIwMCwgZXZ0LnR5cGUgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdCk7XG5cdFx0XHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoIHNjcmlwdFsgMCBdICk7XG5cdFx0XHR9LFxuXHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9XG59KTtcblxuXG5cblxudmFyIG9sZENhbGxiYWNrcyA9IFtdLFxuXHRyanNvbnAgPSAvKD0pXFw/KD89JnwkKXxcXD9cXD8vO1xuXG4vLyBEZWZhdWx0IGpzb25wIHNldHRpbmdzXG5qUXVlcnkuYWpheFNldHVwKHtcblx0anNvbnA6IFwiY2FsbGJhY2tcIixcblx0anNvbnBDYWxsYmFjazogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGNhbGxiYWNrID0gb2xkQ2FsbGJhY2tzLnBvcCgpIHx8ICggalF1ZXJ5LmV4cGFuZG8gKyBcIl9cIiArICggbm9uY2UrKyApICk7XG5cdFx0dGhpc1sgY2FsbGJhY2sgXSA9IHRydWU7XG5cdFx0cmV0dXJuIGNhbGxiYWNrO1xuXHR9XG59KTtcblxuLy8gRGV0ZWN0LCBub3JtYWxpemUgb3B0aW9ucyBhbmQgaW5zdGFsbCBjYWxsYmFja3MgZm9yIGpzb25wIHJlcXVlc3RzXG5qUXVlcnkuYWpheFByZWZpbHRlciggXCJqc29uIGpzb25wXCIsIGZ1bmN0aW9uKCBzLCBvcmlnaW5hbFNldHRpbmdzLCBqcVhIUiApIHtcblxuXHR2YXIgY2FsbGJhY2tOYW1lLCBvdmVyd3JpdHRlbiwgcmVzcG9uc2VDb250YWluZXIsXG5cdFx0anNvblByb3AgPSBzLmpzb25wICE9PSBmYWxzZSAmJiAoIHJqc29ucC50ZXN0KCBzLnVybCApID9cblx0XHRcdFwidXJsXCIgOlxuXHRcdFx0dHlwZW9mIHMuZGF0YSA9PT0gXCJzdHJpbmdcIiAmJiAhKCBzLmNvbnRlbnRUeXBlIHx8IFwiXCIgKS5pbmRleE9mKFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXCIpICYmIHJqc29ucC50ZXN0KCBzLmRhdGEgKSAmJiBcImRhdGFcIlxuXHRcdCk7XG5cblx0Ly8gSGFuZGxlIGlmZiB0aGUgZXhwZWN0ZWQgZGF0YSB0eXBlIGlzIFwianNvbnBcIiBvciB3ZSBoYXZlIGEgcGFyYW1ldGVyIHRvIHNldFxuXHRpZiAoIGpzb25Qcm9wIHx8IHMuZGF0YVR5cGVzWyAwIF0gPT09IFwianNvbnBcIiApIHtcblxuXHRcdC8vIEdldCBjYWxsYmFjayBuYW1lLCByZW1lbWJlcmluZyBwcmVleGlzdGluZyB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggaXRcblx0XHRjYWxsYmFja05hbWUgPSBzLmpzb25wQ2FsbGJhY2sgPSBqUXVlcnkuaXNGdW5jdGlvbiggcy5qc29ucENhbGxiYWNrICkgP1xuXHRcdFx0cy5qc29ucENhbGxiYWNrKCkgOlxuXHRcdFx0cy5qc29ucENhbGxiYWNrO1xuXG5cdFx0Ly8gSW5zZXJ0IGNhbGxiYWNrIGludG8gdXJsIG9yIGZvcm0gZGF0YVxuXHRcdGlmICgganNvblByb3AgKSB7XG5cdFx0XHRzWyBqc29uUHJvcCBdID0gc1sganNvblByb3AgXS5yZXBsYWNlKCByanNvbnAsIFwiJDFcIiArIGNhbGxiYWNrTmFtZSApO1xuXHRcdH0gZWxzZSBpZiAoIHMuanNvbnAgIT09IGZhbHNlICkge1xuXHRcdFx0cy51cmwgKz0gKCBycXVlcnkudGVzdCggcy51cmwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuanNvbnAgKyBcIj1cIiArIGNhbGxiYWNrTmFtZTtcblx0XHR9XG5cblx0XHQvLyBVc2UgZGF0YSBjb252ZXJ0ZXIgdG8gcmV0cmlldmUganNvbiBhZnRlciBzY3JpcHQgZXhlY3V0aW9uXG5cdFx0cy5jb252ZXJ0ZXJzW1wic2NyaXB0IGpzb25cIl0gPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggIXJlc3BvbnNlQ29udGFpbmVyICkge1xuXHRcdFx0XHRqUXVlcnkuZXJyb3IoIGNhbGxiYWNrTmFtZSArIFwiIHdhcyBub3QgY2FsbGVkXCIgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXNwb25zZUNvbnRhaW5lclsgMCBdO1xuXHRcdH07XG5cblx0XHQvLyBmb3JjZSBqc29uIGRhdGFUeXBlXG5cdFx0cy5kYXRhVHlwZXNbIDAgXSA9IFwianNvblwiO1xuXG5cdFx0Ly8gSW5zdGFsbCBjYWxsYmFja1xuXHRcdG92ZXJ3cml0dGVuID0gd2luZG93WyBjYWxsYmFja05hbWUgXTtcblx0XHR3aW5kb3dbIGNhbGxiYWNrTmFtZSBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXNwb25zZUNvbnRhaW5lciA9IGFyZ3VtZW50cztcblx0XHR9O1xuXG5cdFx0Ly8gQ2xlYW4tdXAgZnVuY3Rpb24gKGZpcmVzIGFmdGVyIGNvbnZlcnRlcnMpXG5cdFx0anFYSFIuYWx3YXlzKGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8gUmVzdG9yZSBwcmVleGlzdGluZyB2YWx1ZVxuXHRcdFx0d2luZG93WyBjYWxsYmFja05hbWUgXSA9IG92ZXJ3cml0dGVuO1xuXG5cdFx0XHQvLyBTYXZlIGJhY2sgYXMgZnJlZVxuXHRcdFx0aWYgKCBzWyBjYWxsYmFja05hbWUgXSApIHtcblx0XHRcdFx0Ly8gbWFrZSBzdXJlIHRoYXQgcmUtdXNpbmcgdGhlIG9wdGlvbnMgZG9lc24ndCBzY3JldyB0aGluZ3MgYXJvdW5kXG5cdFx0XHRcdHMuanNvbnBDYWxsYmFjayA9IG9yaWdpbmFsU2V0dGluZ3MuanNvbnBDYWxsYmFjaztcblxuXHRcdFx0XHQvLyBzYXZlIHRoZSBjYWxsYmFjayBuYW1lIGZvciBmdXR1cmUgdXNlXG5cdFx0XHRcdG9sZENhbGxiYWNrcy5wdXNoKCBjYWxsYmFja05hbWUgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2FsbCBpZiBpdCB3YXMgYSBmdW5jdGlvbiBhbmQgd2UgaGF2ZSBhIHJlc3BvbnNlXG5cdFx0XHRpZiAoIHJlc3BvbnNlQ29udGFpbmVyICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCBvdmVyd3JpdHRlbiApICkge1xuXHRcdFx0XHRvdmVyd3JpdHRlbiggcmVzcG9uc2VDb250YWluZXJbIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXNwb25zZUNvbnRhaW5lciA9IG92ZXJ3cml0dGVuID0gdW5kZWZpbmVkO1xuXHRcdH0pO1xuXG5cdFx0Ly8gRGVsZWdhdGUgdG8gc2NyaXB0XG5cdFx0cmV0dXJuIFwic2NyaXB0XCI7XG5cdH1cbn0pO1xuXG5cblxuXG4vLyBkYXRhOiBzdHJpbmcgb2YgaHRtbFxuLy8gY29udGV4dCAob3B0aW9uYWwpOiBJZiBzcGVjaWZpZWQsIHRoZSBmcmFnbWVudCB3aWxsIGJlIGNyZWF0ZWQgaW4gdGhpcyBjb250ZXh0LCBkZWZhdWx0cyB0byBkb2N1bWVudFxuLy8ga2VlcFNjcmlwdHMgKG9wdGlvbmFsKTogSWYgdHJ1ZSwgd2lsbCBpbmNsdWRlIHNjcmlwdHMgcGFzc2VkIGluIHRoZSBodG1sIHN0cmluZ1xualF1ZXJ5LnBhcnNlSFRNTCA9IGZ1bmN0aW9uKCBkYXRhLCBjb250ZXh0LCBrZWVwU2NyaXB0cyApIHtcblx0aWYgKCAhZGF0YSB8fCB0eXBlb2YgZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXHRpZiAoIHR5cGVvZiBjb250ZXh0ID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRrZWVwU2NyaXB0cyA9IGNvbnRleHQ7XG5cdFx0Y29udGV4dCA9IGZhbHNlO1xuXHR9XG5cdGNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50O1xuXG5cdHZhciBwYXJzZWQgPSByc2luZ2xlVGFnLmV4ZWMoIGRhdGEgKSxcblx0XHRzY3JpcHRzID0gIWtlZXBTY3JpcHRzICYmIFtdO1xuXG5cdC8vIFNpbmdsZSB0YWdcblx0aWYgKCBwYXJzZWQgKSB7XG5cdFx0cmV0dXJuIFsgY29udGV4dC5jcmVhdGVFbGVtZW50KCBwYXJzZWRbMV0gKSBdO1xuXHR9XG5cblx0cGFyc2VkID0galF1ZXJ5LmJ1aWxkRnJhZ21lbnQoIFsgZGF0YSBdLCBjb250ZXh0LCBzY3JpcHRzICk7XG5cblx0aWYgKCBzY3JpcHRzICYmIHNjcmlwdHMubGVuZ3RoICkge1xuXHRcdGpRdWVyeSggc2NyaXB0cyApLnJlbW92ZSgpO1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeS5tZXJnZSggW10sIHBhcnNlZC5jaGlsZE5vZGVzICk7XG59O1xuXG5cbi8vIEtlZXAgYSBjb3B5IG9mIHRoZSBvbGQgbG9hZCBtZXRob2RcbnZhciBfbG9hZCA9IGpRdWVyeS5mbi5sb2FkO1xuXG4vKipcbiAqIExvYWQgYSB1cmwgaW50byBhIHBhZ2VcbiAqL1xualF1ZXJ5LmZuLmxvYWQgPSBmdW5jdGlvbiggdXJsLCBwYXJhbXMsIGNhbGxiYWNrICkge1xuXHRpZiAoIHR5cGVvZiB1cmwgIT09IFwic3RyaW5nXCIgJiYgX2xvYWQgKSB7XG5cdFx0cmV0dXJuIF9sb2FkLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0fVxuXG5cdHZhciBzZWxlY3RvciwgdHlwZSwgcmVzcG9uc2UsXG5cdFx0c2VsZiA9IHRoaXMsXG5cdFx0b2ZmID0gdXJsLmluZGV4T2YoXCIgXCIpO1xuXG5cdGlmICggb2ZmID49IDAgKSB7XG5cdFx0c2VsZWN0b3IgPSBqUXVlcnkudHJpbSggdXJsLnNsaWNlKCBvZmYgKSApO1xuXHRcdHVybCA9IHVybC5zbGljZSggMCwgb2ZmICk7XG5cdH1cblxuXHQvLyBJZiBpdCdzIGEgZnVuY3Rpb25cblx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggcGFyYW1zICkgKSB7XG5cblx0XHQvLyBXZSBhc3N1bWUgdGhhdCBpdCdzIHRoZSBjYWxsYmFja1xuXHRcdGNhbGxiYWNrID0gcGFyYW1zO1xuXHRcdHBhcmFtcyA9IHVuZGVmaW5lZDtcblxuXHQvLyBPdGhlcndpc2UsIGJ1aWxkIGEgcGFyYW0gc3RyaW5nXG5cdH0gZWxzZSBpZiAoIHBhcmFtcyAmJiB0eXBlb2YgcGFyYW1zID09PSBcIm9iamVjdFwiICkge1xuXHRcdHR5cGUgPSBcIlBPU1RcIjtcblx0fVxuXG5cdC8vIElmIHdlIGhhdmUgZWxlbWVudHMgdG8gbW9kaWZ5LCBtYWtlIHRoZSByZXF1ZXN0XG5cdGlmICggc2VsZi5sZW5ndGggPiAwICkge1xuXHRcdGpRdWVyeS5hamF4KHtcblx0XHRcdHVybDogdXJsLFxuXG5cdFx0XHQvLyBpZiBcInR5cGVcIiB2YXJpYWJsZSBpcyB1bmRlZmluZWQsIHRoZW4gXCJHRVRcIiBtZXRob2Qgd2lsbCBiZSB1c2VkXG5cdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0ZGF0YVR5cGU6IFwiaHRtbFwiLFxuXHRcdFx0ZGF0YTogcGFyYW1zXG5cdFx0fSkuZG9uZShmdW5jdGlvbiggcmVzcG9uc2VUZXh0ICkge1xuXG5cdFx0XHQvLyBTYXZlIHJlc3BvbnNlIGZvciB1c2UgaW4gY29tcGxldGUgY2FsbGJhY2tcblx0XHRcdHJlc3BvbnNlID0gYXJndW1lbnRzO1xuXG5cdFx0XHRzZWxmLmh0bWwoIHNlbGVjdG9yID9cblxuXHRcdFx0XHQvLyBJZiBhIHNlbGVjdG9yIHdhcyBzcGVjaWZpZWQsIGxvY2F0ZSB0aGUgcmlnaHQgZWxlbWVudHMgaW4gYSBkdW1teSBkaXZcblx0XHRcdFx0Ly8gRXhjbHVkZSBzY3JpcHRzIHRvIGF2b2lkIElFICdQZXJtaXNzaW9uIERlbmllZCcgZXJyb3JzXG5cdFx0XHRcdGpRdWVyeShcIjxkaXY+XCIpLmFwcGVuZCggalF1ZXJ5LnBhcnNlSFRNTCggcmVzcG9uc2VUZXh0ICkgKS5maW5kKCBzZWxlY3RvciApIDpcblxuXHRcdFx0XHQvLyBPdGhlcndpc2UgdXNlIHRoZSBmdWxsIHJlc3VsdFxuXHRcdFx0XHRyZXNwb25zZVRleHQgKTtcblxuXHRcdH0pLmNvbXBsZXRlKCBjYWxsYmFjayAmJiBmdW5jdGlvbigganFYSFIsIHN0YXR1cyApIHtcblx0XHRcdHNlbGYuZWFjaCggY2FsbGJhY2ssIHJlc3BvbnNlIHx8IFsganFYSFIucmVzcG9uc2VUZXh0LCBzdGF0dXMsIGpxWEhSIF0gKTtcblx0XHR9KTtcblx0fVxuXG5cdHJldHVybiB0aGlzO1xufTtcblxuXG5cblxualF1ZXJ5LmV4cHIuZmlsdGVycy5hbmltYXRlZCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRyZXR1cm4galF1ZXJ5LmdyZXAoalF1ZXJ5LnRpbWVycywgZnVuY3Rpb24oIGZuICkge1xuXHRcdHJldHVybiBlbGVtID09PSBmbi5lbGVtO1xuXHR9KS5sZW5ndGg7XG59O1xuXG5cblxuXG52YXIgZG9jRWxlbSA9IHdpbmRvdy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cbi8qKlxuICogR2V0cyBhIHdpbmRvdyBmcm9tIGFuIGVsZW1lbnRcbiAqL1xuZnVuY3Rpb24gZ2V0V2luZG93KCBlbGVtICkge1xuXHRyZXR1cm4galF1ZXJ5LmlzV2luZG93KCBlbGVtICkgPyBlbGVtIDogZWxlbS5ub2RlVHlwZSA9PT0gOSAmJiBlbGVtLmRlZmF1bHRWaWV3O1xufVxuXG5qUXVlcnkub2Zmc2V0ID0ge1xuXHRzZXRPZmZzZXQ6IGZ1bmN0aW9uKCBlbGVtLCBvcHRpb25zLCBpICkge1xuXHRcdHZhciBjdXJQb3NpdGlvbiwgY3VyTGVmdCwgY3VyQ1NTVG9wLCBjdXJUb3AsIGN1ck9mZnNldCwgY3VyQ1NTTGVmdCwgY2FsY3VsYXRlUG9zaXRpb24sXG5cdFx0XHRwb3NpdGlvbiA9IGpRdWVyeS5jc3MoIGVsZW0sIFwicG9zaXRpb25cIiApLFxuXHRcdFx0Y3VyRWxlbSA9IGpRdWVyeSggZWxlbSApLFxuXHRcdFx0cHJvcHMgPSB7fTtcblxuXHRcdC8vIFNldCBwb3NpdGlvbiBmaXJzdCwgaW4tY2FzZSB0b3AvbGVmdCBhcmUgc2V0IGV2ZW4gb24gc3RhdGljIGVsZW1cblx0XHRpZiAoIHBvc2l0aW9uID09PSBcInN0YXRpY1wiICkge1xuXHRcdFx0ZWxlbS5zdHlsZS5wb3NpdGlvbiA9IFwicmVsYXRpdmVcIjtcblx0XHR9XG5cblx0XHRjdXJPZmZzZXQgPSBjdXJFbGVtLm9mZnNldCgpO1xuXHRcdGN1ckNTU1RvcCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwidG9wXCIgKTtcblx0XHRjdXJDU1NMZWZ0ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJsZWZ0XCIgKTtcblx0XHRjYWxjdWxhdGVQb3NpdGlvbiA9ICggcG9zaXRpb24gPT09IFwiYWJzb2x1dGVcIiB8fCBwb3NpdGlvbiA9PT0gXCJmaXhlZFwiICkgJiZcblx0XHRcdCggY3VyQ1NTVG9wICsgY3VyQ1NTTGVmdCApLmluZGV4T2YoXCJhdXRvXCIpID4gLTE7XG5cblx0XHQvLyBOZWVkIHRvIGJlIGFibGUgdG8gY2FsY3VsYXRlIHBvc2l0aW9uIGlmIGVpdGhlciB0b3Agb3IgbGVmdCBpcyBhdXRvIGFuZCBwb3NpdGlvbiBpcyBlaXRoZXIgYWJzb2x1dGUgb3IgZml4ZWRcblx0XHRpZiAoIGNhbGN1bGF0ZVBvc2l0aW9uICkge1xuXHRcdFx0Y3VyUG9zaXRpb24gPSBjdXJFbGVtLnBvc2l0aW9uKCk7XG5cdFx0XHRjdXJUb3AgPSBjdXJQb3NpdGlvbi50b3A7XG5cdFx0XHRjdXJMZWZ0ID0gY3VyUG9zaXRpb24ubGVmdDtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjdXJUb3AgPSBwYXJzZUZsb2F0KCBjdXJDU1NUb3AgKSB8fCAwO1xuXHRcdFx0Y3VyTGVmdCA9IHBhcnNlRmxvYXQoIGN1ckNTU0xlZnQgKSB8fCAwO1xuXHRcdH1cblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIG9wdGlvbnMgKSApIHtcblx0XHRcdG9wdGlvbnMgPSBvcHRpb25zLmNhbGwoIGVsZW0sIGksIGN1ck9mZnNldCApO1xuXHRcdH1cblxuXHRcdGlmICggb3B0aW9ucy50b3AgIT0gbnVsbCApIHtcblx0XHRcdHByb3BzLnRvcCA9ICggb3B0aW9ucy50b3AgLSBjdXJPZmZzZXQudG9wICkgKyBjdXJUb3A7XG5cdFx0fVxuXHRcdGlmICggb3B0aW9ucy5sZWZ0ICE9IG51bGwgKSB7XG5cdFx0XHRwcm9wcy5sZWZ0ID0gKCBvcHRpb25zLmxlZnQgLSBjdXJPZmZzZXQubGVmdCApICsgY3VyTGVmdDtcblx0XHR9XG5cblx0XHRpZiAoIFwidXNpbmdcIiBpbiBvcHRpb25zICkge1xuXHRcdFx0b3B0aW9ucy51c2luZy5jYWxsKCBlbGVtLCBwcm9wcyApO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdGN1ckVsZW0uY3NzKCBwcm9wcyApO1xuXHRcdH1cblx0fVxufTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdG9mZnNldDogZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoICkge1xuXHRcdFx0cmV0dXJuIG9wdGlvbnMgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdHRoaXMgOlxuXHRcdFx0XHR0aGlzLmVhY2goZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5Lm9mZnNldC5zZXRPZmZzZXQoIHRoaXMsIG9wdGlvbnMsIGkgKTtcblx0XHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0dmFyIGRvY0VsZW0sIHdpbixcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXG5cdFx0XHRib3ggPSB7IHRvcDogMCwgbGVmdDogMCB9LFxuXHRcdFx0ZG9jID0gZWxlbSAmJiBlbGVtLm93bmVyRG9jdW1lbnQ7XG5cblx0XHRpZiAoICFkb2MgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0ZG9jRWxlbSA9IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG5cblx0XHQvLyBNYWtlIHN1cmUgaXQncyBub3QgYSBkaXNjb25uZWN0ZWQgRE9NIG5vZGVcblx0XHRpZiAoICFqUXVlcnkuY29udGFpbnMoIGRvY0VsZW0sIGVsZW0gKSApIHtcblx0XHRcdHJldHVybiBib3g7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgd2UgZG9uJ3QgaGF2ZSBnQkNSLCBqdXN0IHVzZSAwLDAgcmF0aGVyIHRoYW4gZXJyb3Jcblx0XHQvLyBCbGFja0JlcnJ5IDUsIGlPUyAzIChvcmlnaW5hbCBpUGhvbmUpXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QgIT09IHN0cnVuZGVmaW5lZCApIHtcblx0XHRcdGJveCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0fVxuXHRcdHdpbiA9IGdldFdpbmRvdyggZG9jICk7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHRvcDogYm94LnRvcCArIHdpbi5wYWdlWU9mZnNldCAtIGRvY0VsZW0uY2xpZW50VG9wLFxuXHRcdFx0bGVmdDogYm94LmxlZnQgKyB3aW4ucGFnZVhPZmZzZXQgLSBkb2NFbGVtLmNsaWVudExlZnRcblx0XHR9O1xuXHR9LFxuXG5cdHBvc2l0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRpZiAoICF0aGlzWyAwIF0gKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIG9mZnNldFBhcmVudCwgb2Zmc2V0LFxuXHRcdFx0ZWxlbSA9IHRoaXNbIDAgXSxcblx0XHRcdHBhcmVudE9mZnNldCA9IHsgdG9wOiAwLCBsZWZ0OiAwIH07XG5cblx0XHQvLyBGaXhlZCBlbGVtZW50cyBhcmUgb2Zmc2V0IGZyb20gd2luZG93IChwYXJlbnRPZmZzZXQgPSB7dG9wOjAsIGxlZnQ6IDB9LCBiZWNhdXNlIGl0IGlzIGl0cyBvbmx5IG9mZnNldCBwYXJlbnRcblx0XHRpZiAoIGpRdWVyeS5jc3MoIGVsZW0sIFwicG9zaXRpb25cIiApID09PSBcImZpeGVkXCIgKSB7XG5cdFx0XHQvLyBXZSBhc3N1bWUgdGhhdCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgaXMgYXZhaWxhYmxlIHdoZW4gY29tcHV0ZWQgcG9zaXRpb24gaXMgZml4ZWRcblx0XHRcdG9mZnNldCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gR2V0ICpyZWFsKiBvZmZzZXRQYXJlbnRcblx0XHRcdG9mZnNldFBhcmVudCA9IHRoaXMub2Zmc2V0UGFyZW50KCk7XG5cblx0XHRcdC8vIEdldCBjb3JyZWN0IG9mZnNldHNcblx0XHRcdG9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XG5cdFx0XHRpZiAoICFqUXVlcnkubm9kZU5hbWUoIG9mZnNldFBhcmVudFsgMCBdLCBcImh0bWxcIiApICkge1xuXHRcdFx0XHRwYXJlbnRPZmZzZXQgPSBvZmZzZXRQYXJlbnQub2Zmc2V0KCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBvZmZzZXRQYXJlbnQgYm9yZGVyc1xuXHRcdFx0cGFyZW50T2Zmc2V0LnRvcCArPSBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnRbIDAgXSwgXCJib3JkZXJUb3BXaWR0aFwiLCB0cnVlICk7XG5cdFx0XHRwYXJlbnRPZmZzZXQubGVmdCArPSBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnRbIDAgXSwgXCJib3JkZXJMZWZ0V2lkdGhcIiwgdHJ1ZSApO1xuXHRcdH1cblxuXHRcdC8vIFN1YnRyYWN0IHBhcmVudCBvZmZzZXRzIGFuZCBlbGVtZW50IG1hcmdpbnNcblx0XHRyZXR1cm4ge1xuXHRcdFx0dG9wOiBvZmZzZXQudG9wIC0gcGFyZW50T2Zmc2V0LnRvcCAtIGpRdWVyeS5jc3MoIGVsZW0sIFwibWFyZ2luVG9wXCIsIHRydWUgKSxcblx0XHRcdGxlZnQ6IG9mZnNldC5sZWZ0IC0gcGFyZW50T2Zmc2V0LmxlZnQgLSBqUXVlcnkuY3NzKCBlbGVtLCBcIm1hcmdpbkxlZnRcIiwgdHJ1ZSApXG5cdFx0fTtcblx0fSxcblxuXHRvZmZzZXRQYXJlbnQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLm1hcChmdW5jdGlvbigpIHtcblx0XHRcdHZhciBvZmZzZXRQYXJlbnQgPSB0aGlzLm9mZnNldFBhcmVudCB8fCBkb2NFbGVtO1xuXG5cdFx0XHR3aGlsZSAoIG9mZnNldFBhcmVudCAmJiAoICFqUXVlcnkubm9kZU5hbWUoIG9mZnNldFBhcmVudCwgXCJodG1sXCIgKSAmJiBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnQsIFwicG9zaXRpb25cIiApID09PSBcInN0YXRpY1wiICkgKSB7XG5cdFx0XHRcdG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudC5vZmZzZXRQYXJlbnQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBvZmZzZXRQYXJlbnQgfHwgZG9jRWxlbTtcblx0XHR9KTtcblx0fVxufSk7XG5cbi8vIENyZWF0ZSBzY3JvbGxMZWZ0IGFuZCBzY3JvbGxUb3AgbWV0aG9kc1xualF1ZXJ5LmVhY2goIHsgc2Nyb2xsTGVmdDogXCJwYWdlWE9mZnNldFwiLCBzY3JvbGxUb3A6IFwicGFnZVlPZmZzZXRcIiB9LCBmdW5jdGlvbiggbWV0aG9kLCBwcm9wICkge1xuXHR2YXIgdG9wID0gXCJwYWdlWU9mZnNldFwiID09PSBwcm9wO1xuXG5cdGpRdWVyeS5mblsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBtZXRob2QsIHZhbCApIHtcblx0XHRcdHZhciB3aW4gPSBnZXRXaW5kb3coIGVsZW0gKTtcblxuXHRcdFx0aWYgKCB2YWwgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHdpbiA/IHdpblsgcHJvcCBdIDogZWxlbVsgbWV0aG9kIF07XG5cdFx0XHR9XG5cblx0XHRcdGlmICggd2luICkge1xuXHRcdFx0XHR3aW4uc2Nyb2xsVG8oXG5cdFx0XHRcdFx0IXRvcCA/IHZhbCA6IHdpbmRvdy5wYWdlWE9mZnNldCxcblx0XHRcdFx0XHR0b3AgPyB2YWwgOiB3aW5kb3cucGFnZVlPZmZzZXRcblx0XHRcdFx0KTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbVsgbWV0aG9kIF0gPSB2YWw7XG5cdFx0XHR9XG5cdFx0fSwgbWV0aG9kLCB2YWwsIGFyZ3VtZW50cy5sZW5ndGgsIG51bGwgKTtcblx0fTtcbn0pO1xuXG4vLyBBZGQgdGhlIHRvcC9sZWZ0IGNzc0hvb2tzIHVzaW5nIGpRdWVyeS5mbi5wb3NpdGlvblxuLy8gV2Via2l0IGJ1ZzogaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTI5MDg0XG4vLyBnZXRDb21wdXRlZFN0eWxlIHJldHVybnMgcGVyY2VudCB3aGVuIHNwZWNpZmllZCBmb3IgdG9wL2xlZnQvYm90dG9tL3JpZ2h0XG4vLyByYXRoZXIgdGhhbiBtYWtlIHRoZSBjc3MgbW9kdWxlIGRlcGVuZCBvbiB0aGUgb2Zmc2V0IG1vZHVsZSwgd2UganVzdCBjaGVjayBmb3IgaXQgaGVyZVxualF1ZXJ5LmVhY2goIFsgXCJ0b3BcIiwgXCJsZWZ0XCIgXSwgZnVuY3Rpb24oIGksIHByb3AgKSB7XG5cdGpRdWVyeS5jc3NIb29rc1sgcHJvcCBdID0gYWRkR2V0SG9va0lmKCBzdXBwb3J0LnBpeGVsUG9zaXRpb24sXG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkge1xuXHRcdFx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRcdFx0Y29tcHV0ZWQgPSBjdXJDU1MoIGVsZW0sIHByb3AgKTtcblx0XHRcdFx0Ly8gaWYgY3VyQ1NTIHJldHVybnMgcGVyY2VudGFnZSwgZmFsbGJhY2sgdG8gb2Zmc2V0XG5cdFx0XHRcdHJldHVybiBybnVtbm9ucHgudGVzdCggY29tcHV0ZWQgKSA/XG5cdFx0XHRcdFx0alF1ZXJ5KCBlbGVtICkucG9zaXRpb24oKVsgcHJvcCBdICsgXCJweFwiIDpcblx0XHRcdFx0XHRjb21wdXRlZDtcblx0XHRcdH1cblx0XHR9XG5cdCk7XG59KTtcblxuXG4vLyBDcmVhdGUgaW5uZXJIZWlnaHQsIGlubmVyV2lkdGgsIGhlaWdodCwgd2lkdGgsIG91dGVySGVpZ2h0IGFuZCBvdXRlcldpZHRoIG1ldGhvZHNcbmpRdWVyeS5lYWNoKCB7IEhlaWdodDogXCJoZWlnaHRcIiwgV2lkdGg6IFwid2lkdGhcIiB9LCBmdW5jdGlvbiggbmFtZSwgdHlwZSApIHtcblx0alF1ZXJ5LmVhY2goIHsgcGFkZGluZzogXCJpbm5lclwiICsgbmFtZSwgY29udGVudDogdHlwZSwgXCJcIjogXCJvdXRlclwiICsgbmFtZSB9LCBmdW5jdGlvbiggZGVmYXVsdEV4dHJhLCBmdW5jTmFtZSApIHtcblx0XHQvLyBtYXJnaW4gaXMgb25seSBmb3Igb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGhcblx0XHRqUXVlcnkuZm5bIGZ1bmNOYW1lIF0gPSBmdW5jdGlvbiggbWFyZ2luLCB2YWx1ZSApIHtcblx0XHRcdHZhciBjaGFpbmFibGUgPSBhcmd1bWVudHMubGVuZ3RoICYmICggZGVmYXVsdEV4dHJhIHx8IHR5cGVvZiBtYXJnaW4gIT09IFwiYm9vbGVhblwiICksXG5cdFx0XHRcdGV4dHJhID0gZGVmYXVsdEV4dHJhIHx8ICggbWFyZ2luID09PSB0cnVlIHx8IHZhbHVlID09PSB0cnVlID8gXCJtYXJnaW5cIiA6IFwiYm9yZGVyXCIgKTtcblxuXHRcdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIHR5cGUsIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgZG9jO1xuXG5cdFx0XHRcdGlmICggalF1ZXJ5LmlzV2luZG93KCBlbGVtICkgKSB7XG5cdFx0XHRcdFx0Ly8gQXMgb2YgNS84LzIwMTIgdGhpcyB3aWxsIHlpZWxkIGluY29ycmVjdCByZXN1bHRzIGZvciBNb2JpbGUgU2FmYXJpLCBidXQgdGhlcmVcblx0XHRcdFx0XHQvLyBpc24ndCBhIHdob2xlIGxvdCB3ZSBjYW4gZG8uIFNlZSBwdWxsIHJlcXVlc3QgYXQgdGhpcyBVUkwgZm9yIGRpc2N1c3Npb246XG5cdFx0XHRcdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9qcXVlcnkvcHVsbC83NjRcblx0XHRcdFx0XHRyZXR1cm4gZWxlbS5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbIFwiY2xpZW50XCIgKyBuYW1lIF07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBHZXQgZG9jdW1lbnQgd2lkdGggb3IgaGVpZ2h0XG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0XHRkb2MgPSBlbGVtLmRvY3VtZW50RWxlbWVudDtcblxuXHRcdFx0XHRcdC8vIEVpdGhlciBzY3JvbGxbV2lkdGgvSGVpZ2h0XSBvciBvZmZzZXRbV2lkdGgvSGVpZ2h0XSBvciBjbGllbnRbV2lkdGgvSGVpZ2h0XSxcblx0XHRcdFx0XHQvLyB3aGljaGV2ZXIgaXMgZ3JlYXRlc3Rcblx0XHRcdFx0XHRyZXR1cm4gTWF0aC5tYXgoXG5cdFx0XHRcdFx0XHRlbGVtLmJvZHlbIFwic2Nyb2xsXCIgKyBuYW1lIF0sIGRvY1sgXCJzY3JvbGxcIiArIG5hbWUgXSxcblx0XHRcdFx0XHRcdGVsZW0uYm9keVsgXCJvZmZzZXRcIiArIG5hbWUgXSwgZG9jWyBcIm9mZnNldFwiICsgbmFtZSBdLFxuXHRcdFx0XHRcdFx0ZG9jWyBcImNsaWVudFwiICsgbmFtZSBdXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdFx0XHQvLyBHZXQgd2lkdGggb3IgaGVpZ2h0IG9uIHRoZSBlbGVtZW50LCByZXF1ZXN0aW5nIGJ1dCBub3QgZm9yY2luZyBwYXJzZUZsb2F0XG5cdFx0XHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgdHlwZSwgZXh0cmEgKSA6XG5cblx0XHRcdFx0XHQvLyBTZXQgd2lkdGggb3IgaGVpZ2h0IG9uIHRoZSBlbGVtZW50XG5cdFx0XHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCB0eXBlLCB2YWx1ZSwgZXh0cmEgKTtcblx0XHRcdH0sIHR5cGUsIGNoYWluYWJsZSA/IG1hcmdpbiA6IHVuZGVmaW5lZCwgY2hhaW5hYmxlLCBudWxsICk7XG5cdFx0fTtcblx0fSk7XG59KTtcblxuXG4vLyBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIGNvbnRhaW5lZCBpbiB0aGUgbWF0Y2hlZCBlbGVtZW50IHNldFxualF1ZXJ5LmZuLnNpemUgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIHRoaXMubGVuZ3RoO1xufTtcblxualF1ZXJ5LmZuLmFuZFNlbGYgPSBqUXVlcnkuZm4uYWRkQmFjaztcblxuXG5cblxuLy8gUmVnaXN0ZXIgYXMgYSBuYW1lZCBBTUQgbW9kdWxlLCBzaW5jZSBqUXVlcnkgY2FuIGJlIGNvbmNhdGVuYXRlZCB3aXRoIG90aGVyXG4vLyBmaWxlcyB0aGF0IG1heSB1c2UgZGVmaW5lLCBidXQgbm90IHZpYSBhIHByb3BlciBjb25jYXRlbmF0aW9uIHNjcmlwdCB0aGF0XG4vLyB1bmRlcnN0YW5kcyBhbm9ueW1vdXMgQU1EIG1vZHVsZXMuIEEgbmFtZWQgQU1EIGlzIHNhZmVzdCBhbmQgbW9zdCByb2J1c3Rcbi8vIHdheSB0byByZWdpc3Rlci4gTG93ZXJjYXNlIGpxdWVyeSBpcyB1c2VkIGJlY2F1c2UgQU1EIG1vZHVsZSBuYW1lcyBhcmVcbi8vIGRlcml2ZWQgZnJvbSBmaWxlIG5hbWVzLCBhbmQgalF1ZXJ5IGlzIG5vcm1hbGx5IGRlbGl2ZXJlZCBpbiBhIGxvd2VyY2FzZVxuLy8gZmlsZSBuYW1lLiBEbyB0aGlzIGFmdGVyIGNyZWF0aW5nIHRoZSBnbG9iYWwgc28gdGhhdCBpZiBhbiBBTUQgbW9kdWxlIHdhbnRzXG4vLyB0byBjYWxsIG5vQ29uZmxpY3QgdG8gaGlkZSB0aGlzIHZlcnNpb24gb2YgalF1ZXJ5LCBpdCB3aWxsIHdvcmsuXG5cbi8vIE5vdGUgdGhhdCBmb3IgbWF4aW11bSBwb3J0YWJpbGl0eSwgbGlicmFyaWVzIHRoYXQgYXJlIG5vdCBqUXVlcnkgc2hvdWxkXG4vLyBkZWNsYXJlIHRoZW1zZWx2ZXMgYXMgYW5vbnltb3VzIG1vZHVsZXMsIGFuZCBhdm9pZCBzZXR0aW5nIGEgZ2xvYmFsIGlmIGFuXG4vLyBBTUQgbG9hZGVyIGlzIHByZXNlbnQuIGpRdWVyeSBpcyBhIHNwZWNpYWwgY2FzZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZVxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2pyYnVya2UvcmVxdWlyZWpzL3dpa2kvVXBkYXRpbmctZXhpc3RpbmctbGlicmFyaWVzI3dpa2ktYW5vblxuXG5pZiAoIHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kICkge1xuXHRkZWZpbmUoIFwianF1ZXJ5XCIsIFtdLCBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4galF1ZXJ5O1xuXHR9KTtcbn1cblxuXG5cblxudmFyXG5cdC8vIE1hcCBvdmVyIGpRdWVyeSBpbiBjYXNlIG9mIG92ZXJ3cml0ZVxuXHRfalF1ZXJ5ID0gd2luZG93LmpRdWVyeSxcblxuXHQvLyBNYXAgb3ZlciB0aGUgJCBpbiBjYXNlIG9mIG92ZXJ3cml0ZVxuXHRfJCA9IHdpbmRvdy4kO1xuXG5qUXVlcnkubm9Db25mbGljdCA9IGZ1bmN0aW9uKCBkZWVwICkge1xuXHRpZiAoIHdpbmRvdy4kID09PSBqUXVlcnkgKSB7XG5cdFx0d2luZG93LiQgPSBfJDtcblx0fVxuXG5cdGlmICggZGVlcCAmJiB3aW5kb3cualF1ZXJ5ID09PSBqUXVlcnkgKSB7XG5cdFx0d2luZG93LmpRdWVyeSA9IF9qUXVlcnk7XG5cdH1cblxuXHRyZXR1cm4galF1ZXJ5O1xufTtcblxuLy8gRXhwb3NlIGpRdWVyeSBhbmQgJCBpZGVudGlmaWVycywgZXZlbiBpblxuLy8gQU1EICgjNzEwMiNjb21tZW50OjEwLCBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L2pxdWVyeS9wdWxsLzU1Nylcbi8vIGFuZCBDb21tb25KUyBmb3IgYnJvd3NlciBlbXVsYXRvcnMgKCMxMzU2NilcbmlmICggdHlwZW9mIG5vR2xvYmFsID09PSBzdHJ1bmRlZmluZWQgKSB7XG5cdHdpbmRvdy5qUXVlcnkgPSB3aW5kb3cuJCA9IGpRdWVyeTtcbn1cblxuXG5cblxucmV0dXJuIGpRdWVyeTtcblxufSkpO1xuIiwiKGZ1bmN0aW9uIChzaW5vbkNoYWkpIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIC8vIE1vZHVsZSBzeXN0ZW1zIG1hZ2ljIGRhbmNlLlxuXG4gICAgaWYgKHR5cGVvZiByZXF1aXJlID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAvLyBOb2RlSlNcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBzaW5vbkNoYWk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICAvLyBBTURcbiAgICAgICAgZGVmaW5lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBzaW5vbkNoYWk7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE90aGVyIGVudmlyb25tZW50ICh1c3VhbGx5IDxzY3JpcHQ+IHRhZyk6IHBsdWcgaW4gdG8gZ2xvYmFsIGNoYWkgaW5zdGFuY2UgZGlyZWN0bHkuXG4gICAgICAgIGNoYWkudXNlKHNpbm9uQ2hhaSk7XG4gICAgfVxufShmdW5jdGlvbiBzaW5vbkNoYWkoY2hhaSwgdXRpbHMpIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIHZhciBzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcblxuICAgIGZ1bmN0aW9uIGlzU3B5KHB1dGF0aXZlU3B5KSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgcHV0YXRpdmVTcHkgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAgICAgICAgdHlwZW9mIHB1dGF0aXZlU3B5LmdldENhbGwgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAgICAgICAgdHlwZW9mIHB1dGF0aXZlU3B5LmNhbGxlZFdpdGhFeGFjdGx5ID09PSBcImZ1bmN0aW9uXCI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdGltZXNJbldvcmRzKGNvdW50KSB7XG4gICAgICAgIHJldHVybiBjb3VudCA9PT0gMSA/IFwib25jZVwiIDpcbiAgICAgICAgICAgICAgIGNvdW50ID09PSAyID8gXCJ0d2ljZVwiIDpcbiAgICAgICAgICAgICAgIGNvdW50ID09PSAzID8gXCJ0aHJpY2VcIiA6XG4gICAgICAgICAgICAgICAoY291bnQgfHwgMCkgKyBcIiB0aW1lc1wiO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzQ2FsbChwdXRhdGl2ZUNhbGwpIHtcbiAgICAgICAgcmV0dXJuIHB1dGF0aXZlQ2FsbCAmJiBpc1NweShwdXRhdGl2ZUNhbGwucHJveHkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFzc2VydENhbldvcmtXaXRoKGFzc2VydGlvbikge1xuICAgICAgICBpZiAoIWlzU3B5KGFzc2VydGlvbi5fb2JqKSAmJiAhaXNDYWxsKGFzc2VydGlvbi5fb2JqKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcih1dGlscy5pbnNwZWN0KGFzc2VydGlvbi5fb2JqKSArIFwiIGlzIG5vdCBhIHNweSBvciBhIGNhbGwgdG8gYSBzcHkhXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0TWVzc2FnZXMoc3B5LCBhY3Rpb24sIG5vbk5lZ2F0ZWRTdWZmaXgsIGFsd2F5cywgYXJncykge1xuICAgICAgICB2YXIgdmVyYlBocmFzZSA9IGFsd2F5cyA/IFwiYWx3YXlzIGhhdmUgXCIgOiBcImhhdmUgXCI7XG4gICAgICAgIG5vbk5lZ2F0ZWRTdWZmaXggPSBub25OZWdhdGVkU3VmZml4IHx8IFwiXCI7XG4gICAgICAgIGlmIChpc1NweShzcHkucHJveHkpKSB7XG4gICAgICAgICAgICBzcHkgPSBzcHkucHJveHk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBwcmludGZBcnJheShhcnJheSkge1xuICAgICAgICAgICAgcmV0dXJuIHNweS5wcmludGYuYXBwbHkoc3B5LCBhcnJheSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYWZmaXJtYXRpdmU6IHByaW50ZkFycmF5KFtcImV4cGVjdGVkICVuIHRvIFwiICsgdmVyYlBocmFzZSArIGFjdGlvbiArIG5vbk5lZ2F0ZWRTdWZmaXhdLmNvbmNhdChhcmdzKSksXG4gICAgICAgICAgICBuZWdhdGl2ZTogcHJpbnRmQXJyYXkoW1wiZXhwZWN0ZWQgJW4gdG8gbm90IFwiICsgdmVyYlBocmFzZSArIGFjdGlvbl0uY29uY2F0KGFyZ3MpKVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNpbm9uUHJvcGVydHkobmFtZSwgYWN0aW9uLCBub25OZWdhdGVkU3VmZml4KSB7XG4gICAgICAgIHV0aWxzLmFkZFByb3BlcnR5KGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgbmFtZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgYXNzZXJ0Q2FuV29ya1dpdGgodGhpcyk7XG5cbiAgICAgICAgICAgIHZhciBtZXNzYWdlcyA9IGdldE1lc3NhZ2VzKHRoaXMuX29iaiwgYWN0aW9uLCBub25OZWdhdGVkU3VmZml4LCBmYWxzZSk7XG4gICAgICAgICAgICB0aGlzLmFzc2VydCh0aGlzLl9vYmpbbmFtZV0sIG1lc3NhZ2VzLmFmZmlybWF0aXZlLCBtZXNzYWdlcy5uZWdhdGl2ZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNpbm9uUHJvcGVydHlBc0Jvb2xlYW5NZXRob2QobmFtZSwgYWN0aW9uLCBub25OZWdhdGVkU3VmZml4KSB7XG4gICAgICAgIHV0aWxzLmFkZE1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsIG5hbWUsIGZ1bmN0aW9uIChhcmcpIHtcbiAgICAgICAgICAgIGFzc2VydENhbldvcmtXaXRoKHRoaXMpO1xuXG4gICAgICAgICAgICB2YXIgbWVzc2FnZXMgPSBnZXRNZXNzYWdlcyh0aGlzLl9vYmosIGFjdGlvbiwgbm9uTmVnYXRlZFN1ZmZpeCwgZmFsc2UsIFt0aW1lc0luV29yZHMoYXJnKV0pO1xuICAgICAgICAgICAgdGhpcy5hc3NlcnQodGhpcy5fb2JqW25hbWVdID09PSBhcmcsIG1lc3NhZ2VzLmFmZmlybWF0aXZlLCBtZXNzYWdlcy5uZWdhdGl2ZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZVNpbm9uTWV0aG9kSGFuZGxlcihzaW5vbk5hbWUsIGFjdGlvbiwgbm9uTmVnYXRlZFN1ZmZpeCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgYXNzZXJ0Q2FuV29ya1dpdGgodGhpcyk7XG5cbiAgICAgICAgICAgIHZhciBhbHdheXNTaW5vbk1ldGhvZCA9IFwiYWx3YXlzXCIgKyBzaW5vbk5hbWVbMF0udG9VcHBlckNhc2UoKSArIHNpbm9uTmFtZS5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgICB2YXIgc2hvdWxkQmVBbHdheXMgPSB1dGlscy5mbGFnKHRoaXMsIFwiYWx3YXlzXCIpICYmIHR5cGVvZiB0aGlzLl9vYmpbYWx3YXlzU2lub25NZXRob2RdID09PSBcImZ1bmN0aW9uXCI7XG4gICAgICAgICAgICB2YXIgc2lub25NZXRob2QgPSBzaG91bGRCZUFsd2F5cyA/IGFsd2F5c1Npbm9uTWV0aG9kIDogc2lub25OYW1lO1xuXG4gICAgICAgICAgICB2YXIgbWVzc2FnZXMgPSBnZXRNZXNzYWdlcyh0aGlzLl9vYmosIGFjdGlvbiwgbm9uTmVnYXRlZFN1ZmZpeCwgc2hvdWxkQmVBbHdheXMsIHNsaWNlLmNhbGwoYXJndW1lbnRzKSk7XG4gICAgICAgICAgICB0aGlzLmFzc2VydCh0aGlzLl9vYmpbc2lub25NZXRob2RdLmFwcGx5KHRoaXMuX29iaiwgYXJndW1lbnRzKSwgbWVzc2FnZXMuYWZmaXJtYXRpdmUsIG1lc3NhZ2VzLm5lZ2F0aXZlKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzaW5vbk1ldGhvZEFzUHJvcGVydHkobmFtZSwgYWN0aW9uLCBub25OZWdhdGVkU3VmZml4KSB7XG4gICAgICAgIHZhciBoYW5kbGVyID0gY3JlYXRlU2lub25NZXRob2RIYW5kbGVyKG5hbWUsIGFjdGlvbiwgbm9uTmVnYXRlZFN1ZmZpeCk7XG4gICAgICAgIHV0aWxzLmFkZFByb3BlcnR5KGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgbmFtZSwgaGFuZGxlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXhjZXB0aW9uYWxTaW5vbk1ldGhvZChjaGFpTmFtZSwgc2lub25OYW1lLCBhY3Rpb24sIG5vbk5lZ2F0ZWRTdWZmaXgpIHtcbiAgICAgICAgdmFyIGhhbmRsZXIgPSBjcmVhdGVTaW5vbk1ldGhvZEhhbmRsZXIoc2lub25OYW1lLCBhY3Rpb24sIG5vbk5lZ2F0ZWRTdWZmaXgpO1xuICAgICAgICB1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBjaGFpTmFtZSwgaGFuZGxlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2lub25NZXRob2QobmFtZSwgYWN0aW9uLCBub25OZWdhdGVkU3VmZml4KSB7XG4gICAgICAgIGV4Y2VwdGlvbmFsU2lub25NZXRob2QobmFtZSwgbmFtZSwgYWN0aW9uLCBub25OZWdhdGVkU3VmZml4KTtcbiAgICB9XG5cbiAgICB1dGlscy5hZGRQcm9wZXJ0eShjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsIFwiYWx3YXlzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdXRpbHMuZmxhZyh0aGlzLCBcImFsd2F5c1wiLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIHNpbm9uUHJvcGVydHkoXCJjYWxsZWRcIiwgXCJiZWVuIGNhbGxlZFwiLCBcIiBhdCBsZWFzdCBvbmNlLCBidXQgaXQgd2FzIG5ldmVyIGNhbGxlZFwiKTtcbiAgICBzaW5vblByb3BlcnR5QXNCb29sZWFuTWV0aG9kKFwiY2FsbENvdW50XCIsIFwiYmVlbiBjYWxsZWQgZXhhY3RseSAlMVwiLCBcIiwgYnV0IGl0IHdhcyBjYWxsZWQgJWMlQ1wiKTtcbiAgICBzaW5vblByb3BlcnR5KFwiY2FsbGVkT25jZVwiLCBcImJlZW4gY2FsbGVkIGV4YWN0bHkgb25jZVwiLCBcIiwgYnV0IGl0IHdhcyBjYWxsZWQgJWMlQ1wiKTtcbiAgICBzaW5vblByb3BlcnR5KFwiY2FsbGVkVHdpY2VcIiwgXCJiZWVuIGNhbGxlZCBleGFjdGx5IHR3aWNlXCIsIFwiLCBidXQgaXQgd2FzIGNhbGxlZCAlYyVDXCIpO1xuICAgIHNpbm9uUHJvcGVydHkoXCJjYWxsZWRUaHJpY2VcIiwgXCJiZWVuIGNhbGxlZCBleGFjdGx5IHRocmljZVwiLCBcIiwgYnV0IGl0IHdhcyBjYWxsZWQgJWMlQ1wiKTtcbiAgICBzaW5vbk1ldGhvZEFzUHJvcGVydHkoXCJjYWxsZWRXaXRoTmV3XCIsIFwiYmVlbiBjYWxsZWQgd2l0aCBuZXdcIik7XG4gICAgc2lub25NZXRob2QoXCJjYWxsZWRCZWZvcmVcIiwgXCJiZWVuIGNhbGxlZCBiZWZvcmUgJTFcIik7XG4gICAgc2lub25NZXRob2QoXCJjYWxsZWRBZnRlclwiLCBcImJlZW4gY2FsbGVkIGFmdGVyICUxXCIpO1xuICAgIHNpbm9uTWV0aG9kKFwiY2FsbGVkT25cIiwgXCJiZWVuIGNhbGxlZCB3aXRoICUxIGFzIHRoaXNcIiwgXCIsIGJ1dCBpdCB3YXMgY2FsbGVkIHdpdGggJXQgaW5zdGVhZFwiKTtcbiAgICBzaW5vbk1ldGhvZChcImNhbGxlZFdpdGhcIiwgXCJiZWVuIGNhbGxlZCB3aXRoIGFyZ3VtZW50cyAlKlwiLCBcIiVDXCIpO1xuICAgIHNpbm9uTWV0aG9kKFwiY2FsbGVkV2l0aEV4YWN0bHlcIiwgXCJiZWVuIGNhbGxlZCB3aXRoIGV4YWN0IGFyZ3VtZW50cyAlKlwiLCBcIiVDXCIpO1xuICAgIHNpbm9uTWV0aG9kKFwiY2FsbGVkV2l0aE1hdGNoXCIsIFwiYmVlbiBjYWxsZWQgd2l0aCBhcmd1bWVudHMgbWF0Y2hpbmcgJSpcIiwgXCIlQ1wiKTtcbiAgICBzaW5vbk1ldGhvZChcInJldHVybmVkXCIsIFwicmV0dXJuZWQgJTFcIik7XG4gICAgZXhjZXB0aW9uYWxTaW5vbk1ldGhvZChcInRocm93blwiLCBcInRocmV3XCIsIFwidGhyb3duICUxXCIpO1xufSkpO1xuIiwiLypqc2xpbnQgZXFlcWVxOiBmYWxzZSwgb25ldmFyOiBmYWxzZSwgZm9yaW46IHRydWUsIG5vbWVuOiBmYWxzZSwgcmVnZXhwOiBmYWxzZSwgcGx1c3BsdXM6IGZhbHNlKi9cbi8qZ2xvYmFsIG1vZHVsZSwgcmVxdWlyZSwgX19kaXJuYW1lLCBkb2N1bWVudCovXG4vKipcbiAqIFNpbm9uIGNvcmUgdXRpbGl0aWVzLiBGb3IgaW50ZXJuYWwgdXNlIG9ubHkuXG4gKlxuICogQGF1dGhvciBDaHJpc3RpYW4gSm9oYW5zZW4gKGNocmlzdGlhbkBjam9oYW5zZW4ubm8pXG4gKiBAbGljZW5zZSBCU0RcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMyBDaHJpc3RpYW4gSm9oYW5zZW5cbiAqL1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBzaW5vbiA9IChmdW5jdGlvbiAoZm9ybWF0aW8pIHtcbiAgICB2YXIgZGl2ID0gdHlwZW9mIGRvY3VtZW50ICE9IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICB2YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuICAgIGZ1bmN0aW9uIGlzRE9NTm9kZShvYmopIHtcbiAgICAgICAgdmFyIHN1Y2Nlc3MgPSBmYWxzZTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgb2JqLmFwcGVuZENoaWxkKGRpdik7XG4gICAgICAgICAgICBzdWNjZXNzID0gZGl2LnBhcmVudE5vZGUgPT0gb2JqO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG9iai5yZW1vdmVDaGlsZChkaXYpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBmYWlsZWQsIG5vdCBtdWNoIHdlIGNhbiBkbyBhYm91dCB0aGF0XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc3VjY2VzcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0VsZW1lbnQob2JqKSB7XG4gICAgICAgIHJldHVybiBkaXYgJiYgb2JqICYmIG9iai5ub2RlVHlwZSA9PT0gMSAmJiBpc0RPTU5vZGUob2JqKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0Z1bmN0aW9uKG9iaikge1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gXCJmdW5jdGlvblwiIHx8ICEhKG9iaiAmJiBvYmouY29uc3RydWN0b3IgJiYgb2JqLmNhbGwgJiYgb2JqLmFwcGx5KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1JlYWxseU5hTih2YWwpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdudW1iZXInICYmIGlzTmFOKHZhbCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWlycm9yUHJvcGVydGllcyh0YXJnZXQsIHNvdXJjZSkge1xuICAgICAgICBmb3IgKHZhciBwcm9wIGluIHNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKCFoYXNPd24uY2FsbCh0YXJnZXQsIHByb3ApKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W3Byb3BdID0gc291cmNlW3Byb3BdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNSZXN0b3JhYmxlIChvYmopIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2Ygb2JqLnJlc3RvcmUgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmoucmVzdG9yZS5zaW5vbjtcbiAgICB9XG5cbiAgICB2YXIgc2lub24gPSB7XG4gICAgICAgIHdyYXBNZXRob2Q6IGZ1bmN0aW9uIHdyYXBNZXRob2Qob2JqZWN0LCBwcm9wZXJ0eSwgbWV0aG9kKSB7XG4gICAgICAgICAgICBpZiAoIW9iamVjdCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTaG91bGQgd3JhcCBwcm9wZXJ0eSBvZiBvYmplY3RcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWV0aG9kICE9IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNZXRob2Qgd3JhcHBlciBzaG91bGQgYmUgZnVuY3Rpb25cIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB3cmFwcGVkTWV0aG9kID0gb2JqZWN0W3Byb3BlcnR5XSxcbiAgICAgICAgICAgICAgICBlcnJvcjtcblxuICAgICAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKHdyYXBwZWRNZXRob2QpKSB7XG4gICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgVHlwZUVycm9yKFwiQXR0ZW1wdGVkIHRvIHdyYXAgXCIgKyAodHlwZW9mIHdyYXBwZWRNZXRob2QpICsgXCIgcHJvcGVydHkgXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHkgKyBcIiBhcyBmdW5jdGlvblwiKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAod3JhcHBlZE1ldGhvZC5yZXN0b3JlICYmIHdyYXBwZWRNZXRob2QucmVzdG9yZS5zaW5vbikge1xuICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IFR5cGVFcnJvcihcIkF0dGVtcHRlZCB0byB3cmFwIFwiICsgcHJvcGVydHkgKyBcIiB3aGljaCBpcyBhbHJlYWR5IHdyYXBwZWRcIik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHdyYXBwZWRNZXRob2QuY2FsbGVkQmVmb3JlKSB7XG4gICAgICAgICAgICAgICAgdmFyIHZlcmIgPSAhIXdyYXBwZWRNZXRob2QucmV0dXJucyA/IFwic3R1YmJlZFwiIDogXCJzcGllZCBvblwiO1xuICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IFR5cGVFcnJvcihcIkF0dGVtcHRlZCB0byB3cmFwIFwiICsgcHJvcGVydHkgKyBcIiB3aGljaCBpcyBhbHJlYWR5IFwiICsgdmVyYik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGlmICh3cmFwcGVkTWV0aG9kICYmIHdyYXBwZWRNZXRob2QuX3N0YWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yLnN0YWNrICs9ICdcXG4tLS0tLS0tLS0tLS0tLVxcbicgKyB3cmFwcGVkTWV0aG9kLl9zdGFjaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElFIDggZG9lcyBub3Qgc3VwcG9ydCBoYXNPd25Qcm9wZXJ0eSBvbiB0aGUgd2luZG93IG9iamVjdCBhbmQgRmlyZWZveCBoYXMgYSBwcm9ibGVtXG4gICAgICAgICAgICAvLyB3aGVuIHVzaW5nIGhhc093bi5jYWxsIG9uIG9iamVjdHMgZnJvbSBvdGhlciBmcmFtZXMuXG4gICAgICAgICAgICB2YXIgb3duZWQgPSBvYmplY3QuaGFzT3duUHJvcGVydHkgPyBvYmplY3QuaGFzT3duUHJvcGVydHkocHJvcGVydHkpIDogaGFzT3duLmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7XG4gICAgICAgICAgICBvYmplY3RbcHJvcGVydHldID0gbWV0aG9kO1xuICAgICAgICAgICAgbWV0aG9kLmRpc3BsYXlOYW1lID0gcHJvcGVydHk7XG4gICAgICAgICAgICAvLyBTZXQgdXAgYSBzdGFjayB0cmFjZSB3aGljaCBjYW4gYmUgdXNlZCBsYXRlciB0byBmaW5kIHdoYXQgbGluZSBvZlxuICAgICAgICAgICAgLy8gY29kZSB0aGUgb3JpZ2luYWwgbWV0aG9kIHdhcyBjcmVhdGVkIG9uLlxuICAgICAgICAgICAgbWV0aG9kLl9zdGFjayA9IChuZXcgRXJyb3IoJ1N0YWNrIFRyYWNlIGZvciBvcmlnaW5hbCcpKS5zdGFjaztcblxuICAgICAgICAgICAgbWV0aG9kLnJlc3RvcmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgLy8gRm9yIHByb3RvdHlwZSBwcm9wZXJ0aWVzIHRyeSB0byByZXNldCBieSBkZWxldGUgZmlyc3QuXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBmYWlscyAoZXg6IGxvY2FsU3RvcmFnZSBvbiBtb2JpbGUgc2FmYXJpKSB0aGVuIGZvcmNlIGEgcmVzZXRcbiAgICAgICAgICAgICAgICAvLyB2aWEgZGlyZWN0IGFzc2lnbm1lbnQuXG4gICAgICAgICAgICAgICAgaWYgKCFvd25lZCkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgb2JqZWN0W3Byb3BlcnR5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdFtwcm9wZXJ0eV0gPT09IG1ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3RbcHJvcGVydHldID0gd3JhcHBlZE1ldGhvZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBtZXRob2QucmVzdG9yZS5zaW5vbiA9IHRydWU7XG4gICAgICAgICAgICBtaXJyb3JQcm9wZXJ0aWVzKG1ldGhvZCwgd3JhcHBlZE1ldGhvZCk7XG5cbiAgICAgICAgICAgIHJldHVybiBtZXRob2Q7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZXh0ZW5kOiBmdW5jdGlvbiBleHRlbmQodGFyZ2V0KSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMSwgbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBwcm9wIGluIGFyZ3VtZW50c1tpXSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzW2ldLmhhc093blByb3BlcnR5KHByb3ApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbcHJvcF0gPSBhcmd1bWVudHNbaV1bcHJvcF07XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBET05UIEVOVU0gYnVnLCBvbmx5IGNhcmUgYWJvdXQgdG9TdHJpbmdcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50c1tpXS5oYXNPd25Qcm9wZXJ0eShcInRvU3RyaW5nXCIpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHNbaV0udG9TdHJpbmcgIT0gdGFyZ2V0LnRvU3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQudG9TdHJpbmcgPSBhcmd1bWVudHNbaV0udG9TdHJpbmc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY3JlYXRlOiBmdW5jdGlvbiBjcmVhdGUocHJvdG8pIHtcbiAgICAgICAgICAgIHZhciBGID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgICAgICBGLnByb3RvdHlwZSA9IHByb3RvO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBGKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZGVlcEVxdWFsOiBmdW5jdGlvbiBkZWVwRXF1YWwoYSwgYikge1xuICAgICAgICAgICAgaWYgKHNpbm9uLm1hdGNoICYmIHNpbm9uLm1hdGNoLmlzTWF0Y2hlcihhKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhLnRlc3QoYik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgYSAhPSAnb2JqZWN0JyB8fCB0eXBlb2YgYiAhPSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIGlmIChpc1JlYWxseU5hTihhKSAmJiBpc1JlYWxseU5hTihiKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYSA9PT0gYjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0VsZW1lbnQoYSkgfHwgaXNFbGVtZW50KGIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGEgPT09IGI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChhID09PSBiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICgoYSA9PT0gbnVsbCAmJiBiICE9PSBudWxsKSB8fCAoYSAhPT0gbnVsbCAmJiBiID09PSBudWxsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGEgaW5zdGFuY2VvZiBSZWdFeHAgJiYgYiBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgICByZXR1cm4gKGEuc291cmNlID09PSBiLnNvdXJjZSkgJiYgKGEuZ2xvYmFsID09PSBiLmdsb2JhbCkgJiZcbiAgICAgICAgICAgICAgICAoYS5pZ25vcmVDYXNlID09PSBiLmlnbm9yZUNhc2UpICYmIChhLm11bHRpbGluZSA9PT0gYi5tdWx0aWxpbmUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgYVN0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhKTtcbiAgICAgICAgICAgIGlmIChhU3RyaW5nICE9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGFTdHJpbmcgPT0gXCJbb2JqZWN0IERhdGVdXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYS52YWx1ZU9mKCkgPT09IGIudmFsdWVPZigpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcHJvcCwgYUxlbmd0aCA9IDAsIGJMZW5ndGggPSAwO1xuXG4gICAgICAgICAgICBpZiAoYVN0cmluZyA9PSBcIltvYmplY3QgQXJyYXldXCIgJiYgYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHByb3AgaW4gYSkge1xuICAgICAgICAgICAgICAgIGFMZW5ndGggKz0gMTtcblxuICAgICAgICAgICAgICAgIGlmICghKHByb3AgaW4gYikpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghZGVlcEVxdWFsKGFbcHJvcF0sIGJbcHJvcF0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAocHJvcCBpbiBiKSB7XG4gICAgICAgICAgICAgICAgYkxlbmd0aCArPSAxO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gYUxlbmd0aCA9PSBiTGVuZ3RoO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZ1bmN0aW9uTmFtZTogZnVuY3Rpb24gZnVuY3Rpb25OYW1lKGZ1bmMpIHtcbiAgICAgICAgICAgIHZhciBuYW1lID0gZnVuYy5kaXNwbGF5TmFtZSB8fCBmdW5jLm5hbWU7XG5cbiAgICAgICAgICAgIC8vIFVzZSBmdW5jdGlvbiBkZWNvbXBvc2l0aW9uIGFzIGEgbGFzdCByZXNvcnQgdG8gZ2V0IGZ1bmN0aW9uXG4gICAgICAgICAgICAvLyBuYW1lLiBEb2VzIG5vdCByZWx5IG9uIGZ1bmN0aW9uIGRlY29tcG9zaXRpb24gdG8gd29yayAtIGlmIGl0XG4gICAgICAgICAgICAvLyBkb2Vzbid0IGRlYnVnZ2luZyB3aWxsIGJlIHNsaWdodGx5IGxlc3MgaW5mb3JtYXRpdmVcbiAgICAgICAgICAgIC8vIChpLmUuIHRvU3RyaW5nIHdpbGwgc2F5ICdzcHknIHJhdGhlciB0aGFuICdteUZ1bmMnKS5cbiAgICAgICAgICAgIGlmICghbmFtZSkge1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaGVzID0gZnVuYy50b1N0cmluZygpLm1hdGNoKC9mdW5jdGlvbiAoW15cXHNcXChdKykvKTtcbiAgICAgICAgICAgICAgICBuYW1lID0gbWF0Y2hlcyAmJiBtYXRjaGVzWzFdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgICAgfSxcblxuICAgICAgICBmdW5jdGlvblRvU3RyaW5nOiBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmdldENhbGwgJiYgdGhpcy5jYWxsQ291bnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGhpc1ZhbHVlLCBwcm9wLCBpID0gdGhpcy5jYWxsQ291bnQ7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNWYWx1ZSA9IHRoaXMuZ2V0Q2FsbChpKS50aGlzVmFsdWU7XG5cbiAgICAgICAgICAgICAgICAgICAgZm9yIChwcm9wIGluIHRoaXNWYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXNWYWx1ZVtwcm9wXSA9PT0gdGhpcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9wO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kaXNwbGF5TmFtZSB8fCBcInNpbm9uIGZha2VcIjtcbiAgICAgICAgfSxcblxuICAgICAgICBnZXRDb25maWc6IGZ1bmN0aW9uIChjdXN0b20pIHtcbiAgICAgICAgICAgIHZhciBjb25maWcgPSB7fTtcbiAgICAgICAgICAgIGN1c3RvbSA9IGN1c3RvbSB8fCB7fTtcbiAgICAgICAgICAgIHZhciBkZWZhdWx0cyA9IHNpbm9uLmRlZmF1bHRDb25maWc7XG5cbiAgICAgICAgICAgIGZvciAodmFyIHByb3AgaW4gZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGVmYXVsdHMuaGFzT3duUHJvcGVydHkocHJvcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnW3Byb3BdID0gY3VzdG9tLmhhc093blByb3BlcnR5KHByb3ApID8gY3VzdG9tW3Byb3BdIDogZGVmYXVsdHNbcHJvcF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gY29uZmlnO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZvcm1hdDogZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICAgICAgcmV0dXJuIFwiXCIgKyB2YWw7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZGVmYXVsdENvbmZpZzoge1xuICAgICAgICAgICAgaW5qZWN0SW50b1RoaXM6IHRydWUsXG4gICAgICAgICAgICBpbmplY3RJbnRvOiBudWxsLFxuICAgICAgICAgICAgcHJvcGVydGllczogW1wic3B5XCIsIFwic3R1YlwiLCBcIm1vY2tcIiwgXCJjbG9ja1wiLCBcInNlcnZlclwiLCBcInJlcXVlc3RzXCJdLFxuICAgICAgICAgICAgdXNlRmFrZVRpbWVyczogdHJ1ZSxcbiAgICAgICAgICAgIHVzZUZha2VTZXJ2ZXI6IHRydWVcbiAgICAgICAgfSxcblxuICAgICAgICB0aW1lc0luV29yZHM6IGZ1bmN0aW9uIHRpbWVzSW5Xb3Jkcyhjb3VudCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvdW50ID09IDEgJiYgXCJvbmNlXCIgfHxcbiAgICAgICAgICAgICAgICBjb3VudCA9PSAyICYmIFwidHdpY2VcIiB8fFxuICAgICAgICAgICAgICAgIGNvdW50ID09IDMgJiYgXCJ0aHJpY2VcIiB8fFxuICAgICAgICAgICAgICAgIChjb3VudCB8fCAwKSArIFwiIHRpbWVzXCI7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY2FsbGVkSW5PcmRlcjogZnVuY3Rpb24gKHNwaWVzKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMSwgbCA9IHNwaWVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghc3BpZXNbaSAtIDFdLmNhbGxlZEJlZm9yZShzcGllc1tpXSkgfHwgIXNwaWVzW2ldLmNhbGxlZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSxcblxuICAgICAgICBvcmRlckJ5Rmlyc3RDYWxsOiBmdW5jdGlvbiAoc3BpZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBzcGllcy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgICAgICAgLy8gdXVpZCwgd29uJ3QgZXZlciBiZSBlcXVhbFxuICAgICAgICAgICAgICAgIHZhciBhQ2FsbCA9IGEuZ2V0Q2FsbCgwKTtcbiAgICAgICAgICAgICAgICB2YXIgYkNhbGwgPSBiLmdldENhbGwoMCk7XG4gICAgICAgICAgICAgICAgdmFyIGFJZCA9IGFDYWxsICYmIGFDYWxsLmNhbGxJZCB8fCAtMTtcbiAgICAgICAgICAgICAgICB2YXIgYklkID0gYkNhbGwgJiYgYkNhbGwuY2FsbElkIHx8IC0xO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGFJZCA8IGJJZCA/IC0xIDogMTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuXG4gICAgICAgIGxvZzogZnVuY3Rpb24gKCkge30sXG5cbiAgICAgICAgbG9nRXJyb3I6IGZ1bmN0aW9uIChsYWJlbCwgZXJyKSB7XG4gICAgICAgICAgICB2YXIgbXNnID0gbGFiZWwgKyBcIiB0aHJldyBleGNlcHRpb246IFwiO1xuICAgICAgICAgICAgc2lub24ubG9nKG1zZyArIFwiW1wiICsgZXJyLm5hbWUgKyBcIl0gXCIgKyBlcnIubWVzc2FnZSk7XG4gICAgICAgICAgICBpZiAoZXJyLnN0YWNrKSB7IHNpbm9uLmxvZyhlcnIuc3RhY2spOyB9XG5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID0gbXNnICsgZXJyLm1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgdHlwZU9mOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJ1bmRlZmluZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBzdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuIHN0cmluZy5zdWJzdHJpbmcoOCwgc3RyaW5nLmxlbmd0aCAtIDEpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY3JlYXRlU3R1Ykluc3RhbmNlOiBmdW5jdGlvbiAoY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY29uc3RydWN0b3IgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJUaGUgY29uc3RydWN0b3Igc2hvdWxkIGJlIGEgZnVuY3Rpb24uXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNpbm9uLnN0dWIoc2lub24uY3JlYXRlKGNvbnN0cnVjdG9yLnByb3RvdHlwZSkpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHJlc3RvcmU6IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgIT09IG51bGwgJiYgdHlwZW9mIG9iamVjdCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIHByb3AgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc1Jlc3RvcmFibGUob2JqZWN0W3Byb3BdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0W3Byb3BdLnJlc3RvcmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzUmVzdG9yYWJsZShvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnJlc3RvcmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgaXNOb2RlID0gdHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUuZXhwb3J0cyAmJiB0eXBlb2YgcmVxdWlyZSA9PSBcImZ1bmN0aW9uXCI7XG4gICAgdmFyIGlzQU1EID0gdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgZGVmaW5lLmFtZCA9PT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZDtcblxuICAgIGZ1bmN0aW9uIG1ha2VQdWJsaWNBUEkocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gc2lub247XG4gICAgICAgIHNpbm9uLnNweSA9IHJlcXVpcmUoXCIuL3Npbm9uL3NweVwiKTtcbiAgICAgICAgc2lub24uc3B5Q2FsbCA9IHJlcXVpcmUoXCIuL3Npbm9uL2NhbGxcIik7XG4gICAgICAgIHNpbm9uLmJlaGF2aW9yID0gcmVxdWlyZShcIi4vc2lub24vYmVoYXZpb3JcIik7XG4gICAgICAgIHNpbm9uLnN0dWIgPSByZXF1aXJlKFwiLi9zaW5vbi9zdHViXCIpO1xuICAgICAgICBzaW5vbi5tb2NrID0gcmVxdWlyZShcIi4vc2lub24vbW9ja1wiKTtcbiAgICAgICAgc2lub24uY29sbGVjdGlvbiA9IHJlcXVpcmUoXCIuL3Npbm9uL2NvbGxlY3Rpb25cIik7XG4gICAgICAgIHNpbm9uLmFzc2VydCA9IHJlcXVpcmUoXCIuL3Npbm9uL2Fzc2VydFwiKTtcbiAgICAgICAgc2lub24uc2FuZGJveCA9IHJlcXVpcmUoXCIuL3Npbm9uL3NhbmRib3hcIik7XG4gICAgICAgIHNpbm9uLnRlc3QgPSByZXF1aXJlKFwiLi9zaW5vbi90ZXN0XCIpO1xuICAgICAgICBzaW5vbi50ZXN0Q2FzZSA9IHJlcXVpcmUoXCIuL3Npbm9uL3Rlc3RfY2FzZVwiKTtcbiAgICAgICAgc2lub24ubWF0Y2ggPSByZXF1aXJlKFwiLi9zaW5vbi9tYXRjaFwiKTtcbiAgICB9XG5cbiAgICBpZiAoaXNBTUQpIHtcbiAgICAgICAgZGVmaW5lKG1ha2VQdWJsaWNBUEkpO1xuICAgIH0gZWxzZSBpZiAoaXNOb2RlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmb3JtYXRpbyA9IHJlcXVpcmUoXCJmb3JtYXRpb1wiKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgbWFrZVB1YmxpY0FQSShyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpO1xuICAgIH1cblxuICAgIGlmIChmb3JtYXRpbykge1xuICAgICAgICB2YXIgZm9ybWF0dGVyID0gZm9ybWF0aW8uY29uZmlndXJlKHsgcXVvdGVTdHJpbmdzOiBmYWxzZSB9KTtcbiAgICAgICAgc2lub24uZm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdHRlci5hc2NpaS5hcHBseShmb3JtYXR0ZXIsIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgfSBlbHNlIGlmIChpc05vZGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhciB1dGlsID0gcmVxdWlyZShcInV0aWxcIik7XG4gICAgICAgICAgICBzaW5vbi5mb3JtYXQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09IFwib2JqZWN0XCIgJiYgdmFsdWUudG9TdHJpbmcgPT09IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcgPyB1dGlsLmluc3BlY3QodmFsdWUpIDogdmFsdWU7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvKiBOb2RlLCBidXQgbm8gdXRpbCBtb2R1bGUgLSB3b3VsZCBiZSB2ZXJ5IG9sZCwgYnV0IGJldHRlciBzYWZlIHRoYW5cbiAgICAgICAgICAgICBzb3JyeSAqL1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNpbm9uO1xufSh0eXBlb2YgZm9ybWF0aW8gPT0gXCJvYmplY3RcIiAmJiBmb3JtYXRpbykpO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xuLyoqXG4gKiBAZGVwZW5kIC4uL3Npbm9uLmpzXG4gKiBAZGVwZW5kIHN0dWIuanNcbiAqL1xuLypqc2xpbnQgZXFlcWVxOiBmYWxzZSwgb25ldmFyOiBmYWxzZSwgbm9tZW46IGZhbHNlLCBwbHVzcGx1czogZmFsc2UqL1xuLypnbG9iYWwgbW9kdWxlLCByZXF1aXJlLCBzaW5vbiovXG4vKipcbiAqIEFzc2VydGlvbnMgbWF0Y2hpbmcgdGhlIHRlc3Qgc3B5IHJldHJpZXZhbCBpbnRlcmZhY2UuXG4gKlxuICogQGF1dGhvciBDaHJpc3RpYW4gSm9oYW5zZW4gKGNocmlzdGlhbkBjam9oYW5zZW4ubm8pXG4gKiBAbGljZW5zZSBCU0RcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMyBDaHJpc3RpYW4gSm9oYW5zZW5cbiAqL1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbihmdW5jdGlvbiAoc2lub24sIGdsb2JhbCkge1xuICAgIHZhciBjb21tb25KU01vZHVsZSA9IHR5cGVvZiBtb2R1bGUgIT09IFwidW5kZWZpbmVkXCIgJiYgbW9kdWxlLmV4cG9ydHMgJiYgdHlwZW9mIHJlcXVpcmUgPT0gXCJmdW5jdGlvblwiO1xuICAgIHZhciBzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcbiAgICB2YXIgYXNzZXJ0O1xuXG4gICAgaWYgKCFzaW5vbiAmJiBjb21tb25KU01vZHVsZSkge1xuICAgICAgICBzaW5vbiA9IHJlcXVpcmUoXCIuLi9zaW5vblwiKTtcbiAgICB9XG5cbiAgICBpZiAoIXNpbm9uKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB2ZXJpZnlJc1N0dWIoKSB7XG4gICAgICAgIHZhciBtZXRob2Q7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgICAgICAgICBtZXRob2QgPSBhcmd1bWVudHNbaV07XG5cbiAgICAgICAgICAgIGlmICghbWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0LmZhaWwoXCJmYWtlIGlzIG5vdCBhIHNweVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXRob2QgIT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0LmZhaWwobWV0aG9kICsgXCIgaXMgbm90IGEgZnVuY3Rpb25cIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWV0aG9kLmdldENhbGwgIT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0LmZhaWwobWV0aG9kICsgXCIgaXMgbm90IHN0dWJiZWRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBmYWlsQXNzZXJ0aW9uKG9iamVjdCwgbXNnKSB7XG4gICAgICAgIG9iamVjdCA9IG9iamVjdCB8fCBnbG9iYWw7XG4gICAgICAgIHZhciBmYWlsTWV0aG9kID0gb2JqZWN0LmZhaWwgfHwgYXNzZXJ0LmZhaWw7XG4gICAgICAgIGZhaWxNZXRob2QuY2FsbChvYmplY3QsIG1zZyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWlycm9yUHJvcEFzQXNzZXJ0aW9uKG5hbWUsIG1ldGhvZCwgbWVzc2FnZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAyKSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gbWV0aG9kO1xuICAgICAgICAgICAgbWV0aG9kID0gbmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGFzc2VydFtuYW1lXSA9IGZ1bmN0aW9uIChmYWtlKSB7XG4gICAgICAgICAgICB2ZXJpZnlJc1N0dWIoZmFrZSk7XG5cbiAgICAgICAgICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICAgICAgdmFyIGZhaWxlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG1ldGhvZCA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBmYWlsZWQgPSAhbWV0aG9kKGZha2UpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmYWlsZWQgPSB0eXBlb2YgZmFrZVttZXRob2RdID09IFwiZnVuY3Rpb25cIiA/XG4gICAgICAgICAgICAgICAgICAgICFmYWtlW21ldGhvZF0uYXBwbHkoZmFrZSwgYXJncykgOiAhZmFrZVttZXRob2RdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZmFpbGVkKSB7XG4gICAgICAgICAgICAgICAgZmFpbEFzc2VydGlvbih0aGlzLCBmYWtlLnByaW50Zi5hcHBseShmYWtlLCBbbWVzc2FnZV0uY29uY2F0KGFyZ3MpKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGFzc2VydC5wYXNzKG5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGV4cG9zZWROYW1lKHByZWZpeCwgcHJvcCkge1xuICAgICAgICByZXR1cm4gIXByZWZpeCB8fCAvXmZhaWwvLnRlc3QocHJvcCkgPyBwcm9wIDpcbiAgICAgICAgICAgIHByZWZpeCArIHByb3Auc2xpY2UoMCwgMSkudG9VcHBlckNhc2UoKSArIHByb3Auc2xpY2UoMSk7XG4gICAgfVxuXG4gICAgYXNzZXJ0ID0ge1xuICAgICAgICBmYWlsRXhjZXB0aW9uOiBcIkFzc2VydEVycm9yXCIsXG5cbiAgICAgICAgZmFpbDogZnVuY3Rpb24gZmFpbChtZXNzYWdlKSB7XG4gICAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgICAgICBlcnJvci5uYW1lID0gdGhpcy5mYWlsRXhjZXB0aW9uIHx8IGFzc2VydC5mYWlsRXhjZXB0aW9uO1xuXG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfSxcblxuICAgICAgICBwYXNzOiBmdW5jdGlvbiBwYXNzKGFzc2VydGlvbikge30sXG5cbiAgICAgICAgY2FsbE9yZGVyOiBmdW5jdGlvbiBhc3NlcnRDYWxsT3JkZXIoKSB7XG4gICAgICAgICAgICB2ZXJpZnlJc1N0dWIuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIHZhciBleHBlY3RlZCA9IFwiXCIsIGFjdHVhbCA9IFwiXCI7XG5cbiAgICAgICAgICAgIGlmICghc2lub24uY2FsbGVkSW5PcmRlcihhcmd1bWVudHMpKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQgPSBbXS5qb2luLmNhbGwoYXJndW1lbnRzLCBcIiwgXCIpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgY2FsbHMgPSBzbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gY2FsbHMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjYWxsc1stLWldLmNhbGxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhY3R1YWwgPSBzaW5vbi5vcmRlckJ5Rmlyc3RDYWxsKGNhbGxzKS5qb2luKFwiLCBcIik7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGZhaWxzLCB3ZSdsbCBqdXN0IGZhbGwgYmFjayB0byB0aGUgYmxhbmsgc3RyaW5nXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZmFpbEFzc2VydGlvbih0aGlzLCBcImV4cGVjdGVkIFwiICsgZXhwZWN0ZWQgKyBcIiB0byBiZSBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNhbGxlZCBpbiBvcmRlciBidXQgd2VyZSBjYWxsZWQgYXMgXCIgKyBhY3R1YWwpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhc3NlcnQucGFzcyhcImNhbGxPcmRlclwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBjYWxsQ291bnQ6IGZ1bmN0aW9uIGFzc2VydENhbGxDb3VudChtZXRob2QsIGNvdW50KSB7XG4gICAgICAgICAgICB2ZXJpZnlJc1N0dWIobWV0aG9kKTtcblxuICAgICAgICAgICAgaWYgKG1ldGhvZC5jYWxsQ291bnQgIT0gY291bnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgbXNnID0gXCJleHBlY3RlZCAlbiB0byBiZSBjYWxsZWQgXCIgKyBzaW5vbi50aW1lc0luV29yZHMoY291bnQpICtcbiAgICAgICAgICAgICAgICAgICAgXCIgYnV0IHdhcyBjYWxsZWQgJWMlQ1wiO1xuICAgICAgICAgICAgICAgIGZhaWxBc3NlcnRpb24odGhpcywgbWV0aG9kLnByaW50Zihtc2cpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0LnBhc3MoXCJjYWxsQ291bnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgZXhwb3NlOiBmdW5jdGlvbiBleHBvc2UodGFyZ2V0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ0YXJnZXQgaXMgbnVsbCBvciB1bmRlZmluZWRcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBvID0gb3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgIHZhciBwcmVmaXggPSB0eXBlb2Ygby5wcmVmaXggPT0gXCJ1bmRlZmluZWRcIiAmJiBcImFzc2VydFwiIHx8IG8ucHJlZml4O1xuICAgICAgICAgICAgdmFyIGluY2x1ZGVGYWlsID0gdHlwZW9mIG8uaW5jbHVkZUZhaWwgPT0gXCJ1bmRlZmluZWRcIiB8fCAhIW8uaW5jbHVkZUZhaWw7XG5cbiAgICAgICAgICAgIGZvciAodmFyIG1ldGhvZCBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1ldGhvZCAhPSBcImV4cG9ydFwiICYmIChpbmNsdWRlRmFpbCB8fCAhL14oZmFpbCkvLnRlc3QobWV0aG9kKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W2V4cG9zZWROYW1lKHByZWZpeCwgbWV0aG9kKV0gPSB0aGlzW21ldGhvZF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgICAgICB9LFxuXG4gICAgICAgIG1hdGNoOiBmdW5jdGlvbiBtYXRjaChhY3R1YWwsIGV4cGVjdGF0aW9uKSB7XG4gICAgICAgICAgICB2YXIgbWF0Y2hlciA9IHNpbm9uLm1hdGNoKGV4cGVjdGF0aW9uKTtcbiAgICAgICAgICAgIGlmIChtYXRjaGVyLnRlc3QoYWN0dWFsKSkge1xuICAgICAgICAgICAgICAgIGFzc2VydC5wYXNzKFwibWF0Y2hcIik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBmb3JtYXR0ZWQgPSBbXG4gICAgICAgICAgICAgICAgICAgIFwiZXhwZWN0ZWQgdmFsdWUgdG8gbWF0Y2hcIixcbiAgICAgICAgICAgICAgICAgICAgXCIgICAgZXhwZWN0ZWQgPSBcIiArIHNpbm9uLmZvcm1hdChleHBlY3RhdGlvbiksXG4gICAgICAgICAgICAgICAgICAgIFwiICAgIGFjdHVhbCA9IFwiICsgc2lub24uZm9ybWF0KGFjdHVhbClcbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgZmFpbEFzc2VydGlvbih0aGlzLCBmb3JtYXR0ZWQuam9pbihcIlxcblwiKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgbWlycm9yUHJvcEFzQXNzZXJ0aW9uKFwiY2FsbGVkXCIsIFwiZXhwZWN0ZWQgJW4gdG8gaGF2ZSBiZWVuIGNhbGxlZCBhdCBsZWFzdCBvbmNlIGJ1dCB3YXMgbmV2ZXIgY2FsbGVkXCIpO1xuICAgIG1pcnJvclByb3BBc0Fzc2VydGlvbihcIm5vdENhbGxlZFwiLCBmdW5jdGlvbiAoc3B5KSB7IHJldHVybiAhc3B5LmNhbGxlZDsgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJleHBlY3RlZCAlbiB0byBub3QgaGF2ZSBiZWVuIGNhbGxlZCBidXQgd2FzIGNhbGxlZCAlYyVDXCIpO1xuICAgIG1pcnJvclByb3BBc0Fzc2VydGlvbihcImNhbGxlZE9uY2VcIiwgXCJleHBlY3RlZCAlbiB0byBiZSBjYWxsZWQgb25jZSBidXQgd2FzIGNhbGxlZCAlYyVDXCIpO1xuICAgIG1pcnJvclByb3BBc0Fzc2VydGlvbihcImNhbGxlZFR3aWNlXCIsIFwiZXhwZWN0ZWQgJW4gdG8gYmUgY2FsbGVkIHR3aWNlIGJ1dCB3YXMgY2FsbGVkICVjJUNcIik7XG4gICAgbWlycm9yUHJvcEFzQXNzZXJ0aW9uKFwiY2FsbGVkVGhyaWNlXCIsIFwiZXhwZWN0ZWQgJW4gdG8gYmUgY2FsbGVkIHRocmljZSBidXQgd2FzIGNhbGxlZCAlYyVDXCIpO1xuICAgIG1pcnJvclByb3BBc0Fzc2VydGlvbihcImNhbGxlZE9uXCIsIFwiZXhwZWN0ZWQgJW4gdG8gYmUgY2FsbGVkIHdpdGggJTEgYXMgdGhpcyBidXQgd2FzIGNhbGxlZCB3aXRoICV0XCIpO1xuICAgIG1pcnJvclByb3BBc0Fzc2VydGlvbihcImFsd2F5c0NhbGxlZE9uXCIsIFwiZXhwZWN0ZWQgJW4gdG8gYWx3YXlzIGJlIGNhbGxlZCB3aXRoICUxIGFzIHRoaXMgYnV0IHdhcyBjYWxsZWQgd2l0aCAldFwiKTtcbiAgICBtaXJyb3JQcm9wQXNBc3NlcnRpb24oXCJjYWxsZWRXaXRoTmV3XCIsIFwiZXhwZWN0ZWQgJW4gdG8gYmUgY2FsbGVkIHdpdGggbmV3XCIpO1xuICAgIG1pcnJvclByb3BBc0Fzc2VydGlvbihcImFsd2F5c0NhbGxlZFdpdGhOZXdcIiwgXCJleHBlY3RlZCAlbiB0byBhbHdheXMgYmUgY2FsbGVkIHdpdGggbmV3XCIpO1xuICAgIG1pcnJvclByb3BBc0Fzc2VydGlvbihcImNhbGxlZFdpdGhcIiwgXCJleHBlY3RlZCAlbiB0byBiZSBjYWxsZWQgd2l0aCBhcmd1bWVudHMgJSolQ1wiKTtcbiAgICBtaXJyb3JQcm9wQXNBc3NlcnRpb24oXCJjYWxsZWRXaXRoTWF0Y2hcIiwgXCJleHBlY3RlZCAlbiB0byBiZSBjYWxsZWQgd2l0aCBtYXRjaCAlKiVDXCIpO1xuICAgIG1pcnJvclByb3BBc0Fzc2VydGlvbihcImFsd2F5c0NhbGxlZFdpdGhcIiwgXCJleHBlY3RlZCAlbiB0byBhbHdheXMgYmUgY2FsbGVkIHdpdGggYXJndW1lbnRzICUqJUNcIik7XG4gICAgbWlycm9yUHJvcEFzQXNzZXJ0aW9uKFwiYWx3YXlzQ2FsbGVkV2l0aE1hdGNoXCIsIFwiZXhwZWN0ZWQgJW4gdG8gYWx3YXlzIGJlIGNhbGxlZCB3aXRoIG1hdGNoICUqJUNcIik7XG4gICAgbWlycm9yUHJvcEFzQXNzZXJ0aW9uKFwiY2FsbGVkV2l0aEV4YWN0bHlcIiwgXCJleHBlY3RlZCAlbiB0byBiZSBjYWxsZWQgd2l0aCBleGFjdCBhcmd1bWVudHMgJSolQ1wiKTtcbiAgICBtaXJyb3JQcm9wQXNBc3NlcnRpb24oXCJhbHdheXNDYWxsZWRXaXRoRXhhY3RseVwiLCBcImV4cGVjdGVkICVuIHRvIGFsd2F5cyBiZSBjYWxsZWQgd2l0aCBleGFjdCBhcmd1bWVudHMgJSolQ1wiKTtcbiAgICBtaXJyb3JQcm9wQXNBc3NlcnRpb24oXCJuZXZlckNhbGxlZFdpdGhcIiwgXCJleHBlY3RlZCAlbiB0byBuZXZlciBiZSBjYWxsZWQgd2l0aCBhcmd1bWVudHMgJSolQ1wiKTtcbiAgICBtaXJyb3JQcm9wQXNBc3NlcnRpb24oXCJuZXZlckNhbGxlZFdpdGhNYXRjaFwiLCBcImV4cGVjdGVkICVuIHRvIG5ldmVyIGJlIGNhbGxlZCB3aXRoIG1hdGNoICUqJUNcIik7XG4gICAgbWlycm9yUHJvcEFzQXNzZXJ0aW9uKFwidGhyZXdcIiwgXCIlbiBkaWQgbm90IHRocm93IGV4Y2VwdGlvbiVDXCIpO1xuICAgIG1pcnJvclByb3BBc0Fzc2VydGlvbihcImFsd2F5c1RocmV3XCIsIFwiJW4gZGlkIG5vdCBhbHdheXMgdGhyb3cgZXhjZXB0aW9uJUNcIik7XG5cbiAgICBzaW5vbi5hc3NlcnQgPSBhc3NlcnQ7XG5cbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKFtcIm1vZHVsZVwiXSwgZnVuY3Rpb24obW9kdWxlKSB7IG1vZHVsZS5leHBvcnRzID0gYXNzZXJ0OyB9KTtcbiAgICB9IGVsc2UgaWYgKGNvbW1vbkpTTW9kdWxlKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gYXNzZXJ0O1xuICAgIH1cbn0odHlwZW9mIHNpbm9uID09IFwib2JqZWN0XCIgJiYgc2lub24gfHwgbnVsbCwgdHlwZW9mIHdpbmRvdyAhPSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogKHR5cGVvZiBzZWxmICE9IFwidW5kZWZpbmVkXCIpID8gc2VsZiA6IGdsb2JhbCkpO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KSIsIihmdW5jdGlvbiAocHJvY2Vzcyl7XG4vKipcbiAqIEBkZXBlbmQgLi4vc2lub24uanNcbiAqL1xuLypqc2xpbnQgZXFlcWVxOiBmYWxzZSwgb25ldmFyOiBmYWxzZSovXG4vKmdsb2JhbCBtb2R1bGUsIHJlcXVpcmUsIHNpbm9uLCBwcm9jZXNzLCBzZXRJbW1lZGlhdGUsIHNldFRpbWVvdXQqL1xuLyoqXG4gKiBTdHViIGJlaGF2aW9yXG4gKlxuICogQGF1dGhvciBDaHJpc3RpYW4gSm9oYW5zZW4gKGNocmlzdGlhbkBjam9oYW5zZW4ubm8pXG4gKiBAYXV0aG9yIFRpbSBGaXNjaGJhY2ggKG1haWxAdGltZmlzY2hiYWNoLmRlKVxuICogQGxpY2Vuc2UgQlNEXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTMgQ2hyaXN0aWFuIEpvaGFuc2VuXG4gKi9cblwidXNlIHN0cmljdFwiO1xuXG4oZnVuY3Rpb24gKHNpbm9uKSB7XG4gICAgdmFyIGNvbW1vbkpTTW9kdWxlID0gdHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUuZXhwb3J0cyAmJiB0eXBlb2YgcmVxdWlyZSA9PSBcImZ1bmN0aW9uXCI7XG5cbiAgICBpZiAoIXNpbm9uICYmIGNvbW1vbkpTTW9kdWxlKSB7XG4gICAgICAgIHNpbm9uID0gcmVxdWlyZShcIi4uL3Npbm9uXCIpO1xuICAgIH1cblxuICAgIGlmICghc2lub24pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcbiAgICB2YXIgam9pbiA9IEFycmF5LnByb3RvdHlwZS5qb2luO1xuICAgIHZhciBwcm90bztcblxuICAgIHZhciBuZXh0VGljayA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcHJvY2Vzcy5uZXh0VGljayA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljaztcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBzZXRJbW1lZGlhdGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChjYWxsYmFjaywgMCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSkoKTtcblxuICAgIGZ1bmN0aW9uIHRocm93c0V4Y2VwdGlvbihlcnJvciwgbWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIGVycm9yID09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHRoaXMuZXhjZXB0aW9uID0gbmV3IEVycm9yKG1lc3NhZ2UgfHwgXCJcIik7XG4gICAgICAgICAgICB0aGlzLmV4Y2VwdGlvbi5uYW1lID0gZXJyb3I7XG4gICAgICAgIH0gZWxzZSBpZiAoIWVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IG5ldyBFcnJvcihcIkVycm9yXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5leGNlcHRpb24gPSBlcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldENhbGxiYWNrKGJlaGF2aW9yLCBhcmdzKSB7XG4gICAgICAgIHZhciBjYWxsQXJnQXQgPSBiZWhhdmlvci5jYWxsQXJnQXQ7XG5cbiAgICAgICAgaWYgKGNhbGxBcmdBdCA8IDApIHtcbiAgICAgICAgICAgIHZhciBjYWxsQXJnUHJvcCA9IGJlaGF2aW9yLmNhbGxBcmdQcm9wO1xuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGFyZ3MubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjYWxsQXJnUHJvcCAmJiB0eXBlb2YgYXJnc1tpXSA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyZ3NbaV07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGNhbGxBcmdQcm9wICYmIGFyZ3NbaV0gJiZcbiAgICAgICAgICAgICAgICAgICAgdHlwZW9mIGFyZ3NbaV1bY2FsbEFyZ1Byb3BdID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJnc1tpXVtjYWxsQXJnUHJvcF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcmdzW2NhbGxBcmdBdF07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0Q2FsbGJhY2tFcnJvcihiZWhhdmlvciwgZnVuYywgYXJncykge1xuICAgICAgICBpZiAoYmVoYXZpb3IuY2FsbEFyZ0F0IDwgMCkge1xuICAgICAgICAgICAgdmFyIG1zZztcblxuICAgICAgICAgICAgaWYgKGJlaGF2aW9yLmNhbGxBcmdQcm9wKSB7XG4gICAgICAgICAgICAgICAgbXNnID0gc2lub24uZnVuY3Rpb25OYW1lKGJlaGF2aW9yLnN0dWIpICtcbiAgICAgICAgICAgICAgICAgICAgXCIgZXhwZWN0ZWQgdG8geWllbGQgdG8gJ1wiICsgYmVoYXZpb3IuY2FsbEFyZ1Byb3AgK1xuICAgICAgICAgICAgICAgICAgICBcIicsIGJ1dCBubyBvYmplY3Qgd2l0aCBzdWNoIGEgcHJvcGVydHkgd2FzIHBhc3NlZC5cIjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbXNnID0gc2lub24uZnVuY3Rpb25OYW1lKGJlaGF2aW9yLnN0dWIpICtcbiAgICAgICAgICAgICAgICAgICAgXCIgZXhwZWN0ZWQgdG8geWllbGQsIGJ1dCBubyBjYWxsYmFjayB3YXMgcGFzc2VkLlwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgbXNnICs9IFwiIFJlY2VpdmVkIFtcIiArIGpvaW4uY2FsbChhcmdzLCBcIiwgXCIpICsgXCJdXCI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBtc2c7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gXCJhcmd1bWVudCBhdCBpbmRleCBcIiArIGJlaGF2aW9yLmNhbGxBcmdBdCArIFwiIGlzIG5vdCBhIGZ1bmN0aW9uOiBcIiArIGZ1bmM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsbENhbGxiYWNrKGJlaGF2aW9yLCBhcmdzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYmVoYXZpb3IuY2FsbEFyZ0F0ID09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIHZhciBmdW5jID0gZ2V0Q2FsbGJhY2soYmVoYXZpb3IsIGFyZ3MpO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihnZXRDYWxsYmFja0Vycm9yKGJlaGF2aW9yLCBmdW5jLCBhcmdzKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChiZWhhdmlvci5jYWxsYmFja0FzeW5jKSB7XG4gICAgICAgICAgICAgICAgbmV4dFRpY2soZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bmMuYXBwbHkoYmVoYXZpb3IuY2FsbGJhY2tDb250ZXh0LCBiZWhhdmlvci5jYWxsYmFja0FyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZ1bmMuYXBwbHkoYmVoYXZpb3IuY2FsbGJhY2tDb250ZXh0LCBiZWhhdmlvci5jYWxsYmFja0FyZ3VtZW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcm90byA9IHtcbiAgICAgICAgY3JlYXRlOiBmdW5jdGlvbihzdHViKSB7XG4gICAgICAgICAgICB2YXIgYmVoYXZpb3IgPSBzaW5vbi5leHRlbmQoe30sIHNpbm9uLmJlaGF2aW9yKTtcbiAgICAgICAgICAgIGRlbGV0ZSBiZWhhdmlvci5jcmVhdGU7XG4gICAgICAgICAgICBiZWhhdmlvci5zdHViID0gc3R1YjtcblxuICAgICAgICAgICAgcmV0dXJuIGJlaGF2aW9yO1xuICAgICAgICB9LFxuXG4gICAgICAgIGlzUHJlc2VudDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gKHR5cGVvZiB0aGlzLmNhbGxBcmdBdCA9PSAnbnVtYmVyJyB8fFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4Y2VwdGlvbiB8fFxuICAgICAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcy5yZXR1cm5BcmdBdCA9PSAnbnVtYmVyJyB8fFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJldHVyblRoaXMgfHxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXR1cm5WYWx1ZURlZmluZWQpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGludm9rZTogZnVuY3Rpb24oY29udGV4dCwgYXJncykge1xuICAgICAgICAgICAgY2FsbENhbGxiYWNrKHRoaXMsIGFyZ3MpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5leGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyB0aGlzLmV4Y2VwdGlvbjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMucmV0dXJuQXJnQXQgPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJnc1t0aGlzLnJldHVybkFyZ0F0XTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5yZXR1cm5UaGlzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJldHVyblZhbHVlO1xuICAgICAgICB9LFxuXG4gICAgICAgIG9uQ2FsbDogZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0dWIub25DYWxsKGluZGV4KTtcbiAgICAgICAgfSxcblxuICAgICAgICBvbkZpcnN0Q2FsbDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdHViLm9uRmlyc3RDYWxsKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgb25TZWNvbmRDYWxsOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0dWIub25TZWNvbmRDYWxsKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgb25UaGlyZENhbGw6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3R1Yi5vblRoaXJkQ2FsbCgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHdpdGhBcmdzOiBmdW5jdGlvbigvKiBhcmd1bWVudHMgKi8pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRGVmaW5pbmcgYSBzdHViIGJ5IGludm9raW5nIFwic3R1Yi5vbkNhbGwoLi4uKS53aXRoQXJncyguLi4pXCIgaXMgbm90IHN1cHBvcnRlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1VzZSBcInN0dWIud2l0aEFyZ3MoLi4uKS5vbkNhbGwoLi4uKVwiIHRvIGRlZmluZSBzZXF1ZW50aWFsIGJlaGF2aW9yIGZvciBjYWxscyB3aXRoIGNlcnRhaW4gYXJndW1lbnRzLicpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNhbGxzQXJnOiBmdW5jdGlvbiBjYWxsc0FyZyhwb3MpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcG9zICE9IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXJndW1lbnQgaW5kZXggaXMgbm90IG51bWJlclwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jYWxsQXJnQXQgPSBwb3M7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQXJndW1lbnRzID0gW107XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQ29udGV4dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuY2FsbEFyZ1Byb3AgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQXN5bmMgPSBmYWxzZTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY2FsbHNBcmdPbjogZnVuY3Rpb24gY2FsbHNBcmdPbihwb3MsIGNvbnRleHQpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcG9zICE9IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXJndW1lbnQgaW5kZXggaXMgbm90IG51bWJlclwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dCAhPSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImFyZ3VtZW50IGNvbnRleHQgaXMgbm90IGFuIG9iamVjdFwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jYWxsQXJnQXQgPSBwb3M7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQXJndW1lbnRzID0gW107XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQ29udGV4dCA9IGNvbnRleHQ7XG4gICAgICAgICAgICB0aGlzLmNhbGxBcmdQcm9wID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFja0FzeW5jID0gZmFsc2U7XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNhbGxzQXJnV2l0aDogZnVuY3Rpb24gY2FsbHNBcmdXaXRoKHBvcykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBwb3MgIT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJhcmd1bWVudCBpbmRleCBpcyBub3QgbnVtYmVyXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmNhbGxBcmdBdCA9IHBvcztcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tBcmd1bWVudHMgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQ29udGV4dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuY2FsbEFyZ1Byb3AgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQXN5bmMgPSBmYWxzZTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY2FsbHNBcmdPbldpdGg6IGZ1bmN0aW9uIGNhbGxzQXJnV2l0aChwb3MsIGNvbnRleHQpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcG9zICE9IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXJndW1lbnQgaW5kZXggaXMgbm90IG51bWJlclwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dCAhPSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImFyZ3VtZW50IGNvbnRleHQgaXMgbm90IGFuIG9iamVjdFwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jYWxsQXJnQXQgPSBwb3M7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQXJndW1lbnRzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpO1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFja0NvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICAgICAgdGhpcy5jYWxsQXJnUHJvcCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tBc3luYyA9IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICB5aWVsZHM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMuY2FsbEFyZ0F0ID0gLTE7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQXJndW1lbnRzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFja0NvbnRleHQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLmNhbGxBcmdQcm9wID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFja0FzeW5jID0gZmFsc2U7XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIHlpZWxkc09uOiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0ICE9IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXJndW1lbnQgY29udGV4dCBpcyBub3QgYW4gb2JqZWN0XCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmNhbGxBcmdBdCA9IC0xO1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFja0FyZ3VtZW50cyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tDb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgICAgIHRoaXMuY2FsbEFyZ1Byb3AgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQXN5bmMgPSBmYWxzZTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgeWllbGRzVG86IGZ1bmN0aW9uIChwcm9wKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxBcmdBdCA9IC0xO1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFja0FyZ3VtZW50cyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tDb250ZXh0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5jYWxsQXJnUHJvcCA9IHByb3A7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQXN5bmMgPSBmYWxzZTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgeWllbGRzVG9PbjogZnVuY3Rpb24gKHByb3AsIGNvbnRleHQpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dCAhPSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImFyZ3VtZW50IGNvbnRleHQgaXMgbm90IGFuIG9iamVjdFwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jYWxsQXJnQXQgPSAtMTtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tBcmd1bWVudHMgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQ29udGV4dCA9IGNvbnRleHQ7XG4gICAgICAgICAgICB0aGlzLmNhbGxBcmdQcm9wID0gcHJvcDtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tBc3luYyA9IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuXG4gICAgICAgIFwidGhyb3dzXCI6IHRocm93c0V4Y2VwdGlvbixcbiAgICAgICAgdGhyb3dzRXhjZXB0aW9uOiB0aHJvd3NFeGNlcHRpb24sXG5cbiAgICAgICAgcmV0dXJuczogZnVuY3Rpb24gcmV0dXJucyh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5yZXR1cm5WYWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgdGhpcy5yZXR1cm5WYWx1ZURlZmluZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICByZXR1cm5zQXJnOiBmdW5jdGlvbiByZXR1cm5zQXJnKHBvcykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBwb3MgIT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJhcmd1bWVudCBpbmRleCBpcyBub3QgbnVtYmVyXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnJldHVybkFyZ0F0ID0gcG9zO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICByZXR1cm5zVGhpczogZnVuY3Rpb24gcmV0dXJuc1RoaXMoKSB7XG4gICAgICAgICAgICB0aGlzLnJldHVyblRoaXMgPSB0cnVlO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBjcmVhdGUgYXN5bmNocm9ub3VzIHZlcnNpb25zIG9mIGNhbGxzQXJnKiBhbmQgeWllbGRzKiBtZXRob2RzXG4gICAgZm9yICh2YXIgbWV0aG9kIGluIHByb3RvKSB7XG4gICAgICAgIC8vIG5lZWQgdG8gYXZvaWQgY3JlYXRpbmcgYW5vdGhlcmFzeW5jIHZlcnNpb25zIG9mIHRoZSBuZXdseSBhZGRlZCBhc3luYyBtZXRob2RzXG4gICAgICAgIGlmIChwcm90by5oYXNPd25Qcm9wZXJ0eShtZXRob2QpICYmXG4gICAgICAgICAgICBtZXRob2QubWF0Y2goL14oY2FsbHNBcmd8eWllbGRzKS8pICYmXG4gICAgICAgICAgICAhbWV0aG9kLm1hdGNoKC9Bc3luYy8pKSB7XG4gICAgICAgICAgICBwcm90b1ttZXRob2QgKyAnQXN5bmMnXSA9IChmdW5jdGlvbiAoc3luY0ZuTmFtZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB0aGlzW3N5bmNGbk5hbWVdLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tBc3luYyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pKG1ldGhvZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzaW5vbi5iZWhhdmlvciA9IHByb3RvO1xuXG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShbXCJtb2R1bGVcIl0sIGZ1bmN0aW9uKG1vZHVsZSkgeyBtb2R1bGUuZXhwb3J0cyA9IHByb3RvOyB9KTtcbiAgICB9IGVsc2UgaWYgKGNvbW1vbkpTTW9kdWxlKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gcHJvdG87XG4gICAgfVxufSh0eXBlb2Ygc2lub24gPT0gXCJvYmplY3RcIiAmJiBzaW5vbiB8fCBudWxsKSk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwiMVlpWjVTXCIpKSIsIi8qKlxuICAqIEBkZXBlbmQgLi4vc2lub24uanNcbiAgKiBAZGVwZW5kIG1hdGNoLmpzXG4gICovXG4vKmpzbGludCBlcWVxZXE6IGZhbHNlLCBvbmV2YXI6IGZhbHNlLCBwbHVzcGx1czogZmFsc2UqL1xuLypnbG9iYWwgbW9kdWxlLCByZXF1aXJlLCBzaW5vbiovXG4vKipcbiAgKiBTcHkgY2FsbHNcbiAgKlxuICAqIEBhdXRob3IgQ2hyaXN0aWFuIEpvaGFuc2VuIChjaHJpc3RpYW5AY2pvaGFuc2VuLm5vKVxuICAqIEBhdXRob3IgTWF4aW1pbGlhbiBBbnRvbmkgKG1haWxAbWF4YW50b25pLmRlKVxuICAqIEBsaWNlbnNlIEJTRFxuICAqXG4gICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTMgQ2hyaXN0aWFuIEpvaGFuc2VuXG4gICogQ29weXJpZ2h0IChjKSAyMDEzIE1heGltaWxpYW4gQW50b25pXG4gICovXG5cInVzZSBzdHJpY3RcIjtcblxuKGZ1bmN0aW9uIChzaW5vbikge1xuICAgIHZhciBjb21tb25KU01vZHVsZSA9IHR5cGVvZiBtb2R1bGUgIT09IFwidW5kZWZpbmVkXCIgJiYgbW9kdWxlLmV4cG9ydHMgJiYgdHlwZW9mIHJlcXVpcmUgPT0gXCJmdW5jdGlvblwiO1xuICAgIGlmICghc2lub24gJiYgY29tbW9uSlNNb2R1bGUpIHtcbiAgICAgICAgc2lub24gPSByZXF1aXJlKFwiLi4vc2lub25cIik7XG4gICAgfVxuXG4gICAgaWYgKCFzaW5vbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdGhyb3dZaWVsZEVycm9yKHByb3h5LCB0ZXh0LCBhcmdzKSB7XG4gICAgICAgIHZhciBtc2cgPSBzaW5vbi5mdW5jdGlvbk5hbWUocHJveHkpICsgdGV4dDtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgICAgICBtc2cgKz0gXCIgUmVjZWl2ZWQgW1wiICsgc2xpY2UuY2FsbChhcmdzKS5qb2luKFwiLCBcIikgKyBcIl1cIjtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICB9XG5cbiAgICB2YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbiAgICB2YXIgY2FsbFByb3RvID0ge1xuICAgICAgICBjYWxsZWRPbjogZnVuY3Rpb24gY2FsbGVkT24odGhpc1ZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoc2lub24ubWF0Y2ggJiYgc2lub24ubWF0Y2guaXNNYXRjaGVyKHRoaXNWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1ZhbHVlLnRlc3QodGhpcy50aGlzVmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudGhpc1ZhbHVlID09PSB0aGlzVmFsdWU7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY2FsbGVkV2l0aDogZnVuY3Rpb24gY2FsbGVkV2l0aCgpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGlmICghc2lub24uZGVlcEVxdWFsKGFyZ3VtZW50c1tpXSwgdGhpcy5hcmdzW2ldKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSxcblxuICAgICAgICBjYWxsZWRXaXRoTWF0Y2g6IGZ1bmN0aW9uIGNhbGxlZFdpdGhNYXRjaCgpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIHZhciBhY3R1YWwgPSB0aGlzLmFyZ3NbaV07XG4gICAgICAgICAgICAgICAgdmFyIGV4cGVjdGF0aW9uID0gYXJndW1lbnRzW2ldO1xuICAgICAgICAgICAgICAgIGlmICghc2lub24ubWF0Y2ggfHwgIXNpbm9uLm1hdGNoKGV4cGVjdGF0aW9uKS50ZXN0KGFjdHVhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNhbGxlZFdpdGhFeGFjdGx5OiBmdW5jdGlvbiBjYWxsZWRXaXRoRXhhY3RseSgpIHtcbiAgICAgICAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09IHRoaXMuYXJncy5sZW5ndGggJiZcbiAgICAgICAgICAgICAgICB0aGlzLmNhbGxlZFdpdGguYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfSxcblxuICAgICAgICBub3RDYWxsZWRXaXRoOiBmdW5jdGlvbiBub3RDYWxsZWRXaXRoKCkge1xuICAgICAgICAgICAgcmV0dXJuICF0aGlzLmNhbGxlZFdpdGguYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfSxcblxuICAgICAgICBub3RDYWxsZWRXaXRoTWF0Y2g6IGZ1bmN0aW9uIG5vdENhbGxlZFdpdGhNYXRjaCgpIHtcbiAgICAgICAgICAgIHJldHVybiAhdGhpcy5jYWxsZWRXaXRoTWF0Y2guYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfSxcblxuICAgICAgICByZXR1cm5lZDogZnVuY3Rpb24gcmV0dXJuZWQodmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiBzaW5vbi5kZWVwRXF1YWwodmFsdWUsIHRoaXMucmV0dXJuVmFsdWUpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHRocmV3OiBmdW5jdGlvbiB0aHJldyhlcnJvcikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlcnJvciA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhdGhpcy5leGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gISF0aGlzLmV4Y2VwdGlvbjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhjZXB0aW9uID09PSBlcnJvciB8fCB0aGlzLmV4Y2VwdGlvbi5uYW1lID09PSBlcnJvcjtcbiAgICAgICAgfSxcblxuICAgICAgICBjYWxsZWRXaXRoTmV3OiBmdW5jdGlvbiBjYWxsZWRXaXRoTmV3KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJveHkucHJvdG90eXBlICYmIHRoaXMudGhpc1ZhbHVlIGluc3RhbmNlb2YgdGhpcy5wcm94eTtcbiAgICAgICAgfSxcblxuICAgICAgICBjYWxsZWRCZWZvcmU6IGZ1bmN0aW9uIChvdGhlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FsbElkIDwgb3RoZXIuY2FsbElkO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNhbGxlZEFmdGVyOiBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNhbGxJZCA+IG90aGVyLmNhbGxJZDtcbiAgICAgICAgfSxcblxuICAgICAgICBjYWxsQXJnOiBmdW5jdGlvbiAocG9zKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3NbcG9zXSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNhbGxBcmdPbjogZnVuY3Rpb24gKHBvcywgdGhpc1ZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3NbcG9zXS5hcHBseSh0aGlzVmFsdWUpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNhbGxBcmdXaXRoOiBmdW5jdGlvbiAocG9zKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxBcmdPbldpdGguYXBwbHkodGhpcywgW3BvcywgbnVsbF0uY29uY2F0KHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSkpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNhbGxBcmdPbldpdGg6IGZ1bmN0aW9uIChwb3MsIHRoaXNWYWx1ZSkge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgICAgICAgICB0aGlzLmFyZ3NbcG9zXS5hcHBseSh0aGlzVmFsdWUsIGFyZ3MpO1xuICAgICAgICB9LFxuXG4gICAgICAgIFwieWllbGRcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy55aWVsZE9uLmFwcGx5KHRoaXMsIFtudWxsXS5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgeWllbGRPbjogZnVuY3Rpb24gKHRoaXNWYWx1ZSkge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSB0aGlzLmFyZ3M7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGFyZ3MubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmdzW2ldID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgYXJnc1tpXS5hcHBseSh0aGlzVmFsdWUsIHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvd1lpZWxkRXJyb3IodGhpcy5wcm94eSwgXCIgY2Fubm90IHlpZWxkIHNpbmNlIG5vIGNhbGxiYWNrIHdhcyBwYXNzZWQuXCIsIGFyZ3MpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHlpZWxkVG86IGZ1bmN0aW9uIChwcm9wKSB7XG4gICAgICAgICAgICB0aGlzLnlpZWxkVG9Pbi5hcHBseSh0aGlzLCBbcHJvcCwgbnVsbF0uY29uY2F0KHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSkpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHlpZWxkVG9PbjogZnVuY3Rpb24gKHByb3AsIHRoaXNWYWx1ZSkge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSB0aGlzLmFyZ3M7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGFyZ3MubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFyZ3NbaV0gJiYgdHlwZW9mIGFyZ3NbaV1bcHJvcF0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBhcmdzW2ldW3Byb3BdLmFwcGx5KHRoaXNWYWx1ZSwgc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93WWllbGRFcnJvcih0aGlzLnByb3h5LCBcIiBjYW5ub3QgeWllbGQgdG8gJ1wiICsgcHJvcCArXG4gICAgICAgICAgICAgICAgXCInIHNpbmNlIG5vIGNhbGxiYWNrIHdhcyBwYXNzZWQuXCIsIGFyZ3MpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHRvU3RyaW5nOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgY2FsbFN0ciA9IHRoaXMucHJveHkudG9TdHJpbmcoKSArIFwiKFwiO1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBbXTtcblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLmFyZ3MubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgICAgICAgICAgICAgYXJncy5wdXNoKHNpbm9uLmZvcm1hdCh0aGlzLmFyZ3NbaV0pKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbFN0ciA9IGNhbGxTdHIgKyBhcmdzLmpvaW4oXCIsIFwiKSArIFwiKVwiO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMucmV0dXJuVmFsdWUgIT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIGNhbGxTdHIgKz0gXCIgPT4gXCIgKyBzaW5vbi5mb3JtYXQodGhpcy5yZXR1cm5WYWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICAgIGNhbGxTdHIgKz0gXCIgIVwiICsgdGhpcy5leGNlcHRpb24ubmFtZTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmV4Y2VwdGlvbi5tZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxTdHIgKz0gXCIoXCIgKyB0aGlzLmV4Y2VwdGlvbi5tZXNzYWdlICsgXCIpXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gY2FsbFN0cjtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBjYWxsUHJvdG8uaW52b2tlQ2FsbGJhY2sgPSBjYWxsUHJvdG8ueWllbGQ7XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVTcHlDYWxsKHNweSwgdGhpc1ZhbHVlLCBhcmdzLCByZXR1cm5WYWx1ZSwgZXhjZXB0aW9uLCBpZCkge1xuICAgICAgICBpZiAodHlwZW9mIGlkICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2FsbCBpZCBpcyBub3QgYSBudW1iZXJcIik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHByb3h5Q2FsbCA9IHNpbm9uLmNyZWF0ZShjYWxsUHJvdG8pO1xuICAgICAgICBwcm94eUNhbGwucHJveHkgPSBzcHk7XG4gICAgICAgIHByb3h5Q2FsbC50aGlzVmFsdWUgPSB0aGlzVmFsdWU7XG4gICAgICAgIHByb3h5Q2FsbC5hcmdzID0gYXJncztcbiAgICAgICAgcHJveHlDYWxsLnJldHVyblZhbHVlID0gcmV0dXJuVmFsdWU7XG4gICAgICAgIHByb3h5Q2FsbC5leGNlcHRpb24gPSBleGNlcHRpb247XG4gICAgICAgIHByb3h5Q2FsbC5jYWxsSWQgPSBpZDtcblxuICAgICAgICByZXR1cm4gcHJveHlDYWxsO1xuICAgIH1cbiAgICBjcmVhdGVTcHlDYWxsLnRvU3RyaW5nID0gY2FsbFByb3RvLnRvU3RyaW5nOyAvLyB1c2VkIGJ5IG1vY2tzXG5cbiAgICBzaW5vbi5zcHlDYWxsID0gY3JlYXRlU3B5Q2FsbDtcblxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoW1wibW9kdWxlXCJdLCBmdW5jdGlvbihtb2R1bGUpIHsgbW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVTcHlDYWxsOyB9KTtcbiAgICB9IGVsc2UgaWYgKGNvbW1vbkpTTW9kdWxlKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gY3JlYXRlU3B5Q2FsbDtcbiAgICB9XG59KHR5cGVvZiBzaW5vbiA9PSBcIm9iamVjdFwiICYmIHNpbm9uIHx8IG51bGwpKTtcblxuIiwiLyoqXG4gKiBAZGVwZW5kIC4uL3Npbm9uLmpzXG4gKiBAZGVwZW5kIHN0dWIuanNcbiAqIEBkZXBlbmQgbW9jay5qc1xuICovXG4vKmpzbGludCBlcWVxZXE6IGZhbHNlLCBvbmV2YXI6IGZhbHNlLCBmb3JpbjogdHJ1ZSovXG4vKmdsb2JhbCBtb2R1bGUsIHJlcXVpcmUsIHNpbm9uKi9cbi8qKlxuICogQ29sbGVjdGlvbnMgb2Ygc3R1YnMsIHNwaWVzIGFuZCBtb2Nrcy5cbiAqXG4gKiBAYXV0aG9yIENocmlzdGlhbiBKb2hhbnNlbiAoY2hyaXN0aWFuQGNqb2hhbnNlbi5ubylcbiAqIEBsaWNlbnNlIEJTRFxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIENocmlzdGlhbiBKb2hhbnNlblxuICovXG5cInVzZSBzdHJpY3RcIjtcblxuKGZ1bmN0aW9uIChzaW5vbikge1xuICAgIHZhciBjb21tb25KU01vZHVsZSA9IHR5cGVvZiBtb2R1bGUgIT09IFwidW5kZWZpbmVkXCIgJiYgbW9kdWxlLmV4cG9ydHMgJiYgdHlwZW9mIHJlcXVpcmUgPT0gXCJmdW5jdGlvblwiO1xuICAgIHZhciBwdXNoID0gW10ucHVzaDtcbiAgICB2YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4gICAgaWYgKCFzaW5vbiAmJiBjb21tb25KU01vZHVsZSkge1xuICAgICAgICBzaW5vbiA9IHJlcXVpcmUoXCIuLi9zaW5vblwiKTtcbiAgICB9XG5cbiAgICBpZiAoIXNpbm9uKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRGYWtlcyhmYWtlQ29sbGVjdGlvbikge1xuICAgICAgICBpZiAoIWZha2VDb2xsZWN0aW9uLmZha2VzKSB7XG4gICAgICAgICAgICBmYWtlQ29sbGVjdGlvbi5mYWtlcyA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZha2VDb2xsZWN0aW9uLmZha2VzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGVhY2goZmFrZUNvbGxlY3Rpb24sIG1ldGhvZCkge1xuICAgICAgICB2YXIgZmFrZXMgPSBnZXRGYWtlcyhmYWtlQ29sbGVjdGlvbik7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBmYWtlcy5sZW5ndGg7IGkgPCBsOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZmFrZXNbaV1bbWV0aG9kXSA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBmYWtlc1tpXVttZXRob2RdKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb21wYWN0KGZha2VDb2xsZWN0aW9uKSB7XG4gICAgICAgIHZhciBmYWtlcyA9IGdldEZha2VzKGZha2VDb2xsZWN0aW9uKTtcbiAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICB3aGlsZSAoaSA8IGZha2VzLmxlbmd0aCkge1xuICAgICAgICAgIGZha2VzLnNwbGljZShpLCAxKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBjb2xsZWN0aW9uID0ge1xuICAgICAgICB2ZXJpZnk6IGZ1bmN0aW9uIHJlc29sdmUoKSB7XG4gICAgICAgICAgICBlYWNoKHRoaXMsIFwidmVyaWZ5XCIpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHJlc3RvcmU6IGZ1bmN0aW9uIHJlc3RvcmUoKSB7XG4gICAgICAgICAgICBlYWNoKHRoaXMsIFwicmVzdG9yZVwiKTtcbiAgICAgICAgICAgIGNvbXBhY3QodGhpcyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgdmVyaWZ5QW5kUmVzdG9yZTogZnVuY3Rpb24gdmVyaWZ5QW5kUmVzdG9yZSgpIHtcbiAgICAgICAgICAgIHZhciBleGNlcHRpb247XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy52ZXJpZnkoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnJlc3RvcmUoKTtcblxuICAgICAgICAgICAgaWYgKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICAgIHRocm93IGV4Y2VwdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBhZGQ6IGZ1bmN0aW9uIGFkZChmYWtlKSB7XG4gICAgICAgICAgICBwdXNoLmNhbGwoZ2V0RmFrZXModGhpcyksIGZha2UpO1xuICAgICAgICAgICAgcmV0dXJuIGZha2U7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc3B5OiBmdW5jdGlvbiBzcHkoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGQoc2lub24uc3B5LmFwcGx5KHNpbm9uLCBhcmd1bWVudHMpKTtcbiAgICAgICAgfSxcblxuICAgICAgICBzdHViOiBmdW5jdGlvbiBzdHViKG9iamVjdCwgcHJvcGVydHksIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICB2YXIgb3JpZ2luYWwgPSBvYmplY3RbcHJvcGVydHldO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvcmlnaW5hbCAhPSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHN0dWIgbm9uLWV4aXN0ZW50IG93biBwcm9wZXJ0eSBcIiArIHByb3BlcnR5KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdFtwcm9wZXJ0eV0gPSB2YWx1ZTtcblxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdG9yZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdFtwcm9wZXJ0eV0gPSBvcmlnaW5hbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFwcm9wZXJ0eSAmJiAhIW9iamVjdCAmJiB0eXBlb2Ygb2JqZWN0ID09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3R1YmJlZE9iaiA9IHNpbm9uLnN0dWIuYXBwbHkoc2lub24sIGFyZ3VtZW50cyk7XG5cbiAgICAgICAgICAgICAgICBmb3IgKHZhciBwcm9wIGluIHN0dWJiZWRPYmopIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBzdHViYmVkT2JqW3Byb3BdID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkKHN0dWJiZWRPYmpbcHJvcF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0dWJiZWRPYmo7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFkZChzaW5vbi5zdHViLmFwcGx5KHNpbm9uLCBhcmd1bWVudHMpKTtcbiAgICAgICAgfSxcblxuICAgICAgICBtb2NrOiBmdW5jdGlvbiBtb2NrKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRkKHNpbm9uLm1vY2suYXBwbHkoc2lub24sIGFyZ3VtZW50cykpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGluamVjdDogZnVuY3Rpb24gaW5qZWN0KG9iaikge1xuICAgICAgICAgICAgdmFyIGNvbCA9IHRoaXM7XG5cbiAgICAgICAgICAgIG9iai5zcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbC5zcHkuYXBwbHkoY29sLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgb2JqLnN0dWIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbC5zdHViLmFwcGx5KGNvbCwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIG9iai5tb2NrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb2wubW9jay5hcHBseShjb2wsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHNpbm9uLmNvbGxlY3Rpb24gPSBjb2xsZWN0aW9uO1xuXG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShbXCJtb2R1bGVcIl0sIGZ1bmN0aW9uKG1vZHVsZSkgeyBtb2R1bGUuZXhwb3J0cyA9IGNvbGxlY3Rpb247IH0pO1xuICAgIH0gZWxzZSBpZiAoY29tbW9uSlNNb2R1bGUpIHtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBjb2xsZWN0aW9uO1xuICAgIH1cbn0odHlwZW9mIHNpbm9uID09IFwib2JqZWN0XCIgJiYgc2lub24gfHwgbnVsbCkpO1xuIiwiLyogQGRlcGVuZCAuLi9zaW5vbi5qcyAqL1xuLypqc2xpbnQgZXFlcWVxOiBmYWxzZSwgb25ldmFyOiBmYWxzZSwgcGx1c3BsdXM6IGZhbHNlKi9cbi8qZ2xvYmFsIG1vZHVsZSwgcmVxdWlyZSwgc2lub24qL1xuLyoqXG4gKiBNYXRjaCBmdW5jdGlvbnNcbiAqXG4gKiBAYXV0aG9yIE1heGltaWxpYW4gQW50b25pIChtYWlsQG1heGFudG9uaS5kZSlcbiAqIEBsaWNlbnNlIEJTRFxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMiBNYXhpbWlsaWFuIEFudG9uaVxuICovXG5cInVzZSBzdHJpY3RcIjtcblxuKGZ1bmN0aW9uIChzaW5vbikge1xuICAgIHZhciBjb21tb25KU01vZHVsZSA9IHR5cGVvZiBtb2R1bGUgIT09IFwidW5kZWZpbmVkXCIgJiYgbW9kdWxlLmV4cG9ydHMgJiYgdHlwZW9mIHJlcXVpcmUgPT0gXCJmdW5jdGlvblwiO1xuXG4gICAgaWYgKCFzaW5vbiAmJiBjb21tb25KU01vZHVsZSkge1xuICAgICAgICBzaW5vbiA9IHJlcXVpcmUoXCIuLi9zaW5vblwiKTtcbiAgICB9XG5cbiAgICBpZiAoIXNpbm9uKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhc3NlcnRUeXBlKHZhbHVlLCB0eXBlLCBuYW1lKSB7XG4gICAgICAgIHZhciBhY3R1YWwgPSBzaW5vbi50eXBlT2YodmFsdWUpO1xuICAgICAgICBpZiAoYWN0dWFsICE9PSB0eXBlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgdHlwZSBvZiBcIiArIG5hbWUgKyBcIiB0byBiZSBcIiArXG4gICAgICAgICAgICAgICAgdHlwZSArIFwiLCBidXQgd2FzIFwiICsgYWN0dWFsKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBtYXRjaGVyID0ge1xuICAgICAgICB0b1N0cmluZzogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWVzc2FnZTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBpc01hdGNoZXIob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBtYXRjaGVyLmlzUHJvdG90eXBlT2Yob2JqZWN0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXRjaE9iamVjdChleHBlY3RhdGlvbiwgYWN0dWFsKSB7XG4gICAgICAgIGlmIChhY3R1YWwgPT09IG51bGwgfHwgYWN0dWFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBrZXkgaW4gZXhwZWN0YXRpb24pIHtcbiAgICAgICAgICAgIGlmIChleHBlY3RhdGlvbi5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGV4cCA9IGV4cGVjdGF0aW9uW2tleV07XG4gICAgICAgICAgICAgICAgdmFyIGFjdCA9IGFjdHVhbFtrZXldO1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaC5pc01hdGNoZXIoZXhwKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWV4cC50ZXN0KGFjdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2lub24udHlwZU9mKGV4cCkgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRjaE9iamVjdChleHAsIGFjdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXNpbm9uLmRlZXBFcXVhbChleHAsIGFjdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBtYXRjaGVyLm9yID0gZnVuY3Rpb24gKG0yKSB7XG4gICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk1hdGNoZXIgZXhwZWN0ZWRcIik7XG4gICAgICAgIH0gZWxzZSBpZiAoIWlzTWF0Y2hlcihtMikpIHtcbiAgICAgICAgICAgIG0yID0gbWF0Y2gobTIpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtMSA9IHRoaXM7XG4gICAgICAgIHZhciBvciA9IHNpbm9uLmNyZWF0ZShtYXRjaGVyKTtcbiAgICAgICAgb3IudGVzdCA9IGZ1bmN0aW9uIChhY3R1YWwpIHtcbiAgICAgICAgICAgIHJldHVybiBtMS50ZXN0KGFjdHVhbCkgfHwgbTIudGVzdChhY3R1YWwpO1xuICAgICAgICB9O1xuICAgICAgICBvci5tZXNzYWdlID0gbTEubWVzc2FnZSArIFwiLm9yKFwiICsgbTIubWVzc2FnZSArIFwiKVwiO1xuICAgICAgICByZXR1cm4gb3I7XG4gICAgfTtcblxuICAgIG1hdGNoZXIuYW5kID0gZnVuY3Rpb24gKG0yKSB7XG4gICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk1hdGNoZXIgZXhwZWN0ZWRcIik7XG4gICAgICAgIH0gZWxzZSBpZiAoIWlzTWF0Y2hlcihtMikpIHtcbiAgICAgICAgICAgIG0yID0gbWF0Y2gobTIpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtMSA9IHRoaXM7XG4gICAgICAgIHZhciBhbmQgPSBzaW5vbi5jcmVhdGUobWF0Y2hlcik7XG4gICAgICAgIGFuZC50ZXN0ID0gZnVuY3Rpb24gKGFjdHVhbCkge1xuICAgICAgICAgICAgcmV0dXJuIG0xLnRlc3QoYWN0dWFsKSAmJiBtMi50ZXN0KGFjdHVhbCk7XG4gICAgICAgIH07XG4gICAgICAgIGFuZC5tZXNzYWdlID0gbTEubWVzc2FnZSArIFwiLmFuZChcIiArIG0yLm1lc3NhZ2UgKyBcIilcIjtcbiAgICAgICAgcmV0dXJuIGFuZDtcbiAgICB9O1xuXG4gICAgdmFyIG1hdGNoID0gZnVuY3Rpb24gKGV4cGVjdGF0aW9uLCBtZXNzYWdlKSB7XG4gICAgICAgIHZhciBtID0gc2lub24uY3JlYXRlKG1hdGNoZXIpO1xuICAgICAgICB2YXIgdHlwZSA9IHNpbm9uLnR5cGVPZihleHBlY3RhdGlvbik7XG4gICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICBpZiAodHlwZW9mIGV4cGVjdGF0aW9uLnRlc3QgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIG0udGVzdCA9IGZ1bmN0aW9uIChhY3R1YWwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4cGVjdGF0aW9uLnRlc3QoYWN0dWFsKSA9PT0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG0ubWVzc2FnZSA9IFwibWF0Y2goXCIgKyBzaW5vbi5mdW5jdGlvbk5hbWUoZXhwZWN0YXRpb24udGVzdCkgKyBcIilcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBzdHIgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBleHBlY3RhdGlvbikge1xuICAgICAgICAgICAgICAgIGlmIChleHBlY3RhdGlvbi5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0ci5wdXNoKGtleSArIFwiOiBcIiArIGV4cGVjdGF0aW9uW2tleV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG0udGVzdCA9IGZ1bmN0aW9uIChhY3R1YWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hPYmplY3QoZXhwZWN0YXRpb24sIGFjdHVhbCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgbS5tZXNzYWdlID0gXCJtYXRjaChcIiArIHN0ci5qb2luKFwiLCBcIikgKyBcIilcIjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICBtLnRlc3QgPSBmdW5jdGlvbiAoYWN0dWFsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV4cGVjdGF0aW9uID09IGFjdHVhbDtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAgbS50ZXN0ID0gZnVuY3Rpb24gKGFjdHVhbCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYWN0dWFsICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFjdHVhbC5pbmRleE9mKGV4cGVjdGF0aW9uKSAhPT0gLTE7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgbS5tZXNzYWdlID0gXCJtYXRjaChcXFwiXCIgKyBleHBlY3RhdGlvbiArIFwiXFxcIilcIjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwicmVnZXhwXCI6XG4gICAgICAgICAgICBtLnRlc3QgPSBmdW5jdGlvbiAoYWN0dWFsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhY3R1YWwgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZXhwZWN0YXRpb24udGVzdChhY3R1YWwpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiZnVuY3Rpb25cIjpcbiAgICAgICAgICAgIG0udGVzdCA9IGV4cGVjdGF0aW9uO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICBtLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtLm1lc3NhZ2UgPSBcIm1hdGNoKFwiICsgc2lub24uZnVuY3Rpb25OYW1lKGV4cGVjdGF0aW9uKSArIFwiKVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBtLnRlc3QgPSBmdW5jdGlvbiAoYWN0dWFsKSB7XG4gICAgICAgICAgICAgIHJldHVybiBzaW5vbi5kZWVwRXF1YWwoZXhwZWN0YXRpb24sIGFjdHVhbCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmICghbS5tZXNzYWdlKSB7XG4gICAgICAgICAgICBtLm1lc3NhZ2UgPSBcIm1hdGNoKFwiICsgZXhwZWN0YXRpb24gKyBcIilcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbTtcbiAgICB9O1xuXG4gICAgbWF0Y2guaXNNYXRjaGVyID0gaXNNYXRjaGVyO1xuXG4gICAgbWF0Y2guYW55ID0gbWF0Y2goZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LCBcImFueVwiKTtcblxuICAgIG1hdGNoLmRlZmluZWQgPSBtYXRjaChmdW5jdGlvbiAoYWN0dWFsKSB7XG4gICAgICAgIHJldHVybiBhY3R1YWwgIT09IG51bGwgJiYgYWN0dWFsICE9PSB1bmRlZmluZWQ7XG4gICAgfSwgXCJkZWZpbmVkXCIpO1xuXG4gICAgbWF0Y2gudHJ1dGh5ID0gbWF0Y2goZnVuY3Rpb24gKGFjdHVhbCkge1xuICAgICAgICByZXR1cm4gISFhY3R1YWw7XG4gICAgfSwgXCJ0cnV0aHlcIik7XG5cbiAgICBtYXRjaC5mYWxzeSA9IG1hdGNoKGZ1bmN0aW9uIChhY3R1YWwpIHtcbiAgICAgICAgcmV0dXJuICFhY3R1YWw7XG4gICAgfSwgXCJmYWxzeVwiKTtcblxuICAgIG1hdGNoLnNhbWUgPSBmdW5jdGlvbiAoZXhwZWN0YXRpb24pIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoKGZ1bmN0aW9uIChhY3R1YWwpIHtcbiAgICAgICAgICAgIHJldHVybiBleHBlY3RhdGlvbiA9PT0gYWN0dWFsO1xuICAgICAgICB9LCBcInNhbWUoXCIgKyBleHBlY3RhdGlvbiArIFwiKVwiKTtcbiAgICB9O1xuXG4gICAgbWF0Y2gudHlwZU9mID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgICAgYXNzZXJ0VHlwZSh0eXBlLCBcInN0cmluZ1wiLCBcInR5cGVcIik7XG4gICAgICAgIHJldHVybiBtYXRjaChmdW5jdGlvbiAoYWN0dWFsKSB7XG4gICAgICAgICAgICByZXR1cm4gc2lub24udHlwZU9mKGFjdHVhbCkgPT09IHR5cGU7XG4gICAgICAgIH0sIFwidHlwZU9mKFxcXCJcIiArIHR5cGUgKyBcIlxcXCIpXCIpO1xuICAgIH07XG5cbiAgICBtYXRjaC5pbnN0YW5jZU9mID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgICAgYXNzZXJ0VHlwZSh0eXBlLCBcImZ1bmN0aW9uXCIsIFwidHlwZVwiKTtcbiAgICAgICAgcmV0dXJuIG1hdGNoKGZ1bmN0aW9uIChhY3R1YWwpIHtcbiAgICAgICAgICAgIHJldHVybiBhY3R1YWwgaW5zdGFuY2VvZiB0eXBlO1xuICAgICAgICB9LCBcImluc3RhbmNlT2YoXCIgKyBzaW5vbi5mdW5jdGlvbk5hbWUodHlwZSkgKyBcIilcIik7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGNyZWF0ZVByb3BlcnR5TWF0Y2hlcihwcm9wZXJ0eVRlc3QsIG1lc3NhZ2VQcmVmaXgpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGFzc2VydFR5cGUocHJvcGVydHksIFwic3RyaW5nXCIsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAgICB2YXIgb25seVByb3BlcnR5ID0gYXJndW1lbnRzLmxlbmd0aCA9PT0gMTtcbiAgICAgICAgICAgIHZhciBtZXNzYWdlID0gbWVzc2FnZVByZWZpeCArIFwiKFxcXCJcIiArIHByb3BlcnR5ICsgXCJcXFwiXCI7XG4gICAgICAgICAgICBpZiAoIW9ubHlQcm9wZXJ0eSkge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgKz0gXCIsIFwiICsgdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtZXNzYWdlICs9IFwiKVwiO1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoKGZ1bmN0aW9uIChhY3R1YWwpIHtcbiAgICAgICAgICAgICAgICBpZiAoYWN0dWFsID09PSB1bmRlZmluZWQgfHwgYWN0dWFsID09PSBudWxsIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAhcHJvcGVydHlUZXN0KGFjdHVhbCwgcHJvcGVydHkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9ubHlQcm9wZXJ0eSB8fCBzaW5vbi5kZWVwRXF1YWwodmFsdWUsIGFjdHVhbFtwcm9wZXJ0eV0pO1xuICAgICAgICAgICAgfSwgbWVzc2FnZSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgbWF0Y2guaGFzID0gY3JlYXRlUHJvcGVydHlNYXRjaGVyKGZ1bmN0aW9uIChhY3R1YWwsIHByb3BlcnR5KSB7XG4gICAgICAgIGlmICh0eXBlb2YgYWN0dWFsID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvcGVydHkgaW4gYWN0dWFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY3R1YWxbcHJvcGVydHldICE9PSB1bmRlZmluZWQ7XG4gICAgfSwgXCJoYXNcIik7XG5cbiAgICBtYXRjaC5oYXNPd24gPSBjcmVhdGVQcm9wZXJ0eU1hdGNoZXIoZnVuY3Rpb24gKGFjdHVhbCwgcHJvcGVydHkpIHtcbiAgICAgICAgcmV0dXJuIGFjdHVhbC5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eSk7XG4gICAgfSwgXCJoYXNPd25cIik7XG5cbiAgICBtYXRjaC5ib29sID0gbWF0Y2gudHlwZU9mKFwiYm9vbGVhblwiKTtcbiAgICBtYXRjaC5udW1iZXIgPSBtYXRjaC50eXBlT2YoXCJudW1iZXJcIik7XG4gICAgbWF0Y2guc3RyaW5nID0gbWF0Y2gudHlwZU9mKFwic3RyaW5nXCIpO1xuICAgIG1hdGNoLm9iamVjdCA9IG1hdGNoLnR5cGVPZihcIm9iamVjdFwiKTtcbiAgICBtYXRjaC5mdW5jID0gbWF0Y2gudHlwZU9mKFwiZnVuY3Rpb25cIik7XG4gICAgbWF0Y2guYXJyYXkgPSBtYXRjaC50eXBlT2YoXCJhcnJheVwiKTtcbiAgICBtYXRjaC5yZWdleHAgPSBtYXRjaC50eXBlT2YoXCJyZWdleHBcIik7XG4gICAgbWF0Y2guZGF0ZSA9IG1hdGNoLnR5cGVPZihcImRhdGVcIik7XG5cbiAgICBzaW5vbi5tYXRjaCA9IG1hdGNoO1xuXG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShbXCJtb2R1bGVcIl0sIGZ1bmN0aW9uKG1vZHVsZSkgeyBtb2R1bGUuZXhwb3J0cyA9IG1hdGNoOyB9KTtcbiAgICB9IGVsc2UgaWYgKGNvbW1vbkpTTW9kdWxlKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gbWF0Y2g7XG4gICAgfVxufSh0eXBlb2Ygc2lub24gPT0gXCJvYmplY3RcIiAmJiBzaW5vbiB8fCBudWxsKSk7XG4iLCIvKipcbiAqIEBkZXBlbmQgLi4vc2lub24uanNcbiAqIEBkZXBlbmQgc3R1Yi5qc1xuICovXG4vKmpzbGludCBlcWVxZXE6IGZhbHNlLCBvbmV2YXI6IGZhbHNlLCBub21lbjogZmFsc2UqL1xuLypnbG9iYWwgbW9kdWxlLCByZXF1aXJlLCBzaW5vbiovXG4vKipcbiAqIE1vY2sgZnVuY3Rpb25zLlxuICpcbiAqIEBhdXRob3IgQ2hyaXN0aWFuIEpvaGFuc2VuIChjaHJpc3RpYW5AY2pvaGFuc2VuLm5vKVxuICogQGxpY2Vuc2UgQlNEXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTMgQ2hyaXN0aWFuIEpvaGFuc2VuXG4gKi9cblwidXNlIHN0cmljdFwiO1xuXG4oZnVuY3Rpb24gKHNpbm9uKSB7XG4gICAgdmFyIGNvbW1vbkpTTW9kdWxlID0gdHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUuZXhwb3J0cyAmJiB0eXBlb2YgcmVxdWlyZSA9PSBcImZ1bmN0aW9uXCI7XG4gICAgdmFyIHB1c2ggPSBbXS5wdXNoO1xuICAgIHZhciBtYXRjaDtcblxuICAgIGlmICghc2lub24gJiYgY29tbW9uSlNNb2R1bGUpIHtcbiAgICAgICAgc2lub24gPSByZXF1aXJlKFwiLi4vc2lub25cIik7XG4gICAgfVxuXG4gICAgaWYgKCFzaW5vbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbWF0Y2ggPSBzaW5vbi5tYXRjaDtcblxuICAgIGlmICghbWF0Y2ggJiYgY29tbW9uSlNNb2R1bGUpIHtcbiAgICAgICAgbWF0Y2ggPSByZXF1aXJlKFwiLi9tYXRjaFwiKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb2NrKG9iamVjdCkge1xuICAgICAgICBpZiAoIW9iamVjdCkge1xuICAgICAgICAgICAgcmV0dXJuIHNpbm9uLmV4cGVjdGF0aW9uLmNyZWF0ZShcIkFub255bW91cyBtb2NrXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1vY2suY3JlYXRlKG9iamVjdCk7XG4gICAgfVxuXG4gICAgc2lub24ubW9jayA9IG1vY2s7XG5cbiAgICBzaW5vbi5leHRlbmQobW9jaywgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZnVuY3Rpb24gZWFjaChjb2xsZWN0aW9uLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaWYgKCFjb2xsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGNvbGxlY3Rpb24ubGVuZ3RoOyBpIDwgbDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soY29sbGVjdGlvbltpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlOiBmdW5jdGlvbiBjcmVhdGUob2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFvYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIm9iamVjdCBpcyBudWxsXCIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciBtb2NrT2JqZWN0ID0gc2lub24uZXh0ZW5kKHt9LCBtb2NrKTtcbiAgICAgICAgICAgICAgICBtb2NrT2JqZWN0Lm9iamVjdCA9IG9iamVjdDtcbiAgICAgICAgICAgICAgICBkZWxldGUgbW9ja09iamVjdC5jcmVhdGU7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gbW9ja09iamVjdDtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIGV4cGVjdHM6IGZ1bmN0aW9uIGV4cGVjdHMobWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFtZXRob2QpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIm1ldGhvZCBpcyBmYWxzeVwiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZXhwZWN0YXRpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhwZWN0YXRpb25zID0ge307XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJveGllcyA9IFtdO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5leHBlY3RhdGlvbnNbbWV0aG9kXSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4cGVjdGF0aW9uc1ttZXRob2RdID0gW107XG4gICAgICAgICAgICAgICAgICAgIHZhciBtb2NrT2JqZWN0ID0gdGhpcztcblxuICAgICAgICAgICAgICAgICAgICBzaW5vbi53cmFwTWV0aG9kKHRoaXMub2JqZWN0LCBtZXRob2QsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtb2NrT2JqZWN0Lmludm9rZU1ldGhvZChtZXRob2QsIHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHB1c2guY2FsbCh0aGlzLnByb3hpZXMsIG1ldGhvZCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIGV4cGVjdGF0aW9uID0gc2lub24uZXhwZWN0YXRpb24uY3JlYXRlKG1ldGhvZCk7XG4gICAgICAgICAgICAgICAgcHVzaC5jYWxsKHRoaXMuZXhwZWN0YXRpb25zW21ldGhvZF0sIGV4cGVjdGF0aW9uKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBleHBlY3RhdGlvbjtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIHJlc3RvcmU6IGZ1bmN0aW9uIHJlc3RvcmUoKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9iamVjdCA9IHRoaXMub2JqZWN0O1xuXG4gICAgICAgICAgICAgICAgZWFjaCh0aGlzLnByb3hpZXMsIGZ1bmN0aW9uIChwcm94eSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdFtwcm94eV0ucmVzdG9yZSA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdFtwcm94eV0ucmVzdG9yZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICB2ZXJpZnk6IGZ1bmN0aW9uIHZlcmlmeSgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXhwZWN0YXRpb25zID0gdGhpcy5leHBlY3RhdGlvbnMgfHwge307XG4gICAgICAgICAgICAgICAgdmFyIG1lc3NhZ2VzID0gW10sIG1ldCA9IFtdO1xuXG4gICAgICAgICAgICAgICAgZWFjaCh0aGlzLnByb3hpZXMsIGZ1bmN0aW9uIChwcm94eSkge1xuICAgICAgICAgICAgICAgICAgICBlYWNoKGV4cGVjdGF0aW9uc1twcm94eV0sIGZ1bmN0aW9uIChleHBlY3RhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFleHBlY3RhdGlvbi5tZXQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1c2guY2FsbChtZXNzYWdlcywgZXhwZWN0YXRpb24udG9TdHJpbmcoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1c2guY2FsbChtZXQsIGV4cGVjdGF0aW9uLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHRoaXMucmVzdG9yZSgpO1xuXG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgc2lub24uZXhwZWN0YXRpb24uZmFpbChtZXNzYWdlcy5jb25jYXQobWV0KS5qb2luKFwiXFxuXCIpKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzaW5vbi5leHBlY3RhdGlvbi5wYXNzKG1lc3NhZ2VzLmNvbmNhdChtZXQpLmpvaW4oXCJcXG5cIikpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgaW52b2tlTWV0aG9kOiBmdW5jdGlvbiBpbnZva2VNZXRob2QobWV0aG9kLCB0aGlzVmFsdWUsIGFyZ3MpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXhwZWN0YXRpb25zID0gdGhpcy5leHBlY3RhdGlvbnMgJiYgdGhpcy5leHBlY3RhdGlvbnNbbWV0aG9kXTtcbiAgICAgICAgICAgICAgICB2YXIgbGVuZ3RoID0gZXhwZWN0YXRpb25zICYmIGV4cGVjdGF0aW9ucy5sZW5ndGggfHwgMCwgaTtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWV4cGVjdGF0aW9uc1tpXS5tZXQoKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0YXRpb25zW2ldLmFsbG93c0NhbGwodGhpc1ZhbHVlLCBhcmdzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4cGVjdGF0aW9uc1tpXS5hcHBseSh0aGlzVmFsdWUsIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIG1lc3NhZ2VzID0gW10sIGF2YWlsYWJsZSwgZXhoYXVzdGVkID0gMDtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXhwZWN0YXRpb25zW2ldLmFsbG93c0NhbGwodGhpc1ZhbHVlLCBhcmdzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmxlID0gYXZhaWxhYmxlIHx8IGV4cGVjdGF0aW9uc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aGF1c3RlZCArPSAxO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHB1c2guY2FsbChtZXNzYWdlcywgXCIgICAgXCIgKyBleHBlY3RhdGlvbnNbaV0udG9TdHJpbmcoKSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGV4aGF1c3RlZCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXZhaWxhYmxlLmFwcGx5KHRoaXNWYWx1ZSwgYXJncyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbWVzc2FnZXMudW5zaGlmdChcIlVuZXhwZWN0ZWQgY2FsbDogXCIgKyBzaW5vbi5zcHlDYWxsLnRvU3RyaW5nLmNhbGwoe1xuICAgICAgICAgICAgICAgICAgICBwcm94eTogbWV0aG9kLFxuICAgICAgICAgICAgICAgICAgICBhcmdzOiBhcmdzXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgICAgc2lub24uZXhwZWN0YXRpb24uZmFpbChtZXNzYWdlcy5qb2luKFwiXFxuXCIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KCkpKTtcblxuICAgIHZhciB0aW1lcyA9IHNpbm9uLnRpbWVzSW5Xb3JkcztcblxuICAgIHNpbm9uLmV4cGVjdGF0aW9uID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuICAgICAgICB2YXIgX2ludm9rZSA9IHNpbm9uLnNweS5pbnZva2U7XG5cbiAgICAgICAgZnVuY3Rpb24gY2FsbENvdW50SW5Xb3JkcyhjYWxsQ291bnQpIHtcbiAgICAgICAgICAgIGlmIChjYWxsQ291bnQgPT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBcIm5ldmVyIGNhbGxlZFwiO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJjYWxsZWQgXCIgKyB0aW1lcyhjYWxsQ291bnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gZXhwZWN0ZWRDYWxsQ291bnRJbldvcmRzKGV4cGVjdGF0aW9uKSB7XG4gICAgICAgICAgICB2YXIgbWluID0gZXhwZWN0YXRpb24ubWluQ2FsbHM7XG4gICAgICAgICAgICB2YXIgbWF4ID0gZXhwZWN0YXRpb24ubWF4Q2FsbHM7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWluID09IFwibnVtYmVyXCIgJiYgdHlwZW9mIG1heCA9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0ciA9IHRpbWVzKG1pbik7XG5cbiAgICAgICAgICAgICAgICBpZiAobWluICE9IG1heCkge1xuICAgICAgICAgICAgICAgICAgICBzdHIgPSBcImF0IGxlYXN0IFwiICsgc3RyICsgXCIgYW5kIGF0IG1vc3QgXCIgKyB0aW1lcyhtYXgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBzdHI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWluID09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJhdCBsZWFzdCBcIiArIHRpbWVzKG1pbik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBcImF0IG1vc3QgXCIgKyB0aW1lcyhtYXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gcmVjZWl2ZWRNaW5DYWxscyhleHBlY3RhdGlvbikge1xuICAgICAgICAgICAgdmFyIGhhc01pbkxpbWl0ID0gdHlwZW9mIGV4cGVjdGF0aW9uLm1pbkNhbGxzID09IFwibnVtYmVyXCI7XG4gICAgICAgICAgICByZXR1cm4gIWhhc01pbkxpbWl0IHx8IGV4cGVjdGF0aW9uLmNhbGxDb3VudCA+PSBleHBlY3RhdGlvbi5taW5DYWxscztcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHJlY2VpdmVkTWF4Q2FsbHMoZXhwZWN0YXRpb24pIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZXhwZWN0YXRpb24ubWF4Q2FsbHMgIT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGV4cGVjdGF0aW9uLmNhbGxDb3VudCA9PSBleHBlY3RhdGlvbi5tYXhDYWxscztcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHZlcmlmeU1hdGNoZXIocG9zc2libGVNYXRjaGVyLCBhcmcpe1xuICAgICAgICAgICAgaWYgKG1hdGNoICYmIG1hdGNoLmlzTWF0Y2hlcihwb3NzaWJsZU1hdGNoZXIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc3NpYmxlTWF0Y2hlci50ZXN0KGFyZyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG1pbkNhbGxzOiAxLFxuICAgICAgICAgICAgbWF4Q2FsbHM6IDEsXG5cbiAgICAgICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKG1ldGhvZE5hbWUpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXhwZWN0YXRpb24gPSBzaW5vbi5leHRlbmQoc2lub24uc3R1Yi5jcmVhdGUoKSwgc2lub24uZXhwZWN0YXRpb24pO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBleHBlY3RhdGlvbi5jcmVhdGU7XG4gICAgICAgICAgICAgICAgZXhwZWN0YXRpb24ubWV0aG9kID0gbWV0aG9kTmFtZTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBleHBlY3RhdGlvbjtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIGludm9rZTogZnVuY3Rpb24gaW52b2tlKGZ1bmMsIHRoaXNWYWx1ZSwgYXJncykge1xuICAgICAgICAgICAgICAgIHRoaXMudmVyaWZ5Q2FsbEFsbG93ZWQodGhpc1ZhbHVlLCBhcmdzKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBfaW52b2tlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBhdExlYXN0OiBmdW5jdGlvbiBhdExlYXN0KG51bSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbnVtICE9IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidcIiArIG51bSArIFwiJyBpcyBub3QgbnVtYmVyXCIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5saW1pdHNTZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXhDYWxscyA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGltaXRzU2V0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLm1pbkNhbGxzID0gbnVtO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBhdE1vc3Q6IGZ1bmN0aW9uIGF0TW9zdChudW0pIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG51bSAhPSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInXCIgKyBudW0gKyBcIicgaXMgbm90IG51bWJlclwiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubGltaXRzU2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWluQ2FsbHMgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxpbWl0c1NldCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5tYXhDYWxscyA9IG51bTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgbmV2ZXI6IGZ1bmN0aW9uIG5ldmVyKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmV4YWN0bHkoMCk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBvbmNlOiBmdW5jdGlvbiBvbmNlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmV4YWN0bHkoMSk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICB0d2ljZTogZnVuY3Rpb24gdHdpY2UoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhhY3RseSgyKTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIHRocmljZTogZnVuY3Rpb24gdGhyaWNlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmV4YWN0bHkoMyk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBleGFjdGx5OiBmdW5jdGlvbiBleGFjdGx5KG51bSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbnVtICE9IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidcIiArIG51bSArIFwiJyBpcyBub3QgYSBudW1iZXJcIik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5hdExlYXN0KG51bSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYXRNb3N0KG51bSk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBtZXQ6IGZ1bmN0aW9uIG1ldCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gIXRoaXMuZmFpbGVkICYmIHJlY2VpdmVkTWluQ2FsbHModGhpcyk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICB2ZXJpZnlDYWxsQWxsb3dlZDogZnVuY3Rpb24gdmVyaWZ5Q2FsbEFsbG93ZWQodGhpc1ZhbHVlLCBhcmdzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlY2VpdmVkTWF4Q2FsbHModGhpcykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWlsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBzaW5vbi5leHBlY3RhdGlvbi5mYWlsKHRoaXMubWV0aG9kICsgXCIgYWxyZWFkeSBjYWxsZWQgXCIgKyB0aW1lcyh0aGlzLm1heENhbGxzKSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKFwiZXhwZWN0ZWRUaGlzXCIgaW4gdGhpcyAmJiB0aGlzLmV4cGVjdGVkVGhpcyAhPT0gdGhpc1ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHNpbm9uLmV4cGVjdGF0aW9uLmZhaWwodGhpcy5tZXRob2QgKyBcIiBjYWxsZWQgd2l0aCBcIiArIHRoaXNWYWx1ZSArIFwiIGFzIHRoaXNWYWx1ZSwgZXhwZWN0ZWQgXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5leHBlY3RlZFRoaXMpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghKFwiZXhwZWN0ZWRBcmd1bWVudHNcIiBpbiB0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCFhcmdzKSB7XG4gICAgICAgICAgICAgICAgICAgIHNpbm9uLmV4cGVjdGF0aW9uLmZhaWwodGhpcy5tZXRob2QgKyBcIiByZWNlaXZlZCBubyBhcmd1bWVudHMsIGV4cGVjdGVkIFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbm9uLmZvcm1hdCh0aGlzLmV4cGVjdGVkQXJndW1lbnRzKSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgdGhpcy5leHBlY3RlZEFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgc2lub24uZXhwZWN0YXRpb24uZmFpbCh0aGlzLm1ldGhvZCArIFwiIHJlY2VpdmVkIHRvbyBmZXcgYXJndW1lbnRzIChcIiArIHNpbm9uLmZvcm1hdChhcmdzKSArXG4gICAgICAgICAgICAgICAgICAgICAgICBcIiksIGV4cGVjdGVkIFwiICsgc2lub24uZm9ybWF0KHRoaXMuZXhwZWN0ZWRBcmd1bWVudHMpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5leHBlY3RzRXhhY3RBcmdDb3VudCAmJlxuICAgICAgICAgICAgICAgICAgICBhcmdzLmxlbmd0aCAhPSB0aGlzLmV4cGVjdGVkQXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBzaW5vbi5leHBlY3RhdGlvbi5mYWlsKHRoaXMubWV0aG9kICsgXCIgcmVjZWl2ZWQgdG9vIG1hbnkgYXJndW1lbnRzIChcIiArIHNpbm9uLmZvcm1hdChhcmdzKSArXG4gICAgICAgICAgICAgICAgICAgICAgICBcIiksIGV4cGVjdGVkIFwiICsgc2lub24uZm9ybWF0KHRoaXMuZXhwZWN0ZWRBcmd1bWVudHMpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuZXhwZWN0ZWRBcmd1bWVudHMubGVuZ3RoOyBpIDwgbDsgaSArPSAxKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCF2ZXJpZnlNYXRjaGVyKHRoaXMuZXhwZWN0ZWRBcmd1bWVudHNbaV0sYXJnc1tpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbm9uLmV4cGVjdGF0aW9uLmZhaWwodGhpcy5tZXRob2QgKyBcIiByZWNlaXZlZCB3cm9uZyBhcmd1bWVudHMgXCIgKyBzaW5vbi5mb3JtYXQoYXJncykgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiLCBkaWRuJ3QgbWF0Y2ggXCIgKyB0aGlzLmV4cGVjdGVkQXJndW1lbnRzLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzaW5vbi5kZWVwRXF1YWwodGhpcy5leHBlY3RlZEFyZ3VtZW50c1tpXSwgYXJnc1tpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbm9uLmV4cGVjdGF0aW9uLmZhaWwodGhpcy5tZXRob2QgKyBcIiByZWNlaXZlZCB3cm9uZyBhcmd1bWVudHMgXCIgKyBzaW5vbi5mb3JtYXQoYXJncykgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiLCBleHBlY3RlZCBcIiArIHNpbm9uLmZvcm1hdCh0aGlzLmV4cGVjdGVkQXJndW1lbnRzKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBhbGxvd3NDYWxsOiBmdW5jdGlvbiBhbGxvd3NDYWxsKHRoaXNWYWx1ZSwgYXJncykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLm1ldCgpICYmIHJlY2VpdmVkTWF4Q2FsbHModGhpcykpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChcImV4cGVjdGVkVGhpc1wiIGluIHRoaXMgJiYgdGhpcy5leHBlY3RlZFRoaXMgIT09IHRoaXNWYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCEoXCJleHBlY3RlZEFyZ3VtZW50c1wiIGluIHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmdzIHx8IFtdO1xuXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgdGhpcy5leHBlY3RlZEFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmV4cGVjdHNFeGFjdEFyZ0NvdW50ICYmXG4gICAgICAgICAgICAgICAgICAgIGFyZ3MubGVuZ3RoICE9IHRoaXMuZXhwZWN0ZWRBcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuZXhwZWN0ZWRBcmd1bWVudHMubGVuZ3RoOyBpIDwgbDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdmVyaWZ5TWF0Y2hlcih0aGlzLmV4cGVjdGVkQXJndW1lbnRzW2ldLGFyZ3NbaV0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoIXNpbm9uLmRlZXBFcXVhbCh0aGlzLmV4cGVjdGVkQXJndW1lbnRzW2ldLCBhcmdzW2ldKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICB3aXRoQXJnczogZnVuY3Rpb24gd2l0aEFyZ3MoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5leHBlY3RlZEFyZ3VtZW50cyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIHdpdGhFeGFjdEFyZ3M6IGZ1bmN0aW9uIHdpdGhFeGFjdEFyZ3MoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy53aXRoQXJncy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgIHRoaXMuZXhwZWN0c0V4YWN0QXJnQ291bnQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgb246IGZ1bmN0aW9uIG9uKHRoaXNWYWx1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZXhwZWN0ZWRUaGlzID0gdGhpc1ZhbHVlO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgdG9TdHJpbmc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXJncyA9ICh0aGlzLmV4cGVjdGVkQXJndW1lbnRzIHx8IFtdKS5zbGljZSgpO1xuXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmV4cGVjdHNFeGFjdEFyZ0NvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHB1c2guY2FsbChhcmdzLCBcIlsuLi5dXCIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciBjYWxsU3RyID0gc2lub24uc3B5Q2FsbC50b1N0cmluZy5jYWxsKHtcbiAgICAgICAgICAgICAgICAgICAgcHJveHk6IHRoaXMubWV0aG9kIHx8IFwiYW5vbnltb3VzIG1vY2sgZXhwZWN0YXRpb25cIixcbiAgICAgICAgICAgICAgICAgICAgYXJnczogYXJnc1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBjYWxsU3RyLnJlcGxhY2UoXCIsIFsuLi5cIiwgXCJbLCAuLi5cIikgKyBcIiBcIiArXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkQ2FsbENvdW50SW5Xb3Jkcyh0aGlzKTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm1ldCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIkV4cGVjdGF0aW9uIG1ldDogXCIgKyBtZXNzYWdlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBcIkV4cGVjdGVkIFwiICsgbWVzc2FnZSArIFwiIChcIiArXG4gICAgICAgICAgICAgICAgICAgIGNhbGxDb3VudEluV29yZHModGhpcy5jYWxsQ291bnQpICsgXCIpXCI7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICB2ZXJpZnk6IGZ1bmN0aW9uIHZlcmlmeSgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubWV0KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgc2lub24uZXhwZWN0YXRpb24uZmFpbCh0aGlzLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNpbm9uLmV4cGVjdGF0aW9uLnBhc3ModGhpcy50b1N0cmluZygpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIHBhc3M6IGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgc2lub24uYXNzZXJ0LnBhc3MobWVzc2FnZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZmFpbDogZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXhjZXB0aW9uID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5uYW1lID0gXCJFeHBlY3RhdGlvbkVycm9yXCI7XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBleGNlcHRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSgpKTtcblxuICAgIHNpbm9uLm1vY2sgPSBtb2NrO1xuXG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShbXCJtb2R1bGVcIl0sIGZ1bmN0aW9uKG1vZHVsZSkgeyBtb2R1bGUuZXhwb3J0cyA9IG1vY2s7IH0pO1xuICAgIH0gZWxzZSBpZiAoY29tbW9uSlNNb2R1bGUpIHtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBtb2NrO1xuICAgIH1cbn0odHlwZW9mIHNpbm9uID09IFwib2JqZWN0XCIgJiYgc2lub24gfHwgbnVsbCkpO1xuIiwiLyoqXG4gKiBAZGVwZW5kIC4uL3Npbm9uLmpzXG4gKiBAZGVwZW5kIGNvbGxlY3Rpb24uanNcbiAqIEBkZXBlbmQgdXRpbC9mYWtlX3RpbWVycy5qc1xuICogQGRlcGVuZCB1dGlsL2Zha2Vfc2VydmVyX3dpdGhfY2xvY2suanNcbiAqL1xuLypqc2xpbnQgZXFlcWVxOiBmYWxzZSwgb25ldmFyOiBmYWxzZSwgcGx1c3BsdXM6IGZhbHNlKi9cbi8qZ2xvYmFsIHJlcXVpcmUsIG1vZHVsZSovXG4vKipcbiAqIE1hbmFnZXMgZmFrZSBjb2xsZWN0aW9ucyBhcyB3ZWxsIGFzIGZha2UgdXRpbGl0aWVzIHN1Y2ggYXMgU2lub24nc1xuICogdGltZXJzIGFuZCBmYWtlIFhIUiBpbXBsZW1lbnRhdGlvbiBpbiBvbmUgY29udmVuaWVudCBvYmplY3QuXG4gKlxuICogQGF1dGhvciBDaHJpc3RpYW4gSm9oYW5zZW4gKGNocmlzdGlhbkBjam9oYW5zZW4ubm8pXG4gKiBAbGljZW5zZSBCU0RcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMyBDaHJpc3RpYW4gSm9oYW5zZW5cbiAqL1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbmlmICh0eXBlb2YgbW9kdWxlICE9PSBcInVuZGVmaW5lZFwiICYmIG1vZHVsZS5leHBvcnRzICYmIHR5cGVvZiByZXF1aXJlID09IFwiZnVuY3Rpb25cIikge1xuICAgIHZhciBzaW5vbiA9IHJlcXVpcmUoXCIuLi9zaW5vblwiKTtcbiAgICBzaW5vbi5leHRlbmQoc2lub24sIHJlcXVpcmUoXCIuL3V0aWwvZmFrZV90aW1lcnNcIikpO1xufVxuXG4oZnVuY3Rpb24gKCkge1xuICAgIHZhciBwdXNoID0gW10ucHVzaDtcblxuICAgIGZ1bmN0aW9uIGV4cG9zZVZhbHVlKHNhbmRib3gsIGNvbmZpZywga2V5LCB2YWx1ZSkge1xuICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLmluamVjdEludG8gJiYgIShrZXkgaW4gY29uZmlnLmluamVjdEludG8pKSB7XG4gICAgICAgICAgICBjb25maWcuaW5qZWN0SW50b1trZXldID0gdmFsdWU7XG4gICAgICAgICAgICBzYW5kYm94LmluamVjdGVkS2V5cy5wdXNoKGtleSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwdXNoLmNhbGwoc2FuZGJveC5hcmdzLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVwYXJlU2FuZGJveEZyb21Db25maWcoY29uZmlnKSB7XG4gICAgICAgIHZhciBzYW5kYm94ID0gc2lub24uY3JlYXRlKHNpbm9uLnNhbmRib3gpO1xuXG4gICAgICAgIGlmIChjb25maWcudXNlRmFrZVNlcnZlcikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjb25maWcudXNlRmFrZVNlcnZlciA9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgc2FuZGJveC5zZXJ2ZXJQcm90b3R5cGUgPSBjb25maWcudXNlRmFrZVNlcnZlcjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2FuZGJveC51c2VGYWtlU2VydmVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLnVzZUZha2VUaW1lcnMpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY29uZmlnLnVzZUZha2VUaW1lcnMgPT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgIHNhbmRib3gudXNlRmFrZVRpbWVycy5hcHBseShzYW5kYm94LCBjb25maWcudXNlRmFrZVRpbWVycyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNhbmRib3gudXNlRmFrZVRpbWVycygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgfVxuXG4gICAgc2lub24uc2FuZGJveCA9IHNpbm9uLmV4dGVuZChzaW5vbi5jcmVhdGUoc2lub24uY29sbGVjdGlvbiksIHtcbiAgICAgICAgdXNlRmFrZVRpbWVyczogZnVuY3Rpb24gdXNlRmFrZVRpbWVycygpIHtcbiAgICAgICAgICAgIHRoaXMuY2xvY2sgPSBzaW5vbi51c2VGYWtlVGltZXJzLmFwcGx5KHNpbm9uLCBhcmd1bWVudHMpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGQodGhpcy5jbG9jayk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2VydmVyUHJvdG90eXBlOiBzaW5vbi5mYWtlU2VydmVyLFxuXG4gICAgICAgIHVzZUZha2VTZXJ2ZXI6IGZ1bmN0aW9uIHVzZUZha2VTZXJ2ZXIoKSB7XG4gICAgICAgICAgICB2YXIgcHJvdG8gPSB0aGlzLnNlcnZlclByb3RvdHlwZSB8fCBzaW5vbi5mYWtlU2VydmVyO1xuXG4gICAgICAgICAgICBpZiAoIXByb3RvIHx8ICFwcm90by5jcmVhdGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5zZXJ2ZXIgPSBwcm90by5jcmVhdGUoKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFkZCh0aGlzLnNlcnZlcik7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaW5qZWN0OiBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICBzaW5vbi5jb2xsZWN0aW9uLmluamVjdC5jYWxsKHRoaXMsIG9iaik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmNsb2NrKSB7XG4gICAgICAgICAgICAgICAgb2JqLmNsb2NrID0gdGhpcy5jbG9jaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuc2VydmVyKSB7XG4gICAgICAgICAgICAgICAgb2JqLnNlcnZlciA9IHRoaXMuc2VydmVyO1xuICAgICAgICAgICAgICAgIG9iai5yZXF1ZXN0cyA9IHRoaXMuc2VydmVyLnJlcXVlc3RzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9LFxuXG4gICAgICAgIHJlc3RvcmU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNpbm9uLmNvbGxlY3Rpb24ucmVzdG9yZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgdGhpcy5yZXN0b3JlQ29udGV4dCgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHJlc3RvcmVDb250ZXh0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pbmplY3RlZEtleXMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaiA9IHRoaXMuaW5qZWN0ZWRLZXlzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbmplY3RJbnRvW3RoaXMuaW5qZWN0ZWRLZXlzW2ldXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5pbmplY3RlZEtleXMgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBjcmVhdGU6IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICAgICAgICAgIGlmICghY29uZmlnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNpbm9uLmNyZWF0ZShzaW5vbi5zYW5kYm94KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHNhbmRib3ggPSBwcmVwYXJlU2FuZGJveEZyb21Db25maWcoY29uZmlnKTtcbiAgICAgICAgICAgIHNhbmRib3guYXJncyA9IHNhbmRib3guYXJncyB8fCBbXTtcbiAgICAgICAgICAgIHNhbmRib3guaW5qZWN0ZWRLZXlzID0gW107XG4gICAgICAgICAgICBzYW5kYm94LmluamVjdEludG8gPSBjb25maWcuaW5qZWN0SW50bztcbiAgICAgICAgICAgIHZhciBwcm9wLCB2YWx1ZSwgZXhwb3NlZCA9IHNhbmRib3guaW5qZWN0KHt9KTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5wcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjb25maWcucHJvcGVydGllcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvcCA9IGNvbmZpZy5wcm9wZXJ0aWVzW2ldO1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGV4cG9zZWRbcHJvcF0gfHwgcHJvcCA9PSBcInNhbmRib3hcIiAmJiBzYW5kYm94O1xuICAgICAgICAgICAgICAgICAgICBleHBvc2VWYWx1ZShzYW5kYm94LCBjb25maWcsIHByb3AsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGV4cG9zZVZhbHVlKHNhbmRib3gsIGNvbmZpZywgXCJzYW5kYm94XCIsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHNpbm9uLnNhbmRib3gudXNlRmFrZVhNTEh0dHBSZXF1ZXN0ID0gc2lub24uc2FuZGJveC51c2VGYWtlU2VydmVyO1xuXG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShbXCJtb2R1bGVcIl0sIGZ1bmN0aW9uKG1vZHVsZSkgeyBtb2R1bGUuZXhwb3J0cyA9IHNpbm9uLnNhbmRib3g7IH0pO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBzaW5vbi5zYW5kYm94O1xuICAgIH1cbn0oKSk7XG4iLCIvKipcbiAgKiBAZGVwZW5kIC4uL3Npbm9uLmpzXG4gICogQGRlcGVuZCBjYWxsLmpzXG4gICovXG4vKmpzbGludCBlcWVxZXE6IGZhbHNlLCBvbmV2YXI6IGZhbHNlLCBwbHVzcGx1czogZmFsc2UqL1xuLypnbG9iYWwgbW9kdWxlLCByZXF1aXJlLCBzaW5vbiovXG4vKipcbiAgKiBTcHkgZnVuY3Rpb25zXG4gICpcbiAgKiBAYXV0aG9yIENocmlzdGlhbiBKb2hhbnNlbiAoY2hyaXN0aWFuQGNqb2hhbnNlbi5ubylcbiAgKiBAbGljZW5zZSBCU0RcbiAgKlxuICAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIENocmlzdGlhbiBKb2hhbnNlblxuICAqL1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbihmdW5jdGlvbiAoc2lub24pIHtcbiAgICB2YXIgY29tbW9uSlNNb2R1bGUgPSB0eXBlb2YgbW9kdWxlICE9PSBcInVuZGVmaW5lZFwiICYmIG1vZHVsZS5leHBvcnRzICYmIHR5cGVvZiByZXF1aXJlID09IFwiZnVuY3Rpb25cIjtcbiAgICB2YXIgcHVzaCA9IEFycmF5LnByb3RvdHlwZS5wdXNoO1xuICAgIHZhciBzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcbiAgICB2YXIgY2FsbElkID0gMDtcblxuICAgIGlmICghc2lub24gJiYgY29tbW9uSlNNb2R1bGUpIHtcbiAgICAgICAgc2lub24gPSByZXF1aXJlKFwiLi4vc2lub25cIik7XG4gICAgfVxuXG4gICAgaWYgKCFzaW5vbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3B5KG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICAgICAgaWYgKCFwcm9wZXJ0eSAmJiB0eXBlb2Ygb2JqZWN0ID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcmV0dXJuIHNweS5jcmVhdGUob2JqZWN0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghb2JqZWN0ICYmICFwcm9wZXJ0eSkge1xuICAgICAgICAgICAgcmV0dXJuIHNweS5jcmVhdGUoZnVuY3Rpb24gKCkgeyB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtZXRob2QgPSBvYmplY3RbcHJvcGVydHldO1xuICAgICAgICByZXR1cm4gc2lub24ud3JhcE1ldGhvZChvYmplY3QsIHByb3BlcnR5LCBzcHkuY3JlYXRlKG1ldGhvZCkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoaW5nRmFrZShmYWtlcywgYXJncywgc3RyaWN0KSB7XG4gICAgICAgIGlmICghZmFrZXMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gZmFrZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoZmFrZXNbaV0ubWF0Y2hlcyhhcmdzLCBzdHJpY3QpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZha2VzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5jcmVtZW50Q2FsbENvdW50KCkge1xuICAgICAgICB0aGlzLmNhbGxlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuY2FsbENvdW50ICs9IDE7XG4gICAgICAgIHRoaXMubm90Q2FsbGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2FsbGVkT25jZSA9IHRoaXMuY2FsbENvdW50ID09IDE7XG4gICAgICAgIHRoaXMuY2FsbGVkVHdpY2UgPSB0aGlzLmNhbGxDb3VudCA9PSAyO1xuICAgICAgICB0aGlzLmNhbGxlZFRocmljZSA9IHRoaXMuY2FsbENvdW50ID09IDM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlQ2FsbFByb3BlcnRpZXMoKSB7XG4gICAgICAgIHRoaXMuZmlyc3RDYWxsID0gdGhpcy5nZXRDYWxsKDApO1xuICAgICAgICB0aGlzLnNlY29uZENhbGwgPSB0aGlzLmdldENhbGwoMSk7XG4gICAgICAgIHRoaXMudGhpcmRDYWxsID0gdGhpcy5nZXRDYWxsKDIpO1xuICAgICAgICB0aGlzLmxhc3RDYWxsID0gdGhpcy5nZXRDYWxsKHRoaXMuY2FsbENvdW50IC0gMSk7XG4gICAgfVxuXG4gICAgdmFyIHZhcnMgPSBcImEsYixjLGQsZSxmLGcsaCxpLGosayxsXCI7XG4gICAgZnVuY3Rpb24gY3JlYXRlUHJveHkoZnVuYykge1xuICAgICAgICAvLyBSZXRhaW4gdGhlIGZ1bmN0aW9uIGxlbmd0aDpcbiAgICAgICAgdmFyIHA7XG4gICAgICAgIGlmIChmdW5jLmxlbmd0aCkge1xuICAgICAgICAgICAgZXZhbChcInAgPSAoZnVuY3Rpb24gcHJveHkoXCIgKyB2YXJzLnN1YnN0cmluZygwLCBmdW5jLmxlbmd0aCAqIDIgLSAxKSArXG4gICAgICAgICAgICAgICAgXCIpIHsgcmV0dXJuIHAuaW52b2tlKGZ1bmMsIHRoaXMsIHNsaWNlLmNhbGwoYXJndW1lbnRzKSk7IH0pO1wiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHAgPSBmdW5jdGlvbiBwcm94eSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcC5pbnZva2UoZnVuYywgdGhpcywgc2xpY2UuY2FsbChhcmd1bWVudHMpKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHA7XG4gICAgfVxuXG4gICAgdmFyIHV1aWQgPSAwO1xuXG4gICAgLy8gUHVibGljIEFQSVxuICAgIHZhciBzcHlBcGkgPSB7XG4gICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5ub3RDYWxsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5jYWxsZWRPbmNlID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmNhbGxlZFR3aWNlID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmNhbGxlZFRocmljZSA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5jYWxsQ291bnQgPSAwO1xuICAgICAgICAgICAgdGhpcy5maXJzdENhbGwgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5zZWNvbmRDYWxsID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMudGhpcmRDYWxsID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMubGFzdENhbGwgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5hcmdzID0gW107XG4gICAgICAgICAgICB0aGlzLnJldHVyblZhbHVlcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy50aGlzVmFsdWVzID0gW107XG4gICAgICAgICAgICB0aGlzLmV4Y2VwdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuY2FsbElkcyA9IFtdO1xuICAgICAgICAgICAgaWYgKHRoaXMuZmFrZXMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZmFrZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWtlc1tpXS5yZXNldCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBjcmVhdGU6IGZ1bmN0aW9uIGNyZWF0ZShmdW5jKSB7XG4gICAgICAgICAgICB2YXIgbmFtZTtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBmdW5jICE9IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGZ1bmMgPSBmdW5jdGlvbiAoKSB7IH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5hbWUgPSBzaW5vbi5mdW5jdGlvbk5hbWUoZnVuYyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBwcm94eSA9IGNyZWF0ZVByb3h5KGZ1bmMpO1xuXG4gICAgICAgICAgICBzaW5vbi5leHRlbmQocHJveHksIHNweSk7XG4gICAgICAgICAgICBkZWxldGUgcHJveHkuY3JlYXRlO1xuICAgICAgICAgICAgc2lub24uZXh0ZW5kKHByb3h5LCBmdW5jKTtcblxuICAgICAgICAgICAgcHJveHkucmVzZXQoKTtcbiAgICAgICAgICAgIHByb3h5LnByb3RvdHlwZSA9IGZ1bmMucHJvdG90eXBlO1xuICAgICAgICAgICAgcHJveHkuZGlzcGxheU5hbWUgPSBuYW1lIHx8IFwic3B5XCI7XG4gICAgICAgICAgICBwcm94eS50b1N0cmluZyA9IHNpbm9uLmZ1bmN0aW9uVG9TdHJpbmc7XG4gICAgICAgICAgICBwcm94eS5fY3JlYXRlID0gc2lub24uc3B5LmNyZWF0ZTtcbiAgICAgICAgICAgIHByb3h5LmlkID0gXCJzcHkjXCIgKyB1dWlkKys7XG5cbiAgICAgICAgICAgIHJldHVybiBwcm94eTtcbiAgICAgICAgfSxcblxuICAgICAgICBpbnZva2U6IGZ1bmN0aW9uIGludm9rZShmdW5jLCB0aGlzVmFsdWUsIGFyZ3MpIHtcbiAgICAgICAgICAgIHZhciBtYXRjaGluZyA9IG1hdGNoaW5nRmFrZSh0aGlzLmZha2VzLCBhcmdzKTtcbiAgICAgICAgICAgIHZhciBleGNlcHRpb24sIHJldHVyblZhbHVlO1xuXG4gICAgICAgICAgICBpbmNyZW1lbnRDYWxsQ291bnQuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgIHB1c2guY2FsbCh0aGlzLnRoaXNWYWx1ZXMsIHRoaXNWYWx1ZSk7XG4gICAgICAgICAgICBwdXNoLmNhbGwodGhpcy5hcmdzLCBhcmdzKTtcbiAgICAgICAgICAgIHB1c2guY2FsbCh0aGlzLmNhbGxJZHMsIGNhbGxJZCsrKTtcblxuICAgICAgICAgICAgLy8gTWFrZSBjYWxsIHByb3BlcnRpZXMgYXZhaWxhYmxlIGZyb20gd2l0aGluIHRoZSBzcGllZCBmdW5jdGlvbjpcbiAgICAgICAgICAgIGNyZWF0ZUNhbGxQcm9wZXJ0aWVzLmNhbGwodGhpcyk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlID0gbWF0Y2hpbmcuaW52b2tlKGZ1bmMsIHRoaXNWYWx1ZSwgYXJncyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSAodGhpcy5mdW5jIHx8IGZ1bmMpLmFwcGx5KHRoaXNWYWx1ZSwgYXJncyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIHRoaXNDYWxsID0gdGhpcy5nZXRDYWxsKHRoaXMuY2FsbENvdW50IC0gMSk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXNDYWxsLmNhbGxlZFdpdGhOZXcoKSAmJiB0eXBlb2YgcmV0dXJuVmFsdWUgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlID0gdGhpc1ZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdXNoLmNhbGwodGhpcy5leGNlcHRpb25zLCBleGNlcHRpb24pO1xuICAgICAgICAgICAgcHVzaC5jYWxsKHRoaXMucmV0dXJuVmFsdWVzLCByZXR1cm5WYWx1ZSk7XG5cbiAgICAgICAgICAgIC8vIE1ha2UgcmV0dXJuIHZhbHVlIGFuZCBleGNlcHRpb24gYXZhaWxhYmxlIGluIHRoZSBjYWxsczpcbiAgICAgICAgICAgIGNyZWF0ZUNhbGxQcm9wZXJ0aWVzLmNhbGwodGhpcyk7XG5cbiAgICAgICAgICAgIGlmIChleGNlcHRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRocm93IGV4Y2VwdGlvbjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgICAgICB9LFxuXG4gICAgICAgIG5hbWVkOiBmdW5jdGlvbiBuYW1lZChuYW1lKSB7XG4gICAgICAgICAgICB0aGlzLmRpc3BsYXlOYW1lID0gbmFtZTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGdldENhbGw6IGZ1bmN0aW9uIGdldENhbGwoaSkge1xuICAgICAgICAgICAgaWYgKGkgPCAwIHx8IGkgPj0gdGhpcy5jYWxsQ291bnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHNpbm9uLnNweUNhbGwodGhpcywgdGhpcy50aGlzVmFsdWVzW2ldLCB0aGlzLmFyZ3NbaV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJldHVyblZhbHVlc1tpXSwgdGhpcy5leGNlcHRpb25zW2ldLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYWxsSWRzW2ldKTtcbiAgICAgICAgfSxcblxuICAgICAgICBnZXRDYWxsczogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGNhbGxzID0gW107XG4gICAgICAgICAgICB2YXIgaTtcblxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMuY2FsbENvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBjYWxscy5wdXNoKHRoaXMuZ2V0Q2FsbChpKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBjYWxscztcbiAgICAgICAgfSxcblxuICAgICAgICBjYWxsZWRCZWZvcmU6IGZ1bmN0aW9uIGNhbGxlZEJlZm9yZShzcHlGbikge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNhbGxlZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFzcHlGbi5jYWxsZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FsbElkc1swXSA8IHNweUZuLmNhbGxJZHNbc3B5Rm4uY2FsbElkcy5sZW5ndGggLSAxXTtcbiAgICAgICAgfSxcblxuICAgICAgICBjYWxsZWRBZnRlcjogZnVuY3Rpb24gY2FsbGVkQWZ0ZXIoc3B5Rm4pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jYWxsZWQgfHwgIXNweUZuLmNhbGxlZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FsbElkc1t0aGlzLmNhbGxDb3VudCAtIDFdID4gc3B5Rm4uY2FsbElkc1tzcHlGbi5jYWxsQ291bnQgLSAxXTtcbiAgICAgICAgfSxcblxuICAgICAgICB3aXRoQXJnczogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmZha2VzKSB7XG4gICAgICAgICAgICAgICAgdmFyIG1hdGNoID0gbWF0Y2hpbmdGYWtlKHRoaXMuZmFrZXMsIGFyZ3MsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZmFrZXMgPSBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIG9yaWdpbmFsID0gdGhpcztcbiAgICAgICAgICAgIHZhciBmYWtlID0gdGhpcy5fY3JlYXRlKCk7XG4gICAgICAgICAgICBmYWtlLm1hdGNoaW5nQWd1bWVudHMgPSBhcmdzO1xuICAgICAgICAgICAgZmFrZS5wYXJlbnQgPSB0aGlzO1xuICAgICAgICAgICAgcHVzaC5jYWxsKHRoaXMuZmFrZXMsIGZha2UpO1xuXG4gICAgICAgICAgICBmYWtlLndpdGhBcmdzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbC53aXRoQXJncy5hcHBseShvcmlnaW5hbCwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5hcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZha2UubWF0Y2hlcyh0aGlzLmFyZ3NbaV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGluY3JlbWVudENhbGxDb3VudC5jYWxsKGZha2UpO1xuICAgICAgICAgICAgICAgICAgICBwdXNoLmNhbGwoZmFrZS50aGlzVmFsdWVzLCB0aGlzLnRoaXNWYWx1ZXNbaV0pO1xuICAgICAgICAgICAgICAgICAgICBwdXNoLmNhbGwoZmFrZS5hcmdzLCB0aGlzLmFyZ3NbaV0pO1xuICAgICAgICAgICAgICAgICAgICBwdXNoLmNhbGwoZmFrZS5yZXR1cm5WYWx1ZXMsIHRoaXMucmV0dXJuVmFsdWVzW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgcHVzaC5jYWxsKGZha2UuZXhjZXB0aW9ucywgdGhpcy5leGNlcHRpb25zW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgcHVzaC5jYWxsKGZha2UuY2FsbElkcywgdGhpcy5jYWxsSWRzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjcmVhdGVDYWxsUHJvcGVydGllcy5jYWxsKGZha2UpO1xuXG4gICAgICAgICAgICByZXR1cm4gZmFrZTtcbiAgICAgICAgfSxcblxuICAgICAgICBtYXRjaGVzOiBmdW5jdGlvbiAoYXJncywgc3RyaWN0KSB7XG4gICAgICAgICAgICB2YXIgbWFyZ3MgPSB0aGlzLm1hdGNoaW5nQWd1bWVudHM7XG5cbiAgICAgICAgICAgIGlmIChtYXJncy5sZW5ndGggPD0gYXJncy5sZW5ndGggJiZcbiAgICAgICAgICAgICAgICBzaW5vbi5kZWVwRXF1YWwobWFyZ3MsIGFyZ3Muc2xpY2UoMCwgbWFyZ3MubGVuZ3RoKSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gIXN0cmljdCB8fCBtYXJncy5sZW5ndGggPT0gYXJncy5sZW5ndGg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgcHJpbnRmOiBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gICAgICAgICAgICB2YXIgc3B5ID0gdGhpcztcbiAgICAgICAgICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICAgICAgdmFyIGZvcm1hdHRlcjtcblxuICAgICAgICAgICAgcmV0dXJuIChmb3JtYXQgfHwgXCJcIikucmVwbGFjZSgvJSguKS9nLCBmdW5jdGlvbiAobWF0Y2gsIHNwZWNpZnllcikge1xuICAgICAgICAgICAgICAgIGZvcm1hdHRlciA9IHNweUFwaS5mb3JtYXR0ZXJzW3NwZWNpZnllcl07XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGZvcm1hdHRlciA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZvcm1hdHRlci5jYWxsKG51bGwsIHNweSwgYXJncyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNOYU4ocGFyc2VJbnQoc3BlY2lmeWVyLCAxMCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzaW5vbi5mb3JtYXQoYXJnc1tzcGVjaWZ5ZXIgLSAxXSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiJVwiICsgc3BlY2lmeWVyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gZGVsZWdhdGVUb0NhbGxzKG1ldGhvZCwgbWF0Y2hBbnksIGFjdHVhbCwgbm90Q2FsbGVkKSB7XG4gICAgICAgIHNweUFwaVttZXRob2RdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNhbGxlZCkge1xuICAgICAgICAgICAgICAgIGlmIChub3RDYWxsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vdENhbGxlZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBjdXJyZW50Q2FsbDtcbiAgICAgICAgICAgIHZhciBtYXRjaGVzID0gMDtcblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLmNhbGxDb3VudDsgaSA8IGw7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRDYWxsID0gdGhpcy5nZXRDYWxsKGkpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRDYWxsW2FjdHVhbCB8fCBtZXRob2RdLmFwcGx5KGN1cnJlbnRDYWxsLCBhcmd1bWVudHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIG1hdGNoZXMgKz0gMTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2hBbnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbWF0Y2hlcyA9PT0gdGhpcy5jYWxsQ291bnQ7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZGVsZWdhdGVUb0NhbGxzKFwiY2FsbGVkT25cIiwgdHJ1ZSk7XG4gICAgZGVsZWdhdGVUb0NhbGxzKFwiYWx3YXlzQ2FsbGVkT25cIiwgZmFsc2UsIFwiY2FsbGVkT25cIik7XG4gICAgZGVsZWdhdGVUb0NhbGxzKFwiY2FsbGVkV2l0aFwiLCB0cnVlKTtcbiAgICBkZWxlZ2F0ZVRvQ2FsbHMoXCJjYWxsZWRXaXRoTWF0Y2hcIiwgdHJ1ZSk7XG4gICAgZGVsZWdhdGVUb0NhbGxzKFwiYWx3YXlzQ2FsbGVkV2l0aFwiLCBmYWxzZSwgXCJjYWxsZWRXaXRoXCIpO1xuICAgIGRlbGVnYXRlVG9DYWxscyhcImFsd2F5c0NhbGxlZFdpdGhNYXRjaFwiLCBmYWxzZSwgXCJjYWxsZWRXaXRoTWF0Y2hcIik7XG4gICAgZGVsZWdhdGVUb0NhbGxzKFwiY2FsbGVkV2l0aEV4YWN0bHlcIiwgdHJ1ZSk7XG4gICAgZGVsZWdhdGVUb0NhbGxzKFwiYWx3YXlzQ2FsbGVkV2l0aEV4YWN0bHlcIiwgZmFsc2UsIFwiY2FsbGVkV2l0aEV4YWN0bHlcIik7XG4gICAgZGVsZWdhdGVUb0NhbGxzKFwibmV2ZXJDYWxsZWRXaXRoXCIsIGZhbHNlLCBcIm5vdENhbGxlZFdpdGhcIixcbiAgICAgICAgZnVuY3Rpb24gKCkgeyByZXR1cm4gdHJ1ZTsgfSk7XG4gICAgZGVsZWdhdGVUb0NhbGxzKFwibmV2ZXJDYWxsZWRXaXRoTWF0Y2hcIiwgZmFsc2UsIFwibm90Q2FsbGVkV2l0aE1hdGNoXCIsXG4gICAgICAgIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH0pO1xuICAgIGRlbGVnYXRlVG9DYWxscyhcInRocmV3XCIsIHRydWUpO1xuICAgIGRlbGVnYXRlVG9DYWxscyhcImFsd2F5c1RocmV3XCIsIGZhbHNlLCBcInRocmV3XCIpO1xuICAgIGRlbGVnYXRlVG9DYWxscyhcInJldHVybmVkXCIsIHRydWUpO1xuICAgIGRlbGVnYXRlVG9DYWxscyhcImFsd2F5c1JldHVybmVkXCIsIGZhbHNlLCBcInJldHVybmVkXCIpO1xuICAgIGRlbGVnYXRlVG9DYWxscyhcImNhbGxlZFdpdGhOZXdcIiwgdHJ1ZSk7XG4gICAgZGVsZWdhdGVUb0NhbGxzKFwiYWx3YXlzQ2FsbGVkV2l0aE5ld1wiLCBmYWxzZSwgXCJjYWxsZWRXaXRoTmV3XCIpO1xuICAgIGRlbGVnYXRlVG9DYWxscyhcImNhbGxBcmdcIiwgZmFsc2UsIFwiY2FsbEFyZ1dpdGhcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy50b1N0cmluZygpICsgXCIgY2Fubm90IGNhbGwgYXJnIHNpbmNlIGl0IHdhcyBub3QgeWV0IGludm9rZWQuXCIpO1xuICAgIH0pO1xuICAgIHNweUFwaS5jYWxsQXJnV2l0aCA9IHNweUFwaS5jYWxsQXJnO1xuICAgIGRlbGVnYXRlVG9DYWxscyhcImNhbGxBcmdPblwiLCBmYWxzZSwgXCJjYWxsQXJnT25XaXRoXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHRoaXMudG9TdHJpbmcoKSArIFwiIGNhbm5vdCBjYWxsIGFyZyBzaW5jZSBpdCB3YXMgbm90IHlldCBpbnZva2VkLlwiKTtcbiAgICB9KTtcbiAgICBzcHlBcGkuY2FsbEFyZ09uV2l0aCA9IHNweUFwaS5jYWxsQXJnT247XG4gICAgZGVsZWdhdGVUb0NhbGxzKFwieWllbGRcIiwgZmFsc2UsIFwieWllbGRcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy50b1N0cmluZygpICsgXCIgY2Fubm90IHlpZWxkIHNpbmNlIGl0IHdhcyBub3QgeWV0IGludm9rZWQuXCIpO1xuICAgIH0pO1xuICAgIC8vIFwiaW52b2tlQ2FsbGJhY2tcIiBpcyBhbiBhbGlhcyBmb3IgXCJ5aWVsZFwiIHNpbmNlIFwieWllbGRcIiBpcyBpbnZhbGlkIGluIHN0cmljdCBtb2RlLlxuICAgIHNweUFwaS5pbnZva2VDYWxsYmFjayA9IHNweUFwaS55aWVsZDtcbiAgICBkZWxlZ2F0ZVRvQ2FsbHMoXCJ5aWVsZE9uXCIsIGZhbHNlLCBcInlpZWxkT25cIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy50b1N0cmluZygpICsgXCIgY2Fubm90IHlpZWxkIHNpbmNlIGl0IHdhcyBub3QgeWV0IGludm9rZWQuXCIpO1xuICAgIH0pO1xuICAgIGRlbGVnYXRlVG9DYWxscyhcInlpZWxkVG9cIiwgZmFsc2UsIFwieWllbGRUb1wiLCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHRoaXMudG9TdHJpbmcoKSArIFwiIGNhbm5vdCB5aWVsZCB0byAnXCIgKyBwcm9wZXJ0eSArXG4gICAgICAgICAgICBcIicgc2luY2UgaXQgd2FzIG5vdCB5ZXQgaW52b2tlZC5cIik7XG4gICAgfSk7XG4gICAgZGVsZWdhdGVUb0NhbGxzKFwieWllbGRUb09uXCIsIGZhbHNlLCBcInlpZWxkVG9PblwiLCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHRoaXMudG9TdHJpbmcoKSArIFwiIGNhbm5vdCB5aWVsZCB0byAnXCIgKyBwcm9wZXJ0eSArXG4gICAgICAgICAgICBcIicgc2luY2UgaXQgd2FzIG5vdCB5ZXQgaW52b2tlZC5cIik7XG4gICAgfSk7XG5cbiAgICBzcHlBcGkuZm9ybWF0dGVycyA9IHtcbiAgICAgICAgXCJjXCI6IGZ1bmN0aW9uIChzcHkpIHtcbiAgICAgICAgICAgIHJldHVybiBzaW5vbi50aW1lc0luV29yZHMoc3B5LmNhbGxDb3VudCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgXCJuXCI6IGZ1bmN0aW9uIChzcHkpIHtcbiAgICAgICAgICAgIHJldHVybiBzcHkudG9TdHJpbmcoKTtcbiAgICAgICAgfSxcblxuICAgICAgICBcIkNcIjogZnVuY3Rpb24gKHNweSkge1xuICAgICAgICAgICAgdmFyIGNhbGxzID0gW107XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gc3B5LmNhbGxDb3VudDsgaSA8IGw7ICsraSkge1xuICAgICAgICAgICAgICAgIHZhciBzdHJpbmdpZmllZENhbGwgPSBcIiAgICBcIiArIHNweS5nZXRDYWxsKGkpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgaWYgKC9cXG4vLnRlc3QoY2FsbHNbaSAtIDFdKSkge1xuICAgICAgICAgICAgICAgICAgICBzdHJpbmdpZmllZENhbGwgPSBcIlxcblwiICsgc3RyaW5naWZpZWRDYWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwdXNoLmNhbGwoY2FsbHMsIHN0cmluZ2lmaWVkQ2FsbCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBjYWxscy5sZW5ndGggPiAwID8gXCJcXG5cIiArIGNhbGxzLmpvaW4oXCJcXG5cIikgOiBcIlwiO1xuICAgICAgICB9LFxuXG4gICAgICAgIFwidFwiOiBmdW5jdGlvbiAoc3B5KSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0cyA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHNweS5jYWxsQ291bnQ7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgICAgICAgICBwdXNoLmNhbGwob2JqZWN0cywgc2lub24uZm9ybWF0KHNweS50aGlzVmFsdWVzW2ldKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBvYmplY3RzLmpvaW4oXCIsIFwiKTtcbiAgICAgICAgfSxcblxuICAgICAgICBcIipcIjogZnVuY3Rpb24gKHNweSwgYXJncykge1xuICAgICAgICAgICAgdmFyIGZvcm1hdHRlZCA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGFyZ3MubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgICAgICAgICAgICAgcHVzaC5jYWxsKGZvcm1hdHRlZCwgc2lub24uZm9ybWF0KGFyZ3NbaV0pKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdHRlZC5qb2luKFwiLCBcIik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgc2lub24uZXh0ZW5kKHNweSwgc3B5QXBpKTtcblxuICAgIHNweS5zcHlDYWxsID0gc2lub24uc3B5Q2FsbDtcbiAgICBzaW5vbi5zcHkgPSBzcHk7XG5cbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKFtcIm1vZHVsZVwiXSwgZnVuY3Rpb24obW9kdWxlKSB7IG1vZHVsZS5leHBvcnRzID0gc3B5OyB9KTtcbiAgICB9IGVsc2UgaWYgKGNvbW1vbkpTTW9kdWxlKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gc3B5O1xuICAgIH1cbn0odHlwZW9mIHNpbm9uID09IFwib2JqZWN0XCIgJiYgc2lub24gfHwgbnVsbCkpO1xuIiwiLyoqXG4gKiBAZGVwZW5kIC4uL3Npbm9uLmpzXG4gKiBAZGVwZW5kIHNweS5qc1xuICogQGRlcGVuZCBiZWhhdmlvci5qc1xuICovXG4vKmpzbGludCBlcWVxZXE6IGZhbHNlLCBvbmV2YXI6IGZhbHNlKi9cbi8qZ2xvYmFsIG1vZHVsZSwgcmVxdWlyZSwgc2lub24qL1xuLyoqXG4gKiBTdHViIGZ1bmN0aW9uc1xuICpcbiAqIEBhdXRob3IgQ2hyaXN0aWFuIEpvaGFuc2VuIChjaHJpc3RpYW5AY2pvaGFuc2VuLm5vKVxuICogQGxpY2Vuc2UgQlNEXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTMgQ2hyaXN0aWFuIEpvaGFuc2VuXG4gKi9cblwidXNlIHN0cmljdFwiO1xuXG4oZnVuY3Rpb24gKHNpbm9uKSB7XG4gICAgdmFyIGNvbW1vbkpTTW9kdWxlID0gdHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUuZXhwb3J0cyAmJiB0eXBlb2YgcmVxdWlyZSA9PSBcImZ1bmN0aW9uXCI7XG5cbiAgICBpZiAoIXNpbm9uICYmIGNvbW1vbkpTTW9kdWxlKSB7XG4gICAgICAgIHNpbm9uID0gcmVxdWlyZShcIi4uL3Npbm9uXCIpO1xuICAgIH1cblxuICAgIGlmICghc2lub24pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0dWIob2JqZWN0LCBwcm9wZXJ0eSwgZnVuYykge1xuICAgICAgICBpZiAoISFmdW5jICYmIHR5cGVvZiBmdW5jICE9IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkN1c3RvbSBzdHViIHNob3VsZCBiZSBmdW5jdGlvblwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB3cmFwcGVyO1xuXG4gICAgICAgIGlmIChmdW5jKSB7XG4gICAgICAgICAgICB3cmFwcGVyID0gc2lub24uc3B5ICYmIHNpbm9uLnNweS5jcmVhdGUgPyBzaW5vbi5zcHkuY3JlYXRlKGZ1bmMpIDogZnVuYztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdyYXBwZXIgPSBzdHViLmNyZWF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFvYmplY3QgJiYgdHlwZW9mIHByb3BlcnR5ID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gc2lub24uc3R1Yi5jcmVhdGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgcHJvcGVydHkgPT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZW9mIG9iamVjdCA9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBwcm9wIGluIG9iamVjdCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0W3Byb3BdID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3R1YihvYmplY3QsIHByb3ApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzaW5vbi53cmFwTWV0aG9kKG9iamVjdCwgcHJvcGVydHksIHdyYXBwZXIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldERlZmF1bHRCZWhhdmlvcihzdHViKSB7XG4gICAgICAgIHJldHVybiBzdHViLmRlZmF1bHRCZWhhdmlvciB8fCBnZXRQYXJlbnRCZWhhdmlvdXIoc3R1YikgfHwgc2lub24uYmVoYXZpb3IuY3JlYXRlKHN0dWIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFBhcmVudEJlaGF2aW91cihzdHViKSB7XG4gICAgICAgIHJldHVybiAoc3R1Yi5wYXJlbnQgJiYgZ2V0Q3VycmVudEJlaGF2aW9yKHN0dWIucGFyZW50KSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0Q3VycmVudEJlaGF2aW9yKHN0dWIpIHtcbiAgICAgICAgdmFyIGJlaGF2aW9yID0gc3R1Yi5iZWhhdmlvcnNbc3R1Yi5jYWxsQ291bnQgLSAxXTtcbiAgICAgICAgcmV0dXJuIGJlaGF2aW9yICYmIGJlaGF2aW9yLmlzUHJlc2VudCgpID8gYmVoYXZpb3IgOiBnZXREZWZhdWx0QmVoYXZpb3Ioc3R1Yik7XG4gICAgfVxuXG4gICAgdmFyIHV1aWQgPSAwO1xuXG4gICAgc2lub24uZXh0ZW5kKHN0dWIsIChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm90byA9IHtcbiAgICAgICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgICAgICAgICAgICAgIHZhciBmdW5jdGlvblN0dWIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRDdXJyZW50QmVoYXZpb3IoZnVuY3Rpb25TdHViKS5pbnZva2UodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgZnVuY3Rpb25TdHViLmlkID0gXCJzdHViI1wiICsgdXVpZCsrO1xuICAgICAgICAgICAgICAgIHZhciBvcmlnID0gZnVuY3Rpb25TdHViO1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uU3R1YiA9IHNpbm9uLnNweS5jcmVhdGUoZnVuY3Rpb25TdHViKTtcbiAgICAgICAgICAgICAgICBmdW5jdGlvblN0dWIuZnVuYyA9IG9yaWc7XG5cbiAgICAgICAgICAgICAgICBzaW5vbi5leHRlbmQoZnVuY3Rpb25TdHViLCBzdHViKTtcbiAgICAgICAgICAgICAgICBmdW5jdGlvblN0dWIuX2NyZWF0ZSA9IHNpbm9uLnN0dWIuY3JlYXRlO1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uU3R1Yi5kaXNwbGF5TmFtZSA9IFwic3R1YlwiO1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uU3R1Yi50b1N0cmluZyA9IHNpbm9uLmZ1bmN0aW9uVG9TdHJpbmc7XG5cbiAgICAgICAgICAgICAgICBmdW5jdGlvblN0dWIuZGVmYXVsdEJlaGF2aW9yID0gbnVsbDtcbiAgICAgICAgICAgICAgICBmdW5jdGlvblN0dWIuYmVoYXZpb3JzID0gW107XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb25TdHViO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgcmVzZXRCZWhhdmlvcjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5kZWZhdWx0QmVoYXZpb3IgPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMuYmVoYXZpb3JzID0gW107XG5cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZXR1cm5WYWx1ZTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZXR1cm5BcmdBdDtcbiAgICAgICAgICAgICAgICB0aGlzLnJldHVyblRoaXMgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmZha2VzKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLmZha2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZha2VzW2ldLnJlc2V0QmVoYXZpb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIG9uQ2FsbDogZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYmVoYXZpb3JzW2luZGV4XSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJlaGF2aW9yc1tpbmRleF0gPSBzaW5vbi5iZWhhdmlvci5jcmVhdGUodGhpcyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYmVoYXZpb3JzW2luZGV4XTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIG9uRmlyc3RDYWxsOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vbkNhbGwoMCk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBvblNlY29uZENhbGw6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9uQ2FsbCgxKTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIG9uVGhpcmRDYWxsOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vbkNhbGwoMik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgZm9yICh2YXIgbWV0aG9kIGluIHNpbm9uLmJlaGF2aW9yKSB7XG4gICAgICAgICAgICBpZiAoc2lub24uYmVoYXZpb3IuaGFzT3duUHJvcGVydHkobWV0aG9kKSAmJlxuICAgICAgICAgICAgICAgICFwcm90by5oYXNPd25Qcm9wZXJ0eShtZXRob2QpICYmXG4gICAgICAgICAgICAgICAgbWV0aG9kICE9ICdjcmVhdGUnICYmXG4gICAgICAgICAgICAgICAgbWV0aG9kICE9ICd3aXRoQXJncycgJiZcbiAgICAgICAgICAgICAgICBtZXRob2QgIT0gJ2ludm9rZScpIHtcbiAgICAgICAgICAgICAgICBwcm90b1ttZXRob2RdID0gKGZ1bmN0aW9uKGJlaGF2aW9yTWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGVmYXVsdEJlaGF2aW9yID0gdGhpcy5kZWZhdWx0QmVoYXZpb3IgfHwgc2lub24uYmVoYXZpb3IuY3JlYXRlKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWZhdWx0QmVoYXZpb3JbYmVoYXZpb3JNZXRob2RdLmFwcGx5KHRoaXMuZGVmYXVsdEJlaGF2aW9yLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfShtZXRob2QpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwcm90bztcbiAgICB9KCkpKTtcblxuICAgIHNpbm9uLnN0dWIgPSBzdHViO1xuXG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShbXCJtb2R1bGVcIl0sIGZ1bmN0aW9uKG1vZHVsZSkgeyBtb2R1bGUuZXhwb3J0cyA9IHN0dWI7IH0pO1xuICAgIH0gZWxzZSBpZiAoY29tbW9uSlNNb2R1bGUpIHtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBzdHViO1xuICAgIH1cbn0odHlwZW9mIHNpbm9uID09IFwib2JqZWN0XCIgJiYgc2lub24gfHwgbnVsbCkpO1xuIiwiLyoqXG4gKiBAZGVwZW5kIC4uL3Npbm9uLmpzXG4gKiBAZGVwZW5kIHN0dWIuanNcbiAqIEBkZXBlbmQgbW9jay5qc1xuICogQGRlcGVuZCBzYW5kYm94LmpzXG4gKi9cbi8qanNsaW50IGVxZXFlcTogZmFsc2UsIG9uZXZhcjogZmFsc2UsIGZvcmluOiB0cnVlLCBwbHVzcGx1czogZmFsc2UqL1xuLypnbG9iYWwgbW9kdWxlLCByZXF1aXJlLCBzaW5vbiovXG4vKipcbiAqIFRlc3QgZnVuY3Rpb24sIHNhbmRib3hlcyBmYWtlc1xuICpcbiAqIEBhdXRob3IgQ2hyaXN0aWFuIEpvaGFuc2VuIChjaHJpc3RpYW5AY2pvaGFuc2VuLm5vKVxuICogQGxpY2Vuc2UgQlNEXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTMgQ2hyaXN0aWFuIEpvaGFuc2VuXG4gKi9cblwidXNlIHN0cmljdFwiO1xuXG4oZnVuY3Rpb24gKHNpbm9uKSB7XG4gICAgdmFyIGNvbW1vbkpTTW9kdWxlID0gdHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUuZXhwb3J0cyAmJiB0eXBlb2YgcmVxdWlyZSA9PSBcImZ1bmN0aW9uXCI7XG5cbiAgICBpZiAoIXNpbm9uICYmIGNvbW1vbkpTTW9kdWxlKSB7XG4gICAgICAgIHNpbm9uID0gcmVxdWlyZShcIi4uL3Npbm9uXCIpO1xuICAgIH1cblxuICAgIGlmICghc2lub24pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRlc3QoY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgY2FsbGJhY2s7XG5cbiAgICAgICAgaWYgKHR5cGUgIT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwic2lub24udGVzdCBuZWVkcyB0byB3cmFwIGEgdGVzdCBmdW5jdGlvbiwgZ290IFwiICsgdHlwZSk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBzaW5vblNhbmRib3hlZFRlc3QoKSB7XG4gICAgICAgICAgICB2YXIgY29uZmlnID0gc2lub24uZ2V0Q29uZmlnKHNpbm9uLmNvbmZpZyk7XG4gICAgICAgICAgICBjb25maWcuaW5qZWN0SW50byA9IGNvbmZpZy5pbmplY3RJbnRvVGhpcyAmJiB0aGlzIHx8IGNvbmZpZy5pbmplY3RJbnRvO1xuICAgICAgICAgICAgdmFyIHNhbmRib3ggPSBzaW5vbi5zYW5kYm94LmNyZWF0ZShjb25maWcpO1xuICAgICAgICAgICAgdmFyIGV4Y2VwdGlvbiwgcmVzdWx0O1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLmNvbmNhdChzYW5kYm94LmFyZ3MpO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgZXhjZXB0aW9uICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXhjZXB0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2FuZGJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGNhbGxiYWNrLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNpbm9uQXN5bmNTYW5kYm94ZWRUZXN0KGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNpbm9uU2FuZGJveGVkVGVzdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzaW5vblNhbmRib3hlZFRlc3Q7XG4gICAgfVxuXG4gICAgdGVzdC5jb25maWcgPSB7XG4gICAgICAgIGluamVjdEludG9UaGlzOiB0cnVlLFxuICAgICAgICBpbmplY3RJbnRvOiBudWxsLFxuICAgICAgICBwcm9wZXJ0aWVzOiBbXCJzcHlcIiwgXCJzdHViXCIsIFwibW9ja1wiLCBcImNsb2NrXCIsIFwic2VydmVyXCIsIFwicmVxdWVzdHNcIl0sXG4gICAgICAgIHVzZUZha2VUaW1lcnM6IHRydWUsXG4gICAgICAgIHVzZUZha2VTZXJ2ZXI6IHRydWVcbiAgICB9O1xuXG4gICAgc2lub24udGVzdCA9IHRlc3Q7XG5cbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKFtcIm1vZHVsZVwiXSwgZnVuY3Rpb24obW9kdWxlKSB7IG1vZHVsZS5leHBvcnRzID0gdGVzdDsgfSk7XG4gICAgfSBlbHNlIGlmIChjb21tb25KU01vZHVsZSkge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IHRlc3Q7XG4gICAgfVxufSh0eXBlb2Ygc2lub24gPT0gXCJvYmplY3RcIiAmJiBzaW5vbiB8fCBudWxsKSk7XG4iLCIvKipcbiAqIEBkZXBlbmQgLi4vc2lub24uanNcbiAqIEBkZXBlbmQgdGVzdC5qc1xuICovXG4vKmpzbGludCBlcWVxZXE6IGZhbHNlLCBvbmV2YXI6IGZhbHNlLCBlcWVxZXE6IGZhbHNlKi9cbi8qZ2xvYmFsIG1vZHVsZSwgcmVxdWlyZSwgc2lub24qL1xuLyoqXG4gKiBUZXN0IGNhc2UsIHNhbmRib3hlcyBhbGwgdGVzdCBmdW5jdGlvbnNcbiAqXG4gKiBAYXV0aG9yIENocmlzdGlhbiBKb2hhbnNlbiAoY2hyaXN0aWFuQGNqb2hhbnNlbi5ubylcbiAqIEBsaWNlbnNlIEJTRFxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIENocmlzdGlhbiBKb2hhbnNlblxuICovXG5cInVzZSBzdHJpY3RcIjtcblxuKGZ1bmN0aW9uIChzaW5vbikge1xuICAgIHZhciBjb21tb25KU01vZHVsZSA9IHR5cGVvZiBtb2R1bGUgIT09IFwidW5kZWZpbmVkXCIgJiYgbW9kdWxlLmV4cG9ydHMgJiYgdHlwZW9mIHJlcXVpcmUgPT0gXCJmdW5jdGlvblwiO1xuXG4gICAgaWYgKCFzaW5vbiAmJiBjb21tb25KU01vZHVsZSkge1xuICAgICAgICBzaW5vbiA9IHJlcXVpcmUoXCIuLi9zaW5vblwiKTtcbiAgICB9XG5cbiAgICBpZiAoIXNpbm9uIHx8ICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVUZXN0KHByb3BlcnR5LCBzZXRVcCwgdGVhckRvd24pIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChzZXRVcCkge1xuICAgICAgICAgICAgICAgIHNldFVwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBleGNlcHRpb24sIHJlc3VsdDtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBwcm9wZXJ0eS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0ZWFyRG93bikge1xuICAgICAgICAgICAgICAgIHRlYXJEb3duLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBleGNlcHRpb247XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdGVzdENhc2UodGVzdHMsIHByZWZpeCkge1xuICAgICAgICAvKmpzbDppZ25vcmUqL1xuICAgICAgICBpZiAoIXRlc3RzIHx8IHR5cGVvZiB0ZXN0cyAhPSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwic2lub24udGVzdENhc2UgbmVlZHMgYW4gb2JqZWN0IHdpdGggdGVzdCBmdW5jdGlvbnNcIik7XG4gICAgICAgIH1cbiAgICAgICAgLypqc2w6ZW5kKi9cblxuICAgICAgICBwcmVmaXggPSBwcmVmaXggfHwgXCJ0ZXN0XCI7XG4gICAgICAgIHZhciByUHJlZml4ID0gbmV3IFJlZ0V4cChcIl5cIiArIHByZWZpeCk7XG4gICAgICAgIHZhciBtZXRob2RzID0ge30sIHRlc3ROYW1lLCBwcm9wZXJ0eSwgbWV0aG9kO1xuICAgICAgICB2YXIgc2V0VXAgPSB0ZXN0cy5zZXRVcDtcbiAgICAgICAgdmFyIHRlYXJEb3duID0gdGVzdHMudGVhckRvd247XG5cbiAgICAgICAgZm9yICh0ZXN0TmFtZSBpbiB0ZXN0cykge1xuICAgICAgICAgICAgaWYgKHRlc3RzLmhhc093blByb3BlcnR5KHRlc3ROYW1lKSkge1xuICAgICAgICAgICAgICAgIHByb3BlcnR5ID0gdGVzdHNbdGVzdE5hbWVdO1xuXG4gICAgICAgICAgICAgICAgaWYgKC9eKHNldFVwfHRlYXJEb3duKSQvLnRlc3QodGVzdE5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcHJvcGVydHkgPT0gXCJmdW5jdGlvblwiICYmIHJQcmVmaXgudGVzdCh0ZXN0TmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gcHJvcGVydHk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNldFVwIHx8IHRlYXJEb3duKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSBjcmVhdGVUZXN0KHByb3BlcnR5LCBzZXRVcCwgdGVhckRvd24pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kc1t0ZXN0TmFtZV0gPSBzaW5vbi50ZXN0KG1ldGhvZCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kc1t0ZXN0TmFtZV0gPSB0ZXN0c1t0ZXN0TmFtZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1ldGhvZHM7XG4gICAgfVxuXG4gICAgc2lub24udGVzdENhc2UgPSB0ZXN0Q2FzZTtcblxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoW1wibW9kdWxlXCJdLCBmdW5jdGlvbihtb2R1bGUpIHsgbW9kdWxlLmV4cG9ydHMgPSB0ZXN0Q2FzZTsgfSk7XG4gICAgfSBlbHNlIGlmIChjb21tb25KU01vZHVsZSkge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IHRlc3RDYXNlO1xuICAgIH1cbn0odHlwZW9mIHNpbm9uID09IFwib2JqZWN0XCIgJiYgc2lub24gfHwgbnVsbCkpO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xuLypqc2xpbnQgZXFlcWVxOiBmYWxzZSwgcGx1c3BsdXM6IGZhbHNlLCBldmlsOiB0cnVlLCBvbmV2YXI6IGZhbHNlLCBicm93c2VyOiB0cnVlLCBmb3JpbjogZmFsc2UqL1xuLypnbG9iYWwgbW9kdWxlLCByZXF1aXJlLCB3aW5kb3cqL1xuLyoqXG4gKiBGYWtlIHRpbWVyIEFQSVxuICogc2V0VGltZW91dFxuICogc2V0SW50ZXJ2YWxcbiAqIGNsZWFyVGltZW91dFxuICogY2xlYXJJbnRlcnZhbFxuICogdGlja1xuICogcmVzZXRcbiAqIERhdGVcbiAqXG4gKiBJbnNwaXJlZCBieSBqc1VuaXRNb2NrVGltZU91dCBmcm9tIEpzVW5pdFxuICpcbiAqIEBhdXRob3IgQ2hyaXN0aWFuIEpvaGFuc2VuIChjaHJpc3RpYW5AY2pvaGFuc2VuLm5vKVxuICogQGxpY2Vuc2UgQlNEXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTMgQ2hyaXN0aWFuIEpvaGFuc2VuXG4gKi9cblwidXNlIHN0cmljdFwiO1xuXG5pZiAodHlwZW9mIHNpbm9uID09IFwidW5kZWZpbmVkXCIpIHtcbiAgICB2YXIgc2lub24gPSB7fTtcbn1cblxuKGZ1bmN0aW9uIChnbG9iYWwpIHtcbiAgICAvLyBub2RlIGV4cGVjdHMgc2V0VGltZW91dC9zZXRJbnRlcnZhbCB0byByZXR1cm4gYSBmbiBvYmplY3Qgdy8gLnJlZigpLy51bnJlZigpXG4gICAgLy8gYnJvd3NlcnMsIGEgbnVtYmVyLlxuICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2pvaGFuc2VuL1Npbm9uLkpTL3B1bGwvNDM2XG4gICAgdmFyIHRpbWVvdXRSZXN1bHQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge30sIDApO1xuICAgIHZhciBhZGRUaW1lclJldHVybnNPYmplY3QgPSB0eXBlb2YgdGltZW91dFJlc3VsdCA9PT0gJ29iamVjdCc7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRSZXN1bHQpO1xuXG4gICAgdmFyIGlkID0gMTtcblxuICAgIGZ1bmN0aW9uIGFkZFRpbWVyKGFyZ3MsIHJlY3VycmluZykge1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkZ1bmN0aW9uIHJlcXVpcmVzIGF0IGxlYXN0IDEgcGFyYW1ldGVyXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBhcmdzWzBdID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYWxsYmFjayBtdXN0IGJlIHByb3ZpZGVkIHRvIHRpbWVyIGNhbGxzXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRvSWQgPSBpZCsrO1xuICAgICAgICB2YXIgZGVsYXkgPSBhcmdzWzFdIHx8IDA7XG5cbiAgICAgICAgaWYgKCF0aGlzLnRpbWVvdXRzKSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVvdXRzID0ge307XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRpbWVvdXRzW3RvSWRdID0ge1xuICAgICAgICAgICAgaWQ6IHRvSWQsXG4gICAgICAgICAgICBmdW5jOiBhcmdzWzBdLFxuICAgICAgICAgICAgY2FsbEF0OiB0aGlzLm5vdyArIGRlbGF5LFxuICAgICAgICAgICAgaW52b2tlQXJnczogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncywgMilcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAocmVjdXJyaW5nID09PSB0cnVlKSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVvdXRzW3RvSWRdLmludGVydmFsID0gZGVsYXk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYWRkVGltZXJSZXR1cm5zT2JqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGlkOiB0b0lkLFxuICAgICAgICAgICAgICAgIHJlZjogZnVuY3Rpb24oKSB7fSxcbiAgICAgICAgICAgICAgICB1bnJlZjogZnVuY3Rpb24oKSB7fVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0b0lkO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VUaW1lKHN0cikge1xuICAgICAgICBpZiAoIXN0cikge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc3RyaW5ncyA9IHN0ci5zcGxpdChcIjpcIik7XG4gICAgICAgIHZhciBsID0gc3RyaW5ncy5sZW5ndGgsIGkgPSBsO1xuICAgICAgICB2YXIgbXMgPSAwLCBwYXJzZWQ7XG5cbiAgICAgICAgaWYgKGwgPiAzIHx8ICEvXihcXGRcXGQ6KXswLDJ9XFxkXFxkPyQvLnRlc3Qoc3RyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGljayBvbmx5IHVuZGVyc3RhbmRzIG51bWJlcnMgYW5kICdoOm06cydcIik7XG4gICAgICAgIH1cblxuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBwYXJzZWQgPSBwYXJzZUludChzdHJpbmdzW2ldLCAxMCk7XG5cbiAgICAgICAgICAgIGlmIChwYXJzZWQgPj0gNjApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHRpbWUgXCIgKyBzdHIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBtcyArPSBwYXJzZWQgKiBNYXRoLnBvdyg2MCwgKGwgLSBpIC0gMSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1zICogMTAwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVPYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHZhciBuZXdPYmplY3Q7XG5cbiAgICAgICAgaWYgKE9iamVjdC5jcmVhdGUpIHtcbiAgICAgICAgICAgIG5ld09iamVjdCA9IE9iamVjdC5jcmVhdGUob2JqZWN0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBGID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgICAgICBGLnByb3RvdHlwZSA9IG9iamVjdDtcbiAgICAgICAgICAgIG5ld09iamVjdCA9IG5ldyBGKCk7XG4gICAgICAgIH1cblxuICAgICAgICBuZXdPYmplY3QuRGF0ZS5jbG9jayA9IG5ld09iamVjdDtcbiAgICAgICAgcmV0dXJuIG5ld09iamVjdDtcbiAgICB9XG5cbiAgICBzaW5vbi5jbG9jayA9IHtcbiAgICAgICAgbm93OiAwLFxuXG4gICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKG5vdykge1xuICAgICAgICAgICAgdmFyIGNsb2NrID0gY3JlYXRlT2JqZWN0KHRoaXMpO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG5vdyA9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgY2xvY2subm93ID0gbm93O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoISFub3cgJiYgdHlwZW9mIG5vdyA9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIm5vdyBzaG91bGQgYmUgbWlsbGlzZWNvbmRzIHNpbmNlIFVOSVggZXBvY2hcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBjbG9jaztcbiAgICAgICAgfSxcblxuICAgICAgICBzZXRUaW1lb3V0OiBmdW5jdGlvbiBzZXRUaW1lb3V0KGNhbGxiYWNrLCB0aW1lb3V0KSB7XG4gICAgICAgICAgICByZXR1cm4gYWRkVGltZXIuY2FsbCh0aGlzLCBhcmd1bWVudHMsIGZhbHNlKTtcbiAgICAgICAgfSxcblxuICAgICAgICBjbGVhclRpbWVvdXQ6IGZ1bmN0aW9uIGNsZWFyVGltZW91dCh0aW1lcklkKSB7XG4gICAgICAgICAgICBpZiAoIXRpbWVySWQpIHtcbiAgICAgICAgICAgICAgICAvLyBudWxsIGFwcGVhcnMgdG8gYmUgYWxsb3dlZCBpbiBtb3N0IGJyb3dzZXJzLCBhbmQgYXBwZWFycyB0byBiZSByZWxpZWQgdXBvbiBieSBzb21lIGxpYnJhcmllcywgbGlrZSBCb290c3RyYXAgY2Fyb3VzZWxcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMudGltZW91dHMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRpbWVvdXRzID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBpbiBOb2RlLCB0aW1lcklkIGlzIGFuIG9iamVjdCB3aXRoIC5yZWYoKS8udW5yZWYoKSwgYW5kXG4gICAgICAgICAgICAvLyBpdHMgLmlkIGZpZWxkIGlzIHRoZSBhY3R1YWwgdGltZXIgaWQuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRpbWVySWQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgIHRpbWVySWQgPSB0aW1lcklkLmlkXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGltZXJJZCBpbiB0aGlzLnRpbWVvdXRzKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMudGltZW91dHNbdGltZXJJZF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2V0SW50ZXJ2YWw6IGZ1bmN0aW9uIHNldEludGVydmFsKGNhbGxiYWNrLCB0aW1lb3V0KSB7XG4gICAgICAgICAgICByZXR1cm4gYWRkVGltZXIuY2FsbCh0aGlzLCBhcmd1bWVudHMsIHRydWUpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNsZWFySW50ZXJ2YWw6IGZ1bmN0aW9uIGNsZWFySW50ZXJ2YWwodGltZXJJZCkge1xuICAgICAgICAgICAgdGhpcy5jbGVhclRpbWVvdXQodGltZXJJZCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2V0SW1tZWRpYXRlOiBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHZhciBwYXNzVGhydUFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgICAgICAgICByZXR1cm4gYWRkVGltZXIuY2FsbCh0aGlzLCBbY2FsbGJhY2ssIDBdLmNvbmNhdChwYXNzVGhydUFyZ3MpLCBmYWxzZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY2xlYXJJbW1lZGlhdGU6IGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKHRpbWVySWQpIHtcbiAgICAgICAgICAgIHRoaXMuY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHRpY2s6IGZ1bmN0aW9uIHRpY2sobXMpIHtcbiAgICAgICAgICAgIG1zID0gdHlwZW9mIG1zID09IFwibnVtYmVyXCIgPyBtcyA6IHBhcnNlVGltZShtcyk7XG4gICAgICAgICAgICB2YXIgdGlja0Zyb20gPSB0aGlzLm5vdywgdGlja1RvID0gdGhpcy5ub3cgKyBtcywgcHJldmlvdXMgPSB0aGlzLm5vdztcbiAgICAgICAgICAgIHZhciB0aW1lciA9IHRoaXMuZmlyc3RUaW1lckluUmFuZ2UodGlja0Zyb20sIHRpY2tUbyk7XG5cbiAgICAgICAgICAgIHZhciBmaXJzdEV4Y2VwdGlvbjtcbiAgICAgICAgICAgIHdoaWxlICh0aW1lciAmJiB0aWNrRnJvbSA8PSB0aWNrVG8pIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy50aW1lb3V0c1t0aW1lci5pZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgdGlja0Zyb20gPSB0aGlzLm5vdyA9IHRpbWVyLmNhbGxBdDtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbGxUaW1lcih0aW1lcik7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBmaXJzdEV4Y2VwdGlvbiA9IGZpcnN0RXhjZXB0aW9uIHx8IGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aW1lciA9IHRoaXMuZmlyc3RUaW1lckluUmFuZ2UocHJldmlvdXMsIHRpY2tUbyk7XG4gICAgICAgICAgICAgICAgcHJldmlvdXMgPSB0aWNrRnJvbTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5ub3cgPSB0aWNrVG87XG5cbiAgICAgICAgICAgIGlmIChmaXJzdEV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICB0aHJvdyBmaXJzdEV4Y2VwdGlvbjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubm93O1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpcnN0VGltZXJJblJhbmdlOiBmdW5jdGlvbiAoZnJvbSwgdG8pIHtcbiAgICAgICAgICAgIHZhciB0aW1lciwgc21hbGxlc3QgPSBudWxsLCBvcmlnaW5hbFRpbWVyO1xuXG4gICAgICAgICAgICBmb3IgKHZhciBpZCBpbiB0aGlzLnRpbWVvdXRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudGltZW91dHMuaGFzT3duUHJvcGVydHkoaWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnRpbWVvdXRzW2lkXS5jYWxsQXQgPCBmcm9tIHx8IHRoaXMudGltZW91dHNbaWRdLmNhbGxBdCA+IHRvKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChzbWFsbGVzdCA9PT0gbnVsbCB8fCB0aGlzLnRpbWVvdXRzW2lkXS5jYWxsQXQgPCBzbWFsbGVzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxUaW1lciA9IHRoaXMudGltZW91dHNbaWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgc21hbGxlc3QgPSB0aGlzLnRpbWVvdXRzW2lkXS5jYWxsQXQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVyID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmM6IHRoaXMudGltZW91dHNbaWRdLmZ1bmMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbEF0OiB0aGlzLnRpbWVvdXRzW2lkXS5jYWxsQXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWw6IHRoaXMudGltZW91dHNbaWRdLmludGVydmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiB0aGlzLnRpbWVvdXRzW2lkXS5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZva2VBcmdzOiB0aGlzLnRpbWVvdXRzW2lkXS5pbnZva2VBcmdzXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGltZXIgfHwgbnVsbDtcbiAgICAgICAgfSxcblxuICAgICAgICBjYWxsVGltZXI6IGZ1bmN0aW9uICh0aW1lcikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aW1lci5pbnRlcnZhbCA9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50aW1lb3V0c1t0aW1lci5pZF0uY2FsbEF0ICs9IHRpbWVyLmludGVydmFsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy50aW1lb3V0c1t0aW1lci5pZF07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0aW1lci5mdW5jID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICB0aW1lci5mdW5jLmFwcGx5KG51bGwsIHRpbWVyLmludm9rZUFyZ3MpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGV2YWwodGltZXIuZnVuYyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICB2YXIgZXhjZXB0aW9uID0gZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF0aGlzLnRpbWVvdXRzW3RpbWVyLmlkXSkge1xuICAgICAgICAgICAgICAgIGlmIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IGV4Y2VwdGlvbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgIHRocm93IGV4Y2VwdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICByZXNldDogZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVvdXRzID0ge307XG4gICAgICAgIH0sXG5cbiAgICAgICAgRGF0ZTogKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBOYXRpdmVEYXRlID0gRGF0ZTtcblxuICAgICAgICAgICAgZnVuY3Rpb24gQ2xvY2tEYXRlKHllYXIsIG1vbnRoLCBkYXRlLCBob3VyLCBtaW51dGUsIHNlY29uZCwgbXMpIHtcbiAgICAgICAgICAgICAgICAvLyBEZWZlbnNpdmUgYW5kIHZlcmJvc2UgdG8gYXZvaWQgcG90ZW50aWFsIGhhcm0gaW4gcGFzc2luZ1xuICAgICAgICAgICAgICAgIC8vIGV4cGxpY2l0IHVuZGVmaW5lZCB3aGVuIHVzZXIgZG9lcyBub3QgcGFzcyBhcmd1bWVudFxuICAgICAgICAgICAgICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVEYXRlKENsb2NrRGF0ZS5jbG9jay5ub3cpO1xuICAgICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVEYXRlKHllYXIpO1xuICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVEYXRlKHllYXIsIG1vbnRoKTtcbiAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTmF0aXZlRGF0ZSh5ZWFyLCBtb250aCwgZGF0ZSk7XG4gICAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE5hdGl2ZURhdGUoeWVhciwgbW9udGgsIGRhdGUsIGhvdXIpO1xuICAgICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVEYXRlKHllYXIsIG1vbnRoLCBkYXRlLCBob3VyLCBtaW51dGUpO1xuICAgICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVEYXRlKHllYXIsIG1vbnRoLCBkYXRlLCBob3VyLCBtaW51dGUsIHNlY29uZCk7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVEYXRlKHllYXIsIG1vbnRoLCBkYXRlLCBob3VyLCBtaW51dGUsIHNlY29uZCwgbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG1pcnJvckRhdGVQcm9wZXJ0aWVzKENsb2NrRGF0ZSwgTmF0aXZlRGF0ZSk7XG4gICAgICAgIH0oKSlcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gbWlycm9yRGF0ZVByb3BlcnRpZXModGFyZ2V0LCBzb3VyY2UpIHtcbiAgICAgICAgaWYgKHNvdXJjZS5ub3cpIHtcbiAgICAgICAgICAgIHRhcmdldC5ub3cgPSBmdW5jdGlvbiBub3coKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldC5jbG9jay5ub3c7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsZXRlIHRhcmdldC5ub3c7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc291cmNlLnRvU291cmNlKSB7XG4gICAgICAgICAgICB0YXJnZXQudG9Tb3VyY2UgPSBmdW5jdGlvbiB0b1NvdXJjZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc291cmNlLnRvU291cmNlKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsZXRlIHRhcmdldC50b1NvdXJjZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRhcmdldC50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS50b1N0cmluZygpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRhcmdldC5wcm90b3R5cGUgPSBzb3VyY2UucHJvdG90eXBlO1xuICAgICAgICB0YXJnZXQucGFyc2UgPSBzb3VyY2UucGFyc2U7XG4gICAgICAgIHRhcmdldC5VVEMgPSBzb3VyY2UuVVRDO1xuICAgICAgICB0YXJnZXQucHJvdG90eXBlLnRvVVRDU3RyaW5nID0gc291cmNlLnByb3RvdHlwZS50b1VUQ1N0cmluZztcblxuICAgICAgICBmb3IgKHZhciBwcm9wIGluIHNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKHNvdXJjZS5oYXNPd25Qcm9wZXJ0eShwcm9wKSkge1xuICAgICAgICAgICAgICAgIHRhcmdldFtwcm9wXSA9IHNvdXJjZVtwcm9wXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgdmFyIG1ldGhvZHMgPSBbXCJEYXRlXCIsIFwic2V0VGltZW91dFwiLCBcInNldEludGVydmFsXCIsXG4gICAgICAgICAgICAgICAgICAgXCJjbGVhclRpbWVvdXRcIiwgXCJjbGVhckludGVydmFsXCJdO1xuXG4gICAgaWYgKHR5cGVvZiBnbG9iYWwuc2V0SW1tZWRpYXRlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIG1ldGhvZHMucHVzaChcInNldEltbWVkaWF0ZVwiKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGdsb2JhbC5jbGVhckltbWVkaWF0ZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBtZXRob2RzLnB1c2goXCJjbGVhckltbWVkaWF0ZVwiKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXN0b3JlKCkge1xuICAgICAgICB2YXIgbWV0aG9kO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5tZXRob2RzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgbWV0aG9kID0gdGhpcy5tZXRob2RzW2ldO1xuXG4gICAgICAgICAgICBpZiAoZ2xvYmFsW21ldGhvZF0uaGFkT3duUHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICBnbG9iYWxbbWV0aG9kXSA9IHRoaXNbXCJfXCIgKyBtZXRob2RdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgZ2xvYmFsW21ldGhvZF07XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFByZXZlbnQgbXVsdGlwbGUgZXhlY3V0aW9ucyB3aGljaCB3aWxsIGNvbXBsZXRlbHkgcmVtb3ZlIHRoZXNlIHByb3BzXG4gICAgICAgIHRoaXMubWV0aG9kcyA9IFtdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0dWJHbG9iYWwobWV0aG9kLCBjbG9jaykge1xuICAgICAgICBjbG9ja1ttZXRob2RdLmhhZE93blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGdsb2JhbCwgbWV0aG9kKTtcbiAgICAgICAgY2xvY2tbXCJfXCIgKyBtZXRob2RdID0gZ2xvYmFsW21ldGhvZF07XG5cbiAgICAgICAgaWYgKG1ldGhvZCA9PSBcIkRhdGVcIikge1xuICAgICAgICAgICAgdmFyIGRhdGUgPSBtaXJyb3JEYXRlUHJvcGVydGllcyhjbG9ja1ttZXRob2RdLCBnbG9iYWxbbWV0aG9kXSk7XG4gICAgICAgICAgICBnbG9iYWxbbWV0aG9kXSA9IGRhdGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbG9iYWxbbWV0aG9kXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2xvY2tbbWV0aG9kXS5hcHBseShjbG9jaywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGZvciAodmFyIHByb3AgaW4gY2xvY2tbbWV0aG9kXSkge1xuICAgICAgICAgICAgICAgIGlmIChjbG9ja1ttZXRob2RdLmhhc093blByb3BlcnR5KHByb3ApKSB7XG4gICAgICAgICAgICAgICAgICAgIGdsb2JhbFttZXRob2RdW3Byb3BdID0gY2xvY2tbbWV0aG9kXVtwcm9wXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBnbG9iYWxbbWV0aG9kXS5jbG9jayA9IGNsb2NrO1xuICAgIH1cblxuICAgIHNpbm9uLnVzZUZha2VUaW1lcnMgPSBmdW5jdGlvbiB1c2VGYWtlVGltZXJzKG5vdykge1xuICAgICAgICB2YXIgY2xvY2sgPSBzaW5vbi5jbG9jay5jcmVhdGUobm93KTtcbiAgICAgICAgY2xvY2sucmVzdG9yZSA9IHJlc3RvcmU7XG4gICAgICAgIGNsb2NrLm1ldGhvZHMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2Ygbm93ID09IFwibnVtYmVyXCIgPyAxIDogMCk7XG5cbiAgICAgICAgaWYgKGNsb2NrLm1ldGhvZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBjbG9jay5tZXRob2RzID0gbWV0aG9kcztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gY2xvY2subWV0aG9kcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIHN0dWJHbG9iYWwoY2xvY2subWV0aG9kc1tpXSwgY2xvY2spO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNsb2NrO1xuICAgIH07XG59KHR5cGVvZiBnbG9iYWwgIT0gXCJ1bmRlZmluZWRcIiAmJiB0eXBlb2YgZ2xvYmFsICE9PSBcImZ1bmN0aW9uXCIgPyBnbG9iYWwgOiB0aGlzKSk7XG5cbnNpbm9uLnRpbWVycyA9IHtcbiAgICBzZXRUaW1lb3V0OiBzZXRUaW1lb3V0LFxuICAgIGNsZWFyVGltZW91dDogY2xlYXJUaW1lb3V0LFxuICAgIHNldEltbWVkaWF0ZTogKHR5cGVvZiBzZXRJbW1lZGlhdGUgIT09IFwidW5kZWZpbmVkXCIgPyBzZXRJbW1lZGlhdGUgOiB1bmRlZmluZWQpLFxuICAgIGNsZWFySW1tZWRpYXRlOiAodHlwZW9mIGNsZWFySW1tZWRpYXRlICE9PSBcInVuZGVmaW5lZFwiID8gY2xlYXJJbW1lZGlhdGU6IHVuZGVmaW5lZCksXG4gICAgc2V0SW50ZXJ2YWw6IHNldEludGVydmFsLFxuICAgIGNsZWFySW50ZXJ2YWw6IGNsZWFySW50ZXJ2YWwsXG4gICAgRGF0ZTogRGF0ZVxufTtcblxuaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBzaW5vbjtcbn1cblxufSkuY2FsbCh0aGlzLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSkiLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG4oKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kICYmIGZ1bmN0aW9uIChtKSB7XG4gICAgZGVmaW5lKFwiZm9ybWF0aW9cIiwgW1wic2Ftc2FtXCJdLCBtKTtcbn0pIHx8ICh0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIGZ1bmN0aW9uIChtKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBtKHJlcXVpcmUoXCJzYW1zYW1cIikpO1xufSkgfHwgZnVuY3Rpb24gKG0pIHsgdGhpcy5mb3JtYXRpbyA9IG0odGhpcy5zYW1zYW0pOyB9XG4pKGZ1bmN0aW9uIChzYW1zYW0pIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIHZhciBmb3JtYXRpbyA9IHtcbiAgICAgICAgZXhjbHVkZUNvbnN0cnVjdG9yczogW1wiT2JqZWN0XCIsIC9eLiQvXSxcbiAgICAgICAgcXVvdGVTdHJpbmdzOiB0cnVlXG4gICAgfTtcblxuICAgIHZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4gICAgdmFyIHNwZWNpYWxPYmplY3RzID0gW107XG4gICAgaWYgKHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgc3BlY2lhbE9iamVjdHMucHVzaCh7IG9iamVjdDogZ2xvYmFsLCB2YWx1ZTogXCJbb2JqZWN0IGdsb2JhbF1cIiB9KTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBzcGVjaWFsT2JqZWN0cy5wdXNoKHtcbiAgICAgICAgICAgIG9iamVjdDogZG9jdW1lbnQsXG4gICAgICAgICAgICB2YWx1ZTogXCJbb2JqZWN0IEhUTUxEb2N1bWVudF1cIlxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgc3BlY2lhbE9iamVjdHMucHVzaCh7IG9iamVjdDogd2luZG93LCB2YWx1ZTogXCJbb2JqZWN0IFdpbmRvd11cIiB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBmdW5jdGlvbk5hbWUoZnVuYykge1xuICAgICAgICBpZiAoIWZ1bmMpIHsgcmV0dXJuIFwiXCI7IH1cbiAgICAgICAgaWYgKGZ1bmMuZGlzcGxheU5hbWUpIHsgcmV0dXJuIGZ1bmMuZGlzcGxheU5hbWU7IH1cbiAgICAgICAgaWYgKGZ1bmMubmFtZSkgeyByZXR1cm4gZnVuYy5uYW1lOyB9XG4gICAgICAgIHZhciBtYXRjaGVzID0gZnVuYy50b1N0cmluZygpLm1hdGNoKC9mdW5jdGlvblxccysoW15cXChdKykvbSk7XG4gICAgICAgIHJldHVybiAobWF0Y2hlcyAmJiBtYXRjaGVzWzFdKSB8fCBcIlwiO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbnN0cnVjdG9yTmFtZShmLCBvYmplY3QpIHtcbiAgICAgICAgdmFyIG5hbWUgPSBmdW5jdGlvbk5hbWUob2JqZWN0ICYmIG9iamVjdC5jb25zdHJ1Y3Rvcik7XG4gICAgICAgIHZhciBleGNsdWRlcyA9IGYuZXhjbHVkZUNvbnN0cnVjdG9ycyB8fFxuICAgICAgICAgICAgICAgIGZvcm1hdGlvLmV4Y2x1ZGVDb25zdHJ1Y3RvcnMgfHwgW107XG5cbiAgICAgICAgdmFyIGksIGw7XG4gICAgICAgIGZvciAoaSA9IDAsIGwgPSBleGNsdWRlcy5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZXhjbHVkZXNbaV0gPT09IFwic3RyaW5nXCIgJiYgZXhjbHVkZXNbaV0gPT09IG5hbWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZXhjbHVkZXNbaV0udGVzdCAmJiBleGNsdWRlc1tpXS50ZXN0KG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmFtZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0NpcmN1bGFyKG9iamVjdCwgb2JqZWN0cykge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gXCJvYmplY3RcIikgeyByZXR1cm4gZmFsc2U7IH1cbiAgICAgICAgdmFyIGksIGw7XG4gICAgICAgIGZvciAoaSA9IDAsIGwgPSBvYmplY3RzLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgICAgICAgICAgaWYgKG9iamVjdHNbaV0gPT09IG9iamVjdCkgeyByZXR1cm4gdHJ1ZTsgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhc2NpaShmLCBvYmplY3QsIHByb2Nlc3NlZCwgaW5kZW50KSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB2YXIgcXMgPSBmLnF1b3RlU3RyaW5ncztcbiAgICAgICAgICAgIHZhciBxdW90ZSA9IHR5cGVvZiBxcyAhPT0gXCJib29sZWFuXCIgfHwgcXM7XG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc2VkIHx8IHF1b3RlID8gJ1wiJyArIG9iamVjdCArICdcIicgOiBvYmplY3Q7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIG9iamVjdCA9PT0gXCJmdW5jdGlvblwiICYmICEob2JqZWN0IGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgICAgICAgICAgcmV0dXJuIGFzY2lpLmZ1bmMob2JqZWN0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb2Nlc3NlZCA9IHByb2Nlc3NlZCB8fCBbXTtcblxuICAgICAgICBpZiAoaXNDaXJjdWxhcihvYmplY3QsIHByb2Nlc3NlZCkpIHsgcmV0dXJuIFwiW0NpcmN1bGFyXVwiOyB9XG5cbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09PSBcIltvYmplY3QgQXJyYXldXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBhc2NpaS5hcnJheS5jYWxsKGYsIG9iamVjdCwgcHJvY2Vzc2VkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghb2JqZWN0KSB7IHJldHVybiBTdHJpbmcoKDEvb2JqZWN0KSA9PT0gLUluZmluaXR5ID8gXCItMFwiIDogb2JqZWN0KTsgfVxuICAgICAgICBpZiAoc2Ftc2FtLmlzRWxlbWVudChvYmplY3QpKSB7IHJldHVybiBhc2NpaS5lbGVtZW50KG9iamVjdCk7IH1cblxuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC50b1N0cmluZyA9PT0gXCJmdW5jdGlvblwiICYmXG4gICAgICAgICAgICAgICAgb2JqZWN0LnRvU3RyaW5nICE9PSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaSwgbDtcbiAgICAgICAgZm9yIChpID0gMCwgbCA9IHNwZWNpYWxPYmplY3RzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgaWYgKG9iamVjdCA9PT0gc3BlY2lhbE9iamVjdHNbaV0ub2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNwZWNpYWxPYmplY3RzW2ldLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFzY2lpLm9iamVjdC5jYWxsKGYsIG9iamVjdCwgcHJvY2Vzc2VkLCBpbmRlbnQpO1xuICAgIH1cblxuICAgIGFzY2lpLmZ1bmMgPSBmdW5jdGlvbiAoZnVuYykge1xuICAgICAgICByZXR1cm4gXCJmdW5jdGlvbiBcIiArIGZ1bmN0aW9uTmFtZShmdW5jKSArIFwiKCkge31cIjtcbiAgICB9O1xuXG4gICAgYXNjaWkuYXJyYXkgPSBmdW5jdGlvbiAoYXJyYXksIHByb2Nlc3NlZCkge1xuICAgICAgICBwcm9jZXNzZWQgPSBwcm9jZXNzZWQgfHwgW107XG4gICAgICAgIHByb2Nlc3NlZC5wdXNoKGFycmF5KTtcbiAgICAgICAgdmFyIGksIGwsIHBpZWNlcyA9IFtdO1xuICAgICAgICBmb3IgKGkgPSAwLCBsID0gYXJyYXkubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgICAgICAgICBwaWVjZXMucHVzaChhc2NpaSh0aGlzLCBhcnJheVtpXSwgcHJvY2Vzc2VkKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFwiW1wiICsgcGllY2VzLmpvaW4oXCIsIFwiKSArIFwiXVwiO1xuICAgIH07XG5cbiAgICBhc2NpaS5vYmplY3QgPSBmdW5jdGlvbiAob2JqZWN0LCBwcm9jZXNzZWQsIGluZGVudCkge1xuICAgICAgICBwcm9jZXNzZWQgPSBwcm9jZXNzZWQgfHwgW107XG4gICAgICAgIHByb2Nlc3NlZC5wdXNoKG9iamVjdCk7XG4gICAgICAgIGluZGVudCA9IGluZGVudCB8fCAwO1xuICAgICAgICB2YXIgcGllY2VzID0gW10sIHByb3BlcnRpZXMgPSBzYW1zYW0ua2V5cyhvYmplY3QpLnNvcnQoKTtcbiAgICAgICAgdmFyIGxlbmd0aCA9IDM7XG4gICAgICAgIHZhciBwcm9wLCBzdHIsIG9iaiwgaSwgbDtcblxuICAgICAgICBmb3IgKGkgPSAwLCBsID0gcHJvcGVydGllcy5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgICAgIHByb3AgPSBwcm9wZXJ0aWVzW2ldO1xuICAgICAgICAgICAgb2JqID0gb2JqZWN0W3Byb3BdO1xuXG4gICAgICAgICAgICBpZiAoaXNDaXJjdWxhcihvYmosIHByb2Nlc3NlZCkpIHtcbiAgICAgICAgICAgICAgICBzdHIgPSBcIltDaXJjdWxhcl1cIjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RyID0gYXNjaWkodGhpcywgb2JqLCBwcm9jZXNzZWQsIGluZGVudCArIDIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzdHIgPSAoL1xccy8udGVzdChwcm9wKSA/ICdcIicgKyBwcm9wICsgJ1wiJyA6IHByb3ApICsgXCI6IFwiICsgc3RyO1xuICAgICAgICAgICAgbGVuZ3RoICs9IHN0ci5sZW5ndGg7XG4gICAgICAgICAgICBwaWVjZXMucHVzaChzdHIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNvbnMgPSBjb25zdHJ1Y3Rvck5hbWUodGhpcywgb2JqZWN0KTtcbiAgICAgICAgdmFyIHByZWZpeCA9IGNvbnMgPyBcIltcIiArIGNvbnMgKyBcIl0gXCIgOiBcIlwiO1xuICAgICAgICB2YXIgaXMgPSBcIlwiO1xuICAgICAgICBmb3IgKGkgPSAwLCBsID0gaW5kZW50OyBpIDwgbDsgKytpKSB7IGlzICs9IFwiIFwiOyB9XG5cbiAgICAgICAgaWYgKGxlbmd0aCArIGluZGVudCA+IDgwKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJlZml4ICsgXCJ7XFxuICBcIiArIGlzICsgcGllY2VzLmpvaW4oXCIsXFxuICBcIiArIGlzKSArIFwiXFxuXCIgK1xuICAgICAgICAgICAgICAgIGlzICsgXCJ9XCI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByZWZpeCArIFwieyBcIiArIHBpZWNlcy5qb2luKFwiLCBcIikgKyBcIiB9XCI7XG4gICAgfTtcblxuICAgIGFzY2lpLmVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICB2YXIgdGFnTmFtZSA9IGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICB2YXIgYXR0cnMgPSBlbGVtZW50LmF0dHJpYnV0ZXMsIGF0dHIsIHBhaXJzID0gW10sIGF0dHJOYW1lLCBpLCBsLCB2YWw7XG5cbiAgICAgICAgZm9yIChpID0gMCwgbCA9IGF0dHJzLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgICAgICAgICAgYXR0ciA9IGF0dHJzLml0ZW0oaSk7XG4gICAgICAgICAgICBhdHRyTmFtZSA9IGF0dHIubm9kZU5hbWUudG9Mb3dlckNhc2UoKS5yZXBsYWNlKFwiaHRtbDpcIiwgXCJcIik7XG4gICAgICAgICAgICB2YWwgPSBhdHRyLm5vZGVWYWx1ZTtcbiAgICAgICAgICAgIGlmIChhdHRyTmFtZSAhPT0gXCJjb250ZW50ZWRpdGFibGVcIiB8fCB2YWwgIT09IFwiaW5oZXJpdFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhdmFsKSB7IHBhaXJzLnB1c2goYXR0ck5hbWUgKyBcIj1cXFwiXCIgKyB2YWwgKyBcIlxcXCJcIik7IH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBmb3JtYXR0ZWQgPSBcIjxcIiArIHRhZ05hbWUgKyAocGFpcnMubGVuZ3RoID4gMCA/IFwiIFwiIDogXCJcIik7XG4gICAgICAgIHZhciBjb250ZW50ID0gZWxlbWVudC5pbm5lckhUTUw7XG5cbiAgICAgICAgaWYgKGNvbnRlbnQubGVuZ3RoID4gMjApIHtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBjb250ZW50LnN1YnN0cigwLCAyMCkgKyBcIlsuLi5dXCI7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVzID0gZm9ybWF0dGVkICsgcGFpcnMuam9pbihcIiBcIikgKyBcIj5cIiArIGNvbnRlbnQgK1xuICAgICAgICAgICAgICAgIFwiPC9cIiArIHRhZ05hbWUgKyBcIj5cIjtcblxuICAgICAgICByZXR1cm4gcmVzLnJlcGxhY2UoLyBjb250ZW50RWRpdGFibGU9XCJpbmhlcml0XCIvLCBcIlwiKTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gRm9ybWF0aW8ob3B0aW9ucykge1xuICAgICAgICBmb3IgKHZhciBvcHQgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgdGhpc1tvcHRdID0gb3B0aW9uc1tvcHRdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgRm9ybWF0aW8ucHJvdG90eXBlID0ge1xuICAgICAgICBmdW5jdGlvbk5hbWU6IGZ1bmN0aW9uTmFtZSxcblxuICAgICAgICBjb25maWd1cmU6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEZvcm1hdGlvKG9wdGlvbnMpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNvbnN0cnVjdG9yTmFtZTogZnVuY3Rpb24gKG9iamVjdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cnVjdG9yTmFtZSh0aGlzLCBvYmplY3QpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGFzY2lpOiBmdW5jdGlvbiAob2JqZWN0LCBwcm9jZXNzZWQsIGluZGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGFzY2lpKHRoaXMsIG9iamVjdCwgcHJvY2Vzc2VkLCBpbmRlbnQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBGb3JtYXRpby5wcm90b3R5cGU7XG59KTtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSkiLCIoKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kICYmIGZ1bmN0aW9uIChtKSB7IGRlZmluZShcInNhbXNhbVwiLCBtKTsgfSkgfHxcbiAodHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgZnVuY3Rpb24gKG0pIHsgbW9kdWxlLmV4cG9ydHMgPSBtKCk7IH0pIHx8IC8vIE5vZGVcbiBmdW5jdGlvbiAobSkgeyB0aGlzLnNhbXNhbSA9IG0oKTsgfSAvLyBCcm93c2VyIGdsb2JhbHNcbikoZnVuY3Rpb24gKCkge1xuICAgIHZhciBvID0gT2JqZWN0LnByb3RvdHlwZTtcbiAgICB2YXIgZGl2ID0gdHlwZW9mIGRvY3VtZW50ICE9PSBcInVuZGVmaW5lZFwiICYmIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgICBmdW5jdGlvbiBpc05hTih2YWx1ZSkge1xuICAgICAgICAvLyBVbmxpa2UgZ2xvYmFsIGlzTmFOLCB0aGlzIGF2b2lkcyB0eXBlIGNvZXJjaW9uXG4gICAgICAgIC8vIHR5cGVvZiBjaGVjayBhdm9pZHMgSUUgaG9zdCBvYmplY3QgaXNzdWVzLCBoYXQgdGlwIHRvXG4gICAgICAgIC8vIGxvZGFzaFxuICAgICAgICB2YXIgdmFsID0gdmFsdWU7IC8vIEpzTGludCB0aGlua3MgdmFsdWUgIT09IHZhbHVlIGlzIFwid2VpcmRcIlxuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiICYmIHZhbHVlICE9PSB2YWw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0Q2xhc3ModmFsdWUpIHtcbiAgICAgICAgLy8gUmV0dXJucyB0aGUgaW50ZXJuYWwgW1tDbGFzc11dIGJ5IGNhbGxpbmcgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ1xuICAgICAgICAvLyB3aXRoIHRoZSBwcm92aWRlZCB2YWx1ZSBhcyB0aGlzLiBSZXR1cm4gdmFsdWUgaXMgYSBzdHJpbmcsIG5hbWluZyB0aGVcbiAgICAgICAgLy8gaW50ZXJuYWwgY2xhc3MsIGUuZy4gXCJBcnJheVwiXG4gICAgICAgIHJldHVybiBvLnRvU3RyaW5nLmNhbGwodmFsdWUpLnNwbGl0KC9bIFxcXV0vKVsxXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAbmFtZSBzYW1zYW0uaXNBcmd1bWVudHNcbiAgICAgKiBAcGFyYW0gT2JqZWN0IG9iamVjdFxuICAgICAqXG4gICAgICogUmV0dXJucyBgYHRydWVgYCBpZiBgYG9iamVjdGBgIGlzIGFuIGBgYXJndW1lbnRzYGAgb2JqZWN0LFxuICAgICAqIGBgZmFsc2VgYCBvdGhlcndpc2UuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNBcmd1bWVudHMob2JqZWN0KSB7XG4gICAgICAgIGlmIChnZXRDbGFzcyhvYmplY3QpID09PSAnQXJndW1lbnRzJykgeyByZXR1cm4gdHJ1ZTsgfVxuICAgICAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gXCJvYmplY3RcIiB8fCB0eXBlb2Ygb2JqZWN0Lmxlbmd0aCAhPT0gXCJudW1iZXJcIiB8fFxuICAgICAgICAgICAgICAgIGdldENsYXNzKG9iamVjdCkgPT09IFwiQXJyYXlcIikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmNhbGxlZSA9PSBcImZ1bmN0aW9uXCIpIHsgcmV0dXJuIHRydWU7IH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG9iamVjdFtvYmplY3QubGVuZ3RoXSA9IDY7XG4gICAgICAgICAgICBkZWxldGUgb2JqZWN0W29iamVjdC5sZW5ndGhdO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQG5hbWUgc2Ftc2FtLmlzRWxlbWVudFxuICAgICAqIEBwYXJhbSBPYmplY3Qgb2JqZWN0XG4gICAgICpcbiAgICAgKiBSZXR1cm5zIGBgdHJ1ZWBgIGlmIGBgb2JqZWN0YGAgaXMgYSBET00gZWxlbWVudCBub2RlLiBVbmxpa2VcbiAgICAgKiBVbmRlcnNjb3JlLmpzL2xvZGFzaCwgdGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiBgYGZhbHNlYGAgaWYgYGBvYmplY3RgYFxuICAgICAqIGlzIGFuICplbGVtZW50LWxpa2UqIG9iamVjdCwgaS5lLiBhIHJlZ3VsYXIgb2JqZWN0IHdpdGggYSBgYG5vZGVUeXBlYGBcbiAgICAgKiBwcm9wZXJ0eSB0aGF0IGhvbGRzIHRoZSB2YWx1ZSBgYDFgYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VsZW1lbnQob2JqZWN0KSB7XG4gICAgICAgIGlmICghb2JqZWN0IHx8IG9iamVjdC5ub2RlVHlwZSAhPT0gMSB8fCAhZGl2KSB7IHJldHVybiBmYWxzZTsgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgb2JqZWN0LmFwcGVuZENoaWxkKGRpdik7XG4gICAgICAgICAgICBvYmplY3QucmVtb3ZlQ2hpbGQoZGl2KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBuYW1lIHNhbXNhbS5rZXlzXG4gICAgICogQHBhcmFtIE9iamVjdCBvYmplY3RcbiAgICAgKlxuICAgICAqIFJldHVybiBhbiBhcnJheSBvZiBvd24gcHJvcGVydHkgbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24ga2V5cyhvYmplY3QpIHtcbiAgICAgICAgdmFyIGtzID0gW10sIHByb3A7XG4gICAgICAgIGZvciAocHJvcCBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wKSkgeyBrcy5wdXNoKHByb3ApOyB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGtzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBuYW1lIHNhbXNhbS5pc0RhdGVcbiAgICAgKiBAcGFyYW0gT2JqZWN0IHZhbHVlXG4gICAgICpcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIG9iamVjdCBpcyBhIGBgRGF0ZWBgLCBvciAqZGF0ZS1saWtlKi4gRHVjayB0eXBpbmdcbiAgICAgKiBvZiBkYXRlIG9iamVjdHMgd29yayBieSBjaGVja2luZyB0aGF0IHRoZSBvYmplY3QgaGFzIGEgYGBnZXRUaW1lYGBcbiAgICAgKiBmdW5jdGlvbiB3aG9zZSByZXR1cm4gdmFsdWUgZXF1YWxzIHRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgb2JqZWN0J3NcbiAgICAgKiBgYHZhbHVlT2ZgYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0RhdGUodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZS5nZXRUaW1lID09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAgICAgdmFsdWUuZ2V0VGltZSgpID09IHZhbHVlLnZhbHVlT2YoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAbmFtZSBzYW1zYW0uaXNOZWdaZXJvXG4gICAgICogQHBhcmFtIE9iamVjdCB2YWx1ZVxuICAgICAqXG4gICAgICogUmV0dXJucyBgYHRydWVgYCBpZiBgYHZhbHVlYGAgaXMgYGAtMGBgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTmVnWmVybyh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlID09PSAtSW5maW5pdHk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQG5hbWUgc2Ftc2FtLmVxdWFsXG4gICAgICogQHBhcmFtIE9iamVjdCBvYmoxXG4gICAgICogQHBhcmFtIE9iamVjdCBvYmoyXG4gICAgICpcbiAgICAgKiBSZXR1cm5zIGBgdHJ1ZWBgIGlmIHR3byBvYmplY3RzIGFyZSBzdHJpY3RseSBlcXVhbC4gQ29tcGFyZWQgdG9cbiAgICAgKiBgYD09PWBgIHRoZXJlIGFyZSB0d28gZXhjZXB0aW9uczpcbiAgICAgKlxuICAgICAqICAgLSBOYU4gaXMgY29uc2lkZXJlZCBlcXVhbCB0byBOYU5cbiAgICAgKiAgIC0gLTAgYW5kICswIGFyZSBub3QgY29uc2lkZXJlZCBlcXVhbFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlkZW50aWNhbChvYmoxLCBvYmoyKSB7XG4gICAgICAgIGlmIChvYmoxID09PSBvYmoyIHx8IChpc05hTihvYmoxKSAmJiBpc05hTihvYmoyKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmoxICE9PSAwIHx8IGlzTmVnWmVybyhvYmoxKSA9PT0gaXNOZWdaZXJvKG9iajIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBAbmFtZSBzYW1zYW0uZGVlcEVxdWFsXG4gICAgICogQHBhcmFtIE9iamVjdCBvYmoxXG4gICAgICogQHBhcmFtIE9iamVjdCBvYmoyXG4gICAgICpcbiAgICAgKiBEZWVwIGVxdWFsIGNvbXBhcmlzb24uIFR3byB2YWx1ZXMgYXJlIFwiZGVlcCBlcXVhbFwiIGlmOlxuICAgICAqXG4gICAgICogICAtIFRoZXkgYXJlIGVxdWFsLCBhY2NvcmRpbmcgdG8gc2Ftc2FtLmlkZW50aWNhbFxuICAgICAqICAgLSBUaGV5IGFyZSBib3RoIGRhdGUgb2JqZWN0cyByZXByZXNlbnRpbmcgdGhlIHNhbWUgdGltZVxuICAgICAqICAgLSBUaGV5IGFyZSBib3RoIGFycmF5cyBjb250YWluaW5nIGVsZW1lbnRzIHRoYXQgYXJlIGFsbCBkZWVwRXF1YWxcbiAgICAgKiAgIC0gVGhleSBhcmUgb2JqZWN0cyB3aXRoIHRoZSBzYW1lIHNldCBvZiBwcm9wZXJ0aWVzLCBhbmQgZWFjaCBwcm9wZXJ0eVxuICAgICAqICAgICBpbiBgYG9iajFgYCBpcyBkZWVwRXF1YWwgdG8gdGhlIGNvcnJlc3BvbmRpbmcgcHJvcGVydHkgaW4gYGBvYmoyYGBcbiAgICAgKlxuICAgICAqIFN1cHBvcnRzIGN5Y2xpYyBvYmplY3RzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRlZXBFcXVhbEN5Y2xpYyhvYmoxLCBvYmoyKSB7XG5cbiAgICAgICAgLy8gdXNlZCBmb3IgY3ljbGljIGNvbXBhcmlzb25cbiAgICAgICAgLy8gY29udGFpbiBhbHJlYWR5IHZpc2l0ZWQgb2JqZWN0c1xuICAgICAgICB2YXIgb2JqZWN0czEgPSBbXSxcbiAgICAgICAgICAgIG9iamVjdHMyID0gW10sXG4gICAgICAgIC8vIGNvbnRhaW4gcGF0aGVzIChwb3NpdGlvbiBpbiB0aGUgb2JqZWN0IHN0cnVjdHVyZSlcbiAgICAgICAgLy8gb2YgdGhlIGFscmVhZHkgdmlzaXRlZCBvYmplY3RzXG4gICAgICAgIC8vIGluZGV4ZXMgc2FtZSBhcyBpbiBvYmplY3RzIGFycmF5c1xuICAgICAgICAgICAgcGF0aHMxID0gW10sXG4gICAgICAgICAgICBwYXRoczIgPSBbXSxcbiAgICAgICAgLy8gY29udGFpbnMgY29tYmluYXRpb25zIG9mIGFscmVhZHkgY29tcGFyZWQgb2JqZWN0c1xuICAgICAgICAvLyBpbiB0aGUgbWFubmVyOiB7IFwiJDFbJ3JlZiddJDJbJ3JlZiddXCI6IHRydWUgfVxuICAgICAgICAgICAgY29tcGFyZWQgPSB7fTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogdXNlZCB0byBjaGVjaywgaWYgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgaXMgYW4gb2JqZWN0XG4gICAgICAgICAqIChjeWNsaWMgbG9naWMgaXMgb25seSBuZWVkZWQgZm9yIG9iamVjdHMpXG4gICAgICAgICAqIG9ubHkgbmVlZGVkIGZvciBjeWNsaWMgbG9naWNcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgICAgICEodmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKSAmJlxuICAgICAgICAgICAgICAgICAgICAhKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgICAgJiZcbiAgICAgICAgICAgICAgICAgICAgISh2YWx1ZSBpbnN0YW5jZW9mIE51bWJlcikgICYmXG4gICAgICAgICAgICAgICAgICAgICEodmFsdWUgaW5zdGFuY2VvZiBSZWdFeHApICAmJlxuICAgICAgICAgICAgICAgICAgICAhKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSkge1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZ2l2ZW4gb2JqZWN0IGluIHRoZVxuICAgICAgICAgKiBnaXZlbiBvYmplY3RzIGFycmF5LCAtMSBpZiBub3QgY29udGFpbmVkXG4gICAgICAgICAqIG9ubHkgbmVlZGVkIGZvciBjeWNsaWMgbG9naWNcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGdldEluZGV4KG9iamVjdHMsIG9iaikge1xuXG4gICAgICAgICAgICB2YXIgaTtcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBvYmplY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdHNbaV0gPT09IG9iaikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGRvZXMgdGhlIHJlY3Vyc2lvbiBmb3IgdGhlIGRlZXAgZXF1YWwgY2hlY2tcbiAgICAgICAgcmV0dXJuIChmdW5jdGlvbiBkZWVwRXF1YWwob2JqMSwgb2JqMiwgcGF0aDEsIHBhdGgyKSB7XG4gICAgICAgICAgICB2YXIgdHlwZTEgPSB0eXBlb2Ygb2JqMTtcbiAgICAgICAgICAgIHZhciB0eXBlMiA9IHR5cGVvZiBvYmoyO1xuXG4gICAgICAgICAgICAvLyA9PSBudWxsIGFsc28gbWF0Y2hlcyB1bmRlZmluZWRcbiAgICAgICAgICAgIGlmIChvYmoxID09PSBvYmoyIHx8XG4gICAgICAgICAgICAgICAgICAgIGlzTmFOKG9iajEpIHx8IGlzTmFOKG9iajIpIHx8XG4gICAgICAgICAgICAgICAgICAgIG9iajEgPT0gbnVsbCB8fCBvYmoyID09IG51bGwgfHxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTEgIT09IFwib2JqZWN0XCIgfHwgdHlwZTIgIT09IFwib2JqZWN0XCIpIHtcblxuICAgICAgICAgICAgICAgIHJldHVybiBpZGVudGljYWwob2JqMSwgb2JqMik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEVsZW1lbnRzIGFyZSBvbmx5IGVxdWFsIGlmIGlkZW50aWNhbChleHBlY3RlZCwgYWN0dWFsKVxuICAgICAgICAgICAgaWYgKGlzRWxlbWVudChvYmoxKSB8fCBpc0VsZW1lbnQob2JqMikpIHsgcmV0dXJuIGZhbHNlOyB9XG5cbiAgICAgICAgICAgIHZhciBpc0RhdGUxID0gaXNEYXRlKG9iajEpLCBpc0RhdGUyID0gaXNEYXRlKG9iajIpO1xuICAgICAgICAgICAgaWYgKGlzRGF0ZTEgfHwgaXNEYXRlMikge1xuICAgICAgICAgICAgICAgIGlmICghaXNEYXRlMSB8fCAhaXNEYXRlMiB8fCBvYmoxLmdldFRpbWUoKSAhPT0gb2JqMi5nZXRUaW1lKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG9iajEgaW5zdGFuY2VvZiBSZWdFeHAgJiYgb2JqMiBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgICAgIGlmIChvYmoxLnRvU3RyaW5nKCkgIT09IG9iajIudG9TdHJpbmcoKSkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGNsYXNzMSA9IGdldENsYXNzKG9iajEpO1xuICAgICAgICAgICAgdmFyIGNsYXNzMiA9IGdldENsYXNzKG9iajIpO1xuICAgICAgICAgICAgdmFyIGtleXMxID0ga2V5cyhvYmoxKTtcbiAgICAgICAgICAgIHZhciBrZXlzMiA9IGtleXMob2JqMik7XG5cbiAgICAgICAgICAgIGlmIChpc0FyZ3VtZW50cyhvYmoxKSB8fCBpc0FyZ3VtZW50cyhvYmoyKSkge1xuICAgICAgICAgICAgICAgIGlmIChvYmoxLmxlbmd0aCAhPT0gb2JqMi5sZW5ndGgpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlMSAhPT0gdHlwZTIgfHwgY2xhc3MxICE9PSBjbGFzczIgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleXMxLmxlbmd0aCAhPT0ga2V5czIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBrZXksIGksIGwsXG4gICAgICAgICAgICAgICAgLy8gZm9sbG93aW5nIHZhcnMgYXJlIHVzZWQgZm9yIHRoZSBjeWNsaWMgbG9naWNcbiAgICAgICAgICAgICAgICB2YWx1ZTEsIHZhbHVlMixcbiAgICAgICAgICAgICAgICBpc09iamVjdDEsIGlzT2JqZWN0MixcbiAgICAgICAgICAgICAgICBpbmRleDEsIGluZGV4MixcbiAgICAgICAgICAgICAgICBuZXdQYXRoMSwgbmV3UGF0aDI7XG5cbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBrZXlzMS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICBrZXkgPSBrZXlzMVtpXTtcbiAgICAgICAgICAgICAgICBpZiAoIW8uaGFzT3duUHJvcGVydHkuY2FsbChvYmoyLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBTdGFydCBvZiB0aGUgY3ljbGljIGxvZ2ljXG5cbiAgICAgICAgICAgICAgICB2YWx1ZTEgPSBvYmoxW2tleV07XG4gICAgICAgICAgICAgICAgdmFsdWUyID0gb2JqMltrZXldO1xuXG4gICAgICAgICAgICAgICAgaXNPYmplY3QxID0gaXNPYmplY3QodmFsdWUxKTtcbiAgICAgICAgICAgICAgICBpc09iamVjdDIgPSBpc09iamVjdCh2YWx1ZTIpO1xuXG4gICAgICAgICAgICAgICAgLy8gZGV0ZXJtaW5lLCBpZiB0aGUgb2JqZWN0cyB3ZXJlIGFscmVhZHkgdmlzaXRlZFxuICAgICAgICAgICAgICAgIC8vIChpdCdzIGZhc3RlciB0byBjaGVjayBmb3IgaXNPYmplY3QgZmlyc3QsIHRoYW4gdG9cbiAgICAgICAgICAgICAgICAvLyBnZXQgLTEgZnJvbSBnZXRJbmRleCBmb3Igbm9uIG9iamVjdHMpXG4gICAgICAgICAgICAgICAgaW5kZXgxID0gaXNPYmplY3QxID8gZ2V0SW5kZXgob2JqZWN0czEsIHZhbHVlMSkgOiAtMTtcbiAgICAgICAgICAgICAgICBpbmRleDIgPSBpc09iamVjdDIgPyBnZXRJbmRleChvYmplY3RzMiwgdmFsdWUyKSA6IC0xO1xuXG4gICAgICAgICAgICAgICAgLy8gZGV0ZXJtaW5lIHRoZSBuZXcgcGF0aGVzIG9mIHRoZSBvYmplY3RzXG4gICAgICAgICAgICAgICAgLy8gLSBmb3Igbm9uIGN5Y2xpYyBvYmplY3RzIHRoZSBjdXJyZW50IHBhdGggd2lsbCBiZSBleHRlbmRlZFxuICAgICAgICAgICAgICAgIC8vICAgYnkgY3VycmVudCBwcm9wZXJ0eSBuYW1lXG4gICAgICAgICAgICAgICAgLy8gLSBmb3IgY3ljbGljIG9iamVjdHMgdGhlIHN0b3JlZCBwYXRoIGlzIHRha2VuXG4gICAgICAgICAgICAgICAgbmV3UGF0aDEgPSBpbmRleDEgIT09IC0xXG4gICAgICAgICAgICAgICAgICAgID8gcGF0aHMxW2luZGV4MV1cbiAgICAgICAgICAgICAgICAgICAgOiBwYXRoMSArICdbJyArIEpTT04uc3RyaW5naWZ5KGtleSkgKyAnXSc7XG4gICAgICAgICAgICAgICAgbmV3UGF0aDIgPSBpbmRleDIgIT09IC0xXG4gICAgICAgICAgICAgICAgICAgID8gcGF0aHMyW2luZGV4Ml1cbiAgICAgICAgICAgICAgICAgICAgOiBwYXRoMiArICdbJyArIEpTT04uc3RyaW5naWZ5KGtleSkgKyAnXSc7XG5cbiAgICAgICAgICAgICAgICAvLyBzdG9wIHJlY3Vyc2lvbiBpZiBjdXJyZW50IG9iamVjdHMgYXJlIGFscmVhZHkgY29tcGFyZWRcbiAgICAgICAgICAgICAgICBpZiAoY29tcGFyZWRbbmV3UGF0aDEgKyBuZXdQYXRoMl0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gcmVtZW1iZXIgdGhlIGN1cnJlbnQgb2JqZWN0cyBhbmQgdGhlaXIgcGF0aGVzXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4MSA9PT0gLTEgJiYgaXNPYmplY3QxKSB7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdHMxLnB1c2godmFsdWUxKTtcbiAgICAgICAgICAgICAgICAgICAgcGF0aHMxLnB1c2gobmV3UGF0aDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaW5kZXgyID09PSAtMSAmJiBpc09iamVjdDIpIHtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0czIucHVzaCh2YWx1ZTIpO1xuICAgICAgICAgICAgICAgICAgICBwYXRoczIucHVzaChuZXdQYXRoMik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gcmVtZW1iZXIgdGhhdCB0aGUgY3VycmVudCBvYmplY3RzIGFyZSBhbHJlYWR5IGNvbXBhcmVkXG4gICAgICAgICAgICAgICAgaWYgKGlzT2JqZWN0MSAmJiBpc09iamVjdDIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGFyZWRbbmV3UGF0aDEgKyBuZXdQYXRoMl0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEVuZCBvZiBjeWNsaWMgbG9naWNcblxuICAgICAgICAgICAgICAgIC8vIG5laXRoZXIgdmFsdWUxIG5vciB2YWx1ZTIgaXMgYSBjeWNsZVxuICAgICAgICAgICAgICAgIC8vIGNvbnRpbnVlIHdpdGggbmV4dCBsZXZlbFxuICAgICAgICAgICAgICAgIGlmICghZGVlcEVxdWFsKHZhbHVlMSwgdmFsdWUyLCBuZXdQYXRoMSwgbmV3UGF0aDIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgICAgIH0ob2JqMSwgb2JqMiwgJyQxJywgJyQyJykpO1xuICAgIH1cblxuICAgIHZhciBtYXRjaDtcblxuICAgIGZ1bmN0aW9uIGFycmF5Q29udGFpbnMoYXJyYXksIHN1YnNldCkge1xuICAgICAgICBpZiAoc3Vic2V0Lmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gdHJ1ZTsgfVxuICAgICAgICB2YXIgaSwgbCwgaiwgaztcbiAgICAgICAgZm9yIChpID0gMCwgbCA9IGFycmF5Lmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgICAgICAgICAgaWYgKG1hdGNoKGFycmF5W2ldLCBzdWJzZXRbMF0pKSB7XG4gICAgICAgICAgICAgICAgZm9yIChqID0gMCwgayA9IHN1YnNldC5sZW5ndGg7IGogPCBrOyArK2opIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRjaChhcnJheVtpICsgal0sIHN1YnNldFtqXSkpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAbmFtZSBzYW1zYW0ubWF0Y2hcbiAgICAgKiBAcGFyYW0gT2JqZWN0IG9iamVjdFxuICAgICAqIEBwYXJhbSBPYmplY3QgbWF0Y2hlclxuICAgICAqXG4gICAgICogQ29tcGFyZSBhcmJpdHJhcnkgdmFsdWUgYGBvYmplY3RgYCB3aXRoIG1hdGNoZXIuXG4gICAgICovXG4gICAgbWF0Y2ggPSBmdW5jdGlvbiBtYXRjaChvYmplY3QsIG1hdGNoZXIpIHtcbiAgICAgICAgaWYgKG1hdGNoZXIgJiYgdHlwZW9mIG1hdGNoZXIudGVzdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICByZXR1cm4gbWF0Y2hlci50ZXN0KG9iamVjdCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIG1hdGNoZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXIob2JqZWN0KSA9PT0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgbWF0Y2hlciA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgbWF0Y2hlciA9IG1hdGNoZXIudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIHZhciBub3ROdWxsID0gdHlwZW9mIG9iamVjdCA9PT0gXCJzdHJpbmdcIiB8fCAhIW9iamVjdDtcbiAgICAgICAgICAgIHJldHVybiBub3ROdWxsICYmXG4gICAgICAgICAgICAgICAgKFN0cmluZyhvYmplY3QpKS50b0xvd2VyQ2FzZSgpLmluZGV4T2YobWF0Y2hlcikgPj0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgbWF0Y2hlciA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXIgPT09IG9iamVjdDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgbWF0Y2hlciA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBtYXRjaGVyID09PSBvYmplY3Q7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZ2V0Q2xhc3Mob2JqZWN0KSA9PT0gXCJBcnJheVwiICYmIGdldENsYXNzKG1hdGNoZXIpID09PSBcIkFycmF5XCIpIHtcbiAgICAgICAgICAgIHJldHVybiBhcnJheUNvbnRhaW5zKG9iamVjdCwgbWF0Y2hlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWF0Y2hlciAmJiB0eXBlb2YgbWF0Y2hlciA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgdmFyIHByb3A7XG4gICAgICAgICAgICBmb3IgKHByb3AgaW4gbWF0Y2hlcikge1xuICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IG9iamVjdFtwcm9wXTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2Ygb2JqZWN0LmdldEF0dHJpYnV0ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gb2JqZWN0LmdldEF0dHJpYnV0ZShwcm9wKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhbWF0Y2godmFsdWUsIG1hdGNoZXJbcHJvcF0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1hdGNoZXIgd2FzIG5vdCBhIHN0cmluZywgYSBudW1iZXIsIGEgXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCJmdW5jdGlvbiwgYSBib29sZWFuIG9yIGFuIG9iamVjdFwiKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgaXNBcmd1bWVudHM6IGlzQXJndW1lbnRzLFxuICAgICAgICBpc0VsZW1lbnQ6IGlzRWxlbWVudCxcbiAgICAgICAgaXNEYXRlOiBpc0RhdGUsXG4gICAgICAgIGlzTmVnWmVybzogaXNOZWdaZXJvLFxuICAgICAgICBpZGVudGljYWw6IGlkZW50aWNhbCxcbiAgICAgICAgZGVlcEVxdWFsOiBkZWVwRXF1YWxDeWNsaWMsXG4gICAgICAgIG1hdGNoOiBtYXRjaCxcbiAgICAgICAga2V5czoga2V5c1xuICAgIH07XG59KTtcbiIsIi8vICAgICBVbmRlcnNjb3JlLmpzIDEuNy4wXG4vLyAgICAgaHR0cDovL3VuZGVyc2NvcmVqcy5vcmdcbi8vICAgICAoYykgMjAwOS0yMDE0IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4vLyAgICAgVW5kZXJzY29yZSBtYXkgYmUgZnJlZWx5IGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cblxuKGZ1bmN0aW9uKCkge1xuXG4gIC8vIEJhc2VsaW5lIHNldHVwXG4gIC8vIC0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gRXN0YWJsaXNoIHRoZSByb290IG9iamVjdCwgYHdpbmRvd2AgaW4gdGhlIGJyb3dzZXIsIG9yIGBleHBvcnRzYCBvbiB0aGUgc2VydmVyLlxuICB2YXIgcm9vdCA9IHRoaXM7XG5cbiAgLy8gU2F2ZSB0aGUgcHJldmlvdXMgdmFsdWUgb2YgdGhlIGBfYCB2YXJpYWJsZS5cbiAgdmFyIHByZXZpb3VzVW5kZXJzY29yZSA9IHJvb3QuXztcblxuICAvLyBTYXZlIGJ5dGVzIGluIHRoZSBtaW5pZmllZCAoYnV0IG5vdCBnemlwcGVkKSB2ZXJzaW9uOlxuICB2YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSwgT2JqUHJvdG8gPSBPYmplY3QucHJvdG90eXBlLCBGdW5jUHJvdG8gPSBGdW5jdGlvbi5wcm90b3R5cGU7XG5cbiAgLy8gQ3JlYXRlIHF1aWNrIHJlZmVyZW5jZSB2YXJpYWJsZXMgZm9yIHNwZWVkIGFjY2VzcyB0byBjb3JlIHByb3RvdHlwZXMuXG4gIHZhclxuICAgIHB1c2ggICAgICAgICAgICAgPSBBcnJheVByb3RvLnB1c2gsXG4gICAgc2xpY2UgICAgICAgICAgICA9IEFycmF5UHJvdG8uc2xpY2UsXG4gICAgY29uY2F0ICAgICAgICAgICA9IEFycmF5UHJvdG8uY29uY2F0LFxuICAgIHRvU3RyaW5nICAgICAgICAgPSBPYmpQcm90by50b1N0cmluZyxcbiAgICBoYXNPd25Qcm9wZXJ0eSAgID0gT2JqUHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbiAgLy8gQWxsICoqRUNNQVNjcmlwdCA1KiogbmF0aXZlIGZ1bmN0aW9uIGltcGxlbWVudGF0aW9ucyB0aGF0IHdlIGhvcGUgdG8gdXNlXG4gIC8vIGFyZSBkZWNsYXJlZCBoZXJlLlxuICB2YXJcbiAgICBuYXRpdmVJc0FycmF5ICAgICAgPSBBcnJheS5pc0FycmF5LFxuICAgIG5hdGl2ZUtleXMgICAgICAgICA9IE9iamVjdC5rZXlzLFxuICAgIG5hdGl2ZUJpbmQgICAgICAgICA9IEZ1bmNQcm90by5iaW5kO1xuXG4gIC8vIENyZWF0ZSBhIHNhZmUgcmVmZXJlbmNlIHRvIHRoZSBVbmRlcnNjb3JlIG9iamVjdCBmb3IgdXNlIGJlbG93LlxuICB2YXIgXyA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmIChvYmogaW5zdGFuY2VvZiBfKSByZXR1cm4gb2JqO1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBfKSkgcmV0dXJuIG5ldyBfKG9iaik7XG4gICAgdGhpcy5fd3JhcHBlZCA9IG9iajtcbiAgfTtcblxuICAvLyBFeHBvcnQgdGhlIFVuZGVyc2NvcmUgb2JqZWN0IGZvciAqKk5vZGUuanMqKiwgd2l0aFxuICAvLyBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSBmb3IgdGhlIG9sZCBgcmVxdWlyZSgpYCBBUEkuIElmIHdlJ3JlIGluXG4gIC8vIHRoZSBicm93c2VyLCBhZGQgYF9gIGFzIGEgZ2xvYmFsIG9iamVjdC5cbiAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgICAgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gXztcbiAgICB9XG4gICAgZXhwb3J0cy5fID0gXztcbiAgfSBlbHNlIHtcbiAgICByb290Ll8gPSBfO1xuICB9XG5cbiAgLy8gQ3VycmVudCB2ZXJzaW9uLlxuICBfLlZFUlNJT04gPSAnMS43LjAnO1xuXG4gIC8vIEludGVybmFsIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhbiBlZmZpY2llbnQgKGZvciBjdXJyZW50IGVuZ2luZXMpIHZlcnNpb25cbiAgLy8gb2YgdGhlIHBhc3NlZC1pbiBjYWxsYmFjaywgdG8gYmUgcmVwZWF0ZWRseSBhcHBsaWVkIGluIG90aGVyIFVuZGVyc2NvcmVcbiAgLy8gZnVuY3Rpb25zLlxuICB2YXIgY3JlYXRlQ2FsbGJhY2sgPSBmdW5jdGlvbihmdW5jLCBjb250ZXh0LCBhcmdDb3VudCkge1xuICAgIGlmIChjb250ZXh0ID09PSB2b2lkIDApIHJldHVybiBmdW5jO1xuICAgIHN3aXRjaCAoYXJnQ291bnQgPT0gbnVsbCA/IDMgOiBhcmdDb3VudCkge1xuICAgICAgY2FzZSAxOiByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmMuY2FsbChjb250ZXh0LCB2YWx1ZSk7XG4gICAgICB9O1xuICAgICAgY2FzZSAyOiByZXR1cm4gZnVuY3Rpb24odmFsdWUsIG90aGVyKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmNhbGwoY29udGV4dCwgdmFsdWUsIG90aGVyKTtcbiAgICAgIH07XG4gICAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIGZ1bmMuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgICAgfTtcbiAgICAgIGNhc2UgNDogcmV0dXJuIGZ1bmN0aW9uKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIGZ1bmMuY2FsbChjb250ZXh0LCBhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfTtcblxuICAvLyBBIG1vc3RseS1pbnRlcm5hbCBmdW5jdGlvbiB0byBnZW5lcmF0ZSBjYWxsYmFja3MgdGhhdCBjYW4gYmUgYXBwbGllZFxuICAvLyB0byBlYWNoIGVsZW1lbnQgaW4gYSBjb2xsZWN0aW9uLCByZXR1cm5pbmcgdGhlIGRlc2lyZWQgcmVzdWx0IOKAlCBlaXRoZXJcbiAgLy8gaWRlbnRpdHksIGFuIGFyYml0cmFyeSBjYWxsYmFjaywgYSBwcm9wZXJ0eSBtYXRjaGVyLCBvciBhIHByb3BlcnR5IGFjY2Vzc29yLlxuICBfLml0ZXJhdGVlID0gZnVuY3Rpb24odmFsdWUsIGNvbnRleHQsIGFyZ0NvdW50KSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBfLmlkZW50aXR5O1xuICAgIGlmIChfLmlzRnVuY3Rpb24odmFsdWUpKSByZXR1cm4gY3JlYXRlQ2FsbGJhY2sodmFsdWUsIGNvbnRleHQsIGFyZ0NvdW50KTtcbiAgICBpZiAoXy5pc09iamVjdCh2YWx1ZSkpIHJldHVybiBfLm1hdGNoZXModmFsdWUpO1xuICAgIHJldHVybiBfLnByb3BlcnR5KHZhbHVlKTtcbiAgfTtcblxuICAvLyBDb2xsZWN0aW9uIEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8vIFRoZSBjb3JuZXJzdG9uZSwgYW4gYGVhY2hgIGltcGxlbWVudGF0aW9uLCBha2EgYGZvckVhY2hgLlxuICAvLyBIYW5kbGVzIHJhdyBvYmplY3RzIGluIGFkZGl0aW9uIHRvIGFycmF5LWxpa2VzLiBUcmVhdHMgYWxsXG4gIC8vIHNwYXJzZSBhcnJheS1saWtlcyBhcyBpZiB0aGV5IHdlcmUgZGVuc2UuXG4gIF8uZWFjaCA9IF8uZm9yRWFjaCA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0ZWUsIGNvbnRleHQpIHtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiBvYmo7XG4gICAgaXRlcmF0ZWUgPSBjcmVhdGVDYWxsYmFjayhpdGVyYXRlZSwgY29udGV4dCk7XG4gICAgdmFyIGksIGxlbmd0aCA9IG9iai5sZW5ndGg7XG4gICAgaWYgKGxlbmd0aCA9PT0gK2xlbmd0aCkge1xuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGl0ZXJhdGVlKG9ialtpXSwgaSwgb2JqKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTtcbiAgICAgIGZvciAoaSA9IDAsIGxlbmd0aCA9IGtleXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaXRlcmF0ZWUob2JqW2tleXNbaV1dLCBrZXlzW2ldLCBvYmopO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqO1xuICB9O1xuXG4gIC8vIFJldHVybiB0aGUgcmVzdWx0cyBvZiBhcHBseWluZyB0aGUgaXRlcmF0ZWUgdG8gZWFjaCBlbGVtZW50LlxuICBfLm1hcCA9IF8uY29sbGVjdCA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0ZWUsIGNvbnRleHQpIHtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiBbXTtcbiAgICBpdGVyYXRlZSA9IF8uaXRlcmF0ZWUoaXRlcmF0ZWUsIGNvbnRleHQpO1xuICAgIHZhciBrZXlzID0gb2JqLmxlbmd0aCAhPT0gK29iai5sZW5ndGggJiYgXy5rZXlzKG9iaiksXG4gICAgICAgIGxlbmd0aCA9IChrZXlzIHx8IG9iaikubGVuZ3RoLFxuICAgICAgICByZXN1bHRzID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgICAgY3VycmVudEtleTtcbiAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjdXJyZW50S2V5ID0ga2V5cyA/IGtleXNbaW5kZXhdIDogaW5kZXg7XG4gICAgICByZXN1bHRzW2luZGV4XSA9IGl0ZXJhdGVlKG9ialtjdXJyZW50S2V5XSwgY3VycmVudEtleSwgb2JqKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH07XG5cbiAgdmFyIHJlZHVjZUVycm9yID0gJ1JlZHVjZSBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnO1xuXG4gIC8vICoqUmVkdWNlKiogYnVpbGRzIHVwIGEgc2luZ2xlIHJlc3VsdCBmcm9tIGEgbGlzdCBvZiB2YWx1ZXMsIGFrYSBgaW5qZWN0YCxcbiAgLy8gb3IgYGZvbGRsYC5cbiAgXy5yZWR1Y2UgPSBfLmZvbGRsID0gXy5pbmplY3QgPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBtZW1vLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSBvYmogPSBbXTtcbiAgICBpdGVyYXRlZSA9IGNyZWF0ZUNhbGxiYWNrKGl0ZXJhdGVlLCBjb250ZXh0LCA0KTtcbiAgICB2YXIga2V5cyA9IG9iai5sZW5ndGggIT09ICtvYmoubGVuZ3RoICYmIF8ua2V5cyhvYmopLFxuICAgICAgICBsZW5ndGggPSAoa2V5cyB8fCBvYmopLmxlbmd0aCxcbiAgICAgICAgaW5kZXggPSAwLCBjdXJyZW50S2V5O1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMykge1xuICAgICAgaWYgKCFsZW5ndGgpIHRocm93IG5ldyBUeXBlRXJyb3IocmVkdWNlRXJyb3IpO1xuICAgICAgbWVtbyA9IG9ialtrZXlzID8ga2V5c1tpbmRleCsrXSA6IGluZGV4KytdO1xuICAgIH1cbiAgICBmb3IgKDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGN1cnJlbnRLZXkgPSBrZXlzID8ga2V5c1tpbmRleF0gOiBpbmRleDtcbiAgICAgIG1lbW8gPSBpdGVyYXRlZShtZW1vLCBvYmpbY3VycmVudEtleV0sIGN1cnJlbnRLZXksIG9iaik7XG4gICAgfVxuICAgIHJldHVybiBtZW1vO1xuICB9O1xuXG4gIC8vIFRoZSByaWdodC1hc3NvY2lhdGl2ZSB2ZXJzaW9uIG9mIHJlZHVjZSwgYWxzbyBrbm93biBhcyBgZm9sZHJgLlxuICBfLnJlZHVjZVJpZ2h0ID0gXy5mb2xkciA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0ZWUsIG1lbW8sIGNvbnRleHQpIHtcbiAgICBpZiAob2JqID09IG51bGwpIG9iaiA9IFtdO1xuICAgIGl0ZXJhdGVlID0gY3JlYXRlQ2FsbGJhY2soaXRlcmF0ZWUsIGNvbnRleHQsIDQpO1xuICAgIHZhciBrZXlzID0gb2JqLmxlbmd0aCAhPT0gKyBvYmoubGVuZ3RoICYmIF8ua2V5cyhvYmopLFxuICAgICAgICBpbmRleCA9IChrZXlzIHx8IG9iaikubGVuZ3RoLFxuICAgICAgICBjdXJyZW50S2V5O1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMykge1xuICAgICAgaWYgKCFpbmRleCkgdGhyb3cgbmV3IFR5cGVFcnJvcihyZWR1Y2VFcnJvcik7XG4gICAgICBtZW1vID0gb2JqW2tleXMgPyBrZXlzWy0taW5kZXhdIDogLS1pbmRleF07XG4gICAgfVxuICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICBjdXJyZW50S2V5ID0ga2V5cyA/IGtleXNbaW5kZXhdIDogaW5kZXg7XG4gICAgICBtZW1vID0gaXRlcmF0ZWUobWVtbywgb2JqW2N1cnJlbnRLZXldLCBjdXJyZW50S2V5LCBvYmopO1xuICAgIH1cbiAgICByZXR1cm4gbWVtbztcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIGZpcnN0IHZhbHVlIHdoaWNoIHBhc3NlcyBhIHRydXRoIHRlc3QuIEFsaWFzZWQgYXMgYGRldGVjdGAuXG4gIF8uZmluZCA9IF8uZGV0ZWN0ID0gZnVuY3Rpb24ob2JqLCBwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0O1xuICAgIHByZWRpY2F0ZSA9IF8uaXRlcmF0ZWUocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICBfLnNvbWUob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBsaXN0KSkge1xuICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyB0aGF0IHBhc3MgYSB0cnV0aCB0ZXN0LlxuICAvLyBBbGlhc2VkIGFzIGBzZWxlY3RgLlxuICBfLmZpbHRlciA9IF8uc2VsZWN0ID0gZnVuY3Rpb24ob2JqLCBwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHJlc3VsdHM7XG4gICAgcHJlZGljYXRlID0gXy5pdGVyYXRlZShwcmVkaWNhdGUsIGNvbnRleHQpO1xuICAgIF8uZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGxpc3QpKSByZXN1bHRzLnB1c2godmFsdWUpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9O1xuXG4gIC8vIFJldHVybiBhbGwgdGhlIGVsZW1lbnRzIGZvciB3aGljaCBhIHRydXRoIHRlc3QgZmFpbHMuXG4gIF8ucmVqZWN0ID0gZnVuY3Rpb24ob2JqLCBwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICByZXR1cm4gXy5maWx0ZXIob2JqLCBfLm5lZ2F0ZShfLml0ZXJhdGVlKHByZWRpY2F0ZSkpLCBjb250ZXh0KTtcbiAgfTtcblxuICAvLyBEZXRlcm1pbmUgd2hldGhlciBhbGwgb2YgdGhlIGVsZW1lbnRzIG1hdGNoIGEgdHJ1dGggdGVzdC5cbiAgLy8gQWxpYXNlZCBhcyBgYWxsYC5cbiAgXy5ldmVyeSA9IF8uYWxsID0gZnVuY3Rpb24ob2JqLCBwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiB0cnVlO1xuICAgIHByZWRpY2F0ZSA9IF8uaXRlcmF0ZWUocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICB2YXIga2V5cyA9IG9iai5sZW5ndGggIT09ICtvYmoubGVuZ3RoICYmIF8ua2V5cyhvYmopLFxuICAgICAgICBsZW5ndGggPSAoa2V5cyB8fCBvYmopLmxlbmd0aCxcbiAgICAgICAgaW5kZXgsIGN1cnJlbnRLZXk7XG4gICAgZm9yIChpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjdXJyZW50S2V5ID0ga2V5cyA/IGtleXNbaW5kZXhdIDogaW5kZXg7XG4gICAgICBpZiAoIXByZWRpY2F0ZShvYmpbY3VycmVudEtleV0sIGN1cnJlbnRLZXksIG9iaikpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgLy8gRGV0ZXJtaW5lIGlmIGF0IGxlYXN0IG9uZSBlbGVtZW50IGluIHRoZSBvYmplY3QgbWF0Y2hlcyBhIHRydXRoIHRlc3QuXG4gIC8vIEFsaWFzZWQgYXMgYGFueWAuXG4gIF8uc29tZSA9IF8uYW55ID0gZnVuY3Rpb24ob2JqLCBwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICBwcmVkaWNhdGUgPSBfLml0ZXJhdGVlKHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgdmFyIGtleXMgPSBvYmoubGVuZ3RoICE9PSArb2JqLmxlbmd0aCAmJiBfLmtleXMob2JqKSxcbiAgICAgICAgbGVuZ3RoID0gKGtleXMgfHwgb2JqKS5sZW5ndGgsXG4gICAgICAgIGluZGV4LCBjdXJyZW50S2V5O1xuICAgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgY3VycmVudEtleSA9IGtleXMgPyBrZXlzW2luZGV4XSA6IGluZGV4O1xuICAgICAgaWYgKHByZWRpY2F0ZShvYmpbY3VycmVudEtleV0sIGN1cnJlbnRLZXksIG9iaikpIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG5cbiAgLy8gRGV0ZXJtaW5lIGlmIHRoZSBhcnJheSBvciBvYmplY3QgY29udGFpbnMgYSBnaXZlbiB2YWx1ZSAodXNpbmcgYD09PWApLlxuICAvLyBBbGlhc2VkIGFzIGBpbmNsdWRlYC5cbiAgXy5jb250YWlucyA9IF8uaW5jbHVkZSA9IGZ1bmN0aW9uKG9iaiwgdGFyZ2V0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKG9iai5sZW5ndGggIT09ICtvYmoubGVuZ3RoKSBvYmogPSBfLnZhbHVlcyhvYmopO1xuICAgIHJldHVybiBfLmluZGV4T2Yob2JqLCB0YXJnZXQpID49IDA7XG4gIH07XG5cbiAgLy8gSW52b2tlIGEgbWV0aG9kICh3aXRoIGFyZ3VtZW50cykgb24gZXZlcnkgaXRlbSBpbiBhIGNvbGxlY3Rpb24uXG4gIF8uaW52b2tlID0gZnVuY3Rpb24ob2JqLCBtZXRob2QpIHtcbiAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcbiAgICB2YXIgaXNGdW5jID0gXy5pc0Z1bmN0aW9uKG1ldGhvZCk7XG4gICAgcmV0dXJuIF8ubWFwKG9iaiwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiAoaXNGdW5jID8gbWV0aG9kIDogdmFsdWVbbWV0aG9kXSkuYXBwbHkodmFsdWUsIGFyZ3MpO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIENvbnZlbmllbmNlIHZlcnNpb24gb2YgYSBjb21tb24gdXNlIGNhc2Ugb2YgYG1hcGA6IGZldGNoaW5nIGEgcHJvcGVydHkuXG4gIF8ucGx1Y2sgPSBmdW5jdGlvbihvYmosIGtleSkge1xuICAgIHJldHVybiBfLm1hcChvYmosIF8ucHJvcGVydHkoa2V5KSk7XG4gIH07XG5cbiAgLy8gQ29udmVuaWVuY2UgdmVyc2lvbiBvZiBhIGNvbW1vbiB1c2UgY2FzZSBvZiBgZmlsdGVyYDogc2VsZWN0aW5nIG9ubHkgb2JqZWN0c1xuICAvLyBjb250YWluaW5nIHNwZWNpZmljIGBrZXk6dmFsdWVgIHBhaXJzLlxuICBfLndoZXJlID0gZnVuY3Rpb24ob2JqLCBhdHRycykge1xuICAgIHJldHVybiBfLmZpbHRlcihvYmosIF8ubWF0Y2hlcyhhdHRycykpO1xuICB9O1xuXG4gIC8vIENvbnZlbmllbmNlIHZlcnNpb24gb2YgYSBjb21tb24gdXNlIGNhc2Ugb2YgYGZpbmRgOiBnZXR0aW5nIHRoZSBmaXJzdCBvYmplY3RcbiAgLy8gY29udGFpbmluZyBzcGVjaWZpYyBga2V5OnZhbHVlYCBwYWlycy5cbiAgXy5maW5kV2hlcmUgPSBmdW5jdGlvbihvYmosIGF0dHJzKSB7XG4gICAgcmV0dXJuIF8uZmluZChvYmosIF8ubWF0Y2hlcyhhdHRycykpO1xuICB9O1xuXG4gIC8vIFJldHVybiB0aGUgbWF4aW11bSBlbGVtZW50IChvciBlbGVtZW50LWJhc2VkIGNvbXB1dGF0aW9uKS5cbiAgXy5tYXggPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgdmFyIHJlc3VsdCA9IC1JbmZpbml0eSwgbGFzdENvbXB1dGVkID0gLUluZmluaXR5LFxuICAgICAgICB2YWx1ZSwgY29tcHV0ZWQ7XG4gICAgaWYgKGl0ZXJhdGVlID09IG51bGwgJiYgb2JqICE9IG51bGwpIHtcbiAgICAgIG9iaiA9IG9iai5sZW5ndGggPT09ICtvYmoubGVuZ3RoID8gb2JqIDogXy52YWx1ZXMob2JqKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBvYmoubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFsdWUgPSBvYmpbaV07XG4gICAgICAgIGlmICh2YWx1ZSA+IHJlc3VsdCkge1xuICAgICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGl0ZXJhdGVlID0gXy5pdGVyYXRlZShpdGVyYXRlZSwgY29udGV4dCk7XG4gICAgICBfLmVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSh2YWx1ZSwgaW5kZXgsIGxpc3QpO1xuICAgICAgICBpZiAoY29tcHV0ZWQgPiBsYXN0Q29tcHV0ZWQgfHwgY29tcHV0ZWQgPT09IC1JbmZpbml0eSAmJiByZXN1bHQgPT09IC1JbmZpbml0eSkge1xuICAgICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgICAgIGxhc3RDb21wdXRlZCA9IGNvbXB1dGVkO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIG1pbmltdW0gZWxlbWVudCAob3IgZWxlbWVudC1iYXNlZCBjb21wdXRhdGlvbikuXG4gIF8ubWluID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgIHZhciByZXN1bHQgPSBJbmZpbml0eSwgbGFzdENvbXB1dGVkID0gSW5maW5pdHksXG4gICAgICAgIHZhbHVlLCBjb21wdXRlZDtcbiAgICBpZiAoaXRlcmF0ZWUgPT0gbnVsbCAmJiBvYmogIT0gbnVsbCkge1xuICAgICAgb2JqID0gb2JqLmxlbmd0aCA9PT0gK29iai5sZW5ndGggPyBvYmogOiBfLnZhbHVlcyhvYmopO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IG9iai5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICB2YWx1ZSA9IG9ialtpXTtcbiAgICAgICAgaWYgKHZhbHVlIDwgcmVzdWx0KSB7XG4gICAgICAgICAgcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaXRlcmF0ZWUgPSBfLml0ZXJhdGVlKGl0ZXJhdGVlLCBjb250ZXh0KTtcbiAgICAgIF8uZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlKHZhbHVlLCBpbmRleCwgbGlzdCk7XG4gICAgICAgIGlmIChjb21wdXRlZCA8IGxhc3RDb21wdXRlZCB8fCBjb21wdXRlZCA9PT0gSW5maW5pdHkgJiYgcmVzdWx0ID09PSBJbmZpbml0eSkge1xuICAgICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgICAgIGxhc3RDb21wdXRlZCA9IGNvbXB1dGVkO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBTaHVmZmxlIGEgY29sbGVjdGlvbiwgdXNpbmcgdGhlIG1vZGVybiB2ZXJzaW9uIG9mIHRoZVxuICAvLyBbRmlzaGVyLVlhdGVzIHNodWZmbGVdKGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRmlzaGVy4oCTWWF0ZXNfc2h1ZmZsZSkuXG4gIF8uc2h1ZmZsZSA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHZhciBzZXQgPSBvYmogJiYgb2JqLmxlbmd0aCA9PT0gK29iai5sZW5ndGggPyBvYmogOiBfLnZhbHVlcyhvYmopO1xuICAgIHZhciBsZW5ndGggPSBzZXQubGVuZ3RoO1xuICAgIHZhciBzaHVmZmxlZCA9IEFycmF5KGxlbmd0aCk7XG4gICAgZm9yICh2YXIgaW5kZXggPSAwLCByYW5kOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgcmFuZCA9IF8ucmFuZG9tKDAsIGluZGV4KTtcbiAgICAgIGlmIChyYW5kICE9PSBpbmRleCkgc2h1ZmZsZWRbaW5kZXhdID0gc2h1ZmZsZWRbcmFuZF07XG4gICAgICBzaHVmZmxlZFtyYW5kXSA9IHNldFtpbmRleF07XG4gICAgfVxuICAgIHJldHVybiBzaHVmZmxlZDtcbiAgfTtcblxuICAvLyBTYW1wbGUgKipuKiogcmFuZG9tIHZhbHVlcyBmcm9tIGEgY29sbGVjdGlvbi5cbiAgLy8gSWYgKipuKiogaXMgbm90IHNwZWNpZmllZCwgcmV0dXJucyBhIHNpbmdsZSByYW5kb20gZWxlbWVudC5cbiAgLy8gVGhlIGludGVybmFsIGBndWFyZGAgYXJndW1lbnQgYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgbWFwYC5cbiAgXy5zYW1wbGUgPSBmdW5jdGlvbihvYmosIG4sIGd1YXJkKSB7XG4gICAgaWYgKG4gPT0gbnVsbCB8fCBndWFyZCkge1xuICAgICAgaWYgKG9iai5sZW5ndGggIT09ICtvYmoubGVuZ3RoKSBvYmogPSBfLnZhbHVlcyhvYmopO1xuICAgICAgcmV0dXJuIG9ialtfLnJhbmRvbShvYmoubGVuZ3RoIC0gMSldO1xuICAgIH1cbiAgICByZXR1cm4gXy5zaHVmZmxlKG9iaikuc2xpY2UoMCwgTWF0aC5tYXgoMCwgbikpO1xuICB9O1xuXG4gIC8vIFNvcnQgdGhlIG9iamVjdCdzIHZhbHVlcyBieSBhIGNyaXRlcmlvbiBwcm9kdWNlZCBieSBhbiBpdGVyYXRlZS5cbiAgXy5zb3J0QnkgPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgaXRlcmF0ZWUgPSBfLml0ZXJhdGVlKGl0ZXJhdGVlLCBjb250ZXh0KTtcbiAgICByZXR1cm4gXy5wbHVjayhfLm1hcChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICBpbmRleDogaW5kZXgsXG4gICAgICAgIGNyaXRlcmlhOiBpdGVyYXRlZSh2YWx1ZSwgaW5kZXgsIGxpc3QpXG4gICAgICB9O1xuICAgIH0pLnNvcnQoZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgICAgIHZhciBhID0gbGVmdC5jcml0ZXJpYTtcbiAgICAgIHZhciBiID0gcmlnaHQuY3JpdGVyaWE7XG4gICAgICBpZiAoYSAhPT0gYikge1xuICAgICAgICBpZiAoYSA+IGIgfHwgYSA9PT0gdm9pZCAwKSByZXR1cm4gMTtcbiAgICAgICAgaWYgKGEgPCBiIHx8IGIgPT09IHZvaWQgMCkgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGxlZnQuaW5kZXggLSByaWdodC5pbmRleDtcbiAgICB9KSwgJ3ZhbHVlJyk7XG4gIH07XG5cbiAgLy8gQW4gaW50ZXJuYWwgZnVuY3Rpb24gdXNlZCBmb3IgYWdncmVnYXRlIFwiZ3JvdXAgYnlcIiBvcGVyYXRpb25zLlxuICB2YXIgZ3JvdXAgPSBmdW5jdGlvbihiZWhhdmlvcikge1xuICAgIHJldHVybiBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICBpdGVyYXRlZSA9IF8uaXRlcmF0ZWUoaXRlcmF0ZWUsIGNvbnRleHQpO1xuICAgICAgXy5lYWNoKG9iaiwgZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7XG4gICAgICAgIHZhciBrZXkgPSBpdGVyYXRlZSh2YWx1ZSwgaW5kZXgsIG9iaik7XG4gICAgICAgIGJlaGF2aW9yKHJlc3VsdCwgdmFsdWUsIGtleSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfTtcblxuICAvLyBHcm91cHMgdGhlIG9iamVjdCdzIHZhbHVlcyBieSBhIGNyaXRlcmlvbi4gUGFzcyBlaXRoZXIgYSBzdHJpbmcgYXR0cmlidXRlXG4gIC8vIHRvIGdyb3VwIGJ5LCBvciBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgY3JpdGVyaW9uLlxuICBfLmdyb3VwQnkgPSBncm91cChmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICBpZiAoXy5oYXMocmVzdWx0LCBrZXkpKSByZXN1bHRba2V5XS5wdXNoKHZhbHVlKTsgZWxzZSByZXN1bHRba2V5XSA9IFt2YWx1ZV07XG4gIH0pO1xuXG4gIC8vIEluZGV4ZXMgdGhlIG9iamVjdCdzIHZhbHVlcyBieSBhIGNyaXRlcmlvbiwgc2ltaWxhciB0byBgZ3JvdXBCeWAsIGJ1dCBmb3JcbiAgLy8gd2hlbiB5b3Uga25vdyB0aGF0IHlvdXIgaW5kZXggdmFsdWVzIHdpbGwgYmUgdW5pcXVlLlxuICBfLmluZGV4QnkgPSBncm91cChmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHRba2V5XSA9IHZhbHVlO1xuICB9KTtcblxuICAvLyBDb3VudHMgaW5zdGFuY2VzIG9mIGFuIG9iamVjdCB0aGF0IGdyb3VwIGJ5IGEgY2VydGFpbiBjcml0ZXJpb24uIFBhc3NcbiAgLy8gZWl0aGVyIGEgc3RyaW5nIGF0dHJpYnV0ZSB0byBjb3VudCBieSwgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlXG4gIC8vIGNyaXRlcmlvbi5cbiAgXy5jb3VudEJ5ID0gZ3JvdXAoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgaWYgKF8uaGFzKHJlc3VsdCwga2V5KSkgcmVzdWx0W2tleV0rKzsgZWxzZSByZXN1bHRba2V5XSA9IDE7XG4gIH0pO1xuXG4gIC8vIFVzZSBhIGNvbXBhcmF0b3IgZnVuY3Rpb24gdG8gZmlndXJlIG91dCB0aGUgc21hbGxlc3QgaW5kZXggYXQgd2hpY2hcbiAgLy8gYW4gb2JqZWN0IHNob3VsZCBiZSBpbnNlcnRlZCBzbyBhcyB0byBtYWludGFpbiBvcmRlci4gVXNlcyBiaW5hcnkgc2VhcmNoLlxuICBfLnNvcnRlZEluZGV4ID0gZnVuY3Rpb24oYXJyYXksIG9iaiwgaXRlcmF0ZWUsIGNvbnRleHQpIHtcbiAgICBpdGVyYXRlZSA9IF8uaXRlcmF0ZWUoaXRlcmF0ZWUsIGNvbnRleHQsIDEpO1xuICAgIHZhciB2YWx1ZSA9IGl0ZXJhdGVlKG9iaik7XG4gICAgdmFyIGxvdyA9IDAsIGhpZ2ggPSBhcnJheS5sZW5ndGg7XG4gICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICAgIHZhciBtaWQgPSBsb3cgKyBoaWdoID4+PiAxO1xuICAgICAgaWYgKGl0ZXJhdGVlKGFycmF5W21pZF0pIDwgdmFsdWUpIGxvdyA9IG1pZCArIDE7IGVsc2UgaGlnaCA9IG1pZDtcbiAgICB9XG4gICAgcmV0dXJuIGxvdztcbiAgfTtcblxuICAvLyBTYWZlbHkgY3JlYXRlIGEgcmVhbCwgbGl2ZSBhcnJheSBmcm9tIGFueXRoaW5nIGl0ZXJhYmxlLlxuICBfLnRvQXJyYXkgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAoIW9iaikgcmV0dXJuIFtdO1xuICAgIGlmIChfLmlzQXJyYXkob2JqKSkgcmV0dXJuIHNsaWNlLmNhbGwob2JqKTtcbiAgICBpZiAob2JqLmxlbmd0aCA9PT0gK29iai5sZW5ndGgpIHJldHVybiBfLm1hcChvYmosIF8uaWRlbnRpdHkpO1xuICAgIHJldHVybiBfLnZhbHVlcyhvYmopO1xuICB9O1xuXG4gIC8vIFJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIGFuIG9iamVjdC5cbiAgXy5zaXplID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gMDtcbiAgICByZXR1cm4gb2JqLmxlbmd0aCA9PT0gK29iai5sZW5ndGggPyBvYmoubGVuZ3RoIDogXy5rZXlzKG9iaikubGVuZ3RoO1xuICB9O1xuXG4gIC8vIFNwbGl0IGEgY29sbGVjdGlvbiBpbnRvIHR3byBhcnJheXM6IG9uZSB3aG9zZSBlbGVtZW50cyBhbGwgc2F0aXNmeSB0aGUgZ2l2ZW5cbiAgLy8gcHJlZGljYXRlLCBhbmQgb25lIHdob3NlIGVsZW1lbnRzIGFsbCBkbyBub3Qgc2F0aXNmeSB0aGUgcHJlZGljYXRlLlxuICBfLnBhcnRpdGlvbiA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgcHJlZGljYXRlID0gXy5pdGVyYXRlZShwcmVkaWNhdGUsIGNvbnRleHQpO1xuICAgIHZhciBwYXNzID0gW10sIGZhaWwgPSBbXTtcbiAgICBfLmVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBvYmopIHtcbiAgICAgIChwcmVkaWNhdGUodmFsdWUsIGtleSwgb2JqKSA/IHBhc3MgOiBmYWlsKS5wdXNoKHZhbHVlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gW3Bhc3MsIGZhaWxdO1xuICB9O1xuXG4gIC8vIEFycmF5IEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS1cblxuICAvLyBHZXQgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYW4gYXJyYXkuIFBhc3NpbmcgKipuKiogd2lsbCByZXR1cm4gdGhlIGZpcnN0IE5cbiAgLy8gdmFsdWVzIGluIHRoZSBhcnJheS4gQWxpYXNlZCBhcyBgaGVhZGAgYW5kIGB0YWtlYC4gVGhlICoqZ3VhcmQqKiBjaGVja1xuICAvLyBhbGxvd3MgaXQgdG8gd29yayB3aXRoIGBfLm1hcGAuXG4gIF8uZmlyc3QgPSBfLmhlYWQgPSBfLnRha2UgPSBmdW5jdGlvbihhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICBpZiAoYXJyYXkgPT0gbnVsbCkgcmV0dXJuIHZvaWQgMDtcbiAgICBpZiAobiA9PSBudWxsIHx8IGd1YXJkKSByZXR1cm4gYXJyYXlbMF07XG4gICAgaWYgKG4gPCAwKSByZXR1cm4gW107XG4gICAgcmV0dXJuIHNsaWNlLmNhbGwoYXJyYXksIDAsIG4pO1xuICB9O1xuXG4gIC8vIFJldHVybnMgZXZlcnl0aGluZyBidXQgdGhlIGxhc3QgZW50cnkgb2YgdGhlIGFycmF5LiBFc3BlY2lhbGx5IHVzZWZ1bCBvblxuICAvLyB0aGUgYXJndW1lbnRzIG9iamVjdC4gUGFzc2luZyAqKm4qKiB3aWxsIHJldHVybiBhbGwgdGhlIHZhbHVlcyBpblxuICAvLyB0aGUgYXJyYXksIGV4Y2x1ZGluZyB0aGUgbGFzdCBOLiBUaGUgKipndWFyZCoqIGNoZWNrIGFsbG93cyBpdCB0byB3b3JrIHdpdGhcbiAgLy8gYF8ubWFwYC5cbiAgXy5pbml0aWFsID0gZnVuY3Rpb24oYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgcmV0dXJuIHNsaWNlLmNhbGwoYXJyYXksIDAsIE1hdGgubWF4KDAsIGFycmF5Lmxlbmd0aCAtIChuID09IG51bGwgfHwgZ3VhcmQgPyAxIDogbikpKTtcbiAgfTtcblxuICAvLyBHZXQgdGhlIGxhc3QgZWxlbWVudCBvZiBhbiBhcnJheS4gUGFzc2luZyAqKm4qKiB3aWxsIHJldHVybiB0aGUgbGFzdCBOXG4gIC8vIHZhbHVlcyBpbiB0aGUgYXJyYXkuIFRoZSAqKmd1YXJkKiogY2hlY2sgYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgXy5tYXBgLlxuICBfLmxhc3QgPSBmdW5jdGlvbihhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICBpZiAoYXJyYXkgPT0gbnVsbCkgcmV0dXJuIHZvaWQgMDtcbiAgICBpZiAobiA9PSBudWxsIHx8IGd1YXJkKSByZXR1cm4gYXJyYXlbYXJyYXkubGVuZ3RoIC0gMV07XG4gICAgcmV0dXJuIHNsaWNlLmNhbGwoYXJyYXksIE1hdGgubWF4KGFycmF5Lmxlbmd0aCAtIG4sIDApKTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGV2ZXJ5dGhpbmcgYnV0IHRoZSBmaXJzdCBlbnRyeSBvZiB0aGUgYXJyYXkuIEFsaWFzZWQgYXMgYHRhaWxgIGFuZCBgZHJvcGAuXG4gIC8vIEVzcGVjaWFsbHkgdXNlZnVsIG9uIHRoZSBhcmd1bWVudHMgb2JqZWN0LiBQYXNzaW5nIGFuICoqbioqIHdpbGwgcmV0dXJuXG4gIC8vIHRoZSByZXN0IE4gdmFsdWVzIGluIHRoZSBhcnJheS4gVGhlICoqZ3VhcmQqKlxuICAvLyBjaGVjayBhbGxvd3MgaXQgdG8gd29yayB3aXRoIGBfLm1hcGAuXG4gIF8ucmVzdCA9IF8udGFpbCA9IF8uZHJvcCA9IGZ1bmN0aW9uKGFycmF5LCBuLCBndWFyZCkge1xuICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCBuID09IG51bGwgfHwgZ3VhcmQgPyAxIDogbik7XG4gIH07XG5cbiAgLy8gVHJpbSBvdXQgYWxsIGZhbHN5IHZhbHVlcyBmcm9tIGFuIGFycmF5LlxuICBfLmNvbXBhY3QgPSBmdW5jdGlvbihhcnJheSkge1xuICAgIHJldHVybiBfLmZpbHRlcihhcnJheSwgXy5pZGVudGl0eSk7XG4gIH07XG5cbiAgLy8gSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gb2YgYSByZWN1cnNpdmUgYGZsYXR0ZW5gIGZ1bmN0aW9uLlxuICB2YXIgZmxhdHRlbiA9IGZ1bmN0aW9uKGlucHV0LCBzaGFsbG93LCBzdHJpY3QsIG91dHB1dCkge1xuICAgIGlmIChzaGFsbG93ICYmIF8uZXZlcnkoaW5wdXQsIF8uaXNBcnJheSkpIHtcbiAgICAgIHJldHVybiBjb25jYXQuYXBwbHkob3V0cHV0LCBpbnB1dCk7XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBpbnB1dC5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHZhbHVlID0gaW5wdXRbaV07XG4gICAgICBpZiAoIV8uaXNBcnJheSh2YWx1ZSkgJiYgIV8uaXNBcmd1bWVudHModmFsdWUpKSB7XG4gICAgICAgIGlmICghc3RyaWN0KSBvdXRwdXQucHVzaCh2YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHNoYWxsb3cpIHtcbiAgICAgICAgcHVzaC5hcHBseShvdXRwdXQsIHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZsYXR0ZW4odmFsdWUsIHNoYWxsb3csIHN0cmljdCwgb3V0cHV0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfTtcblxuICAvLyBGbGF0dGVuIG91dCBhbiBhcnJheSwgZWl0aGVyIHJlY3Vyc2l2ZWx5IChieSBkZWZhdWx0KSwgb3IganVzdCBvbmUgbGV2ZWwuXG4gIF8uZmxhdHRlbiA9IGZ1bmN0aW9uKGFycmF5LCBzaGFsbG93KSB7XG4gICAgcmV0dXJuIGZsYXR0ZW4oYXJyYXksIHNoYWxsb3csIGZhbHNlLCBbXSk7XG4gIH07XG5cbiAgLy8gUmV0dXJuIGEgdmVyc2lvbiBvZiB0aGUgYXJyYXkgdGhhdCBkb2VzIG5vdCBjb250YWluIHRoZSBzcGVjaWZpZWQgdmFsdWUocykuXG4gIF8ud2l0aG91dCA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgcmV0dXJuIF8uZGlmZmVyZW5jZShhcnJheSwgc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTtcbiAgfTtcblxuICAvLyBQcm9kdWNlIGEgZHVwbGljYXRlLWZyZWUgdmVyc2lvbiBvZiB0aGUgYXJyYXkuIElmIHRoZSBhcnJheSBoYXMgYWxyZWFkeVxuICAvLyBiZWVuIHNvcnRlZCwgeW91IGhhdmUgdGhlIG9wdGlvbiBvZiB1c2luZyBhIGZhc3RlciBhbGdvcml0aG0uXG4gIC8vIEFsaWFzZWQgYXMgYHVuaXF1ZWAuXG4gIF8udW5pcSA9IF8udW5pcXVlID0gZnVuY3Rpb24oYXJyYXksIGlzU29ydGVkLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgIGlmIChhcnJheSA9PSBudWxsKSByZXR1cm4gW107XG4gICAgaWYgKCFfLmlzQm9vbGVhbihpc1NvcnRlZCkpIHtcbiAgICAgIGNvbnRleHQgPSBpdGVyYXRlZTtcbiAgICAgIGl0ZXJhdGVlID0gaXNTb3J0ZWQ7XG4gICAgICBpc1NvcnRlZCA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAoaXRlcmF0ZWUgIT0gbnVsbCkgaXRlcmF0ZWUgPSBfLml0ZXJhdGVlKGl0ZXJhdGVlLCBjb250ZXh0KTtcbiAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgdmFyIHNlZW4gPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2ldO1xuICAgICAgaWYgKGlzU29ydGVkKSB7XG4gICAgICAgIGlmICghaSB8fCBzZWVuICE9PSB2YWx1ZSkgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICBzZWVuID0gdmFsdWU7XG4gICAgICB9IGVsc2UgaWYgKGl0ZXJhdGVlKSB7XG4gICAgICAgIHZhciBjb21wdXRlZCA9IGl0ZXJhdGVlKHZhbHVlLCBpLCBhcnJheSk7XG4gICAgICAgIGlmIChfLmluZGV4T2Yoc2VlbiwgY29tcHV0ZWQpIDwgMCkge1xuICAgICAgICAgIHNlZW4ucHVzaChjb21wdXRlZCk7XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKF8uaW5kZXhPZihyZXN1bHQsIHZhbHVlKSA8IDApIHtcbiAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIFByb2R1Y2UgYW4gYXJyYXkgdGhhdCBjb250YWlucyB0aGUgdW5pb246IGVhY2ggZGlzdGluY3QgZWxlbWVudCBmcm9tIGFsbCBvZlxuICAvLyB0aGUgcGFzc2VkLWluIGFycmF5cy5cbiAgXy51bmlvbiA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBfLnVuaXEoZmxhdHRlbihhcmd1bWVudHMsIHRydWUsIHRydWUsIFtdKSk7XG4gIH07XG5cbiAgLy8gUHJvZHVjZSBhbiBhcnJheSB0aGF0IGNvbnRhaW5zIGV2ZXJ5IGl0ZW0gc2hhcmVkIGJldHdlZW4gYWxsIHRoZVxuICAvLyBwYXNzZWQtaW4gYXJyYXlzLlxuICBfLmludGVyc2VjdGlvbiA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiBbXTtcbiAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgdmFyIGFyZ3NMZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBhcnJheS5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGl0ZW0gPSBhcnJheVtpXTtcbiAgICAgIGlmIChfLmNvbnRhaW5zKHJlc3VsdCwgaXRlbSkpIGNvbnRpbnVlO1xuICAgICAgZm9yICh2YXIgaiA9IDE7IGogPCBhcmdzTGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKCFfLmNvbnRhaW5zKGFyZ3VtZW50c1tqXSwgaXRlbSkpIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKGogPT09IGFyZ3NMZW5ndGgpIHJlc3VsdC5wdXNoKGl0ZW0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIFRha2UgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBvbmUgYXJyYXkgYW5kIGEgbnVtYmVyIG9mIG90aGVyIGFycmF5cy5cbiAgLy8gT25seSB0aGUgZWxlbWVudHMgcHJlc2VudCBpbiBqdXN0IHRoZSBmaXJzdCBhcnJheSB3aWxsIHJlbWFpbi5cbiAgXy5kaWZmZXJlbmNlID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICB2YXIgcmVzdCA9IGZsYXR0ZW4oc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLCB0cnVlLCB0cnVlLCBbXSk7XG4gICAgcmV0dXJuIF8uZmlsdGVyKGFycmF5LCBmdW5jdGlvbih2YWx1ZSl7XG4gICAgICByZXR1cm4gIV8uY29udGFpbnMocmVzdCwgdmFsdWUpO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIFppcCB0b2dldGhlciBtdWx0aXBsZSBsaXN0cyBpbnRvIGEgc2luZ2xlIGFycmF5IC0tIGVsZW1lbnRzIHRoYXQgc2hhcmVcbiAgLy8gYW4gaW5kZXggZ28gdG9nZXRoZXIuXG4gIF8uemlwID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICBpZiAoYXJyYXkgPT0gbnVsbCkgcmV0dXJuIFtdO1xuICAgIHZhciBsZW5ndGggPSBfLm1heChhcmd1bWVudHMsICdsZW5ndGgnKS5sZW5ndGg7XG4gICAgdmFyIHJlc3VsdHMgPSBBcnJheShsZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdHNbaV0gPSBfLnBsdWNrKGFyZ3VtZW50cywgaSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9O1xuXG4gIC8vIENvbnZlcnRzIGxpc3RzIGludG8gb2JqZWN0cy4gUGFzcyBlaXRoZXIgYSBzaW5nbGUgYXJyYXkgb2YgYFtrZXksIHZhbHVlXWBcbiAgLy8gcGFpcnMsIG9yIHR3byBwYXJhbGxlbCBhcnJheXMgb2YgdGhlIHNhbWUgbGVuZ3RoIC0tIG9uZSBvZiBrZXlzLCBhbmQgb25lIG9mXG4gIC8vIHRoZSBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgXy5vYmplY3QgPSBmdW5jdGlvbihsaXN0LCB2YWx1ZXMpIHtcbiAgICBpZiAobGlzdCA9PSBudWxsKSByZXR1cm4ge307XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBsaXN0Lmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodmFsdWVzKSB7XG4gICAgICAgIHJlc3VsdFtsaXN0W2ldXSA9IHZhbHVlc1tpXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdFtsaXN0W2ldWzBdXSA9IGxpc3RbaV1bMV07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBhbiBpdGVtIGluIGFuIGFycmF5LFxuICAvLyBvciAtMSBpZiB0aGUgaXRlbSBpcyBub3QgaW5jbHVkZWQgaW4gdGhlIGFycmF5LlxuICAvLyBJZiB0aGUgYXJyYXkgaXMgbGFyZ2UgYW5kIGFscmVhZHkgaW4gc29ydCBvcmRlciwgcGFzcyBgdHJ1ZWBcbiAgLy8gZm9yICoqaXNTb3J0ZWQqKiB0byB1c2UgYmluYXJ5IHNlYXJjaC5cbiAgXy5pbmRleE9mID0gZnVuY3Rpb24oYXJyYXksIGl0ZW0sIGlzU29ydGVkKSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiAtMTtcbiAgICB2YXIgaSA9IDAsIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcbiAgICBpZiAoaXNTb3J0ZWQpIHtcbiAgICAgIGlmICh0eXBlb2YgaXNTb3J0ZWQgPT0gJ251bWJlcicpIHtcbiAgICAgICAgaSA9IGlzU29ydGVkIDwgMCA/IE1hdGgubWF4KDAsIGxlbmd0aCArIGlzU29ydGVkKSA6IGlzU29ydGVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaSA9IF8uc29ydGVkSW5kZXgoYXJyYXksIGl0ZW0pO1xuICAgICAgICByZXR1cm4gYXJyYXlbaV0gPT09IGl0ZW0gPyBpIDogLTE7XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIGlmIChhcnJheVtpXSA9PT0gaXRlbSkgcmV0dXJuIGk7XG4gICAgcmV0dXJuIC0xO1xuICB9O1xuXG4gIF8ubGFzdEluZGV4T2YgPSBmdW5jdGlvbihhcnJheSwgaXRlbSwgZnJvbSkge1xuICAgIGlmIChhcnJheSA9PSBudWxsKSByZXR1cm4gLTE7XG4gICAgdmFyIGlkeCA9IGFycmF5Lmxlbmd0aDtcbiAgICBpZiAodHlwZW9mIGZyb20gPT0gJ251bWJlcicpIHtcbiAgICAgIGlkeCA9IGZyb20gPCAwID8gaWR4ICsgZnJvbSArIDEgOiBNYXRoLm1pbihpZHgsIGZyb20gKyAxKTtcbiAgICB9XG4gICAgd2hpbGUgKC0taWR4ID49IDApIGlmIChhcnJheVtpZHhdID09PSBpdGVtKSByZXR1cm4gaWR4O1xuICAgIHJldHVybiAtMTtcbiAgfTtcblxuICAvLyBHZW5lcmF0ZSBhbiBpbnRlZ2VyIEFycmF5IGNvbnRhaW5pbmcgYW4gYXJpdGhtZXRpYyBwcm9ncmVzc2lvbi4gQSBwb3J0IG9mXG4gIC8vIHRoZSBuYXRpdmUgUHl0aG9uIGByYW5nZSgpYCBmdW5jdGlvbi4gU2VlXG4gIC8vIFt0aGUgUHl0aG9uIGRvY3VtZW50YXRpb25dKGh0dHA6Ly9kb2NzLnB5dGhvbi5vcmcvbGlicmFyeS9mdW5jdGlvbnMuaHRtbCNyYW5nZSkuXG4gIF8ucmFuZ2UgPSBmdW5jdGlvbihzdGFydCwgc3RvcCwgc3RlcCkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDw9IDEpIHtcbiAgICAgIHN0b3AgPSBzdGFydCB8fCAwO1xuICAgICAgc3RhcnQgPSAwO1xuICAgIH1cbiAgICBzdGVwID0gc3RlcCB8fCAxO1xuXG4gICAgdmFyIGxlbmd0aCA9IE1hdGgubWF4KE1hdGguY2VpbCgoc3RvcCAtIHN0YXJ0KSAvIHN0ZXApLCAwKTtcbiAgICB2YXIgcmFuZ2UgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgZm9yICh2YXIgaWR4ID0gMDsgaWR4IDwgbGVuZ3RoOyBpZHgrKywgc3RhcnQgKz0gc3RlcCkge1xuICAgICAgcmFuZ2VbaWR4XSA9IHN0YXJ0O1xuICAgIH1cblxuICAgIHJldHVybiByYW5nZTtcbiAgfTtcblxuICAvLyBGdW5jdGlvbiAoYWhlbSkgRnVuY3Rpb25zXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8vIFJldXNhYmxlIGNvbnN0cnVjdG9yIGZ1bmN0aW9uIGZvciBwcm90b3R5cGUgc2V0dGluZy5cbiAgdmFyIEN0b3IgPSBmdW5jdGlvbigpe307XG5cbiAgLy8gQ3JlYXRlIGEgZnVuY3Rpb24gYm91bmQgdG8gYSBnaXZlbiBvYmplY3QgKGFzc2lnbmluZyBgdGhpc2AsIGFuZCBhcmd1bWVudHMsXG4gIC8vIG9wdGlvbmFsbHkpLiBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgRnVuY3Rpb24uYmluZGAgaWZcbiAgLy8gYXZhaWxhYmxlLlxuICBfLmJpbmQgPSBmdW5jdGlvbihmdW5jLCBjb250ZXh0KSB7XG4gICAgdmFyIGFyZ3MsIGJvdW5kO1xuICAgIGlmIChuYXRpdmVCaW5kICYmIGZ1bmMuYmluZCA9PT0gbmF0aXZlQmluZCkgcmV0dXJuIG5hdGl2ZUJpbmQuYXBwbHkoZnVuYywgc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTtcbiAgICBpZiAoIV8uaXNGdW5jdGlvbihmdW5jKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignQmluZCBtdXN0IGJlIGNhbGxlZCBvbiBhIGZ1bmN0aW9uJyk7XG4gICAgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcbiAgICBib3VuZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIGJvdW5kKSkgcmV0dXJuIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICBDdG9yLnByb3RvdHlwZSA9IGZ1bmMucHJvdG90eXBlO1xuICAgICAgdmFyIHNlbGYgPSBuZXcgQ3RvcjtcbiAgICAgIEN0b3IucHJvdG90eXBlID0gbnVsbDtcbiAgICAgIHZhciByZXN1bHQgPSBmdW5jLmFwcGx5KHNlbGYsIGFyZ3MuY29uY2F0KHNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xuICAgICAgaWYgKF8uaXNPYmplY3QocmVzdWx0KSkgcmV0dXJuIHJlc3VsdDtcbiAgICAgIHJldHVybiBzZWxmO1xuICAgIH07XG4gICAgcmV0dXJuIGJvdW5kO1xuICB9O1xuXG4gIC8vIFBhcnRpYWxseSBhcHBseSBhIGZ1bmN0aW9uIGJ5IGNyZWF0aW5nIGEgdmVyc2lvbiB0aGF0IGhhcyBoYWQgc29tZSBvZiBpdHNcbiAgLy8gYXJndW1lbnRzIHByZS1maWxsZWQsIHdpdGhvdXQgY2hhbmdpbmcgaXRzIGR5bmFtaWMgYHRoaXNgIGNvbnRleHQuIF8gYWN0c1xuICAvLyBhcyBhIHBsYWNlaG9sZGVyLCBhbGxvd2luZyBhbnkgY29tYmluYXRpb24gb2YgYXJndW1lbnRzIHRvIGJlIHByZS1maWxsZWQuXG4gIF8ucGFydGlhbCA9IGZ1bmN0aW9uKGZ1bmMpIHtcbiAgICB2YXIgYm91bmRBcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBwb3NpdGlvbiA9IDA7XG4gICAgICB2YXIgYXJncyA9IGJvdW5kQXJncy5zbGljZSgpO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGFyZ3MubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGFyZ3NbaV0gPT09IF8pIGFyZ3NbaV0gPSBhcmd1bWVudHNbcG9zaXRpb24rK107XG4gICAgICB9XG4gICAgICB3aGlsZSAocG9zaXRpb24gPCBhcmd1bWVudHMubGVuZ3RoKSBhcmdzLnB1c2goYXJndW1lbnRzW3Bvc2l0aW9uKytdKTtcbiAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH07XG4gIH07XG5cbiAgLy8gQmluZCBhIG51bWJlciBvZiBhbiBvYmplY3QncyBtZXRob2RzIHRvIHRoYXQgb2JqZWN0LiBSZW1haW5pbmcgYXJndW1lbnRzXG4gIC8vIGFyZSB0aGUgbWV0aG9kIG5hbWVzIHRvIGJlIGJvdW5kLiBVc2VmdWwgZm9yIGVuc3VyaW5nIHRoYXQgYWxsIGNhbGxiYWNrc1xuICAvLyBkZWZpbmVkIG9uIGFuIG9iamVjdCBiZWxvbmcgdG8gaXQuXG4gIF8uYmluZEFsbCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHZhciBpLCBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLCBrZXk7XG4gICAgaWYgKGxlbmd0aCA8PSAxKSB0aHJvdyBuZXcgRXJyb3IoJ2JpbmRBbGwgbXVzdCBiZSBwYXNzZWQgZnVuY3Rpb24gbmFtZXMnKTtcbiAgICBmb3IgKGkgPSAxOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGtleSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgIG9ialtrZXldID0gXy5iaW5kKG9ialtrZXldLCBvYmopO1xuICAgIH1cbiAgICByZXR1cm4gb2JqO1xuICB9O1xuXG4gIC8vIE1lbW9pemUgYW4gZXhwZW5zaXZlIGZ1bmN0aW9uIGJ5IHN0b3JpbmcgaXRzIHJlc3VsdHMuXG4gIF8ubWVtb2l6ZSA9IGZ1bmN0aW9uKGZ1bmMsIGhhc2hlcikge1xuICAgIHZhciBtZW1vaXplID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgICB2YXIgY2FjaGUgPSBtZW1vaXplLmNhY2hlO1xuICAgICAgdmFyIGFkZHJlc3MgPSBoYXNoZXIgPyBoYXNoZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSA6IGtleTtcbiAgICAgIGlmICghXy5oYXMoY2FjaGUsIGFkZHJlc3MpKSBjYWNoZVthZGRyZXNzXSA9IGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHJldHVybiBjYWNoZVthZGRyZXNzXTtcbiAgICB9O1xuICAgIG1lbW9pemUuY2FjaGUgPSB7fTtcbiAgICByZXR1cm4gbWVtb2l6ZTtcbiAgfTtcblxuICAvLyBEZWxheXMgYSBmdW5jdGlvbiBmb3IgdGhlIGdpdmVuIG51bWJlciBvZiBtaWxsaXNlY29uZHMsIGFuZCB0aGVuIGNhbGxzXG4gIC8vIGl0IHdpdGggdGhlIGFyZ3VtZW50cyBzdXBwbGllZC5cbiAgXy5kZWxheSA9IGZ1bmN0aW9uKGZ1bmMsIHdhaXQpIHtcbiAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcbiAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkobnVsbCwgYXJncyk7XG4gICAgfSwgd2FpdCk7XG4gIH07XG5cbiAgLy8gRGVmZXJzIGEgZnVuY3Rpb24sIHNjaGVkdWxpbmcgaXQgdG8gcnVuIGFmdGVyIHRoZSBjdXJyZW50IGNhbGwgc3RhY2sgaGFzXG4gIC8vIGNsZWFyZWQuXG4gIF8uZGVmZXIgPSBmdW5jdGlvbihmdW5jKSB7XG4gICAgcmV0dXJuIF8uZGVsYXkuYXBwbHkoXywgW2Z1bmMsIDFdLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpKTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24sIHRoYXQsIHdoZW4gaW52b2tlZCwgd2lsbCBvbmx5IGJlIHRyaWdnZXJlZCBhdCBtb3N0IG9uY2VcbiAgLy8gZHVyaW5nIGEgZ2l2ZW4gd2luZG93IG9mIHRpbWUuIE5vcm1hbGx5LCB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uIHdpbGwgcnVuXG4gIC8vIGFzIG11Y2ggYXMgaXQgY2FuLCB3aXRob3V0IGV2ZXIgZ29pbmcgbW9yZSB0aGFuIG9uY2UgcGVyIGB3YWl0YCBkdXJhdGlvbjtcbiAgLy8gYnV0IGlmIHlvdSdkIGxpa2UgdG8gZGlzYWJsZSB0aGUgZXhlY3V0aW9uIG9uIHRoZSBsZWFkaW5nIGVkZ2UsIHBhc3NcbiAgLy8gYHtsZWFkaW5nOiBmYWxzZX1gLiBUbyBkaXNhYmxlIGV4ZWN1dGlvbiBvbiB0aGUgdHJhaWxpbmcgZWRnZSwgZGl0dG8uXG4gIF8udGhyb3R0bGUgPSBmdW5jdGlvbihmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gICAgdmFyIGNvbnRleHQsIGFyZ3MsIHJlc3VsdDtcbiAgICB2YXIgdGltZW91dCA9IG51bGw7XG4gICAgdmFyIHByZXZpb3VzID0gMDtcbiAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICB2YXIgbGF0ZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIHByZXZpb3VzID0gb3B0aW9ucy5sZWFkaW5nID09PSBmYWxzZSA/IDAgOiBfLm5vdygpO1xuICAgICAgdGltZW91dCA9IG51bGw7XG4gICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgICAgaWYgKCF0aW1lb3V0KSBjb250ZXh0ID0gYXJncyA9IG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgbm93ID0gXy5ub3coKTtcbiAgICAgIGlmICghcHJldmlvdXMgJiYgb3B0aW9ucy5sZWFkaW5nID09PSBmYWxzZSkgcHJldmlvdXMgPSBub3c7XG4gICAgICB2YXIgcmVtYWluaW5nID0gd2FpdCAtIChub3cgLSBwcmV2aW91cyk7XG4gICAgICBjb250ZXh0ID0gdGhpcztcbiAgICAgIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICBpZiAocmVtYWluaW5nIDw9IDAgfHwgcmVtYWluaW5nID4gd2FpdCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgICBwcmV2aW91cyA9IG5vdztcbiAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgaWYgKCF0aW1lb3V0KSBjb250ZXh0ID0gYXJncyA9IG51bGw7XG4gICAgICB9IGVsc2UgaWYgKCF0aW1lb3V0ICYmIG9wdGlvbnMudHJhaWxpbmcgIT09IGZhbHNlKSB7XG4gICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCByZW1haW5pbmcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9O1xuXG4gIC8vIFJldHVybnMgYSBmdW5jdGlvbiwgdGhhdCwgYXMgbG9uZyBhcyBpdCBjb250aW51ZXMgdG8gYmUgaW52b2tlZCwgd2lsbCBub3RcbiAgLy8gYmUgdHJpZ2dlcmVkLiBUaGUgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgYWZ0ZXIgaXQgc3RvcHMgYmVpbmcgY2FsbGVkIGZvclxuICAvLyBOIG1pbGxpc2Vjb25kcy4gSWYgYGltbWVkaWF0ZWAgaXMgcGFzc2VkLCB0cmlnZ2VyIHRoZSBmdW5jdGlvbiBvbiB0aGVcbiAgLy8gbGVhZGluZyBlZGdlLCBpbnN0ZWFkIG9mIHRoZSB0cmFpbGluZy5cbiAgXy5kZWJvdW5jZSA9IGZ1bmN0aW9uKGZ1bmMsIHdhaXQsIGltbWVkaWF0ZSkge1xuICAgIHZhciB0aW1lb3V0LCBhcmdzLCBjb250ZXh0LCB0aW1lc3RhbXAsIHJlc3VsdDtcblxuICAgIHZhciBsYXRlciA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGxhc3QgPSBfLm5vdygpIC0gdGltZXN0YW1wO1xuXG4gICAgICBpZiAobGFzdCA8IHdhaXQgJiYgbGFzdCA+IDApIHtcbiAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQgLSBsYXN0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgICBpZiAoIWltbWVkaWF0ZSkge1xuICAgICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICAgICAgaWYgKCF0aW1lb3V0KSBjb250ZXh0ID0gYXJncyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgY29udGV4dCA9IHRoaXM7XG4gICAgICBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgdGltZXN0YW1wID0gXy5ub3coKTtcbiAgICAgIHZhciBjYWxsTm93ID0gaW1tZWRpYXRlICYmICF0aW1lb3V0O1xuICAgICAgaWYgKCF0aW1lb3V0KSB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgd2FpdCk7XG4gICAgICBpZiAoY2FsbE5vdykge1xuICAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgICAgICBjb250ZXh0ID0gYXJncyA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIHRoZSBmaXJzdCBmdW5jdGlvbiBwYXNzZWQgYXMgYW4gYXJndW1lbnQgdG8gdGhlIHNlY29uZCxcbiAgLy8gYWxsb3dpbmcgeW91IHRvIGFkanVzdCBhcmd1bWVudHMsIHJ1biBjb2RlIGJlZm9yZSBhbmQgYWZ0ZXIsIGFuZFxuICAvLyBjb25kaXRpb25hbGx5IGV4ZWN1dGUgdGhlIG9yaWdpbmFsIGZ1bmN0aW9uLlxuICBfLndyYXAgPSBmdW5jdGlvbihmdW5jLCB3cmFwcGVyKSB7XG4gICAgcmV0dXJuIF8ucGFydGlhbCh3cmFwcGVyLCBmdW5jKTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgbmVnYXRlZCB2ZXJzaW9uIG9mIHRoZSBwYXNzZWQtaW4gcHJlZGljYXRlLlxuICBfLm5lZ2F0ZSA9IGZ1bmN0aW9uKHByZWRpY2F0ZSkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAhcHJlZGljYXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBpcyB0aGUgY29tcG9zaXRpb24gb2YgYSBsaXN0IG9mIGZ1bmN0aW9ucywgZWFjaFxuICAvLyBjb25zdW1pbmcgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgZnVuY3Rpb24gdGhhdCBmb2xsb3dzLlxuICBfLmNvbXBvc2UgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICB2YXIgc3RhcnQgPSBhcmdzLmxlbmd0aCAtIDE7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGkgPSBzdGFydDtcbiAgICAgIHZhciByZXN1bHQgPSBhcmdzW3N0YXJ0XS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgd2hpbGUgKGktLSkgcmVzdWx0ID0gYXJnc1tpXS5jYWxsKHRoaXMsIHJlc3VsdCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBvbmx5IGJlIGV4ZWN1dGVkIGFmdGVyIGJlaW5nIGNhbGxlZCBOIHRpbWVzLlxuICBfLmFmdGVyID0gZnVuY3Rpb24odGltZXMsIGZ1bmMpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoLS10aW1lcyA8IDEpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuXG4gIC8vIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IHdpbGwgb25seSBiZSBleGVjdXRlZCBiZWZvcmUgYmVpbmcgY2FsbGVkIE4gdGltZXMuXG4gIF8uYmVmb3JlID0gZnVuY3Rpb24odGltZXMsIGZ1bmMpIHtcbiAgICB2YXIgbWVtbztcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoLS10aW1lcyA+IDApIHtcbiAgICAgICAgbWVtbyA9IGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZ1bmMgPSBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1lbW87XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGV4ZWN1dGVkIGF0IG1vc3Qgb25lIHRpbWUsIG5vIG1hdHRlciBob3dcbiAgLy8gb2Z0ZW4geW91IGNhbGwgaXQuIFVzZWZ1bCBmb3IgbGF6eSBpbml0aWFsaXphdGlvbi5cbiAgXy5vbmNlID0gXy5wYXJ0aWFsKF8uYmVmb3JlLCAyKTtcblxuICAvLyBPYmplY3QgRnVuY3Rpb25zXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBSZXRyaWV2ZSB0aGUgbmFtZXMgb2YgYW4gb2JqZWN0J3MgcHJvcGVydGllcy5cbiAgLy8gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYE9iamVjdC5rZXlzYFxuICBfLmtleXMgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAoIV8uaXNPYmplY3Qob2JqKSkgcmV0dXJuIFtdO1xuICAgIGlmIChuYXRpdmVLZXlzKSByZXR1cm4gbmF0aXZlS2V5cyhvYmopO1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikgaWYgKF8uaGFzKG9iaiwga2V5KSkga2V5cy5wdXNoKGtleSk7XG4gICAgcmV0dXJuIGtleXM7XG4gIH07XG5cbiAgLy8gUmV0cmlldmUgdGhlIHZhbHVlcyBvZiBhbiBvYmplY3QncyBwcm9wZXJ0aWVzLlxuICBfLnZhbHVlcyA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHZhciBrZXlzID0gXy5rZXlzKG9iaik7XG4gICAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoO1xuICAgIHZhciB2YWx1ZXMgPSBBcnJheShsZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhbHVlc1tpXSA9IG9ialtrZXlzW2ldXTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfTtcblxuICAvLyBDb252ZXJ0IGFuIG9iamVjdCBpbnRvIGEgbGlzdCBvZiBgW2tleSwgdmFsdWVdYCBwYWlycy5cbiAgXy5wYWlycyA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHZhciBrZXlzID0gXy5rZXlzKG9iaik7XG4gICAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoO1xuICAgIHZhciBwYWlycyA9IEFycmF5KGxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgcGFpcnNbaV0gPSBba2V5c1tpXSwgb2JqW2tleXNbaV1dXTtcbiAgICB9XG4gICAgcmV0dXJuIHBhaXJzO1xuICB9O1xuXG4gIC8vIEludmVydCB0aGUga2V5cyBhbmQgdmFsdWVzIG9mIGFuIG9iamVjdC4gVGhlIHZhbHVlcyBtdXN0IGJlIHNlcmlhbGl6YWJsZS5cbiAgXy5pbnZlcnQgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgcmVzdWx0W29ialtrZXlzW2ldXV0gPSBrZXlzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIFJldHVybiBhIHNvcnRlZCBsaXN0IG9mIHRoZSBmdW5jdGlvbiBuYW1lcyBhdmFpbGFibGUgb24gdGhlIG9iamVjdC5cbiAgLy8gQWxpYXNlZCBhcyBgbWV0aG9kc2BcbiAgXy5mdW5jdGlvbnMgPSBfLm1ldGhvZHMgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgbmFtZXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoXy5pc0Z1bmN0aW9uKG9ialtrZXldKSkgbmFtZXMucHVzaChrZXkpO1xuICAgIH1cbiAgICByZXR1cm4gbmFtZXMuc29ydCgpO1xuICB9O1xuXG4gIC8vIEV4dGVuZCBhIGdpdmVuIG9iamVjdCB3aXRoIGFsbCB0aGUgcHJvcGVydGllcyBpbiBwYXNzZWQtaW4gb2JqZWN0KHMpLlxuICBfLmV4dGVuZCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmICghXy5pc09iamVjdChvYmopKSByZXR1cm4gb2JqO1xuICAgIHZhciBzb3VyY2UsIHByb3A7XG4gICAgZm9yICh2YXIgaSA9IDEsIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgc291cmNlID0gYXJndW1lbnRzW2ldO1xuICAgICAgZm9yIChwcm9wIGluIHNvdXJjZSkge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIHByb3ApKSB7XG4gICAgICAgICAgICBvYmpbcHJvcF0gPSBzb3VyY2VbcHJvcF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfTtcblxuICAvLyBSZXR1cm4gYSBjb3B5IG9mIHRoZSBvYmplY3Qgb25seSBjb250YWluaW5nIHRoZSB3aGl0ZWxpc3RlZCBwcm9wZXJ0aWVzLlxuICBfLnBpY2sgPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgdmFyIHJlc3VsdCA9IHt9LCBrZXk7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gcmVzdWx0O1xuICAgIGlmIChfLmlzRnVuY3Rpb24oaXRlcmF0ZWUpKSB7XG4gICAgICBpdGVyYXRlZSA9IGNyZWF0ZUNhbGxiYWNrKGl0ZXJhdGVlLCBjb250ZXh0KTtcbiAgICAgIGZvciAoa2V5IGluIG9iaikge1xuICAgICAgICB2YXIgdmFsdWUgPSBvYmpba2V5XTtcbiAgICAgICAgaWYgKGl0ZXJhdGVlKHZhbHVlLCBrZXksIG9iaikpIHJlc3VsdFtrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBrZXlzID0gY29uY2F0LmFwcGx5KFtdLCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgICAgb2JqID0gbmV3IE9iamVjdChvYmopO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGtleXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgaWYgKGtleSBpbiBvYmopIHJlc3VsdFtrZXldID0gb2JqW2tleV07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgIC8vIFJldHVybiBhIGNvcHkgb2YgdGhlIG9iamVjdCB3aXRob3V0IHRoZSBibGFja2xpc3RlZCBwcm9wZXJ0aWVzLlxuICBfLm9taXQgPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgaWYgKF8uaXNGdW5jdGlvbihpdGVyYXRlZSkpIHtcbiAgICAgIGl0ZXJhdGVlID0gXy5uZWdhdGUoaXRlcmF0ZWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIga2V5cyA9IF8ubWFwKGNvbmNhdC5hcHBseShbXSwgc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKSwgU3RyaW5nKTtcbiAgICAgIGl0ZXJhdGVlID0gZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgICByZXR1cm4gIV8uY29udGFpbnMoa2V5cywga2V5KTtcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBfLnBpY2sob2JqLCBpdGVyYXRlZSwgY29udGV4dCk7XG4gIH07XG5cbiAgLy8gRmlsbCBpbiBhIGdpdmVuIG9iamVjdCB3aXRoIGRlZmF1bHQgcHJvcGVydGllcy5cbiAgXy5kZWZhdWx0cyA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmICghXy5pc09iamVjdChvYmopKSByZXR1cm4gb2JqO1xuICAgIGZvciAodmFyIGkgPSAxLCBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07XG4gICAgICBmb3IgKHZhciBwcm9wIGluIHNvdXJjZSkge1xuICAgICAgICBpZiAob2JqW3Byb3BdID09PSB2b2lkIDApIG9ialtwcm9wXSA9IHNvdXJjZVtwcm9wXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfTtcblxuICAvLyBDcmVhdGUgYSAoc2hhbGxvdy1jbG9uZWQpIGR1cGxpY2F0ZSBvZiBhbiBvYmplY3QuXG4gIF8uY2xvbmUgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAoIV8uaXNPYmplY3Qob2JqKSkgcmV0dXJuIG9iajtcbiAgICByZXR1cm4gXy5pc0FycmF5KG9iaikgPyBvYmouc2xpY2UoKSA6IF8uZXh0ZW5kKHt9LCBvYmopO1xuICB9O1xuXG4gIC8vIEludm9rZXMgaW50ZXJjZXB0b3Igd2l0aCB0aGUgb2JqLCBhbmQgdGhlbiByZXR1cm5zIG9iai5cbiAgLy8gVGhlIHByaW1hcnkgcHVycG9zZSBvZiB0aGlzIG1ldGhvZCBpcyB0byBcInRhcCBpbnRvXCIgYSBtZXRob2QgY2hhaW4sIGluXG4gIC8vIG9yZGVyIHRvIHBlcmZvcm0gb3BlcmF0aW9ucyBvbiBpbnRlcm1lZGlhdGUgcmVzdWx0cyB3aXRoaW4gdGhlIGNoYWluLlxuICBfLnRhcCA9IGZ1bmN0aW9uKG9iaiwgaW50ZXJjZXB0b3IpIHtcbiAgICBpbnRlcmNlcHRvcihvYmopO1xuICAgIHJldHVybiBvYmo7XG4gIH07XG5cbiAgLy8gSW50ZXJuYWwgcmVjdXJzaXZlIGNvbXBhcmlzb24gZnVuY3Rpb24gZm9yIGBpc0VxdWFsYC5cbiAgdmFyIGVxID0gZnVuY3Rpb24oYSwgYiwgYVN0YWNrLCBiU3RhY2spIHtcbiAgICAvLyBJZGVudGljYWwgb2JqZWN0cyBhcmUgZXF1YWwuIGAwID09PSAtMGAsIGJ1dCB0aGV5IGFyZW4ndCBpZGVudGljYWwuXG4gICAgLy8gU2VlIHRoZSBbSGFybW9ueSBgZWdhbGAgcHJvcG9zYWxdKGh0dHA6Ly93aWtpLmVjbWFzY3JpcHQub3JnL2Rva3UucGhwP2lkPWhhcm1vbnk6ZWdhbCkuXG4gICAgaWYgKGEgPT09IGIpIHJldHVybiBhICE9PSAwIHx8IDEgLyBhID09PSAxIC8gYjtcbiAgICAvLyBBIHN0cmljdCBjb21wYXJpc29uIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIGBudWxsID09IHVuZGVmaW5lZGAuXG4gICAgaWYgKGEgPT0gbnVsbCB8fCBiID09IG51bGwpIHJldHVybiBhID09PSBiO1xuICAgIC8vIFVud3JhcCBhbnkgd3JhcHBlZCBvYmplY3RzLlxuICAgIGlmIChhIGluc3RhbmNlb2YgXykgYSA9IGEuX3dyYXBwZWQ7XG4gICAgaWYgKGIgaW5zdGFuY2VvZiBfKSBiID0gYi5fd3JhcHBlZDtcbiAgICAvLyBDb21wYXJlIGBbW0NsYXNzXV1gIG5hbWVzLlxuICAgIHZhciBjbGFzc05hbWUgPSB0b1N0cmluZy5jYWxsKGEpO1xuICAgIGlmIChjbGFzc05hbWUgIT09IHRvU3RyaW5nLmNhbGwoYikpIHJldHVybiBmYWxzZTtcbiAgICBzd2l0Y2ggKGNsYXNzTmFtZSkge1xuICAgICAgLy8gU3RyaW5ncywgbnVtYmVycywgcmVndWxhciBleHByZXNzaW9ucywgZGF0ZXMsIGFuZCBib29sZWFucyBhcmUgY29tcGFyZWQgYnkgdmFsdWUuXG4gICAgICBjYXNlICdbb2JqZWN0IFJlZ0V4cF0nOlxuICAgICAgLy8gUmVnRXhwcyBhcmUgY29lcmNlZCB0byBzdHJpbmdzIGZvciBjb21wYXJpc29uIChOb3RlOiAnJyArIC9hL2kgPT09ICcvYS9pJylcbiAgICAgIGNhc2UgJ1tvYmplY3QgU3RyaW5nXSc6XG4gICAgICAgIC8vIFByaW1pdGl2ZXMgYW5kIHRoZWlyIGNvcnJlc3BvbmRpbmcgb2JqZWN0IHdyYXBwZXJzIGFyZSBlcXVpdmFsZW50OyB0aHVzLCBgXCI1XCJgIGlzXG4gICAgICAgIC8vIGVxdWl2YWxlbnQgdG8gYG5ldyBTdHJpbmcoXCI1XCIpYC5cbiAgICAgICAgcmV0dXJuICcnICsgYSA9PT0gJycgKyBiO1xuICAgICAgY2FzZSAnW29iamVjdCBOdW1iZXJdJzpcbiAgICAgICAgLy8gYE5hTmBzIGFyZSBlcXVpdmFsZW50LCBidXQgbm9uLXJlZmxleGl2ZS5cbiAgICAgICAgLy8gT2JqZWN0KE5hTikgaXMgZXF1aXZhbGVudCB0byBOYU5cbiAgICAgICAgaWYgKCthICE9PSArYSkgcmV0dXJuICtiICE9PSArYjtcbiAgICAgICAgLy8gQW4gYGVnYWxgIGNvbXBhcmlzb24gaXMgcGVyZm9ybWVkIGZvciBvdGhlciBudW1lcmljIHZhbHVlcy5cbiAgICAgICAgcmV0dXJuICthID09PSAwID8gMSAvICthID09PSAxIC8gYiA6ICthID09PSArYjtcbiAgICAgIGNhc2UgJ1tvYmplY3QgRGF0ZV0nOlxuICAgICAgY2FzZSAnW29iamVjdCBCb29sZWFuXSc6XG4gICAgICAgIC8vIENvZXJjZSBkYXRlcyBhbmQgYm9vbGVhbnMgdG8gbnVtZXJpYyBwcmltaXRpdmUgdmFsdWVzLiBEYXRlcyBhcmUgY29tcGFyZWQgYnkgdGhlaXJcbiAgICAgICAgLy8gbWlsbGlzZWNvbmQgcmVwcmVzZW50YXRpb25zLiBOb3RlIHRoYXQgaW52YWxpZCBkYXRlcyB3aXRoIG1pbGxpc2Vjb25kIHJlcHJlc2VudGF0aW9uc1xuICAgICAgICAvLyBvZiBgTmFOYCBhcmUgbm90IGVxdWl2YWxlbnQuXG4gICAgICAgIHJldHVybiArYSA9PT0gK2I7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYSAhPSAnb2JqZWN0JyB8fCB0eXBlb2YgYiAhPSAnb2JqZWN0JykgcmV0dXJuIGZhbHNlO1xuICAgIC8vIEFzc3VtZSBlcXVhbGl0eSBmb3IgY3ljbGljIHN0cnVjdHVyZXMuIFRoZSBhbGdvcml0aG0gZm9yIGRldGVjdGluZyBjeWNsaWNcbiAgICAvLyBzdHJ1Y3R1cmVzIGlzIGFkYXB0ZWQgZnJvbSBFUyA1LjEgc2VjdGlvbiAxNS4xMi4zLCBhYnN0cmFjdCBvcGVyYXRpb24gYEpPYC5cbiAgICB2YXIgbGVuZ3RoID0gYVN0YWNrLmxlbmd0aDtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIC8vIExpbmVhciBzZWFyY2guIFBlcmZvcm1hbmNlIGlzIGludmVyc2VseSBwcm9wb3J0aW9uYWwgdG8gdGhlIG51bWJlciBvZlxuICAgICAgLy8gdW5pcXVlIG5lc3RlZCBzdHJ1Y3R1cmVzLlxuICAgICAgaWYgKGFTdGFja1tsZW5ndGhdID09PSBhKSByZXR1cm4gYlN0YWNrW2xlbmd0aF0gPT09IGI7XG4gICAgfVxuICAgIC8vIE9iamVjdHMgd2l0aCBkaWZmZXJlbnQgY29uc3RydWN0b3JzIGFyZSBub3QgZXF1aXZhbGVudCwgYnV0IGBPYmplY3Rgc1xuICAgIC8vIGZyb20gZGlmZmVyZW50IGZyYW1lcyBhcmUuXG4gICAgdmFyIGFDdG9yID0gYS5jb25zdHJ1Y3RvciwgYkN0b3IgPSBiLmNvbnN0cnVjdG9yO1xuICAgIGlmIChcbiAgICAgIGFDdG9yICE9PSBiQ3RvciAmJlxuICAgICAgLy8gSGFuZGxlIE9iamVjdC5jcmVhdGUoeCkgY2FzZXNcbiAgICAgICdjb25zdHJ1Y3RvcicgaW4gYSAmJiAnY29uc3RydWN0b3InIGluIGIgJiZcbiAgICAgICEoXy5pc0Z1bmN0aW9uKGFDdG9yKSAmJiBhQ3RvciBpbnN0YW5jZW9mIGFDdG9yICYmXG4gICAgICAgIF8uaXNGdW5jdGlvbihiQ3RvcikgJiYgYkN0b3IgaW5zdGFuY2VvZiBiQ3RvcilcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gQWRkIHRoZSBmaXJzdCBvYmplY3QgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLlxuICAgIGFTdGFjay5wdXNoKGEpO1xuICAgIGJTdGFjay5wdXNoKGIpO1xuICAgIHZhciBzaXplLCByZXN1bHQ7XG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIGFuZCBhcnJheXMuXG4gICAgaWYgKGNsYXNzTmFtZSA9PT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgICAgLy8gQ29tcGFyZSBhcnJheSBsZW5ndGhzIHRvIGRldGVybWluZSBpZiBhIGRlZXAgY29tcGFyaXNvbiBpcyBuZWNlc3NhcnkuXG4gICAgICBzaXplID0gYS5sZW5ndGg7XG4gICAgICByZXN1bHQgPSBzaXplID09PSBiLmxlbmd0aDtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgLy8gRGVlcCBjb21wYXJlIHRoZSBjb250ZW50cywgaWdub3Jpbmcgbm9uLW51bWVyaWMgcHJvcGVydGllcy5cbiAgICAgICAgd2hpbGUgKHNpemUtLSkge1xuICAgICAgICAgIGlmICghKHJlc3VsdCA9IGVxKGFbc2l6ZV0sIGJbc2l6ZV0sIGFTdGFjaywgYlN0YWNrKSkpIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZXAgY29tcGFyZSBvYmplY3RzLlxuICAgICAgdmFyIGtleXMgPSBfLmtleXMoYSksIGtleTtcbiAgICAgIHNpemUgPSBrZXlzLmxlbmd0aDtcbiAgICAgIC8vIEVuc3VyZSB0aGF0IGJvdGggb2JqZWN0cyBjb250YWluIHRoZSBzYW1lIG51bWJlciBvZiBwcm9wZXJ0aWVzIGJlZm9yZSBjb21wYXJpbmcgZGVlcCBlcXVhbGl0eS5cbiAgICAgIHJlc3VsdCA9IF8ua2V5cyhiKS5sZW5ndGggPT09IHNpemU7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIHdoaWxlIChzaXplLS0pIHtcbiAgICAgICAgICAvLyBEZWVwIGNvbXBhcmUgZWFjaCBtZW1iZXJcbiAgICAgICAgICBrZXkgPSBrZXlzW3NpemVdO1xuICAgICAgICAgIGlmICghKHJlc3VsdCA9IF8uaGFzKGIsIGtleSkgJiYgZXEoYVtrZXldLCBiW2tleV0sIGFTdGFjaywgYlN0YWNrKSkpIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFJlbW92ZSB0aGUgZmlyc3Qgb2JqZWN0IGZyb20gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLlxuICAgIGFTdGFjay5wb3AoKTtcbiAgICBiU3RhY2sucG9wKCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBQZXJmb3JtIGEgZGVlcCBjb21wYXJpc29uIHRvIGNoZWNrIGlmIHR3byBvYmplY3RzIGFyZSBlcXVhbC5cbiAgXy5pc0VxdWFsID0gZnVuY3Rpb24oYSwgYikge1xuICAgIHJldHVybiBlcShhLCBiLCBbXSwgW10pO1xuICB9O1xuXG4gIC8vIElzIGEgZ2l2ZW4gYXJyYXksIHN0cmluZywgb3Igb2JqZWN0IGVtcHR5P1xuICAvLyBBbiBcImVtcHR5XCIgb2JqZWN0IGhhcyBubyBlbnVtZXJhYmxlIG93bi1wcm9wZXJ0aWVzLlxuICBfLmlzRW1wdHkgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiB0cnVlO1xuICAgIGlmIChfLmlzQXJyYXkob2JqKSB8fCBfLmlzU3RyaW5nKG9iaikgfHwgXy5pc0FyZ3VtZW50cyhvYmopKSByZXR1cm4gb2JqLmxlbmd0aCA9PT0gMDtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSBpZiAoXy5oYXMob2JqLCBrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YWx1ZSBhIERPTSBlbGVtZW50P1xuICBfLmlzRWxlbWVudCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiAhIShvYmogJiYgb2JqLm5vZGVUeXBlID09PSAxKTtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhbHVlIGFuIGFycmF5P1xuICAvLyBEZWxlZ2F0ZXMgdG8gRUNNQTUncyBuYXRpdmUgQXJyYXkuaXNBcnJheVxuICBfLmlzQXJyYXkgPSBuYXRpdmVJc0FycmF5IHx8IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiB0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IEFycmF5XSc7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YXJpYWJsZSBhbiBvYmplY3Q/XG4gIF8uaXNPYmplY3QgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgdHlwZSA9IHR5cGVvZiBvYmo7XG4gICAgcmV0dXJuIHR5cGUgPT09ICdmdW5jdGlvbicgfHwgdHlwZSA9PT0gJ29iamVjdCcgJiYgISFvYmo7XG4gIH07XG5cbiAgLy8gQWRkIHNvbWUgaXNUeXBlIG1ldGhvZHM6IGlzQXJndW1lbnRzLCBpc0Z1bmN0aW9uLCBpc1N0cmluZywgaXNOdW1iZXIsIGlzRGF0ZSwgaXNSZWdFeHAuXG4gIF8uZWFjaChbJ0FyZ3VtZW50cycsICdGdW5jdGlvbicsICdTdHJpbmcnLCAnTnVtYmVyJywgJ0RhdGUnLCAnUmVnRXhwJ10sIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBfWydpcycgKyBuYW1lXSA9IGZ1bmN0aW9uKG9iaikge1xuICAgICAgcmV0dXJuIHRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgJyArIG5hbWUgKyAnXSc7XG4gICAgfTtcbiAgfSk7XG5cbiAgLy8gRGVmaW5lIGEgZmFsbGJhY2sgdmVyc2lvbiBvZiB0aGUgbWV0aG9kIGluIGJyb3dzZXJzIChhaGVtLCBJRSksIHdoZXJlXG4gIC8vIHRoZXJlIGlzbid0IGFueSBpbnNwZWN0YWJsZSBcIkFyZ3VtZW50c1wiIHR5cGUuXG4gIGlmICghXy5pc0FyZ3VtZW50cyhhcmd1bWVudHMpKSB7XG4gICAgXy5pc0FyZ3VtZW50cyA9IGZ1bmN0aW9uKG9iaikge1xuICAgICAgcmV0dXJuIF8uaGFzKG9iaiwgJ2NhbGxlZScpO1xuICAgIH07XG4gIH1cblxuICAvLyBPcHRpbWl6ZSBgaXNGdW5jdGlvbmAgaWYgYXBwcm9wcmlhdGUuIFdvcmsgYXJvdW5kIGFuIElFIDExIGJ1Zy5cbiAgaWYgKHR5cGVvZiAvLi8gIT09ICdmdW5jdGlvbicpIHtcbiAgICBfLmlzRnVuY3Rpb24gPSBmdW5jdGlvbihvYmopIHtcbiAgICAgIHJldHVybiB0eXBlb2Ygb2JqID09ICdmdW5jdGlvbicgfHwgZmFsc2U7XG4gICAgfTtcbiAgfVxuXG4gIC8vIElzIGEgZ2l2ZW4gb2JqZWN0IGEgZmluaXRlIG51bWJlcj9cbiAgXy5pc0Zpbml0ZSA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiBpc0Zpbml0ZShvYmopICYmICFpc05hTihwYXJzZUZsb2F0KG9iaikpO1xuICB9O1xuXG4gIC8vIElzIHRoZSBnaXZlbiB2YWx1ZSBgTmFOYD8gKE5hTiBpcyB0aGUgb25seSBudW1iZXIgd2hpY2ggZG9lcyBub3QgZXF1YWwgaXRzZWxmKS5cbiAgXy5pc05hTiA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiBfLmlzTnVtYmVyKG9iaikgJiYgb2JqICE9PSArb2JqO1xuICB9O1xuXG4gIC8vIElzIGEgZ2l2ZW4gdmFsdWUgYSBib29sZWFuP1xuICBfLmlzQm9vbGVhbiA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiBvYmogPT09IHRydWUgfHwgb2JqID09PSBmYWxzZSB8fCB0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IEJvb2xlYW5dJztcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhbHVlIGVxdWFsIHRvIG51bGw/XG4gIF8uaXNOdWxsID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgcmV0dXJuIG9iaiA9PT0gbnVsbDtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhcmlhYmxlIHVuZGVmaW5lZD9cbiAgXy5pc1VuZGVmaW5lZCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiBvYmogPT09IHZvaWQgMDtcbiAgfTtcblxuICAvLyBTaG9ydGN1dCBmdW5jdGlvbiBmb3IgY2hlY2tpbmcgaWYgYW4gb2JqZWN0IGhhcyBhIGdpdmVuIHByb3BlcnR5IGRpcmVjdGx5XG4gIC8vIG9uIGl0c2VsZiAoaW4gb3RoZXIgd29yZHMsIG5vdCBvbiBhIHByb3RvdHlwZSkuXG4gIF8uaGFzID0gZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICByZXR1cm4gb2JqICE9IG51bGwgJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSk7XG4gIH07XG5cbiAgLy8gVXRpbGl0eSBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBSdW4gVW5kZXJzY29yZS5qcyBpbiAqbm9Db25mbGljdCogbW9kZSwgcmV0dXJuaW5nIHRoZSBgX2AgdmFyaWFibGUgdG8gaXRzXG4gIC8vIHByZXZpb3VzIG93bmVyLiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBVbmRlcnNjb3JlIG9iamVjdC5cbiAgXy5ub0NvbmZsaWN0ID0gZnVuY3Rpb24oKSB7XG4gICAgcm9vdC5fID0gcHJldmlvdXNVbmRlcnNjb3JlO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8vIEtlZXAgdGhlIGlkZW50aXR5IGZ1bmN0aW9uIGFyb3VuZCBmb3IgZGVmYXVsdCBpdGVyYXRlZXMuXG4gIF8uaWRlbnRpdHkgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfTtcblxuICBfLmNvbnN0YW50ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfTtcbiAgfTtcblxuICBfLm5vb3AgPSBmdW5jdGlvbigpe307XG5cbiAgXy5wcm9wZXJ0eSA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHJldHVybiBmdW5jdGlvbihvYmopIHtcbiAgICAgIHJldHVybiBvYmpba2V5XTtcbiAgICB9O1xuICB9O1xuXG4gIC8vIFJldHVybnMgYSBwcmVkaWNhdGUgZm9yIGNoZWNraW5nIHdoZXRoZXIgYW4gb2JqZWN0IGhhcyBhIGdpdmVuIHNldCBvZiBga2V5OnZhbHVlYCBwYWlycy5cbiAgXy5tYXRjaGVzID0gZnVuY3Rpb24oYXR0cnMpIHtcbiAgICB2YXIgcGFpcnMgPSBfLnBhaXJzKGF0dHJzKSwgbGVuZ3RoID0gcGFpcnMubGVuZ3RoO1xuICAgIHJldHVybiBmdW5jdGlvbihvYmopIHtcbiAgICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuICFsZW5ndGg7XG4gICAgICBvYmogPSBuZXcgT2JqZWN0KG9iaik7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBwYWlyID0gcGFpcnNbaV0sIGtleSA9IHBhaXJbMF07XG4gICAgICAgIGlmIChwYWlyWzFdICE9PSBvYmpba2V5XSB8fCAhKGtleSBpbiBvYmopKSByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuICB9O1xuXG4gIC8vIFJ1biBhIGZ1bmN0aW9uICoqbioqIHRpbWVzLlxuICBfLnRpbWVzID0gZnVuY3Rpb24obiwgaXRlcmF0ZWUsIGNvbnRleHQpIHtcbiAgICB2YXIgYWNjdW0gPSBBcnJheShNYXRoLm1heCgwLCBuKSk7XG4gICAgaXRlcmF0ZWUgPSBjcmVhdGVDYWxsYmFjayhpdGVyYXRlZSwgY29udGV4dCwgMSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIGFjY3VtW2ldID0gaXRlcmF0ZWUoaSk7XG4gICAgcmV0dXJuIGFjY3VtO1xuICB9O1xuXG4gIC8vIFJldHVybiBhIHJhbmRvbSBpbnRlZ2VyIGJldHdlZW4gbWluIGFuZCBtYXggKGluY2x1c2l2ZSkuXG4gIF8ucmFuZG9tID0gZnVuY3Rpb24obWluLCBtYXgpIHtcbiAgICBpZiAobWF4ID09IG51bGwpIHtcbiAgICAgIG1heCA9IG1pbjtcbiAgICAgIG1pbiA9IDA7XG4gICAgfVxuICAgIHJldHVybiBtaW4gKyBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAobWF4IC0gbWluICsgMSkpO1xuICB9O1xuXG4gIC8vIEEgKHBvc3NpYmx5IGZhc3Rlcikgd2F5IHRvIGdldCB0aGUgY3VycmVudCB0aW1lc3RhbXAgYXMgYW4gaW50ZWdlci5cbiAgXy5ub3cgPSBEYXRlLm5vdyB8fCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIH07XG5cbiAgIC8vIExpc3Qgb2YgSFRNTCBlbnRpdGllcyBmb3IgZXNjYXBpbmcuXG4gIHZhciBlc2NhcGVNYXAgPSB7XG4gICAgJyYnOiAnJmFtcDsnLFxuICAgICc8JzogJyZsdDsnLFxuICAgICc+JzogJyZndDsnLFxuICAgICdcIic6ICcmcXVvdDsnLFxuICAgIFwiJ1wiOiAnJiN4Mjc7JyxcbiAgICAnYCc6ICcmI3g2MDsnXG4gIH07XG4gIHZhciB1bmVzY2FwZU1hcCA9IF8uaW52ZXJ0KGVzY2FwZU1hcCk7XG5cbiAgLy8gRnVuY3Rpb25zIGZvciBlc2NhcGluZyBhbmQgdW5lc2NhcGluZyBzdHJpbmdzIHRvL2Zyb20gSFRNTCBpbnRlcnBvbGF0aW9uLlxuICB2YXIgY3JlYXRlRXNjYXBlciA9IGZ1bmN0aW9uKG1hcCkge1xuICAgIHZhciBlc2NhcGVyID0gZnVuY3Rpb24obWF0Y2gpIHtcbiAgICAgIHJldHVybiBtYXBbbWF0Y2hdO1xuICAgIH07XG4gICAgLy8gUmVnZXhlcyBmb3IgaWRlbnRpZnlpbmcgYSBrZXkgdGhhdCBuZWVkcyB0byBiZSBlc2NhcGVkXG4gICAgdmFyIHNvdXJjZSA9ICcoPzonICsgXy5rZXlzKG1hcCkuam9pbignfCcpICsgJyknO1xuICAgIHZhciB0ZXN0UmVnZXhwID0gUmVnRXhwKHNvdXJjZSk7XG4gICAgdmFyIHJlcGxhY2VSZWdleHAgPSBSZWdFeHAoc291cmNlLCAnZycpO1xuICAgIHJldHVybiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgIHN0cmluZyA9IHN0cmluZyA9PSBudWxsID8gJycgOiAnJyArIHN0cmluZztcbiAgICAgIHJldHVybiB0ZXN0UmVnZXhwLnRlc3Qoc3RyaW5nKSA/IHN0cmluZy5yZXBsYWNlKHJlcGxhY2VSZWdleHAsIGVzY2FwZXIpIDogc3RyaW5nO1xuICAgIH07XG4gIH07XG4gIF8uZXNjYXBlID0gY3JlYXRlRXNjYXBlcihlc2NhcGVNYXApO1xuICBfLnVuZXNjYXBlID0gY3JlYXRlRXNjYXBlcih1bmVzY2FwZU1hcCk7XG5cbiAgLy8gSWYgdGhlIHZhbHVlIG9mIHRoZSBuYW1lZCBgcHJvcGVydHlgIGlzIGEgZnVuY3Rpb24gdGhlbiBpbnZva2UgaXQgd2l0aCB0aGVcbiAgLy8gYG9iamVjdGAgYXMgY29udGV4dDsgb3RoZXJ3aXNlLCByZXR1cm4gaXQuXG4gIF8ucmVzdWx0ID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkge1xuICAgIGlmIChvYmplY3QgPT0gbnVsbCkgcmV0dXJuIHZvaWQgMDtcbiAgICB2YXIgdmFsdWUgPSBvYmplY3RbcHJvcGVydHldO1xuICAgIHJldHVybiBfLmlzRnVuY3Rpb24odmFsdWUpID8gb2JqZWN0W3Byb3BlcnR5XSgpIDogdmFsdWU7XG4gIH07XG5cbiAgLy8gR2VuZXJhdGUgYSB1bmlxdWUgaW50ZWdlciBpZCAodW5pcXVlIHdpdGhpbiB0aGUgZW50aXJlIGNsaWVudCBzZXNzaW9uKS5cbiAgLy8gVXNlZnVsIGZvciB0ZW1wb3JhcnkgRE9NIGlkcy5cbiAgdmFyIGlkQ291bnRlciA9IDA7XG4gIF8udW5pcXVlSWQgPSBmdW5jdGlvbihwcmVmaXgpIHtcbiAgICB2YXIgaWQgPSArK2lkQ291bnRlciArICcnO1xuICAgIHJldHVybiBwcmVmaXggPyBwcmVmaXggKyBpZCA6IGlkO1xuICB9O1xuXG4gIC8vIEJ5IGRlZmF1bHQsIFVuZGVyc2NvcmUgdXNlcyBFUkItc3R5bGUgdGVtcGxhdGUgZGVsaW1pdGVycywgY2hhbmdlIHRoZVxuICAvLyBmb2xsb3dpbmcgdGVtcGxhdGUgc2V0dGluZ3MgdG8gdXNlIGFsdGVybmF0aXZlIGRlbGltaXRlcnMuXG4gIF8udGVtcGxhdGVTZXR0aW5ncyA9IHtcbiAgICBldmFsdWF0ZSAgICA6IC88JShbXFxzXFxTXSs/KSU+L2csXG4gICAgaW50ZXJwb2xhdGUgOiAvPCU9KFtcXHNcXFNdKz8pJT4vZyxcbiAgICBlc2NhcGUgICAgICA6IC88JS0oW1xcc1xcU10rPyklPi9nXG4gIH07XG5cbiAgLy8gV2hlbiBjdXN0b21pemluZyBgdGVtcGxhdGVTZXR0aW5nc2AsIGlmIHlvdSBkb24ndCB3YW50IHRvIGRlZmluZSBhblxuICAvLyBpbnRlcnBvbGF0aW9uLCBldmFsdWF0aW9uIG9yIGVzY2FwaW5nIHJlZ2V4LCB3ZSBuZWVkIG9uZSB0aGF0IGlzXG4gIC8vIGd1YXJhbnRlZWQgbm90IHRvIG1hdGNoLlxuICB2YXIgbm9NYXRjaCA9IC8oLileLztcblxuICAvLyBDZXJ0YWluIGNoYXJhY3RlcnMgbmVlZCB0byBiZSBlc2NhcGVkIHNvIHRoYXQgdGhleSBjYW4gYmUgcHV0IGludG8gYVxuICAvLyBzdHJpbmcgbGl0ZXJhbC5cbiAgdmFyIGVzY2FwZXMgPSB7XG4gICAgXCInXCI6ICAgICAgXCInXCIsXG4gICAgJ1xcXFwnOiAgICAgJ1xcXFwnLFxuICAgICdcXHInOiAgICAgJ3InLFxuICAgICdcXG4nOiAgICAgJ24nLFxuICAgICdcXHUyMDI4JzogJ3UyMDI4JyxcbiAgICAnXFx1MjAyOSc6ICd1MjAyOSdcbiAgfTtcblxuICB2YXIgZXNjYXBlciA9IC9cXFxcfCd8XFxyfFxcbnxcXHUyMDI4fFxcdTIwMjkvZztcblxuICB2YXIgZXNjYXBlQ2hhciA9IGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgcmV0dXJuICdcXFxcJyArIGVzY2FwZXNbbWF0Y2hdO1xuICB9O1xuXG4gIC8vIEphdmFTY3JpcHQgbWljcm8tdGVtcGxhdGluZywgc2ltaWxhciB0byBKb2huIFJlc2lnJ3MgaW1wbGVtZW50YXRpb24uXG4gIC8vIFVuZGVyc2NvcmUgdGVtcGxhdGluZyBoYW5kbGVzIGFyYml0cmFyeSBkZWxpbWl0ZXJzLCBwcmVzZXJ2ZXMgd2hpdGVzcGFjZSxcbiAgLy8gYW5kIGNvcnJlY3RseSBlc2NhcGVzIHF1b3RlcyB3aXRoaW4gaW50ZXJwb2xhdGVkIGNvZGUuXG4gIC8vIE5COiBgb2xkU2V0dGluZ3NgIG9ubHkgZXhpc3RzIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cbiAgXy50ZW1wbGF0ZSA9IGZ1bmN0aW9uKHRleHQsIHNldHRpbmdzLCBvbGRTZXR0aW5ncykge1xuICAgIGlmICghc2V0dGluZ3MgJiYgb2xkU2V0dGluZ3MpIHNldHRpbmdzID0gb2xkU2V0dGluZ3M7XG4gICAgc2V0dGluZ3MgPSBfLmRlZmF1bHRzKHt9LCBzZXR0aW5ncywgXy50ZW1wbGF0ZVNldHRpbmdzKTtcblxuICAgIC8vIENvbWJpbmUgZGVsaW1pdGVycyBpbnRvIG9uZSByZWd1bGFyIGV4cHJlc3Npb24gdmlhIGFsdGVybmF0aW9uLlxuICAgIHZhciBtYXRjaGVyID0gUmVnRXhwKFtcbiAgICAgIChzZXR0aW5ncy5lc2NhcGUgfHwgbm9NYXRjaCkuc291cmNlLFxuICAgICAgKHNldHRpbmdzLmludGVycG9sYXRlIHx8IG5vTWF0Y2gpLnNvdXJjZSxcbiAgICAgIChzZXR0aW5ncy5ldmFsdWF0ZSB8fCBub01hdGNoKS5zb3VyY2VcbiAgICBdLmpvaW4oJ3wnKSArICd8JCcsICdnJyk7XG5cbiAgICAvLyBDb21waWxlIHRoZSB0ZW1wbGF0ZSBzb3VyY2UsIGVzY2FwaW5nIHN0cmluZyBsaXRlcmFscyBhcHByb3ByaWF0ZWx5LlxuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIHNvdXJjZSA9IFwiX19wKz0nXCI7XG4gICAgdGV4dC5yZXBsYWNlKG1hdGNoZXIsIGZ1bmN0aW9uKG1hdGNoLCBlc2NhcGUsIGludGVycG9sYXRlLCBldmFsdWF0ZSwgb2Zmc2V0KSB7XG4gICAgICBzb3VyY2UgKz0gdGV4dC5zbGljZShpbmRleCwgb2Zmc2V0KS5yZXBsYWNlKGVzY2FwZXIsIGVzY2FwZUNoYXIpO1xuICAgICAgaW5kZXggPSBvZmZzZXQgKyBtYXRjaC5sZW5ndGg7XG5cbiAgICAgIGlmIChlc2NhcGUpIHtcbiAgICAgICAgc291cmNlICs9IFwiJytcXG4oKF9fdD0oXCIgKyBlc2NhcGUgKyBcIikpPT1udWxsPycnOl8uZXNjYXBlKF9fdCkpK1xcbidcIjtcbiAgICAgIH0gZWxzZSBpZiAoaW50ZXJwb2xhdGUpIHtcbiAgICAgICAgc291cmNlICs9IFwiJytcXG4oKF9fdD0oXCIgKyBpbnRlcnBvbGF0ZSArIFwiKSk9PW51bGw/Jyc6X190KStcXG4nXCI7XG4gICAgICB9IGVsc2UgaWYgKGV2YWx1YXRlKSB7XG4gICAgICAgIHNvdXJjZSArPSBcIic7XFxuXCIgKyBldmFsdWF0ZSArIFwiXFxuX19wKz0nXCI7XG4gICAgICB9XG5cbiAgICAgIC8vIEFkb2JlIFZNcyBuZWVkIHRoZSBtYXRjaCByZXR1cm5lZCB0byBwcm9kdWNlIHRoZSBjb3JyZWN0IG9mZmVzdC5cbiAgICAgIHJldHVybiBtYXRjaDtcbiAgICB9KTtcbiAgICBzb3VyY2UgKz0gXCInO1xcblwiO1xuXG4gICAgLy8gSWYgYSB2YXJpYWJsZSBpcyBub3Qgc3BlY2lmaWVkLCBwbGFjZSBkYXRhIHZhbHVlcyBpbiBsb2NhbCBzY29wZS5cbiAgICBpZiAoIXNldHRpbmdzLnZhcmlhYmxlKSBzb3VyY2UgPSAnd2l0aChvYmp8fHt9KXtcXG4nICsgc291cmNlICsgJ31cXG4nO1xuXG4gICAgc291cmNlID0gXCJ2YXIgX190LF9fcD0nJyxfX2o9QXJyYXkucHJvdG90eXBlLmpvaW4sXCIgK1xuICAgICAgXCJwcmludD1mdW5jdGlvbigpe19fcCs9X19qLmNhbGwoYXJndW1lbnRzLCcnKTt9O1xcblwiICtcbiAgICAgIHNvdXJjZSArICdyZXR1cm4gX19wO1xcbic7XG5cbiAgICB0cnkge1xuICAgICAgdmFyIHJlbmRlciA9IG5ldyBGdW5jdGlvbihzZXR0aW5ncy52YXJpYWJsZSB8fCAnb2JqJywgJ18nLCBzb3VyY2UpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGUuc291cmNlID0gc291cmNlO1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICB2YXIgdGVtcGxhdGUgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgICByZXR1cm4gcmVuZGVyLmNhbGwodGhpcywgZGF0YSwgXyk7XG4gICAgfTtcblxuICAgIC8vIFByb3ZpZGUgdGhlIGNvbXBpbGVkIHNvdXJjZSBhcyBhIGNvbnZlbmllbmNlIGZvciBwcmVjb21waWxhdGlvbi5cbiAgICB2YXIgYXJndW1lbnQgPSBzZXR0aW5ncy52YXJpYWJsZSB8fCAnb2JqJztcbiAgICB0ZW1wbGF0ZS5zb3VyY2UgPSAnZnVuY3Rpb24oJyArIGFyZ3VtZW50ICsgJyl7XFxuJyArIHNvdXJjZSArICd9JztcblxuICAgIHJldHVybiB0ZW1wbGF0ZTtcbiAgfTtcblxuICAvLyBBZGQgYSBcImNoYWluXCIgZnVuY3Rpb24uIFN0YXJ0IGNoYWluaW5nIGEgd3JhcHBlZCBVbmRlcnNjb3JlIG9iamVjdC5cbiAgXy5jaGFpbiA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHZhciBpbnN0YW5jZSA9IF8ob2JqKTtcbiAgICBpbnN0YW5jZS5fY2hhaW4gPSB0cnVlO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfTtcblxuICAvLyBPT1BcbiAgLy8gLS0tLS0tLS0tLS0tLS0tXG4gIC8vIElmIFVuZGVyc2NvcmUgaXMgY2FsbGVkIGFzIGEgZnVuY3Rpb24sIGl0IHJldHVybnMgYSB3cmFwcGVkIG9iamVjdCB0aGF0XG4gIC8vIGNhbiBiZSB1c2VkIE9PLXN0eWxlLiBUaGlzIHdyYXBwZXIgaG9sZHMgYWx0ZXJlZCB2ZXJzaW9ucyBvZiBhbGwgdGhlXG4gIC8vIHVuZGVyc2NvcmUgZnVuY3Rpb25zLiBXcmFwcGVkIG9iamVjdHMgbWF5IGJlIGNoYWluZWQuXG5cbiAgLy8gSGVscGVyIGZ1bmN0aW9uIHRvIGNvbnRpbnVlIGNoYWluaW5nIGludGVybWVkaWF0ZSByZXN1bHRzLlxuICB2YXIgcmVzdWx0ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NoYWluID8gXyhvYmopLmNoYWluKCkgOiBvYmo7XG4gIH07XG5cbiAgLy8gQWRkIHlvdXIgb3duIGN1c3RvbSBmdW5jdGlvbnMgdG8gdGhlIFVuZGVyc2NvcmUgb2JqZWN0LlxuICBfLm1peGluID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgXy5lYWNoKF8uZnVuY3Rpb25zKG9iaiksIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIHZhciBmdW5jID0gX1tuYW1lXSA9IG9ialtuYW1lXTtcbiAgICAgIF8ucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gW3RoaXMuX3dyYXBwZWRdO1xuICAgICAgICBwdXNoLmFwcGx5KGFyZ3MsIGFyZ3VtZW50cyk7XG4gICAgICAgIHJldHVybiByZXN1bHQuY2FsbCh0aGlzLCBmdW5jLmFwcGx5KF8sIGFyZ3MpKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH07XG5cbiAgLy8gQWRkIGFsbCBvZiB0aGUgVW5kZXJzY29yZSBmdW5jdGlvbnMgdG8gdGhlIHdyYXBwZXIgb2JqZWN0LlxuICBfLm1peGluKF8pO1xuXG4gIC8vIEFkZCBhbGwgbXV0YXRvciBBcnJheSBmdW5jdGlvbnMgdG8gdGhlIHdyYXBwZXIuXG4gIF8uZWFjaChbJ3BvcCcsICdwdXNoJywgJ3JldmVyc2UnLCAnc2hpZnQnLCAnc29ydCcsICdzcGxpY2UnLCAndW5zaGlmdCddLCBmdW5jdGlvbihuYW1lKSB7XG4gICAgdmFyIG1ldGhvZCA9IEFycmF5UHJvdG9bbmFtZV07XG4gICAgXy5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBvYmogPSB0aGlzLl93cmFwcGVkO1xuICAgICAgbWV0aG9kLmFwcGx5KG9iaiwgYXJndW1lbnRzKTtcbiAgICAgIGlmICgobmFtZSA9PT0gJ3NoaWZ0JyB8fCBuYW1lID09PSAnc3BsaWNlJykgJiYgb2JqLmxlbmd0aCA9PT0gMCkgZGVsZXRlIG9ialswXTtcbiAgICAgIHJldHVybiByZXN1bHQuY2FsbCh0aGlzLCBvYmopO1xuICAgIH07XG4gIH0pO1xuXG4gIC8vIEFkZCBhbGwgYWNjZXNzb3IgQXJyYXkgZnVuY3Rpb25zIHRvIHRoZSB3cmFwcGVyLlxuICBfLmVhY2goWydjb25jYXQnLCAnam9pbicsICdzbGljZSddLCBmdW5jdGlvbihuYW1lKSB7XG4gICAgdmFyIG1ldGhvZCA9IEFycmF5UHJvdG9bbmFtZV07XG4gICAgXy5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiByZXN1bHQuY2FsbCh0aGlzLCBtZXRob2QuYXBwbHkodGhpcy5fd3JhcHBlZCwgYXJndW1lbnRzKSk7XG4gICAgfTtcbiAgfSk7XG5cbiAgLy8gRXh0cmFjdHMgdGhlIHJlc3VsdCBmcm9tIGEgd3JhcHBlZCBhbmQgY2hhaW5lZCBvYmplY3QuXG4gIF8ucHJvdG90eXBlLnZhbHVlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyYXBwZWQ7XG4gIH07XG5cbiAgLy8gQU1EIHJlZ2lzdHJhdGlvbiBoYXBwZW5zIGF0IHRoZSBlbmQgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBBTUQgbG9hZGVyc1xuICAvLyB0aGF0IG1heSBub3QgZW5mb3JjZSBuZXh0LXR1cm4gc2VtYW50aWNzIG9uIG1vZHVsZXMuIEV2ZW4gdGhvdWdoIGdlbmVyYWxcbiAgLy8gcHJhY3RpY2UgZm9yIEFNRCByZWdpc3RyYXRpb24gaXMgdG8gYmUgYW5vbnltb3VzLCB1bmRlcnNjb3JlIHJlZ2lzdGVyc1xuICAvLyBhcyBhIG5hbWVkIG1vZHVsZSBiZWNhdXNlLCBsaWtlIGpRdWVyeSwgaXQgaXMgYSBiYXNlIGxpYnJhcnkgdGhhdCBpc1xuICAvLyBwb3B1bGFyIGVub3VnaCB0byBiZSBidW5kbGVkIGluIGEgdGhpcmQgcGFydHkgbGliLCBidXQgbm90IGJlIHBhcnQgb2ZcbiAgLy8gYW4gQU1EIGxvYWQgcmVxdWVzdC4gVGhvc2UgY2FzZXMgY291bGQgZ2VuZXJhdGUgYW4gZXJyb3Igd2hlbiBhblxuICAvLyBhbm9ueW1vdXMgZGVmaW5lKCkgaXMgY2FsbGVkIG91dHNpZGUgb2YgYSBsb2FkZXIgcmVxdWVzdC5cbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgIGRlZmluZSgndW5kZXJzY29yZScsIFtdLCBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBfO1xuICAgIH0pO1xuICB9XG59LmNhbGwodGhpcykpO1xuIiwiY2hhaSAgICAgID0gcmVxdWlyZSgnY2hhaScpXG5leHBlY3QgICAgPSBjaGFpLmV4cGVjdFxuc2hvdWxkICAgID0gY2hhaS5zaG91bGQoKVxuc2lub24gICAgID0gcmVxdWlyZSgnc2lub24nKVxuc2lub25DaGFpID0gcmVxdWlyZSgnc2lub24tY2hhaScpXG5fICAgICAgICAgPSByZXF1aXJlKFwidW5kZXJzY29yZVwiKVxuXG5jaGFpLnVzZShzaW5vbkNoYWkpXG5cblkgPSByZXF1aXJlIFwiLi4vbGliL2luZGV4XCJcbkNvbm5lY3Rvcl91bmluaXRpYWxpemVkID0gcmVxdWlyZSBcIi4uL2xpYi9Db25uZWN0b3JzL1Rlc3RDb25uZWN0b3JcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsYXNzIFRlc3RcbiAgY29uc3RydWN0b3I6IChAbmFtZV9zdWZmaXggPSBcIlwiKS0+XG4gICAgQG51bWJlcl9vZl90ZXN0X2Nhc2VzX211bHRpcGxpZXIgPSAxXG4gICAgQHJlcGVhdF90aGlzID0gMSAqIEBudW1iZXJfb2ZfdGVzdF9jYXNlc19tdWx0aXBsaWVyXG4gICAgQGRvU29tZXRoaW5nX2Ftb3VudCA9IDIwICsgQG51bWJlcl9vZl90ZXN0X2Nhc2VzX211bHRpcGxpZXJcbiAgICBAbnVtYmVyX29mX2VuZ2luZXMgPSA1ICsgQG51bWJlcl9vZl90ZXN0X2Nhc2VzX211bHRpcGxpZXIgLSAxXG5cbiAgICBAdGltZSA9IDBcbiAgICBAb3BzID0gMFxuICAgIEB0aW1lX25vdyA9IDBcblxuICAgIEBkZWJ1ZyA9IGZhbHNlXG5cbiAgICBAcmVpbml0aWFsaXplKClcblxuICByZWluaXRpYWxpemU6ICgpLT5cbiAgICBAdXNlcnMgPSBbXVxuICAgIEBDb25uZWN0b3IgPSBDb25uZWN0b3JfdW5pbml0aWFsaXplZCBAdXNlcnNcbiAgICBmb3IgaSBpbiBbMC4uLkBudW1iZXJfb2ZfZW5naW5lc11cbiAgICAgIHUgPSBAbWFrZU5ld1VzZXIgKGkrQG5hbWVfc3VmZml4KSwgQENvbm5lY3RvclxuICAgICAgQHVzZXJzLnB1c2ggdVxuICAgICNAdXNlcnNbMF0udmFsKCduYW1lJyxcImlcIilcbiAgICBAZmx1c2hBbGwoKVxuXG4gIG1ha2VOZXdVc2VyOiAodXNlciktPlxuICAgIHVzZXIuSEIuc2V0TWFudWFsR2FyYmFnZUNvbGxlY3QoKVxuICAgIHVzZXJcblxuICBnZXRTb21lVXNlcjogKCktPlxuICAgIGkgPSBfLnJhbmRvbSAwLCAoQHVzZXJzLmxlbmd0aC0xKVxuICAgIEB1c2Vyc1tpXVxuXG4gIGdldFJhbmRvbVRleHQ6IChjaGFycywgbWluX2xlbmd0aCA9IDApLT5cbiAgICBjaGFycyA/PSBcImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6XCJcbiAgICBsZW5ndGggPSBfLnJhbmRvbSBtaW5fbGVuZ3RoLCAxMFxuICAgICNsZW5ndGggPSAxXG4gICAgbmV4dGNoYXIgPSBjaGFyc1soXy5yYW5kb20gMCwgKGNoYXJzLmxlbmd0aC0xKSldXG4gICAgdGV4dCA9IFwiXCJcbiAgICBfKGxlbmd0aCkudGltZXMgKCktPiB0ZXh0ICs9IG5leHRjaGFyXG4gICAgdGV4dFxuXG4gIGdldFJhbmRvbU9iamVjdDogKCktPlxuICAgIHJlc3VsdCA9IHt9XG4gICAga2V5MSA9IEBnZXRSYW5kb21LZXkoKVxuICAgIGtleTIgPSBAZ2V0UmFuZG9tS2V5KClcbiAgICB2YWwxID0gQGdldFJhbmRvbVRleHQoKVxuICAgIHZhbDIgPSBudWxsXG4gICAgaWYgXy5yYW5kb20oMCwxKSBpcyAxXG4gICAgICB2YWwyID0gQGdldFJhbmRvbU9iamVjdCgpXG4gICAgZWxzZVxuICAgICAgdmFsMiA9IEBnZXRSYW5kb21UZXh0KClcbiAgICByZXN1bHRba2V5MV0gPSB2YWwxXG4gICAgcmVzdWx0W2tleTJdID0gdmFsMlxuICAgIHJlc3VsdFxuXG4gIGdldFJhbmRvbUtleTogKCktPlxuICAgIEBnZXRSYW5kb21UZXh0IFsxLDIsJ3gnLCd5J10sIDEgIyBvbmx5IDQga2V5c1xuXG4gIGdldEdlbmVyYXRpbmdGdW5jdGlvbnM6ICh1c2VyX251bSk9PlxuICAgIHR5cGVzID0gQHVzZXJzW3VzZXJfbnVtXS50eXBlc1xuICAgIFtcbiAgICAgICAgZiA6ICh5KT0+ICMgSU5TRVJUIFRFWFRcbiAgICAgICAgICB5XG4gICAgICAgICAgcG9zID0gXy5yYW5kb20gMCwgKHkudmFsKCkubGVuZ3RoLTEpXG4gICAgICAgICAgeS5pbnNlcnRUZXh0IHBvcywgQGdldFJhbmRvbVRleHQoKVxuICAgICAgICAgIG51bGxcbiAgICAgICAgdHlwZXM6IFt0eXBlcy5Xb3JkVHlwZV1cbiAgICAgICxcbiAgICAgICAgZiA6ICh5KS0+ICMgREVMRVRFIFRFWFRcbiAgICAgICAgICBpZiB5LnZhbCgpLmxlbmd0aCA+IDBcbiAgICAgICAgICAgIHBvcyA9IF8ucmFuZG9tIDAsICh5LnZhbCgpLmxlbmd0aC0xKVxuICAgICAgICAgICAgbGVuZ3RoID0gXy5yYW5kb20gMCwgKHkudmFsKCkubGVuZ3RoIC0gcG9zKVxuICAgICAgICAgICAgb3BzMSA9IHkuZGVsZXRlVGV4dCBwb3MsIGxlbmd0aFxuICAgICAgICAgIHVuZGVmaW5lZFxuICAgICAgICB0eXBlcyA6IFt0eXBlcy5Xb3JkVHlwZV1cbiAgICAgICxcbiAgICAgICAgZiA6ICh5KT0+ICMgUkVQTEFDRSBURVhUXG4gICAgICAgICAgeS5yZXBsYWNlVGV4dCBAZ2V0UmFuZG9tVGV4dCgpXG4gICAgICAgICAgbnVsbFxuICAgICAgICB0eXBlczogW3R5cGVzLldvcmRUeXBlXVxuICAgIF1cbiAgZ2V0UmFuZG9tUm9vdDogKHVzZXJfbnVtKS0+XG4gICAgdGhyb3cgbmV3IEVycm9yIFwib3ZlcndyaXRlIG1lIVwiXG5cbiAgZ2V0Q29udGVudDogKHVzZXJfbnVtKS0+XG4gICAgdGhyb3cgbmV3IEVycm9yIFwib3ZlcndyaXRlIG1lIVwiXG5cbiAgZ2VuZXJhdGVSYW5kb21PcDogKHVzZXJfbnVtKT0+XG4gICAgeSA9IEBnZXRSYW5kb21Sb290KHVzZXJfbnVtKVxuICAgIGNob2ljZXMgPSBAZ2V0R2VuZXJhdGluZ0Z1bmN0aW9ucyh1c2VyX251bSkuZmlsdGVyIChnZiktPlxuICAgICAgXy5zb21lIGdmLnR5cGVzLCAodHlwZSktPlxuICAgICAgICB5IGluc3RhbmNlb2YgdHlwZVxuXG4gICAgaWYgY2hvaWNlcy5sZW5ndGggaXMgMFxuICAgICAgdGhyb3cgbmV3IEVycm9yIFwiWW91IGZvcmdvdCB0byBzcGVjaWZ5IGEgdGVzdCBnZW5lcmF0aW9uIG1ldGhvdCBmb3IgdGhpcyBPcGVyYXRpb24hXCJcbiAgICBpID0gXy5yYW5kb20gMCwgKGNob2ljZXMubGVuZ3RoLTEpXG4gICAgY2hvaWNlc1tpXS5mIHlcblxuICBhcHBseVJhbmRvbU9wOiAodXNlcl9udW0pPT5cbiAgICB1c2VyID0gQHVzZXJzW3VzZXJfbnVtXVxuICAgIHVzZXIuZ2V0Q29ubmVjdG9yKCkuZmx1c2hPbmVSYW5kb20oKVxuXG4gIGRvU29tZXRoaW5nOiAoKS0+XG4gICAgdXNlcl9udW0gPSBfLnJhbmRvbSAoQG51bWJlcl9vZl9lbmdpbmVzLTEpXG4gICAgY2hvaWNlcyA9IFtAYXBwbHlSYW5kb21PcCwgQGdlbmVyYXRlUmFuZG9tT3BdXG4gICAgY2hvaWNlID0gXy5yYW5kb20gKGNob2ljZXMubGVuZ3RoLTEpXG4gICAgY2hvaWNlc1tjaG9pY2VdKHVzZXJfbnVtKVxuXG4gIGZsdXNoQWxsOiAoZmluYWwpLT5cbiAgICAjIFRPRE86ISFcbiAgICBmaW5hbCA9IGZhbHNlXG4gICAgaWYgQHVzZXJzLmxlbmd0aCA8PSAxIG9yIG5vdCBmaW5hbFxuICAgICAgZm9yIHVzZXIsdXNlcl9udW1iZXIgaW4gQHVzZXJzXG4gICAgICAgIHVzZXIuZ2V0Q29ubmVjdG9yKCkuZmx1c2hBbGwoKVxuICAgIGVsc2VcbiAgICAgIGZvciB1c2VyLHVzZXJfbnVtYmVyIGluIEB1c2Vyc1sxLi5dXG4gICAgICAgIHVzZXIuZ2V0Q29ubmVjdG9yKCkuZmx1c2hBbGwoKVxuICAgICAgb3BzID0gQHVzZXJzWzFdLmdldEhpc3RvcnlCdWZmZXIoKS5fZW5jb2RlIEB1c2Vyc1swXS5IQi5nZXRPcGVyYXRpb25Db3VudGVyKClcbiAgICAgIEB1c2Vyc1swXS5lbmdpbmUuYXBwbHlPcHNDaGVja0RvdWJsZSBvcHNcblxuXG5cbiAgY29tcGFyZUFsbDogKHRlc3RfbnVtYmVyKS0+XG4gICAgQGZsdXNoQWxsKHRydWUpXG5cbiAgICBAdGltZSArPSAobmV3IERhdGUoKSkuZ2V0VGltZSgpIC0gQHRpbWVfbm93XG5cbiAgICBudW1iZXJfb2ZfY3JlYXRlZF9vcGVyYXRpb25zID0gMFxuICAgIGZvciBpIGluIFswLi4uKEB1c2Vycy5sZW5ndGgpXVxuICAgICAgbnVtYmVyX29mX2NyZWF0ZWRfb3BlcmF0aW9ucyArPSBAdXNlcnNbaV0uZ2V0Q29ubmVjdG9yKCkuZ2V0T3BzSW5FeGVjdXRpb25PcmRlcigpLmxlbmd0aFxuICAgIEBvcHMgKz0gbnVtYmVyX29mX2NyZWF0ZWRfb3BlcmF0aW9ucypAdXNlcnMubGVuZ3RoXG5cbiAgICBvcHNfcGVyX21zZWsgPSBNYXRoLmZsb29yKEBvcHMvQHRpbWUpXG4gICAgaWYgdGVzdF9udW1iZXI/ICMgYW5kIEBkZWJ1Z1xuICAgICAgY29uc29sZS5sb2cgXCIje3Rlc3RfbnVtYmVyfS8je0ByZXBlYXRfdGhpc306ICN7bnVtYmVyX29mX2NyZWF0ZWRfb3BlcmF0aW9uc30gd2VyZSBjcmVhdGVkIGFuZCBhcHBsaWVkIG9uICgje0B1c2Vycy5sZW5ndGh9KSB1c2VycyBvcHMgaW4gYSBkaWZmZXJlbnQgb3JkZXIuXCIgKyBcIiBPdmVyIGFsbCB3ZSBjb25zdW1lZCAje0BvcHN9IG9wZXJhdGlvbnMgaW4gI3tAdGltZS8xMDAwfSBzZWNvbmRzICgje29wc19wZXJfbXNla30gb3BzL21zZWspLlwiXG5cbiAgICBmb3IgaSBpbiBbMC4uLihAdXNlcnMubGVuZ3RoLTEpXVxuICAgICAgaWYgQGRlYnVnXG4gICAgICAgIGlmIG5vdCBfLmlzRXF1YWwgQGdldENvbnRlbnQoaSksIEBnZXRDb250ZW50KGkrMSlcbiAgICAgICAgICBwcmludE9wc0luRXhlY3V0aW9uT3JkZXIgPSAob3RudW1iZXIsIG90aGVyb3RudW1iZXIpPT5cbiAgICAgICAgICAgIG9wcyA9IF8uZmlsdGVyIEB1c2Vyc1tvdG51bWJlcl0uZ2V0Q29ubmVjdG9yKCkuZ2V0T3BzSW5FeGVjdXRpb25PcmRlcigpLCAobyktPlxuICAgICAgICAgICAgICB0eXBlb2Ygby51aWQub3BfbmFtZSBpc250ICdzdHJpbmcnIGFuZCBvLnVpZC5jcmVhdG9yIGlzbnQgJ18nXG4gICAgICAgICAgICBmb3IgcyxqIGluIG9wc1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZyBcIm9wI3tqfSA9IFwiICsgKEpTT04uc3RyaW5naWZ5IHMpXG4gICAgICAgICAgICBjb25zb2xlLmxvZyBcIlwiXG4gICAgICAgICAgICBzID0gXCJvcHMgPSBbXCJcbiAgICAgICAgICAgIGZvciBvLGogaW4gb3BzXG4gICAgICAgICAgICAgIGlmIGogaXNudCAwXG4gICAgICAgICAgICAgICAgcyArPSBcIiwgXCJcbiAgICAgICAgICAgICAgcyArPSBcIm9wI3tqfVwiXG4gICAgICAgICAgICBzICs9IFwiXVwiXG4gICAgICAgICAgICBjb25zb2xlLmxvZyBzXG4gICAgICAgICAgICBjb25zb2xlLmxvZyBcIkB0ZXN0X3VzZXIuZW5naW5lLmFwcGx5T3BzIG9wc1wiXG4gICAgICAgICAgICBjb25zb2xlLmxvZyBcImV4cGVjdChAdGVzdF91c2VyLnZhbCgnbmFtZScpLnZhbCgpKS50by5lcXVhbChcXFwiI3tAdXNlcnNbb3RoZXJvdG51bWJlcl0udmFsKCduYW1lJykudmFsKCl9XFxcIilcIlxuICAgICAgICAgICAgb3BzXG4gICAgICAgICAgY29uc29sZS5sb2cgXCJcIlxuICAgICAgICAgIGNvbnNvbGUubG9nIFwiRm91bmQgYW4gT1QgUHV6emxlIVwiXG4gICAgICAgICAgY29uc29sZS5sb2cgXCJPVCBzdGF0ZXM6XCJcbiAgICAgICAgICBmb3IgdSxqIGluIEB1c2Vyc1xuICAgICAgICAgICAgY29uc29sZS5sb2cgXCJPVCN7an06IFwiK3UudmFsKCduYW1lJykudmFsKClcbiAgICAgICAgICBjb25zb2xlLmxvZyBcIlxcbk9UIGV4ZWN1dGlvbiBvcmRlciAoI3tpfSwje2krMX0pOlwiXG4gICAgICAgICAgcHJpbnRPcHNJbkV4ZWN1dGlvbk9yZGVyIGksIGkrMVxuICAgICAgICAgIGNvbnNvbGUubG9nIFwiXCJcbiAgICAgICAgICBvcHMgPSBwcmludE9wc0luRXhlY3V0aW9uT3JkZXIgaSsxLCBpXG5cbiAgICAgICAgICBjb25zb2xlLmxvZyBcIlwiXG4gICAgICBleHBlY3QoQGdldENvbnRlbnQoaSkpLnRvLmRlZXAuZXF1YWwoQGdldENvbnRlbnQoaSsxKSlcblxuICBydW46ICgpLT5cbiAgICBpZiBAZGVidWdcbiAgICAgIGNvbnNvbGUubG9nICcnXG4gICAgZm9yIHRpbWVzIGluIFsxLi5AcmVwZWF0X3RoaXNdXG4gICAgICBAdGltZV9ub3cgPSAobmV3IERhdGUpLmdldFRpbWUoKVxuICAgICAgZm9yIGkgaW4gWzEuLk1hdGguZmxvb3IoQGRvU29tZXRoaW5nX2Ftb3VudC8yKV1cbiAgICAgICAgQGRvU29tZXRoaW5nKClcbiAgICAgIEBmbHVzaEFsbChmYWxzZSlcbiAgICAgIGZvciB1IGluIEB1c2Vyc1xuICAgICAgICB1LkhCLmVtcHR5R2FyYmFnZSgpXG4gICAgICBmb3IgaSBpbiBbMS4uTWF0aC5mbG9vcihAZG9Tb21ldGhpbmdfYW1vdW50LzIpXVxuICAgICAgICBAZG9Tb21ldGhpbmcoKVxuXG4gICAgICBAY29tcGFyZUFsbCh0aW1lcylcbiAgICAgIEB0ZXN0SEJlbmNvZGluZygpXG4gICAgICBpZiB0aW1lcyBpc250IEByZXBlYXRfdGhpc1xuICAgICAgICBAcmVpbml0aWFsaXplKClcblxuICB0ZXN0SEJlbmNvZGluZzogKCktPlxuICAgICMgaW4gY2FzZSBvZiBKc29uRnJhbWV3b3JrLCBldmVyeSB1c2VyIHdpbGwgY3JlYXRlIGl0cyBKU09OIGZpcnN0ISB0aGVyZWZvcmUsIHRoZSB0ZXN0dXNlcnMgaWQgbXVzdCBiZSBzbWFsbCB0aGFuIGFsbCB0aGUgb3RoZXJzIChzZWUgSW5zZXJ0VHlwZSlcbiAgICBAdXNlcnNbQHVzZXJzLmxlbmd0aF0gPSBAbWFrZU5ld1VzZXIgKC0xKSwgKENvbm5lY3Rvcl91bmluaXRpYWxpemVkIFtdKVxuICAgIEB1c2Vyc1tAdXNlcnMubGVuZ3RoLTFdLmVuZ2luZS5hcHBseU9wcyBAdXNlcnNbMF0uSEIuX2VuY29kZSgpXG5cbiAgICAjaWYgQGdldENvbnRlbnQoQHVzZXJzLmxlbmd0aC0xKSBpc250IEBnZXRDb250ZW50KDApXG4gICAgIyAgY29uc29sZS5sb2cgXCJ0ZXN0SEJlbmNvZGluZzpcIlxuICAgICMgIGNvbnNvbGUubG9nIFwiVW5wcm9jZXNzZWQgb3BzIGZpcnN0OiAje0B1c2Vyc1swXS5lbmdpbmUudW5wcm9jZXNzZWRfb3BzLmxlbmd0aH1cIlxuICAgICMgIGNvbnNvbGUubG9nIFwiVW5wcm9jZXNzZWQgb3BzIGxhc3Q6ICN7QHVzZXJzW0B1c2Vycy5sZW5ndGgtMV0uZW5naW5lLnVucHJvY2Vzc2VkX29wcy5sZW5ndGh9XCJcbiAgICBleHBlY3QoQGdldENvbnRlbnQoQHVzZXJzLmxlbmd0aC0xKSkudG8uZGVlcC5lcXVhbChAZ2V0Q29udGVudCgwKSlcblxuIiwiY2hhaSAgICAgID0gcmVxdWlyZSgnY2hhaScpXG5leHBlY3QgICAgPSBjaGFpLmV4cGVjdFxuc2hvdWxkICAgID0gY2hhaS5zaG91bGQoKVxuc2lub24gICAgID0gcmVxdWlyZSgnc2lub24nKVxuc2lub25DaGFpID0gcmVxdWlyZSgnc2lub24tY2hhaScpXG5fICAgICAgICAgPSByZXF1aXJlKFwidW5kZXJzY29yZVwiKVxuJCAgICAgICAgID0gcmVxdWlyZShcImpxdWVyeVwiKVxuZG9jdW1lbnQ/LiQgPSAkICMgZm9yIGJyb3dzZXJcbnJlcXVpcmUgJ2NvZmZlZS1lcnJvcnMnXG5cbmNoYWkudXNlKHNpbm9uQ2hhaSlcblxuWSA9IHJlcXVpcmUgXCIuLi9saWIvaW5kZXhcIlxuQ29ubmVjdG9yX3VuaW5pdGlhbGl6ZWQgPSByZXF1aXJlIFwiLi4vbGliL0Nvbm5lY3RvcnMvVGVzdENvbm5lY3RvclwiXG5cblRlc3QgPSByZXF1aXJlIFwiLi9UZXN0U3VpdGVcIlxuY2xhc3MgWG1sVGVzdCBleHRlbmRzIFRlc3RcblxuICB0eXBlOiBcIlhtbFRlc3RcIlxuXG4gIG1ha2VOZXdVc2VyOiAodXNlciwgY29ubiktPlxuICAgIHN1cGVyIG5ldyBZLlhtbEZyYW1ld29yayB1c2VyLCBjb25uXG5cbiAgZ2V0UmFuZG9tUm9vdDogKHVzZXJfbnVtKS0+XG4gICAgQHVzZXJzW3VzZXJfbnVtXS5nZXRTaGFyZWRPYmplY3QoKVxuXG4gIGdldENvbnRlbnQ6ICh1c2VyX251bSktPlxuICAgIEB1c2Vyc1t1c2VyX251bV0udmFsKClcblxuXG5kZXNjcmliZSBcIlhtbEZyYW1ld29ya1wiLCAtPlxuICBiZWZvcmVFYWNoIChkb25lKS0+XG4gICAgQHRpbWVvdXQgNTAwMDBcbiAgICBAeVRlc3QgPSBuZXcgWG1sVGVzdCgpXG4gICAgIyMjXG5cbiAgICBAdXNlcnMgPSBAeVRlc3QudXNlcnNcbiAgICAjIyNcbiAgICBAdGVzdF91c2VyID0gQHlUZXN0Lm1ha2VOZXdVc2VyIDAsIChDb25uZWN0b3JfdW5pbml0aWFsaXplZCBbXSlcbiAgICBkb25lKClcblxuICBpdCBcImNhbiB0cmFuc2Zvcm0gdG8gYSByZWFsIERvbSBlbGVtZW50XCIsIC0+XG4gICAgZG9tID0gJChcIiN0ZXN0X2RvbVwiKVswXVxuICAgIEB0ZXN0X3VzZXIudmFsKGRvbSlcbiAgICBkb21fID0gQHRlc3RfdXNlci52YWwodHJ1ZSlcbiAgICBleHBlY3QoZG9tXyBpc250IGRvbSkudG8uYmUudHJ1ZVxuICAgIGV4cGVjdChkb21fLm91dGVySFRNTCkudG8uZXF1YWwoZG9tLm91dGVySFRNTClcbiAgICBjb25zb2xlLmxvZyBcImR0cm5cIlxuXG4iXX0=
|