diff --git a/.babelrc b/.babelrc
index ac95979..6570dbf 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,10 +1,10 @@
{
"presets": [
- [
- "es2015",
- {
+ ["latest", {
+ "es2015": {
"modules": false
}
- ]
- ]
-}
+ }]
+ ],
+ "plugins": ["external-helpers"]
+}
\ No newline at end of file
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..c066e75
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,33 @@
+{
+ "env": {
+ "browser": true,
+ "es6": true
+ },
+ "extends": "eslint:recommended",
+ "parserOptions": {
+ "sourceType": "module"
+ },
+ "rules": {
+ "indent": [
+ "error",
+ "tab"
+ ],
+ "linebreak-style": [
+ "error",
+ "unix"
+ ],
+ "semi": [
+ "error",
+ "always"
+ ],
+ "no-console": [
+ "error",
+ {
+ "allow": ["warn", "error"]
+ }
+ ]
+ },
+ "globals": {
+ "ENV": true
+ }
+}
\ No newline at end of file
diff --git a/dist/frappe-charts.min.js b/dist/frappe-charts.min.js
index c91504c..de860e4 100644
--- a/dist/frappe-charts.min.js
+++ b/dist/frappe-charts.min.js
@@ -1,35 +1,546 @@
-(function () {
+var Chart = (function () {
'use strict';
-let frappe = {chart:{}, chart_types:['line', 'bar', 'percentage', 'heatmap']};
+var asyncGenerator = function () {
+ function AwaitValue(value) {
+ this.value = value;
+ }
-frappe.chart.FrappeChart = class {
- constructor({
- parent = "",
- height = 240,
+ function AsyncGenerator(gen) {
+ var front, back;
- title = '', subtitle = '',
+ function send(key, arg) {
+ return new Promise(function (resolve, reject) {
+ var request = {
+ key: key,
+ arg: arg,
+ resolve: resolve,
+ reject: reject,
+ next: null
+ };
- data = {},
- format_lambdas = {},
+ if (back) {
+ back = back.next = request;
+ } else {
+ front = back = request;
+ resume(key, arg);
+ }
+ });
+ }
- summary = [],
+ function resume(key, arg) {
+ try {
+ var result = gen[key](arg);
+ var value = result.value;
- is_navigable = 0,
+ if (value instanceof AwaitValue) {
+ Promise.resolve(value.value).then(function (arg) {
+ resume("next", arg);
+ }, function (arg) {
+ resume("throw", arg);
+ });
+ } else {
+ settle(result.done ? "return" : "normal", result.value);
+ }
+ } catch (err) {
+ settle("throw", err);
+ }
+ }
- type = ''
- }) {
- if(Object.getPrototypeOf(this) === frappe.chart.FrappeChart.prototype) {
- if(type === 'line') {
- return new frappe.chart.LineChart(arguments[0]);
- } else if(type === 'bar') {
- return new frappe.chart.BarChart(arguments[0]);
- } else if(type === 'percentage') {
- return new frappe.chart.PercentageChart(arguments[0]);
- } else if(type === 'heatmap') {
- return new frappe.chart.HeatMap(arguments[0]);
+ function settle(type, value) {
+ switch (type) {
+ case "return":
+ front.resolve({
+ value: value,
+ done: true
+ });
+ break;
+
+ case "throw":
+ front.reject(value);
+ break;
+
+ default:
+ front.resolve({
+ value: value,
+ done: false
+ });
+ break;
+ }
+
+ front = front.next;
+
+ if (front) {
+ resume(front.key, front.arg);
+ } else {
+ back = null;
+ }
+ }
+
+ this._invoke = send;
+
+ if (typeof gen.return !== "function") {
+ this.return = undefined;
+ }
+ }
+
+ if (typeof Symbol === "function" && Symbol.asyncIterator) {
+ AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
+ return this;
+ };
+ }
+
+ AsyncGenerator.prototype.next = function (arg) {
+ return this._invoke("next", arg);
+ };
+
+ AsyncGenerator.prototype.throw = function (arg) {
+ return this._invoke("throw", arg);
+ };
+
+ AsyncGenerator.prototype.return = function (arg) {
+ return this._invoke("return", arg);
+ };
+
+ return {
+ wrap: function (fn) {
+ return function () {
+ return new AsyncGenerator(fn.apply(this, arguments));
+ };
+ },
+ await: function (value) {
+ return new AwaitValue(value);
+ }
+ };
+}();
+
+
+
+
+
+var classCallCheck = function (instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+};
+
+var createClass = function () {
+ function defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+
+ return function (Constructor, protoProps, staticProps) {
+ if (protoProps) defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) defineProperties(Constructor, staticProps);
+ return Constructor;
+ };
+}();
+
+
+
+
+
+
+
+var get = function get(object, property, receiver) {
+ if (object === null) object = Function.prototype;
+ var desc = Object.getOwnPropertyDescriptor(object, property);
+
+ if (desc === undefined) {
+ var parent = Object.getPrototypeOf(object);
+
+ if (parent === null) {
+ return undefined;
+ } else {
+ return get(parent, property, receiver);
+ }
+ } else if ("value" in desc) {
+ return desc.value;
+ } else {
+ var getter = desc.get;
+
+ if (getter === undefined) {
+ return undefined;
+ }
+
+ return getter.call(receiver);
+ }
+};
+
+var inherits = function (subClass, superClass) {
+ if (typeof superClass !== "function" && superClass !== null) {
+ throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
+ }
+
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
+ constructor: {
+ value: subClass,
+ enumerable: false,
+ writable: true,
+ configurable: true
+ }
+ });
+ if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
+};
+
+
+
+
+
+
+
+
+
+
+
+var possibleConstructorReturn = function (self, call) {
+ if (!self) {
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+ }
+
+ return call && (typeof call === "object" || typeof call === "function") ? call : self;
+};
+
+
+
+
+
+var slicedToArray = function () {
+ function sliceIterator(arr, i) {
+ var _arr = [];
+ var _n = true;
+ var _d = false;
+ var _e = undefined;
+
+ try {
+ for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
+ _arr.push(_s.value);
+
+ if (i && _arr.length === i) break;
+ }
+ } catch (err) {
+ _d = true;
+ _e = err;
+ } finally {
+ try {
+ if (!_n && _i["return"]) _i["return"]();
+ } finally {
+ if (_d) throw _e;
+ }
+ }
+
+ return _arr;
+ }
+
+ return function (arr, i) {
+ if (Array.isArray(arr)) {
+ return arr;
+ } else if (Symbol.iterator in Object(arr)) {
+ return sliceIterator(arr, i);
+ } else {
+ throw new TypeError("Invalid attempt to destructure non-iterable instance");
+ }
+ };
+}();
+
+
+
+
+
+
+
+
+
+
+
+
+
+var toConsumableArray = function (arr) {
+ if (Array.isArray(arr)) {
+ for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
+
+ return arr2;
+ } else {
+ return Array.from(arr);
+ }
+};
+
+function $(expr, con) {
+ return typeof expr === "string" ? (con || document).querySelector(expr) : expr || null;
+}
+
+$.findNodeIndex = function (node) {
+ var i = 0;
+ while (node.previousSibling) {
+ node = node.previousSibling;
+ i++;
+ }
+ return i;
+};
+
+$.create = function (tag, o) {
+ var element = document.createElement(tag);
+
+ for (var i in o) {
+ var val = o[i];
+
+ if (i === "inside") {
+ $(val).appendChild(element);
+ } else if (i === "around") {
+ var ref = $(val);
+ ref.parentNode.insertBefore(element, ref);
+ element.appendChild(ref);
+ } else if (i in element) {
+ element[i] = val;
+ } else {
+ element.setAttribute(i, val);
+ }
+ }
+
+ return element;
+};
+
+$.createSVG = function (tag, o) {
+ var element = document.createElementNS("http://www.w3.org/2000/svg", tag);
+
+ for (var i in o) {
+ var val = o[i];
+
+ if (i === "inside") {
+ $(val).appendChild(element);
+ } else if (i === "around") {
+ var ref = $(val);
+ ref.parentNode.insertBefore(element, ref);
+ element.appendChild(ref);
+ } else {
+ if (i === "className") {
+ i = "class";
+ }
+ if (i === "innerHTML") {
+ element['textContent'] = val;
} else {
- return new frappe.chart.LineChart(arguments[0]);
+ element.setAttribute(i, val);
+ }
+ }
+ }
+
+ return element;
+};
+
+$.runSVGAnimation = function (svg_container, elements) {
+ // let parent = elements[0][0]['unit'].parentNode;
+
+ var new_elements = [];
+ var anim_elements = [];
+
+ elements.map(function (element) {
+ var obj = element[0];
+ var parent = obj.unit.parentNode;
+ // let index = let findNodeIndex(obj.unit);
+
+ var anim_element = void 0,
+ new_element = void 0;
+
+ element[0] = obj.unit;
+
+ var _$$animateSVG = $.animateSVG.apply($, toConsumableArray(element));
+
+ var _$$animateSVG2 = slicedToArray(_$$animateSVG, 2);
+
+ anim_element = _$$animateSVG2[0];
+ new_element = _$$animateSVG2[1];
+
+
+ new_elements.push(new_element);
+ anim_elements.push([anim_element, parent]);
+
+ parent.replaceChild(anim_element, obj.unit);
+
+ if (obj.array) {
+ obj.array[obj.index] = new_element;
+ } else {
+ obj.object[obj.key] = new_element;
+ }
+ });
+
+ var anim_svg = svg_container.cloneNode(true);
+
+ anim_elements.map(function (anim_element, i) {
+ anim_element[1].replaceChild(new_elements[i], anim_element[0]);
+ elements[i][0] = new_elements[i];
+ });
+
+ return anim_svg;
+};
+
+$.animateSVG = function (element, props, dur) {
+ var easing_type = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "linear";
+ var type = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
+ var old_values = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
+
+ var easing = {
+ ease: "0.25 0.1 0.25 1",
+ linear: "0 0 1 1",
+ // easein: "0.42 0 1 1",
+ easein: "0.1 0.8 0.2 1",
+ easeout: "0 0 0.58 1",
+ easeinout: "0.42 0 0.58 1"
+ };
+
+ var anim_element = element.cloneNode(true);
+ var new_element = element.cloneNode(true);
+
+ for (var attributeName in props) {
+ var animate_element = void 0;
+ if (attributeName === 'transform') {
+ animate_element = document.createElementNS("http://www.w3.org/2000/svg", "animateTransform");
+ } else {
+ animate_element = document.createElementNS("http://www.w3.org/2000/svg", "animate");
+ }
+ var current_value = old_values[attributeName] || element.getAttribute(attributeName);
+ var value = props[attributeName];
+
+ var anim_attr = {
+ attributeName: attributeName,
+ from: current_value,
+ to: value,
+ begin: "0s",
+ dur: dur / 1000 + "s",
+ values: current_value + ";" + value,
+ keySplines: easing[easing_type],
+ keyTimes: "0;1",
+ calcMode: "spline",
+ fill: 'freeze'
+ };
+
+ if (type) {
+ anim_attr["type"] = type;
+ }
+
+ for (var i in anim_attr) {
+ animate_element.setAttribute(i, anim_attr[i]);
+ }
+
+ anim_element.appendChild(animate_element);
+
+ if (type) {
+ new_element.setAttribute(attributeName, "translate(" + value + ")");
+ } else {
+ new_element.setAttribute(attributeName, value);
+ }
+ }
+
+ return [anim_element, new_element];
+};
+
+$.offset = function (element) {
+ var rect = element.getBoundingClientRect();
+ return {
+ // https://stackoverflow.com/a/7436602/6495043
+ // rect.top varies with scroll, so we add whatever has been
+ // scrolled to it to get absolute distance from actual page top
+ top: rect.top + (document.documentElement.scrollTop || document.body.scrollTop),
+ left: rect.left + (document.documentElement.scrollLeft || document.body.scrollLeft)
+ };
+};
+
+$.isElementInViewport = function (el) {
+ // Although straightforward: https://stackoverflow.com/a/7557433/6495043
+ var rect = el.getBoundingClientRect();
+
+ return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
+ rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
+ ;
+};
+
+$.bind = function (element, o) {
+ if (element) {
+ for (var event in o) {
+ var callback = o[event];
+
+ event.split(/\s+/).forEach(function (event) {
+ element.addEventListener(event, callback);
+ });
+ }
+ }
+};
+
+$.unbind = function (element, o) {
+ if (element) {
+ for (var event in o) {
+ var callback = o[event];
+
+ event.split(/\s+/).forEach(function (event) {
+ element.removeEventListener(event, callback);
+ });
+ }
+ }
+};
+
+$.fire = function (target, type, properties) {
+ var evt = document.createEvent("HTMLEvents");
+
+ evt.initEvent(type, true, true);
+
+ for (var j in properties) {
+ evt[j] = properties[j];
+ }
+
+ return target.dispatchEvent(evt);
+};
+
+function float_2(d) {
+ return parseFloat(d.toFixed(2));
+}
+
+function arrays_equal(arr1, arr2) {
+ if (arr1.length !== arr2.length) return false;
+ var are_equal = true;
+ arr1.map(function (d, i) {
+ if (arr2[i] !== d) are_equal = false;
+ });
+ return are_equal;
+}
+
+var Chart = function () {
+ function Chart(_ref) {
+ var _ref$parent = _ref.parent,
+ parent = _ref$parent === undefined ? "" : _ref$parent,
+ _ref$height = _ref.height,
+ height = _ref$height === undefined ? 240 : _ref$height,
+ _ref$title = _ref.title,
+ title = _ref$title === undefined ? '' : _ref$title,
+ _ref$subtitle = _ref.subtitle,
+ subtitle = _ref$subtitle === undefined ? '' : _ref$subtitle,
+ _ref$data = _ref.data,
+ data = _ref$data === undefined ? {} : _ref$data,
+ _ref$format_lambdas = _ref.format_lambdas,
+ format_lambdas = _ref$format_lambdas === undefined ? {} : _ref$format_lambdas,
+ _ref$summary = _ref.summary,
+ summary = _ref$summary === undefined ? [] : _ref$summary,
+ _ref$is_navigable = _ref.is_navigable,
+ is_navigable = _ref$is_navigable === undefined ? 0 : _ref$is_navigable,
+ _ref$type = _ref.type,
+ type = _ref$type === undefined ? '' : _ref$type;
+ classCallCheck(this, Chart);
+
+ if (Object.getPrototypeOf(this) === Chart.prototype) {
+ if (type === 'line') {
+ return new LineChart(arguments[0]);
+ } else if (type === 'bar') {
+ return new BarChart(arguments[0]);
+ } else if (type === 'percentage') {
+ return new PercentageChart(arguments[0]);
+ } else if (type === 'heatmap') {
+ return new HeatMap(arguments[0]);
+ } else {
+ return new LineChart(arguments[0]);
}
}
@@ -46,1840 +557,2095 @@ frappe.chart.FrappeChart = class {
this.summary = summary;
this.is_navigable = is_navigable;
- if(this.is_navigable) {
+ if (this.is_navigable) {
this.current_index = 0;
}
- $$.createSVG('svg', {
- className: 'chart',
- inside: parent,
- width: 1000,
- height: height
- });
+ this.chart_types = ['line', 'bar', 'percentage', 'heatmap'];
this.set_margins(height);
}
- get_different_chart(type) {
- if(!frappe.chart_types.includes(type)) {
- console.error(`'${type}' is not a valid chart type.`);
- }
- if(type === this.type) return;
-
- // Only across compatible types
- let compatible_types = {
- bar: ['line', 'percentage'],
- line: ['bar', 'percentage'],
- percentage: ['bar', 'line'],
- heatmap: []
- };
-
- if(!compatible_types[this.type].includes(type)) {
- console.error(`'${this.type}' chart cannot be converted to a '${type}' chart.`);
- }
-
- // Okay, this is anticlimactic
- // this function will need to be 'change_chart_type(type)'
- // that will update only the required elements, but for now ...
- return new frappe.chart.FrappeChart({
- parent: this.raw_chart_args.parent,
- data: this.raw_chart_args.data,
- type: type,
- height: this.raw_chart_args.height
- });
- }
-
- set_margins(height) {
- this.base_height = height;
- this.height = height - 40;
- this.translate_x = 60;
- this.translate_y = 10;
- }
-
- setup() {
- this.bind_window_events();
- this.refresh(true);
- }
-
- bind_window_events() {
- window.addEventListener('resize', () => this.refresh());
- window.addEventListener('orientationchange', () => this.refresh());
- }
-
- refresh(init=false) {
- this.setup_base_values();
- this.set_width();
-
- this.setup_container();
- this.setup_components();
-
- this.setup_values();
- this.setup_utils();
-
- this.make_graph_components(init);
- this.make_tooltip();
-
- if(this.summary.length > 0) {
- this.show_custom_summary();
- } else {
- this.show_summary();
- }
-
- if(this.is_navigable) {
- this.setup_navigation(init);
- }
- }
-
- set_width() {
- let special_values_width = 0;
- this.specific_values.map(val => {
- if(this.get_strwidth(val.title) > special_values_width) {
- special_values_width = this.get_strwidth(val.title) - 40;
+ createClass(Chart, [{
+ key: 'get_different_chart',
+ value: function get_different_chart(type) {
+ if (!this.chart_types.includes(type)) {
+ console.error('\'' + type + '\' is not a valid chart type.');
}
- });
- this.base_width = this.parent.offsetWidth - special_values_width;
- this.width = this.base_width - this.translate_x * 2;
- }
+ if (type === this.type) return;
- setup_base_values() {}
+ // Only across compatible types
+ var compatible_types = {
+ bar: ['line', 'percentage'],
+ line: ['bar', 'percentage'],
+ percentage: ['bar', 'line'],
+ heatmap: []
+ };
- setup_container() {
- this.container = $$.create('div', {
- className: 'chart-container',
- innerHTML: `
${this.title}
- ${this.subtitle}
-
- `
- });
+ if (!compatible_types[this.type].includes(type)) {
+ console.error('\'' + this.type + '\' chart cannot be converted to a \'' + type + '\' chart.');
+ }
- // Chart needs a dedicated parent element
- this.parent.innerHTML = '';
- this.parent.appendChild(this.container);
-
- this.chart_wrapper = this.container.querySelector('.frappe-chart');
- this.stats_wrapper = this.container.querySelector('.graph-stats-container');
-
- this.make_chart_area();
- this.make_draw_area();
- }
-
- make_chart_area() {
- this.svg = $$.createSVG('svg', {
- className: 'chart',
- inside: this.chart_wrapper,
- width: this.base_width,
- height: this.base_height
- });
-
- this.svg_defs = $$.createSVG('defs', {
- inside: this.svg,
- });
-
- return this.svg;
- }
-
- make_draw_area() {
- this.draw_area = $$.createSVG("g", {
- className: this.type + '-chart',
- inside: this.svg,
- transform: `translate(${this.translate_x}, ${this.translate_y})`
- });
- }
-
- setup_components() { }
-
- make_tooltip() {
- this.tip = new frappe.chart.SvgTip({
- parent: this.chart_wrapper,
- });
- this.bind_tooltip();
- }
-
-
- show_summary() {}
- show_custom_summary() {
- this.summary.map(d => {
- let stats = $$.create('div', {
- className: 'stats',
- innerHTML: `${d.title}: ${d.value}`
- });
- this.stats_wrapper.appendChild(stats);
- });
- }
-
- setup_navigation(init=false) {
- this.make_overlay();
-
- if(init) {
- this.bind_overlay();
-
- document.addEventListener('keydown', (e) => {
- if($$.isElementInViewport(this.chart_wrapper)) {
- e = e || window.event;
-
- if (e.keyCode == '37') {
- this.on_left_arrow();
- } else if (e.keyCode == '39') {
- this.on_right_arrow();
- } else if (e.keyCode == '38') {
- this.on_up_arrow();
- } else if (e.keyCode == '40') {
- this.on_down_arrow();
- } else if (e.keyCode == '13') {
- this.on_enter_key();
- }
- }
+ // Okay, this is anticlimactic
+ // this function will need to actually be 'change_chart_type(type)'
+ // that will update only the required elements, but for now ...
+ return new Chart({
+ parent: this.raw_chart_args.parent,
+ data: this.raw_chart_args.data,
+ type: type,
+ height: this.raw_chart_args.height
});
}
- }
-
- make_overlay() {}
- bind_overlay() {}
-
- on_left_arrow() {}
- on_right_arrow() {}
- on_up_arrow() {}
- on_down_arrow() {}
- on_enter_key() {}
-
- get_data_point(index=this.current_index) {
- // check for length
- let data_point = {
- index: index
- };
- let y = this.y[0];
- ['svg_units', 'y_tops', 'values'].map(key => {
- let data_key = key.slice(0, key.length-1);
- data_point[data_key] = y[key][index];
- });
- data_point.label = this.x[index];
- return data_point;
- }
-
- update_current_data_point(index) {
- if(index < 0) index = 0;
- if(index >= this.x.length) index = this.x.length - 1;
- if(index === this.current_index) return;
- this.current_index = index;
- $$.fire(this.parent, "data-select", this.get_data_point());
- }
-
- // Helpers
- get_strwidth(string) {
- return string.length * 8;
- }
-
- // Objects
- setup_utils() { }
-};
-
-frappe.chart.AxisChart = class AxisChart extends frappe.chart.FrappeChart {
- constructor(args) {
- super(args);
-
- this.x = this.data.labels;
- this.y = this.data.datasets;
-
- this.get_y_label = this.format_lambdas.y_label;
- this.get_y_tooltip = this.format_lambdas.y_tooltip;
- this.get_x_tooltip = this.format_lambdas.x_tooltip;
-
- this.colors = ['green', 'blue', 'violet', 'red', 'orange',
- 'yellow', 'light-blue', 'light-green', 'purple', 'magenta'];
-
- this.zero_line = this.height;
- }
-
- setup_values() {
- this.data.datasets.map(d => {
- d.values = d.values.map(val => (!isNaN(val) ? val : 0));
- });
- this.setup_x();
- this.setup_y();
- }
-
- setup_x() {
- this.set_avg_unit_width_and_x_offset();
-
- if(this.x_axis_positions) {
- this.x_old_axis_positions = this.x_axis_positions.slice();
+ }, {
+ key: 'set_margins',
+ value: function set_margins(height) {
+ this.base_height = height;
+ this.height = height - 40;
+ this.translate_x = 60;
+ this.translate_y = 10;
}
- this.x_axis_positions = this.x.map((d, i) =>
- $$.float_2(this.x_offset + i * this.avg_unit_width));
-
- if(!this.x_old_axis_positions) {
- this.x_old_axis_positions = this.x_axis_positions.slice();
+ }, {
+ key: 'setup',
+ value: function setup() {
+ this.bind_window_events();
+ this.refresh(true);
}
- }
+ }, {
+ key: 'bind_window_events',
+ value: function bind_window_events() {
+ var _this = this;
- setup_y() {
- if(this.y_axis_values) {
- this.y_old_axis_values = this.y_axis_values.slice();
- }
-
- let values = this.get_all_y_values();
-
- if(this.y_sums && this.y_sums.length > 0) {
- values = values.concat(this.y_sums);
- }
-
- this.y_axis_values = this.get_y_axis_points(values);
-
- if(!this.y_old_axis_values) {
- this.y_old_axis_values = this.y_axis_values.slice();
- }
-
- const y_pts = this.y_axis_values;
- const value_range = y_pts[y_pts.length-1] - y_pts[0];
-
- if(this.multiplier) this.old_multiplier = this.multiplier;
- this.multiplier = this.height / value_range;
- if(!this.old_multiplier) this.old_multiplier = this.multiplier;
-
- const zero_index = y_pts.indexOf(0);
- const interval = y_pts[1] - y_pts[0];
- const interval_height = interval * this.multiplier;
-
- if(this.zero_line) this.old_zero_line = this.zero_line;
- this.zero_line = this.height - (zero_index * interval_height);
- if(!this.old_zero_line) this.old_zero_line = this.zero_line;
- }
-
- setup_components() {
- super.setup_components();
- this.setup_marker_components();
- this.setup_aggregation_components();
- this.setup_graph_components();
- }
-
- setup_marker_components() {
- this.y_axis_group = $$.createSVG('g', {className: 'y axis', inside: this.draw_area});
- this.x_axis_group = $$.createSVG('g', {className: 'x axis', inside: this.draw_area});
- this.specific_y_group = $$.createSVG('g', {className: 'specific axis', inside: this.draw_area});
- }
-
- setup_aggregation_components() {
- this.sum_group = $$.createSVG('g', {className: 'data-points', inside: this.draw_area});
- this.average_group = $$.createSVG('g', {className: 'chart-area', inside: this.draw_area});
- }
-
- setup_graph_components() {
- this.svg_units_groups = [];
- this.y.map((d, i) => {
- this.svg_units_groups[i] = $$.createSVG('g', {
- className: 'data-points data-points-' + i,
- inside: this.draw_area
+ window.addEventListener('resize', function () {
+ return _this.refresh();
+ });
+ window.addEventListener('orientationchange', function () {
+ return _this.refresh();
});
- });
- }
-
- make_graph_components(init=false) {
- this.make_y_axis();
- this.make_x_axis();
- this.draw_graph(init);
- this.make_y_specifics();
- }
-
- // make VERTICAL lines for x values
- make_x_axis(animate=false) {
- let start_at, height, text_start_at, axis_line_class = '';
- if(this.x_axis_mode === 'span') { // long spanning lines
- start_at = -7;
- height = this.height + 15;
- text_start_at = this.height + 25;
- } else if(this.x_axis_mode === 'tick'){ // short label lines
- start_at = this.height;
- height = 6;
- text_start_at = 9;
- axis_line_class = 'x-axis-label';
}
+ }, {
+ key: 'refresh',
+ value: function refresh() {
+ var init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
- this.x_axis_group.setAttribute('transform', `translate(0,${start_at})`);
+ this.setup_base_values();
+ this.set_width();
- if(animate) {
- this.make_anim_x_axis(height, text_start_at, axis_line_class);
- return;
- }
+ this.setup_container();
+ this.setup_components();
- this.x_axis_group.textContent = '';
- this.x.map((point, i) => {
- this.x_axis_group.appendChild(
- this.make_x_line(
- height,
- text_start_at,
- point,
- 'x-value-text',
- axis_line_class,
- this.x_axis_positions[i]
- )
- );
- });
- }
+ this.setup_values();
+ this.setup_utils();
- // make HORIZONTAL lines for y values
- make_y_axis(animate=false) {
- if(animate) {
- this.make_anim_y_axis();
- this.make_anim_y_specifics();
- return;
- }
+ this.make_graph_components(init);
+ this.make_tooltip();
- let [width, text_end_at, axis_line_class, start_at] = this.get_y_axis_line_props();
-
- this.y_axis_group.textContent = '';
- this.y_axis_values.map((value, i) => {
- this.y_axis_group.appendChild(
- this.make_y_line(
- start_at,
- width,
- text_end_at,
- value,
- 'y-value-text',
- axis_line_class,
- this.zero_line - value * this.multiplier,
- (value === 0 && i !== 0) // Non-first Zero line
- )
- );
- });
- }
-
- get_y_axis_line_props(specific=false) {
- if(specific) {
- return[this.width, this.width + 5, 'specific-value', 0];
- }
- let width, text_end_at = -9, axis_line_class = '', start_at = 0;
- if(this.y_axis_mode === 'span') { // long spanning lines
- width = this.width + 6;
- start_at = -6;
- } else if(this.y_axis_mode === 'tick'){ // short label lines
- width = -6;
- axis_line_class = 'y-axis-label';
- }
-
- return [width, text_end_at, axis_line_class, start_at];
- }
-
- draw_graph(init=false) {
- if(init) {
- this.draw_new_graph_and_animate();
- return;
- }
- this.y.map((d, i) => {
- d.svg_units = [];
- this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, d.color || this.colors[i]);
- this.make_new_units(d, i);
- });
- }
-
- draw_new_graph_and_animate() {
- let data = [];
- this.y.map((d, i) => {
- // Anim: Don't draw initial values, store them and update later
- d.y_tops = new Array(d.values.length).fill(this.zero_line); // no value
- data.push({values: d.values});
- d.svg_units = [];
-
- this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, d.color || this.colors[i]);
- this.make_new_units(d, i);
- });
-
- setTimeout(() => {
- this.update_values(data);
- }, 350);
- }
-
- setup_navigation(init) {
- // Hack: defer nav till initial update_values
- setTimeout(() => {
- super.setup_navigation(init);
- }, 500);
- }
-
- make_new_units(d, i) {
- this.make_new_units_for_dataset(
- this.x_axis_positions,
- d.y_tops,
- d.color || this.colors[i],
- i,
- this.y.length
- );
- }
-
- make_new_units_for_dataset(x_values, y_values, color, dataset_index, no_of_datasets, group, array, unit) {
- if(!group) group = this.svg_units_groups[dataset_index];
- if(!array) array = this.y[dataset_index].svg_units;
- if(!unit) unit = this.unit_args;
-
- group.textContent = '';
- array.length = 0;
-
- y_values.map((y, i) => {
- let data_unit = this.draw[unit.type](
- x_values[i],
- y,
- unit.args,
- color,
- dataset_index,
- no_of_datasets
- );
- group.appendChild(data_unit);
- array.push(data_unit);
- });
- }
-
- make_y_specifics() {
- this.specific_y_group.textContent = '';
- this.specific_values.map(d => {
- this.specific_y_group.appendChild(
- this.make_y_line(
- 0,
- this.width,
- this.width + 5,
- d.title.toUpperCase(),
- 'specific-value',
- 'specific-value',
- this.zero_line - d.value * this.multiplier,
- false,
- d.line_type
- )
- );
- });
- }
-
- bind_tooltip() {
- // TODO: could be in tooltip itself, as it is a given functionality for its parent
- this.chart_wrapper.addEventListener('mousemove', (e) => {
- let offset = $$.offset(this.chart_wrapper);
- let relX = e.pageX - offset.left - this.translate_x;
- let relY = e.pageY - offset.top - this.translate_y;
-
- if(relY < this.height + this.translate_y * 2) {
- this.map_tooltip_x_position_and_show(relX);
+ if (this.summary.length > 0) {
+ this.show_custom_summary();
} else {
- this.tip.hide_tip();
- }
- });
- }
-
- map_tooltip_x_position_and_show(relX) {
- for(var i=this.x_axis_positions.length - 1; i >= 0 ; i--) {
- let x_val = this.x_axis_positions[i];
- // let delta = i === 0 ? this.avg_unit_width : x_val - this.x_axis_positions[i-1];
- if(relX > x_val - this.avg_unit_width/2) {
- let x = x_val + this.translate_x;
- let y = this.y_min_tops[i] + this.translate_y;
-
- let title = this.x.formatted && this.x.formatted.length>0
- ? this.x.formatted[i] : this.x[i];
- let values = this.y.map((set, j) => {
- return {
- title: set.title,
- value: set.formatted ? set.formatted[i] : set.values[i],
- color: set.color || this.colors[j],
- }
- });
-
- // TODO: upside-down tooltips for negative values?
- this.tip.set_values(x, y, title, '', values);
- this.tip.show_tip();
- break;
- }
- }
- }
-
- // API
- show_sums() {
- this.updating = true;
-
- this.y_sums = new Array(this.x_axis_positions.length).fill(0);
- this.y.map(d => {
- d.values.map( (value, i) => {
- this.y_sums[i] += value;
- });
- });
-
- // Remake y axis, animate
- this.update_values();
-
- // Then make sum units, don't animate
- this.sum_units = [];
-
- this.make_new_units_for_dataset(
- this.x_axis_positions,
- this.y_sums.map( val => $$.float_2(this.zero_line - val * this.multiplier)),
- 'light-grey',
- 0,
- 1,
- this.sum_group,
- this.sum_units
- );
-
- // this.make_path && this.make_path(d, i, old_x, old_y, d.color || this.colors[i]);
-
- this.updating = false;
- }
-
- hide_sums() {
- if(this.updating) return;
- this.y_sums = [];
- this.sum_group.textContent = '';
- this.sum_units = [];
- this.update_values();
- }
-
- show_average() {
- this.old_specific_values = this.specific_values.slice();
- this.y.map((d, i) => {
- let sum = 0;
- d.values.map(e => {sum+=e;});
- let average = sum/d.values.length;
-
- this.specific_values.push({
- title: "AVG" + " " + (i+1),
- line_type: "dashed",
- value: average,
- auto: 1
- });
- });
-
- console.log(this.specific_values);
-
- this.update_values();
- }
-
- hide_average() {
- this.old_specific_values = this.specific_values.slice();
-
- let indices_to_remove = [];
- this.specific_values.map((d, i) => {
- if(d.auto) indices_to_remove.unshift(i);
- });
-
- console.log(indices_to_remove);
-
- indices_to_remove.map(index => {
- this.specific_values.splice(index, 1);
- });
-
- console.log(this.specific_values);
-
- this.update_values();
- }
-
- update_values(new_y, new_x) {
- if(!new_x) {
- new_x = this.x;
- }
- this.elements_to_animate = [];
- this.updating = true;
-
- this.old_x_values = this.x.slice();
- this.old_y_axis_tops = this.y.map(d => d.y_tops.slice());
-
- this.old_y_values = this.y.map(d => d.values);
-
- this.no_of_extra_pts = new_x.length - this.x.length;
-
- // Just update values prop, setup_x/y() will do the rest
- if(new_y) this.y.map((d, i) => {d.values = new_y[i].values;});
- if(new_x) this.x = new_x;
-
- this.setup_x();
- this.setup_y();
-
- // Animate only if positions have changed
- if(!$$.arrays_equal(this.x_old_axis_positions, this.x_axis_positions)) {
- this.make_x_axis(true);
- setTimeout(() => {
- if(!this.updating) this.make_x_axis();
- }, 300);
- }
-
- if(!$$.arrays_equal(this.y_old_axis_values, this.y_axis_values) ||
- (this.old_specific_values &&
- !$$.arrays_equal(this.old_specific_values, this.specific_values))) {
-
- this.make_y_axis(true);
- setTimeout(() => {
- if(!this.updating) {
- this.make_y_axis();
- this.make_y_specifics();
- }
- }, 300);
- }
-
- // Change in data, so calculate dependencies
- this.calc_y_dependencies();
-
- this.animate_graphs();
-
- // Trigger animation with the animatable elements in this.elements_to_animate
- this.run_animation();
-
- this.updating = false;
- }
-
- add_data_point(y_point, x_point, index=this.x.length) {
- let new_y = this.y.map(data_set => { return {values:data_set.values}; });
- new_y.map((d, i) => { d.values.splice(index, 0, y_point[i]); });
- let new_x = this.x.slice();
- new_x.splice(index, 0, x_point);
-
- this.update_values(new_y, new_x);
- }
-
- remove_data_point(index = this.x.length-1) {
- if(this.x.length < 3) return;
-
- let new_y = this.y.map(data_set => { return {values:data_set.values}; });
- new_y.map((d, i) => { d.values.splice(index, 1); });
- let new_x = this.x.slice();
- new_x.splice(index, 1);
-
- this.update_values(new_y, new_x);
- }
-
- run_animation() {
- let anim_svg = $$.runSVGAnimation(this.svg, this.elements_to_animate);
-
- if(this.svg.parentNode == this.chart_wrapper) {
- this.chart_wrapper.removeChild(this.svg);
- this.chart_wrapper.appendChild(anim_svg);
-
- }
-
- // Replace the new svg (data has long been replaced)
- setTimeout(() => {
- if(anim_svg.parentNode == this.chart_wrapper) {
- this.chart_wrapper.removeChild(anim_svg);
- this.chart_wrapper.appendChild(this.svg);
- }
- }, 200);
- }
-
- animate_graphs() {
- this.y.map((d, i) => {
- // Pre-prep, equilize no of positions between old and new
- let [old_x, old_y, new_x, new_y] = this.calc_old_and_new_postions(d, i);
- if(this.no_of_extra_pts >= 0) {
- this.make_path && this.make_path(d, i, old_x, old_y, d.color || this.colors[i]);
- this.make_new_units_for_dataset(old_x, old_y, d.color || this.colors[i], i, this.y.length);
- }
- d.path && this.animate_path(d, i, old_x, old_y, new_x, new_y);
- this.animate_units(d, i, old_x, old_y, new_x, new_y);
- });
-
- // TODO: replace with real units
- setTimeout(() => {
- this.y.map((d, i) => {
- this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, d.color || this.colors[i]);
- this.make_new_units(d, i);
- });
- }, 300);
- }
-
- animate_path(d, i, old_x, old_y, new_x, new_y) {
- // Animate path
- const new_points_list = new_y.map((y, i) => (new_x[i] + ',' + y));
- const new_path_str = new_points_list.join("L");
-
- const path_args = [{unit: d.path, object: d, key: 'path'}, {d:"M"+new_path_str}, 250, "easein"];
- this.elements_to_animate.push(path_args);
-
- // Animate region
- if(d.region_path) {
- let reg_start_pt = `0,${this.zero_line}L`;
- let reg_end_pt = `L${this.width},${this.zero_line}`;
-
- const region_args = [
- {unit: d.region_path, object: d, key: 'region_path'},
- {d:"M" + reg_start_pt + new_path_str + reg_end_pt},
- 250,
- "easein"
- ];
- this.elements_to_animate.push(region_args);
- }
- }
-
- animate_units(d, index, old_x, old_y, new_x, new_y) {
- let type = this.unit_args.type;
-
- d.svg_units.map((unit, i) => {
- this.elements_to_animate.push(this.animate[type](
- {unit:unit, array:d.svg_units, index: i}, // unit, with info to replace where it came from in the data
- new_x[i],
- new_y[i],
- index
- ));
- });
- }
-
- calc_old_and_new_postions(d, i) {
- let old_x = this.x_old_axis_positions.slice();
- let new_x = this.x_axis_positions.slice();
-
- let old_y = this.old_y_axis_tops[i].slice();
- let new_y = d.y_tops.slice();
-
- const last_old_x_pos = old_x[old_x.length - 1];
- const last_old_y_pos = old_y[old_y.length - 1];
-
- const last_new_x_pos = new_x[new_x.length - 1];
- const last_new_y_pos = new_y[new_y.length - 1];
-
- if(this.no_of_extra_pts >= 0) {
- // First substitute current path with a squiggled one (looking the same but
- // having more points at end),
- // then animate to stretch it later to new points
- // (new points already have more points)
-
- // Hence, the extra end points will correspond to current(old) positions
- let filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_old_x_pos);
- let filler_y = new Array(Math.abs(this.no_of_extra_pts)).fill(last_old_y_pos);
-
- old_x = old_x.concat(filler_x);
- old_y = old_y.concat(filler_y);
-
- } else {
- // Just modify the new points to have extra points
- // with the same position at end
- let filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_new_x_pos);
- let filler_y = new Array(Math.abs(this.no_of_extra_pts)).fill(last_new_y_pos);
-
- new_x = new_x.concat(filler_x);
- new_y = new_y.concat(filler_y);
- }
-
- return [old_x, old_y, new_x, new_y];
- }
-
- make_anim_x_axis(height, text_start_at, axis_line_class) {
- // Animate X AXIS to account for more or less axis lines
-
- const old_pos = this.x_old_axis_positions;
- const new_pos = this.x_axis_positions;
-
- const old_vals = this.old_x_values;
- const new_vals = this.x;
-
- const last_line_pos = old_pos[old_pos.length - 1];
-
- let add_and_animate_line = (value, old_pos, new_pos, i) => {
- const x_line = this.make_x_line(
- height,
- text_start_at,
- value, // new value
- 'x-value-text',
- axis_line_class,
- old_pos // old position
- );
- this.x_axis_group.appendChild(x_line);
-
- this.elements_to_animate && this.elements_to_animate.push([
- {unit: x_line, array: [0], index: 0},
- {transform: `${ new_pos }, 0`},
- 250,
- "easein",
- "translate",
- {transform: `${ old_pos }, 0`}
- ]);
- };
-
- this.x_axis_group.textContent = '';
-
- this.make_new_axis_anim_lines(
- old_pos,
- new_pos,
- old_vals,
- new_vals,
- last_line_pos,
- add_and_animate_line
- );
- }
-
- make_anim_y_axis() {
- // Animate Y AXIS to account for more or less axis lines
-
- const old_pos = this.y_old_axis_values.map(value =>
- this.zero_line - value * this.multiplier);
- const new_pos = this.y_axis_values.map(value =>
- this.zero_line - value * this.multiplier);
-
- const old_vals = this.y_old_axis_values;
- const new_vals = this.y_axis_values;
-
- const last_line_pos = old_pos[old_pos.length - 1];
-
- this.y_axis_group.textContent = '';
-
- this.make_new_axis_anim_lines(
- old_pos,
- new_pos,
- old_vals,
- new_vals,
- last_line_pos,
- this.add_and_animate_y_line.bind(this),
- this.y_axis_group
- );
- }
-
- make_anim_y_specifics() {
- this.specific_y_group.textContent = '';
- this.specific_values.map((d, i) => {
- this.add_and_animate_y_line(
- d.title,
- this.old_zero_line - d.value * this.old_multiplier,
- this.zero_line - d.value * this.multiplier,
- 0,
- this.specific_y_group,
- d.line_type,
- true
- );
- });
- }
-
- make_new_axis_anim_lines(old_pos, new_pos, old_vals, new_vals, last_line_pos, add_and_animate_line, group) {
- let superimposed_positions, superimposed_values;
- let no_of_extras = new_vals.length - old_vals.length;
- if(no_of_extras > 0) {
- // More axis are needed
- // First make only the superimposed (same position) ones
- // Add in the extras at the end later
- superimposed_positions = new_pos.slice(0, old_pos.length);
- superimposed_values = new_vals.slice(0, old_vals.length);
- } else {
- // Axis have to be reduced
- // Fake it by moving all current extra axis to the last position
- // You'll need filler positions and values in the new arrays
- const filler_vals = new Array(Math.abs(no_of_extras)).fill("");
- superimposed_values = new_vals.concat(filler_vals);
-
- const filler_pos = new Array(Math.abs(no_of_extras)).fill(last_line_pos);
- superimposed_positions = new_pos.concat(filler_pos);
- }
-
- superimposed_values.map((value, i) => {
- add_and_animate_line(value, old_pos[i], superimposed_positions[i], i, group);
- });
-
- if(no_of_extras > 0) {
- // Add in extra axis in the end
- // and then animate to new positions
- const extra_values = new_vals.slice(old_vals.length);
- const extra_positions = new_pos.slice(old_pos.length);
-
- extra_values.map((value, i) => {
- add_and_animate_line(value, last_line_pos, extra_positions[i], i, group);
- });
- }
- }
-
- make_x_line(height, text_start_at, point, label_class, axis_line_class, x_pos) {
- let allowed_space = this.avg_unit_width * 1.5;
-
- if(this.get_strwidth(point) > allowed_space) {
- let allowed_letters = allowed_space / 8;
- point = point.slice(0, allowed_letters-3) + " ...";
- }
-
- let line = $$.createSVG('line', {
- x1: 0,
- x2: 0,
- y1: 0,
- y2: height
- });
-
- let text = $$.createSVG('text', {
- className: label_class,
- x: 0,
- y: text_start_at,
- dy: '.71em',
- innerHTML: point
- });
-
- let x_level = $$.createSVG('g', {
- className: `tick ${axis_line_class}`,
- transform: `translate(${ x_pos }, 0)`
- });
-
- x_level.appendChild(line);
- x_level.appendChild(text);
-
- return x_level;
- }
-
- make_y_line(start_at, width, text_end_at, point, label_class, axis_line_class, y_pos, darker=false, line_type="") {
- let line = $$.createSVG('line', {
- className: line_type === "dashed" ? "dashed": "",
- x1: start_at,
- x2: width,
- y1: 0,
- y2: 0
- });
-
- let text = $$.createSVG('text', {
- className: label_class,
- x: text_end_at,
- y: 0,
- dy: '.32em',
- innerHTML: point+""
- });
-
- let y_level = $$.createSVG('g', {
- className: `tick ${axis_line_class}`,
- transform: `translate(0, ${y_pos})`
- });
-
- if(darker) {
- line.style.stroke = "rgba(27, 31, 35, 0.6)";
- }
-
- y_level.appendChild(line);
- y_level.appendChild(text);
-
- return y_level;
- }
-
- add_and_animate_y_line(value, old_pos, new_pos, i, group, type, specific=false) {
- let [width, text_end_at, axis_line_class, start_at] = this.get_y_axis_line_props(specific);
- let axis_label_class = !specific ? 'y-value-text' : 'specific-value';
- value = !specific ? value : (value+"").toUpperCase();
- const y_line = this.make_y_line(
- start_at,
- width,
- text_end_at,
- value,
- axis_label_class,
- axis_line_class,
- old_pos, // old position
- (value === 0 && i !== 0), // Non-first Zero line
- type
- );
-
- group.appendChild(y_line);
-
- this.elements_to_animate && this.elements_to_animate.push([
- {unit: y_line, array: [0], index: 0},
- {transform: `0, ${ new_pos }`},
- 250,
- "easein",
- "translate",
- {transform: `0, ${ old_pos }`}
- ]);
- }
-
- get_y_axis_points(array) {
- //*** Where the magic happens ***
-
- // Calculates best-fit y intervals from given values
- // and returns the interval array
-
- // TODO: Fractions
-
- let max_bound, min_bound, pos_no_of_parts, neg_no_of_parts, part_size;
-
- // Critical values
- let max_val = parseInt(Math.max(...array));
- let min_val = parseInt(Math.min(...array));
- if(min_val >= 0) {
- min_val = 0;
- }
-
- let get_params = (value1, value2) => {
- let bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size;
- if((value1+"").length <= 1) {
- [bound1, no_of_parts_1] = [10, 5];
- } else {
- [bound1, no_of_parts_1] = this.calc_upper_bound_and_no_of_parts(value1);
+ this.show_summary();
}
- interval_size = bound1 / no_of_parts_1;
- no_of_parts_2 = this.calc_no_of_parts(value2, interval_size);
- bound2 = no_of_parts_2 * interval_size;
-
- return [bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size];
- };
-
- const abs_min_val = min_val * -1;
- if(abs_min_val <= max_val) {
- // Get the positive region intervals
- // then calc negative ones accordingly
- [max_bound, min_bound, pos_no_of_parts, neg_no_of_parts, part_size]
- = get_params(max_val, abs_min_val);
- if(abs_min_val === 0) {
- min_bound = 0; neg_no_of_parts = 0;
+ if (this.is_navigable) {
+ this.setup_navigation(init);
}
- } else {
- // Get the negative region here first
- [min_bound, max_bound, neg_no_of_parts, pos_no_of_parts, part_size]
- = get_params(abs_min_val, max_val);
}
+ }, {
+ key: 'set_width',
+ value: function set_width() {
+ var _this2 = this;
- // Make both region parts even
- if(pos_no_of_parts % 2 !== 0 && neg_no_of_parts > 0) pos_no_of_parts++;
- if(neg_no_of_parts % 2 !== 0) {
- // every increase in no_of_parts entails an increase in corresponding bound
- // except here, it happens implicitly after every calc_no_of_parts() call
- neg_no_of_parts++;
- min_bound += part_size;
- }
-
- let no_of_parts = pos_no_of_parts + neg_no_of_parts;
- if(no_of_parts > 5) {
- no_of_parts /= 2;
- part_size *= 2;
- }
-
- return this.get_intervals(
- (-1) * min_bound,
- part_size,
- no_of_parts
- );
- }
-
- get_intervals(start, interval_size, count) {
- let intervals = [];
- for(var i = 0; i <= count; i++){
- intervals.push(start);
- start += interval_size;
- }
- return intervals;
- }
-
- calc_upper_bound_and_no_of_parts(max_val) {
- // Given a positive value, calculates a nice-number upper bound
- // and a consequent optimal number of parts
-
- const part_size = Math.pow(10, ((max_val+"").length - 1));
- const no_of_parts = this.calc_no_of_parts(max_val, part_size);
-
- // Use it to get a nice even upper bound
- const upper_bound = part_size * no_of_parts;
-
- return [upper_bound, no_of_parts];
- }
-
- calc_no_of_parts(value, divisor) {
- // value should be a positive number, divisor should be greater than 0
- // returns an even no of parts
- let no_of_parts = Math.ceil(value / divisor);
- if(no_of_parts % 2 !== 0) no_of_parts++; // Make it an even number
-
- return no_of_parts;
- }
-
- get_optimal_no_of_parts(no_of_parts) {
- // aka Divide by 2 if too large
- return (no_of_parts < 5) ? no_of_parts : no_of_parts / 2;
- }
-
- set_avg_unit_width_and_x_offset() {
- // Set the ... you get it
- this.avg_unit_width = this.width/(this.x.length - 1);
- this.x_offset = 0;
- }
-
- get_all_y_values() {
- let all_values = [];
-
- // Add in all the y values in the datasets
- this.y.map(d => {
- all_values = all_values.concat(d.values);
- });
-
- // Add in all the specific values
- return all_values.concat(this.specific_values.map(d => d.value));
- }
-
- calc_y_dependencies() {
- this.y_min_tops = new Array(this.x_axis_positions.length).fill(9999);
- this.y.map(d => {
- d.y_tops = d.values.map( val => $$.float_2(this.zero_line - val * this.multiplier));
- d.y_tops.map( (y_top, i) => {
- if(y_top < this.y_min_tops[i]) {
- this.y_min_tops[i] = y_top;
+ var special_values_width = 0;
+ this.specific_values.map(function (val) {
+ if (_this2.get_strwidth(val.title) > special_values_width) {
+ special_values_width = _this2.get_strwidth(val.title) - 40;
}
});
- });
- }
-
- get_bar_height_and_y_attr(y_top) {
- let height, y;
- if (y_top <= this.zero_line) {
- height = this.zero_line - y_top;
- y = y_top;
-
- // In case of invisible bars
- if(height === 0) {
- height = this.height * 0.01;
- y -= height;
- }
- } else {
- height = y_top - this.zero_line;
- y = this.zero_line;
-
- // In case of invisible bars
- if(height === 0) {
- height = this.height * 0.01;
- }
+ this.base_width = this.parent.offsetWidth - special_values_width;
+ this.width = this.base_width - this.translate_x * 2;
}
-
- return [height, y];
- }
-
- setup_utils() {
- this.draw = {
- 'bar': (x, y_top, args, color, index, no_of_datasets) => {
- let total_width = this.avg_unit_width - args.space_width;
- let start_x = x - total_width/2;
-
- let width = total_width / no_of_datasets;
- let current_x = start_x + width * index;
-
- let [height, y] = this.get_bar_height_and_y_attr(y_top);
-
- return $$.createSVG('rect', {
- className: `bar mini fill ${color}`,
- x: current_x,
- y: y,
- width: width,
- height: height
- });
-
- },
- 'dot': (x, y, args, color) => {
- return $$.createSVG('circle', {
- className: `fill ${color}`,
- cx: x,
- cy: y,
- r: args.radius
- });
- }
- };
-
- this.animate = {
- 'bar': (bar_obj, x, y_top, index) => {
- let start = x - this.avg_unit_width/4;
- let width = (this.avg_unit_width/2)/this.y.length;
- let [height, y] = this.get_bar_height_and_y_attr(y_top);
-
- x = start + (width * index);
-
- return [bar_obj, {width: width, height: height, x: x, y: y}, 250, "easein"];
- // bar.animate({height: args.new_height, y: y_top}, 250, mina.easein);
- },
- 'dot': (dot_obj, x, y_top) => {
- return [dot_obj, {cx: x, cy: y_top}, 300, "easein"];
- // dot.animate({cy: y_top}, 250, mina.easein);
- }
- };
- }
-};
-
-frappe.chart.BarChart = class BarChart extends frappe.chart.AxisChart {
- constructor(args) {
- super(args);
-
- this.type = 'bar';
- this.x_axis_mode = args.x_axis_mode || 'tick';
- this.y_axis_mode = args.y_axis_mode || 'span';
- this.setup();
- }
-
- setup_values() {
- super.setup_values();
- this.x_offset = this.avg_unit_width;
- this.unit_args = {
- type: 'bar',
- args: {
- space_width: this.avg_unit_width/2,
- }
- };
- }
-
- make_overlay() {
- // Just make one out of the first element
- let index = this.x.length - 1;
- let unit = this.y[0].svg_units[index];
- this.update_current_data_point(index);
-
- if(this.overlay) {
- this.overlay.parentNode.removeChild(this.overlay);
- }
-
- this.overlay = unit.cloneNode();
- this.overlay.style.fill = '#000000';
- this.overlay.style.opacity = '0.4';
- this.draw_area.appendChild(this.overlay);
- }
-
- bind_overlay() {
- // on event, update overlay
- this.parent.addEventListener('data-select', (e) => {
- this.update_overlay(e.svg_unit);
- });
- }
-
- update_overlay(unit) {
- let attributes = [];
- Object.keys(unit.attributes).map(index => {
- attributes.push(unit.attributes[index]);
- });
-
- attributes.filter(attr => attr.specified).map(attr => {
- this.overlay.setAttribute(attr.name, attr.nodeValue);
- });
- }
-
- on_left_arrow() {
- this.update_current_data_point(this.current_index - 1);
- }
-
- on_right_arrow() {
- this.update_current_data_point(this.current_index + 1);
- }
-
- set_avg_unit_width_and_x_offset() {
- this.avg_unit_width = this.width/(this.x.length + 1);
- this.x_offset = this.avg_unit_width;
- }
-};
-
-frappe.chart.LineChart = class LineChart extends frappe.chart.AxisChart {
- constructor(args) {
- super(args);
- if(Object.getPrototypeOf(this) !== frappe.chart.LineChart.prototype) {
- return;
- }
-
- this.type = 'line';
- this.region_fill = args.region_fill;
- this.x_axis_mode = args.x_axis_mode || 'span';
- this.y_axis_mode = args.y_axis_mode || 'span';
-
- this.setup();
- }
-
- setup_graph_components() {
- this.setup_path_groups();
- super.setup_graph_components();
- }
-
- setup_path_groups() {
- this.paths_groups = [];
- this.y.map((d, i) => {
- this.paths_groups[i] = $$.createSVG('g', {
- className: 'path-group path-group-' + i,
- inside: this.draw_area
+ }, {
+ key: 'setup_base_values',
+ value: function setup_base_values() {}
+ }, {
+ key: 'setup_container',
+ value: function setup_container() {
+ this.container = $.create('div', {
+ className: 'chart-container',
+ innerHTML: '' + this.title + '
\n\t\t\t\t' + this.subtitle + '
\n\t\t\t\t\n\t\t\t\t'
});
- });
- }
- setup_values() {
- super.setup_values();
- this.unit_args = {
- type: 'dot',
- args: { radius: 8 }
- };
- }
+ // Chart needs a dedicated parent element
+ this.parent.innerHTML = '';
+ this.parent.appendChild(this.container);
- make_paths() {
- this.y.map((d, i) => {
- this.make_path(d, i, this.x_axis_positions, d.y_tops, d.color || this.colors[i]);
- });
- }
+ this.chart_wrapper = this.container.querySelector('.frappe-chart');
+ this.stats_wrapper = this.container.querySelector('.graph-stats-container');
- make_path(d, i, x_positions, y_positions, color) {
- // let points_list = y_positions.map((y, i) => (x_positions[i] + ',' + y));
- // let points_str = points_list.join("L");
-
- // this.paths_groups[i].textContent = '';
-
- // d.path = $$.createSVG('path', {
- // inside: this.paths_groups[i],
- // className: `stroke ${color}`,
- // d: "M"+points_str
- // });
-
- // if(this.region_fill) {
- // let gradient_id ='path-fill-gradient' + '-' + color;
-
- // this.gradient_def = $$.createSVG('linearGradient', {
- // inside: this.svg_defs,
- // id: gradient_id,
- // x1: 0,
- // x2: 0,
- // y1: 0,
- // y2: 1
- // });
-
- // function set_gradient_stop(grad_elem, offset, color, opacity) {
- // $$.createSVG('stop', {
- // 'className': 'stop-color ' + color,
- // 'inside': grad_elem,
- // 'offset': offset,
- // 'stop-opacity': opacity
- // });
- // }
-
- // set_gradient_stop(this.gradient_def, "0%", color, 0.4);
- // set_gradient_stop(this.gradient_def, "50%", color, 0.2);
- // set_gradient_stop(this.gradient_def, "100%", color, 0);
-
- // d.region_path = $$.createSVG('path', {
- // inside: this.paths_groups[i],
- // className: `region-fill`,
- // d: "M" + `0,${this.zero_line}L` + points_str + `L${this.width},${this.zero_line}`,
- // });
-
- // d.region_path.style.stroke = "none";
- // d.region_path.style.fill = `url(#${gradient_id})`;
- // }
- }
-};
-
-frappe.chart.PercentageChart = class PercentageChart extends frappe.chart.FrappeChart {
- constructor(args) {
- super(args);
- this.type = 'percentage';
-
- this.get_y_label = this.format_lambdas.y_label;
- this.get_x_tooltip = this.format_lambdas.x_tooltip;
- this.get_y_tooltip = this.format_lambdas.y_tooltip;
-
- this.max_slices = 10;
- this.max_legend_points = 6;
-
- this.colors = args.colors;
-
- if(!this.colors || this.colors.length < this.data.labels.length) {
- this.colors = ['light-blue', 'blue', 'violet', 'red', 'orange',
- 'yellow', 'green', 'light-green', 'purple', 'magenta'];
+ this.make_chart_area();
+ this.make_draw_area();
}
-
- this.setup();
- }
-
- make_chart_area() {
- this.chart_wrapper.className += ' ' + 'graph-focus-margin';
- this.chart_wrapper.style.marginTop = '45px';
-
- this.stats_wrapper.className += ' ' + 'graph-focus-margin';
- this.stats_wrapper.style.marginBottom = '30px';
- this.stats_wrapper.style.paddingTop = '0px';
- }
-
- make_draw_area() {
- this.chart_div = $$.create('div', {
- className: 'div',
- inside: this.chart_wrapper,
- width: this.base_width,
- height: this.base_height
- });
-
- this.chart = $$.create('div', {
- className: 'progress-chart',
- inside: this.chart_div
- });
- }
-
- setup_components() {
- this.percentage_bar = $$.create('div', {
- className: 'progress',
- inside: this.chart
- });
- }
-
- setup_values() {
- this.slice_totals = [];
- let all_totals = this.data.labels.map((d, i) => {
- let total = 0;
- this.data.datasets.map(e => {
- total += e.values[i];
+ }, {
+ key: 'make_chart_area',
+ value: function make_chart_area() {
+ this.svg = $.createSVG('svg', {
+ className: 'chart',
+ inside: this.chart_wrapper,
+ width: this.base_width,
+ height: this.base_height
});
- return [total, d];
- }).filter(d => { return d[0] > 0; }); // keep only positive results
- let totals = all_totals;
+ this.svg_defs = $.createSVG('defs', {
+ inside: this.svg
+ });
- if(all_totals.length > this.max_slices) {
- all_totals.sort((a, b) => { return b[0] - a[0]; });
-
- totals = all_totals.slice(0, this.max_slices-1);
- let others = all_totals.slice(this.max_slices-1);
-
- let sum_of_others = 0;
- others.map(d => {sum_of_others += d[0];});
-
- totals.push([sum_of_others, 'Rest']);
-
- this.colors[this.max_slices-1] = 'grey';
+ return this.svg;
}
-
- this.labels = [];
- totals.map(d => {
- this.slice_totals.push(d[0]);
- this.labels.push(d[1]);
- });
-
- this.legend_totals = this.slice_totals.slice(0, this.max_legend_points);
- }
-
- setup_utils() { }
-
- make_graph_components() {
- this.grand_total = this.slice_totals.reduce((a, b) => a + b, 0);
- this.slices = [];
- this.slice_totals.map((total, i) => {
- let slice = $$.create('div', {
- className: `progress-bar background ${this.colors[i]}`,
- style: `width: ${total*100/this.grand_total}%`,
- inside: this.percentage_bar
+ }, {
+ key: 'make_draw_area',
+ value: function make_draw_area() {
+ this.draw_area = $.createSVG("g", {
+ className: this.type + '-chart',
+ inside: this.svg,
+ transform: 'translate(' + this.translate_x + ', ' + this.translate_y + ')'
});
- this.slices.push(slice);
- });
- }
-
- bind_tooltip() {
- this.slices.map((slice, i) => {
- slice.addEventListener('mouseenter', () => {
- let g_off = $$.offset(this.chart_wrapper), p_off = $$.offset(slice);
-
- let x = p_off.left - g_off.left + slice.offsetWidth/2;
- let y = p_off.top - g_off.top - 6;
- let title = (this.formatted_labels && this.formatted_labels.length>0
- ? this.formatted_labels[i] : this.labels[i]) + ': ';
- let percent = (this.slice_totals[i]*100/this.grand_total).toFixed(1);
-
- this.tip.set_values(x, y, title, percent + "%");
- this.tip.show_tip();
+ }
+ }, {
+ key: 'setup_components',
+ value: function setup_components() {}
+ }, {
+ key: 'make_tooltip',
+ value: function make_tooltip() {
+ this.tip = new SvgTip({
+ parent: this.chart_wrapper
});
- });
- }
+ this.bind_tooltip();
+ }
+ }, {
+ key: 'show_summary',
+ value: function show_summary() {}
+ }, {
+ key: 'show_custom_summary',
+ value: function show_custom_summary() {
+ var _this3 = this;
- show_summary() {
- let x_values = this.formatted_labels && this.formatted_labels.length > 0
- ? this.formatted_labels : this.labels;
- this.legend_totals.map((d, i) => {
- if(d) {
- let stats = $$.create('div', {
+ this.summary.map(function (d) {
+ var stats = $.create('div', {
className: 'stats',
- inside: this.stats_wrapper
+ innerHTML: '' + d.title + ': ' + d.value + ''
+ });
+ _this3.stats_wrapper.appendChild(stats);
+ });
+ }
+ }, {
+ key: 'setup_navigation',
+ value: function setup_navigation() {
+ var _this4 = this;
+
+ var init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+
+ this.make_overlay();
+
+ if (init) {
+ this.bind_overlay();
+
+ document.addEventListener('keydown', function (e) {
+ if ($.isElementInViewport(_this4.chart_wrapper)) {
+ e = e || window.event;
+
+ if (e.keyCode == '37') {
+ _this4.on_left_arrow();
+ } else if (e.keyCode == '39') {
+ _this4.on_right_arrow();
+ } else if (e.keyCode == '38') {
+ _this4.on_up_arrow();
+ } else if (e.keyCode == '40') {
+ _this4.on_down_arrow();
+ } else if (e.keyCode == '13') {
+ _this4.on_enter_key();
+ }
+ }
});
- stats.innerHTML = `
- ${x_values[i]}:
- ${d}
- `;
}
- });
- }
-};
-
-frappe.chart.HeatMap = class HeatMap extends frappe.chart.FrappeChart {
- constructor({
- start = '',
- domain = '',
- subdomain = '',
- data = {},
- discrete_domains = 0,
- count_label = ''
- }) {
- super(arguments[0]);
-
- this.type = 'heatmap';
-
- this.domain = domain;
- this.subdomain = subdomain;
- this.data = data;
- this.discrete_domains = discrete_domains;
- this.count_label = count_label;
-
- let today = new Date();
- this.start = start || this.add_days(today, 365);
-
- this.legend_colors = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127'];
-
- this.translate_x = 0;
- this.setup();
- }
-
- setup_base_values() {
- this.today = new Date();
-
- if(!this.start) {
- this.start = new Date();
- this.start.setFullYear( this.start.getFullYear() - 1 );
}
- this.first_week_start = new Date(this.start.toDateString());
- this.last_week_start = new Date(this.today.toDateString());
- if(this.first_week_start.getDay() !== 7) {
- this.add_days(this.first_week_start, (-1) * this.first_week_start.getDay());
+ }, {
+ key: 'make_overlay',
+ value: function make_overlay() {}
+ }, {
+ key: 'bind_overlay',
+ value: function bind_overlay() {}
+ }, {
+ key: 'on_left_arrow',
+ value: function on_left_arrow() {}
+ }, {
+ key: 'on_right_arrow',
+ value: function on_right_arrow() {}
+ }, {
+ key: 'on_up_arrow',
+ value: function on_up_arrow() {}
+ }, {
+ key: 'on_down_arrow',
+ value: function on_down_arrow() {}
+ }, {
+ key: 'on_enter_key',
+ value: function on_enter_key() {}
+ }, {
+ key: 'get_data_point',
+ value: function get_data_point() {
+ var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.current_index;
+
+ // check for length
+ var data_point = {
+ index: index
+ };
+ var y = this.y[0];
+ ['svg_units', 'y_tops', 'values'].map(function (key) {
+ var data_key = key.slice(0, key.length - 1);
+ data_point[data_key] = y[key][index];
+ });
+ data_point.label = this.x[index];
+ return data_point;
}
- if(this.last_week_start.getDay() !== 7) {
- this.add_days(this.last_week_start, (-1) * this.last_week_start.getDay());
+ }, {
+ key: 'update_current_data_point',
+ value: function update_current_data_point(index) {
+ if (index < 0) index = 0;
+ if (index >= this.x.length) index = this.x.length - 1;
+ if (index === this.current_index) return;
+ this.current_index = index;
+ $.fire(this.parent, "data-select", this.get_data_point());
}
- this.no_of_cols = this.get_weeks_between(this.first_week_start + '', this.last_week_start + '') + 1;
- }
- set_width() {
- this.base_width = (this.no_of_cols) * 12;
+ // Helpers
- if(this.discrete_domains) {
- this.base_width += (12 * 12);
+ }, {
+ key: 'get_strwidth',
+ value: function get_strwidth(string) {
+ return string.length * 8;
}
+
+ // Objects
+
+ }, {
+ key: 'setup_utils',
+ value: function setup_utils() {}
+ }]);
+ return Chart;
+}();
+
+var AxisChart = function (_Chart) {
+ inherits(AxisChart, _Chart);
+
+ function AxisChart(args) {
+ classCallCheck(this, AxisChart);
+
+ var _this5 = possibleConstructorReturn(this, (AxisChart.__proto__ || Object.getPrototypeOf(AxisChart)).call(this, args));
+
+ _this5.x = _this5.data.labels;
+ _this5.y = _this5.data.datasets;
+
+ _this5.get_y_label = _this5.format_lambdas.y_label;
+ _this5.get_y_tooltip = _this5.format_lambdas.y_tooltip;
+ _this5.get_x_tooltip = _this5.format_lambdas.x_tooltip;
+
+ _this5.colors = ['green', 'blue', 'violet', 'red', 'orange', 'yellow', 'light-blue', 'light-green', 'purple', 'magenta'];
+
+ _this5.zero_line = _this5.height;
+ return _this5;
}
- setup_components() {
- this.domain_label_group = $$.createSVG("g", {
- className: "domain-label-group chart-label",
- inside: this.draw_area
- });
- this.data_groups = $$.createSVG("g", {
- className: "data-groups",
- inside: this.draw_area,
- transform: `translate(0, 20)`
- });
- }
+ createClass(AxisChart, [{
+ key: 'setup_values',
+ value: function setup_values() {
+ this.data.datasets.map(function (d) {
+ d.values = d.values.map(function (val) {
+ return !isNaN(val) ? val : 0;
+ });
+ });
+ this.setup_x();
+ this.setup_y();
+ }
+ }, {
+ key: 'setup_x',
+ value: function setup_x() {
+ var _this6 = this;
- setup_values() {
- this.domain_label_group.textContent = '';
- this.data_groups.textContent = '';
- this.distribution = this.get_distribution(this.data, this.legend_colors);
- this.month_names = ["January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"
- ];
+ this.set_avg_unit_width_and_x_offset();
- this.render_all_weeks_and_store_x_values(this.no_of_cols);
- }
-
- render_all_weeks_and_store_x_values(no_of_weeks) {
- let current_week_sunday = new Date(this.first_week_start);
- this.week_col = 0;
- this.current_month = current_week_sunday.getMonth();
-
- this.months = [this.current_month + ''];
- this.month_weeks = {}, this.month_start_points = [];
- this.month_weeks[this.current_month] = 0;
- this.month_start_points.push(13);
-
- for(var i = 0; i < no_of_weeks; i++) {
- let data_group, month_change = 0;
- let day = new Date(current_week_sunday);
-
- [data_group, month_change] = this.get_week_squares_group(day, this.week_col);
- this.data_groups.appendChild(data_group);
- this.week_col += 1 + parseInt(this.discrete_domains && month_change);
- this.month_weeks[this.current_month]++;
- if(month_change) {
- this.current_month = (this.current_month + 1) % 12;
- this.months.push(this.current_month + '');
- this.month_weeks[this.current_month] = 1;
+ if (this.x_axis_positions) {
+ this.x_old_axis_positions = this.x_axis_positions.slice();
}
- this.add_days(current_week_sunday, 7);
- }
- this.render_month_labels();
- }
-
- get_week_squares_group(current_date, index) {
- const no_of_weekdays = 7;
- const square_side = 10;
- const cell_padding = 2;
- const step = 1;
-
- let month_change = 0;
- let week_col_change = 0;
-
- let data_group = $$.createSVG("g", {
- className: "data-group",
- inside: this.data_groups
- });
-
- for(var y = 0, i = 0; i < no_of_weekdays; i += step, y += (square_side + cell_padding)) {
- let data_value = 0;
- let color_index = 0;
-
- let timestamp = Math.floor(current_date.getTime()/1000).toFixed(1);
-
- if(this.data[timestamp]) {
- data_value = this.data[timestamp];
- color_index = this.get_max_checkpoint(data_value, this.distribution);
- }
-
- if(this.data[Math.round(timestamp)]) {
- data_value = this.data[Math.round(timestamp)];
- color_index = this.get_max_checkpoint(data_value, this.distribution);
- }
-
- let x = 13 + (index + week_col_change) * 12;
-
- $$.createSVG("rect", {
- className: 'day',
- inside: data_group,
- x: x,
- y: y,
- width: square_side,
- height: square_side,
- fill: this.legend_colors[color_index],
- 'data-date': this.get_dd_mm_yyyy(current_date),
- 'data-value': data_value,
- 'data-day': current_date.getDay()
+ this.x_axis_positions = this.x.map(function (d, i) {
+ return float_2(_this6.x_offset + i * _this6.avg_unit_width);
});
- let next_date = new Date(current_date);
- this.add_days(next_date, 1);
- if(next_date.getMonth() - current_date.getMonth()) {
- month_change = 1;
- if(this.discrete_domains) {
- week_col_change = 1;
+ if (!this.x_old_axis_positions) {
+ this.x_old_axis_positions = this.x_axis_positions.slice();
+ }
+ }
+ }, {
+ key: 'setup_y',
+ value: function setup_y() {
+ if (this.y_axis_values) {
+ this.y_old_axis_values = this.y_axis_values.slice();
+ }
+
+ var values = this.get_all_y_values();
+
+ if (this.y_sums && this.y_sums.length > 0) {
+ values = values.concat(this.y_sums);
+ }
+
+ this.y_axis_values = this.get_y_axis_points(values);
+
+ if (!this.y_old_axis_values) {
+ this.y_old_axis_values = this.y_axis_values.slice();
+ }
+
+ var y_pts = this.y_axis_values;
+ var value_range = y_pts[y_pts.length - 1] - y_pts[0];
+
+ if (this.multiplier) this.old_multiplier = this.multiplier;
+ this.multiplier = this.height / value_range;
+ if (!this.old_multiplier) this.old_multiplier = this.multiplier;
+
+ var zero_index = y_pts.indexOf(0);
+ var interval = y_pts[1] - y_pts[0];
+ var interval_height = interval * this.multiplier;
+
+ if (this.zero_line) this.old_zero_line = this.zero_line;
+ this.zero_line = this.height - zero_index * interval_height;
+ if (!this.old_zero_line) this.old_zero_line = this.zero_line;
+ }
+ }, {
+ key: 'setup_components',
+ value: function setup_components() {
+ get(AxisChart.prototype.__proto__ || Object.getPrototypeOf(AxisChart.prototype), 'setup_components', this).call(this);
+ this.setup_marker_components();
+ this.setup_aggregation_components();
+ this.setup_graph_components();
+ }
+ }, {
+ key: 'setup_marker_components',
+ value: function setup_marker_components() {
+ this.y_axis_group = $.createSVG('g', { className: 'y axis', inside: this.draw_area });
+ this.x_axis_group = $.createSVG('g', { className: 'x axis', inside: this.draw_area });
+ this.specific_y_group = $.createSVG('g', { className: 'specific axis', inside: this.draw_area });
+ }
+ }, {
+ key: 'setup_aggregation_components',
+ value: function setup_aggregation_components() {
+ this.sum_group = $.createSVG('g', { className: 'data-points', inside: this.draw_area });
+ this.average_group = $.createSVG('g', { className: 'chart-area', inside: this.draw_area });
+ }
+ }, {
+ key: 'setup_graph_components',
+ value: function setup_graph_components() {
+ var _this7 = this;
+
+ this.svg_units_groups = [];
+ this.y.map(function (d, i) {
+ _this7.svg_units_groups[i] = $.createSVG('g', {
+ className: 'data-points data-points-' + i,
+ inside: _this7.draw_area
+ });
+ });
+ }
+ }, {
+ key: 'make_graph_components',
+ value: function make_graph_components() {
+ var init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+
+ this.make_y_axis();
+ this.make_x_axis();
+ this.draw_graph(init);
+ this.make_y_specifics();
+ }
+
+ // make VERTICAL lines for x values
+
+ }, {
+ key: 'make_x_axis',
+ value: function make_x_axis() {
+ var _this8 = this;
+
+ var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+
+ var start_at = void 0,
+ height = void 0,
+ text_start_at = void 0,
+ axis_line_class = '';
+ if (this.x_axis_mode === 'span') {
+ // long spanning lines
+ start_at = -7;
+ height = this.height + 15;
+ text_start_at = this.height + 25;
+ } else if (this.x_axis_mode === 'tick') {
+ // short label lines
+ start_at = this.height;
+ height = 6;
+ text_start_at = 9;
+ axis_line_class = 'x-axis-label';
+ }
+
+ this.x_axis_group.setAttribute('transform', 'translate(0,' + start_at + ')');
+
+ if (animate) {
+ this.make_anim_x_axis(height, text_start_at, axis_line_class);
+ return;
+ }
+
+ this.x_axis_group.textContent = '';
+ this.x.map(function (point, i) {
+ _this8.x_axis_group.appendChild(_this8.make_x_line(height, text_start_at, point, 'x-value-text', axis_line_class, _this8.x_axis_positions[i]));
+ });
+ }
+
+ // make HORIZONTAL lines for y values
+
+ }, {
+ key: 'make_y_axis',
+ value: function make_y_axis() {
+ var _this9 = this;
+
+ var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+
+ if (animate) {
+ this.make_anim_y_axis();
+ this.make_anim_y_specifics();
+ return;
+ }
+
+ var _get_y_axis_line_prop = this.get_y_axis_line_props(),
+ _get_y_axis_line_prop2 = slicedToArray(_get_y_axis_line_prop, 4),
+ width = _get_y_axis_line_prop2[0],
+ text_end_at = _get_y_axis_line_prop2[1],
+ axis_line_class = _get_y_axis_line_prop2[2],
+ start_at = _get_y_axis_line_prop2[3];
+
+ this.y_axis_group.textContent = '';
+ this.y_axis_values.map(function (value, i) {
+ _this9.y_axis_group.appendChild(_this9.make_y_line(start_at, width, text_end_at, value, 'y-value-text', axis_line_class, _this9.zero_line - value * _this9.multiplier, value === 0 && i !== 0 // Non-first Zero line
+ ));
+ });
+ }
+ }, {
+ key: 'get_y_axis_line_props',
+ value: function get_y_axis_line_props() {
+ var specific = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+
+ if (specific) {
+ return [this.width, this.width + 5, 'specific-value', 0];
+ }
+ var width = void 0,
+ text_end_at = -9,
+ axis_line_class = '',
+ start_at = 0;
+ if (this.y_axis_mode === 'span') {
+ // long spanning lines
+ width = this.width + 6;
+ start_at = -6;
+ } else if (this.y_axis_mode === 'tick') {
+ // short label lines
+ width = -6;
+ axis_line_class = 'y-axis-label';
+ }
+
+ return [width, text_end_at, axis_line_class, start_at];
+ }
+ }, {
+ key: 'draw_graph',
+ value: function draw_graph() {
+ var _this10 = this;
+
+ var init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+
+ if (init) {
+ this.draw_new_graph_and_animate();
+ return;
+ }
+ this.y.map(function (d, i) {
+ d.svg_units = [];
+ _this10.make_path && _this10.make_path(d, i, _this10.x_axis_positions, d.y_tops, d.color || _this10.colors[i]);
+ _this10.make_new_units(d, i);
+ });
+ }
+ }, {
+ key: 'draw_new_graph_and_animate',
+ value: function draw_new_graph_and_animate() {
+ var _this11 = this;
+
+ var data = [];
+ this.y.map(function (d, i) {
+ // Anim: Don't draw initial values, store them and update later
+ d.y_tops = new Array(d.values.length).fill(_this11.zero_line); // no value
+ data.push({ values: d.values });
+ d.svg_units = [];
+
+ _this11.make_path && _this11.make_path(d, i, _this11.x_axis_positions, d.y_tops, d.color || _this11.colors[i]);
+ _this11.make_new_units(d, i);
+ });
+
+ setTimeout(function () {
+ _this11.update_values(data);
+ }, 350);
+ }
+ }, {
+ key: 'setup_navigation',
+ value: function setup_navigation(init) {
+ var _this12 = this;
+
+ // Hack: defer nav till initial update_values
+ setTimeout(function () {
+ get(AxisChart.prototype.__proto__ || Object.getPrototypeOf(AxisChart.prototype), 'setup_navigation', _this12).call(_this12, init);
+ }, 500);
+ }
+ }, {
+ key: 'make_new_units',
+ value: function make_new_units(d, i) {
+ this.make_new_units_for_dataset(this.x_axis_positions, d.y_tops, d.color || this.colors[i], i, this.y.length);
+ }
+ }, {
+ key: 'make_new_units_for_dataset',
+ value: function make_new_units_for_dataset(x_values, y_values, color, dataset_index, no_of_datasets, group, array, unit) {
+ var _this13 = this;
+
+ if (!group) group = this.svg_units_groups[dataset_index];
+ if (!array) array = this.y[dataset_index].svg_units;
+ if (!unit) unit = this.unit_args;
+
+ group.textContent = '';
+ array.length = 0;
+
+ y_values.map(function (y, i) {
+ var data_unit = _this13.draw[unit.type](x_values[i], y, unit.args, color, dataset_index, no_of_datasets);
+ group.appendChild(data_unit);
+ array.push(data_unit);
+ });
+ }
+ }, {
+ key: 'make_y_specifics',
+ value: function make_y_specifics() {
+ var _this14 = this;
+
+ this.specific_y_group.textContent = '';
+ this.specific_values.map(function (d) {
+ _this14.specific_y_group.appendChild(_this14.make_y_line(0, _this14.width, _this14.width + 5, d.title.toUpperCase(), 'specific-value', 'specific-value', _this14.zero_line - d.value * _this14.multiplier, false, d.line_type));
+ });
+ }
+ }, {
+ key: 'bind_tooltip',
+ value: function bind_tooltip() {
+ var _this15 = this;
+
+ // TODO: could be in tooltip itself, as it is a given functionality for its parent
+ this.chart_wrapper.addEventListener('mousemove', function (e) {
+ var offset = $.offset(_this15.chart_wrapper);
+ var relX = e.pageX - offset.left - _this15.translate_x;
+ var relY = e.pageY - offset.top - _this15.translate_y;
+
+ if (relY < _this15.height + _this15.translate_y * 2) {
+ _this15.map_tooltip_x_position_and_show(relX);
+ } else {
+ _this15.tip.hide_tip();
+ }
+ });
+ }
+ }, {
+ key: 'map_tooltip_x_position_and_show',
+ value: function map_tooltip_x_position_and_show(relX) {
+ var _this16 = this;
+
+ for (var i = this.x_axis_positions.length - 1; i >= 0; i--) {
+ var x_val = this.x_axis_positions[i];
+ // let delta = i === 0 ? this.avg_unit_width : x_val - this.x_axis_positions[i-1];
+ if (relX > x_val - this.avg_unit_width / 2) {
+ var x = x_val + this.translate_x;
+ var y = this.y_min_tops[i] + this.translate_y;
+
+ var title = this.x.formatted && this.x.formatted.length > 0 ? this.x.formatted[i] : this.x[i];
+ var values = this.y.map(function (set$$1, j) {
+ return {
+ title: set$$1.title,
+ value: set$$1.formatted ? set$$1.formatted[i] : set$$1.values[i],
+ color: set$$1.color || _this16.colors[j]
+ };
+ });
+
+ // TODO: upside-down tooltips for negative values?
+ this.tip.set_values(x, y, title, '', values);
+ this.tip.show_tip();
+ break;
+ }
+ }
+ }
+
+ // API
+
+ }, {
+ key: 'show_sums',
+ value: function show_sums() {
+ var _this17 = this;
+
+ this.updating = true;
+
+ this.y_sums = new Array(this.x_axis_positions.length).fill(0);
+ this.y.map(function (d) {
+ d.values.map(function (value, i) {
+ _this17.y_sums[i] += value;
+ });
+ });
+
+ // Remake y axis, animate
+ this.update_values();
+
+ // Then make sum units, don't animate
+ this.sum_units = [];
+
+ this.make_new_units_for_dataset(this.x_axis_positions, this.y_sums.map(function (val) {
+ return float_2(_this17.zero_line - val * _this17.multiplier);
+ }), 'light-grey', 0, 1, this.sum_group, this.sum_units);
+
+ // this.make_path && this.make_path(d, i, old_x, old_y, d.color || this.colors[i]);
+
+ this.updating = false;
+ }
+ }, {
+ key: 'hide_sums',
+ value: function hide_sums() {
+ if (this.updating) return;
+ this.y_sums = [];
+ this.sum_group.textContent = '';
+ this.sum_units = [];
+ this.update_values();
+ }
+ }, {
+ key: 'show_average',
+ value: function show_average() {
+ var _this18 = this;
+
+ this.old_specific_values = this.specific_values.slice();
+ this.y.map(function (d, i) {
+ var sum = 0;
+ d.values.map(function (e) {
+ sum += e;
+ });
+ var average = sum / d.values.length;
+
+ _this18.specific_values.push({
+ title: "AVG" + " " + (i + 1),
+ line_type: "dashed",
+ value: average,
+ auto: 1
+ });
+ });
+
+ this.update_values();
+ }
+ }, {
+ key: 'hide_average',
+ value: function hide_average() {
+ var _this19 = this;
+
+ this.old_specific_values = this.specific_values.slice();
+
+ var indices_to_remove = [];
+ this.specific_values.map(function (d, i) {
+ if (d.auto) indices_to_remove.unshift(i);
+ });
+
+ indices_to_remove.map(function (index) {
+ _this19.specific_values.splice(index, 1);
+ });
+
+ this.update_values();
+ }
+ }, {
+ key: 'update_values',
+ value: function update_values(new_y, new_x) {
+ var _this20 = this;
+
+ if (!new_x) {
+ new_x = this.x;
+ }
+ this.elements_to_animate = [];
+ this.updating = true;
+
+ this.old_x_values = this.x.slice();
+ this.old_y_axis_tops = this.y.map(function (d) {
+ return d.y_tops.slice();
+ });
+
+ this.old_y_values = this.y.map(function (d) {
+ return d.values;
+ });
+
+ this.no_of_extra_pts = new_x.length - this.x.length;
+
+ // Just update values prop, setup_x/y() will do the rest
+ if (new_y) this.y.map(function (d, i) {
+ d.values = new_y[i].values;
+ });
+ if (new_x) this.x = new_x;
+
+ this.setup_x();
+ this.setup_y();
+
+ // Animate only if positions have changed
+ if (!arrays_equal(this.x_old_axis_positions, this.x_axis_positions)) {
+ this.make_x_axis(true);
+ setTimeout(function () {
+ if (!_this20.updating) _this20.make_x_axis();
+ }, 300);
+ }
+
+ if (!arrays_equal(this.y_old_axis_values, this.y_axis_values) || this.old_specific_values && !arrays_equal(this.old_specific_values, this.specific_values)) {
+
+ this.make_y_axis(true);
+ setTimeout(function () {
+ if (!_this20.updating) {
+ _this20.make_y_axis();
+ _this20.make_y_specifics();
+ }
+ }, 300);
+ }
+
+ // Change in data, so calculate dependencies
+ this.calc_y_dependencies();
+
+ this.animate_graphs();
+
+ // Trigger animation with the animatable elements in this.elements_to_animate
+ this.run_animation();
+
+ this.updating = false;
+ }
+ }, {
+ key: 'add_data_point',
+ value: function add_data_point(y_point, x_point) {
+ var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.x.length;
+
+ var new_y = this.y.map(function (data_set) {
+ return { values: data_set.values };
+ });
+ new_y.map(function (d, i) {
+ d.values.splice(index, 0, y_point[i]);
+ });
+ var new_x = this.x.slice();
+ new_x.splice(index, 0, x_point);
+
+ this.update_values(new_y, new_x);
+ }
+ }, {
+ key: 'remove_data_point',
+ value: function remove_data_point() {
+ var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.x.length - 1;
+
+ if (this.x.length < 3) return;
+
+ var new_y = this.y.map(function (data_set) {
+ return { values: data_set.values };
+ });
+ new_y.map(function (d) {
+ d.values.splice(index, 1);
+ });
+ var new_x = this.x.slice();
+ new_x.splice(index, 1);
+
+ this.update_values(new_y, new_x);
+ }
+ }, {
+ key: 'run_animation',
+ value: function run_animation() {
+ var _this21 = this;
+
+ var anim_svg = $.runSVGAnimation(this.svg, this.elements_to_animate);
+
+ if (this.svg.parentNode == this.chart_wrapper) {
+ this.chart_wrapper.removeChild(this.svg);
+ this.chart_wrapper.appendChild(anim_svg);
+ }
+
+ // Replace the new svg (data has long been replaced)
+ setTimeout(function () {
+ if (anim_svg.parentNode == _this21.chart_wrapper) {
+ _this21.chart_wrapper.removeChild(anim_svg);
+ _this21.chart_wrapper.appendChild(_this21.svg);
+ }
+ }, 200);
+ }
+ }, {
+ key: 'animate_graphs',
+ value: function animate_graphs() {
+ var _this22 = this;
+
+ this.y.map(function (d, i) {
+ // Pre-prep, equilize no of positions between old and new
+ var _calc_old_and_new_pos = _this22.calc_old_and_new_postions(d, i),
+ _calc_old_and_new_pos2 = slicedToArray(_calc_old_and_new_pos, 4),
+ old_x = _calc_old_and_new_pos2[0],
+ old_y = _calc_old_and_new_pos2[1],
+ new_x = _calc_old_and_new_pos2[2],
+ new_y = _calc_old_and_new_pos2[3];
+
+ if (_this22.no_of_extra_pts >= 0) {
+ _this22.make_path && _this22.make_path(d, i, old_x, old_y, d.color || _this22.colors[i]);
+ _this22.make_new_units_for_dataset(old_x, old_y, d.color || _this22.colors[i], i, _this22.y.length);
+ }
+ d.path && _this22.animate_path(d, i, old_x, old_y, new_x, new_y);
+ _this22.animate_units(d, i, old_x, old_y, new_x, new_y);
+ });
+
+ // TODO: replace with real units
+ setTimeout(function () {
+ _this22.y.map(function (d, i) {
+ _this22.make_path && _this22.make_path(d, i, _this22.x_axis_positions, d.y_tops, d.color || _this22.colors[i]);
+ _this22.make_new_units(d, i);
+ });
+ }, 300);
+ }
+ }, {
+ key: 'animate_path',
+ value: function animate_path(d, i, old_x, old_y, new_x, new_y) {
+ // Animate path
+ var new_points_list = new_y.map(function (y, i) {
+ return new_x[i] + ',' + y;
+ });
+ var new_path_str = new_points_list.join("L");
+
+ var path_args = [{ unit: d.path, object: d, key: 'path' }, { d: "M" + new_path_str }, 250, "easein"];
+ this.elements_to_animate.push(path_args);
+
+ // Animate region
+ if (d.region_path) {
+ var reg_start_pt = '0,' + this.zero_line + 'L';
+ var reg_end_pt = 'L' + this.width + ',' + this.zero_line;
+
+ var region_args = [{ unit: d.region_path, object: d, key: 'region_path' }, { d: "M" + reg_start_pt + new_path_str + reg_end_pt }, 250, "easein"];
+ this.elements_to_animate.push(region_args);
+ }
+ }
+ }, {
+ key: 'animate_units',
+ value: function animate_units(d, index, old_x, old_y, new_x, new_y) {
+ var _this23 = this;
+
+ var type = this.unit_args.type;
+
+ d.svg_units.map(function (unit, i) {
+ _this23.elements_to_animate.push(_this23.animate[type]({ unit: unit, array: d.svg_units, index: i }, // unit, with info to replace where it came from in the data
+ new_x[i], new_y[i], index));
+ });
+ }
+ }, {
+ key: 'calc_old_and_new_postions',
+ value: function calc_old_and_new_postions(d, i) {
+ var old_x = this.x_old_axis_positions.slice();
+ var new_x = this.x_axis_positions.slice();
+
+ var old_y = this.old_y_axis_tops[i].slice();
+ var new_y = d.y_tops.slice();
+
+ var last_old_x_pos = old_x[old_x.length - 1];
+ var last_old_y_pos = old_y[old_y.length - 1];
+
+ var last_new_x_pos = new_x[new_x.length - 1];
+ var last_new_y_pos = new_y[new_y.length - 1];
+
+ if (this.no_of_extra_pts >= 0) {
+ // First substitute current path with a squiggled one (looking the same but
+ // having more points at end),
+ // then animate to stretch it later to new points
+ // (new points already have more points)
+
+ // Hence, the extra end points will correspond to current(old) positions
+ var filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_old_x_pos);
+ var filler_y = new Array(Math.abs(this.no_of_extra_pts)).fill(last_old_y_pos);
+
+ old_x = old_x.concat(filler_x);
+ old_y = old_y.concat(filler_y);
+ } else {
+ // Just modify the new points to have extra points
+ // with the same position at end
+ var _filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_new_x_pos);
+ var _filler_y = new Array(Math.abs(this.no_of_extra_pts)).fill(last_new_y_pos);
+
+ new_x = new_x.concat(_filler_x);
+ new_y = new_y.concat(_filler_y);
+ }
+
+ return [old_x, old_y, new_x, new_y];
+ }
+ }, {
+ key: 'make_anim_x_axis',
+ value: function make_anim_x_axis(height, text_start_at, axis_line_class) {
+ var _this24 = this;
+
+ // Animate X AXIS to account for more or less axis lines
+
+ var old_pos = this.x_old_axis_positions;
+ var new_pos = this.x_axis_positions;
+
+ var old_vals = this.old_x_values;
+ var new_vals = this.x;
+
+ var last_line_pos = old_pos[old_pos.length - 1];
+
+ var add_and_animate_line = function add_and_animate_line(value, old_pos, new_pos) {
+ var x_line = _this24.make_x_line(height, text_start_at, value, // new value
+ 'x-value-text', axis_line_class, old_pos // old position
+ );
+ _this24.x_axis_group.appendChild(x_line);
+
+ _this24.elements_to_animate && _this24.elements_to_animate.push([{ unit: x_line, array: [0], index: 0 }, { transform: new_pos + ', 0' }, 250, "easein", "translate", { transform: old_pos + ', 0' }]);
+ };
+
+ this.x_axis_group.textContent = '';
+
+ this.make_new_axis_anim_lines(old_pos, new_pos, old_vals, new_vals, last_line_pos, add_and_animate_line);
+ }
+ }, {
+ key: 'make_anim_y_axis',
+ value: function make_anim_y_axis() {
+ var _this25 = this;
+
+ // Animate Y AXIS to account for more or less axis lines
+
+ var old_pos = this.y_old_axis_values.map(function (value) {
+ return _this25.zero_line - value * _this25.multiplier;
+ });
+ var new_pos = this.y_axis_values.map(function (value) {
+ return _this25.zero_line - value * _this25.multiplier;
+ });
+
+ var old_vals = this.y_old_axis_values;
+ var new_vals = this.y_axis_values;
+
+ var last_line_pos = old_pos[old_pos.length - 1];
+
+ this.y_axis_group.textContent = '';
+
+ this.make_new_axis_anim_lines(old_pos, new_pos, old_vals, new_vals, last_line_pos, this.add_and_animate_y_line.bind(this), this.y_axis_group);
+ }
+ }, {
+ key: 'make_anim_y_specifics',
+ value: function make_anim_y_specifics() {
+ var _this26 = this;
+
+ this.specific_y_group.textContent = '';
+ this.specific_values.map(function (d) {
+ _this26.add_and_animate_y_line(d.title, _this26.old_zero_line - d.value * _this26.old_multiplier, _this26.zero_line - d.value * _this26.multiplier, 0, _this26.specific_y_group, d.line_type, true);
+ });
+ }
+ }, {
+ key: 'make_new_axis_anim_lines',
+ value: function make_new_axis_anim_lines(old_pos, new_pos, old_vals, new_vals, last_line_pos, add_and_animate_line, group) {
+ var superimposed_positions = void 0,
+ superimposed_values = void 0;
+ var no_of_extras = new_vals.length - old_vals.length;
+ if (no_of_extras > 0) {
+ // More axis are needed
+ // First make only the superimposed (same position) ones
+ // Add in the extras at the end later
+ superimposed_positions = new_pos.slice(0, old_pos.length);
+ superimposed_values = new_vals.slice(0, old_vals.length);
+ } else {
+ // Axis have to be reduced
+ // Fake it by moving all current extra axis to the last position
+ // You'll need filler positions and values in the new arrays
+ var filler_vals = new Array(Math.abs(no_of_extras)).fill("");
+ superimposed_values = new_vals.concat(filler_vals);
+
+ var filler_pos = new Array(Math.abs(no_of_extras)).fill(last_line_pos);
+ superimposed_positions = new_pos.concat(filler_pos);
+ }
+
+ superimposed_values.map(function (value, i) {
+ add_and_animate_line(value, old_pos[i], superimposed_positions[i], i, group);
+ });
+
+ if (no_of_extras > 0) {
+ // Add in extra axis in the end
+ // and then animate to new positions
+ var extra_values = new_vals.slice(old_vals.length);
+ var extra_positions = new_pos.slice(old_pos.length);
+
+ extra_values.map(function (value, i) {
+ add_and_animate_line(value, last_line_pos, extra_positions[i], i, group);
+ });
+ }
+ }
+ }, {
+ key: 'make_x_line',
+ value: function make_x_line(height, text_start_at, point, label_class, axis_line_class, x_pos) {
+ var allowed_space = this.avg_unit_width * 1.5;
+
+ if (this.get_strwidth(point) > allowed_space) {
+ var allowed_letters = allowed_space / 8;
+ point = point.slice(0, allowed_letters - 3) + " ...";
+ }
+
+ var line = $.createSVG('line', {
+ x1: 0,
+ x2: 0,
+ y1: 0,
+ y2: height
+ });
+
+ var text = $.createSVG('text', {
+ className: label_class,
+ x: 0,
+ y: text_start_at,
+ dy: '.71em',
+ innerHTML: point
+ });
+
+ var x_level = $.createSVG('g', {
+ className: 'tick ' + axis_line_class,
+ transform: 'translate(' + x_pos + ', 0)'
+ });
+
+ x_level.appendChild(line);
+ x_level.appendChild(text);
+
+ return x_level;
+ }
+ }, {
+ key: 'make_y_line',
+ value: function make_y_line(start_at, width, text_end_at, point, label_class, axis_line_class, y_pos) {
+ var darker = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false;
+ var line_type = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : "";
+
+ var line = $.createSVG('line', {
+ className: line_type === "dashed" ? "dashed" : "",
+ x1: start_at,
+ x2: width,
+ y1: 0,
+ y2: 0
+ });
+
+ var text = $.createSVG('text', {
+ className: label_class,
+ x: text_end_at,
+ y: 0,
+ dy: '.32em',
+ innerHTML: point + ""
+ });
+
+ var y_level = $.createSVG('g', {
+ className: 'tick ' + axis_line_class,
+ transform: 'translate(0, ' + y_pos + ')'
+ });
+
+ if (darker) {
+ line.style.stroke = "rgba(27, 31, 35, 0.6)";
+ }
+
+ y_level.appendChild(line);
+ y_level.appendChild(text);
+
+ return y_level;
+ }
+ }, {
+ key: 'add_and_animate_y_line',
+ value: function add_and_animate_y_line(value, old_pos, new_pos, i, group, type) {
+ var specific = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;
+
+ var _get_y_axis_line_prop3 = this.get_y_axis_line_props(specific),
+ _get_y_axis_line_prop4 = slicedToArray(_get_y_axis_line_prop3, 4),
+ width = _get_y_axis_line_prop4[0],
+ text_end_at = _get_y_axis_line_prop4[1],
+ axis_line_class = _get_y_axis_line_prop4[2],
+ start_at = _get_y_axis_line_prop4[3];
+
+ var axis_label_class = !specific ? 'y-value-text' : 'specific-value';
+ value = !specific ? value : (value + "").toUpperCase();
+ var y_line = this.make_y_line(start_at, width, text_end_at, value, axis_label_class, axis_line_class, old_pos, // old position
+ value === 0 && i !== 0, // Non-first Zero line
+ type);
+
+ group.appendChild(y_line);
+
+ this.elements_to_animate && this.elements_to_animate.push([{ unit: y_line, array: [0], index: 0 }, { transform: '0, ' + new_pos }, 250, "easein", "translate", { transform: '0, ' + old_pos }]);
+ }
+ }, {
+ key: 'get_y_axis_points',
+ value: function get_y_axis_points(array) {
+ var _this27 = this;
+
+ //*** Where the magic happens ***
+
+ // Calculates best-fit y intervals from given values
+ // and returns the interval array
+
+ // TODO: Fractions
+
+ var max_bound = void 0,
+ min_bound = void 0,
+ pos_no_of_parts = void 0,
+ neg_no_of_parts = void 0,
+ part_size = void 0; // eslint-disable-line no-unused-vars
+
+ // Critical values
+ var max_val = parseInt(Math.max.apply(Math, toConsumableArray(array)));
+ var min_val = parseInt(Math.min.apply(Math, toConsumableArray(array)));
+ if (min_val >= 0) {
+ min_val = 0;
+ }
+
+ var get_params = function get_params(value1, value2) {
+ var bound1 = void 0,
+ bound2 = void 0,
+ no_of_parts_1 = void 0,
+ no_of_parts_2 = void 0,
+ interval_size = void 0;
+ if ((value1 + "").length <= 1) {
+ bound1 = 10;
+ no_of_parts_1 = 5;
+ } else {
+ var _calc_upper_bound_and = _this27.calc_upper_bound_and_no_of_parts(value1);
+
+ var _calc_upper_bound_and2 = slicedToArray(_calc_upper_bound_and, 2);
+
+ bound1 = _calc_upper_bound_and2[0];
+ no_of_parts_1 = _calc_upper_bound_and2[1];
}
- this.month_start_points.push(13 + (index + week_col_change) * 12);
+ interval_size = bound1 / no_of_parts_1;
+ no_of_parts_2 = _this27.calc_no_of_parts(value2, interval_size);
+ bound2 = no_of_parts_2 * interval_size;
+
+ return [bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size];
+ };
+
+ var abs_min_val = min_val * -1;
+ if (abs_min_val <= max_val) {
+ var _get_params = get_params(max_val, abs_min_val);
+ // Get the positive region intervals
+ // then calc negative ones accordingly
+
+
+ var _get_params2 = slicedToArray(_get_params, 5);
+
+ min_bound = _get_params2[1];
+ pos_no_of_parts = _get_params2[2];
+ neg_no_of_parts = _get_params2[3];
+ part_size = _get_params2[4];
+
+ if (abs_min_val === 0) {
+ min_bound = 0;neg_no_of_parts = 0;
+ }
+ } else {
+ var _get_params3 = get_params(abs_min_val, max_val);
+ // Get the negative region here first
+
+
+ var _get_params4 = slicedToArray(_get_params3, 5);
+
+ min_bound = _get_params4[0];
+ neg_no_of_parts = _get_params4[2];
+ pos_no_of_parts = _get_params4[3];
+ part_size = _get_params4[4];
}
- current_date = next_date;
+
+ // Make both region parts even
+ if (pos_no_of_parts % 2 !== 0 && neg_no_of_parts > 0) pos_no_of_parts++;
+ if (neg_no_of_parts % 2 !== 0) {
+ // every increase in no_of_parts entails an increase in corresponding bound
+ // except here, it happens implicitly after every calc_no_of_parts() call
+ neg_no_of_parts++;
+ min_bound += part_size;
+ }
+
+ var no_of_parts = pos_no_of_parts + neg_no_of_parts;
+ if (no_of_parts > 5) {
+ no_of_parts /= 2;
+ part_size *= 2;
+ }
+
+ return this.get_intervals(-1 * min_bound, part_size, no_of_parts);
+ }
+ }, {
+ key: 'get_intervals',
+ value: function get_intervals(start, interval_size, count) {
+ var intervals = [];
+ for (var i = 0; i <= count; i++) {
+ intervals.push(start);
+ start += interval_size;
+ }
+ return intervals;
+ }
+ }, {
+ key: 'calc_upper_bound_and_no_of_parts',
+ value: function calc_upper_bound_and_no_of_parts(max_val) {
+ // Given a positive value, calculates a nice-number upper bound
+ // and a consequent optimal number of parts
+
+ var part_size = Math.pow(10, (max_val + "").length - 1);
+ var no_of_parts = this.calc_no_of_parts(max_val, part_size);
+
+ // Use it to get a nice even upper bound
+ var upper_bound = part_size * no_of_parts;
+
+ return [upper_bound, no_of_parts];
+ }
+ }, {
+ key: 'calc_no_of_parts',
+ value: function calc_no_of_parts(value, divisor) {
+ // value should be a positive number, divisor should be greater than 0
+ // returns an even no of parts
+ var no_of_parts = Math.ceil(value / divisor);
+ if (no_of_parts % 2 !== 0) no_of_parts++; // Make it an even number
+
+ return no_of_parts;
+ }
+ }, {
+ key: 'get_optimal_no_of_parts',
+ value: function get_optimal_no_of_parts(no_of_parts) {
+ // aka Divide by 2 if too large
+ return no_of_parts < 5 ? no_of_parts : no_of_parts / 2;
+ }
+ }, {
+ key: 'set_avg_unit_width_and_x_offset',
+ value: function set_avg_unit_width_and_x_offset() {
+ // Set the ... you get it
+ this.avg_unit_width = this.width / (this.x.length - 1);
+ this.x_offset = 0;
+ }
+ }, {
+ key: 'get_all_y_values',
+ value: function get_all_y_values() {
+ var all_values = [];
+
+ // Add in all the y values in the datasets
+ this.y.map(function (d) {
+ all_values = all_values.concat(d.values);
+ });
+
+ // Add in all the specific values
+ return all_values.concat(this.specific_values.map(function (d) {
+ return d.value;
+ }));
+ }
+ }, {
+ key: 'calc_y_dependencies',
+ value: function calc_y_dependencies() {
+ var _this28 = this;
+
+ this.y_min_tops = new Array(this.x_axis_positions.length).fill(9999);
+ this.y.map(function (d) {
+ d.y_tops = d.values.map(function (val) {
+ return float_2(_this28.zero_line - val * _this28.multiplier);
+ });
+ d.y_tops.map(function (y_top, i) {
+ if (y_top < _this28.y_min_tops[i]) {
+ _this28.y_min_tops[i] = y_top;
+ }
+ });
+ });
+ }
+ }, {
+ key: 'get_bar_height_and_y_attr',
+ value: function get_bar_height_and_y_attr(y_top) {
+ var height = void 0,
+ y = void 0;
+ if (y_top <= this.zero_line) {
+ height = this.zero_line - y_top;
+ y = y_top;
+
+ // In case of invisible bars
+ if (height === 0) {
+ height = this.height * 0.01;
+ y -= height;
+ }
+ } else {
+ height = y_top - this.zero_line;
+ y = this.zero_line;
+
+ // In case of invisible bars
+ if (height === 0) {
+ height = this.height * 0.01;
+ }
+ }
+
+ return [height, y];
+ }
+ }, {
+ key: 'setup_utils',
+ value: function setup_utils() {
+ var _this29 = this;
+
+ this.draw = {
+ 'bar': function bar(x, y_top, args, color, index, no_of_datasets) {
+ var total_width = _this29.avg_unit_width - args.space_width;
+ var start_x = x - total_width / 2;
+
+ var width = total_width / no_of_datasets;
+ var current_x = start_x + width * index;
+
+ var _get_bar_height_and_y = _this29.get_bar_height_and_y_attr(y_top),
+ _get_bar_height_and_y2 = slicedToArray(_get_bar_height_and_y, 2),
+ height = _get_bar_height_and_y2[0],
+ y = _get_bar_height_and_y2[1];
+
+ return $.createSVG('rect', {
+ className: 'bar mini fill ' + color,
+ x: current_x,
+ y: y,
+ width: width,
+ height: height
+ });
+ },
+ 'dot': function dot(x, y, args, color) {
+ return $.createSVG('circle', {
+ className: 'fill ' + color,
+ cx: x,
+ cy: y,
+ r: args.radius
+ });
+ }
+ };
+
+ this.animate = {
+ 'bar': function bar(bar_obj, x, y_top, index) {
+ var start = x - _this29.avg_unit_width / 4;
+ var width = _this29.avg_unit_width / 2 / _this29.y.length;
+
+ var _get_bar_height_and_y3 = _this29.get_bar_height_and_y_attr(y_top),
+ _get_bar_height_and_y4 = slicedToArray(_get_bar_height_and_y3, 2),
+ height = _get_bar_height_and_y4[0],
+ y = _get_bar_height_and_y4[1];
+
+ x = start + width * index;
+
+ return [bar_obj, { width: width, height: height, x: x, y: y }, 250, "easein"];
+ // bar.animate({height: args.new_height, y: y_top}, 250, mina.easein);
+ },
+ 'dot': function dot(dot_obj, x, y_top) {
+ return [dot_obj, { cx: x, cy: y_top }, 300, "easein"];
+ // dot.animate({cy: y_top}, 250, mina.easein);
+ }
+ };
+ }
+ }]);
+ return AxisChart;
+}(Chart);
+
+var BarChart = function (_AxisChart) {
+ inherits(BarChart, _AxisChart);
+
+ function BarChart(args) {
+ classCallCheck(this, BarChart);
+
+ var _this30 = possibleConstructorReturn(this, (BarChart.__proto__ || Object.getPrototypeOf(BarChart)).call(this, args));
+
+ _this30.type = 'bar';
+ _this30.x_axis_mode = args.x_axis_mode || 'tick';
+ _this30.y_axis_mode = args.y_axis_mode || 'span';
+ _this30.setup();
+ return _this30;
+ }
+
+ createClass(BarChart, [{
+ key: 'setup_values',
+ value: function setup_values() {
+ get(BarChart.prototype.__proto__ || Object.getPrototypeOf(BarChart.prototype), 'setup_values', this).call(this);
+ this.x_offset = this.avg_unit_width;
+ this.unit_args = {
+ type: 'bar',
+ args: {
+ space_width: this.avg_unit_width / 2
+ }
+ };
+ }
+ }, {
+ key: 'make_overlay',
+ value: function make_overlay() {
+ // Just make one out of the first element
+ var index = this.x.length - 1;
+ var unit = this.y[0].svg_units[index];
+ this.update_current_data_point(index);
+
+ if (this.overlay) {
+ this.overlay.parentNode.removeChild(this.overlay);
+ }
+
+ this.overlay = unit.cloneNode();
+ this.overlay.style.fill = '#000000';
+ this.overlay.style.opacity = '0.4';
+ this.draw_area.appendChild(this.overlay);
+ }
+ }, {
+ key: 'bind_overlay',
+ value: function bind_overlay() {
+ var _this31 = this;
+
+ // on event, update overlay
+ this.parent.addEventListener('data-select', function (e) {
+ _this31.update_overlay(e.svg_unit);
+ });
+ }
+ }, {
+ key: 'update_overlay',
+ value: function update_overlay(unit) {
+ var _this32 = this;
+
+ var attributes = [];
+ Object.keys(unit.attributes).map(function (index) {
+ attributes.push(unit.attributes[index]);
+ });
+
+ attributes.filter(function (attr) {
+ return attr.specified;
+ }).map(function (attr) {
+ _this32.overlay.setAttribute(attr.name, attr.nodeValue);
+ });
+ }
+ }, {
+ key: 'on_left_arrow',
+ value: function on_left_arrow() {
+ this.update_current_data_point(this.current_index - 1);
+ }
+ }, {
+ key: 'on_right_arrow',
+ value: function on_right_arrow() {
+ this.update_current_data_point(this.current_index + 1);
+ }
+ }, {
+ key: 'set_avg_unit_width_and_x_offset',
+ value: function set_avg_unit_width_and_x_offset() {
+ this.avg_unit_width = this.width / (this.x.length + 1);
+ this.x_offset = this.avg_unit_width;
+ }
+ }]);
+ return BarChart;
+}(AxisChart);
+
+var LineChart = function (_AxisChart2) {
+ inherits(LineChart, _AxisChart2);
+
+ function LineChart(args) {
+ classCallCheck(this, LineChart);
+
+ var _this33 = possibleConstructorReturn(this, (LineChart.__proto__ || Object.getPrototypeOf(LineChart)).call(this, args));
+
+ if (Object.getPrototypeOf(_this33) !== LineChart.prototype) {
+ return possibleConstructorReturn(_this33);
}
- return [data_group, month_change];
+ _this33.type = 'line';
+ _this33.region_fill = args.region_fill;
+ _this33.x_axis_mode = args.x_axis_mode || 'span';
+ _this33.y_axis_mode = args.y_axis_mode || 'span';
+
+ _this33.setup();
+ return _this33;
}
- render_month_labels() {
- // this.first_month_label = 1;
- // if (this.first_week_start.getDate() > 8) {
- // this.first_month_label = 0;
- // }
- // this.last_month_label = 1;
+ createClass(LineChart, [{
+ key: 'setup_graph_components',
+ value: function setup_graph_components() {
+ this.setup_path_groups();
+ get(LineChart.prototype.__proto__ || Object.getPrototypeOf(LineChart.prototype), 'setup_graph_components', this).call(this);
+ }
+ }, {
+ key: 'setup_path_groups',
+ value: function setup_path_groups() {
+ var _this34 = this;
- // let first_month = this.months.shift();
- // let first_month_start = this.month_start_points.shift();
- // render first month if
+ this.paths_groups = [];
+ this.y.map(function (d, i) {
+ _this34.paths_groups[i] = $.createSVG('g', {
+ className: 'path-group path-group-' + i,
+ inside: _this34.draw_area
+ });
+ });
+ }
+ }, {
+ key: 'setup_values',
+ value: function setup_values() {
+ get(LineChart.prototype.__proto__ || Object.getPrototypeOf(LineChart.prototype), 'setup_values', this).call(this);
+ this.unit_args = {
+ type: 'dot',
+ args: { radius: 8 }
+ };
+ }
+ }, {
+ key: 'make_paths',
+ value: function make_paths() {
+ var _this35 = this;
- // let last_month = this.months.pop();
- // let last_month_start = this.month_start_points.pop();
- // render last month if
+ this.y.map(function (d, i) {
+ _this35.make_path(d, i, _this35.x_axis_positions, d.y_tops, d.color || _this35.colors[i]);
+ });
+ }
+ }, {
+ key: 'make_path',
+ value: function make_path(d, i, x_positions, y_positions, color) {
+ var points_list = y_positions.map(function (y, i) {
+ return x_positions[i] + ',' + y;
+ });
+ var points_str = points_list.join("L");
- this.months.shift();
- this.month_start_points.shift();
- this.months.pop();
- this.month_start_points.pop();
+ this.paths_groups[i].textContent = '';
- this.month_start_points.map((start, i) => {
- let month_name = this.month_names[this.months[i]].substring(0, 3);
-
- $$.createSVG('text', {
- className: 'y-value-text',
- inside: this.domain_label_group,
- x: start + 12,
- y: 10,
- dy: '.32em',
- innerHTML: month_name
+ d.path = $.createSVG('path', {
+ inside: this.paths_groups[i],
+ className: 'stroke ' + color,
+ d: "M" + points_str
});
- });
- }
+ if (this.region_fill) {
+ var gradient_id = 'path-fill-gradient' + '-' + color;
- make_graph_components() {
- Array.prototype.slice.call(
- this.container.querySelectorAll('.graph-stats-container, .sub-title, .title')
- ).map(d => {
- d.style.display = 'None';
- });
- this.chart_wrapper.style.marginTop = '0px';
- this.chart_wrapper.style.paddingTop = '0px';
- }
+ this.gradient_def = $.createSVG('linearGradient', {
+ inside: this.svg_defs,
+ id: gradient_id,
+ x1: 0,
+ x2: 0,
+ y1: 0,
+ y2: 1
+ });
- bind_tooltip() {
- Array.prototype.slice.call(
- document.querySelectorAll(".data-group .day")
- ).map(el => {
- el.addEventListener('mouseenter', (e) => {
- let count = e.target.getAttribute('data-value');
- let date_parts = e.target.getAttribute('data-date').split('-');
+ var set_gradient_stop = function set_gradient_stop(grad_elem, offset, color, opacity) {
+ $.createSVG('stop', {
+ 'className': 'stop-color ' + color,
+ 'inside': grad_elem,
+ 'offset': offset,
+ 'stop-opacity': opacity
+ });
+ };
- let month = this.month_names[parseInt(date_parts[1])-1].substring(0, 3);
+ set_gradient_stop(this.gradient_def, "0%", color, 0.4);
+ set_gradient_stop(this.gradient_def, "50%", color, 0.2);
+ set_gradient_stop(this.gradient_def, "100%", color, 0);
- let g_off = this.chart_wrapper.getBoundingClientRect(), p_off = e.target.getBoundingClientRect();
+ d.region_path = $.createSVG('path', {
+ inside: this.paths_groups[i],
+ className: 'region-fill',
+ d: "M" + ('0,' + this.zero_line + 'L') + points_str + ('L' + this.width + ',' + this.zero_line)
+ });
- let width = parseInt(e.target.getAttribute('width'));
- let x = p_off.left - g_off.left + (width+2)/2;
- let y = p_off.top - g_off.top - (width+2)/2;
- let value = count + ' ' + this.count_label;
- let name = ' on ' + month + ' ' + date_parts[0] + ', ' + date_parts[2];
-
- this.tip.set_values(x, y, name, value, [], 1);
- this.tip.show_tip();
- });
- });
- }
-
- update(data) {
- this.data = data;
- this.setup_values();
- this.bind_tooltip();
- }
-
- get_distribution(data={}, mapper_array) {
- let data_values = Object.keys(data).map(key => data[key]);
- let data_max_value = Math.max(...data_values);
-
- let distribution_step = 1 / (mapper_array.length - 1);
- let distribution = [];
-
- mapper_array.map((color, i) => {
- let checkpoint = data_max_value * (distribution_step * i);
- distribution.push(checkpoint);
- });
-
- return distribution;
- }
-
- get_max_checkpoint(value, distribution) {
- return distribution.filter((d, i) => {
- if(i === 1) {
- return distribution[0] < value;
+ d.region_path.style.stroke = "none";
+ d.region_path.style.fill = 'url(#' + gradient_id + ')';
}
- return d <= value;
- }).length - 1;
+ }
+ }]);
+ return LineChart;
+}(AxisChart);
+
+var PercentageChart = function (_Chart2) {
+ inherits(PercentageChart, _Chart2);
+
+ function PercentageChart(args) {
+ classCallCheck(this, PercentageChart);
+
+ var _this36 = possibleConstructorReturn(this, (PercentageChart.__proto__ || Object.getPrototypeOf(PercentageChart)).call(this, args));
+
+ _this36.type = 'percentage';
+
+ _this36.get_y_label = _this36.format_lambdas.y_label;
+ _this36.get_x_tooltip = _this36.format_lambdas.x_tooltip;
+ _this36.get_y_tooltip = _this36.format_lambdas.y_tooltip;
+
+ _this36.max_slices = 10;
+ _this36.max_legend_points = 6;
+
+ _this36.colors = args.colors;
+
+ if (!_this36.colors || _this36.colors.length < _this36.data.labels.length) {
+ _this36.colors = ['light-blue', 'blue', 'violet', 'red', 'orange', 'yellow', 'green', 'light-green', 'purple', 'magenta'];
+ }
+
+ _this36.setup();
+ return _this36;
}
- // TODO: date utils, move these out
+ createClass(PercentageChart, [{
+ key: 'make_chart_area',
+ value: function make_chart_area() {
+ this.chart_wrapper.className += ' ' + 'graph-focus-margin';
+ this.chart_wrapper.style.marginTop = '45px';
- // https://stackoverflow.com/a/11252167/6495043
- treat_as_utc(date_str) {
- let result = new Date(date_str);
- result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
- return result;
+ this.stats_wrapper.className += ' ' + 'graph-focus-margin';
+ this.stats_wrapper.style.marginBottom = '30px';
+ this.stats_wrapper.style.paddingTop = '0px';
+ }
+ }, {
+ key: 'make_draw_area',
+ value: function make_draw_area() {
+ this.chart_div = $.create('div', {
+ className: 'div',
+ inside: this.chart_wrapper,
+ width: this.base_width,
+ height: this.base_height
+ });
+
+ this.chart = $.create('div', {
+ className: 'progress-chart',
+ inside: this.chart_div
+ });
+ }
+ }, {
+ key: 'setup_components',
+ value: function setup_components() {
+ this.percentage_bar = $.create('div', {
+ className: 'progress',
+ inside: this.chart
+ });
+ }
+ }, {
+ key: 'setup_values',
+ value: function setup_values() {
+ var _this37 = this;
+
+ this.slice_totals = [];
+ var all_totals = this.data.labels.map(function (d, i) {
+ var total = 0;
+ _this37.data.datasets.map(function (e) {
+ total += e.values[i];
+ });
+ return [total, d];
+ }).filter(function (d) {
+ return d[0] > 0;
+ }); // keep only positive results
+
+ var totals = all_totals;
+
+ if (all_totals.length > this.max_slices) {
+ all_totals.sort(function (a, b) {
+ return b[0] - a[0];
+ });
+
+ totals = all_totals.slice(0, this.max_slices - 1);
+ var others = all_totals.slice(this.max_slices - 1);
+
+ var sum_of_others = 0;
+ others.map(function (d) {
+ sum_of_others += d[0];
+ });
+
+ totals.push([sum_of_others, 'Rest']);
+
+ this.colors[this.max_slices - 1] = 'grey';
+ }
+
+ this.labels = [];
+ totals.map(function (d) {
+ _this37.slice_totals.push(d[0]);
+ _this37.labels.push(d[1]);
+ });
+
+ this.legend_totals = this.slice_totals.slice(0, this.max_legend_points);
+ }
+ }, {
+ key: 'setup_utils',
+ value: function setup_utils() {}
+ }, {
+ key: 'make_graph_components',
+ value: function make_graph_components() {
+ var _this38 = this;
+
+ this.grand_total = this.slice_totals.reduce(function (a, b) {
+ return a + b;
+ }, 0);
+ this.slices = [];
+ this.slice_totals.map(function (total, i) {
+ var slice = $.create('div', {
+ className: 'progress-bar background ' + _this38.colors[i],
+ style: 'width: ' + total * 100 / _this38.grand_total + '%',
+ inside: _this38.percentage_bar
+ });
+ _this38.slices.push(slice);
+ });
+ }
+ }, {
+ key: 'bind_tooltip',
+ value: function bind_tooltip() {
+ var _this39 = this;
+
+ this.slices.map(function (slice, i) {
+ slice.addEventListener('mouseenter', function () {
+ var g_off = $.offset(_this39.chart_wrapper),
+ p_off = $.offset(slice);
+
+ var x = p_off.left - g_off.left + slice.offsetWidth / 2;
+ var y = p_off.top - g_off.top - 6;
+ var title = (_this39.formatted_labels && _this39.formatted_labels.length > 0 ? _this39.formatted_labels[i] : _this39.labels[i]) + ': ';
+ var percent = (_this39.slice_totals[i] * 100 / _this39.grand_total).toFixed(1);
+
+ _this39.tip.set_values(x, y, title, percent + "%");
+ _this39.tip.show_tip();
+ });
+ });
+ }
+ }, {
+ key: 'show_summary',
+ value: function show_summary() {
+ var _this40 = this;
+
+ var x_values = this.formatted_labels && this.formatted_labels.length > 0 ? this.formatted_labels : this.labels;
+ this.legend_totals.map(function (d, i) {
+ if (d) {
+ var stats = $.create('div', {
+ className: 'stats',
+ inside: _this40.stats_wrapper
+ });
+ stats.innerHTML = '\n\t\t\t\t\t' + x_values[i] + ':\n\t\t\t\t\t' + d + '\n\t\t\t\t';
+ }
+ });
+ }
+ }]);
+ return PercentageChart;
+}(Chart);
+
+var HeatMap = function (_Chart3) {
+ inherits(HeatMap, _Chart3);
+
+ function HeatMap(_ref2) {
+ var _ref2$start = _ref2.start,
+ start = _ref2$start === undefined ? '' : _ref2$start,
+ _ref2$domain = _ref2.domain,
+ domain = _ref2$domain === undefined ? '' : _ref2$domain,
+ _ref2$subdomain = _ref2.subdomain,
+ subdomain = _ref2$subdomain === undefined ? '' : _ref2$subdomain,
+ _ref2$data = _ref2.data,
+ data = _ref2$data === undefined ? {} : _ref2$data,
+ _ref2$discrete_domain = _ref2.discrete_domains,
+ discrete_domains = _ref2$discrete_domain === undefined ? 0 : _ref2$discrete_domain,
+ _ref2$count_label = _ref2.count_label,
+ count_label = _ref2$count_label === undefined ? '' : _ref2$count_label;
+ classCallCheck(this, HeatMap);
+
+ var _this41 = possibleConstructorReturn(this, (HeatMap.__proto__ || Object.getPrototypeOf(HeatMap)).call(this, arguments[0]));
+
+ _this41.type = 'heatmap';
+
+ _this41.domain = domain;
+ _this41.subdomain = subdomain;
+ _this41.data = data;
+ _this41.discrete_domains = discrete_domains;
+ _this41.count_label = count_label;
+
+ var today = new Date();
+ _this41.start = start || _this41.add_days(today, 365);
+
+ _this41.legend_colors = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127'];
+
+ _this41.translate_x = 0;
+ _this41.setup();
+ return _this41;
}
- get_dd_mm_yyyy(date) {
- let dd = date.getDate();
- let mm = date.getMonth() + 1; // getMonth() is zero-based
- return [
- (dd>9 ? '' : '0') + dd,
- (mm>9 ? '' : '0') + mm,
- date.getFullYear()
- ].join('-');
- }
+ createClass(HeatMap, [{
+ key: 'setup_base_values',
+ value: function setup_base_values() {
+ this.today = new Date();
- get_weeks_between(start_date_str, end_date_str) {
- return Math.ceil(this.get_days_between(start_date_str, end_date_str) / 7);
- }
+ if (!this.start) {
+ this.start = new Date();
+ this.start.setFullYear(this.start.getFullYear() - 1);
+ }
+ this.first_week_start = new Date(this.start.toDateString());
+ this.last_week_start = new Date(this.today.toDateString());
+ if (this.first_week_start.getDay() !== 7) {
+ this.add_days(this.first_week_start, -1 * this.first_week_start.getDay());
+ }
+ if (this.last_week_start.getDay() !== 7) {
+ this.add_days(this.last_week_start, -1 * this.last_week_start.getDay());
+ }
+ this.no_of_cols = this.get_weeks_between(this.first_week_start + '', this.last_week_start + '') + 1;
+ }
+ }, {
+ key: 'set_width',
+ value: function set_width() {
+ this.base_width = this.no_of_cols * 12;
- get_days_between(start_date_str, end_date_str) {
- let milliseconds_per_day = 24 * 60 * 60 * 1000;
- return (this.treat_as_utc(end_date_str) - this.treat_as_utc(start_date_str)) / milliseconds_per_day;
- }
+ if (this.discrete_domains) {
+ this.base_width += 12 * 12;
+ }
+ }
+ }, {
+ key: 'setup_components',
+ value: function setup_components() {
+ this.domain_label_group = $.createSVG("g", {
+ className: "domain-label-group chart-label",
+ inside: this.draw_area
+ });
+ this.data_groups = $.createSVG("g", {
+ className: "data-groups",
+ inside: this.draw_area,
+ transform: 'translate(0, 20)'
+ });
+ }
+ }, {
+ key: 'setup_values',
+ value: function setup_values() {
+ this.domain_label_group.textContent = '';
+ this.data_groups.textContent = '';
+ this.distribution = this.get_distribution(this.data, this.legend_colors);
+ this.month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
- // mutates
- add_days(date, number_of_days) {
- date.setDate(date.getDate() + number_of_days);
- }
+ this.render_all_weeks_and_store_x_values(this.no_of_cols);
+ }
+ }, {
+ key: 'render_all_weeks_and_store_x_values',
+ value: function render_all_weeks_and_store_x_values(no_of_weeks) {
+ var current_week_sunday = new Date(this.first_week_start);
+ this.week_col = 0;
+ this.current_month = current_week_sunday.getMonth();
- get_month_name() {}
-};
+ this.months = [this.current_month + ''];
+ this.month_weeks = {}, this.month_start_points = [];
+ this.month_weeks[this.current_month] = 0;
+ this.month_start_points.push(13);
+
+ for (var i = 0; i < no_of_weeks; i++) {
+ var data_group = void 0,
+ month_change = 0;
+ var day = new Date(current_week_sunday);
+
+ var _get_week_squares_gro = this.get_week_squares_group(day, this.week_col);
+
+ var _get_week_squares_gro2 = slicedToArray(_get_week_squares_gro, 2);
+
+ data_group = _get_week_squares_gro2[0];
+ month_change = _get_week_squares_gro2[1];
+
+ this.data_groups.appendChild(data_group);
+ this.week_col += 1 + parseInt(this.discrete_domains && month_change);
+ this.month_weeks[this.current_month]++;
+ if (month_change) {
+ this.current_month = (this.current_month + 1) % 12;
+ this.months.push(this.current_month + '');
+ this.month_weeks[this.current_month] = 1;
+ }
+ this.add_days(current_week_sunday, 7);
+ }
+ this.render_month_labels();
+ }
+ }, {
+ key: 'get_week_squares_group',
+ value: function get_week_squares_group(current_date, index) {
+ var no_of_weekdays = 7;
+ var square_side = 10;
+ var cell_padding = 2;
+ var step = 1;
+
+ var month_change = 0;
+ var week_col_change = 0;
+
+ var data_group = $.createSVG("g", {
+ className: "data-group",
+ inside: this.data_groups
+ });
+
+ for (var y = 0, i = 0; i < no_of_weekdays; i += step, y += square_side + cell_padding) {
+ var data_value = 0;
+ var color_index = 0;
+
+ var timestamp = Math.floor(current_date.getTime() / 1000).toFixed(1);
+
+ if (this.data[timestamp]) {
+ data_value = this.data[timestamp];
+ color_index = this.get_max_checkpoint(data_value, this.distribution);
+ }
+
+ if (this.data[Math.round(timestamp)]) {
+ data_value = this.data[Math.round(timestamp)];
+ color_index = this.get_max_checkpoint(data_value, this.distribution);
+ }
+
+ var x = 13 + (index + week_col_change) * 12;
+
+ $.createSVG("rect", {
+ className: 'day',
+ inside: data_group,
+ x: x,
+ y: y,
+ width: square_side,
+ height: square_side,
+ fill: this.legend_colors[color_index],
+ 'data-date': this.get_dd_mm_yyyy(current_date),
+ 'data-value': data_value,
+ 'data-day': current_date.getDay()
+ });
+
+ var next_date = new Date(current_date);
+ this.add_days(next_date, 1);
+ if (next_date.getMonth() - current_date.getMonth()) {
+ month_change = 1;
+ if (this.discrete_domains) {
+ week_col_change = 1;
+ }
+
+ this.month_start_points.push(13 + (index + week_col_change) * 12);
+ }
+ current_date = next_date;
+ }
+
+ return [data_group, month_change];
+ }
+ }, {
+ key: 'render_month_labels',
+ value: function render_month_labels() {
+ var _this42 = this;
+
+ // this.first_month_label = 1;
+ // if (this.first_week_start.getDate() > 8) {
+ // this.first_month_label = 0;
+ // }
+ // this.last_month_label = 1;
+
+ // let first_month = this.months.shift();
+ // let first_month_start = this.month_start_points.shift();
+ // render first month if
+
+ // let last_month = this.months.pop();
+ // let last_month_start = this.month_start_points.pop();
+ // render last month if
+
+ this.months.shift();
+ this.month_start_points.shift();
+ this.months.pop();
+ this.month_start_points.pop();
+
+ this.month_start_points.map(function (start, i) {
+ var month_name = _this42.month_names[_this42.months[i]].substring(0, 3);
+
+ $.createSVG('text', {
+ className: 'y-value-text',
+ inside: _this42.domain_label_group,
+ x: start + 12,
+ y: 10,
+ dy: '.32em',
+ innerHTML: month_name
+ });
+ });
+ }
+ }, {
+ key: 'make_graph_components',
+ value: function make_graph_components() {
+ Array.prototype.slice.call(this.container.querySelectorAll('.graph-stats-container, .sub-title, .title')).map(function (d) {
+ d.style.display = 'None';
+ });
+ this.chart_wrapper.style.marginTop = '0px';
+ this.chart_wrapper.style.paddingTop = '0px';
+ }
+ }, {
+ key: 'bind_tooltip',
+ value: function bind_tooltip() {
+ var _this43 = this;
+
+ Array.prototype.slice.call(document.querySelectorAll(".data-group .day")).map(function (el) {
+ el.addEventListener('mouseenter', function (e) {
+ var count = e.target.getAttribute('data-value');
+ var date_parts = e.target.getAttribute('data-date').split('-');
+
+ var month = _this43.month_names[parseInt(date_parts[1]) - 1].substring(0, 3);
+
+ var g_off = _this43.chart_wrapper.getBoundingClientRect(),
+ p_off = e.target.getBoundingClientRect();
+
+ var width = parseInt(e.target.getAttribute('width'));
+ var x = p_off.left - g_off.left + (width + 2) / 2;
+ var y = p_off.top - g_off.top - (width + 2) / 2;
+ var value = count + ' ' + _this43.count_label;
+ var name = ' on ' + month + ' ' + date_parts[0] + ', ' + date_parts[2];
+
+ _this43.tip.set_values(x, y, name, value, [], 1);
+ _this43.tip.show_tip();
+ });
+ });
+ }
+ }, {
+ key: 'update',
+ value: function update(data) {
+ this.data = data;
+ this.setup_values();
+ this.bind_tooltip();
+ }
+ }, {
+ key: 'get_distribution',
+ value: function get_distribution() {
+ var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ var mapper_array = arguments[1];
+
+ var data_values = Object.keys(data).map(function (key) {
+ return data[key];
+ });
+ var data_max_value = Math.max.apply(Math, toConsumableArray(data_values));
+
+ var distribution_step = 1 / (mapper_array.length - 1);
+ var distribution = [];
+
+ mapper_array.map(function (color, i) {
+ var checkpoint = data_max_value * (distribution_step * i);
+ distribution.push(checkpoint);
+ });
+
+ return distribution;
+ }
+ }, {
+ key: 'get_max_checkpoint',
+ value: function get_max_checkpoint(value, distribution) {
+ return distribution.filter(function (d, i) {
+ if (i === 1) {
+ return distribution[0] < value;
+ }
+ return d <= value;
+ }).length - 1;
+ }
+
+ // TODO: date utils, move these out
+
+ // https://stackoverflow.com/a/11252167/6495043
+
+ }, {
+ key: 'treat_as_utc',
+ value: function treat_as_utc(date_str) {
+ var result = new Date(date_str);
+ result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
+ return result;
+ }
+ }, {
+ key: 'get_dd_mm_yyyy',
+ value: function get_dd_mm_yyyy(date) {
+ var dd = date.getDate();
+ var mm = date.getMonth() + 1; // getMonth() is zero-based
+ return [(dd > 9 ? '' : '0') + dd, (mm > 9 ? '' : '0') + mm, date.getFullYear()].join('-');
+ }
+ }, {
+ key: 'get_weeks_between',
+ value: function get_weeks_between(start_date_str, end_date_str) {
+ return Math.ceil(this.get_days_between(start_date_str, end_date_str) / 7);
+ }
+ }, {
+ key: 'get_days_between',
+ value: function get_days_between(start_date_str, end_date_str) {
+ var milliseconds_per_day = 24 * 60 * 60 * 1000;
+ return (this.treat_as_utc(end_date_str) - this.treat_as_utc(start_date_str)) / milliseconds_per_day;
+ }
+
+ // mutates
+
+ }, {
+ key: 'add_days',
+ value: function add_days(date, number_of_days) {
+ date.setDate(date.getDate() + number_of_days);
+ }
+ }, {
+ key: 'get_month_name',
+ value: function get_month_name() {}
+ }]);
+ return HeatMap;
+}(Chart);
+
+var SvgTip = function () {
+ function SvgTip(_ref3) {
+ var _ref3$parent = _ref3.parent,
+ parent = _ref3$parent === undefined ? null : _ref3$parent;
+ classCallCheck(this, SvgTip);
-frappe.chart.SvgTip = class {
- constructor({
- parent = null
- }) {
this.parent = parent;
this.title_name = '';
this.title_value = '';
@@ -1895,352 +2661,115 @@ frappe.chart.SvgTip = class {
this.setup();
}
- setup() {
- this.make_tooltip();
- }
-
- refresh() {
- this.fill();
- this.calc_position();
- // this.show_tip();
- }
-
- make_tooltip() {
- this.container = $$.create('div', {
- inside: this.parent,
- className: 'graph-svg-tip comparison',
- innerHTML: `
-
- `
- });
- this.hide_tip();
-
- this.title = this.container.querySelector('.title');
- this.data_point_list = this.container.querySelector('.data-point-list');
-
- this.parent.addEventListener('mouseleave', () => {
- this.hide_tip();
- });
- }
-
- fill() {
- let title;
- if(this.title_value_first) {
- title = `${this.title_value}${this.title_name}`;
- } else {
- title = `${this.title_name}${this.title_value}`;
+ createClass(SvgTip, [{
+ key: 'setup',
+ value: function setup() {
+ this.make_tooltip();
}
- this.title.innerHTML = title;
- this.data_point_list.innerHTML = '';
+ }, {
+ key: 'refresh',
+ value: function refresh() {
+ this.fill();
+ this.calc_position();
+ // this.show_tip();
+ }
+ }, {
+ key: 'make_tooltip',
+ value: function make_tooltip() {
+ var _this44 = this;
- this.list_values.map((set) => {
- let li = $$.create('li', {
- className: `border-top ${set.color || 'black'}`,
- innerHTML: `${set.value ? set.value : '' }
- ${set.title ? set.title : '' }`
+ this.container = $.create('div', {
+ inside: this.parent,
+ className: 'graph-svg-tip comparison',
+ innerHTML: '\n\t\t\t\t\n\t\t\t\t'
});
+ this.hide_tip();
- this.data_point_list.appendChild(li);
- });
- }
+ this.title = this.container.querySelector('.title');
+ this.data_point_list = this.container.querySelector('.data-point-list');
- calc_position() {
- this.top = this.y - this.container.offsetHeight;
- this.left = this.x - this.container.offsetWidth/2;
- let max_left = this.parent.offsetWidth - this.container.offsetWidth;
-
- let pointer = this.container.querySelector('.svg-pointer');
-
- if(this.left < 0) {
- pointer.style.left = `calc(50% - ${-1 * this.left}px)`;
- this.left = 0;
- } else if(this.left > max_left) {
- let delta = this.left - max_left;
- pointer.style.left = `calc(50% + ${delta}px)`;
- this.left = max_left;
- } else {
- pointer.style.left = `50%`;
+ this.parent.addEventListener('mouseleave', function () {
+ _this44.hide_tip();
+ });
}
- }
+ }, {
+ key: 'fill',
+ value: function fill() {
+ var _this45 = this;
- set_values(x, y, title_name = '', title_value = '', list_values = [], title_value_first = 0) {
- this.title_name = title_name;
- this.title_value = title_value;
- this.list_values = list_values;
- this.x = x;
- this.y = y;
- this.title_value_first = title_value_first;
- this.refresh();
- }
-
- hide_tip() {
- this.container.style.top = '0px';
- this.container.style.left = '0px';
- this.container.style.opacity = '0';
- }
-
- show_tip() {
- this.container.style.top = this.top + 'px';
- this.container.style.left = this.left + 'px';
- this.container.style.opacity = '1';
- }
-};
-
-// Helpers
-frappe.chart.utils = {};
-$$.float_2 = d => parseFloat(d.toFixed(2));
-function $$(expr, con) {
- return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
-}
-
-$$.arrays_equal = (arr1, arr2) => {
- if(arr1.length !== arr2.length) return false;
- let are_equal = true;
- arr1.map((d, i) => {
- if(arr2[i] !== d) are_equal = false;
- });
- return are_equal;
-};
-
-$$.shuffle = (array) => {
- // https://stackoverflow.com/a/2450976/6495043
- // Awesomeness: https://bost.ocks.org/mike/shuffle/
-
- var currentIndex = array.length, temporaryValue, randomIndex;
-
- // While there remain elements to shuffle...
- while (0 !== currentIndex) {
-
- // Pick a remaining element...
- randomIndex = Math.floor(Math.random() * currentIndex);
- currentIndex -= 1;
-
- // And swap it with the current element.
- temporaryValue = array[currentIndex];
- array[currentIndex] = array[randomIndex];
- array[randomIndex] = temporaryValue;
- }
-
- return array;
-
-};
-
-// $$.findNodeIndex = (node) =>
-// {
-// var i = 0;
-// while (node = node.previousSibling) {
-// if (node.nodeType === 1) { ++i; }
-// }
-// return i;
-// }
-
-$$.create = function(tag, o) {
- var element = document.createElement(tag);
-
- for (var i in o) {
- var val = o[i];
-
- if (i === "inside") {
- $$(val).appendChild(element);
- }
- else if (i === "around") {
- var ref = $$(val);
- ref.parentNode.insertBefore(element, ref);
- element.appendChild(ref);
- }
- else if (i in element) {
- element[i] = val;
- }
- else {
- element.setAttribute(i, val);
- }
- }
-
- return element;
-};
-
-$$.createSVG = function(tag, o) {
- var element = document.createElementNS("http://www.w3.org/2000/svg", tag);
-
- for (var i in o) {
- var val = o[i];
-
- if (i === "inside") {
- $$(val).appendChild(element);
- }
- else if (i === "around") {
- var ref = $$(val);
- ref.parentNode.insertBefore(element, ref);
- element.appendChild(ref);
- }
- else {
- if(i === "className") { i = "class"; }
- if(i === "innerHTML") {
- element['textContent'] = val;
+ var title = void 0;
+ if (this.title_value_first) {
+ title = '' + this.title_value + '' + this.title_name;
} else {
- element.setAttribute(i, val);
+ title = this.title_name + '' + this.title_value + '';
+ }
+ this.title.innerHTML = title;
+ this.data_point_list.innerHTML = '';
+
+ this.list_values.map(function (set$$1) {
+ var li = $.create('li', {
+ className: 'border-top ' + (set$$1.color || 'black'),
+ innerHTML: '' + (set$$1.value ? set$$1.value : '') + '\n\t\t\t\t\t' + (set$$1.title ? set$$1.title : '')
+ });
+
+ _this45.data_point_list.appendChild(li);
+ });
+ }
+ }, {
+ key: 'calc_position',
+ value: function calc_position() {
+ this.top = this.y - this.container.offsetHeight;
+ this.left = this.x - this.container.offsetWidth / 2;
+ var max_left = this.parent.offsetWidth - this.container.offsetWidth;
+
+ var pointer = this.container.querySelector('.svg-pointer');
+
+ if (this.left < 0) {
+ pointer.style.left = 'calc(50% - ' + -1 * this.left + 'px)';
+ this.left = 0;
+ } else if (this.left > max_left) {
+ var delta = this.left - max_left;
+ pointer.style.left = 'calc(50% + ' + delta + 'px)';
+ this.left = max_left;
+ } else {
+ pointer.style.left = '50%';
}
}
- }
+ }, {
+ key: 'set_values',
+ value: function set_values(x, y) {
+ var title_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
+ var title_value = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
+ var list_values = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
+ var title_value_first = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
- return element;
-};
-
-$$.runSVGAnimation = (svg_container, elements) => {
- // let parent = elements[0][0]['unit'].parentNode;
-
- let new_elements = [];
- let anim_elements = [];
-
- elements.map(element => {
- let obj = element[0];
- let parent = obj.unit.parentNode;
- // let index = $$.findNodeIndex(obj.unit);
-
- let anim_element, new_element;
-
- element[0] = obj.unit;
-
- [anim_element, new_element] = $$.animateSVG(...element);
-
- new_elements.push(new_element);
- anim_elements.push([anim_element, parent]);
-
- parent.replaceChild(anim_element, obj.unit);
-
- if(obj.array) {
- obj.array[obj.index] = new_element;
- } else {
- obj.object[obj.key] = new_element;
+ this.title_name = title_name;
+ this.title_value = title_value;
+ this.list_values = list_values;
+ this.x = x;
+ this.y = y;
+ this.title_value_first = title_value_first;
+ this.refresh();
}
- });
-
- let anim_svg = svg_container.cloneNode(true);
-
- anim_elements.map((anim_element, i) => {
- anim_element[1].replaceChild(new_elements[i], anim_element[0]);
- elements[i][0] = new_elements[i];
- });
-
- return anim_svg;
-};
-
-// $$.animateMotion = (element, props, dur, easing_type="linear")
-
-$$.animateSVG = (element, props, dur, easing_type="linear", type=undefined, old_values={}) => {
- let easing = {
- ease: "0.25 0.1 0.25 1",
- linear: "0 0 1 1",
- // easein: "0.42 0 1 1",
- easein: "0.1 0.8 0.2 1",
- easeout: "0 0 0.58 1",
- easeinout: "0.42 0 0.58 1"
- };
-
- let anim_element = element.cloneNode(true);
- let new_element = element.cloneNode(true);
-
- for(var attributeName in props) {
- let animate_element;
- if(attributeName === 'transform') {
- animate_element = document.createElementNS("http://www.w3.org/2000/svg", "animateTransform");
- } else {
- animate_element = document.createElementNS("http://www.w3.org/2000/svg", "animate");
+ }, {
+ key: 'hide_tip',
+ value: function hide_tip() {
+ this.container.style.top = '0px';
+ this.container.style.left = '0px';
+ this.container.style.opacity = '0';
}
- let current_value = old_values[attributeName] || element.getAttribute(attributeName);
- let value = props[attributeName];
-
- let anim_attr = {
- attributeName: attributeName,
- from: current_value,
- to: value,
- begin: "0s",
- dur: dur/1000 + "s",
- values: current_value + ";" + value,
- keySplines: easing[easing_type],
- keyTimes: "0;1",
- calcMode: "spline",
- fill: 'freeze'
- };
-
- if(type) {
- anim_attr["type"] = type;
+ }, {
+ key: 'show_tip',
+ value: function show_tip() {
+ this.container.style.top = this.top + 'px';
+ this.container.style.left = this.left + 'px';
+ this.container.style.opacity = '1';
}
+ }]);
+ return SvgTip;
+}();
- for (var i in anim_attr) {
- animate_element.setAttribute(i, anim_attr[i]);
- }
-
- anim_element.appendChild(animate_element);
-
- if(type) {
- new_element.setAttribute(attributeName, `translate(${value})`);
- } else {
- new_element.setAttribute(attributeName, value);
- }
- }
-
- return [anim_element, new_element];
-};
-
-$$.offset = (element) => {
- let rect = element.getBoundingClientRect();
- return {
- // https://stackoverflow.com/a/7436602/6495043
- // rect.top varies with scroll, so we add whatever has been
- // scrolled to it to get absolute distance from actual page top
- top: rect.top + (document.documentElement.scrollTop || document.body.scrollTop),
- left: rect.left + (document.documentElement.scrollLeft || document.body.scrollLeft)
- }
-};
-
-$$.isElementInViewport = (el) => {
- // Although straightforward: https://stackoverflow.com/a/7557433/6495043
- var rect = el.getBoundingClientRect();
-
- return (
- rect.top >= 0 &&
- rect.left >= 0 &&
- rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
- rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
- );
-};
-
-$$.bind = function(element, o) {
- if (element) {
- for (var event in o) {
- var callback = o[event];
-
- event.split(/\s+/).forEach(function (event) {
- element.addEventListener(event, callback);
- });
- }
- }
-};
-
-$$.unbind = function(element, o) {
- if (element) {
- for (var event in o) {
- var callback = o[event];
-
- event.split(/\s+/).forEach(function(event) {
- element.removeEventListener(event, callback);
- });
- }
- }
-};
-
-$$.fire = function(target, type, properties) {
- var evt = document.createEvent("HTMLEvents");
-
- evt.initEvent(type, true, true );
-
- for (var j in properties) {
- evt[j] = properties[j];
- }
-
- return target.dispatchEvent(evt);
-};
+return Chart;
}());
-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJhcHBlLWNoYXJ0cy5taW4uanMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jaGFydHMuanMiXSwic291cmNlc0NvbnRlbnQiOlsibGV0IGZyYXBwZSA9IHtjaGFydDp7fSwgY2hhcnRfdHlwZXM6WydsaW5lJywgJ2JhcicsICdwZXJjZW50YWdlJywgJ2hlYXRtYXAnXX07XG5cbmZyYXBwZS5jaGFydC5GcmFwcGVDaGFydCA9IGNsYXNzIHtcblx0Y29uc3RydWN0b3Ioe1xuXHRcdHBhcmVudCA9IFwiXCIsXG5cdFx0aGVpZ2h0ID0gMjQwLFxuXG5cdFx0dGl0bGUgPSAnJywgc3VidGl0bGUgPSAnJyxcblxuXHRcdGRhdGEgPSB7fSxcblx0XHRmb3JtYXRfbGFtYmRhcyA9IHt9LFxuXG5cdFx0c3VtbWFyeSA9IFtdLFxuXG5cdFx0aXNfbmF2aWdhYmxlID0gMCxcblxuXHRcdHR5cGUgPSAnJ1xuXHR9KSB7XG5cdFx0aWYoT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpID09PSBmcmFwcGUuY2hhcnQuRnJhcHBlQ2hhcnQucHJvdG90eXBlKSB7XG5cdFx0XHRpZih0eXBlID09PSAnbGluZScpIHtcblx0XHRcdFx0cmV0dXJuIG5ldyBmcmFwcGUuY2hhcnQuTGluZUNoYXJ0KGFyZ3VtZW50c1swXSk7XG5cdFx0XHR9IGVsc2UgaWYodHlwZSA9PT0gJ2JhcicpIHtcblx0XHRcdFx0cmV0dXJuIG5ldyBmcmFwcGUuY2hhcnQuQmFyQ2hhcnQoYXJndW1lbnRzWzBdKTtcblx0XHRcdH0gZWxzZSBpZih0eXBlID09PSAncGVyY2VudGFnZScpIHtcblx0XHRcdFx0cmV0dXJuIG5ldyBmcmFwcGUuY2hhcnQuUGVyY2VudGFnZUNoYXJ0KGFyZ3VtZW50c1swXSk7XG5cdFx0XHR9IGVsc2UgaWYodHlwZSA9PT0gJ2hlYXRtYXAnKSB7XG5cdFx0XHRcdHJldHVybiBuZXcgZnJhcHBlLmNoYXJ0LkhlYXRNYXAoYXJndW1lbnRzWzBdKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiBuZXcgZnJhcHBlLmNoYXJ0LkxpbmVDaGFydChhcmd1bWVudHNbMF0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMucmF3X2NoYXJ0X2FyZ3MgPSBhcmd1bWVudHNbMF07XG5cblx0XHR0aGlzLnBhcmVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IocGFyZW50KTtcblx0XHR0aGlzLnRpdGxlID0gdGl0bGU7XG5cdFx0dGhpcy5zdWJ0aXRsZSA9IHN1YnRpdGxlO1xuXG5cdFx0dGhpcy5kYXRhID0gZGF0YTtcblx0XHR0aGlzLmZvcm1hdF9sYW1iZGFzID0gZm9ybWF0X2xhbWJkYXM7XG5cblx0XHR0aGlzLnNwZWNpZmljX3ZhbHVlcyA9IGRhdGEuc3BlY2lmaWNfdmFsdWVzIHx8IFtdO1xuXHRcdHRoaXMuc3VtbWFyeSA9IHN1bW1hcnk7XG5cblx0XHR0aGlzLmlzX25hdmlnYWJsZSA9IGlzX25hdmlnYWJsZTtcblx0XHRpZih0aGlzLmlzX25hdmlnYWJsZSkge1xuXHRcdFx0dGhpcy5jdXJyZW50X2luZGV4ID0gMDtcblx0XHR9XG5cblx0XHQkJC5jcmVhdGVTVkcoJ3N2ZycsIHtcblx0XHRcdGNsYXNzTmFtZTogJ2NoYXJ0Jyxcblx0XHRcdGluc2lkZTogcGFyZW50LFxuXHRcdFx0d2lkdGg6IDEwMDAsXG5cdFx0XHRoZWlnaHQ6IGhlaWdodFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5zZXRfbWFyZ2lucyhoZWlnaHQpO1xuXHR9XG5cblx0Z2V0X2RpZmZlcmVudF9jaGFydCh0eXBlKSB7XG5cdFx0aWYoIWZyYXBwZS5jaGFydF90eXBlcy5pbmNsdWRlcyh0eXBlKSkge1xuXHRcdFx0Y29uc29sZS5lcnJvcihgJyR7dHlwZX0nIGlzIG5vdCBhIHZhbGlkIGNoYXJ0IHR5cGUuYCk7XG5cdFx0fVxuXHRcdGlmKHR5cGUgPT09IHRoaXMudHlwZSkgcmV0dXJuO1xuXG5cdFx0Ly8gT25seSBhY3Jvc3MgY29tcGF0aWJsZSB0eXBlc1xuXHRcdGxldCBjb21wYXRpYmxlX3R5cGVzID0ge1xuXHRcdFx0YmFyOiBbJ2xpbmUnLCAncGVyY2VudGFnZSddLFxuXHRcdFx0bGluZTogWydiYXInLCAncGVyY2VudGFnZSddLFxuXHRcdFx0cGVyY2VudGFnZTogWydiYXInLCAnbGluZSddLFxuXHRcdFx0aGVhdG1hcDogW11cblx0XHR9XG5cblx0XHRpZighY29tcGF0aWJsZV90eXBlc1t0aGlzLnR5cGVdLmluY2x1ZGVzKHR5cGUpKSB7XG5cdFx0XHRjb25zb2xlLmVycm9yKGAnJHt0aGlzLnR5cGV9JyBjaGFydCBjYW5ub3QgYmUgY29udmVydGVkIHRvIGEgJyR7dHlwZX0nIGNoYXJ0LmApO1xuXHRcdH1cblxuXHRcdC8vIE9rYXksIHRoaXMgaXMgYW50aWNsaW1hY3RpY1xuXHRcdC8vIHRoaXMgZnVuY3Rpb24gd2lsbCBuZWVkIHRvIGJlICdjaGFuZ2VfY2hhcnRfdHlwZSh0eXBlKSdcblx0XHQvLyB0aGF0IHdpbGwgdXBkYXRlIG9ubHkgdGhlIHJlcXVpcmVkIGVsZW1lbnRzLCBidXQgZm9yIG5vdyAuLi5cblx0XHRyZXR1cm4gbmV3IGZyYXBwZS5jaGFydC5GcmFwcGVDaGFydCh7XG5cdFx0XHRwYXJlbnQ6IHRoaXMucmF3X2NoYXJ0X2FyZ3MucGFyZW50LFxuXHRcdFx0ZGF0YTogdGhpcy5yYXdfY2hhcnRfYXJncy5kYXRhLFxuXHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdGhlaWdodDogdGhpcy5yYXdfY2hhcnRfYXJncy5oZWlnaHRcblx0XHR9KTtcblx0fVxuXG5cdHNldF9tYXJnaW5zKGhlaWdodCkge1xuXHRcdHRoaXMuYmFzZV9oZWlnaHQgPSBoZWlnaHQ7XG5cdFx0dGhpcy5oZWlnaHQgPSBoZWlnaHQgLSA0MDtcblx0XHR0aGlzLnRyYW5zbGF0ZV94ID0gNjA7XG5cdFx0dGhpcy50cmFuc2xhdGVfeSA9IDEwO1xuXHR9XG5cblx0c2V0dXAoKSB7XG5cdFx0dGhpcy5iaW5kX3dpbmRvd19ldmVudHMoKTtcblx0XHR0aGlzLnJlZnJlc2godHJ1ZSk7XG5cdH1cblxuXHRiaW5kX3dpbmRvd19ldmVudHMoKSB7XG5cdFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsICgpID0+IHRoaXMucmVmcmVzaCgpKTtcblx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb3JpZW50YXRpb25jaGFuZ2UnLCAoKSA9PiB0aGlzLnJlZnJlc2goKSk7XG5cdH1cblxuXHRyZWZyZXNoKGluaXQ9ZmFsc2UpIHtcblx0XHR0aGlzLnNldHVwX2Jhc2VfdmFsdWVzKCk7XG5cdFx0dGhpcy5zZXRfd2lkdGgoKTtcblxuXHRcdHRoaXMuc2V0dXBfY29udGFpbmVyKCk7XG5cdFx0dGhpcy5zZXR1cF9jb21wb25lbnRzKCk7XG5cblx0XHR0aGlzLnNldHVwX3ZhbHVlcygpO1xuXHRcdHRoaXMuc2V0dXBfdXRpbHMoKTtcblxuXHRcdHRoaXMubWFrZV9ncmFwaF9jb21wb25lbnRzKGluaXQpO1xuXHRcdHRoaXMubWFrZV90b29sdGlwKCk7XG5cblx0XHRpZih0aGlzLnN1bW1hcnkubGVuZ3RoID4gMCkge1xuXHRcdFx0dGhpcy5zaG93X2N1c3RvbV9zdW1tYXJ5KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuc2hvd19zdW1tYXJ5KCk7XG5cdFx0fVxuXG5cdFx0aWYodGhpcy5pc19uYXZpZ2FibGUpIHtcblx0XHRcdHRoaXMuc2V0dXBfbmF2aWdhdGlvbihpbml0KTtcblx0XHR9XG5cdH1cblxuXHRzZXRfd2lkdGgoKSB7XG5cdFx0bGV0IHNwZWNpYWxfdmFsdWVzX3dpZHRoID0gMDtcblx0XHR0aGlzLnNwZWNpZmljX3ZhbHVlcy5tYXAodmFsID0+IHtcblx0XHRcdGlmKHRoaXMuZ2V0X3N0cndpZHRoKHZhbC50aXRsZSkgPiBzcGVjaWFsX3ZhbHVlc193aWR0aCkge1xuXHRcdFx0XHRzcGVjaWFsX3ZhbHVlc193aWR0aCA9IHRoaXMuZ2V0X3N0cndpZHRoKHZhbC50aXRsZSkgLSA0MDtcblx0XHRcdH1cblx0XHR9KTtcblx0XHR0aGlzLmJhc2Vfd2lkdGggPSB0aGlzLnBhcmVudC5vZmZzZXRXaWR0aCAtIHNwZWNpYWxfdmFsdWVzX3dpZHRoO1xuXHRcdHRoaXMud2lkdGggPSB0aGlzLmJhc2Vfd2lkdGggLSB0aGlzLnRyYW5zbGF0ZV94ICogMjtcblx0fVxuXG5cdHNldHVwX2Jhc2VfdmFsdWVzKCkge31cblxuXHRzZXR1cF9jb250YWluZXIoKSB7XG5cdFx0dGhpcy5jb250YWluZXIgPSAkJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdGNsYXNzTmFtZTogJ2NoYXJ0LWNvbnRhaW5lcicsXG5cdFx0XHRpbm5lckhUTUw6IGA8aDYgY2xhc3M9XCJ0aXRsZVwiIHN0eWxlPVwibWFyZ2luLXRvcDogMTVweDtcIj4ke3RoaXMudGl0bGV9PC9oNj5cblx0XHRcdFx0PGg2IGNsYXNzPVwic3ViLXRpdGxlIHVwcGVyY2FzZVwiPiR7dGhpcy5zdWJ0aXRsZX08L2g2PlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwiZnJhcHBlLWNoYXJ0IGdyYXBoaWNzXCI+PC9kaXY+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJncmFwaC1zdGF0cy1jb250YWluZXJcIj48L2Rpdj5gXG5cdFx0fSk7XG5cblx0XHQvLyBDaGFydCBuZWVkcyBhIGRlZGljYXRlZCBwYXJlbnQgZWxlbWVudFxuXHRcdHRoaXMucGFyZW50LmlubmVySFRNTCA9ICcnO1xuXHRcdHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuY29udGFpbmVyKTtcblxuXHRcdHRoaXMuY2hhcnRfd3JhcHBlciA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy5mcmFwcGUtY2hhcnQnKTtcblx0XHR0aGlzLnN0YXRzX3dyYXBwZXIgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcuZ3JhcGgtc3RhdHMtY29udGFpbmVyJyk7XG5cblx0XHR0aGlzLm1ha2VfY2hhcnRfYXJlYSgpO1xuXHRcdHRoaXMubWFrZV9kcmF3X2FyZWEoKTtcblx0fVxuXG5cdG1ha2VfY2hhcnRfYXJlYSgpIHtcblx0XHR0aGlzLnN2ZyA9ICQkLmNyZWF0ZVNWRygnc3ZnJywge1xuXHRcdFx0Y2xhc3NOYW1lOiAnY2hhcnQnLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmNoYXJ0X3dyYXBwZXIsXG5cdFx0XHR3aWR0aDogdGhpcy5iYXNlX3dpZHRoLFxuXHRcdFx0aGVpZ2h0OiB0aGlzLmJhc2VfaGVpZ2h0XG5cdFx0fSk7XG5cblx0XHR0aGlzLnN2Z19kZWZzID0gJCQuY3JlYXRlU1ZHKCdkZWZzJywge1xuXHRcdFx0aW5zaWRlOiB0aGlzLnN2Zyxcblx0XHR9KTtcblxuXHRcdHJldHVybiB0aGlzLnN2Zztcblx0fVxuXG5cdG1ha2VfZHJhd19hcmVhKCkge1xuXHRcdHRoaXMuZHJhd19hcmVhID0gJCQuY3JlYXRlU1ZHKFwiZ1wiLCB7XG5cdFx0XHRjbGFzc05hbWU6IHRoaXMudHlwZSArICctY2hhcnQnLFxuXHRcdFx0aW5zaWRlOiB0aGlzLnN2Zyxcblx0XHRcdHRyYW5zZm9ybTogYHRyYW5zbGF0ZSgke3RoaXMudHJhbnNsYXRlX3h9LCAke3RoaXMudHJhbnNsYXRlX3l9KWBcblx0XHR9KTtcblx0fVxuXG5cdHNldHVwX2NvbXBvbmVudHMoKSB7IH1cblxuXHRtYWtlX3Rvb2x0aXAoKSB7XG5cdFx0dGhpcy50aXAgPSBuZXcgZnJhcHBlLmNoYXJ0LlN2Z1RpcCh7XG5cdFx0XHRwYXJlbnQ6IHRoaXMuY2hhcnRfd3JhcHBlcixcblx0XHR9KTtcblx0XHR0aGlzLmJpbmRfdG9vbHRpcCgpO1xuXHR9XG5cblxuXHRzaG93X3N1bW1hcnkoKSB7fVxuXHRzaG93X2N1c3RvbV9zdW1tYXJ5KCkge1xuXHRcdHRoaXMuc3VtbWFyeS5tYXAoZCA9PiB7XG5cdFx0XHRsZXQgc3RhdHMgPSAkJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAnc3RhdHMnLFxuXHRcdFx0XHRpbm5lckhUTUw6IGA8c3BhbiBjbGFzcz1cImluZGljYXRvciAke2QuY29sb3J9XCI+JHtkLnRpdGxlfTogJHtkLnZhbHVlfTwvc3Bhbj5gXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuc3RhdHNfd3JhcHBlci5hcHBlbmRDaGlsZChzdGF0cyk7XG5cdFx0fSk7XG5cdH1cblxuXHRzZXR1cF9uYXZpZ2F0aW9uKGluaXQ9ZmFsc2UpIHtcblx0XHR0aGlzLm1ha2Vfb3ZlcmxheSgpO1xuXG5cdFx0aWYoaW5pdCkge1xuXHRcdFx0dGhpcy5iaW5kX292ZXJsYXkoKTtcblxuXHRcdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChlKSA9PiB7XG5cdFx0XHRcdGlmKCQkLmlzRWxlbWVudEluVmlld3BvcnQodGhpcy5jaGFydF93cmFwcGVyKSkge1xuXHRcdFx0XHRcdGUgPSBlIHx8IHdpbmRvdy5ldmVudDtcblxuXHRcdFx0XHRcdGlmIChlLmtleUNvZGUgPT0gJzM3Jykge1xuXHRcdFx0XHRcdFx0dGhpcy5vbl9sZWZ0X2Fycm93KCk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChlLmtleUNvZGUgPT0gJzM5Jykge1xuXHRcdFx0XHRcdFx0dGhpcy5vbl9yaWdodF9hcnJvdygpO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoZS5rZXlDb2RlID09ICczOCcpIHtcblx0XHRcdFx0XHRcdHRoaXMub25fdXBfYXJyb3coKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKGUua2V5Q29kZSA9PSAnNDAnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm9uX2Rvd25fYXJyb3coKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKGUua2V5Q29kZSA9PSAnMTMnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm9uX2VudGVyX2tleSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0bWFrZV9vdmVybGF5KCkge31cblx0YmluZF9vdmVybGF5KCkge31cblxuXHRvbl9sZWZ0X2Fycm93KCkge31cblx0b25fcmlnaHRfYXJyb3coKSB7fVxuXHRvbl91cF9hcnJvdygpIHt9XG5cdG9uX2Rvd25fYXJyb3coKSB7fVxuXHRvbl9lbnRlcl9rZXkoKSB7fVxuXG5cdGdldF9kYXRhX3BvaW50KGluZGV4PXRoaXMuY3VycmVudF9pbmRleCkge1xuXHRcdC8vIGNoZWNrIGZvciBsZW5ndGhcblx0XHRsZXQgZGF0YV9wb2ludCA9IHtcblx0XHRcdGluZGV4OiBpbmRleFxuXHRcdH07XG5cdFx0bGV0IHkgPSB0aGlzLnlbMF07XG5cdFx0WydzdmdfdW5pdHMnLCAneV90b3BzJywgJ3ZhbHVlcyddLm1hcChrZXkgPT4ge1xuXHRcdFx0bGV0IGRhdGFfa2V5ID0ga2V5LnNsaWNlKDAsIGtleS5sZW5ndGgtMSk7XG5cdFx0XHRkYXRhX3BvaW50W2RhdGFfa2V5XSA9IHlba2V5XVtpbmRleF07XG5cdFx0fSk7XG5cdFx0ZGF0YV9wb2ludC5sYWJlbCA9IHRoaXMueFtpbmRleF07XG5cdFx0cmV0dXJuIGRhdGFfcG9pbnQ7XG5cdH1cblxuXHR1cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KGluZGV4KSB7XG5cdFx0aWYoaW5kZXggPCAwKSBpbmRleCA9IDA7XG5cdFx0aWYoaW5kZXggPj0gdGhpcy54Lmxlbmd0aCkgaW5kZXggPSB0aGlzLngubGVuZ3RoIC0gMTtcblx0XHRpZihpbmRleCA9PT0gdGhpcy5jdXJyZW50X2luZGV4KSByZXR1cm47XG5cdFx0dGhpcy5jdXJyZW50X2luZGV4ID0gaW5kZXg7XG5cdFx0JCQuZmlyZSh0aGlzLnBhcmVudCwgXCJkYXRhLXNlbGVjdFwiLCB0aGlzLmdldF9kYXRhX3BvaW50KCkpO1xuXHR9XG5cblx0Ly8gSGVscGVyc1xuXHRnZXRfc3Ryd2lkdGgoc3RyaW5nKSB7XG5cdFx0cmV0dXJuIHN0cmluZy5sZW5ndGggKiA4O1xuXHR9XG5cblx0Ly8gT2JqZWN0c1xuXHRzZXR1cF91dGlscygpIHsgfVxufVxuXG5mcmFwcGUuY2hhcnQuQXhpc0NoYXJ0ID0gY2xhc3MgQXhpc0NoYXJ0IGV4dGVuZHMgZnJhcHBlLmNoYXJ0LkZyYXBwZUNoYXJ0IHtcblx0Y29uc3RydWN0b3IoYXJncykge1xuXHRcdHN1cGVyKGFyZ3MpO1xuXG5cdFx0dGhpcy54ID0gdGhpcy5kYXRhLmxhYmVscztcblx0XHR0aGlzLnkgPSB0aGlzLmRhdGEuZGF0YXNldHM7XG5cblx0XHR0aGlzLmdldF95X2xhYmVsID0gdGhpcy5mb3JtYXRfbGFtYmRhcy55X2xhYmVsO1xuXHRcdHRoaXMuZ2V0X3lfdG9vbHRpcCA9IHRoaXMuZm9ybWF0X2xhbWJkYXMueV90b29sdGlwO1xuXHRcdHRoaXMuZ2V0X3hfdG9vbHRpcCA9IHRoaXMuZm9ybWF0X2xhbWJkYXMueF90b29sdGlwO1xuXG5cdFx0dGhpcy5jb2xvcnMgPSBbJ2dyZWVuJywgJ2JsdWUnLCAndmlvbGV0JywgJ3JlZCcsICdvcmFuZ2UnLFxuXHRcdFx0XHQneWVsbG93JywgJ2xpZ2h0LWJsdWUnLCAnbGlnaHQtZ3JlZW4nLCAncHVycGxlJywgJ21hZ2VudGEnXTtcblxuXHRcdHRoaXMuemVyb19saW5lID0gdGhpcy5oZWlnaHQ7XG5cdH1cblxuXHRzZXR1cF92YWx1ZXMoKSB7XG5cdFx0dGhpcy5kYXRhLmRhdGFzZXRzLm1hcChkID0+IHtcblx0XHRcdGQudmFsdWVzID0gZC52YWx1ZXMubWFwKHZhbCA9PiAoIWlzTmFOKHZhbCkgPyB2YWwgOiAwKSk7XG5cdFx0fSk7XG5cdFx0dGhpcy5zZXR1cF94KCk7XG5cdFx0dGhpcy5zZXR1cF95KCk7XG5cdH1cblxuXHRzZXR1cF94KCkge1xuXHRcdHRoaXMuc2V0X2F2Z191bml0X3dpZHRoX2FuZF94X29mZnNldCgpO1xuXG5cdFx0aWYodGhpcy54X2F4aXNfcG9zaXRpb25zKSB7XG5cdFx0XHR0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zID0gIHRoaXMueF9heGlzX3Bvc2l0aW9ucy5zbGljZSgpO1xuXHRcdH1cblx0XHR0aGlzLnhfYXhpc19wb3NpdGlvbnMgPSB0aGlzLngubWFwKChkLCBpKSA9PlxuXHRcdFx0JCQuZmxvYXRfMih0aGlzLnhfb2Zmc2V0ICsgaSAqIHRoaXMuYXZnX3VuaXRfd2lkdGgpKTtcblxuXHRcdGlmKCF0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zKSB7XG5cdFx0XHR0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zID0gdGhpcy54X2F4aXNfcG9zaXRpb25zLnNsaWNlKCk7XG5cdFx0fVxuXHR9XG5cblx0c2V0dXBfeSgpIHtcblx0XHRpZih0aGlzLnlfYXhpc192YWx1ZXMpIHtcblx0XHRcdHRoaXMueV9vbGRfYXhpc192YWx1ZXMgPSAgdGhpcy55X2F4aXNfdmFsdWVzLnNsaWNlKCk7XG5cdFx0fVxuXG5cdFx0bGV0IHZhbHVlcyA9IHRoaXMuZ2V0X2FsbF95X3ZhbHVlcygpO1xuXG5cdFx0aWYodGhpcy55X3N1bXMgJiYgdGhpcy55X3N1bXMubGVuZ3RoID4gMCkge1xuXHRcdFx0dmFsdWVzID0gdmFsdWVzLmNvbmNhdCh0aGlzLnlfc3Vtcyk7XG5cdFx0fVxuXG5cdFx0dGhpcy55X2F4aXNfdmFsdWVzID0gdGhpcy5nZXRfeV9heGlzX3BvaW50cyh2YWx1ZXMpO1xuXG5cdFx0aWYoIXRoaXMueV9vbGRfYXhpc192YWx1ZXMpIHtcblx0XHRcdHRoaXMueV9vbGRfYXhpc192YWx1ZXMgPSB0aGlzLnlfYXhpc192YWx1ZXMuc2xpY2UoKTtcblx0XHR9XG5cblx0XHRjb25zdCB5X3B0cyA9IHRoaXMueV9heGlzX3ZhbHVlcztcblx0XHRjb25zdCB2YWx1ZV9yYW5nZSA9IHlfcHRzW3lfcHRzLmxlbmd0aC0xXSAtIHlfcHRzWzBdO1xuXG5cdFx0aWYodGhpcy5tdWx0aXBsaWVyKSB0aGlzLm9sZF9tdWx0aXBsaWVyID0gdGhpcy5tdWx0aXBsaWVyO1xuXHRcdHRoaXMubXVsdGlwbGllciA9IHRoaXMuaGVpZ2h0IC8gdmFsdWVfcmFuZ2U7XG5cdFx0aWYoIXRoaXMub2xkX211bHRpcGxpZXIpIHRoaXMub2xkX211bHRpcGxpZXIgPSB0aGlzLm11bHRpcGxpZXI7XG5cblx0XHRjb25zdCB6ZXJvX2luZGV4ID0geV9wdHMuaW5kZXhPZigwKTtcblx0XHRjb25zdCBpbnRlcnZhbCA9IHlfcHRzWzFdIC0geV9wdHNbMF07XG5cdFx0Y29uc3QgaW50ZXJ2YWxfaGVpZ2h0ID0gaW50ZXJ2YWwgKiB0aGlzLm11bHRpcGxpZXI7XG5cblx0XHRpZih0aGlzLnplcm9fbGluZSkgdGhpcy5vbGRfemVyb19saW5lID0gdGhpcy56ZXJvX2xpbmU7XG5cdFx0dGhpcy56ZXJvX2xpbmUgPSB0aGlzLmhlaWdodCAtICh6ZXJvX2luZGV4ICogaW50ZXJ2YWxfaGVpZ2h0KTtcblx0XHRpZighdGhpcy5vbGRfemVyb19saW5lKSB0aGlzLm9sZF96ZXJvX2xpbmUgPSB0aGlzLnplcm9fbGluZTtcblx0fVxuXG5cdHNldHVwX2NvbXBvbmVudHMoKSB7XG5cdFx0c3VwZXIuc2V0dXBfY29tcG9uZW50cygpO1xuXHRcdHRoaXMuc2V0dXBfbWFya2VyX2NvbXBvbmVudHMoKTtcblx0XHR0aGlzLnNldHVwX2FnZ3JlZ2F0aW9uX2NvbXBvbmVudHMoKTtcblx0XHR0aGlzLnNldHVwX2dyYXBoX2NvbXBvbmVudHMoKTtcblx0fVxuXG5cdHNldHVwX21hcmtlcl9jb21wb25lbnRzKCkge1xuXHRcdHRoaXMueV9heGlzX2dyb3VwID0gJCQuY3JlYXRlU1ZHKCdnJywge2NsYXNzTmFtZTogJ3kgYXhpcycsIGluc2lkZTogdGhpcy5kcmF3X2FyZWF9KTtcblx0XHR0aGlzLnhfYXhpc19ncm91cCA9ICQkLmNyZWF0ZVNWRygnZycsIHtjbGFzc05hbWU6ICd4IGF4aXMnLCBpbnNpZGU6IHRoaXMuZHJhd19hcmVhfSk7XG5cdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwID0gJCQuY3JlYXRlU1ZHKCdnJywge2NsYXNzTmFtZTogJ3NwZWNpZmljIGF4aXMnLCBpbnNpZGU6IHRoaXMuZHJhd19hcmVhfSk7XG5cdH1cblxuXHRzZXR1cF9hZ2dyZWdhdGlvbl9jb21wb25lbnRzKCkge1xuXHRcdHRoaXMuc3VtX2dyb3VwID0gJCQuY3JlYXRlU1ZHKCdnJywge2NsYXNzTmFtZTogJ2RhdGEtcG9pbnRzJywgaW5zaWRlOiB0aGlzLmRyYXdfYXJlYX0pO1xuXHRcdHRoaXMuYXZlcmFnZV9ncm91cCA9ICQkLmNyZWF0ZVNWRygnZycsIHtjbGFzc05hbWU6ICdjaGFydC1hcmVhJywgaW5zaWRlOiB0aGlzLmRyYXdfYXJlYX0pO1xuXHR9XG5cblx0c2V0dXBfZ3JhcGhfY29tcG9uZW50cygpIHtcblx0XHR0aGlzLnN2Z191bml0c19ncm91cHMgPSBbXTtcblx0XHR0aGlzLnkubWFwKChkLCBpKSA9PiB7XG5cdFx0XHR0aGlzLnN2Z191bml0c19ncm91cHNbaV0gPSAkJC5jcmVhdGVTVkcoJ2cnLCB7XG5cdFx0XHRcdGNsYXNzTmFtZTogJ2RhdGEtcG9pbnRzIGRhdGEtcG9pbnRzLScgKyBpLFxuXHRcdFx0XHRpbnNpZGU6IHRoaXMuZHJhd19hcmVhXG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfZ3JhcGhfY29tcG9uZW50cyhpbml0PWZhbHNlKSB7XG5cdFx0dGhpcy5tYWtlX3lfYXhpcygpO1xuXHRcdHRoaXMubWFrZV94X2F4aXMoKTtcblx0XHR0aGlzLmRyYXdfZ3JhcGgoaW5pdCk7XG5cdFx0dGhpcy5tYWtlX3lfc3BlY2lmaWNzKCk7XG5cdH1cblxuXHQvLyBtYWtlIFZFUlRJQ0FMIGxpbmVzIGZvciB4IHZhbHVlc1xuXHRtYWtlX3hfYXhpcyhhbmltYXRlPWZhbHNlKSB7XG5cdFx0bGV0IHN0YXJ0X2F0LCBoZWlnaHQsIHRleHRfc3RhcnRfYXQsIGF4aXNfbGluZV9jbGFzcyA9ICcnO1xuXHRcdGlmKHRoaXMueF9heGlzX21vZGUgPT09ICdzcGFuJykge1x0XHQvLyBsb25nIHNwYW5uaW5nIGxpbmVzXG5cdFx0XHRzdGFydF9hdCA9IC03O1xuXHRcdFx0aGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyAxNTtcblx0XHRcdHRleHRfc3RhcnRfYXQgPSB0aGlzLmhlaWdodCArIDI1O1xuXHRcdH0gZWxzZSBpZih0aGlzLnhfYXhpc19tb2RlID09PSAndGljaycpe1x0Ly8gc2hvcnQgbGFiZWwgbGluZXNcblx0XHRcdHN0YXJ0X2F0ID0gdGhpcy5oZWlnaHQ7XG5cdFx0XHRoZWlnaHQgPSA2O1xuXHRcdFx0dGV4dF9zdGFydF9hdCA9IDk7XG5cdFx0XHRheGlzX2xpbmVfY2xhc3MgPSAneC1heGlzLWxhYmVsJztcblx0XHR9XG5cblx0XHR0aGlzLnhfYXhpc19ncm91cC5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsIGB0cmFuc2xhdGUoMCwke3N0YXJ0X2F0fSlgKTtcblxuXHRcdGlmKGFuaW1hdGUpIHtcblx0XHRcdHRoaXMubWFrZV9hbmltX3hfYXhpcyhoZWlnaHQsIHRleHRfc3RhcnRfYXQsIGF4aXNfbGluZV9jbGFzcyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dGhpcy54X2F4aXNfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLngubWFwKChwb2ludCwgaSkgPT4ge1xuXHRcdFx0dGhpcy54X2F4aXNfZ3JvdXAuYXBwZW5kQ2hpbGQoXG5cdFx0XHRcdHRoaXMubWFrZV94X2xpbmUoXG5cdFx0XHRcdFx0aGVpZ2h0LFxuXHRcdFx0XHRcdHRleHRfc3RhcnRfYXQsXG5cdFx0XHRcdFx0cG9pbnQsXG5cdFx0XHRcdFx0J3gtdmFsdWUtdGV4dCcsXG5cdFx0XHRcdFx0YXhpc19saW5lX2NsYXNzLFxuXHRcdFx0XHRcdHRoaXMueF9heGlzX3Bvc2l0aW9uc1tpXVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0Ly8gbWFrZSBIT1JJWk9OVEFMIGxpbmVzIGZvciB5IHZhbHVlc1xuXHRtYWtlX3lfYXhpcyhhbmltYXRlPWZhbHNlKSB7XG5cdFx0aWYoYW5pbWF0ZSkge1xuXHRcdFx0dGhpcy5tYWtlX2FuaW1feV9heGlzKCk7XG5cdFx0XHR0aGlzLm1ha2VfYW5pbV95X3NwZWNpZmljcygpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGxldCBbd2lkdGgsIHRleHRfZW5kX2F0LCBheGlzX2xpbmVfY2xhc3MsIHN0YXJ0X2F0XSA9IHRoaXMuZ2V0X3lfYXhpc19saW5lX3Byb3BzKCk7XG5cblx0XHR0aGlzLnlfYXhpc19ncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdHRoaXMueV9heGlzX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHR0aGlzLnlfYXhpc19ncm91cC5hcHBlbmRDaGlsZChcblx0XHRcdFx0dGhpcy5tYWtlX3lfbGluZShcblx0XHRcdFx0XHRzdGFydF9hdCxcblx0XHRcdFx0XHR3aWR0aCxcblx0XHRcdFx0XHR0ZXh0X2VuZF9hdCxcblx0XHRcdFx0XHR2YWx1ZSxcblx0XHRcdFx0XHQneS12YWx1ZS10ZXh0Jyxcblx0XHRcdFx0XHRheGlzX2xpbmVfY2xhc3MsXG5cdFx0XHRcdFx0dGhpcy56ZXJvX2xpbmUgLSB2YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0XHQodmFsdWUgPT09IDAgJiYgaSAhPT0gMCkgLy8gTm9uLWZpcnN0IFplcm8gbGluZVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0Z2V0X3lfYXhpc19saW5lX3Byb3BzKHNwZWNpZmljPWZhbHNlKSB7XG5cdFx0aWYoc3BlY2lmaWMpIHtcblx0XHRcdHJldHVyblt0aGlzLndpZHRoLCB0aGlzLndpZHRoICsgNSwgJ3NwZWNpZmljLXZhbHVlJywgMF07XG5cdFx0fVxuXHRcdGxldCB3aWR0aCwgdGV4dF9lbmRfYXQgPSAtOSwgYXhpc19saW5lX2NsYXNzID0gJycsIHN0YXJ0X2F0ID0gMDtcblx0XHRpZih0aGlzLnlfYXhpc19tb2RlID09PSAnc3BhbicpIHtcdFx0Ly8gbG9uZyBzcGFubmluZyBsaW5lc1xuXHRcdFx0d2lkdGggPSB0aGlzLndpZHRoICsgNjtcblx0XHRcdHN0YXJ0X2F0ID0gLTY7XG5cdFx0fSBlbHNlIGlmKHRoaXMueV9heGlzX21vZGUgPT09ICd0aWNrJyl7XHQvLyBzaG9ydCBsYWJlbCBsaW5lc1xuXHRcdFx0d2lkdGggPSAtNjtcblx0XHRcdGF4aXNfbGluZV9jbGFzcyA9ICd5LWF4aXMtbGFiZWwnO1xuXHRcdH1cblxuXHRcdHJldHVybiBbd2lkdGgsIHRleHRfZW5kX2F0LCBheGlzX2xpbmVfY2xhc3MsIHN0YXJ0X2F0XTtcblx0fVxuXG5cdGRyYXdfZ3JhcGgoaW5pdD1mYWxzZSkge1xuXHRcdGlmKGluaXQpIHtcblx0XHRcdHRoaXMuZHJhd19uZXdfZ3JhcGhfYW5kX2FuaW1hdGUoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0ZC5zdmdfdW5pdHMgPSBbXTtcblx0XHRcdHRoaXMubWFrZV9wYXRoICYmIHRoaXMubWFrZV9wYXRoKGQsIGksIHRoaXMueF9heGlzX3Bvc2l0aW9ucywgZC55X3RvcHMsIGQuY29sb3IgfHwgdGhpcy5jb2xvcnNbaV0pO1xuXHRcdFx0dGhpcy5tYWtlX25ld191bml0cyhkLCBpKTtcblx0XHR9KTtcblx0fVxuXG5cdGRyYXdfbmV3X2dyYXBoX2FuZF9hbmltYXRlKCkge1xuXHRcdGxldCBkYXRhID0gW107XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0Ly8gQW5pbTogRG9uJ3QgZHJhdyBpbml0aWFsIHZhbHVlcywgc3RvcmUgdGhlbSBhbmQgdXBkYXRlIGxhdGVyXG5cdFx0XHRkLnlfdG9wcyA9IG5ldyBBcnJheShkLnZhbHVlcy5sZW5ndGgpLmZpbGwodGhpcy56ZXJvX2xpbmUpOyAvLyBubyB2YWx1ZVxuXHRcdFx0ZGF0YS5wdXNoKHt2YWx1ZXM6IGQudmFsdWVzfSk7XG5cdFx0XHRkLnN2Z191bml0cyA9IFtdO1xuXG5cdFx0XHR0aGlzLm1ha2VfcGF0aCAmJiB0aGlzLm1ha2VfcGF0aChkLCBpLCB0aGlzLnhfYXhpc19wb3NpdGlvbnMsIGQueV90b3BzLCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblx0XHRcdHRoaXMubWFrZV9uZXdfdW5pdHMoZCwgaSk7XG5cdFx0fSk7XG5cblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHRoaXMudXBkYXRlX3ZhbHVlcyhkYXRhKTtcblx0XHR9LCAzNTApO1xuXHR9XG5cblx0c2V0dXBfbmF2aWdhdGlvbihpbml0KSB7XG5cdFx0Ly8gSGFjazogZGVmZXIgbmF2IHRpbGwgaW5pdGlhbCB1cGRhdGVfdmFsdWVzXG5cdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRzdXBlci5zZXR1cF9uYXZpZ2F0aW9uKGluaXQpO1xuXHRcdH0sIDUwMCk7XG5cdH1cblxuXHRtYWtlX25ld191bml0cyhkLCBpKSB7XG5cdFx0dGhpcy5tYWtlX25ld191bml0c19mb3JfZGF0YXNldChcblx0XHRcdHRoaXMueF9heGlzX3Bvc2l0aW9ucyxcblx0XHRcdGQueV90b3BzLFxuXHRcdFx0ZC5jb2xvciB8fCB0aGlzLmNvbG9yc1tpXSxcblx0XHRcdGksXG5cdFx0XHR0aGlzLnkubGVuZ3RoXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfbmV3X3VuaXRzX2Zvcl9kYXRhc2V0KHhfdmFsdWVzLCB5X3ZhbHVlcywgY29sb3IsIGRhdGFzZXRfaW5kZXgsIG5vX29mX2RhdGFzZXRzLCBncm91cCwgYXJyYXksIHVuaXQpIHtcblx0XHRpZighZ3JvdXApIGdyb3VwID0gdGhpcy5zdmdfdW5pdHNfZ3JvdXBzW2RhdGFzZXRfaW5kZXhdO1xuXHRcdGlmKCFhcnJheSkgYXJyYXkgPSB0aGlzLnlbZGF0YXNldF9pbmRleF0uc3ZnX3VuaXRzO1xuXHRcdGlmKCF1bml0KSB1bml0ID0gdGhpcy51bml0X2FyZ3M7XG5cblx0XHRncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdGFycmF5Lmxlbmd0aCA9IDA7XG5cblx0XHR5X3ZhbHVlcy5tYXAoKHksIGkpID0+IHtcblx0XHRcdGxldCBkYXRhX3VuaXQgPSB0aGlzLmRyYXdbdW5pdC50eXBlXShcblx0XHRcdFx0eF92YWx1ZXNbaV0sXG5cdFx0XHRcdHksXG5cdFx0XHRcdHVuaXQuYXJncyxcblx0XHRcdFx0Y29sb3IsXG5cdFx0XHRcdGRhdGFzZXRfaW5kZXgsXG5cdFx0XHRcdG5vX29mX2RhdGFzZXRzXG5cdFx0XHQpO1xuXHRcdFx0Z3JvdXAuYXBwZW5kQ2hpbGQoZGF0YV91bml0KTtcblx0XHRcdGFycmF5LnB1c2goZGF0YV91bml0KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfeV9zcGVjaWZpY3MoKSB7XG5cdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLnRleHRDb250ZW50ID0gJyc7XG5cdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMubWFwKGQgPT4ge1xuXHRcdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLmFwcGVuZENoaWxkKFxuXHRcdFx0XHR0aGlzLm1ha2VfeV9saW5lKFxuXHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0dGhpcy53aWR0aCxcblx0XHRcdFx0XHR0aGlzLndpZHRoICsgNSxcblx0XHRcdFx0XHRkLnRpdGxlLnRvVXBwZXJDYXNlKCksXG5cdFx0XHRcdFx0J3NwZWNpZmljLXZhbHVlJyxcblx0XHRcdFx0XHQnc3BlY2lmaWMtdmFsdWUnLFxuXHRcdFx0XHRcdHRoaXMuemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0XHRmYWxzZSxcblx0XHRcdFx0XHRkLmxpbmVfdHlwZVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0YmluZF90b29sdGlwKCkge1xuXHRcdC8vIFRPRE86IGNvdWxkIGJlIGluIHRvb2x0aXAgaXRzZWxmLCBhcyBpdCBpcyBhIGdpdmVuIGZ1bmN0aW9uYWxpdHkgZm9yIGl0cyBwYXJlbnRcblx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGUpID0+IHtcblx0XHRcdGxldCBvZmZzZXQgPSAkJC5vZmZzZXQodGhpcy5jaGFydF93cmFwcGVyKTtcblx0XHRcdGxldCByZWxYID0gZS5wYWdlWCAtIG9mZnNldC5sZWZ0IC0gdGhpcy50cmFuc2xhdGVfeDtcblx0XHRcdGxldCByZWxZID0gZS5wYWdlWSAtIG9mZnNldC50b3AgLSB0aGlzLnRyYW5zbGF0ZV95O1xuXG5cdFx0XHRpZihyZWxZIDwgdGhpcy5oZWlnaHQgKyB0aGlzLnRyYW5zbGF0ZV95ICogMikge1xuXHRcdFx0XHR0aGlzLm1hcF90b29sdGlwX3hfcG9zaXRpb25fYW5kX3Nob3cocmVsWCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLnRpcC5oaWRlX3RpcCgpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0bWFwX3Rvb2x0aXBfeF9wb3NpdGlvbl9hbmRfc2hvdyhyZWxYKSB7XG5cdFx0Zm9yKHZhciBpPXRoaXMueF9heGlzX3Bvc2l0aW9ucy5sZW5ndGggLSAxOyBpID49IDAgOyBpLS0pIHtcblx0XHRcdGxldCB4X3ZhbCA9IHRoaXMueF9heGlzX3Bvc2l0aW9uc1tpXTtcblx0XHRcdC8vIGxldCBkZWx0YSA9IGkgPT09IDAgPyB0aGlzLmF2Z191bml0X3dpZHRoIDogeF92YWwgLSB0aGlzLnhfYXhpc19wb3NpdGlvbnNbaS0xXTtcblx0XHRcdGlmKHJlbFggPiB4X3ZhbCAtIHRoaXMuYXZnX3VuaXRfd2lkdGgvMikge1xuXHRcdFx0XHRsZXQgeCA9IHhfdmFsICsgdGhpcy50cmFuc2xhdGVfeDtcblx0XHRcdFx0bGV0IHkgPSB0aGlzLnlfbWluX3RvcHNbaV0gKyB0aGlzLnRyYW5zbGF0ZV95O1xuXG5cdFx0XHRcdGxldCB0aXRsZSA9IHRoaXMueC5mb3JtYXR0ZWQgJiYgdGhpcy54LmZvcm1hdHRlZC5sZW5ndGg+MFxuXHRcdFx0XHRcdD8gdGhpcy54LmZvcm1hdHRlZFtpXSA6IHRoaXMueFtpXTtcblx0XHRcdFx0bGV0IHZhbHVlcyA9IHRoaXMueS5tYXAoKHNldCwgaikgPT4ge1xuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHR0aXRsZTogc2V0LnRpdGxlLFxuXHRcdFx0XHRcdFx0dmFsdWU6IHNldC5mb3JtYXR0ZWQgPyBzZXQuZm9ybWF0dGVkW2ldIDogc2V0LnZhbHVlc1tpXSxcblx0XHRcdFx0XHRcdGNvbG9yOiBzZXQuY29sb3IgfHwgdGhpcy5jb2xvcnNbal0sXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHQvLyBUT0RPOiB1cHNpZGUtZG93biB0b29sdGlwcyBmb3IgbmVnYXRpdmUgdmFsdWVzP1xuXHRcdFx0XHR0aGlzLnRpcC5zZXRfdmFsdWVzKHgsIHksIHRpdGxlLCAnJywgdmFsdWVzKTtcblx0XHRcdFx0dGhpcy50aXAuc2hvd190aXAoKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQVBJXG5cdHNob3dfc3VtcygpIHtcblx0XHR0aGlzLnVwZGF0aW5nID0gdHJ1ZTtcblxuXHRcdHRoaXMueV9zdW1zID0gbmV3IEFycmF5KHRoaXMueF9heGlzX3Bvc2l0aW9ucy5sZW5ndGgpLmZpbGwoMCk7XG5cdFx0dGhpcy55Lm1hcChkID0+IHtcblx0XHRcdGQudmFsdWVzLm1hcCggKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRcdHRoaXMueV9zdW1zW2ldICs9IHZhbHVlO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHQvLyBSZW1ha2UgeSBheGlzLCBhbmltYXRlXG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKCk7XG5cblx0XHQvLyBUaGVuIG1ha2Ugc3VtIHVuaXRzLCBkb24ndCBhbmltYXRlXG5cdFx0dGhpcy5zdW1fdW5pdHMgPSBbXTtcblxuXHRcdHRoaXMubWFrZV9uZXdfdW5pdHNfZm9yX2RhdGFzZXQoXG5cdFx0XHR0aGlzLnhfYXhpc19wb3NpdGlvbnMsXG5cdFx0XHR0aGlzLnlfc3Vtcy5tYXAoIHZhbCA9PiAkJC5mbG9hdF8yKHRoaXMuemVyb19saW5lIC0gdmFsICogdGhpcy5tdWx0aXBsaWVyKSksXG5cdFx0XHQnbGlnaHQtZ3JleScsXG5cdFx0XHQwLFxuXHRcdFx0MSxcblx0XHRcdHRoaXMuc3VtX2dyb3VwLFxuXHRcdFx0dGhpcy5zdW1fdW5pdHNcblx0XHQpO1xuXG5cdFx0Ly8gdGhpcy5tYWtlX3BhdGggJiYgdGhpcy5tYWtlX3BhdGgoZCwgaSwgb2xkX3gsIG9sZF95LCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblxuXHRcdHRoaXMudXBkYXRpbmcgPSBmYWxzZTtcblx0fVxuXG5cdGhpZGVfc3VtcygpIHtcblx0XHRpZih0aGlzLnVwZGF0aW5nKSByZXR1cm47XG5cdFx0dGhpcy55X3N1bXMgPSBbXTtcblx0XHR0aGlzLnN1bV9ncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdHRoaXMuc3VtX3VuaXRzID0gW107XG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKCk7XG5cdH1cblxuXHRzaG93X2F2ZXJhZ2UoKSB7XG5cdFx0dGhpcy5vbGRfc3BlY2lmaWNfdmFsdWVzID0gdGhpcy5zcGVjaWZpY192YWx1ZXMuc2xpY2UoKTtcblx0XHR0aGlzLnkubWFwKChkLCBpKSA9PiB7XG5cdFx0XHRsZXQgc3VtID0gMDtcblx0XHRcdGQudmFsdWVzLm1hcChlID0+IHtzdW0rPWV9KTtcblx0XHRcdGxldCBhdmVyYWdlID0gc3VtL2QudmFsdWVzLmxlbmd0aDtcblxuXHRcdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMucHVzaCh7XG5cdFx0XHRcdHRpdGxlOiBcIkFWR1wiICsgXCIgXCIgKyAoaSsxKSxcblx0XHRcdFx0bGluZV90eXBlOiBcImRhc2hlZFwiLFxuXHRcdFx0XHR2YWx1ZTogYXZlcmFnZSxcblx0XHRcdFx0YXV0bzogMVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHRjb25zb2xlLmxvZyh0aGlzLnNwZWNpZmljX3ZhbHVlcyk7XG5cblx0XHR0aGlzLnVwZGF0ZV92YWx1ZXMoKTtcblx0fVxuXG5cdGhpZGVfYXZlcmFnZSgpIHtcblx0XHR0aGlzLm9sZF9zcGVjaWZpY192YWx1ZXMgPSB0aGlzLnNwZWNpZmljX3ZhbHVlcy5zbGljZSgpO1xuXG5cdFx0bGV0IGluZGljZXNfdG9fcmVtb3ZlID0gW107XG5cdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMubWFwKChkLCBpKSA9PiB7XG5cdFx0XHRpZihkLmF1dG8pIGluZGljZXNfdG9fcmVtb3ZlLnVuc2hpZnQoaSk7XG5cdFx0fSk7XG5cblx0XHRjb25zb2xlLmxvZyhpbmRpY2VzX3RvX3JlbW92ZSk7XG5cblx0XHRpbmRpY2VzX3RvX3JlbW92ZS5tYXAoaW5kZXggPT4ge1xuXHRcdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMuc3BsaWNlKGluZGV4LCAxKTtcblx0XHR9KTtcblxuXHRcdGNvbnNvbGUubG9nKHRoaXMuc3BlY2lmaWNfdmFsdWVzKTtcblxuXHRcdHRoaXMudXBkYXRlX3ZhbHVlcygpO1xuXHR9XG5cblx0dXBkYXRlX3ZhbHVlcyhuZXdfeSwgbmV3X3gpIHtcblx0XHRpZighbmV3X3gpIHtcblx0XHRcdG5ld194ID0gdGhpcy54O1xuXHRcdH1cblx0XHR0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUgPSBbXTtcblx0XHR0aGlzLnVwZGF0aW5nID0gdHJ1ZTtcblxuXHRcdHRoaXMub2xkX3hfdmFsdWVzID0gdGhpcy54LnNsaWNlKCk7XG5cdFx0dGhpcy5vbGRfeV9heGlzX3RvcHMgPSB0aGlzLnkubWFwKGQgPT4gZC55X3RvcHMuc2xpY2UoKSk7XG5cblx0XHR0aGlzLm9sZF95X3ZhbHVlcyA9IHRoaXMueS5tYXAoZCA9PiBkLnZhbHVlcyk7XG5cblx0XHR0aGlzLm5vX29mX2V4dHJhX3B0cyA9IG5ld194Lmxlbmd0aCAtIHRoaXMueC5sZW5ndGg7XG5cblx0XHQvLyBKdXN0IHVwZGF0ZSB2YWx1ZXMgcHJvcCwgc2V0dXBfeC95KCkgd2lsbCBkbyB0aGUgcmVzdFxuXHRcdGlmKG5ld195KSB0aGlzLnkubWFwKChkLCBpKSA9PiB7ZC52YWx1ZXMgPSBuZXdfeVtpXS52YWx1ZXM7fSk7XG5cdFx0aWYobmV3X3gpIHRoaXMueCA9IG5ld194O1xuXG5cdFx0dGhpcy5zZXR1cF94KCk7XG5cdFx0dGhpcy5zZXR1cF95KCk7XG5cblx0XHQvLyBBbmltYXRlIG9ubHkgaWYgcG9zaXRpb25zIGhhdmUgY2hhbmdlZFxuXHRcdGlmKCEkJC5hcnJheXNfZXF1YWwodGhpcy54X29sZF9heGlzX3Bvc2l0aW9ucywgdGhpcy54X2F4aXNfcG9zaXRpb25zKSkge1xuXHRcdFx0dGhpcy5tYWtlX3hfYXhpcyh0cnVlKTtcblx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRpZighdGhpcy51cGRhdGluZykgdGhpcy5tYWtlX3hfYXhpcygpO1xuXHRcdFx0fSwgMzAwKVxuXHRcdH1cblxuXHRcdGlmKCEkJC5hcnJheXNfZXF1YWwodGhpcy55X29sZF9heGlzX3ZhbHVlcywgdGhpcy55X2F4aXNfdmFsdWVzKSB8fFxuXHRcdFx0KHRoaXMub2xkX3NwZWNpZmljX3ZhbHVlcyAmJlxuXHRcdFx0ISQkLmFycmF5c19lcXVhbCh0aGlzLm9sZF9zcGVjaWZpY192YWx1ZXMsIHRoaXMuc3BlY2lmaWNfdmFsdWVzKSkpIHtcblxuXHRcdFx0dGhpcy5tYWtlX3lfYXhpcyh0cnVlKTtcblx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRpZighdGhpcy51cGRhdGluZykge1xuXHRcdFx0XHRcdHRoaXMubWFrZV95X2F4aXMoKTtcblx0XHRcdFx0XHR0aGlzLm1ha2VfeV9zcGVjaWZpY3MoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSwgMzAwKVxuXHRcdH1cblxuXHRcdC8vIENoYW5nZSBpbiBkYXRhLCBzbyBjYWxjdWxhdGUgZGVwZW5kZW5jaWVzXG5cdFx0dGhpcy5jYWxjX3lfZGVwZW5kZW5jaWVzKCk7XG5cblx0XHR0aGlzLmFuaW1hdGVfZ3JhcGhzKCk7XG5cblx0XHQvLyBUcmlnZ2VyIGFuaW1hdGlvbiB3aXRoIHRoZSBhbmltYXRhYmxlIGVsZW1lbnRzIGluIHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZVxuXHRcdHRoaXMucnVuX2FuaW1hdGlvbigpO1xuXG5cdFx0dGhpcy51cGRhdGluZyA9IGZhbHNlO1xuXHR9XG5cblx0YWRkX2RhdGFfcG9pbnQoeV9wb2ludCwgeF9wb2ludCwgaW5kZXg9dGhpcy54Lmxlbmd0aCkge1xuXHRcdGxldCBuZXdfeSA9IHRoaXMueS5tYXAoZGF0YV9zZXQgPT4geyByZXR1cm4ge3ZhbHVlczpkYXRhX3NldC52YWx1ZXN9OyB9KTtcblx0XHRuZXdfeS5tYXAoKGQsIGkpID0+IHsgZC52YWx1ZXMuc3BsaWNlKGluZGV4LCAwLCB5X3BvaW50W2ldKTsgfSk7XG5cdFx0bGV0IG5ld194ID0gdGhpcy54LnNsaWNlKCk7XG5cdFx0bmV3X3guc3BsaWNlKGluZGV4LCAwLCB4X3BvaW50KTtcblxuXHRcdHRoaXMudXBkYXRlX3ZhbHVlcyhuZXdfeSwgbmV3X3gpO1xuXHR9XG5cblx0cmVtb3ZlX2RhdGFfcG9pbnQoaW5kZXggPSB0aGlzLngubGVuZ3RoLTEpIHtcblx0XHRpZih0aGlzLngubGVuZ3RoIDwgMykgcmV0dXJuO1xuXG5cdFx0bGV0IG5ld195ID0gdGhpcy55Lm1hcChkYXRhX3NldCA9PiB7IHJldHVybiB7dmFsdWVzOmRhdGFfc2V0LnZhbHVlc307IH0pO1xuXHRcdG5ld195Lm1hcCgoZCwgaSkgPT4geyBkLnZhbHVlcy5zcGxpY2UoaW5kZXgsIDEpOyB9KTtcblx0XHRsZXQgbmV3X3ggPSB0aGlzLnguc2xpY2UoKTtcblx0XHRuZXdfeC5zcGxpY2UoaW5kZXgsIDEpO1xuXG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKG5ld195LCBuZXdfeCk7XG5cdH1cblxuXHRydW5fYW5pbWF0aW9uKCkge1xuXHRcdGxldCBhbmltX3N2ZyA9ICQkLnJ1blNWR0FuaW1hdGlvbih0aGlzLnN2ZywgdGhpcy5lbGVtZW50c190b19hbmltYXRlKTtcblxuXHRcdGlmKHRoaXMuc3ZnLnBhcmVudE5vZGUgPT0gdGhpcy5jaGFydF93cmFwcGVyKSB7XG5cdFx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIucmVtb3ZlQ2hpbGQodGhpcy5zdmcpO1xuXHRcdFx0dGhpcy5jaGFydF93cmFwcGVyLmFwcGVuZENoaWxkKGFuaW1fc3ZnKTtcblxuXHRcdH1cblxuXHRcdC8vIFJlcGxhY2UgdGhlIG5ldyBzdmcgKGRhdGEgaGFzIGxvbmcgYmVlbiByZXBsYWNlZClcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdGlmKGFuaW1fc3ZnLnBhcmVudE5vZGUgPT0gdGhpcy5jaGFydF93cmFwcGVyKSB7XG5cdFx0XHRcdHRoaXMuY2hhcnRfd3JhcHBlci5yZW1vdmVDaGlsZChhbmltX3N2Zyk7XG5cdFx0XHRcdHRoaXMuY2hhcnRfd3JhcHBlci5hcHBlbmRDaGlsZCh0aGlzLnN2Zyk7XG5cdFx0XHR9XG5cdFx0fSwgMjAwKTtcblx0fVxuXG5cdGFuaW1hdGVfZ3JhcGhzKCkge1xuXHRcdHRoaXMueS5tYXAoKGQsIGkpID0+IHtcblx0XHRcdC8vIFByZS1wcmVwLCBlcXVpbGl6ZSBubyBvZiBwb3NpdGlvbnMgYmV0d2VlbiBvbGQgYW5kIG5ld1xuXHRcdFx0bGV0IFtvbGRfeCwgb2xkX3ksIG5ld194LCBuZXdfeV0gPSB0aGlzLmNhbGNfb2xkX2FuZF9uZXdfcG9zdGlvbnMoZCwgaSk7XG5cdFx0XHRpZih0aGlzLm5vX29mX2V4dHJhX3B0cyA+PSAwKSB7XG5cdFx0XHRcdHRoaXMubWFrZV9wYXRoICYmIHRoaXMubWFrZV9wYXRoKGQsIGksIG9sZF94LCBvbGRfeSwgZC5jb2xvciB8fCB0aGlzLmNvbG9yc1tpXSk7XG5cdFx0XHRcdHRoaXMubWFrZV9uZXdfdW5pdHNfZm9yX2RhdGFzZXQob2xkX3gsIG9sZF95LCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldLCBpLCB0aGlzLnkubGVuZ3RoKTtcblx0XHRcdH1cblx0XHRcdGQucGF0aCAmJiB0aGlzLmFuaW1hdGVfcGF0aChkLCBpLCBvbGRfeCwgb2xkX3ksIG5ld194LCBuZXdfeSk7XG5cdFx0XHR0aGlzLmFuaW1hdGVfdW5pdHMoZCwgaSwgb2xkX3gsIG9sZF95LCBuZXdfeCwgbmV3X3kpO1xuXHRcdH0pO1xuXG5cdFx0Ly8gVE9ETzogcmVwbGFjZSB3aXRoIHJlYWwgdW5pdHNcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHRoaXMueS5tYXAoKGQsIGkpID0+IHtcblx0XHRcdFx0dGhpcy5tYWtlX3BhdGggJiYgdGhpcy5tYWtlX3BhdGgoZCwgaSwgdGhpcy54X2F4aXNfcG9zaXRpb25zLCBkLnlfdG9wcywgZC5jb2xvciB8fCB0aGlzLmNvbG9yc1tpXSk7XG5cdFx0XHRcdHRoaXMubWFrZV9uZXdfdW5pdHMoZCwgaSk7XG5cdFx0XHR9KTtcblx0XHR9LCAzMDApO1xuXHR9XG5cblx0YW5pbWF0ZV9wYXRoKGQsIGksIG9sZF94LCBvbGRfeSwgbmV3X3gsIG5ld195KSB7XG5cdFx0Ly8gQW5pbWF0ZSBwYXRoXG5cdFx0Y29uc3QgbmV3X3BvaW50c19saXN0ID0gbmV3X3kubWFwKCh5LCBpKSA9PiAobmV3X3hbaV0gKyAnLCcgKyB5KSk7XG5cdFx0Y29uc3QgbmV3X3BhdGhfc3RyID0gbmV3X3BvaW50c19saXN0LmpvaW4oXCJMXCIpO1xuXG5cdFx0Y29uc3QgcGF0aF9hcmdzID0gW3t1bml0OiBkLnBhdGgsIG9iamVjdDogZCwga2V5OiAncGF0aCd9LCB7ZDpcIk1cIituZXdfcGF0aF9zdHJ9LCAyNTAsIFwiZWFzZWluXCJdO1xuXHRcdHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZS5wdXNoKHBhdGhfYXJncyk7XG5cblx0XHQvLyBBbmltYXRlIHJlZ2lvblxuXHRcdGlmKGQucmVnaW9uX3BhdGgpIHtcblx0XHRcdGxldCByZWdfc3RhcnRfcHQgPSBgMCwke3RoaXMuemVyb19saW5lfUxgO1xuXHRcdFx0bGV0IHJlZ19lbmRfcHQgPSBgTCR7dGhpcy53aWR0aH0sJHt0aGlzLnplcm9fbGluZX1gO1xuXG5cdFx0XHRjb25zdCByZWdpb25fYXJncyA9IFtcblx0XHRcdFx0e3VuaXQ6IGQucmVnaW9uX3BhdGgsIG9iamVjdDogZCwga2V5OiAncmVnaW9uX3BhdGgnfSxcblx0XHRcdFx0e2Q6XCJNXCIgKyByZWdfc3RhcnRfcHQgKyBuZXdfcGF0aF9zdHIgKyByZWdfZW5kX3B0fSxcblx0XHRcdFx0MjUwLFxuXHRcdFx0XHRcImVhc2VpblwiXG5cdFx0XHRdO1xuXHRcdFx0dGhpcy5lbGVtZW50c190b19hbmltYXRlLnB1c2gocmVnaW9uX2FyZ3MpO1xuXHRcdH1cblx0fVxuXG5cdGFuaW1hdGVfdW5pdHMoZCwgaW5kZXgsIG9sZF94LCBvbGRfeSwgbmV3X3gsIG5ld195KSB7XG5cdFx0bGV0IHR5cGUgPSB0aGlzLnVuaXRfYXJncy50eXBlO1xuXG5cdFx0ZC5zdmdfdW5pdHMubWFwKCh1bml0LCBpKSA9PiB7XG5cdFx0XHR0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUucHVzaCh0aGlzLmFuaW1hdGVbdHlwZV0oXG5cdFx0XHRcdHt1bml0OnVuaXQsIGFycmF5OmQuc3ZnX3VuaXRzLCBpbmRleDogaX0sIC8vIHVuaXQsIHdpdGggaW5mbyB0byByZXBsYWNlIHdoZXJlIGl0IGNhbWUgZnJvbSBpbiB0aGUgZGF0YVxuXHRcdFx0XHRuZXdfeFtpXSxcblx0XHRcdFx0bmV3X3lbaV0sXG5cdFx0XHRcdGluZGV4XG5cdFx0XHQpKTtcblx0XHR9KTtcblx0fVxuXG5cdGNhbGNfb2xkX2FuZF9uZXdfcG9zdGlvbnMoZCwgaSkge1xuXHRcdGxldCBvbGRfeCA9IHRoaXMueF9vbGRfYXhpc19wb3NpdGlvbnMuc2xpY2UoKTtcblx0XHRsZXQgbmV3X3ggPSB0aGlzLnhfYXhpc19wb3NpdGlvbnMuc2xpY2UoKTtcblxuXHRcdGxldCBvbGRfeSA9IHRoaXMub2xkX3lfYXhpc190b3BzW2ldLnNsaWNlKCk7XG5cdFx0bGV0IG5ld195ID0gZC55X3RvcHMuc2xpY2UoKTtcblxuXHRcdGNvbnN0IGxhc3Rfb2xkX3hfcG9zID0gb2xkX3hbb2xkX3gubGVuZ3RoIC0gMV07XG5cdFx0Y29uc3QgbGFzdF9vbGRfeV9wb3MgPSBvbGRfeVtvbGRfeS5sZW5ndGggLSAxXTtcblxuXHRcdGNvbnN0IGxhc3RfbmV3X3hfcG9zID0gbmV3X3hbbmV3X3gubGVuZ3RoIC0gMV07XG5cdFx0Y29uc3QgbGFzdF9uZXdfeV9wb3MgPSBuZXdfeVtuZXdfeS5sZW5ndGggLSAxXTtcblxuXHRcdGlmKHRoaXMubm9fb2ZfZXh0cmFfcHRzID49IDApIHtcblx0XHRcdC8vIEZpcnN0IHN1YnN0aXR1dGUgY3VycmVudCBwYXRoIHdpdGggYSBzcXVpZ2dsZWQgb25lIChsb29raW5nIHRoZSBzYW1lIGJ1dFxuXHRcdFx0Ly8gaGF2aW5nIG1vcmUgcG9pbnRzIGF0IGVuZCksXG5cdFx0XHQvLyB0aGVuIGFuaW1hdGUgdG8gc3RyZXRjaCBpdCBsYXRlciB0byBuZXcgcG9pbnRzXG5cdFx0XHQvLyAobmV3IHBvaW50cyBhbHJlYWR5IGhhdmUgbW9yZSBwb2ludHMpXG5cblx0XHRcdC8vIEhlbmNlLCB0aGUgZXh0cmEgZW5kIHBvaW50cyB3aWxsIGNvcnJlc3BvbmQgdG8gY3VycmVudChvbGQpIHBvc2l0aW9uc1xuXHRcdFx0bGV0IGZpbGxlcl94ID0gbmV3IEFycmF5KE1hdGguYWJzKHRoaXMubm9fb2ZfZXh0cmFfcHRzKSkuZmlsbChsYXN0X29sZF94X3Bvcyk7XG5cdFx0XHRsZXQgZmlsbGVyX3kgPSBuZXcgQXJyYXkoTWF0aC5hYnModGhpcy5ub19vZl9leHRyYV9wdHMpKS5maWxsKGxhc3Rfb2xkX3lfcG9zKTtcblxuXHRcdFx0b2xkX3ggPSBvbGRfeC5jb25jYXQoZmlsbGVyX3gpO1xuXHRcdFx0b2xkX3kgPSBvbGRfeS5jb25jYXQoZmlsbGVyX3kpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEp1c3QgbW9kaWZ5IHRoZSBuZXcgcG9pbnRzIHRvIGhhdmUgZXh0cmEgcG9pbnRzXG5cdFx0XHQvLyB3aXRoIHRoZSBzYW1lIHBvc2l0aW9uIGF0IGVuZFxuXHRcdFx0bGV0IGZpbGxlcl94ID0gbmV3IEFycmF5KE1hdGguYWJzKHRoaXMubm9fb2ZfZXh0cmFfcHRzKSkuZmlsbChsYXN0X25ld194X3Bvcyk7XG5cdFx0XHRsZXQgZmlsbGVyX3kgPSBuZXcgQXJyYXkoTWF0aC5hYnModGhpcy5ub19vZl9leHRyYV9wdHMpKS5maWxsKGxhc3RfbmV3X3lfcG9zKTtcblxuXHRcdFx0bmV3X3ggPSBuZXdfeC5jb25jYXQoZmlsbGVyX3gpO1xuXHRcdFx0bmV3X3kgPSBuZXdfeS5jb25jYXQoZmlsbGVyX3kpO1xuXHRcdH1cblxuXHRcdHJldHVybiBbb2xkX3gsIG9sZF95LCBuZXdfeCwgbmV3X3ldO1xuXHR9XG5cblx0bWFrZV9hbmltX3hfYXhpcyhoZWlnaHQsIHRleHRfc3RhcnRfYXQsIGF4aXNfbGluZV9jbGFzcykge1xuXHRcdC8vIEFuaW1hdGUgWCBBWElTIHRvIGFjY291bnQgZm9yIG1vcmUgb3IgbGVzcyBheGlzIGxpbmVzXG5cblx0XHRjb25zdCBvbGRfcG9zID0gdGhpcy54X29sZF9heGlzX3Bvc2l0aW9ucztcblx0XHRjb25zdCBuZXdfcG9zID0gdGhpcy54X2F4aXNfcG9zaXRpb25zO1xuXG5cdFx0Y29uc3Qgb2xkX3ZhbHMgPSB0aGlzLm9sZF94X3ZhbHVlcztcblx0XHRjb25zdCBuZXdfdmFscyA9IHRoaXMueDtcblxuXHRcdGNvbnN0IGxhc3RfbGluZV9wb3MgPSBvbGRfcG9zW29sZF9wb3MubGVuZ3RoIC0gMV07XG5cblx0XHRsZXQgYWRkX2FuZF9hbmltYXRlX2xpbmUgPSAodmFsdWUsIG9sZF9wb3MsIG5ld19wb3MsIGkpID0+IHtcblx0XHRcdGNvbnN0IHhfbGluZSA9IHRoaXMubWFrZV94X2xpbmUoXG5cdFx0XHRcdGhlaWdodCxcblx0XHRcdFx0dGV4dF9zdGFydF9hdCxcblx0XHRcdFx0dmFsdWUsIC8vIG5ldyB2YWx1ZVxuXHRcdFx0XHQneC12YWx1ZS10ZXh0Jyxcblx0XHRcdFx0YXhpc19saW5lX2NsYXNzLFxuXHRcdFx0XHRvbGRfcG9zIC8vIG9sZCBwb3NpdGlvblxuXHRcdFx0KTtcblx0XHRcdHRoaXMueF9heGlzX2dyb3VwLmFwcGVuZENoaWxkKHhfbGluZSk7XG5cblx0XHRcdHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZSAmJiB0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUucHVzaChbXG5cdFx0XHRcdHt1bml0OiB4X2xpbmUsIGFycmF5OiBbMF0sIGluZGV4OiAwfSxcblx0XHRcdFx0e3RyYW5zZm9ybTogYCR7IG5ld19wb3MgfSwgMGB9LFxuXHRcdFx0XHQyNTAsXG5cdFx0XHRcdFwiZWFzZWluXCIsXG5cdFx0XHRcdFwidHJhbnNsYXRlXCIsXG5cdFx0XHRcdHt0cmFuc2Zvcm06IGAkeyBvbGRfcG9zIH0sIDBgfVxuXHRcdFx0XSk7XG5cdFx0fVxuXG5cdFx0dGhpcy54X2F4aXNfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblxuXHRcdHRoaXMubWFrZV9uZXdfYXhpc19hbmltX2xpbmVzKFxuXHRcdFx0b2xkX3Bvcyxcblx0XHRcdG5ld19wb3MsXG5cdFx0XHRvbGRfdmFscyxcblx0XHRcdG5ld192YWxzLFxuXHRcdFx0bGFzdF9saW5lX3Bvcyxcblx0XHRcdGFkZF9hbmRfYW5pbWF0ZV9saW5lXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfYW5pbV95X2F4aXMoKSB7XG5cdFx0Ly8gQW5pbWF0ZSBZIEFYSVMgdG8gYWNjb3VudCBmb3IgbW9yZSBvciBsZXNzIGF4aXMgbGluZXNcblxuXHRcdGNvbnN0IG9sZF9wb3MgPSB0aGlzLnlfb2xkX2F4aXNfdmFsdWVzLm1hcCh2YWx1ZSA9PlxuXHRcdFx0dGhpcy56ZXJvX2xpbmUgLSB2YWx1ZSAqIHRoaXMubXVsdGlwbGllcik7XG5cdFx0Y29uc3QgbmV3X3BvcyA9IHRoaXMueV9heGlzX3ZhbHVlcy5tYXAodmFsdWUgPT5cblx0XHRcdHRoaXMuemVyb19saW5lIC0gdmFsdWUgKiB0aGlzLm11bHRpcGxpZXIpO1xuXG5cdFx0Y29uc3Qgb2xkX3ZhbHMgPSB0aGlzLnlfb2xkX2F4aXNfdmFsdWVzO1xuXHRcdGNvbnN0IG5ld192YWxzID0gdGhpcy55X2F4aXNfdmFsdWVzO1xuXG5cdFx0Y29uc3QgbGFzdF9saW5lX3BvcyA9IG9sZF9wb3Nbb2xkX3Bvcy5sZW5ndGggLSAxXTtcblxuXHRcdHRoaXMueV9heGlzX2dyb3VwLnRleHRDb250ZW50ID0gJyc7XG5cblx0XHR0aGlzLm1ha2VfbmV3X2F4aXNfYW5pbV9saW5lcyhcblx0XHRcdG9sZF9wb3MsXG5cdFx0XHRuZXdfcG9zLFxuXHRcdFx0b2xkX3ZhbHMsXG5cdFx0XHRuZXdfdmFscyxcblx0XHRcdGxhc3RfbGluZV9wb3MsXG5cdFx0XHR0aGlzLmFkZF9hbmRfYW5pbWF0ZV95X2xpbmUuYmluZCh0aGlzKSxcblx0XHRcdHRoaXMueV9heGlzX2dyb3VwXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfYW5pbV95X3NwZWNpZmljcygpIHtcblx0XHR0aGlzLnNwZWNpZmljX3lfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLnNwZWNpZmljX3ZhbHVlcy5tYXAoKGQsIGkpID0+IHtcblx0XHRcdHRoaXMuYWRkX2FuZF9hbmltYXRlX3lfbGluZShcblx0XHRcdFx0ZC50aXRsZSxcblx0XHRcdFx0dGhpcy5vbGRfemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMub2xkX211bHRpcGxpZXIsXG5cdFx0XHRcdHRoaXMuemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0MCxcblx0XHRcdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLFxuXHRcdFx0XHRkLmxpbmVfdHlwZSxcblx0XHRcdFx0dHJ1ZVxuXHRcdFx0KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfbmV3X2F4aXNfYW5pbV9saW5lcyhvbGRfcG9zLCBuZXdfcG9zLCBvbGRfdmFscywgbmV3X3ZhbHMsIGxhc3RfbGluZV9wb3MsIGFkZF9hbmRfYW5pbWF0ZV9saW5lLCBncm91cCkge1xuXHRcdGxldCBzdXBlcmltcG9zZWRfcG9zaXRpb25zLCBzdXBlcmltcG9zZWRfdmFsdWVzO1xuXHRcdGxldCBub19vZl9leHRyYXMgPSBuZXdfdmFscy5sZW5ndGggLSBvbGRfdmFscy5sZW5ndGg7XG5cdFx0aWYobm9fb2ZfZXh0cmFzID4gMCkge1xuXHRcdFx0Ly8gTW9yZSBheGlzIGFyZSBuZWVkZWRcblx0XHRcdC8vIEZpcnN0IG1ha2Ugb25seSB0aGUgc3VwZXJpbXBvc2VkIChzYW1lIHBvc2l0aW9uKSBvbmVzXG5cdFx0XHQvLyBBZGQgaW4gdGhlIGV4dHJhcyBhdCB0aGUgZW5kIGxhdGVyXG5cdFx0XHRzdXBlcmltcG9zZWRfcG9zaXRpb25zID0gbmV3X3Bvcy5zbGljZSgwLCBvbGRfcG9zLmxlbmd0aCk7XG5cdFx0XHRzdXBlcmltcG9zZWRfdmFsdWVzID0gbmV3X3ZhbHMuc2xpY2UoMCwgb2xkX3ZhbHMubGVuZ3RoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gQXhpcyBoYXZlIHRvIGJlIHJlZHVjZWRcblx0XHRcdC8vIEZha2UgaXQgYnkgbW92aW5nIGFsbCBjdXJyZW50IGV4dHJhIGF4aXMgdG8gdGhlIGxhc3QgcG9zaXRpb25cblx0XHRcdC8vIFlvdSdsbCBuZWVkIGZpbGxlciBwb3NpdGlvbnMgYW5kIHZhbHVlcyBpbiB0aGUgbmV3IGFycmF5c1xuXHRcdFx0Y29uc3QgZmlsbGVyX3ZhbHMgPSBuZXcgQXJyYXkoTWF0aC5hYnMobm9fb2ZfZXh0cmFzKSkuZmlsbChcIlwiKTtcblx0XHRcdHN1cGVyaW1wb3NlZF92YWx1ZXMgPSBuZXdfdmFscy5jb25jYXQoZmlsbGVyX3ZhbHMpO1xuXG5cdFx0XHRjb25zdCBmaWxsZXJfcG9zID0gbmV3IEFycmF5KE1hdGguYWJzKG5vX29mX2V4dHJhcykpLmZpbGwobGFzdF9saW5lX3Bvcyk7XG5cdFx0XHRzdXBlcmltcG9zZWRfcG9zaXRpb25zID0gbmV3X3Bvcy5jb25jYXQoZmlsbGVyX3Bvcyk7XG5cdFx0fVxuXG5cdFx0c3VwZXJpbXBvc2VkX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRhZGRfYW5kX2FuaW1hdGVfbGluZSh2YWx1ZSwgb2xkX3Bvc1tpXSwgc3VwZXJpbXBvc2VkX3Bvc2l0aW9uc1tpXSwgaSwgZ3JvdXApO1xuXHRcdH0pO1xuXG5cdFx0aWYobm9fb2ZfZXh0cmFzID4gMCkge1xuXHRcdFx0Ly8gQWRkIGluIGV4dHJhIGF4aXMgaW4gdGhlIGVuZFxuXHRcdFx0Ly8gYW5kIHRoZW4gYW5pbWF0ZSB0byBuZXcgcG9zaXRpb25zXG5cdFx0XHRjb25zdCBleHRyYV92YWx1ZXMgPSBuZXdfdmFscy5zbGljZShvbGRfdmFscy5sZW5ndGgpO1xuXHRcdFx0Y29uc3QgZXh0cmFfcG9zaXRpb25zID0gbmV3X3Bvcy5zbGljZShvbGRfcG9zLmxlbmd0aCk7XG5cblx0XHRcdGV4dHJhX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRcdGFkZF9hbmRfYW5pbWF0ZV9saW5lKHZhbHVlLCBsYXN0X2xpbmVfcG9zLCBleHRyYV9wb3NpdGlvbnNbaV0sIGksIGdyb3VwKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdG1ha2VfeF9saW5lKGhlaWdodCwgdGV4dF9zdGFydF9hdCwgcG9pbnQsIGxhYmVsX2NsYXNzLCBheGlzX2xpbmVfY2xhc3MsIHhfcG9zKSB7XG5cdFx0bGV0IGFsbG93ZWRfc3BhY2UgPSB0aGlzLmF2Z191bml0X3dpZHRoICogMS41O1xuXG5cdFx0aWYodGhpcy5nZXRfc3Ryd2lkdGgocG9pbnQpID4gYWxsb3dlZF9zcGFjZSkge1xuXHRcdFx0bGV0IGFsbG93ZWRfbGV0dGVycyA9IGFsbG93ZWRfc3BhY2UgLyA4O1xuXHRcdFx0cG9pbnQgPSBwb2ludC5zbGljZSgwLCBhbGxvd2VkX2xldHRlcnMtMykgKyBcIiAuLi5cIjtcblx0XHR9XG5cblx0XHRsZXQgbGluZSA9ICQkLmNyZWF0ZVNWRygnbGluZScsIHtcblx0XHRcdHgxOiAwLFxuXHRcdFx0eDI6IDAsXG5cdFx0XHR5MTogMCxcblx0XHRcdHkyOiBoZWlnaHRcblx0XHR9KTtcblxuXHRcdGxldCB0ZXh0ID0gJCQuY3JlYXRlU1ZHKCd0ZXh0Jywge1xuXHRcdFx0Y2xhc3NOYW1lOiBsYWJlbF9jbGFzcyxcblx0XHRcdHg6IDAsXG5cdFx0XHR5OiB0ZXh0X3N0YXJ0X2F0LFxuXHRcdFx0ZHk6ICcuNzFlbScsXG5cdFx0XHRpbm5lckhUTUw6IHBvaW50XG5cdFx0fSk7XG5cblx0XHRsZXQgeF9sZXZlbCA9ICQkLmNyZWF0ZVNWRygnZycsIHtcblx0XHRcdGNsYXNzTmFtZTogYHRpY2sgJHtheGlzX2xpbmVfY2xhc3N9YCxcblx0XHRcdHRyYW5zZm9ybTogYHRyYW5zbGF0ZSgkeyB4X3BvcyB9LCAwKWBcblx0XHR9KTtcblxuXHRcdHhfbGV2ZWwuYXBwZW5kQ2hpbGQobGluZSk7XG5cdFx0eF9sZXZlbC5hcHBlbmRDaGlsZCh0ZXh0KTtcblxuXHRcdHJldHVybiB4X2xldmVsO1xuXHR9XG5cblx0bWFrZV95X2xpbmUoc3RhcnRfYXQsIHdpZHRoLCB0ZXh0X2VuZF9hdCwgcG9pbnQsIGxhYmVsX2NsYXNzLCBheGlzX2xpbmVfY2xhc3MsIHlfcG9zLCBkYXJrZXI9ZmFsc2UsIGxpbmVfdHlwZT1cIlwiKSB7XG5cdFx0bGV0IGxpbmUgPSAkJC5jcmVhdGVTVkcoJ2xpbmUnLCB7XG5cdFx0XHRjbGFzc05hbWU6IGxpbmVfdHlwZSA9PT0gXCJkYXNoZWRcIiA/IFwiZGFzaGVkXCI6IFwiXCIsXG5cdFx0XHR4MTogc3RhcnRfYXQsXG5cdFx0XHR4Mjogd2lkdGgsXG5cdFx0XHR5MTogMCxcblx0XHRcdHkyOiAwXG5cdFx0fSk7XG5cblx0XHRsZXQgdGV4dCA9ICQkLmNyZWF0ZVNWRygndGV4dCcsIHtcblx0XHRcdGNsYXNzTmFtZTogbGFiZWxfY2xhc3MsXG5cdFx0XHR4OiB0ZXh0X2VuZF9hdCxcblx0XHRcdHk6IDAsXG5cdFx0XHRkeTogJy4zMmVtJyxcblx0XHRcdGlubmVySFRNTDogcG9pbnQrXCJcIlxuXHRcdH0pO1xuXG5cdFx0bGV0IHlfbGV2ZWwgPSAkJC5jcmVhdGVTVkcoJ2cnLCB7XG5cdFx0XHRjbGFzc05hbWU6IGB0aWNrICR7YXhpc19saW5lX2NsYXNzfWAsXG5cdFx0XHR0cmFuc2Zvcm06IGB0cmFuc2xhdGUoMCwgJHt5X3Bvc30pYFxuXHRcdH0pO1xuXG5cdFx0aWYoZGFya2VyKSB7XG5cdFx0XHRsaW5lLnN0eWxlLnN0cm9rZSA9IFwicmdiYSgyNywgMzEsIDM1LCAwLjYpXCI7XG5cdFx0fVxuXG5cdFx0eV9sZXZlbC5hcHBlbmRDaGlsZChsaW5lKTtcblx0XHR5X2xldmVsLmFwcGVuZENoaWxkKHRleHQpO1xuXG5cdFx0cmV0dXJuIHlfbGV2ZWw7XG5cdH1cblxuXHRhZGRfYW5kX2FuaW1hdGVfeV9saW5lKHZhbHVlLCBvbGRfcG9zLCBuZXdfcG9zLCBpLCBncm91cCwgdHlwZSwgc3BlY2lmaWM9ZmFsc2UpIHtcblx0XHRsZXQgW3dpZHRoLCB0ZXh0X2VuZF9hdCwgYXhpc19saW5lX2NsYXNzLCBzdGFydF9hdF0gPSB0aGlzLmdldF95X2F4aXNfbGluZV9wcm9wcyhzcGVjaWZpYyk7XG5cdFx0bGV0IGF4aXNfbGFiZWxfY2xhc3MgPSAhc3BlY2lmaWMgPyAneS12YWx1ZS10ZXh0JyA6ICdzcGVjaWZpYy12YWx1ZSc7XG5cdFx0dmFsdWUgPSAhc3BlY2lmaWMgPyB2YWx1ZSA6ICh2YWx1ZStcIlwiKS50b1VwcGVyQ2FzZSgpO1xuXHRcdGNvbnN0IHlfbGluZSA9IHRoaXMubWFrZV95X2xpbmUoXG5cdFx0XHRzdGFydF9hdCxcblx0XHRcdHdpZHRoLFxuXHRcdFx0dGV4dF9lbmRfYXQsXG5cdFx0XHR2YWx1ZSxcblx0XHRcdGF4aXNfbGFiZWxfY2xhc3MsXG5cdFx0XHRheGlzX2xpbmVfY2xhc3MsXG5cdFx0XHRvbGRfcG9zLCAgLy8gb2xkIHBvc2l0aW9uXG5cdFx0XHQodmFsdWUgPT09IDAgJiYgaSAhPT0gMCksIC8vIE5vbi1maXJzdCBaZXJvIGxpbmVcblx0XHRcdHR5cGVcblx0XHQpO1xuXG5cdFx0Z3JvdXAuYXBwZW5kQ2hpbGQoeV9saW5lKTtcblxuXHRcdHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZSAmJiB0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUucHVzaChbXG5cdFx0XHR7dW5pdDogeV9saW5lLCBhcnJheTogWzBdLCBpbmRleDogMH0sXG5cdFx0XHR7dHJhbnNmb3JtOiBgMCwgJHsgbmV3X3BvcyB9YH0sXG5cdFx0XHQyNTAsXG5cdFx0XHRcImVhc2VpblwiLFxuXHRcdFx0XCJ0cmFuc2xhdGVcIixcblx0XHRcdHt0cmFuc2Zvcm06IGAwLCAkeyBvbGRfcG9zIH1gfVxuXHRcdF0pO1xuXHR9XG5cblx0Z2V0X3lfYXhpc19wb2ludHMoYXJyYXkpIHtcblx0XHQvLyoqKiBXaGVyZSB0aGUgbWFnaWMgaGFwcGVucyAqKipcblxuXHRcdC8vIENhbGN1bGF0ZXMgYmVzdC1maXQgeSBpbnRlcnZhbHMgZnJvbSBnaXZlbiB2YWx1ZXNcblx0XHQvLyBhbmQgcmV0dXJucyB0aGUgaW50ZXJ2YWwgYXJyYXlcblxuXHRcdC8vIFRPRE86IEZyYWN0aW9uc1xuXG5cdFx0bGV0IG1heF9ib3VuZCwgbWluX2JvdW5kLCBwb3Nfbm9fb2ZfcGFydHMsIG5lZ19ub19vZl9wYXJ0cywgcGFydF9zaXplO1xuXG5cdFx0Ly8gQ3JpdGljYWwgdmFsdWVzXG5cdFx0bGV0IG1heF92YWwgPSBwYXJzZUludChNYXRoLm1heCguLi5hcnJheSkpO1xuXHRcdGxldCBtaW5fdmFsID0gcGFyc2VJbnQoTWF0aC5taW4oLi4uYXJyYXkpKTtcblx0XHRpZihtaW5fdmFsID49IDApIHtcblx0XHRcdG1pbl92YWwgPSAwO1xuXHRcdH1cblxuXHRcdGxldCBnZXRfcGFyYW1zID0gKHZhbHVlMSwgdmFsdWUyKSA9PiB7XG5cdFx0XHRsZXQgYm91bmQxLCBib3VuZDIsIG5vX29mX3BhcnRzXzEsIG5vX29mX3BhcnRzXzIsIGludGVydmFsX3NpemU7XG5cdFx0XHRpZigodmFsdWUxK1wiXCIpLmxlbmd0aCA8PSAxKSB7XG5cdFx0XHRcdFtib3VuZDEsIG5vX29mX3BhcnRzXzFdID0gWzEwLCA1XTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFtib3VuZDEsIG5vX29mX3BhcnRzXzFdID0gdGhpcy5jYWxjX3VwcGVyX2JvdW5kX2FuZF9ub19vZl9wYXJ0cyh2YWx1ZTEpO1xuXHRcdFx0fVxuXG5cdFx0XHRpbnRlcnZhbF9zaXplID0gYm91bmQxIC8gbm9fb2ZfcGFydHNfMTtcblx0XHRcdG5vX29mX3BhcnRzXzIgPSB0aGlzLmNhbGNfbm9fb2ZfcGFydHModmFsdWUyLCBpbnRlcnZhbF9zaXplKTtcblx0XHRcdGJvdW5kMiA9IG5vX29mX3BhcnRzXzIgKiBpbnRlcnZhbF9zaXplO1xuXG5cdFx0XHRyZXR1cm4gW2JvdW5kMSwgYm91bmQyLCBub19vZl9wYXJ0c18xLCBub19vZl9wYXJ0c18yLCBpbnRlcnZhbF9zaXplXTtcblx0XHR9XG5cblx0XHRjb25zdCBhYnNfbWluX3ZhbCA9IG1pbl92YWwgKiAtMTtcblx0XHRpZihhYnNfbWluX3ZhbCA8PSBtYXhfdmFsKSB7XG5cdFx0XHQvLyBHZXQgdGhlIHBvc2l0aXZlIHJlZ2lvbiBpbnRlcnZhbHNcblx0XHRcdC8vIHRoZW4gY2FsYyBuZWdhdGl2ZSBvbmVzIGFjY29yZGluZ2x5XG5cdFx0XHRbbWF4X2JvdW5kLCBtaW5fYm91bmQsIHBvc19ub19vZl9wYXJ0cywgbmVnX25vX29mX3BhcnRzLCBwYXJ0X3NpemVdXG5cdFx0XHRcdD0gZ2V0X3BhcmFtcyhtYXhfdmFsLCBhYnNfbWluX3ZhbCk7XG5cdFx0XHRpZihhYnNfbWluX3ZhbCA9PT0gMCkge1xuXHRcdFx0XHRtaW5fYm91bmQgPSAwOyBuZWdfbm9fb2ZfcGFydHMgPSAwO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBHZXQgdGhlIG5lZ2F0aXZlIHJlZ2lvbiBoZXJlIGZpcnN0XG5cdFx0XHRbbWluX2JvdW5kLCBtYXhfYm91bmQsIG5lZ19ub19vZl9wYXJ0cywgcG9zX25vX29mX3BhcnRzLCBwYXJ0X3NpemVdXG5cdFx0XHRcdD0gZ2V0X3BhcmFtcyhhYnNfbWluX3ZhbCwgbWF4X3ZhbCk7XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBib3RoIHJlZ2lvbiBwYXJ0cyBldmVuXG5cdFx0aWYocG9zX25vX29mX3BhcnRzICUgMiAhPT0gMCAmJiBuZWdfbm9fb2ZfcGFydHMgPiAwKSBwb3Nfbm9fb2ZfcGFydHMrKztcblx0XHRpZihuZWdfbm9fb2ZfcGFydHMgJSAyICE9PSAwKSB7XG5cdFx0XHQvLyBldmVyeSBpbmNyZWFzZSBpbiBub19vZl9wYXJ0cyBlbnRhaWxzIGFuIGluY3JlYXNlIGluIGNvcnJlc3BvbmRpbmcgYm91bmRcblx0XHRcdC8vIGV4Y2VwdCBoZXJlLCBpdCBoYXBwZW5zIGltcGxpY2l0bHkgYWZ0ZXIgZXZlcnkgY2FsY19ub19vZl9wYXJ0cygpIGNhbGxcblx0XHRcdG5lZ19ub19vZl9wYXJ0cysrO1xuXHRcdFx0bWluX2JvdW5kICs9IHBhcnRfc2l6ZTtcblx0XHR9XG5cblx0XHRsZXQgbm9fb2ZfcGFydHMgPSBwb3Nfbm9fb2ZfcGFydHMgKyBuZWdfbm9fb2ZfcGFydHM7XG5cdFx0aWYobm9fb2ZfcGFydHMgPiA1KSB7XG5cdFx0XHRub19vZl9wYXJ0cyAvPSAyO1xuXHRcdFx0cGFydF9zaXplICo9IDI7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZ2V0X2ludGVydmFscyhcblx0XHRcdCgtMSkgKiBtaW5fYm91bmQsXG5cdFx0XHRwYXJ0X3NpemUsXG5cdFx0XHRub19vZl9wYXJ0c1xuXHRcdCk7XG5cdH1cblxuXHRnZXRfaW50ZXJ2YWxzKHN0YXJ0LCBpbnRlcnZhbF9zaXplLCBjb3VudCkge1xuXHRcdGxldCBpbnRlcnZhbHMgPSBbXTtcblx0XHRmb3IodmFyIGkgPSAwOyBpIDw9IGNvdW50OyBpKyspe1xuXHRcdFx0aW50ZXJ2YWxzLnB1c2goc3RhcnQpO1xuXHRcdFx0c3RhcnQgKz0gaW50ZXJ2YWxfc2l6ZTtcblx0XHR9XG5cdFx0cmV0dXJuIGludGVydmFscztcblx0fVxuXG5cdGNhbGNfdXBwZXJfYm91bmRfYW5kX25vX29mX3BhcnRzKG1heF92YWwpIHtcblx0XHQvLyBHaXZlbiBhIHBvc2l0aXZlIHZhbHVlLCBjYWxjdWxhdGVzIGEgbmljZS1udW1iZXIgdXBwZXIgYm91bmRcblx0XHQvLyBhbmQgYSBjb25zZXF1ZW50IG9wdGltYWwgbnVtYmVyIG9mIHBhcnRzXG5cblx0XHRjb25zdCBwYXJ0X3NpemUgPSBNYXRoLnBvdygxMCwgKChtYXhfdmFsK1wiXCIpLmxlbmd0aCAtIDEpKTtcblx0XHRjb25zdCBub19vZl9wYXJ0cyA9IHRoaXMuY2FsY19ub19vZl9wYXJ0cyhtYXhfdmFsLCBwYXJ0X3NpemUpO1xuXG5cdFx0Ly8gVXNlIGl0IHRvIGdldCBhIG5pY2UgZXZlbiB1cHBlciBib3VuZFxuXHRcdGNvbnN0IHVwcGVyX2JvdW5kID0gcGFydF9zaXplICogbm9fb2ZfcGFydHM7XG5cblx0XHRyZXR1cm4gW3VwcGVyX2JvdW5kLCBub19vZl9wYXJ0c107XG5cdH1cblxuXHRjYWxjX25vX29mX3BhcnRzKHZhbHVlLCBkaXZpc29yKSB7XG5cdFx0Ly8gdmFsdWUgc2hvdWxkIGJlIGEgcG9zaXRpdmUgbnVtYmVyLCBkaXZpc29yIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gMFxuXHRcdC8vIHJldHVybnMgYW4gZXZlbiBubyBvZiBwYXJ0c1xuXHRcdGxldCBub19vZl9wYXJ0cyA9IE1hdGguY2VpbCh2YWx1ZSAvIGRpdmlzb3IpO1xuXHRcdGlmKG5vX29mX3BhcnRzICUgMiAhPT0gMCkgbm9fb2ZfcGFydHMrKzsgLy8gTWFrZSBpdCBhbiBldmVuIG51bWJlclxuXG5cdFx0cmV0dXJuIG5vX29mX3BhcnRzO1xuXHR9XG5cblx0Z2V0X29wdGltYWxfbm9fb2ZfcGFydHMobm9fb2ZfcGFydHMpIHtcblx0XHQvLyBha2EgRGl2aWRlIGJ5IDIgaWYgdG9vIGxhcmdlXG5cdFx0cmV0dXJuIChub19vZl9wYXJ0cyA8IDUpID8gbm9fb2ZfcGFydHMgOiBub19vZl9wYXJ0cyAvIDI7XG5cdH1cblxuXHRzZXRfYXZnX3VuaXRfd2lkdGhfYW5kX3hfb2Zmc2V0KCkge1xuXHRcdC8vIFNldCB0aGUgLi4uIHlvdSBnZXQgaXRcblx0XHR0aGlzLmF2Z191bml0X3dpZHRoID0gdGhpcy53aWR0aC8odGhpcy54Lmxlbmd0aCAtIDEpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSAwO1xuXHR9XG5cblx0Z2V0X2FsbF95X3ZhbHVlcygpIHtcblx0XHRsZXQgYWxsX3ZhbHVlcyA9IFtdO1xuXG5cdFx0Ly8gQWRkIGluIGFsbCB0aGUgeSB2YWx1ZXMgaW4gdGhlIGRhdGFzZXRzXG5cdFx0dGhpcy55Lm1hcChkID0+IHtcblx0XHRcdGFsbF92YWx1ZXMgPSBhbGxfdmFsdWVzLmNvbmNhdChkLnZhbHVlcyk7XG5cdFx0fSk7XG5cblx0XHQvLyBBZGQgaW4gYWxsIHRoZSBzcGVjaWZpYyB2YWx1ZXNcblx0XHRyZXR1cm4gYWxsX3ZhbHVlcy5jb25jYXQodGhpcy5zcGVjaWZpY192YWx1ZXMubWFwKGQgPT4gZC52YWx1ZSkpO1xuXHR9XG5cblx0Y2FsY195X2RlcGVuZGVuY2llcygpIHtcblx0XHR0aGlzLnlfbWluX3RvcHMgPSBuZXcgQXJyYXkodGhpcy54X2F4aXNfcG9zaXRpb25zLmxlbmd0aCkuZmlsbCg5OTk5KTtcblx0XHR0aGlzLnkubWFwKGQgPT4ge1xuXHRcdFx0ZC55X3RvcHMgPSBkLnZhbHVlcy5tYXAoIHZhbCA9PiAkJC5mbG9hdF8yKHRoaXMuemVyb19saW5lIC0gdmFsICogdGhpcy5tdWx0aXBsaWVyKSk7XG5cdFx0XHRkLnlfdG9wcy5tYXAoICh5X3RvcCwgaSkgPT4ge1xuXHRcdFx0XHRpZih5X3RvcCA8IHRoaXMueV9taW5fdG9wc1tpXSkge1xuXHRcdFx0XHRcdHRoaXMueV9taW5fdG9wc1tpXSA9IHlfdG9wO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdGdldF9iYXJfaGVpZ2h0X2FuZF95X2F0dHIoeV90b3ApIHtcblx0XHRsZXQgaGVpZ2h0LCB5O1xuXHRcdGlmICh5X3RvcCA8PSB0aGlzLnplcm9fbGluZSkge1xuXHRcdFx0aGVpZ2h0ID0gdGhpcy56ZXJvX2xpbmUgLSB5X3RvcDtcblx0XHRcdHkgPSB5X3RvcDtcblxuXHRcdFx0Ly8gSW4gY2FzZSBvZiBpbnZpc2libGUgYmFyc1xuXHRcdFx0aWYoaGVpZ2h0ID09PSAwKSB7XG5cdFx0XHRcdGhlaWdodCA9IHRoaXMuaGVpZ2h0ICogMC4wMTtcblx0XHRcdFx0eSAtPSBoZWlnaHQ7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGhlaWdodCA9IHlfdG9wIC0gdGhpcy56ZXJvX2xpbmU7XG5cdFx0XHR5ID0gdGhpcy56ZXJvX2xpbmU7XG5cblx0XHRcdC8vIEluIGNhc2Ugb2YgaW52aXNpYmxlIGJhcnNcblx0XHRcdGlmKGhlaWdodCA9PT0gMCkge1xuXHRcdFx0XHRoZWlnaHQgPSB0aGlzLmhlaWdodCAqIDAuMDE7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtoZWlnaHQsIHldO1xuXHR9XG5cblx0c2V0dXBfdXRpbHMoKSB7XG5cdFx0dGhpcy5kcmF3ID0ge1xuXHRcdFx0J2Jhcic6ICh4LCB5X3RvcCwgYXJncywgY29sb3IsIGluZGV4LCBub19vZl9kYXRhc2V0cykgPT4ge1xuXHRcdFx0XHRsZXQgdG90YWxfd2lkdGggPSB0aGlzLmF2Z191bml0X3dpZHRoIC0gYXJncy5zcGFjZV93aWR0aDtcblx0XHRcdFx0bGV0IHN0YXJ0X3ggPSB4IC0gdG90YWxfd2lkdGgvMjtcblxuXHRcdFx0XHRsZXQgd2lkdGggPSB0b3RhbF93aWR0aCAvIG5vX29mX2RhdGFzZXRzO1xuXHRcdFx0XHRsZXQgY3VycmVudF94ID0gc3RhcnRfeCArIHdpZHRoICogaW5kZXg7XG5cblx0XHRcdFx0bGV0IFtoZWlnaHQsIHldID0gdGhpcy5nZXRfYmFyX2hlaWdodF9hbmRfeV9hdHRyKHlfdG9wKTtcblxuXHRcdFx0XHRyZXR1cm4gJCQuY3JlYXRlU1ZHKCdyZWN0Jywge1xuXHRcdFx0XHRcdGNsYXNzTmFtZTogYGJhciBtaW5pIGZpbGwgJHtjb2xvcn1gLFxuXHRcdFx0XHRcdHg6IGN1cnJlbnRfeCxcblx0XHRcdFx0XHR5OiB5LFxuXHRcdFx0XHRcdHdpZHRoOiB3aWR0aCxcblx0XHRcdFx0XHRoZWlnaHQ6IGhlaWdodFxuXHRcdFx0XHR9KTtcblxuXHRcdFx0fSxcblx0XHRcdCdkb3QnOiAoeCwgeSwgYXJncywgY29sb3IpID0+IHtcblx0XHRcdFx0cmV0dXJuICQkLmNyZWF0ZVNWRygnY2lyY2xlJywge1xuXHRcdFx0XHRcdGNsYXNzTmFtZTogYGZpbGwgJHtjb2xvcn1gLFxuXHRcdFx0XHRcdGN4OiB4LFxuXHRcdFx0XHRcdGN5OiB5LFxuXHRcdFx0XHRcdHI6IGFyZ3MucmFkaXVzXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR0aGlzLmFuaW1hdGUgPSB7XG5cdFx0XHQnYmFyJzogKGJhcl9vYmosIHgsIHlfdG9wLCBpbmRleCkgPT4ge1xuXHRcdFx0XHRsZXQgc3RhcnQgPSB4IC0gdGhpcy5hdmdfdW5pdF93aWR0aC80O1xuXHRcdFx0XHRsZXQgd2lkdGggPSAodGhpcy5hdmdfdW5pdF93aWR0aC8yKS90aGlzLnkubGVuZ3RoO1xuXHRcdFx0XHRsZXQgW2hlaWdodCwgeV0gPSB0aGlzLmdldF9iYXJfaGVpZ2h0X2FuZF95X2F0dHIoeV90b3ApO1xuXG5cdFx0XHRcdHggPSBzdGFydCArICh3aWR0aCAqIGluZGV4KTtcblxuXHRcdFx0XHRyZXR1cm4gW2Jhcl9vYmosIHt3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0LCB4OiB4LCB5OiB5fSwgMjUwLCBcImVhc2VpblwiXTtcblx0XHRcdFx0Ly8gYmFyLmFuaW1hdGUoe2hlaWdodDogYXJncy5uZXdfaGVpZ2h0LCB5OiB5X3RvcH0sIDI1MCwgbWluYS5lYXNlaW4pO1xuXHRcdFx0fSxcblx0XHRcdCdkb3QnOiAoZG90X29iaiwgeCwgeV90b3ApID0+IHtcblx0XHRcdFx0cmV0dXJuIFtkb3Rfb2JqLCB7Y3g6IHgsIGN5OiB5X3RvcH0sIDMwMCwgXCJlYXNlaW5cIl07XG5cdFx0XHRcdC8vIGRvdC5hbmltYXRlKHtjeTogeV90b3B9LCAyNTAsIG1pbmEuZWFzZWluKTtcblx0XHRcdH1cblx0XHR9O1xuXHR9XG59XG5cbmZyYXBwZS5jaGFydC5CYXJDaGFydCA9IGNsYXNzIEJhckNoYXJ0IGV4dGVuZHMgZnJhcHBlLmNoYXJ0LkF4aXNDaGFydCB7XG5cdGNvbnN0cnVjdG9yKGFyZ3MpIHtcblx0XHRzdXBlcihhcmdzKTtcblxuXHRcdHRoaXMudHlwZSA9ICdiYXInO1xuXHRcdHRoaXMueF9heGlzX21vZGUgPSBhcmdzLnhfYXhpc19tb2RlIHx8ICd0aWNrJztcblx0XHR0aGlzLnlfYXhpc19tb2RlID0gYXJncy55X2F4aXNfbW9kZSB8fCAnc3Bhbic7XG5cdFx0dGhpcy5zZXR1cCgpO1xuXHR9XG5cblx0c2V0dXBfdmFsdWVzKCkge1xuXHRcdHN1cGVyLnNldHVwX3ZhbHVlcygpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSB0aGlzLmF2Z191bml0X3dpZHRoO1xuXHRcdHRoaXMudW5pdF9hcmdzID0ge1xuXHRcdFx0dHlwZTogJ2JhcicsXG5cdFx0XHRhcmdzOiB7XG5cdFx0XHRcdHNwYWNlX3dpZHRoOiB0aGlzLmF2Z191bml0X3dpZHRoLzIsXG5cdFx0XHR9XG5cdFx0fTtcblx0fVxuXG5cdG1ha2Vfb3ZlcmxheSgpIHtcblx0XHQvLyBKdXN0IG1ha2Ugb25lIG91dCBvZiB0aGUgZmlyc3QgZWxlbWVudFxuXHRcdGxldCBpbmRleCA9IHRoaXMueC5sZW5ndGggLSAxO1xuXHRcdGxldCB1bml0ID0gdGhpcy55WzBdLnN2Z191bml0c1tpbmRleF07XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KGluZGV4KTtcblxuXHRcdGlmKHRoaXMub3ZlcmxheSkge1xuXHRcdFx0dGhpcy5vdmVybGF5LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5vdmVybGF5KTtcblx0XHR9XG5cblx0XHR0aGlzLm92ZXJsYXkgPSB1bml0LmNsb25lTm9kZSgpO1xuXHRcdHRoaXMub3ZlcmxheS5zdHlsZS5maWxsID0gJyMwMDAwMDAnO1xuXHRcdHRoaXMub3ZlcmxheS5zdHlsZS5vcGFjaXR5ID0gJzAuNCc7XG5cdFx0dGhpcy5kcmF3X2FyZWEuYXBwZW5kQ2hpbGQodGhpcy5vdmVybGF5KTtcblx0fVxuXG5cdGJpbmRfb3ZlcmxheSgpIHtcblx0XHQvLyBvbiBldmVudCwgdXBkYXRlIG92ZXJsYXlcblx0XHR0aGlzLnBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdkYXRhLXNlbGVjdCcsIChlKSA9PiB7XG5cdFx0XHR0aGlzLnVwZGF0ZV9vdmVybGF5KGUuc3ZnX3VuaXQpO1xuXHRcdH0pO1xuXHR9XG5cblx0dXBkYXRlX292ZXJsYXkodW5pdCkge1xuXHRcdGxldCBhdHRyaWJ1dGVzID0gW107XG5cdFx0T2JqZWN0LmtleXModW5pdC5hdHRyaWJ1dGVzKS5tYXAoaW5kZXggPT4ge1xuXHRcdFx0YXR0cmlidXRlcy5wdXNoKHVuaXQuYXR0cmlidXRlc1tpbmRleF0pO1xuXHRcdH0pO1xuXG5cdFx0YXR0cmlidXRlcy5maWx0ZXIoYXR0ciA9PiBhdHRyLnNwZWNpZmllZCkubWFwKGF0dHIgPT4ge1xuXHRcdFx0dGhpcy5vdmVybGF5LnNldEF0dHJpYnV0ZShhdHRyLm5hbWUsIGF0dHIubm9kZVZhbHVlKTtcblx0XHR9KTtcblx0fVxuXG5cdG9uX2xlZnRfYXJyb3coKSB7XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KHRoaXMuY3VycmVudF9pbmRleCAtIDEpO1xuXHR9XG5cblx0b25fcmlnaHRfYXJyb3coKSB7XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KHRoaXMuY3VycmVudF9pbmRleCArIDEpO1xuXHR9XG5cblx0c2V0X2F2Z191bml0X3dpZHRoX2FuZF94X29mZnNldCgpIHtcblx0XHR0aGlzLmF2Z191bml0X3dpZHRoID0gdGhpcy53aWR0aC8odGhpcy54Lmxlbmd0aCArIDEpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSB0aGlzLmF2Z191bml0X3dpZHRoO1xuXHR9XG59XG5cbmZyYXBwZS5jaGFydC5MaW5lQ2hhcnQgPSBjbGFzcyBMaW5lQ2hhcnQgZXh0ZW5kcyBmcmFwcGUuY2hhcnQuQXhpc0NoYXJ0IHtcblx0Y29uc3RydWN0b3IoYXJncykge1xuXHRcdHN1cGVyKGFyZ3MpO1xuXHRcdGlmKE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKSAhPT0gZnJhcHBlLmNoYXJ0LkxpbmVDaGFydC5wcm90b3R5cGUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR0aGlzLnR5cGUgPSAnbGluZSc7XG5cdFx0dGhpcy5yZWdpb25fZmlsbCA9IGFyZ3MucmVnaW9uX2ZpbGw7XG5cdFx0dGhpcy54X2F4aXNfbW9kZSA9IGFyZ3MueF9heGlzX21vZGUgfHwgJ3NwYW4nO1xuXHRcdHRoaXMueV9heGlzX21vZGUgPSBhcmdzLnlfYXhpc19tb2RlIHx8ICdzcGFuJztcblxuXHRcdHRoaXMuc2V0dXAoKTtcblx0fVxuXG5cdHNldHVwX2dyYXBoX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5zZXR1cF9wYXRoX2dyb3VwcygpO1xuXHRcdHN1cGVyLnNldHVwX2dyYXBoX2NvbXBvbmVudHMoKTtcblx0fVxuXG5cdHNldHVwX3BhdGhfZ3JvdXBzKCkge1xuXHRcdHRoaXMucGF0aHNfZ3JvdXBzID0gW107XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0dGhpcy5wYXRoc19ncm91cHNbaV0gPSAkJC5jcmVhdGVTVkcoJ2cnLCB7XG5cdFx0XHRcdGNsYXNzTmFtZTogJ3BhdGgtZ3JvdXAgcGF0aC1ncm91cC0nICsgaSxcblx0XHRcdFx0aW5zaWRlOiB0aGlzLmRyYXdfYXJlYVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHRzZXR1cF92YWx1ZXMoKSB7XG5cdFx0c3VwZXIuc2V0dXBfdmFsdWVzKCk7XG5cdFx0dGhpcy51bml0X2FyZ3MgPSB7XG5cdFx0XHR0eXBlOiAnZG90Jyxcblx0XHRcdGFyZ3M6IHsgcmFkaXVzOiA4IH1cblx0XHR9O1xuXHR9XG5cblx0bWFrZV9wYXRocygpIHtcblx0XHR0aGlzLnkubWFwKChkLCBpKSA9PiB7XG5cdFx0XHR0aGlzLm1ha2VfcGF0aChkLCBpLCB0aGlzLnhfYXhpc19wb3NpdGlvbnMsIGQueV90b3BzLCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfcGF0aChkLCBpLCB4X3Bvc2l0aW9ucywgeV9wb3NpdGlvbnMsIGNvbG9yKSB7XG5cdFx0Ly8gbGV0IHBvaW50c19saXN0ID0geV9wb3NpdGlvbnMubWFwKCh5LCBpKSA9PiAoeF9wb3NpdGlvbnNbaV0gKyAnLCcgKyB5KSk7XG5cdFx0Ly8gbGV0IHBvaW50c19zdHIgPSBwb2ludHNfbGlzdC5qb2luKFwiTFwiKTtcblxuXHRcdC8vIHRoaXMucGF0aHNfZ3JvdXBzW2ldLnRleHRDb250ZW50ID0gJyc7XG5cblx0XHQvLyBkLnBhdGggPSAkJC5jcmVhdGVTVkcoJ3BhdGgnLCB7XG5cdFx0Ly8gXHRpbnNpZGU6IHRoaXMucGF0aHNfZ3JvdXBzW2ldLFxuXHRcdC8vIFx0Y2xhc3NOYW1lOiBgc3Ryb2tlICR7Y29sb3J9YCxcblx0XHQvLyBcdGQ6IFwiTVwiK3BvaW50c19zdHJcblx0XHQvLyB9KTtcblxuXHRcdC8vIGlmKHRoaXMucmVnaW9uX2ZpbGwpIHtcblx0XHQvLyBcdGxldCBncmFkaWVudF9pZCA9J3BhdGgtZmlsbC1ncmFkaWVudCcgKyAnLScgKyBjb2xvcjtcblxuXHRcdC8vIFx0dGhpcy5ncmFkaWVudF9kZWYgPSAkJC5jcmVhdGVTVkcoJ2xpbmVhckdyYWRpZW50Jywge1xuXHRcdC8vIFx0XHRpbnNpZGU6IHRoaXMuc3ZnX2RlZnMsXG5cdFx0Ly8gXHRcdGlkOiBncmFkaWVudF9pZCxcblx0XHQvLyBcdFx0eDE6IDAsXG5cdFx0Ly8gXHRcdHgyOiAwLFxuXHRcdC8vIFx0XHR5MTogMCxcblx0XHQvLyBcdFx0eTI6IDFcblx0XHQvLyBcdH0pO1xuXG5cdFx0Ly8gXHRmdW5jdGlvbiBzZXRfZ3JhZGllbnRfc3RvcChncmFkX2VsZW0sIG9mZnNldCwgY29sb3IsIG9wYWNpdHkpIHtcblx0XHQvLyBcdFx0JCQuY3JlYXRlU1ZHKCdzdG9wJywge1xuXHRcdC8vIFx0XHRcdCdjbGFzc05hbWUnOiAnc3RvcC1jb2xvciAnICsgY29sb3IsXG5cdFx0Ly8gXHRcdFx0J2luc2lkZSc6IGdyYWRfZWxlbSxcblx0XHQvLyBcdFx0XHQnb2Zmc2V0Jzogb2Zmc2V0LFxuXHRcdC8vIFx0XHRcdCdzdG9wLW9wYWNpdHknOiBvcGFjaXR5XG5cdFx0Ly8gXHRcdH0pO1xuXHRcdC8vIFx0fVxuXG5cdFx0Ly8gXHRzZXRfZ3JhZGllbnRfc3RvcCh0aGlzLmdyYWRpZW50X2RlZiwgXCIwJVwiLCBjb2xvciwgMC40KTtcblx0XHQvLyBcdHNldF9ncmFkaWVudF9zdG9wKHRoaXMuZ3JhZGllbnRfZGVmLCBcIjUwJVwiLCBjb2xvciwgMC4yKTtcblx0XHQvLyBcdHNldF9ncmFkaWVudF9zdG9wKHRoaXMuZ3JhZGllbnRfZGVmLCBcIjEwMCVcIiwgY29sb3IsIDApO1xuXG5cdFx0Ly8gXHRkLnJlZ2lvbl9wYXRoID0gJCQuY3JlYXRlU1ZHKCdwYXRoJywge1xuXHRcdC8vIFx0XHRpbnNpZGU6IHRoaXMucGF0aHNfZ3JvdXBzW2ldLFxuXHRcdC8vIFx0XHRjbGFzc05hbWU6IGByZWdpb24tZmlsbGAsXG5cdFx0Ly8gXHRcdGQ6IFwiTVwiICsgYDAsJHt0aGlzLnplcm9fbGluZX1MYCArIHBvaW50c19zdHIgKyBgTCR7dGhpcy53aWR0aH0sJHt0aGlzLnplcm9fbGluZX1gLFxuXHRcdC8vIFx0fSk7XG5cblx0XHQvLyBcdGQucmVnaW9uX3BhdGguc3R5bGUuc3Ryb2tlID0gXCJub25lXCI7XG5cdFx0Ly8gXHRkLnJlZ2lvbl9wYXRoLnN0eWxlLmZpbGwgPSBgdXJsKCMke2dyYWRpZW50X2lkfSlgO1xuXHRcdC8vIH1cblx0fVxufVxuXG5mcmFwcGUuY2hhcnQuUGVyY2VudGFnZUNoYXJ0ID0gY2xhc3MgUGVyY2VudGFnZUNoYXJ0IGV4dGVuZHMgZnJhcHBlLmNoYXJ0LkZyYXBwZUNoYXJ0IHtcblx0Y29uc3RydWN0b3IoYXJncykge1xuXHRcdHN1cGVyKGFyZ3MpO1xuXHRcdHRoaXMudHlwZSA9ICdwZXJjZW50YWdlJztcblxuXHRcdHRoaXMuZ2V0X3lfbGFiZWwgPSB0aGlzLmZvcm1hdF9sYW1iZGFzLnlfbGFiZWw7XG5cdFx0dGhpcy5nZXRfeF90b29sdGlwID0gdGhpcy5mb3JtYXRfbGFtYmRhcy54X3Rvb2x0aXA7XG5cdFx0dGhpcy5nZXRfeV90b29sdGlwID0gdGhpcy5mb3JtYXRfbGFtYmRhcy55X3Rvb2x0aXA7XG5cblx0XHR0aGlzLm1heF9zbGljZXMgPSAxMDtcblx0XHR0aGlzLm1heF9sZWdlbmRfcG9pbnRzID0gNjtcblxuXHRcdHRoaXMuY29sb3JzID0gYXJncy5jb2xvcnM7XG5cblx0XHRpZighdGhpcy5jb2xvcnMgfHwgdGhpcy5jb2xvcnMubGVuZ3RoIDwgdGhpcy5kYXRhLmxhYmVscy5sZW5ndGgpIHtcblx0XHRcdHRoaXMuY29sb3JzID0gWydsaWdodC1ibHVlJywgJ2JsdWUnLCAndmlvbGV0JywgJ3JlZCcsICdvcmFuZ2UnLFxuXHRcdFx0XHQneWVsbG93JywgJ2dyZWVuJywgJ2xpZ2h0LWdyZWVuJywgJ3B1cnBsZScsICdtYWdlbnRhJ107XG5cdFx0fVxuXG5cdFx0dGhpcy5zZXR1cCgpO1xuXHR9XG5cblx0bWFrZV9jaGFydF9hcmVhKCkge1xuXHRcdHRoaXMuY2hhcnRfd3JhcHBlci5jbGFzc05hbWUgKz0gJyAnICsgJ2dyYXBoLWZvY3VzLW1hcmdpbic7XG5cdFx0dGhpcy5jaGFydF93cmFwcGVyLnN0eWxlLm1hcmdpblRvcCA9ICc0NXB4JztcblxuXHRcdHRoaXMuc3RhdHNfd3JhcHBlci5jbGFzc05hbWUgKz0gJyAnICsgJ2dyYXBoLWZvY3VzLW1hcmdpbic7XG5cdFx0dGhpcy5zdGF0c193cmFwcGVyLnN0eWxlLm1hcmdpbkJvdHRvbSA9ICczMHB4Jztcblx0XHR0aGlzLnN0YXRzX3dyYXBwZXIuc3R5bGUucGFkZGluZ1RvcCA9ICcwcHgnO1xuXHR9XG5cblx0bWFrZV9kcmF3X2FyZWEoKSB7XG5cdFx0dGhpcy5jaGFydF9kaXYgPSAkJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdGNsYXNzTmFtZTogJ2RpdicsXG5cdFx0XHRpbnNpZGU6IHRoaXMuY2hhcnRfd3JhcHBlcixcblx0XHRcdHdpZHRoOiB0aGlzLmJhc2Vfd2lkdGgsXG5cdFx0XHRoZWlnaHQ6IHRoaXMuYmFzZV9oZWlnaHRcblx0XHR9KTtcblxuXHRcdHRoaXMuY2hhcnQgPSAkJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdGNsYXNzTmFtZTogJ3Byb2dyZXNzLWNoYXJ0Jyxcblx0XHRcdGluc2lkZTogdGhpcy5jaGFydF9kaXZcblx0XHR9KTtcblx0fVxuXG5cdHNldHVwX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5wZXJjZW50YWdlX2JhciA9ICQkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0Y2xhc3NOYW1lOiAncHJvZ3Jlc3MnLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmNoYXJ0XG5cdFx0fSk7XG5cdH1cblxuXHRzZXR1cF92YWx1ZXMoKSB7XG5cdFx0dGhpcy5zbGljZV90b3RhbHMgPSBbXTtcblx0XHRsZXQgYWxsX3RvdGFscyA9IHRoaXMuZGF0YS5sYWJlbHMubWFwKChkLCBpKSA9PiB7XG5cdFx0XHRsZXQgdG90YWwgPSAwO1xuXHRcdFx0dGhpcy5kYXRhLmRhdGFzZXRzLm1hcChlID0+IHtcblx0XHRcdFx0dG90YWwgKz0gZS52YWx1ZXNbaV07XG5cdFx0XHR9KTtcblx0XHRcdHJldHVybiBbdG90YWwsIGRdO1xuXHRcdH0pLmZpbHRlcihkID0+IHsgcmV0dXJuIGRbMF0gPiAwOyB9KTsgLy8ga2VlcCBvbmx5IHBvc2l0aXZlIHJlc3VsdHNcblxuXHRcdGxldCB0b3RhbHMgPSBhbGxfdG90YWxzO1xuXG5cdFx0aWYoYWxsX3RvdGFscy5sZW5ndGggPiB0aGlzLm1heF9zbGljZXMpIHtcblx0XHRcdGFsbF90b3RhbHMuc29ydCgoYSwgYikgPT4geyByZXR1cm4gYlswXSAtIGFbMF07IH0pO1xuXG5cdFx0XHR0b3RhbHMgPSBhbGxfdG90YWxzLnNsaWNlKDAsIHRoaXMubWF4X3NsaWNlcy0xKTtcblx0XHRcdGxldCBvdGhlcnMgPSBhbGxfdG90YWxzLnNsaWNlKHRoaXMubWF4X3NsaWNlcy0xKTtcblxuXHRcdFx0bGV0IHN1bV9vZl9vdGhlcnMgPSAwO1xuXHRcdFx0b3RoZXJzLm1hcChkID0+IHtzdW1fb2Zfb3RoZXJzICs9IGRbMF19KTtcblxuXHRcdFx0dG90YWxzLnB1c2goW3N1bV9vZl9vdGhlcnMsICdSZXN0J10pO1xuXG5cdFx0XHR0aGlzLmNvbG9yc1t0aGlzLm1heF9zbGljZXMtMV0gPSAnZ3JleSc7XG5cdFx0fVxuXG5cdFx0dGhpcy5sYWJlbHMgPSBbXTtcblx0XHR0b3RhbHMubWFwKGQgPT4ge1xuXHRcdFx0dGhpcy5zbGljZV90b3RhbHMucHVzaChkWzBdKTtcblx0XHRcdHRoaXMubGFiZWxzLnB1c2goZFsxXSk7XG5cdFx0fSk7XG5cblx0XHR0aGlzLmxlZ2VuZF90b3RhbHMgPSB0aGlzLnNsaWNlX3RvdGFscy5zbGljZSgwLCB0aGlzLm1heF9sZWdlbmRfcG9pbnRzKTtcblx0fVxuXG5cdHNldHVwX3V0aWxzKCkgeyB9XG5cblx0bWFrZV9ncmFwaF9jb21wb25lbnRzKCkge1xuXHRcdHRoaXMuZ3JhbmRfdG90YWwgPSB0aGlzLnNsaWNlX3RvdGFscy5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKTtcblx0XHR0aGlzLnNsaWNlcyA9IFtdO1xuXHRcdHRoaXMuc2xpY2VfdG90YWxzLm1hcCgodG90YWwsIGkpID0+IHtcblx0XHRcdGxldCBzbGljZSA9ICQkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0XHRjbGFzc05hbWU6IGBwcm9ncmVzcy1iYXIgYmFja2dyb3VuZCAke3RoaXMuY29sb3JzW2ldfWAsXG5cdFx0XHRcdHN0eWxlOiBgd2lkdGg6ICR7dG90YWwqMTAwL3RoaXMuZ3JhbmRfdG90YWx9JWAsXG5cdFx0XHRcdGluc2lkZTogdGhpcy5wZXJjZW50YWdlX2JhclxuXHRcdFx0fSk7XG5cdFx0XHR0aGlzLnNsaWNlcy5wdXNoKHNsaWNlKTtcblx0XHR9KTtcblx0fVxuXG5cdGJpbmRfdG9vbHRpcCgpIHtcblx0XHR0aGlzLnNsaWNlcy5tYXAoKHNsaWNlLCBpKSA9PiB7XG5cdFx0XHRzbGljZS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWVudGVyJywgKCkgPT4ge1xuXHRcdFx0XHRsZXQgZ19vZmYgPSAkJC5vZmZzZXQodGhpcy5jaGFydF93cmFwcGVyKSwgcF9vZmYgPSAkJC5vZmZzZXQoc2xpY2UpO1xuXG5cdFx0XHRcdGxldCB4ID0gcF9vZmYubGVmdCAtIGdfb2ZmLmxlZnQgKyBzbGljZS5vZmZzZXRXaWR0aC8yO1xuXHRcdFx0XHRsZXQgeSA9IHBfb2ZmLnRvcCAtIGdfb2ZmLnRvcCAtIDY7XG5cdFx0XHRcdGxldCB0aXRsZSA9ICh0aGlzLmZvcm1hdHRlZF9sYWJlbHMgJiYgdGhpcy5mb3JtYXR0ZWRfbGFiZWxzLmxlbmd0aD4wXG5cdFx0XHRcdFx0PyB0aGlzLmZvcm1hdHRlZF9sYWJlbHNbaV0gOiB0aGlzLmxhYmVsc1tpXSkgKyAnOiAnO1xuXHRcdFx0XHRsZXQgcGVyY2VudCA9ICh0aGlzLnNsaWNlX3RvdGFsc1tpXSoxMDAvdGhpcy5ncmFuZF90b3RhbCkudG9GaXhlZCgxKTtcblxuXHRcdFx0XHR0aGlzLnRpcC5zZXRfdmFsdWVzKHgsIHksIHRpdGxlLCBwZXJjZW50ICsgXCIlXCIpO1xuXHRcdFx0XHR0aGlzLnRpcC5zaG93X3RpcCgpO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHRzaG93X3N1bW1hcnkoKSB7XG5cdFx0bGV0IHhfdmFsdWVzID0gdGhpcy5mb3JtYXR0ZWRfbGFiZWxzICYmIHRoaXMuZm9ybWF0dGVkX2xhYmVscy5sZW5ndGggPiAwXG5cdFx0XHQ/IHRoaXMuZm9ybWF0dGVkX2xhYmVscyA6IHRoaXMubGFiZWxzO1xuXHRcdHRoaXMubGVnZW5kX3RvdGFscy5tYXAoKGQsIGkpID0+IHtcblx0XHRcdGlmKGQpIHtcblx0XHRcdFx0bGV0IHN0YXRzID0gJCQuY3JlYXRlKCdkaXYnLCB7XG5cdFx0XHRcdFx0Y2xhc3NOYW1lOiAnc3RhdHMnLFxuXHRcdFx0XHRcdGluc2lkZTogdGhpcy5zdGF0c193cmFwcGVyXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRzdGF0cy5pbm5lckhUTUwgPSBgPHNwYW4gY2xhc3M9XCJpbmRpY2F0b3IgJHt0aGlzLmNvbG9yc1tpXX1cIj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWRcIj4ke3hfdmFsdWVzW2ldfTo8L3NwYW4+XG5cdFx0XHRcdFx0JHtkfVxuXHRcdFx0XHQ8L3NwYW4+YDtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufVxuXG5mcmFwcGUuY2hhcnQuSGVhdE1hcCA9IGNsYXNzIEhlYXRNYXAgZXh0ZW5kcyBmcmFwcGUuY2hhcnQuRnJhcHBlQ2hhcnQge1xuXHRjb25zdHJ1Y3Rvcih7XG5cdFx0c3RhcnQgPSAnJyxcblx0XHRkb21haW4gPSAnJyxcblx0XHRzdWJkb21haW4gPSAnJyxcblx0XHRkYXRhID0ge30sXG5cdFx0ZGlzY3JldGVfZG9tYWlucyA9IDAsXG5cdFx0Y291bnRfbGFiZWwgPSAnJ1xuXHR9KSB7XG5cdFx0c3VwZXIoYXJndW1lbnRzWzBdKTtcblxuXHRcdHRoaXMudHlwZSA9ICdoZWF0bWFwJztcblxuXHRcdHRoaXMuZG9tYWluID0gZG9tYWluO1xuXHRcdHRoaXMuc3ViZG9tYWluID0gc3ViZG9tYWluO1xuXHRcdHRoaXMuZGF0YSA9IGRhdGE7XG5cdFx0dGhpcy5kaXNjcmV0ZV9kb21haW5zID0gZGlzY3JldGVfZG9tYWlucztcblx0XHR0aGlzLmNvdW50X2xhYmVsID0gY291bnRfbGFiZWw7XG5cblx0XHRsZXQgdG9kYXkgPSBuZXcgRGF0ZSgpO1xuXHRcdHRoaXMuc3RhcnQgPSBzdGFydCB8fCB0aGlzLmFkZF9kYXlzKHRvZGF5LCAzNjUpO1xuXG5cdFx0dGhpcy5sZWdlbmRfY29sb3JzID0gWycjZWJlZGYwJywgJyNjNmU0OGInLCAnIzdiYzk2ZicsICcjMjM5YTNiJywgJyMxOTYxMjcnXTtcblxuXHRcdHRoaXMudHJhbnNsYXRlX3ggPSAwO1xuXHRcdHRoaXMuc2V0dXAoKTtcblx0fVxuXG5cdHNldHVwX2Jhc2VfdmFsdWVzKCkge1xuXHRcdHRoaXMudG9kYXkgPSBuZXcgRGF0ZSgpO1xuXG5cdFx0aWYoIXRoaXMuc3RhcnQpIHtcblx0XHRcdHRoaXMuc3RhcnQgPSBuZXcgRGF0ZSgpO1xuXHRcdFx0dGhpcy5zdGFydC5zZXRGdWxsWWVhciggdGhpcy5zdGFydC5nZXRGdWxsWWVhcigpIC0gMSApO1xuXHRcdH1cblx0XHR0aGlzLmZpcnN0X3dlZWtfc3RhcnQgPSBuZXcgRGF0ZSh0aGlzLnN0YXJ0LnRvRGF0ZVN0cmluZygpKTtcblx0XHR0aGlzLmxhc3Rfd2Vla19zdGFydCA9IG5ldyBEYXRlKHRoaXMudG9kYXkudG9EYXRlU3RyaW5nKCkpO1xuXHRcdGlmKHRoaXMuZmlyc3Rfd2Vla19zdGFydC5nZXREYXkoKSAhPT0gNykge1xuXHRcdFx0dGhpcy5hZGRfZGF5cyh0aGlzLmZpcnN0X3dlZWtfc3RhcnQsICgtMSkgKiB0aGlzLmZpcnN0X3dlZWtfc3RhcnQuZ2V0RGF5KCkpO1xuXHRcdH1cblx0XHRpZih0aGlzLmxhc3Rfd2Vla19zdGFydC5nZXREYXkoKSAhPT0gNykge1xuXHRcdFx0dGhpcy5hZGRfZGF5cyh0aGlzLmxhc3Rfd2Vla19zdGFydCwgKC0xKSAqIHRoaXMubGFzdF93ZWVrX3N0YXJ0LmdldERheSgpKTtcblx0XHR9XG5cdFx0dGhpcy5ub19vZl9jb2xzID0gdGhpcy5nZXRfd2Vla3NfYmV0d2Vlbih0aGlzLmZpcnN0X3dlZWtfc3RhcnQgKyAnJywgdGhpcy5sYXN0X3dlZWtfc3RhcnQgKyAnJykgKyAxO1xuXHR9XG5cblx0c2V0X3dpZHRoKCkge1xuXHRcdHRoaXMuYmFzZV93aWR0aCA9ICh0aGlzLm5vX29mX2NvbHMpICogMTI7XG5cblx0XHRpZih0aGlzLmRpc2NyZXRlX2RvbWFpbnMpIHtcblx0XHRcdHRoaXMuYmFzZV93aWR0aCArPSAoMTIgKiAxMik7XG5cdFx0fVxuXHR9XG5cblx0c2V0dXBfY29tcG9uZW50cygpIHtcblx0XHR0aGlzLmRvbWFpbl9sYWJlbF9ncm91cCA9ICQkLmNyZWF0ZVNWRyhcImdcIiwge1xuXHRcdFx0Y2xhc3NOYW1lOiBcImRvbWFpbi1sYWJlbC1ncm91cCBjaGFydC1sYWJlbFwiLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmRyYXdfYXJlYVxuXHRcdH0pO1xuXHRcdHRoaXMuZGF0YV9ncm91cHMgPSAkJC5jcmVhdGVTVkcoXCJnXCIsIHtcblx0XHRcdGNsYXNzTmFtZTogXCJkYXRhLWdyb3Vwc1wiLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmRyYXdfYXJlYSxcblx0XHRcdHRyYW5zZm9ybTogYHRyYW5zbGF0ZSgwLCAyMClgXG5cdFx0fSk7XG5cdH1cblxuXHRzZXR1cF92YWx1ZXMoKSB7XG5cdFx0dGhpcy5kb21haW5fbGFiZWxfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLmRhdGFfZ3JvdXBzLnRleHRDb250ZW50ID0gJyc7XG5cdFx0dGhpcy5kaXN0cmlidXRpb24gPSB0aGlzLmdldF9kaXN0cmlidXRpb24odGhpcy5kYXRhLCB0aGlzLmxlZ2VuZF9jb2xvcnMpO1xuXHRcdHRoaXMubW9udGhfbmFtZXMgPSBbXCJKYW51YXJ5XCIsIFwiRmVicnVhcnlcIiwgXCJNYXJjaFwiLCBcIkFwcmlsXCIsIFwiTWF5XCIsIFwiSnVuZVwiLFxuXHRcdFx0XCJKdWx5XCIsIFwiQXVndXN0XCIsIFwiU2VwdGVtYmVyXCIsIFwiT2N0b2JlclwiLCBcIk5vdmVtYmVyXCIsIFwiRGVjZW1iZXJcIlxuXHRcdF07XG5cblx0XHR0aGlzLnJlbmRlcl9hbGxfd2Vla3NfYW5kX3N0b3JlX3hfdmFsdWVzKHRoaXMubm9fb2ZfY29scyk7XG5cdH1cblxuXHRyZW5kZXJfYWxsX3dlZWtzX2FuZF9zdG9yZV94X3ZhbHVlcyhub19vZl93ZWVrcykge1xuXHRcdGxldCBjdXJyZW50X3dlZWtfc3VuZGF5ID0gbmV3IERhdGUodGhpcy5maXJzdF93ZWVrX3N0YXJ0KTtcblx0XHR0aGlzLndlZWtfY29sID0gMDtcblx0XHR0aGlzLmN1cnJlbnRfbW9udGggPSBjdXJyZW50X3dlZWtfc3VuZGF5LmdldE1vbnRoKCk7XG5cblx0XHR0aGlzLm1vbnRocyA9IFt0aGlzLmN1cnJlbnRfbW9udGggKyAnJ107XG5cdFx0dGhpcy5tb250aF93ZWVrcyA9IHt9LCB0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cyA9IFtdO1xuXHRcdHRoaXMubW9udGhfd2Vla3NbdGhpcy5jdXJyZW50X21vbnRoXSA9IDA7XG5cdFx0dGhpcy5tb250aF9zdGFydF9wb2ludHMucHVzaCgxMyk7XG5cblx0XHRmb3IodmFyIGkgPSAwOyBpIDwgbm9fb2Zfd2Vla3M7IGkrKykge1xuXHRcdFx0bGV0IGRhdGFfZ3JvdXAsIG1vbnRoX2NoYW5nZSA9IDA7XG5cdFx0XHRsZXQgZGF5ID0gbmV3IERhdGUoY3VycmVudF93ZWVrX3N1bmRheSk7XG5cblx0XHRcdFtkYXRhX2dyb3VwLCBtb250aF9jaGFuZ2VdID0gdGhpcy5nZXRfd2Vla19zcXVhcmVzX2dyb3VwKGRheSwgdGhpcy53ZWVrX2NvbCk7XG5cdFx0XHR0aGlzLmRhdGFfZ3JvdXBzLmFwcGVuZENoaWxkKGRhdGFfZ3JvdXApO1xuXHRcdFx0dGhpcy53ZWVrX2NvbCArPSAxICsgcGFyc2VJbnQodGhpcy5kaXNjcmV0ZV9kb21haW5zICYmIG1vbnRoX2NoYW5nZSk7XG5cdFx0XHR0aGlzLm1vbnRoX3dlZWtzW3RoaXMuY3VycmVudF9tb250aF0rKztcblx0XHRcdGlmKG1vbnRoX2NoYW5nZSkge1xuXHRcdFx0XHR0aGlzLmN1cnJlbnRfbW9udGggPSAodGhpcy5jdXJyZW50X21vbnRoICsgMSkgJSAxMjtcblx0XHRcdFx0dGhpcy5tb250aHMucHVzaCh0aGlzLmN1cnJlbnRfbW9udGggKyAnJyk7XG5cdFx0XHRcdHRoaXMubW9udGhfd2Vla3NbdGhpcy5jdXJyZW50X21vbnRoXSA9IDE7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmFkZF9kYXlzKGN1cnJlbnRfd2Vla19zdW5kYXksIDcpO1xuXHRcdH1cblx0XHR0aGlzLnJlbmRlcl9tb250aF9sYWJlbHMoKTtcblx0fVxuXG5cdGdldF93ZWVrX3NxdWFyZXNfZ3JvdXAoY3VycmVudF9kYXRlLCBpbmRleCkge1xuXHRcdGNvbnN0IG5vX29mX3dlZWtkYXlzID0gNztcblx0XHRjb25zdCBzcXVhcmVfc2lkZSA9IDEwO1xuXHRcdGNvbnN0IGNlbGxfcGFkZGluZyA9IDI7XG5cdFx0Y29uc3Qgc3RlcCA9IDE7XG5cblx0XHRsZXQgbW9udGhfY2hhbmdlID0gMDtcblx0XHRsZXQgd2Vla19jb2xfY2hhbmdlID0gMDtcblxuXHRcdGxldCBkYXRhX2dyb3VwID0gJCQuY3JlYXRlU1ZHKFwiZ1wiLCB7XG5cdFx0XHRjbGFzc05hbWU6IFwiZGF0YS1ncm91cFwiLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmRhdGFfZ3JvdXBzXG5cdFx0fSk7XG5cblx0XHRmb3IodmFyIHkgPSAwLCBpID0gMDsgaSA8IG5vX29mX3dlZWtkYXlzOyBpICs9IHN0ZXAsIHkgKz0gKHNxdWFyZV9zaWRlICsgY2VsbF9wYWRkaW5nKSkge1xuXHRcdFx0bGV0IGRhdGFfdmFsdWUgPSAwO1xuXHRcdFx0bGV0IGNvbG9yX2luZGV4ID0gMDtcblxuXHRcdFx0bGV0IHRpbWVzdGFtcCA9IE1hdGguZmxvb3IoY3VycmVudF9kYXRlLmdldFRpbWUoKS8xMDAwKS50b0ZpeGVkKDEpO1xuXG5cdFx0XHRpZih0aGlzLmRhdGFbdGltZXN0YW1wXSkge1xuXHRcdFx0XHRkYXRhX3ZhbHVlID0gdGhpcy5kYXRhW3RpbWVzdGFtcF07XG5cdFx0XHRcdGNvbG9yX2luZGV4ID0gdGhpcy5nZXRfbWF4X2NoZWNrcG9pbnQoZGF0YV92YWx1ZSwgdGhpcy5kaXN0cmlidXRpb24pO1xuXHRcdFx0fVxuXG5cdFx0XHRpZih0aGlzLmRhdGFbTWF0aC5yb3VuZCh0aW1lc3RhbXApXSkge1xuXHRcdFx0XHRkYXRhX3ZhbHVlID0gdGhpcy5kYXRhW01hdGgucm91bmQodGltZXN0YW1wKV07XG5cdFx0XHRcdGNvbG9yX2luZGV4ID0gdGhpcy5nZXRfbWF4X2NoZWNrcG9pbnQoZGF0YV92YWx1ZSwgdGhpcy5kaXN0cmlidXRpb24pO1xuXHRcdFx0fVxuXG5cdFx0XHRsZXQgeCA9IDEzICsgKGluZGV4ICsgd2Vla19jb2xfY2hhbmdlKSAqIDEyO1xuXG5cdFx0XHQkJC5jcmVhdGVTVkcoXCJyZWN0XCIsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAnZGF5Jyxcblx0XHRcdFx0aW5zaWRlOiBkYXRhX2dyb3VwLFxuXHRcdFx0XHR4OiB4LFxuXHRcdFx0XHR5OiB5LFxuXHRcdFx0XHR3aWR0aDogc3F1YXJlX3NpZGUsXG5cdFx0XHRcdGhlaWdodDogc3F1YXJlX3NpZGUsXG5cdFx0XHRcdGZpbGw6ICB0aGlzLmxlZ2VuZF9jb2xvcnNbY29sb3JfaW5kZXhdLFxuXHRcdFx0XHQnZGF0YS1kYXRlJzogdGhpcy5nZXRfZGRfbW1feXl5eShjdXJyZW50X2RhdGUpLFxuXHRcdFx0XHQnZGF0YS12YWx1ZSc6IGRhdGFfdmFsdWUsXG5cdFx0XHRcdCdkYXRhLWRheSc6IGN1cnJlbnRfZGF0ZS5nZXREYXkoKVxuXHRcdFx0fSk7XG5cblx0XHRcdGxldCBuZXh0X2RhdGUgPSBuZXcgRGF0ZShjdXJyZW50X2RhdGUpO1xuXHRcdFx0dGhpcy5hZGRfZGF5cyhuZXh0X2RhdGUsIDEpO1xuXHRcdFx0aWYobmV4dF9kYXRlLmdldE1vbnRoKCkgLSBjdXJyZW50X2RhdGUuZ2V0TW9udGgoKSkge1xuXHRcdFx0XHRtb250aF9jaGFuZ2UgPSAxO1xuXHRcdFx0XHRpZih0aGlzLmRpc2NyZXRlX2RvbWFpbnMpIHtcblx0XHRcdFx0XHR3ZWVrX2NvbF9jaGFuZ2UgPSAxO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5tb250aF9zdGFydF9wb2ludHMucHVzaCgxMyArIChpbmRleCArIHdlZWtfY29sX2NoYW5nZSkgKiAxMik7XG5cdFx0XHR9XG5cdFx0XHRjdXJyZW50X2RhdGUgPSBuZXh0X2RhdGU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtkYXRhX2dyb3VwLCBtb250aF9jaGFuZ2VdO1xuXHR9XG5cblx0cmVuZGVyX21vbnRoX2xhYmVscygpIHtcblx0XHQvLyB0aGlzLmZpcnN0X21vbnRoX2xhYmVsID0gMTtcblx0XHQvLyBpZiAodGhpcy5maXJzdF93ZWVrX3N0YXJ0LmdldERhdGUoKSA+IDgpIHtcblx0XHQvLyBcdHRoaXMuZmlyc3RfbW9udGhfbGFiZWwgPSAwO1xuXHRcdC8vIH1cblx0XHQvLyB0aGlzLmxhc3RfbW9udGhfbGFiZWwgPSAxO1xuXG5cdFx0Ly8gbGV0IGZpcnN0X21vbnRoID0gdGhpcy5tb250aHMuc2hpZnQoKTtcblx0XHQvLyBsZXQgZmlyc3RfbW9udGhfc3RhcnQgPSB0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cy5zaGlmdCgpO1xuXHRcdC8vIHJlbmRlciBmaXJzdCBtb250aCBpZlxuXG5cdFx0Ly8gbGV0IGxhc3RfbW9udGggPSB0aGlzLm1vbnRocy5wb3AoKTtcblx0XHQvLyBsZXQgbGFzdF9tb250aF9zdGFydCA9IHRoaXMubW9udGhfc3RhcnRfcG9pbnRzLnBvcCgpO1xuXHRcdC8vIHJlbmRlciBsYXN0IG1vbnRoIGlmXG5cblx0XHR0aGlzLm1vbnRocy5zaGlmdCgpO1xuXHRcdHRoaXMubW9udGhfc3RhcnRfcG9pbnRzLnNoaWZ0KCk7XG5cdFx0dGhpcy5tb250aHMucG9wKCk7XG5cdFx0dGhpcy5tb250aF9zdGFydF9wb2ludHMucG9wKCk7XG5cblx0XHR0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cy5tYXAoKHN0YXJ0LCBpKSA9PiB7XG5cdFx0XHRsZXQgbW9udGhfbmFtZSA9ICB0aGlzLm1vbnRoX25hbWVzW3RoaXMubW9udGhzW2ldXS5zdWJzdHJpbmcoMCwgMyk7XG5cblx0XHRcdCQkLmNyZWF0ZVNWRygndGV4dCcsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAneS12YWx1ZS10ZXh0Jyxcblx0XHRcdFx0aW5zaWRlOiB0aGlzLmRvbWFpbl9sYWJlbF9ncm91cCxcblx0XHRcdFx0eDogc3RhcnQgKyAxMixcblx0XHRcdFx0eTogMTAsXG5cdFx0XHRcdGR5OiAnLjMyZW0nLFxuXHRcdFx0XHRpbm5lckhUTUw6IG1vbnRoX25hbWVcblx0XHRcdH0pO1xuXG5cdFx0fSk7XG5cdH1cblxuXHRtYWtlX2dyYXBoX2NvbXBvbmVudHMoKSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoXG5cdFx0XHR0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuZ3JhcGgtc3RhdHMtY29udGFpbmVyLCAuc3ViLXRpdGxlLCAudGl0bGUnKVxuXHRcdCkubWFwKGQgPT4ge1xuXHRcdFx0ZC5zdHlsZS5kaXNwbGF5ID0gJ05vbmUnO1xuXHRcdH0pO1xuXHRcdHRoaXMuY2hhcnRfd3JhcHBlci5zdHlsZS5tYXJnaW5Ub3AgPSAnMHB4Jztcblx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIuc3R5bGUucGFkZGluZ1RvcCA9ICcwcHgnO1xuXHR9XG5cblx0YmluZF90b29sdGlwKCkge1xuXHRcdEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKFxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5kYXRhLWdyb3VwIC5kYXlcIilcblx0XHQpLm1hcChlbCA9PiB7XG5cdFx0XHRlbC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWVudGVyJywgKGUpID0+IHtcblx0XHRcdFx0bGV0IGNvdW50ID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyk7XG5cdFx0XHRcdGxldCBkYXRlX3BhcnRzID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWRhdGUnKS5zcGxpdCgnLScpO1xuXG5cdFx0XHRcdGxldCBtb250aCA9IHRoaXMubW9udGhfbmFtZXNbcGFyc2VJbnQoZGF0ZV9wYXJ0c1sxXSktMV0uc3Vic3RyaW5nKDAsIDMpO1xuXG5cdFx0XHRcdGxldCBnX29mZiA9IHRoaXMuY2hhcnRfd3JhcHBlci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgcF9vZmYgPSBlLnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuXHRcdFx0XHRsZXQgd2lkdGggPSBwYXJzZUludChlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ3dpZHRoJykpO1xuXHRcdFx0XHRsZXQgeCA9IHBfb2ZmLmxlZnQgLSBnX29mZi5sZWZ0ICsgKHdpZHRoKzIpLzI7XG5cdFx0XHRcdGxldCB5ID0gcF9vZmYudG9wIC0gZ19vZmYudG9wIC0gKHdpZHRoKzIpLzI7XG5cdFx0XHRcdGxldCB2YWx1ZSA9IGNvdW50ICsgJyAnICsgdGhpcy5jb3VudF9sYWJlbDtcblx0XHRcdFx0bGV0IG5hbWUgPSAnIG9uICcgKyBtb250aCArICcgJyArIGRhdGVfcGFydHNbMF0gKyAnLCAnICsgZGF0ZV9wYXJ0c1syXTtcblxuXHRcdFx0XHR0aGlzLnRpcC5zZXRfdmFsdWVzKHgsIHksIG5hbWUsIHZhbHVlLCBbXSwgMSk7XG5cdFx0XHRcdHRoaXMudGlwLnNob3dfdGlwKCk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdHVwZGF0ZShkYXRhKSB7XG5cdFx0dGhpcy5kYXRhID0gZGF0YTtcblx0XHR0aGlzLnNldHVwX3ZhbHVlcygpO1xuXHRcdHRoaXMuYmluZF90b29sdGlwKCk7XG5cdH1cblxuXHRnZXRfZGlzdHJpYnV0aW9uKGRhdGE9e30sIG1hcHBlcl9hcnJheSkge1xuXHRcdGxldCBkYXRhX3ZhbHVlcyA9IE9iamVjdC5rZXlzKGRhdGEpLm1hcChrZXkgPT4gZGF0YVtrZXldKTtcblx0XHRsZXQgZGF0YV9tYXhfdmFsdWUgPSBNYXRoLm1heCguLi5kYXRhX3ZhbHVlcyk7XG5cblx0XHRsZXQgZGlzdHJpYnV0aW9uX3N0ZXAgPSAxIC8gKG1hcHBlcl9hcnJheS5sZW5ndGggLSAxKTtcblx0XHRsZXQgZGlzdHJpYnV0aW9uID0gW107XG5cblx0XHRtYXBwZXJfYXJyYXkubWFwKChjb2xvciwgaSkgPT4ge1xuXHRcdFx0bGV0IGNoZWNrcG9pbnQgPSBkYXRhX21heF92YWx1ZSAqIChkaXN0cmlidXRpb25fc3RlcCAqIGkpO1xuXHRcdFx0ZGlzdHJpYnV0aW9uLnB1c2goY2hlY2twb2ludCk7XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gZGlzdHJpYnV0aW9uO1xuXHR9XG5cblx0Z2V0X21heF9jaGVja3BvaW50KHZhbHVlLCBkaXN0cmlidXRpb24pIHtcblx0XHRyZXR1cm4gZGlzdHJpYnV0aW9uLmZpbHRlcigoZCwgaSkgPT4ge1xuXHRcdFx0aWYoaSA9PT0gMSkge1xuXHRcdFx0XHRyZXR1cm4gZGlzdHJpYnV0aW9uWzBdIDwgdmFsdWU7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZCA8PSB2YWx1ZTtcblx0XHR9KS5sZW5ndGggLSAxO1xuXHR9XG5cblx0Ly8gVE9ETzogZGF0ZSB1dGlscywgbW92ZSB0aGVzZSBvdXRcblxuXHQvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTEyNTIxNjcvNjQ5NTA0M1xuXHR0cmVhdF9hc191dGMoZGF0ZV9zdHIpIHtcblx0XHRsZXQgcmVzdWx0ID0gbmV3IERhdGUoZGF0ZV9zdHIpO1xuXHRcdHJlc3VsdC5zZXRNaW51dGVzKHJlc3VsdC5nZXRNaW51dGVzKCkgLSByZXN1bHQuZ2V0VGltZXpvbmVPZmZzZXQoKSk7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdGdldF9kZF9tbV95eXl5KGRhdGUpIHtcblx0XHRsZXQgZGQgPSBkYXRlLmdldERhdGUoKTtcblx0XHRsZXQgbW0gPSBkYXRlLmdldE1vbnRoKCkgKyAxOyAvLyBnZXRNb250aCgpIGlzIHplcm8tYmFzZWRcblx0XHRyZXR1cm4gW1xuXHRcdFx0KGRkPjkgPyAnJyA6ICcwJykgKyBkZCxcblx0XHRcdChtbT45ID8gJycgOiAnMCcpICsgbW0sXG5cdFx0XHRkYXRlLmdldEZ1bGxZZWFyKClcblx0XHRdLmpvaW4oJy0nKTtcblx0fVxuXG5cdGdldF93ZWVrc19iZXR3ZWVuKHN0YXJ0X2RhdGVfc3RyLCBlbmRfZGF0ZV9zdHIpIHtcblx0XHRyZXR1cm4gTWF0aC5jZWlsKHRoaXMuZ2V0X2RheXNfYmV0d2VlbihzdGFydF9kYXRlX3N0ciwgZW5kX2RhdGVfc3RyKSAvIDcpO1xuXHR9XG5cblx0Z2V0X2RheXNfYmV0d2VlbihzdGFydF9kYXRlX3N0ciwgZW5kX2RhdGVfc3RyKSB7XG5cdFx0bGV0IG1pbGxpc2Vjb25kc19wZXJfZGF5ID0gMjQgKiA2MCAqIDYwICogMTAwMDtcblx0XHRyZXR1cm4gKHRoaXMudHJlYXRfYXNfdXRjKGVuZF9kYXRlX3N0cikgLSB0aGlzLnRyZWF0X2FzX3V0YyhzdGFydF9kYXRlX3N0cikpIC8gbWlsbGlzZWNvbmRzX3Blcl9kYXk7XG5cdH1cblxuXHQvLyBtdXRhdGVzXG5cdGFkZF9kYXlzKGRhdGUsIG51bWJlcl9vZl9kYXlzKSB7XG5cdFx0ZGF0ZS5zZXREYXRlKGRhdGUuZ2V0RGF0ZSgpICsgbnVtYmVyX29mX2RheXMpO1xuXHR9XG5cblx0Z2V0X21vbnRoX25hbWUoKSB7fVxufVxuXG5mcmFwcGUuY2hhcnQuU3ZnVGlwID0gY2xhc3Mge1xuXHRjb25zdHJ1Y3Rvcih7XG5cdFx0cGFyZW50ID0gbnVsbFxuXHR9KSB7XG5cdFx0dGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG5cdFx0dGhpcy50aXRsZV9uYW1lID0gJyc7XG5cdFx0dGhpcy50aXRsZV92YWx1ZSA9ICcnO1xuXHRcdHRoaXMubGlzdF92YWx1ZXMgPSBbXTtcblx0XHR0aGlzLnRpdGxlX3ZhbHVlX2ZpcnN0ID0gMDtcblxuXHRcdHRoaXMueCA9IDA7XG5cdFx0dGhpcy55ID0gMDtcblxuXHRcdHRoaXMudG9wID0gMDtcblx0XHR0aGlzLmxlZnQgPSAwO1xuXG5cdFx0dGhpcy5zZXR1cCgpO1xuXHR9XG5cblx0c2V0dXAoKSB7XG5cdFx0dGhpcy5tYWtlX3Rvb2x0aXAoKTtcblx0fVxuXG5cdHJlZnJlc2goKSB7XG5cdFx0dGhpcy5maWxsKCk7XG5cdFx0dGhpcy5jYWxjX3Bvc2l0aW9uKCk7XG5cdFx0Ly8gdGhpcy5zaG93X3RpcCgpO1xuXHR9XG5cblx0bWFrZV90b29sdGlwKCkge1xuXHRcdHRoaXMuY29udGFpbmVyID0gJCQuY3JlYXRlKCdkaXYnLCB7XG5cdFx0XHRpbnNpZGU6IHRoaXMucGFyZW50LFxuXHRcdFx0Y2xhc3NOYW1lOiAnZ3JhcGgtc3ZnLXRpcCBjb21wYXJpc29uJyxcblx0XHRcdGlubmVySFRNTDogYDxzcGFuIGNsYXNzPVwidGl0bGVcIj48L3NwYW4+XG5cdFx0XHRcdDx1bCBjbGFzcz1cImRhdGEtcG9pbnQtbGlzdFwiPjwvdWw+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJzdmctcG9pbnRlclwiPjwvZGl2PmBcblx0XHR9KTtcblx0XHR0aGlzLmhpZGVfdGlwKCk7XG5cblx0XHR0aGlzLnRpdGxlID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcignLnRpdGxlJyk7XG5cdFx0dGhpcy5kYXRhX3BvaW50X2xpc3QgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcuZGF0YS1wb2ludC1saXN0Jyk7XG5cblx0XHR0aGlzLnBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgKCkgPT4ge1xuXHRcdFx0dGhpcy5oaWRlX3RpcCgpO1xuXHRcdH0pO1xuXHR9XG5cblx0ZmlsbCgpIHtcblx0XHRsZXQgdGl0bGU7XG5cdFx0aWYodGhpcy50aXRsZV92YWx1ZV9maXJzdCkge1xuXHRcdFx0dGl0bGUgPSBgPHN0cm9uZz4ke3RoaXMudGl0bGVfdmFsdWV9PC9zdHJvbmc+JHt0aGlzLnRpdGxlX25hbWV9YDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGl0bGUgPSBgJHt0aGlzLnRpdGxlX25hbWV9PHN0cm9uZz4ke3RoaXMudGl0bGVfdmFsdWV9PC9zdHJvbmc+YDtcblx0XHR9XG5cdFx0dGhpcy50aXRsZS5pbm5lckhUTUwgPSB0aXRsZTtcblx0XHR0aGlzLmRhdGFfcG9pbnRfbGlzdC5pbm5lckhUTUwgPSAnJztcblxuXHRcdHRoaXMubGlzdF92YWx1ZXMubWFwKChzZXQpID0+IHtcblx0XHRcdGxldCBsaSA9ICQkLmNyZWF0ZSgnbGknLCB7XG5cdFx0XHRcdGNsYXNzTmFtZTogYGJvcmRlci10b3AgJHtzZXQuY29sb3IgfHwgJ2JsYWNrJ31gLFxuXHRcdFx0XHRpbm5lckhUTUw6IGA8c3Ryb25nIHN0eWxlPVwiZGlzcGxheTogYmxvY2s7XCI+JHtzZXQudmFsdWUgPyBzZXQudmFsdWUgOiAnJyB9PC9zdHJvbmc+XG5cdFx0XHRcdFx0JHtzZXQudGl0bGUgPyBzZXQudGl0bGUgOiAnJyB9YFxuXHRcdFx0fSk7XG5cblx0XHRcdHRoaXMuZGF0YV9wb2ludF9saXN0LmFwcGVuZENoaWxkKGxpKTtcblx0XHR9KTtcblx0fVxuXG5cdGNhbGNfcG9zaXRpb24oKSB7XG5cdFx0dGhpcy50b3AgPSB0aGlzLnkgLSB0aGlzLmNvbnRhaW5lci5vZmZzZXRIZWlnaHQ7XG5cdFx0dGhpcy5sZWZ0ID0gdGhpcy54IC0gdGhpcy5jb250YWluZXIub2Zmc2V0V2lkdGgvMjtcblx0XHRsZXQgbWF4X2xlZnQgPSB0aGlzLnBhcmVudC5vZmZzZXRXaWR0aCAtIHRoaXMuY29udGFpbmVyLm9mZnNldFdpZHRoO1xuXG5cdFx0bGV0IHBvaW50ZXIgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcuc3ZnLXBvaW50ZXInKTtcblxuXHRcdGlmKHRoaXMubGVmdCA8IDApIHtcblx0XHRcdHBvaW50ZXIuc3R5bGUubGVmdCA9IGBjYWxjKDUwJSAtICR7LTEgKiB0aGlzLmxlZnR9cHgpYDtcblx0XHRcdHRoaXMubGVmdCA9IDA7XG5cdFx0fSBlbHNlIGlmKHRoaXMubGVmdCA+IG1heF9sZWZ0KSB7XG5cdFx0XHRsZXQgZGVsdGEgPSB0aGlzLmxlZnQgLSBtYXhfbGVmdDtcblx0XHRcdHBvaW50ZXIuc3R5bGUubGVmdCA9IGBjYWxjKDUwJSArICR7ZGVsdGF9cHgpYDtcblx0XHRcdHRoaXMubGVmdCA9IG1heF9sZWZ0O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwb2ludGVyLnN0eWxlLmxlZnQgPSBgNTAlYDtcblx0XHR9XG5cdH1cblxuXHRzZXRfdmFsdWVzKHgsIHksIHRpdGxlX25hbWUgPSAnJywgdGl0bGVfdmFsdWUgPSAnJywgbGlzdF92YWx1ZXMgPSBbXSwgdGl0bGVfdmFsdWVfZmlyc3QgPSAwKSB7XG5cdFx0dGhpcy50aXRsZV9uYW1lID0gdGl0bGVfbmFtZTtcblx0XHR0aGlzLnRpdGxlX3ZhbHVlID0gdGl0bGVfdmFsdWU7XG5cdFx0dGhpcy5saXN0X3ZhbHVlcyA9IGxpc3RfdmFsdWVzO1xuXHRcdHRoaXMueCA9IHg7XG5cdFx0dGhpcy55ID0geTtcblx0XHR0aGlzLnRpdGxlX3ZhbHVlX2ZpcnN0ID0gdGl0bGVfdmFsdWVfZmlyc3Q7XG5cdFx0dGhpcy5yZWZyZXNoKCk7XG5cdH1cblxuXHRoaWRlX3RpcCgpIHtcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS50b3AgPSAnMHB4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gJzBweCc7XG5cdFx0dGhpcy5jb250YWluZXIuc3R5bGUub3BhY2l0eSA9ICcwJztcblx0fVxuXG5cdHNob3dfdGlwKCkge1xuXHRcdHRoaXMuY29udGFpbmVyLnN0eWxlLnRvcCA9IHRoaXMudG9wICsgJ3B4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gdGhpcy5sZWZ0ICsgJ3B4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5vcGFjaXR5ID0gJzEnO1xuXHR9XG59XG5cbi8vIEhlbHBlcnNcbmZyYXBwZS5jaGFydC51dGlscyA9IHt9O1xuJCQuZmxvYXRfMiA9IGQgPT4gcGFyc2VGbG9hdChkLnRvRml4ZWQoMikpO1xuZnVuY3Rpb24gJCQoZXhwciwgY29uKSB7XG5cdHJldHVybiB0eXBlb2YgZXhwciA9PT0gXCJzdHJpbmdcIj8gKGNvbiB8fCBkb2N1bWVudCkucXVlcnlTZWxlY3RvcihleHByKSA6IGV4cHIgfHwgbnVsbDtcbn1cblxuJCQuYXJyYXlzX2VxdWFsID0gKGFycjEsIGFycjIpID0+IHtcblx0aWYoYXJyMS5sZW5ndGggIT09IGFycjIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cdGxldCBhcmVfZXF1YWwgPSB0cnVlO1xuXHRhcnIxLm1hcCgoZCwgaSkgPT4ge1xuXHRcdGlmKGFycjJbaV0gIT09IGQpIGFyZV9lcXVhbCA9IGZhbHNlO1xuXHR9KTtcblx0cmV0dXJuIGFyZV9lcXVhbDtcbn1cblxuJCQuc2h1ZmZsZSA9IChhcnJheSkgPT4ge1xuXHQvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjQ1MDk3Ni82NDk1MDQzXG5cdC8vIEF3ZXNvbWVuZXNzOiBodHRwczovL2Jvc3Qub2Nrcy5vcmcvbWlrZS9zaHVmZmxlL1xuXG5cdHZhciBjdXJyZW50SW5kZXggPSBhcnJheS5sZW5ndGgsIHRlbXBvcmFyeVZhbHVlLCByYW5kb21JbmRleDtcblxuXHQvLyBXaGlsZSB0aGVyZSByZW1haW4gZWxlbWVudHMgdG8gc2h1ZmZsZS4uLlxuXHR3aGlsZSAoMCAhPT0gY3VycmVudEluZGV4KSB7XG5cblx0XHQvLyBQaWNrIGEgcmVtYWluaW5nIGVsZW1lbnQuLi5cblx0XHRyYW5kb21JbmRleCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGN1cnJlbnRJbmRleCk7XG5cdFx0Y3VycmVudEluZGV4IC09IDE7XG5cblx0XHQvLyBBbmQgc3dhcCBpdCB3aXRoIHRoZSBjdXJyZW50IGVsZW1lbnQuXG5cdFx0dGVtcG9yYXJ5VmFsdWUgPSBhcnJheVtjdXJyZW50SW5kZXhdO1xuXHRcdGFycmF5W2N1cnJlbnRJbmRleF0gPSBhcnJheVtyYW5kb21JbmRleF07XG5cdFx0YXJyYXlbcmFuZG9tSW5kZXhdID0gdGVtcG9yYXJ5VmFsdWU7XG5cdH1cblxuXHRyZXR1cm4gYXJyYXk7XG5cbn1cblxuLy8gJCQuZmluZE5vZGVJbmRleCA9IChub2RlKSA9PlxuLy8ge1xuLy8gXHR2YXIgaSA9IDA7XG4vLyBcdHdoaWxlIChub2RlID0gbm9kZS5wcmV2aW91c1NpYmxpbmcpIHtcbi8vIFx0XHRpZiAobm9kZS5ub2RlVHlwZSA9PT0gMSkgeyArK2k7IH1cbi8vIFx0fVxuLy8gXHRyZXR1cm4gaTtcbi8vIH1cblxuJCQuY3JlYXRlID0gZnVuY3Rpb24odGFnLCBvKSB7XG5cdHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpO1xuXG5cdGZvciAodmFyIGkgaW4gbykge1xuXHRcdHZhciB2YWwgPSBvW2ldO1xuXG5cdFx0aWYgKGkgPT09IFwiaW5zaWRlXCIpIHtcblx0XHRcdCQkKHZhbCkuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKGkgPT09IFwiYXJvdW5kXCIpIHtcblx0XHRcdHZhciByZWYgPSAkJCh2YWwpO1xuXHRcdFx0cmVmLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsZW1lbnQsIHJlZik7XG5cdFx0XHRlbGVtZW50LmFwcGVuZENoaWxkKHJlZik7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKGkgaW4gZWxlbWVudCkge1xuXHRcdFx0ZWxlbWVudFtpXSA9IHZhbDtcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHRlbGVtZW50LnNldEF0dHJpYnV0ZShpLCB2YWwpO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtZW50O1xufTtcblxuJCQuY3JlYXRlU1ZHID0gZnVuY3Rpb24odGFnLCBvKSB7XG5cdHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiwgdGFnKTtcblxuXHRmb3IgKHZhciBpIGluIG8pIHtcblx0XHR2YXIgdmFsID0gb1tpXTtcblxuXHRcdGlmIChpID09PSBcImluc2lkZVwiKSB7XG5cdFx0XHQkJCh2YWwpLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuXHRcdH1cblx0XHRlbHNlIGlmIChpID09PSBcImFyb3VuZFwiKSB7XG5cdFx0XHR2YXIgcmVmID0gJCQodmFsKTtcblx0XHRcdHJlZi5wYXJlbnROb2RlLmluc2VydEJlZm9yZShlbGVtZW50LCByZWYpO1xuXHRcdFx0ZWxlbWVudC5hcHBlbmRDaGlsZChyZWYpO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGlmKGkgPT09IFwiY2xhc3NOYW1lXCIpIHsgaSA9IFwiY2xhc3NcIjsgfVxuXHRcdFx0aWYoaSA9PT0gXCJpbm5lckhUTUxcIikge1xuXHRcdFx0XHRlbGVtZW50Wyd0ZXh0Q29udGVudCddID0gdmFsO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbWVudC5zZXRBdHRyaWJ1dGUoaSwgdmFsKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZWxlbWVudDtcbn07XG5cbiQkLnJ1blNWR0FuaW1hdGlvbiA9IChzdmdfY29udGFpbmVyLCBlbGVtZW50cykgPT4ge1xuXHQvLyBsZXQgcGFyZW50ID0gZWxlbWVudHNbMF1bMF1bJ3VuaXQnXS5wYXJlbnROb2RlO1xuXG5cdGxldCBuZXdfZWxlbWVudHMgPSBbXTtcblx0bGV0IGFuaW1fZWxlbWVudHMgPSBbXTtcblxuXHRlbGVtZW50cy5tYXAoZWxlbWVudCA9PiB7XG5cdFx0bGV0IG9iaiA9IGVsZW1lbnRbMF07XG5cdFx0bGV0IHBhcmVudCA9IG9iai51bml0LnBhcmVudE5vZGU7XG5cdFx0Ly8gbGV0IGluZGV4ID0gJCQuZmluZE5vZGVJbmRleChvYmoudW5pdCk7XG5cblx0XHRsZXQgYW5pbV9lbGVtZW50LCBuZXdfZWxlbWVudDtcblxuXHRcdGVsZW1lbnRbMF0gPSBvYmoudW5pdDtcblxuXHRcdFthbmltX2VsZW1lbnQsIG5ld19lbGVtZW50XSA9ICQkLmFuaW1hdGVTVkcoLi4uZWxlbWVudCk7XG5cblx0XHRuZXdfZWxlbWVudHMucHVzaChuZXdfZWxlbWVudCk7XG5cdFx0YW5pbV9lbGVtZW50cy5wdXNoKFthbmltX2VsZW1lbnQsIHBhcmVudF0pO1xuXG5cdFx0cGFyZW50LnJlcGxhY2VDaGlsZChhbmltX2VsZW1lbnQsIG9iai51bml0KTtcblxuXHRcdGlmKG9iai5hcnJheSkge1xuXHRcdFx0b2JqLmFycmF5W29iai5pbmRleF0gPSBuZXdfZWxlbWVudDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0b2JqLm9iamVjdFtvYmoua2V5XSA9IG5ld19lbGVtZW50O1xuXHRcdH1cblx0fSk7XG5cblx0bGV0IGFuaW1fc3ZnID0gc3ZnX2NvbnRhaW5lci5jbG9uZU5vZGUodHJ1ZSk7XG5cblx0YW5pbV9lbGVtZW50cy5tYXAoKGFuaW1fZWxlbWVudCwgaSkgPT4ge1xuXHRcdGFuaW1fZWxlbWVudFsxXS5yZXBsYWNlQ2hpbGQobmV3X2VsZW1lbnRzW2ldLCBhbmltX2VsZW1lbnRbMF0pO1xuXHRcdGVsZW1lbnRzW2ldWzBdID0gbmV3X2VsZW1lbnRzW2ldO1xuXHR9KTtcblxuXHRyZXR1cm4gYW5pbV9zdmc7XG59XG5cbi8vICQkLmFuaW1hdGVNb3Rpb24gPSAoZWxlbWVudCwgcHJvcHMsIGR1ciwgZWFzaW5nX3R5cGU9XCJsaW5lYXJcIilcblxuJCQuYW5pbWF0ZVNWRyA9IChlbGVtZW50LCBwcm9wcywgZHVyLCBlYXNpbmdfdHlwZT1cImxpbmVhclwiLCB0eXBlPXVuZGVmaW5lZCwgb2xkX3ZhbHVlcz17fSkgPT4ge1xuXHRsZXQgZWFzaW5nID0ge1xuXHRcdGVhc2U6IFwiMC4yNSAwLjEgMC4yNSAxXCIsXG5cdFx0bGluZWFyOiBcIjAgMCAxIDFcIixcblx0XHQvLyBlYXNlaW46IFwiMC40MiAwIDEgMVwiLFxuXHRcdGVhc2VpbjogXCIwLjEgMC44IDAuMiAxXCIsXG5cdFx0ZWFzZW91dDogXCIwIDAgMC41OCAxXCIsXG5cdFx0ZWFzZWlub3V0OiBcIjAuNDIgMCAwLjU4IDFcIlxuXHR9XG5cblx0bGV0IGFuaW1fZWxlbWVudCA9IGVsZW1lbnQuY2xvbmVOb2RlKHRydWUpO1xuXHRsZXQgbmV3X2VsZW1lbnQgPSBlbGVtZW50LmNsb25lTm9kZSh0cnVlKTtcblxuXHRmb3IodmFyIGF0dHJpYnV0ZU5hbWUgaW4gcHJvcHMpIHtcblx0XHRsZXQgYW5pbWF0ZV9lbGVtZW50O1xuXHRcdGlmKGF0dHJpYnV0ZU5hbWUgPT09ICd0cmFuc2Zvcm0nKSB7XG5cdFx0XHRhbmltYXRlX2VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCBcImFuaW1hdGVUcmFuc2Zvcm1cIik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFuaW1hdGVfZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwiYW5pbWF0ZVwiKTtcblx0XHR9XG5cdFx0bGV0IGN1cnJlbnRfdmFsdWUgPSBvbGRfdmFsdWVzW2F0dHJpYnV0ZU5hbWVdIHx8IGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpO1xuXHRcdGxldCB2YWx1ZSA9IHByb3BzW2F0dHJpYnV0ZU5hbWVdO1xuXG5cdFx0bGV0IGFuaW1fYXR0ciA9IHtcblx0XHRcdGF0dHJpYnV0ZU5hbWU6IGF0dHJpYnV0ZU5hbWUsXG5cdFx0XHRmcm9tOiBjdXJyZW50X3ZhbHVlLFxuXHRcdFx0dG86IHZhbHVlLFxuXHRcdFx0YmVnaW46IFwiMHNcIixcblx0XHRcdGR1cjogZHVyLzEwMDAgKyBcInNcIixcblx0XHRcdHZhbHVlczogY3VycmVudF92YWx1ZSArIFwiO1wiICsgdmFsdWUsXG5cdFx0XHRrZXlTcGxpbmVzOiBlYXNpbmdbZWFzaW5nX3R5cGVdLFxuXHRcdFx0a2V5VGltZXM6IFwiMDsxXCIsXG5cdFx0XHRjYWxjTW9kZTogXCJzcGxpbmVcIixcblx0XHRcdGZpbGw6ICdmcmVlemUnXG5cdFx0fVxuXG5cdFx0aWYodHlwZSkge1xuXHRcdFx0YW5pbV9hdHRyW1widHlwZVwiXSA9IHR5cGU7XG5cdFx0fVxuXG5cdFx0Zm9yICh2YXIgaSBpbiBhbmltX2F0dHIpIHtcblx0XHRcdGFuaW1hdGVfZWxlbWVudC5zZXRBdHRyaWJ1dGUoaSwgYW5pbV9hdHRyW2ldKTtcblx0XHR9XG5cblx0XHRhbmltX2VsZW1lbnQuYXBwZW5kQ2hpbGQoYW5pbWF0ZV9lbGVtZW50KTtcblxuXHRcdGlmKHR5cGUpIHtcblx0XHRcdG5ld19lbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCBgdHJhbnNsYXRlKCR7dmFsdWV9KWApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRuZXdfZWxlbWVudC5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSwgdmFsdWUpO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBbYW5pbV9lbGVtZW50LCBuZXdfZWxlbWVudF07XG59XG5cbiQkLm9mZnNldCA9IChlbGVtZW50KSA9PiB7XG5cdGxldCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0cmV0dXJuIHtcblx0XHQvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNzQzNjYwMi82NDk1MDQzXG5cdFx0Ly8gcmVjdC50b3AgdmFyaWVzIHdpdGggc2Nyb2xsLCBzbyB3ZSBhZGQgd2hhdGV2ZXIgaGFzIGJlZW5cblx0XHQvLyBzY3JvbGxlZCB0byBpdCB0byBnZXQgYWJzb2x1dGUgZGlzdGFuY2UgZnJvbSBhY3R1YWwgcGFnZSB0b3Bcblx0XHR0b3A6IHJlY3QudG9wICsgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3ApLFxuXHRcdGxlZnQ6IHJlY3QubGVmdCArIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbExlZnQpXG5cdH1cbn07XG5cbiQkLmlzRWxlbWVudEluVmlld3BvcnQgPSAoZWwpID0+IHtcblx0Ly8gQWx0aG91Z2ggc3RyYWlnaHRmb3J3YXJkOiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNzU1NzQzMy82NDk1MDQzXG4gICAgdmFyIHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIHJldHVybiAoXG4gICAgICAgIHJlY3QudG9wID49IDAgJiZcbiAgICAgICAgcmVjdC5sZWZ0ID49IDAgJiZcbiAgICAgICAgcmVjdC5ib3R0b20gPD0gKHdpbmRvdy5pbm5lckhlaWdodCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0KSAmJiAvKm9yICQod2luZG93KS5oZWlnaHQoKSAqL1xuICAgICAgICByZWN0LnJpZ2h0IDw9ICh3aW5kb3cuaW5uZXJXaWR0aCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgpIC8qb3IgJCh3aW5kb3cpLndpZHRoKCkgKi9cbiAgICApO1xufVxuXG4kJC5iaW5kID0gZnVuY3Rpb24oZWxlbWVudCwgbykge1xuXHRpZiAoZWxlbWVudCkge1xuXHRcdGZvciAodmFyIGV2ZW50IGluIG8pIHtcblx0XHRcdHZhciBjYWxsYmFjayA9IG9bZXZlbnRdO1xuXG5cdFx0XHRldmVudC5zcGxpdCgvXFxzKy8pLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG5cdFx0XHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgY2FsbGJhY2spO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG59O1xuXG4kJC51bmJpbmQgPSBmdW5jdGlvbihlbGVtZW50LCBvKSB7XG5cdGlmIChlbGVtZW50KSB7XG5cdFx0Zm9yICh2YXIgZXZlbnQgaW4gbykge1xuXHRcdFx0dmFyIGNhbGxiYWNrID0gb1tldmVudF07XG5cblx0XHRcdGV2ZW50LnNwbGl0KC9cXHMrLykuZm9yRWFjaChmdW5jdGlvbihldmVudCkge1xuXHRcdFx0XHRlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGNhbGxiYWNrKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxufTtcblxuJCQuZmlyZSA9IGZ1bmN0aW9uKHRhcmdldCwgdHlwZSwgcHJvcGVydGllcykge1xuXHR2YXIgZXZ0ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJIVE1MRXZlbnRzXCIpO1xuXG5cdGV2dC5pbml0RXZlbnQodHlwZSwgdHJ1ZSwgdHJ1ZSApO1xuXG5cdGZvciAodmFyIGogaW4gcHJvcGVydGllcykge1xuXHRcdGV2dFtqXSA9IHByb3BlcnRpZXNbal07XG5cdH1cblxuXHRyZXR1cm4gdGFyZ2V0LmRpc3BhdGNoRXZlbnQoZXZ0KTtcbn07XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsSUFBSSxNQUFNLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLFdBQVcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7O0FBRTlFLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxHQUFHLE1BQU07Q0FDaEMsV0FBVyxDQUFDO0VBQ1gsTUFBTSxHQUFHLEVBQUU7RUFDWCxNQUFNLEdBQUcsR0FBRzs7RUFFWixLQUFLLEdBQUcsRUFBRSxFQUFFLFFBQVEsR0FBRyxFQUFFOztFQUV6QixJQUFJ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LENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7RUFDaEUsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztFQUMzQixLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7O0VBRWhDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0VBQ2pDOztDQUVELGlCQUFpQixDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUU7RUFDMUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsT0FBTzs7RUFFN0IsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsUUFBUSxJQUFJLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7RUFDekUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7RUFDcEQsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztFQUMzQixLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQzs7RUFFdkIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7RUFDakM7O0NBRUQsYUFBYSxHQUFHO0VBQ2YsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxt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
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJhcHBlLWNoYXJ0cy5taW4uanMiLCJzb3VyY2VzIjpbIi4uL3NyYy9kb20uanMiLCIuLi9zcmMvdXRpbHMuanMiLCIuLi9zcmMvY2hhcnRzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICQoZXhwciwgY29uKSB7XG5cdHJldHVybiB0eXBlb2YgZXhwciA9PT0gXCJzdHJpbmdcIj8gKGNvbiB8fCBkb2N1bWVudCkucXVlcnlTZWxlY3RvcihleHByKSA6IGV4cHIgfHwgbnVsbDtcbn1cblxuJC5maW5kTm9kZUluZGV4ID0gKG5vZGUpID0+XG57XG5cdHZhciBpID0gMDtcblx0d2hpbGUgKG5vZGUucHJldmlvdXNTaWJsaW5nKSB7XG5cdFx0bm9kZSA9IG5vZGUucHJldmlvdXNTaWJsaW5nO1xuXHRcdGkrKztcblx0fVxuXHRyZXR1cm4gaTtcbn07XG5cbiQuY3JlYXRlID0gKHRhZywgbykgPT4ge1xuXHR2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnKTtcblxuXHRmb3IgKHZhciBpIGluIG8pIHtcblx0XHR2YXIgdmFsID0gb1tpXTtcblxuXHRcdGlmIChpID09PSBcImluc2lkZVwiKSB7XG5cdFx0XHQkKHZhbCkuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKGkgPT09IFwiYXJvdW5kXCIpIHtcblx0XHRcdHZhciByZWYgPSAkKHZhbCk7XG5cdFx0XHRyZWYucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZWxlbWVudCwgcmVmKTtcblx0XHRcdGVsZW1lbnQuYXBwZW5kQ2hpbGQocmVmKTtcblx0XHR9XG5cdFx0ZWxzZSBpZiAoaSBpbiBlbGVtZW50KSB7XG5cdFx0XHRlbGVtZW50W2ldID0gdmFsO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGVsZW1lbnQuc2V0QXR0cmlidXRlKGksIHZhbCk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW1lbnQ7XG59O1xuXG4kLmNyZWF0ZVNWRyA9ICh0YWcsIG8pID0+IHtcblx0dmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCB0YWcpO1xuXG5cdGZvciAodmFyIGkgaW4gbykge1xuXHRcdHZhciB2YWwgPSBvW2ldO1xuXG5cdFx0aWYgKGkgPT09IFwiaW5zaWRlXCIpIHtcblx0XHRcdCQodmFsKS5hcHBlbmRDaGlsZChlbGVtZW50KTtcblx0XHR9XG5cdFx0ZWxzZSBpZiAoaSA9PT0gXCJhcm91bmRcIikge1xuXHRcdFx0dmFyIHJlZiA9ICQodmFsKTtcblx0XHRcdHJlZi5wYXJlbnROb2RlLmluc2VydEJlZm9yZShlbGVtZW50LCByZWYpO1xuXHRcdFx0ZWxlbWVudC5hcHBlbmRDaGlsZChyZWYpO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGlmKGkgPT09IFwiY2xhc3NOYW1lXCIpIHsgaSA9IFwiY2xhc3NcIjsgfVxuXHRcdFx0aWYoaSA9PT0gXCJpbm5lckhUTUxcIikge1xuXHRcdFx0XHRlbGVtZW50Wyd0ZXh0Q29udGVudCddID0gdmFsO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbWVudC5zZXRBdHRyaWJ1dGUoaSwgdmFsKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZWxlbWVudDtcbn07XG5cbiQucnVuU1ZHQW5pbWF0aW9uID0gKHN2Z19jb250YWluZXIsIGVsZW1lbnRzKSA9PiB7XG5cdC8vIGxldCBwYXJlbnQgPSBlbGVtZW50c1swXVswXVsndW5pdCddLnBhcmVudE5vZGU7XG5cblx0bGV0IG5ld19lbGVtZW50cyA9IFtdO1xuXHRsZXQgYW5pbV9lbGVtZW50cyA9IFtdO1xuXG5cdGVsZW1lbnRzLm1hcChlbGVtZW50ID0+IHtcblx0XHRsZXQgb2JqID0gZWxlbWVudFswXTtcblx0XHRsZXQgcGFyZW50ID0gb2JqLnVuaXQucGFyZW50Tm9kZTtcblx0XHQvLyBsZXQgaW5kZXggPSBsZXQgZmluZE5vZGVJbmRleChvYmoudW5pdCk7XG5cblx0XHRsZXQgYW5pbV9lbGVtZW50LCBuZXdfZWxlbWVudDtcblxuXHRcdGVsZW1lbnRbMF0gPSBvYmoudW5pdDtcblxuXHRcdFthbmltX2VsZW1lbnQsIG5ld19lbGVtZW50XSA9ICQuYW5pbWF0ZVNWRyguLi5lbGVtZW50KTtcblxuXHRcdG5ld19lbGVtZW50cy5wdXNoKG5ld19lbGVtZW50KTtcblx0XHRhbmltX2VsZW1lbnRzLnB1c2goW2FuaW1fZWxlbWVudCwgcGFyZW50XSk7XG5cblx0XHRwYXJlbnQucmVwbGFjZUNoaWxkKGFuaW1fZWxlbWVudCwgb2JqLnVuaXQpO1xuXG5cdFx0aWYob2JqLmFycmF5KSB7XG5cdFx0XHRvYmouYXJyYXlbb2JqLmluZGV4XSA9IG5ld19lbGVtZW50O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvYmoub2JqZWN0W29iai5rZXldID0gbmV3X2VsZW1lbnQ7XG5cdFx0fVxuXHR9KTtcblxuXHRsZXQgYW5pbV9zdmcgPSBzdmdfY29udGFpbmVyLmNsb25lTm9kZSh0cnVlKTtcblxuXHRhbmltX2VsZW1lbnRzLm1hcCgoYW5pbV9lbGVtZW50LCBpKSA9PiB7XG5cdFx0YW5pbV9lbGVtZW50WzFdLnJlcGxhY2VDaGlsZChuZXdfZWxlbWVudHNbaV0sIGFuaW1fZWxlbWVudFswXSk7XG5cdFx0ZWxlbWVudHNbaV1bMF0gPSBuZXdfZWxlbWVudHNbaV07XG5cdH0pO1xuXG5cdHJldHVybiBhbmltX3N2Zztcbn07XG5cbiQuYW5pbWF0ZVNWRyA9IChlbGVtZW50LCBwcm9wcywgZHVyLCBlYXNpbmdfdHlwZT1cImxpbmVhclwiLCB0eXBlPXVuZGVmaW5lZCwgb2xkX3ZhbHVlcz17fSkgPT4ge1xuXHRsZXQgZWFzaW5nID0ge1xuXHRcdGVhc2U6IFwiMC4yNSAwLjEgMC4yNSAxXCIsXG5cdFx0bGluZWFyOiBcIjAgMCAxIDFcIixcblx0XHQvLyBlYXNlaW46IFwiMC40MiAwIDEgMVwiLFxuXHRcdGVhc2VpbjogXCIwLjEgMC44IDAuMiAxXCIsXG5cdFx0ZWFzZW91dDogXCIwIDAgMC41OCAxXCIsXG5cdFx0ZWFzZWlub3V0OiBcIjAuNDIgMCAwLjU4IDFcIlxuXHR9O1xuXG5cdGxldCBhbmltX2VsZW1lbnQgPSBlbGVtZW50LmNsb25lTm9kZSh0cnVlKTtcblx0bGV0IG5ld19lbGVtZW50ID0gZWxlbWVudC5jbG9uZU5vZGUodHJ1ZSk7XG5cblx0Zm9yKHZhciBhdHRyaWJ1dGVOYW1lIGluIHByb3BzKSB7XG5cdFx0bGV0IGFuaW1hdGVfZWxlbWVudDtcblx0XHRpZihhdHRyaWJ1dGVOYW1lID09PSAndHJhbnNmb3JtJykge1xuXHRcdFx0YW5pbWF0ZV9lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiwgXCJhbmltYXRlVHJhbnNmb3JtXCIpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhbmltYXRlX2VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCBcImFuaW1hdGVcIik7XG5cdFx0fVxuXHRcdGxldCBjdXJyZW50X3ZhbHVlID0gb2xkX3ZhbHVlc1thdHRyaWJ1dGVOYW1lXSB8fCBlbGVtZW50LmdldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKTtcblx0XHRsZXQgdmFsdWUgPSBwcm9wc1thdHRyaWJ1dGVOYW1lXTtcblxuXHRcdGxldCBhbmltX2F0dHIgPSB7XG5cdFx0XHRhdHRyaWJ1dGVOYW1lOiBhdHRyaWJ1dGVOYW1lLFxuXHRcdFx0ZnJvbTogY3VycmVudF92YWx1ZSxcblx0XHRcdHRvOiB2YWx1ZSxcblx0XHRcdGJlZ2luOiBcIjBzXCIsXG5cdFx0XHRkdXI6IGR1ci8xMDAwICsgXCJzXCIsXG5cdFx0XHR2YWx1ZXM6IGN1cnJlbnRfdmFsdWUgKyBcIjtcIiArIHZhbHVlLFxuXHRcdFx0a2V5U3BsaW5lczogZWFzaW5nW2Vhc2luZ190eXBlXSxcblx0XHRcdGtleVRpbWVzOiBcIjA7MVwiLFxuXHRcdFx0Y2FsY01vZGU6IFwic3BsaW5lXCIsXG5cdFx0XHRmaWxsOiAnZnJlZXplJ1xuXHRcdH07XG5cblx0XHRpZih0eXBlKSB7XG5cdFx0XHRhbmltX2F0dHJbXCJ0eXBlXCJdID0gdHlwZTtcblx0XHR9XG5cblx0XHRmb3IgKHZhciBpIGluIGFuaW1fYXR0cikge1xuXHRcdFx0YW5pbWF0ZV9lbGVtZW50LnNldEF0dHJpYnV0ZShpLCBhbmltX2F0dHJbaV0pO1xuXHRcdH1cblxuXHRcdGFuaW1fZWxlbWVudC5hcHBlbmRDaGlsZChhbmltYXRlX2VsZW1lbnQpO1xuXG5cdFx0aWYodHlwZSkge1xuXHRcdFx0bmV3X2VsZW1lbnQuc2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUsIGB0cmFuc2xhdGUoJHt2YWx1ZX0pYCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG5ld19lbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCB2YWx1ZSk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIFthbmltX2VsZW1lbnQsIG5ld19lbGVtZW50XTtcbn07XG5cbiQub2Zmc2V0ID0gKGVsZW1lbnQpID0+IHtcblx0bGV0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRyZXR1cm4ge1xuXHRcdC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS83NDM2NjAyLzY0OTUwNDNcblx0XHQvLyByZWN0LnRvcCB2YXJpZXMgd2l0aCBzY3JvbGwsIHNvIHdlIGFkZCB3aGF0ZXZlciBoYXMgYmVlblxuXHRcdC8vIHNjcm9sbGVkIHRvIGl0IHRvIGdldCBhYnNvbHV0ZSBkaXN0YW5jZSBmcm9tIGFjdHVhbCBwYWdlIHRvcFxuXHRcdHRvcDogcmVjdC50b3AgKyAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcCksXG5cdFx0bGVmdDogcmVjdC5sZWZ0ICsgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0IHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsTGVmdClcblx0fTtcbn07XG5cbiQuaXNFbGVtZW50SW5WaWV3cG9ydCA9IChlbCkgPT4ge1xuXHQvLyBBbHRob3VnaCBzdHJhaWdodGZvcndhcmQ6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS83NTU3NDMzLzY0OTUwNDNcblx0dmFyIHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuXHRyZXR1cm4gKFxuXHRcdHJlY3QudG9wID49IDAgJiZcbiAgICAgICAgcmVjdC5sZWZ0ID49IDAgJiZcbiAgICAgICAgcmVjdC5ib3R0b20gPD0gKHdpbmRvdy5pbm5lckhlaWdodCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0KSAmJiAvKm9yICQod2luZG93KS5oZWlnaHQoKSAqL1xuICAgICAgICByZWN0LnJpZ2h0IDw9ICh3aW5kb3cuaW5uZXJXaWR0aCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgpIC8qb3IgJCh3aW5kb3cpLndpZHRoKCkgKi9cblx0KTtcbn07XG5cbiQuYmluZCA9IChlbGVtZW50LCBvKSA9PiB7XG5cdGlmIChlbGVtZW50KSB7XG5cdFx0Zm9yICh2YXIgZXZlbnQgaW4gbykge1xuXHRcdFx0dmFyIGNhbGxiYWNrID0gb1tldmVudF07XG5cblx0XHRcdGV2ZW50LnNwbGl0KC9cXHMrLykuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcblx0XHRcdFx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBjYWxsYmFjayk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cbn07XG5cbiQudW5iaW5kID0gKGVsZW1lbnQsIG8pID0+IHtcblx0aWYgKGVsZW1lbnQpIHtcblx0XHRmb3IgKHZhciBldmVudCBpbiBvKSB7XG5cdFx0XHR2YXIgY2FsbGJhY2sgPSBvW2V2ZW50XTtcblxuXHRcdFx0ZXZlbnQuc3BsaXQoL1xccysvKS5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0XHRcdGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgY2FsbGJhY2spO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG59O1xuXG4kLmZpcmUgPSAodGFyZ2V0LCB0eXBlLCBwcm9wZXJ0aWVzKSA9PiB7XG5cdHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudChcIkhUTUxFdmVudHNcIik7XG5cblx0ZXZ0LmluaXRFdmVudCh0eXBlLCB0cnVlLCB0cnVlICk7XG5cblx0Zm9yICh2YXIgaiBpbiBwcm9wZXJ0aWVzKSB7XG5cdFx0ZXZ0W2pdID0gcHJvcGVydGllc1tqXTtcblx0fVxuXG5cdHJldHVybiB0YXJnZXQuZGlzcGF0Y2hFdmVudChldnQpO1xufTtcbiIsImV4cG9ydCBmdW5jdGlvbiBmbG9hdF8yKGQpIHtcblx0cmV0dXJuIHBhcnNlRmxvYXQoZC50b0ZpeGVkKDIpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFycmF5c19lcXVhbChhcnIxLCBhcnIyKSB7XG5cdGlmKGFycjEubGVuZ3RoICE9PSBhcnIyLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuXHRsZXQgYXJlX2VxdWFsID0gdHJ1ZTtcblx0YXJyMS5tYXAoKGQsIGkpID0+IHtcblx0XHRpZihhcnIyW2ldICE9PSBkKSBhcmVfZXF1YWwgPSBmYWxzZTtcblx0fSk7XG5cdHJldHVybiBhcmVfZXF1YWw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzaHVmZmxlKGFycmF5KSB7XG5cdC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yNDUwOTc2LzY0OTUwNDNcblx0Ly8gQXdlc29tZW5lc3M6IGh0dHBzOi8vYm9zdC5vY2tzLm9yZy9taWtlL3NodWZmbGUvXG5cblx0dmFyIGN1cnJlbnRJbmRleCA9IGFycmF5Lmxlbmd0aCwgdGVtcG9yYXJ5VmFsdWUsIHJhbmRvbUluZGV4O1xuXG5cdC8vIFdoaWxlIHRoZXJlIHJlbWFpbiBlbGVtZW50cyB0byBzaHVmZmxlLi4uXG5cdHdoaWxlICgwICE9PSBjdXJyZW50SW5kZXgpIHtcblxuXHRcdC8vIFBpY2sgYSByZW1haW5pbmcgZWxlbWVudC4uLlxuXHRcdHJhbmRvbUluZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY3VycmVudEluZGV4KTtcblx0XHRjdXJyZW50SW5kZXggLT0gMTtcblxuXHRcdC8vIEFuZCBzd2FwIGl0IHdpdGggdGhlIGN1cnJlbnQgZWxlbWVudC5cblx0XHR0ZW1wb3JhcnlWYWx1ZSA9IGFycmF5W2N1cnJlbnRJbmRleF07XG5cdFx0YXJyYXlbY3VycmVudEluZGV4XSA9IGFycmF5W3JhbmRvbUluZGV4XTtcblx0XHRhcnJheVtyYW5kb21JbmRleF0gPSB0ZW1wb3JhcnlWYWx1ZTtcblx0fVxuXG5cdHJldHVybiBhcnJheTtcbn1cbiIsImltcG9ydCAkIGZyb20gJy4vZG9tJztcbmltcG9ydCB7IGZsb2F0XzIsIGFycmF5c19lcXVhbCB9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDaGFydCB7XG5cdGNvbnN0cnVjdG9yKHtcblx0XHRwYXJlbnQgPSBcIlwiLFxuXHRcdGhlaWdodCA9IDI0MCxcblxuXHRcdHRpdGxlID0gJycsIHN1YnRpdGxlID0gJycsXG5cblx0XHRkYXRhID0ge30sXG5cdFx0Zm9ybWF0X2xhbWJkYXMgPSB7fSxcblxuXHRcdHN1bW1hcnkgPSBbXSxcblxuXHRcdGlzX25hdmlnYWJsZSA9IDAsXG5cblx0XHR0eXBlID0gJydcblx0fSkge1xuXHRcdGlmKE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKSA9PT0gQ2hhcnQucHJvdG90eXBlKSB7XG5cdFx0XHRpZih0eXBlID09PSAnbGluZScpIHtcblx0XHRcdFx0cmV0dXJuIG5ldyBMaW5lQ2hhcnQoYXJndW1lbnRzWzBdKTtcblx0XHRcdH0gZWxzZSBpZih0eXBlID09PSAnYmFyJykge1xuXHRcdFx0XHRyZXR1cm4gbmV3IEJhckNoYXJ0KGFyZ3VtZW50c1swXSk7XG5cdFx0XHR9IGVsc2UgaWYodHlwZSA9PT0gJ3BlcmNlbnRhZ2UnKSB7XG5cdFx0XHRcdHJldHVybiBuZXcgUGVyY2VudGFnZUNoYXJ0KGFyZ3VtZW50c1swXSk7XG5cdFx0XHR9IGVsc2UgaWYodHlwZSA9PT0gJ2hlYXRtYXAnKSB7XG5cdFx0XHRcdHJldHVybiBuZXcgSGVhdE1hcChhcmd1bWVudHNbMF0pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIG5ldyBMaW5lQ2hhcnQoYXJndW1lbnRzWzBdKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLnJhd19jaGFydF9hcmdzID0gYXJndW1lbnRzWzBdO1xuXG5cdFx0dGhpcy5wYXJlbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHBhcmVudCk7XG5cdFx0dGhpcy50aXRsZSA9IHRpdGxlO1xuXHRcdHRoaXMuc3VidGl0bGUgPSBzdWJ0aXRsZTtcblxuXHRcdHRoaXMuZGF0YSA9IGRhdGE7XG5cdFx0dGhpcy5mb3JtYXRfbGFtYmRhcyA9IGZvcm1hdF9sYW1iZGFzO1xuXG5cdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMgPSBkYXRhLnNwZWNpZmljX3ZhbHVlcyB8fCBbXTtcblx0XHR0aGlzLnN1bW1hcnkgPSBzdW1tYXJ5O1xuXG5cdFx0dGhpcy5pc19uYXZpZ2FibGUgPSBpc19uYXZpZ2FibGU7XG5cdFx0aWYodGhpcy5pc19uYXZpZ2FibGUpIHtcblx0XHRcdHRoaXMuY3VycmVudF9pbmRleCA9IDA7XG5cdFx0fVxuXG5cdFx0dGhpcy5jaGFydF90eXBlcyA9IFsnbGluZScsICdiYXInLCAncGVyY2VudGFnZScsICdoZWF0bWFwJ107XG5cblx0XHR0aGlzLnNldF9tYXJnaW5zKGhlaWdodCk7XG5cdH1cblxuXHRnZXRfZGlmZmVyZW50X2NoYXJ0KHR5cGUpIHtcblx0XHRpZighdGhpcy5jaGFydF90eXBlcy5pbmNsdWRlcyh0eXBlKSkge1xuXHRcdFx0Y29uc29sZS5lcnJvcihgJyR7dHlwZX0nIGlzIG5vdCBhIHZhbGlkIGNoYXJ0IHR5cGUuYCk7XG5cdFx0fVxuXHRcdGlmKHR5cGUgPT09IHRoaXMudHlwZSkgcmV0dXJuO1xuXG5cdFx0Ly8gT25seSBhY3Jvc3MgY29tcGF0aWJsZSB0eXBlc1xuXHRcdGxldCBjb21wYXRpYmxlX3R5cGVzID0ge1xuXHRcdFx0YmFyOiBbJ2xpbmUnLCAncGVyY2VudGFnZSddLFxuXHRcdFx0bGluZTogWydiYXInLCAncGVyY2VudGFnZSddLFxuXHRcdFx0cGVyY2VudGFnZTogWydiYXInLCAnbGluZSddLFxuXHRcdFx0aGVhdG1hcDogW11cblx0XHR9O1xuXG5cdFx0aWYoIWNvbXBhdGlibGVfdHlwZXNbdGhpcy50eXBlXS5pbmNsdWRlcyh0eXBlKSkge1xuXHRcdFx0Y29uc29sZS5lcnJvcihgJyR7dGhpcy50eXBlfScgY2hhcnQgY2Fubm90IGJlIGNvbnZlcnRlZCB0byBhICcke3R5cGV9JyBjaGFydC5gKTtcblx0XHR9XG5cblx0XHQvLyBPa2F5LCB0aGlzIGlzIGFudGljbGltYWN0aWNcblx0XHQvLyB0aGlzIGZ1bmN0aW9uIHdpbGwgbmVlZCB0byBhY3R1YWxseSBiZSAnY2hhbmdlX2NoYXJ0X3R5cGUodHlwZSknXG5cdFx0Ly8gdGhhdCB3aWxsIHVwZGF0ZSBvbmx5IHRoZSByZXF1aXJlZCBlbGVtZW50cywgYnV0IGZvciBub3cgLi4uXG5cdFx0cmV0dXJuIG5ldyBDaGFydCh7XG5cdFx0XHRwYXJlbnQ6IHRoaXMucmF3X2NoYXJ0X2FyZ3MucGFyZW50LFxuXHRcdFx0ZGF0YTogdGhpcy5yYXdfY2hhcnRfYXJncy5kYXRhLFxuXHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdGhlaWdodDogdGhpcy5yYXdfY2hhcnRfYXJncy5oZWlnaHRcblx0XHR9KTtcblx0fVxuXG5cdHNldF9tYXJnaW5zKGhlaWdodCkge1xuXHRcdHRoaXMuYmFzZV9oZWlnaHQgPSBoZWlnaHQ7XG5cdFx0dGhpcy5oZWlnaHQgPSBoZWlnaHQgLSA0MDtcblx0XHR0aGlzLnRyYW5zbGF0ZV94ID0gNjA7XG5cdFx0dGhpcy50cmFuc2xhdGVfeSA9IDEwO1xuXHR9XG5cblx0c2V0dXAoKSB7XG5cdFx0dGhpcy5iaW5kX3dpbmRvd19ldmVudHMoKTtcblx0XHR0aGlzLnJlZnJlc2godHJ1ZSk7XG5cdH1cblxuXHRiaW5kX3dpbmRvd19ldmVudHMoKSB7XG5cdFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsICgpID0+IHRoaXMucmVmcmVzaCgpKTtcblx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb3JpZW50YXRpb25jaGFuZ2UnLCAoKSA9PiB0aGlzLnJlZnJlc2goKSk7XG5cdH1cblxuXHRyZWZyZXNoKGluaXQ9ZmFsc2UpIHtcblx0XHR0aGlzLnNldHVwX2Jhc2VfdmFsdWVzKCk7XG5cdFx0dGhpcy5zZXRfd2lkdGgoKTtcblxuXHRcdHRoaXMuc2V0dXBfY29udGFpbmVyKCk7XG5cdFx0dGhpcy5zZXR1cF9jb21wb25lbnRzKCk7XG5cblx0XHR0aGlzLnNldHVwX3ZhbHVlcygpO1xuXHRcdHRoaXMuc2V0dXBfdXRpbHMoKTtcblxuXHRcdHRoaXMubWFrZV9ncmFwaF9jb21wb25lbnRzKGluaXQpO1xuXHRcdHRoaXMubWFrZV90b29sdGlwKCk7XG5cblx0XHRpZih0aGlzLnN1bW1hcnkubGVuZ3RoID4gMCkge1xuXHRcdFx0dGhpcy5zaG93X2N1c3RvbV9zdW1tYXJ5KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuc2hvd19zdW1tYXJ5KCk7XG5cdFx0fVxuXG5cdFx0aWYodGhpcy5pc19uYXZpZ2FibGUpIHtcblx0XHRcdHRoaXMuc2V0dXBfbmF2aWdhdGlvbihpbml0KTtcblx0XHR9XG5cdH1cblxuXHRzZXRfd2lkdGgoKSB7XG5cdFx0bGV0IHNwZWNpYWxfdmFsdWVzX3dpZHRoID0gMDtcblx0XHR0aGlzLnNwZWNpZmljX3ZhbHVlcy5tYXAodmFsID0+IHtcblx0XHRcdGlmKHRoaXMuZ2V0X3N0cndpZHRoKHZhbC50aXRsZSkgPiBzcGVjaWFsX3ZhbHVlc193aWR0aCkge1xuXHRcdFx0XHRzcGVjaWFsX3ZhbHVlc193aWR0aCA9IHRoaXMuZ2V0X3N0cndpZHRoKHZhbC50aXRsZSkgLSA0MDtcblx0XHRcdH1cblx0XHR9KTtcblx0XHR0aGlzLmJhc2Vfd2lkdGggPSB0aGlzLnBhcmVudC5vZmZzZXRXaWR0aCAtIHNwZWNpYWxfdmFsdWVzX3dpZHRoO1xuXHRcdHRoaXMud2lkdGggPSB0aGlzLmJhc2Vfd2lkdGggLSB0aGlzLnRyYW5zbGF0ZV94ICogMjtcblx0fVxuXG5cdHNldHVwX2Jhc2VfdmFsdWVzKCkge31cblxuXHRzZXR1cF9jb250YWluZXIoKSB7XG5cdFx0dGhpcy5jb250YWluZXIgPSAkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0Y2xhc3NOYW1lOiAnY2hhcnQtY29udGFpbmVyJyxcblx0XHRcdGlubmVySFRNTDogYDxoNiBjbGFzcz1cInRpdGxlXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxNXB4O1wiPiR7dGhpcy50aXRsZX08L2g2PlxuXHRcdFx0XHQ8aDYgY2xhc3M9XCJzdWItdGl0bGUgdXBwZXJjYXNlXCI+JHt0aGlzLnN1YnRpdGxlfTwvaDY+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJmcmFwcGUtY2hhcnQgZ3JhcGhpY3NcIj48L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cImdyYXBoLXN0YXRzLWNvbnRhaW5lclwiPjwvZGl2PmBcblx0XHR9KTtcblxuXHRcdC8vIENoYXJ0IG5lZWRzIGEgZGVkaWNhdGVkIHBhcmVudCBlbGVtZW50XG5cdFx0dGhpcy5wYXJlbnQuaW5uZXJIVE1MID0gJyc7XG5cdFx0dGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5jb250YWluZXIpO1xuXG5cdFx0dGhpcy5jaGFydF93cmFwcGVyID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcignLmZyYXBwZS1jaGFydCcpO1xuXHRcdHRoaXMuc3RhdHNfd3JhcHBlciA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy5ncmFwaC1zdGF0cy1jb250YWluZXInKTtcblxuXHRcdHRoaXMubWFrZV9jaGFydF9hcmVhKCk7XG5cdFx0dGhpcy5tYWtlX2RyYXdfYXJlYSgpO1xuXHR9XG5cblx0bWFrZV9jaGFydF9hcmVhKCkge1xuXHRcdHRoaXMuc3ZnID0gJC5jcmVhdGVTVkcoJ3N2ZycsIHtcblx0XHRcdGNsYXNzTmFtZTogJ2NoYXJ0Jyxcblx0XHRcdGluc2lkZTogdGhpcy5jaGFydF93cmFwcGVyLFxuXHRcdFx0d2lkdGg6IHRoaXMuYmFzZV93aWR0aCxcblx0XHRcdGhlaWdodDogdGhpcy5iYXNlX2hlaWdodFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5zdmdfZGVmcyA9ICQuY3JlYXRlU1ZHKCdkZWZzJywge1xuXHRcdFx0aW5zaWRlOiB0aGlzLnN2Zyxcblx0XHR9KTtcblxuXHRcdHJldHVybiB0aGlzLnN2Zztcblx0fVxuXG5cdG1ha2VfZHJhd19hcmVhKCkge1xuXHRcdHRoaXMuZHJhd19hcmVhID0gJC5jcmVhdGVTVkcoXCJnXCIsIHtcblx0XHRcdGNsYXNzTmFtZTogdGhpcy50eXBlICsgJy1jaGFydCcsXG5cdFx0XHRpbnNpZGU6IHRoaXMuc3ZnLFxuXHRcdFx0dHJhbnNmb3JtOiBgdHJhbnNsYXRlKCR7dGhpcy50cmFuc2xhdGVfeH0sICR7dGhpcy50cmFuc2xhdGVfeX0pYFxuXHRcdH0pO1xuXHR9XG5cblx0c2V0dXBfY29tcG9uZW50cygpIHsgfVxuXG5cdG1ha2VfdG9vbHRpcCgpIHtcblx0XHR0aGlzLnRpcCA9IG5ldyBTdmdUaXAoe1xuXHRcdFx0cGFyZW50OiB0aGlzLmNoYXJ0X3dyYXBwZXIsXG5cdFx0fSk7XG5cdFx0dGhpcy5iaW5kX3Rvb2x0aXAoKTtcblx0fVxuXG5cblx0c2hvd19zdW1tYXJ5KCkge31cblx0c2hvd19jdXN0b21fc3VtbWFyeSgpIHtcblx0XHR0aGlzLnN1bW1hcnkubWFwKGQgPT4ge1xuXHRcdFx0bGV0IHN0YXRzID0gJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAnc3RhdHMnLFxuXHRcdFx0XHRpbm5lckhUTUw6IGA8c3BhbiBjbGFzcz1cImluZGljYXRvciAke2QuY29sb3J9XCI+JHtkLnRpdGxlfTogJHtkLnZhbHVlfTwvc3Bhbj5gXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuc3RhdHNfd3JhcHBlci5hcHBlbmRDaGlsZChzdGF0cyk7XG5cdFx0fSk7XG5cdH1cblxuXHRzZXR1cF9uYXZpZ2F0aW9uKGluaXQ9ZmFsc2UpIHtcblx0XHR0aGlzLm1ha2Vfb3ZlcmxheSgpO1xuXG5cdFx0aWYoaW5pdCkge1xuXHRcdFx0dGhpcy5iaW5kX292ZXJsYXkoKTtcblxuXHRcdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChlKSA9PiB7XG5cdFx0XHRcdGlmKCQuaXNFbGVtZW50SW5WaWV3cG9ydCh0aGlzLmNoYXJ0X3dyYXBwZXIpKSB7XG5cdFx0XHRcdFx0ZSA9IGUgfHwgd2luZG93LmV2ZW50O1xuXG5cdFx0XHRcdFx0aWYgKGUua2V5Q29kZSA9PSAnMzcnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm9uX2xlZnRfYXJyb3coKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKGUua2V5Q29kZSA9PSAnMzknKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm9uX3JpZ2h0X2Fycm93KCk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChlLmtleUNvZGUgPT0gJzM4Jykge1xuXHRcdFx0XHRcdFx0dGhpcy5vbl91cF9hcnJvdygpO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoZS5rZXlDb2RlID09ICc0MCcpIHtcblx0XHRcdFx0XHRcdHRoaXMub25fZG93bl9hcnJvdygpO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoZS5rZXlDb2RlID09ICcxMycpIHtcblx0XHRcdFx0XHRcdHRoaXMub25fZW50ZXJfa2V5KCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cblxuXHRtYWtlX292ZXJsYXkoKSB7fVxuXHRiaW5kX292ZXJsYXkoKSB7fVxuXG5cdG9uX2xlZnRfYXJyb3coKSB7fVxuXHRvbl9yaWdodF9hcnJvdygpIHt9XG5cdG9uX3VwX2Fycm93KCkge31cblx0b25fZG93bl9hcnJvdygpIHt9XG5cdG9uX2VudGVyX2tleSgpIHt9XG5cblx0Z2V0X2RhdGFfcG9pbnQoaW5kZXg9dGhpcy5jdXJyZW50X2luZGV4KSB7XG5cdFx0Ly8gY2hlY2sgZm9yIGxlbmd0aFxuXHRcdGxldCBkYXRhX3BvaW50ID0ge1xuXHRcdFx0aW5kZXg6IGluZGV4XG5cdFx0fTtcblx0XHRsZXQgeSA9IHRoaXMueVswXTtcblx0XHRbJ3N2Z191bml0cycsICd5X3RvcHMnLCAndmFsdWVzJ10ubWFwKGtleSA9PiB7XG5cdFx0XHRsZXQgZGF0YV9rZXkgPSBrZXkuc2xpY2UoMCwga2V5Lmxlbmd0aC0xKTtcblx0XHRcdGRhdGFfcG9pbnRbZGF0YV9rZXldID0geVtrZXldW2luZGV4XTtcblx0XHR9KTtcblx0XHRkYXRhX3BvaW50LmxhYmVsID0gdGhpcy54W2luZGV4XTtcblx0XHRyZXR1cm4gZGF0YV9wb2ludDtcblx0fVxuXG5cdHVwZGF0ZV9jdXJyZW50X2RhdGFfcG9pbnQoaW5kZXgpIHtcblx0XHRpZihpbmRleCA8IDApIGluZGV4ID0gMDtcblx0XHRpZihpbmRleCA+PSB0aGlzLngubGVuZ3RoKSBpbmRleCA9IHRoaXMueC5sZW5ndGggLSAxO1xuXHRcdGlmKGluZGV4ID09PSB0aGlzLmN1cnJlbnRfaW5kZXgpIHJldHVybjtcblx0XHR0aGlzLmN1cnJlbnRfaW5kZXggPSBpbmRleDtcblx0XHQkLmZpcmUodGhpcy5wYXJlbnQsIFwiZGF0YS1zZWxlY3RcIiwgdGhpcy5nZXRfZGF0YV9wb2ludCgpKTtcblx0fVxuXG5cdC8vIEhlbHBlcnNcblx0Z2V0X3N0cndpZHRoKHN0cmluZykge1xuXHRcdHJldHVybiBzdHJpbmcubGVuZ3RoICogODtcblx0fVxuXG5cdC8vIE9iamVjdHNcblx0c2V0dXBfdXRpbHMoKSB7IH1cbn1cblxuY2xhc3MgQXhpc0NoYXJ0IGV4dGVuZHMgQ2hhcnQge1xuXHRjb25zdHJ1Y3RvcihhcmdzKSB7XG5cdFx0c3VwZXIoYXJncyk7XG5cblx0XHR0aGlzLnggPSB0aGlzLmRhdGEubGFiZWxzO1xuXHRcdHRoaXMueSA9IHRoaXMuZGF0YS5kYXRhc2V0cztcblxuXHRcdHRoaXMuZ2V0X3lfbGFiZWwgPSB0aGlzLmZvcm1hdF9sYW1iZGFzLnlfbGFiZWw7XG5cdFx0dGhpcy5nZXRfeV90b29sdGlwID0gdGhpcy5mb3JtYXRfbGFtYmRhcy55X3Rvb2x0aXA7XG5cdFx0dGhpcy5nZXRfeF90b29sdGlwID0gdGhpcy5mb3JtYXRfbGFtYmRhcy54X3Rvb2x0aXA7XG5cblx0XHR0aGlzLmNvbG9ycyA9IFsnZ3JlZW4nLCAnYmx1ZScsICd2aW9sZXQnLCAncmVkJywgJ29yYW5nZScsXG5cdFx0XHQneWVsbG93JywgJ2xpZ2h0LWJsdWUnLCAnbGlnaHQtZ3JlZW4nLCAncHVycGxlJywgJ21hZ2VudGEnXTtcblxuXHRcdHRoaXMuemVyb19saW5lID0gdGhpcy5oZWlnaHQ7XG5cdH1cblxuXHRzZXR1cF92YWx1ZXMoKSB7XG5cdFx0dGhpcy5kYXRhLmRhdGFzZXRzLm1hcChkID0+IHtcblx0XHRcdGQudmFsdWVzID0gZC52YWx1ZXMubWFwKHZhbCA9PiAoIWlzTmFOKHZhbCkgPyB2YWwgOiAwKSk7XG5cdFx0fSk7XG5cdFx0dGhpcy5zZXR1cF94KCk7XG5cdFx0dGhpcy5zZXR1cF95KCk7XG5cdH1cblxuXHRzZXR1cF94KCkge1xuXHRcdHRoaXMuc2V0X2F2Z191bml0X3dpZHRoX2FuZF94X29mZnNldCgpO1xuXG5cdFx0aWYodGhpcy54X2F4aXNfcG9zaXRpb25zKSB7XG5cdFx0XHR0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zID0gIHRoaXMueF9heGlzX3Bvc2l0aW9ucy5zbGljZSgpO1xuXHRcdH1cblx0XHR0aGlzLnhfYXhpc19wb3NpdGlvbnMgPSB0aGlzLngubWFwKChkLCBpKSA9PlxuXHRcdFx0ZmxvYXRfMih0aGlzLnhfb2Zmc2V0ICsgaSAqIHRoaXMuYXZnX3VuaXRfd2lkdGgpKTtcblxuXHRcdGlmKCF0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zKSB7XG5cdFx0XHR0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zID0gdGhpcy54X2F4aXNfcG9zaXRpb25zLnNsaWNlKCk7XG5cdFx0fVxuXHR9XG5cblx0c2V0dXBfeSgpIHtcblx0XHRpZih0aGlzLnlfYXhpc192YWx1ZXMpIHtcblx0XHRcdHRoaXMueV9vbGRfYXhpc192YWx1ZXMgPSAgdGhpcy55X2F4aXNfdmFsdWVzLnNsaWNlKCk7XG5cdFx0fVxuXG5cdFx0bGV0IHZhbHVlcyA9IHRoaXMuZ2V0X2FsbF95X3ZhbHVlcygpO1xuXG5cdFx0aWYodGhpcy55X3N1bXMgJiYgdGhpcy55X3N1bXMubGVuZ3RoID4gMCkge1xuXHRcdFx0dmFsdWVzID0gdmFsdWVzLmNvbmNhdCh0aGlzLnlfc3Vtcyk7XG5cdFx0fVxuXG5cdFx0dGhpcy55X2F4aXNfdmFsdWVzID0gdGhpcy5nZXRfeV9heGlzX3BvaW50cyh2YWx1ZXMpO1xuXG5cdFx0aWYoIXRoaXMueV9vbGRfYXhpc192YWx1ZXMpIHtcblx0XHRcdHRoaXMueV9vbGRfYXhpc192YWx1ZXMgPSB0aGlzLnlfYXhpc192YWx1ZXMuc2xpY2UoKTtcblx0XHR9XG5cblx0XHRjb25zdCB5X3B0cyA9IHRoaXMueV9heGlzX3ZhbHVlcztcblx0XHRjb25zdCB2YWx1ZV9yYW5nZSA9IHlfcHRzW3lfcHRzLmxlbmd0aC0xXSAtIHlfcHRzWzBdO1xuXG5cdFx0aWYodGhpcy5tdWx0aXBsaWVyKSB0aGlzLm9sZF9tdWx0aXBsaWVyID0gdGhpcy5tdWx0aXBsaWVyO1xuXHRcdHRoaXMubXVsdGlwbGllciA9IHRoaXMuaGVpZ2h0IC8gdmFsdWVfcmFuZ2U7XG5cdFx0aWYoIXRoaXMub2xkX211bHRpcGxpZXIpIHRoaXMub2xkX211bHRpcGxpZXIgPSB0aGlzLm11bHRpcGxpZXI7XG5cblx0XHRjb25zdCB6ZXJvX2luZGV4ID0geV9wdHMuaW5kZXhPZigwKTtcblx0XHRjb25zdCBpbnRlcnZhbCA9IHlfcHRzWzFdIC0geV9wdHNbMF07XG5cdFx0Y29uc3QgaW50ZXJ2YWxfaGVpZ2h0ID0gaW50ZXJ2YWwgKiB0aGlzLm11bHRpcGxpZXI7XG5cblx0XHRpZih0aGlzLnplcm9fbGluZSkgdGhpcy5vbGRfemVyb19saW5lID0gdGhpcy56ZXJvX2xpbmU7XG5cdFx0dGhpcy56ZXJvX2xpbmUgPSB0aGlzLmhlaWdodCAtICh6ZXJvX2luZGV4ICogaW50ZXJ2YWxfaGVpZ2h0KTtcblx0XHRpZighdGhpcy5vbGRfemVyb19saW5lKSB0aGlzLm9sZF96ZXJvX2xpbmUgPSB0aGlzLnplcm9fbGluZTtcblx0fVxuXG5cdHNldHVwX2NvbXBvbmVudHMoKSB7XG5cdFx0c3VwZXIuc2V0dXBfY29tcG9uZW50cygpO1xuXHRcdHRoaXMuc2V0dXBfbWFya2VyX2NvbXBvbmVudHMoKTtcblx0XHR0aGlzLnNldHVwX2FnZ3JlZ2F0aW9uX2NvbXBvbmVudHMoKTtcblx0XHR0aGlzLnNldHVwX2dyYXBoX2NvbXBvbmVudHMoKTtcblx0fVxuXG5cdHNldHVwX21hcmtlcl9jb21wb25lbnRzKCkge1xuXHRcdHRoaXMueV9heGlzX2dyb3VwID0gJC5jcmVhdGVTVkcoJ2cnLCB7Y2xhc3NOYW1lOiAneSBheGlzJywgaW5zaWRlOiB0aGlzLmRyYXdfYXJlYX0pO1xuXHRcdHRoaXMueF9heGlzX2dyb3VwID0gJC5jcmVhdGVTVkcoJ2cnLCB7Y2xhc3NOYW1lOiAneCBheGlzJywgaW5zaWRlOiB0aGlzLmRyYXdfYXJlYX0pO1xuXHRcdHRoaXMuc3BlY2lmaWNfeV9ncm91cCA9ICQuY3JlYXRlU1ZHKCdnJywge2NsYXNzTmFtZTogJ3NwZWNpZmljIGF4aXMnLCBpbnNpZGU6IHRoaXMuZHJhd19hcmVhfSk7XG5cdH1cblxuXHRzZXR1cF9hZ2dyZWdhdGlvbl9jb21wb25lbnRzKCkge1xuXHRcdHRoaXMuc3VtX2dyb3VwID0gJC5jcmVhdGVTVkcoJ2cnLCB7Y2xhc3NOYW1lOiAnZGF0YS1wb2ludHMnLCBpbnNpZGU6IHRoaXMuZHJhd19hcmVhfSk7XG5cdFx0dGhpcy5hdmVyYWdlX2dyb3VwID0gJC5jcmVhdGVTVkcoJ2cnLCB7Y2xhc3NOYW1lOiAnY2hhcnQtYXJlYScsIGluc2lkZTogdGhpcy5kcmF3X2FyZWF9KTtcblx0fVxuXG5cdHNldHVwX2dyYXBoX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5zdmdfdW5pdHNfZ3JvdXBzID0gW107XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0dGhpcy5zdmdfdW5pdHNfZ3JvdXBzW2ldID0gJC5jcmVhdGVTVkcoJ2cnLCB7XG5cdFx0XHRcdGNsYXNzTmFtZTogJ2RhdGEtcG9pbnRzIGRhdGEtcG9pbnRzLScgKyBpLFxuXHRcdFx0XHRpbnNpZGU6IHRoaXMuZHJhd19hcmVhXG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfZ3JhcGhfY29tcG9uZW50cyhpbml0PWZhbHNlKSB7XG5cdFx0dGhpcy5tYWtlX3lfYXhpcygpO1xuXHRcdHRoaXMubWFrZV94X2F4aXMoKTtcblx0XHR0aGlzLmRyYXdfZ3JhcGgoaW5pdCk7XG5cdFx0dGhpcy5tYWtlX3lfc3BlY2lmaWNzKCk7XG5cdH1cblxuXHQvLyBtYWtlIFZFUlRJQ0FMIGxpbmVzIGZvciB4IHZhbHVlc1xuXHRtYWtlX3hfYXhpcyhhbmltYXRlPWZhbHNlKSB7XG5cdFx0bGV0IHN0YXJ0X2F0LCBoZWlnaHQsIHRleHRfc3RhcnRfYXQsIGF4aXNfbGluZV9jbGFzcyA9ICcnO1xuXHRcdGlmKHRoaXMueF9heGlzX21vZGUgPT09ICdzcGFuJykge1x0XHQvLyBsb25nIHNwYW5uaW5nIGxpbmVzXG5cdFx0XHRzdGFydF9hdCA9IC03O1xuXHRcdFx0aGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyAxNTtcblx0XHRcdHRleHRfc3RhcnRfYXQgPSB0aGlzLmhlaWdodCArIDI1O1xuXHRcdH0gZWxzZSBpZih0aGlzLnhfYXhpc19tb2RlID09PSAndGljaycpe1x0Ly8gc2hvcnQgbGFiZWwgbGluZXNcblx0XHRcdHN0YXJ0X2F0ID0gdGhpcy5oZWlnaHQ7XG5cdFx0XHRoZWlnaHQgPSA2O1xuXHRcdFx0dGV4dF9zdGFydF9hdCA9IDk7XG5cdFx0XHRheGlzX2xpbmVfY2xhc3MgPSAneC1heGlzLWxhYmVsJztcblx0XHR9XG5cblx0XHR0aGlzLnhfYXhpc19ncm91cC5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsIGB0cmFuc2xhdGUoMCwke3N0YXJ0X2F0fSlgKTtcblxuXHRcdGlmKGFuaW1hdGUpIHtcblx0XHRcdHRoaXMubWFrZV9hbmltX3hfYXhpcyhoZWlnaHQsIHRleHRfc3RhcnRfYXQsIGF4aXNfbGluZV9jbGFzcyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dGhpcy54X2F4aXNfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLngubWFwKChwb2ludCwgaSkgPT4ge1xuXHRcdFx0dGhpcy54X2F4aXNfZ3JvdXAuYXBwZW5kQ2hpbGQoXG5cdFx0XHRcdHRoaXMubWFrZV94X2xpbmUoXG5cdFx0XHRcdFx0aGVpZ2h0LFxuXHRcdFx0XHRcdHRleHRfc3RhcnRfYXQsXG5cdFx0XHRcdFx0cG9pbnQsXG5cdFx0XHRcdFx0J3gtdmFsdWUtdGV4dCcsXG5cdFx0XHRcdFx0YXhpc19saW5lX2NsYXNzLFxuXHRcdFx0XHRcdHRoaXMueF9heGlzX3Bvc2l0aW9uc1tpXVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0Ly8gbWFrZSBIT1JJWk9OVEFMIGxpbmVzIGZvciB5IHZhbHVlc1xuXHRtYWtlX3lfYXhpcyhhbmltYXRlPWZhbHNlKSB7XG5cdFx0aWYoYW5pbWF0ZSkge1xuXHRcdFx0dGhpcy5tYWtlX2FuaW1feV9heGlzKCk7XG5cdFx0XHR0aGlzLm1ha2VfYW5pbV95X3NwZWNpZmljcygpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGxldCBbd2lkdGgsIHRleHRfZW5kX2F0LCBheGlzX2xpbmVfY2xhc3MsIHN0YXJ0X2F0XSA9IHRoaXMuZ2V0X3lfYXhpc19saW5lX3Byb3BzKCk7XG5cblx0XHR0aGlzLnlfYXhpc19ncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdHRoaXMueV9heGlzX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHR0aGlzLnlfYXhpc19ncm91cC5hcHBlbmRDaGlsZChcblx0XHRcdFx0dGhpcy5tYWtlX3lfbGluZShcblx0XHRcdFx0XHRzdGFydF9hdCxcblx0XHRcdFx0XHR3aWR0aCxcblx0XHRcdFx0XHR0ZXh0X2VuZF9hdCxcblx0XHRcdFx0XHR2YWx1ZSxcblx0XHRcdFx0XHQneS12YWx1ZS10ZXh0Jyxcblx0XHRcdFx0XHRheGlzX2xpbmVfY2xhc3MsXG5cdFx0XHRcdFx0dGhpcy56ZXJvX2xpbmUgLSB2YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0XHQodmFsdWUgPT09IDAgJiYgaSAhPT0gMCkgLy8gTm9uLWZpcnN0IFplcm8gbGluZVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0Z2V0X3lfYXhpc19saW5lX3Byb3BzKHNwZWNpZmljPWZhbHNlKSB7XG5cdFx0aWYoc3BlY2lmaWMpIHtcblx0XHRcdHJldHVyblt0aGlzLndpZHRoLCB0aGlzLndpZHRoICsgNSwgJ3NwZWNpZmljLXZhbHVlJywgMF07XG5cdFx0fVxuXHRcdGxldCB3aWR0aCwgdGV4dF9lbmRfYXQgPSAtOSwgYXhpc19saW5lX2NsYXNzID0gJycsIHN0YXJ0X2F0ID0gMDtcblx0XHRpZih0aGlzLnlfYXhpc19tb2RlID09PSAnc3BhbicpIHtcdFx0Ly8gbG9uZyBzcGFubmluZyBsaW5lc1xuXHRcdFx0d2lkdGggPSB0aGlzLndpZHRoICsgNjtcblx0XHRcdHN0YXJ0X2F0ID0gLTY7XG5cdFx0fSBlbHNlIGlmKHRoaXMueV9heGlzX21vZGUgPT09ICd0aWNrJyl7XHQvLyBzaG9ydCBsYWJlbCBsaW5lc1xuXHRcdFx0d2lkdGggPSAtNjtcblx0XHRcdGF4aXNfbGluZV9jbGFzcyA9ICd5LWF4aXMtbGFiZWwnO1xuXHRcdH1cblxuXHRcdHJldHVybiBbd2lkdGgsIHRleHRfZW5kX2F0LCBheGlzX2xpbmVfY2xhc3MsIHN0YXJ0X2F0XTtcblx0fVxuXG5cdGRyYXdfZ3JhcGgoaW5pdD1mYWxzZSkge1xuXHRcdGlmKGluaXQpIHtcblx0XHRcdHRoaXMuZHJhd19uZXdfZ3JhcGhfYW5kX2FuaW1hdGUoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0ZC5zdmdfdW5pdHMgPSBbXTtcblx0XHRcdHRoaXMubWFrZV9wYXRoICYmIHRoaXMubWFrZV9wYXRoKGQsIGksIHRoaXMueF9heGlzX3Bvc2l0aW9ucywgZC55X3RvcHMsIGQuY29sb3IgfHwgdGhpcy5jb2xvcnNbaV0pO1xuXHRcdFx0dGhpcy5tYWtlX25ld191bml0cyhkLCBpKTtcblx0XHR9KTtcblx0fVxuXG5cdGRyYXdfbmV3X2dyYXBoX2FuZF9hbmltYXRlKCkge1xuXHRcdGxldCBkYXRhID0gW107XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0Ly8gQW5pbTogRG9uJ3QgZHJhdyBpbml0aWFsIHZhbHVlcywgc3RvcmUgdGhlbSBhbmQgdXBkYXRlIGxhdGVyXG5cdFx0XHRkLnlfdG9wcyA9IG5ldyBBcnJheShkLnZhbHVlcy5sZW5ndGgpLmZpbGwodGhpcy56ZXJvX2xpbmUpOyAvLyBubyB2YWx1ZVxuXHRcdFx0ZGF0YS5wdXNoKHt2YWx1ZXM6IGQudmFsdWVzfSk7XG5cdFx0XHRkLnN2Z191bml0cyA9IFtdO1xuXG5cdFx0XHR0aGlzLm1ha2VfcGF0aCAmJiB0aGlzLm1ha2VfcGF0aChkLCBpLCB0aGlzLnhfYXhpc19wb3NpdGlvbnMsIGQueV90b3BzLCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblx0XHRcdHRoaXMubWFrZV9uZXdfdW5pdHMoZCwgaSk7XG5cdFx0fSk7XG5cblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHRoaXMudXBkYXRlX3ZhbHVlcyhkYXRhKTtcblx0XHR9LCAzNTApO1xuXHR9XG5cblx0c2V0dXBfbmF2aWdhdGlvbihpbml0KSB7XG5cdFx0Ly8gSGFjazogZGVmZXIgbmF2IHRpbGwgaW5pdGlhbCB1cGRhdGVfdmFsdWVzXG5cdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRzdXBlci5zZXR1cF9uYXZpZ2F0aW9uKGluaXQpO1xuXHRcdH0sIDUwMCk7XG5cdH1cblxuXHRtYWtlX25ld191bml0cyhkLCBpKSB7XG5cdFx0dGhpcy5tYWtlX25ld191bml0c19mb3JfZGF0YXNldChcblx0XHRcdHRoaXMueF9heGlzX3Bvc2l0aW9ucyxcblx0XHRcdGQueV90b3BzLFxuXHRcdFx0ZC5jb2xvciB8fCB0aGlzLmNvbG9yc1tpXSxcblx0XHRcdGksXG5cdFx0XHR0aGlzLnkubGVuZ3RoXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfbmV3X3VuaXRzX2Zvcl9kYXRhc2V0KHhfdmFsdWVzLCB5X3ZhbHVlcywgY29sb3IsIGRhdGFzZXRfaW5kZXgsIG5vX29mX2RhdGFzZXRzLCBncm91cCwgYXJyYXksIHVuaXQpIHtcblx0XHRpZighZ3JvdXApIGdyb3VwID0gdGhpcy5zdmdfdW5pdHNfZ3JvdXBzW2RhdGFzZXRfaW5kZXhdO1xuXHRcdGlmKCFhcnJheSkgYXJyYXkgPSB0aGlzLnlbZGF0YXNldF9pbmRleF0uc3ZnX3VuaXRzO1xuXHRcdGlmKCF1bml0KSB1bml0ID0gdGhpcy51bml0X2FyZ3M7XG5cblx0XHRncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdGFycmF5Lmxlbmd0aCA9IDA7XG5cblx0XHR5X3ZhbHVlcy5tYXAoKHksIGkpID0+IHtcblx0XHRcdGxldCBkYXRhX3VuaXQgPSB0aGlzLmRyYXdbdW5pdC50eXBlXShcblx0XHRcdFx0eF92YWx1ZXNbaV0sXG5cdFx0XHRcdHksXG5cdFx0XHRcdHVuaXQuYXJncyxcblx0XHRcdFx0Y29sb3IsXG5cdFx0XHRcdGRhdGFzZXRfaW5kZXgsXG5cdFx0XHRcdG5vX29mX2RhdGFzZXRzXG5cdFx0XHQpO1xuXHRcdFx0Z3JvdXAuYXBwZW5kQ2hpbGQoZGF0YV91bml0KTtcblx0XHRcdGFycmF5LnB1c2goZGF0YV91bml0KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfeV9zcGVjaWZpY3MoKSB7XG5cdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLnRleHRDb250ZW50ID0gJyc7XG5cdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMubWFwKGQgPT4ge1xuXHRcdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLmFwcGVuZENoaWxkKFxuXHRcdFx0XHR0aGlzLm1ha2VfeV9saW5lKFxuXHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0dGhpcy53aWR0aCxcblx0XHRcdFx0XHR0aGlzLndpZHRoICsgNSxcblx0XHRcdFx0XHRkLnRpdGxlLnRvVXBwZXJDYXNlKCksXG5cdFx0XHRcdFx0J3NwZWNpZmljLXZhbHVlJyxcblx0XHRcdFx0XHQnc3BlY2lmaWMtdmFsdWUnLFxuXHRcdFx0XHRcdHRoaXMuemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0XHRmYWxzZSxcblx0XHRcdFx0XHRkLmxpbmVfdHlwZVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0YmluZF90b29sdGlwKCkge1xuXHRcdC8vIFRPRE86IGNvdWxkIGJlIGluIHRvb2x0aXAgaXRzZWxmLCBhcyBpdCBpcyBhIGdpdmVuIGZ1bmN0aW9uYWxpdHkgZm9yIGl0cyBwYXJlbnRcblx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGUpID0+IHtcblx0XHRcdGxldCBvZmZzZXQgPSAkLm9mZnNldCh0aGlzLmNoYXJ0X3dyYXBwZXIpO1xuXHRcdFx0bGV0IHJlbFggPSBlLnBhZ2VYIC0gb2Zmc2V0LmxlZnQgLSB0aGlzLnRyYW5zbGF0ZV94O1xuXHRcdFx0bGV0IHJlbFkgPSBlLnBhZ2VZIC0gb2Zmc2V0LnRvcCAtIHRoaXMudHJhbnNsYXRlX3k7XG5cblx0XHRcdGlmKHJlbFkgPCB0aGlzLmhlaWdodCArIHRoaXMudHJhbnNsYXRlX3kgKiAyKSB7XG5cdFx0XHRcdHRoaXMubWFwX3Rvb2x0aXBfeF9wb3NpdGlvbl9hbmRfc2hvdyhyZWxYKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMudGlwLmhpZGVfdGlwKCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRtYXBfdG9vbHRpcF94X3Bvc2l0aW9uX2FuZF9zaG93KHJlbFgpIHtcblx0XHRmb3IodmFyIGk9dGhpcy54X2F4aXNfcG9zaXRpb25zLmxlbmd0aCAtIDE7IGkgPj0gMCA7IGktLSkge1xuXHRcdFx0bGV0IHhfdmFsID0gdGhpcy54X2F4aXNfcG9zaXRpb25zW2ldO1xuXHRcdFx0Ly8gbGV0IGRlbHRhID0gaSA9PT0gMCA/IHRoaXMuYXZnX3VuaXRfd2lkdGggOiB4X3ZhbCAtIHRoaXMueF9heGlzX3Bvc2l0aW9uc1tpLTFdO1xuXHRcdFx0aWYocmVsWCA+IHhfdmFsIC0gdGhpcy5hdmdfdW5pdF93aWR0aC8yKSB7XG5cdFx0XHRcdGxldCB4ID0geF92YWwgKyB0aGlzLnRyYW5zbGF0ZV94O1xuXHRcdFx0XHRsZXQgeSA9IHRoaXMueV9taW5fdG9wc1tpXSArIHRoaXMudHJhbnNsYXRlX3k7XG5cblx0XHRcdFx0bGV0IHRpdGxlID0gdGhpcy54LmZvcm1hdHRlZCAmJiB0aGlzLnguZm9ybWF0dGVkLmxlbmd0aD4wXG5cdFx0XHRcdFx0PyB0aGlzLnguZm9ybWF0dGVkW2ldIDogdGhpcy54W2ldO1xuXHRcdFx0XHRsZXQgdmFsdWVzID0gdGhpcy55Lm1hcCgoc2V0LCBqKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdHRpdGxlOiBzZXQudGl0bGUsXG5cdFx0XHRcdFx0XHR2YWx1ZTogc2V0LmZvcm1hdHRlZCA/IHNldC5mb3JtYXR0ZWRbaV0gOiBzZXQudmFsdWVzW2ldLFxuXHRcdFx0XHRcdFx0Y29sb3I6IHNldC5jb2xvciB8fCB0aGlzLmNvbG9yc1tqXSxcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHQvLyBUT0RPOiB1cHNpZGUtZG93biB0b29sdGlwcyBmb3IgbmVnYXRpdmUgdmFsdWVzP1xuXHRcdFx0XHR0aGlzLnRpcC5zZXRfdmFsdWVzKHgsIHksIHRpdGxlLCAnJywgdmFsdWVzKTtcblx0XHRcdFx0dGhpcy50aXAuc2hvd190aXAoKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQVBJXG5cdHNob3dfc3VtcygpIHtcblx0XHR0aGlzLnVwZGF0aW5nID0gdHJ1ZTtcblxuXHRcdHRoaXMueV9zdW1zID0gbmV3IEFycmF5KHRoaXMueF9heGlzX3Bvc2l0aW9ucy5sZW5ndGgpLmZpbGwoMCk7XG5cdFx0dGhpcy55Lm1hcChkID0+IHtcblx0XHRcdGQudmFsdWVzLm1hcCggKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRcdHRoaXMueV9zdW1zW2ldICs9IHZhbHVlO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHQvLyBSZW1ha2UgeSBheGlzLCBhbmltYXRlXG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKCk7XG5cblx0XHQvLyBUaGVuIG1ha2Ugc3VtIHVuaXRzLCBkb24ndCBhbmltYXRlXG5cdFx0dGhpcy5zdW1fdW5pdHMgPSBbXTtcblxuXHRcdHRoaXMubWFrZV9uZXdfdW5pdHNfZm9yX2RhdGFzZXQoXG5cdFx0XHR0aGlzLnhfYXhpc19wb3NpdGlvbnMsXG5cdFx0XHR0aGlzLnlfc3Vtcy5tYXAoIHZhbCA9PiBmbG9hdF8yKHRoaXMuemVyb19saW5lIC0gdmFsICogdGhpcy5tdWx0aXBsaWVyKSksXG5cdFx0XHQnbGlnaHQtZ3JleScsXG5cdFx0XHQwLFxuXHRcdFx0MSxcblx0XHRcdHRoaXMuc3VtX2dyb3VwLFxuXHRcdFx0dGhpcy5zdW1fdW5pdHNcblx0XHQpO1xuXG5cdFx0Ly8gdGhpcy5tYWtlX3BhdGggJiYgdGhpcy5tYWtlX3BhdGgoZCwgaSwgb2xkX3gsIG9sZF95LCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblxuXHRcdHRoaXMudXBkYXRpbmcgPSBmYWxzZTtcblx0fVxuXG5cdGhpZGVfc3VtcygpIHtcblx0XHRpZih0aGlzLnVwZGF0aW5nKSByZXR1cm47XG5cdFx0dGhpcy55X3N1bXMgPSBbXTtcblx0XHR0aGlzLnN1bV9ncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdHRoaXMuc3VtX3VuaXRzID0gW107XG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKCk7XG5cdH1cblxuXHRzaG93X2F2ZXJhZ2UoKSB7XG5cdFx0dGhpcy5vbGRfc3BlY2lmaWNfdmFsdWVzID0gdGhpcy5zcGVjaWZpY192YWx1ZXMuc2xpY2UoKTtcblx0XHR0aGlzLnkubWFwKChkLCBpKSA9PiB7XG5cdFx0XHRsZXQgc3VtID0gMDtcblx0XHRcdGQudmFsdWVzLm1hcChlID0+IHtzdW0rPWU7fSk7XG5cdFx0XHRsZXQgYXZlcmFnZSA9IHN1bS9kLnZhbHVlcy5sZW5ndGg7XG5cblx0XHRcdHRoaXMuc3BlY2lmaWNfdmFsdWVzLnB1c2goe1xuXHRcdFx0XHR0aXRsZTogXCJBVkdcIiArIFwiIFwiICsgKGkrMSksXG5cdFx0XHRcdGxpbmVfdHlwZTogXCJkYXNoZWRcIixcblx0XHRcdFx0dmFsdWU6IGF2ZXJhZ2UsXG5cdFx0XHRcdGF1dG86IDFcblx0XHRcdH0pO1xuXHRcdH0pO1xuXG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKCk7XG5cdH1cblxuXHRoaWRlX2F2ZXJhZ2UoKSB7XG5cdFx0dGhpcy5vbGRfc3BlY2lmaWNfdmFsdWVzID0gdGhpcy5zcGVjaWZpY192YWx1ZXMuc2xpY2UoKTtcblxuXHRcdGxldCBpbmRpY2VzX3RvX3JlbW92ZSA9IFtdO1xuXHRcdHRoaXMuc3BlY2lmaWNfdmFsdWVzLm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0aWYoZC5hdXRvKSBpbmRpY2VzX3RvX3JlbW92ZS51bnNoaWZ0KGkpO1xuXHRcdH0pO1xuXG5cdFx0aW5kaWNlc190b19yZW1vdmUubWFwKGluZGV4ID0+IHtcblx0XHRcdHRoaXMuc3BlY2lmaWNfdmFsdWVzLnNwbGljZShpbmRleCwgMSk7XG5cdFx0fSk7XG5cblx0XHR0aGlzLnVwZGF0ZV92YWx1ZXMoKTtcblx0fVxuXG5cdHVwZGF0ZV92YWx1ZXMobmV3X3ksIG5ld194KSB7XG5cdFx0aWYoIW5ld194KSB7XG5cdFx0XHRuZXdfeCA9IHRoaXMueDtcblx0XHR9XG5cdFx0dGhpcy5lbGVtZW50c190b19hbmltYXRlID0gW107XG5cdFx0dGhpcy51cGRhdGluZyA9IHRydWU7XG5cblx0XHR0aGlzLm9sZF94X3ZhbHVlcyA9IHRoaXMueC5zbGljZSgpO1xuXHRcdHRoaXMub2xkX3lfYXhpc190b3BzID0gdGhpcy55Lm1hcChkID0+IGQueV90b3BzLnNsaWNlKCkpO1xuXG5cdFx0dGhpcy5vbGRfeV92YWx1ZXMgPSB0aGlzLnkubWFwKGQgPT4gZC52YWx1ZXMpO1xuXG5cdFx0dGhpcy5ub19vZl9leHRyYV9wdHMgPSBuZXdfeC5sZW5ndGggLSB0aGlzLngubGVuZ3RoO1xuXG5cdFx0Ly8gSnVzdCB1cGRhdGUgdmFsdWVzIHByb3AsIHNldHVwX3gveSgpIHdpbGwgZG8gdGhlIHJlc3Rcblx0XHRpZihuZXdfeSkgdGhpcy55Lm1hcCgoZCwgaSkgPT4ge2QudmFsdWVzID0gbmV3X3lbaV0udmFsdWVzO30pO1xuXHRcdGlmKG5ld194KSB0aGlzLnggPSBuZXdfeDtcblxuXHRcdHRoaXMuc2V0dXBfeCgpO1xuXHRcdHRoaXMuc2V0dXBfeSgpO1xuXG5cdFx0Ly8gQW5pbWF0ZSBvbmx5IGlmIHBvc2l0aW9ucyBoYXZlIGNoYW5nZWRcblx0XHRpZighYXJyYXlzX2VxdWFsKHRoaXMueF9vbGRfYXhpc19wb3NpdGlvbnMsIHRoaXMueF9heGlzX3Bvc2l0aW9ucykpIHtcblx0XHRcdHRoaXMubWFrZV94X2F4aXModHJ1ZSk7XG5cdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0aWYoIXRoaXMudXBkYXRpbmcpIHRoaXMubWFrZV94X2F4aXMoKTtcblx0XHRcdH0sIDMwMCk7XG5cdFx0fVxuXG5cdFx0aWYoIWFycmF5c19lcXVhbCh0aGlzLnlfb2xkX2F4aXNfdmFsdWVzLCB0aGlzLnlfYXhpc192YWx1ZXMpIHx8XG5cdFx0XHQodGhpcy5vbGRfc3BlY2lmaWNfdmFsdWVzICYmXG5cdFx0XHQhYXJyYXlzX2VxdWFsKHRoaXMub2xkX3NwZWNpZmljX3ZhbHVlcywgdGhpcy5zcGVjaWZpY192YWx1ZXMpKSkge1xuXG5cdFx0XHR0aGlzLm1ha2VfeV9heGlzKHRydWUpO1xuXHRcdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRcdGlmKCF0aGlzLnVwZGF0aW5nKSB7XG5cdFx0XHRcdFx0dGhpcy5tYWtlX3lfYXhpcygpO1xuXHRcdFx0XHRcdHRoaXMubWFrZV95X3NwZWNpZmljcygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LCAzMDApO1xuXHRcdH1cblxuXHRcdC8vIENoYW5nZSBpbiBkYXRhLCBzbyBjYWxjdWxhdGUgZGVwZW5kZW5jaWVzXG5cdFx0dGhpcy5jYWxjX3lfZGVwZW5kZW5jaWVzKCk7XG5cblx0XHR0aGlzLmFuaW1hdGVfZ3JhcGhzKCk7XG5cblx0XHQvLyBUcmlnZ2VyIGFuaW1hdGlvbiB3aXRoIHRoZSBhbmltYXRhYmxlIGVsZW1lbnRzIGluIHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZVxuXHRcdHRoaXMucnVuX2FuaW1hdGlvbigpO1xuXG5cdFx0dGhpcy51cGRhdGluZyA9IGZhbHNlO1xuXHR9XG5cblx0YWRkX2RhdGFfcG9pbnQoeV9wb2ludCwgeF9wb2ludCwgaW5kZXg9dGhpcy54Lmxlbmd0aCkge1xuXHRcdGxldCBuZXdfeSA9IHRoaXMueS5tYXAoZGF0YV9zZXQgPT4geyByZXR1cm4ge3ZhbHVlczpkYXRhX3NldC52YWx1ZXN9OyB9KTtcblx0XHRuZXdfeS5tYXAoKGQsIGkpID0+IHsgZC52YWx1ZXMuc3BsaWNlKGluZGV4LCAwLCB5X3BvaW50W2ldKTsgfSk7XG5cdFx0bGV0IG5ld194ID0gdGhpcy54LnNsaWNlKCk7XG5cdFx0bmV3X3guc3BsaWNlKGluZGV4LCAwLCB4X3BvaW50KTtcblxuXHRcdHRoaXMudXBkYXRlX3ZhbHVlcyhuZXdfeSwgbmV3X3gpO1xuXHR9XG5cblx0cmVtb3ZlX2RhdGFfcG9pbnQoaW5kZXggPSB0aGlzLngubGVuZ3RoLTEpIHtcblx0XHRpZih0aGlzLngubGVuZ3RoIDwgMykgcmV0dXJuO1xuXG5cdFx0bGV0IG5ld195ID0gdGhpcy55Lm1hcChkYXRhX3NldCA9PiB7IHJldHVybiB7dmFsdWVzOmRhdGFfc2V0LnZhbHVlc307IH0pO1xuXHRcdG5ld195Lm1hcCgoZCkgPT4geyBkLnZhbHVlcy5zcGxpY2UoaW5kZXgsIDEpOyB9KTtcblx0XHRsZXQgbmV3X3ggPSB0aGlzLnguc2xpY2UoKTtcblx0XHRuZXdfeC5zcGxpY2UoaW5kZXgsIDEpO1xuXG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKG5ld195LCBuZXdfeCk7XG5cdH1cblxuXHRydW5fYW5pbWF0aW9uKCkge1xuXHRcdGxldCBhbmltX3N2ZyA9ICQucnVuU1ZHQW5pbWF0aW9uKHRoaXMuc3ZnLCB0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUpO1xuXG5cdFx0aWYodGhpcy5zdmcucGFyZW50Tm9kZSA9PSB0aGlzLmNoYXJ0X3dyYXBwZXIpIHtcblx0XHRcdHRoaXMuY2hhcnRfd3JhcHBlci5yZW1vdmVDaGlsZCh0aGlzLnN2Zyk7XG5cdFx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIuYXBwZW5kQ2hpbGQoYW5pbV9zdmcpO1xuXG5cdFx0fVxuXG5cdFx0Ly8gUmVwbGFjZSB0aGUgbmV3IHN2ZyAoZGF0YSBoYXMgbG9uZyBiZWVuIHJlcGxhY2VkKVxuXHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0aWYoYW5pbV9zdmcucGFyZW50Tm9kZSA9PSB0aGlzLmNoYXJ0X3dyYXBwZXIpIHtcblx0XHRcdFx0dGhpcy5jaGFydF93cmFwcGVyLnJlbW92ZUNoaWxkKGFuaW1fc3ZnKTtcblx0XHRcdFx0dGhpcy5jaGFydF93cmFwcGVyLmFwcGVuZENoaWxkKHRoaXMuc3ZnKTtcblx0XHRcdH1cblx0XHR9LCAyMDApO1xuXHR9XG5cblx0YW5pbWF0ZV9ncmFwaHMoKSB7XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0Ly8gUHJlLXByZXAsIGVxdWlsaXplIG5vIG9mIHBvc2l0aW9ucyBiZXR3ZWVuIG9sZCBhbmQgbmV3XG5cdFx0XHRsZXQgW29sZF94LCBvbGRfeSwgbmV3X3gsIG5ld195XSA9IHRoaXMuY2FsY19vbGRfYW5kX25ld19wb3N0aW9ucyhkLCBpKTtcblx0XHRcdGlmKHRoaXMubm9fb2ZfZXh0cmFfcHRzID49IDApIHtcblx0XHRcdFx0dGhpcy5tYWtlX3BhdGggJiYgdGhpcy5tYWtlX3BhdGgoZCwgaSwgb2xkX3gsIG9sZF95LCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblx0XHRcdFx0dGhpcy5tYWtlX25ld191bml0c19mb3JfZGF0YXNldChvbGRfeCwgb2xkX3ksIGQuY29sb3IgfHwgdGhpcy5jb2xvcnNbaV0sIGksIHRoaXMueS5sZW5ndGgpO1xuXHRcdFx0fVxuXHRcdFx0ZC5wYXRoICYmIHRoaXMuYW5pbWF0ZV9wYXRoKGQsIGksIG9sZF94LCBvbGRfeSwgbmV3X3gsIG5ld195KTtcblx0XHRcdHRoaXMuYW5pbWF0ZV91bml0cyhkLCBpLCBvbGRfeCwgb2xkX3ksIG5ld194LCBuZXdfeSk7XG5cdFx0fSk7XG5cblx0XHQvLyBUT0RPOiByZXBsYWNlIHdpdGggcmVhbCB1bml0c1xuXHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0XHR0aGlzLm1ha2VfcGF0aCAmJiB0aGlzLm1ha2VfcGF0aChkLCBpLCB0aGlzLnhfYXhpc19wb3NpdGlvbnMsIGQueV90b3BzLCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblx0XHRcdFx0dGhpcy5tYWtlX25ld191bml0cyhkLCBpKTtcblx0XHRcdH0pO1xuXHRcdH0sIDMwMCk7XG5cdH1cblxuXHRhbmltYXRlX3BhdGgoZCwgaSwgb2xkX3gsIG9sZF95LCBuZXdfeCwgbmV3X3kpIHtcblx0XHQvLyBBbmltYXRlIHBhdGhcblx0XHRjb25zdCBuZXdfcG9pbnRzX2xpc3QgPSBuZXdfeS5tYXAoKHksIGkpID0+IChuZXdfeFtpXSArICcsJyArIHkpKTtcblx0XHRjb25zdCBuZXdfcGF0aF9zdHIgPSBuZXdfcG9pbnRzX2xpc3Quam9pbihcIkxcIik7XG5cblx0XHRjb25zdCBwYXRoX2FyZ3MgPSBbe3VuaXQ6IGQucGF0aCwgb2JqZWN0OiBkLCBrZXk6ICdwYXRoJ30sIHtkOlwiTVwiK25ld19wYXRoX3N0cn0sIDI1MCwgXCJlYXNlaW5cIl07XG5cdFx0dGhpcy5lbGVtZW50c190b19hbmltYXRlLnB1c2gocGF0aF9hcmdzKTtcblxuXHRcdC8vIEFuaW1hdGUgcmVnaW9uXG5cdFx0aWYoZC5yZWdpb25fcGF0aCkge1xuXHRcdFx0bGV0IHJlZ19zdGFydF9wdCA9IGAwLCR7dGhpcy56ZXJvX2xpbmV9TGA7XG5cdFx0XHRsZXQgcmVnX2VuZF9wdCA9IGBMJHt0aGlzLndpZHRofSwke3RoaXMuemVyb19saW5lfWA7XG5cblx0XHRcdGNvbnN0IHJlZ2lvbl9hcmdzID0gW1xuXHRcdFx0XHR7dW5pdDogZC5yZWdpb25fcGF0aCwgb2JqZWN0OiBkLCBrZXk6ICdyZWdpb25fcGF0aCd9LFxuXHRcdFx0XHR7ZDpcIk1cIiArIHJlZ19zdGFydF9wdCArIG5ld19wYXRoX3N0ciArIHJlZ19lbmRfcHR9LFxuXHRcdFx0XHQyNTAsXG5cdFx0XHRcdFwiZWFzZWluXCJcblx0XHRcdF07XG5cdFx0XHR0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUucHVzaChyZWdpb25fYXJncyk7XG5cdFx0fVxuXHR9XG5cblx0YW5pbWF0ZV91bml0cyhkLCBpbmRleCwgb2xkX3gsIG9sZF95LCBuZXdfeCwgbmV3X3kpIHtcblx0XHRsZXQgdHlwZSA9IHRoaXMudW5pdF9hcmdzLnR5cGU7XG5cblx0XHRkLnN2Z191bml0cy5tYXAoKHVuaXQsIGkpID0+IHtcblx0XHRcdHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZS5wdXNoKHRoaXMuYW5pbWF0ZVt0eXBlXShcblx0XHRcdFx0e3VuaXQ6dW5pdCwgYXJyYXk6ZC5zdmdfdW5pdHMsIGluZGV4OiBpfSwgLy8gdW5pdCwgd2l0aCBpbmZvIHRvIHJlcGxhY2Ugd2hlcmUgaXQgY2FtZSBmcm9tIGluIHRoZSBkYXRhXG5cdFx0XHRcdG5ld194W2ldLFxuXHRcdFx0XHRuZXdfeVtpXSxcblx0XHRcdFx0aW5kZXhcblx0XHRcdCkpO1xuXHRcdH0pO1xuXHR9XG5cblx0Y2FsY19vbGRfYW5kX25ld19wb3N0aW9ucyhkLCBpKSB7XG5cdFx0bGV0IG9sZF94ID0gdGhpcy54X29sZF9heGlzX3Bvc2l0aW9ucy5zbGljZSgpO1xuXHRcdGxldCBuZXdfeCA9IHRoaXMueF9heGlzX3Bvc2l0aW9ucy5zbGljZSgpO1xuXG5cdFx0bGV0IG9sZF95ID0gdGhpcy5vbGRfeV9heGlzX3RvcHNbaV0uc2xpY2UoKTtcblx0XHRsZXQgbmV3X3kgPSBkLnlfdG9wcy5zbGljZSgpO1xuXG5cdFx0Y29uc3QgbGFzdF9vbGRfeF9wb3MgPSBvbGRfeFtvbGRfeC5sZW5ndGggLSAxXTtcblx0XHRjb25zdCBsYXN0X29sZF95X3BvcyA9IG9sZF95W29sZF95Lmxlbmd0aCAtIDFdO1xuXG5cdFx0Y29uc3QgbGFzdF9uZXdfeF9wb3MgPSBuZXdfeFtuZXdfeC5sZW5ndGggLSAxXTtcblx0XHRjb25zdCBsYXN0X25ld195X3BvcyA9IG5ld195W25ld195Lmxlbmd0aCAtIDFdO1xuXG5cdFx0aWYodGhpcy5ub19vZl9leHRyYV9wdHMgPj0gMCkge1xuXHRcdFx0Ly8gRmlyc3Qgc3Vic3RpdHV0ZSBjdXJyZW50IHBhdGggd2l0aCBhIHNxdWlnZ2xlZCBvbmUgKGxvb2tpbmcgdGhlIHNhbWUgYnV0XG5cdFx0XHQvLyBoYXZpbmcgbW9yZSBwb2ludHMgYXQgZW5kKSxcblx0XHRcdC8vIHRoZW4gYW5pbWF0ZSB0byBzdHJldGNoIGl0IGxhdGVyIHRvIG5ldyBwb2ludHNcblx0XHRcdC8vIChuZXcgcG9pbnRzIGFscmVhZHkgaGF2ZSBtb3JlIHBvaW50cylcblxuXHRcdFx0Ly8gSGVuY2UsIHRoZSBleHRyYSBlbmQgcG9pbnRzIHdpbGwgY29ycmVzcG9uZCB0byBjdXJyZW50KG9sZCkgcG9zaXRpb25zXG5cdFx0XHRsZXQgZmlsbGVyX3ggPSBuZXcgQXJyYXkoTWF0aC5hYnModGhpcy5ub19vZl9leHRyYV9wdHMpKS5maWxsKGxhc3Rfb2xkX3hfcG9zKTtcblx0XHRcdGxldCBmaWxsZXJfeSA9IG5ldyBBcnJheShNYXRoLmFicyh0aGlzLm5vX29mX2V4dHJhX3B0cykpLmZpbGwobGFzdF9vbGRfeV9wb3MpO1xuXG5cdFx0XHRvbGRfeCA9IG9sZF94LmNvbmNhdChmaWxsZXJfeCk7XG5cdFx0XHRvbGRfeSA9IG9sZF95LmNvbmNhdChmaWxsZXJfeSk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gSnVzdCBtb2RpZnkgdGhlIG5ldyBwb2ludHMgdG8gaGF2ZSBleHRyYSBwb2ludHNcblx0XHRcdC8vIHdpdGggdGhlIHNhbWUgcG9zaXRpb24gYXQgZW5kXG5cdFx0XHRsZXQgZmlsbGVyX3ggPSBuZXcgQXJyYXkoTWF0aC5hYnModGhpcy5ub19vZl9leHRyYV9wdHMpKS5maWxsKGxhc3RfbmV3X3hfcG9zKTtcblx0XHRcdGxldCBmaWxsZXJfeSA9IG5ldyBBcnJheShNYXRoLmFicyh0aGlzLm5vX29mX2V4dHJhX3B0cykpLmZpbGwobGFzdF9uZXdfeV9wb3MpO1xuXG5cdFx0XHRuZXdfeCA9IG5ld194LmNvbmNhdChmaWxsZXJfeCk7XG5cdFx0XHRuZXdfeSA9IG5ld195LmNvbmNhdChmaWxsZXJfeSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtvbGRfeCwgb2xkX3ksIG5ld194LCBuZXdfeV07XG5cdH1cblxuXHRtYWtlX2FuaW1feF9heGlzKGhlaWdodCwgdGV4dF9zdGFydF9hdCwgYXhpc19saW5lX2NsYXNzKSB7XG5cdFx0Ly8gQW5pbWF0ZSBYIEFYSVMgdG8gYWNjb3VudCBmb3IgbW9yZSBvciBsZXNzIGF4aXMgbGluZXNcblxuXHRcdGNvbnN0IG9sZF9wb3MgPSB0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zO1xuXHRcdGNvbnN0IG5ld19wb3MgPSB0aGlzLnhfYXhpc19wb3NpdGlvbnM7XG5cblx0XHRjb25zdCBvbGRfdmFscyA9IHRoaXMub2xkX3hfdmFsdWVzO1xuXHRcdGNvbnN0IG5ld192YWxzID0gdGhpcy54O1xuXG5cdFx0Y29uc3QgbGFzdF9saW5lX3BvcyA9IG9sZF9wb3Nbb2xkX3Bvcy5sZW5ndGggLSAxXTtcblxuXHRcdGxldCBhZGRfYW5kX2FuaW1hdGVfbGluZSA9ICh2YWx1ZSwgb2xkX3BvcywgbmV3X3BvcykgPT4ge1xuXHRcdFx0Y29uc3QgeF9saW5lID0gdGhpcy5tYWtlX3hfbGluZShcblx0XHRcdFx0aGVpZ2h0LFxuXHRcdFx0XHR0ZXh0X3N0YXJ0X2F0LFxuXHRcdFx0XHR2YWx1ZSwgLy8gbmV3IHZhbHVlXG5cdFx0XHRcdCd4LXZhbHVlLXRleHQnLFxuXHRcdFx0XHRheGlzX2xpbmVfY2xhc3MsXG5cdFx0XHRcdG9sZF9wb3MgLy8gb2xkIHBvc2l0aW9uXG5cdFx0XHQpO1xuXHRcdFx0dGhpcy54X2F4aXNfZ3JvdXAuYXBwZW5kQ2hpbGQoeF9saW5lKTtcblxuXHRcdFx0dGhpcy5lbGVtZW50c190b19hbmltYXRlICYmIHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZS5wdXNoKFtcblx0XHRcdFx0e3VuaXQ6IHhfbGluZSwgYXJyYXk6IFswXSwgaW5kZXg6IDB9LFxuXHRcdFx0XHR7dHJhbnNmb3JtOiBgJHsgbmV3X3BvcyB9LCAwYH0sXG5cdFx0XHRcdDI1MCxcblx0XHRcdFx0XCJlYXNlaW5cIixcblx0XHRcdFx0XCJ0cmFuc2xhdGVcIixcblx0XHRcdFx0e3RyYW5zZm9ybTogYCR7IG9sZF9wb3MgfSwgMGB9XG5cdFx0XHRdKTtcblx0XHR9O1xuXG5cdFx0dGhpcy54X2F4aXNfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblxuXHRcdHRoaXMubWFrZV9uZXdfYXhpc19hbmltX2xpbmVzKFxuXHRcdFx0b2xkX3Bvcyxcblx0XHRcdG5ld19wb3MsXG5cdFx0XHRvbGRfdmFscyxcblx0XHRcdG5ld192YWxzLFxuXHRcdFx0bGFzdF9saW5lX3Bvcyxcblx0XHRcdGFkZF9hbmRfYW5pbWF0ZV9saW5lXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfYW5pbV95X2F4aXMoKSB7XG5cdFx0Ly8gQW5pbWF0ZSBZIEFYSVMgdG8gYWNjb3VudCBmb3IgbW9yZSBvciBsZXNzIGF4aXMgbGluZXNcblxuXHRcdGNvbnN0IG9sZF9wb3MgPSB0aGlzLnlfb2xkX2F4aXNfdmFsdWVzLm1hcCh2YWx1ZSA9PlxuXHRcdFx0dGhpcy56ZXJvX2xpbmUgLSB2YWx1ZSAqIHRoaXMubXVsdGlwbGllcik7XG5cdFx0Y29uc3QgbmV3X3BvcyA9IHRoaXMueV9heGlzX3ZhbHVlcy5tYXAodmFsdWUgPT5cblx0XHRcdHRoaXMuemVyb19saW5lIC0gdmFsdWUgKiB0aGlzLm11bHRpcGxpZXIpO1xuXG5cdFx0Y29uc3Qgb2xkX3ZhbHMgPSB0aGlzLnlfb2xkX2F4aXNfdmFsdWVzO1xuXHRcdGNvbnN0IG5ld192YWxzID0gdGhpcy55X2F4aXNfdmFsdWVzO1xuXG5cdFx0Y29uc3QgbGFzdF9saW5lX3BvcyA9IG9sZF9wb3Nbb2xkX3Bvcy5sZW5ndGggLSAxXTtcblxuXHRcdHRoaXMueV9heGlzX2dyb3VwLnRleHRDb250ZW50ID0gJyc7XG5cblx0XHR0aGlzLm1ha2VfbmV3X2F4aXNfYW5pbV9saW5lcyhcblx0XHRcdG9sZF9wb3MsXG5cdFx0XHRuZXdfcG9zLFxuXHRcdFx0b2xkX3ZhbHMsXG5cdFx0XHRuZXdfdmFscyxcblx0XHRcdGxhc3RfbGluZV9wb3MsXG5cdFx0XHR0aGlzLmFkZF9hbmRfYW5pbWF0ZV95X2xpbmUuYmluZCh0aGlzKSxcblx0XHRcdHRoaXMueV9heGlzX2dyb3VwXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfYW5pbV95X3NwZWNpZmljcygpIHtcblx0XHR0aGlzLnNwZWNpZmljX3lfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLnNwZWNpZmljX3ZhbHVlcy5tYXAoKGQpID0+IHtcblx0XHRcdHRoaXMuYWRkX2FuZF9hbmltYXRlX3lfbGluZShcblx0XHRcdFx0ZC50aXRsZSxcblx0XHRcdFx0dGhpcy5vbGRfemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMub2xkX211bHRpcGxpZXIsXG5cdFx0XHRcdHRoaXMuemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0MCxcblx0XHRcdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLFxuXHRcdFx0XHRkLmxpbmVfdHlwZSxcblx0XHRcdFx0dHJ1ZVxuXHRcdFx0KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfbmV3X2F4aXNfYW5pbV9saW5lcyhvbGRfcG9zLCBuZXdfcG9zLCBvbGRfdmFscywgbmV3X3ZhbHMsIGxhc3RfbGluZV9wb3MsIGFkZF9hbmRfYW5pbWF0ZV9saW5lLCBncm91cCkge1xuXHRcdGxldCBzdXBlcmltcG9zZWRfcG9zaXRpb25zLCBzdXBlcmltcG9zZWRfdmFsdWVzO1xuXHRcdGxldCBub19vZl9leHRyYXMgPSBuZXdfdmFscy5sZW5ndGggLSBvbGRfdmFscy5sZW5ndGg7XG5cdFx0aWYobm9fb2ZfZXh0cmFzID4gMCkge1xuXHRcdFx0Ly8gTW9yZSBheGlzIGFyZSBuZWVkZWRcblx0XHRcdC8vIEZpcnN0IG1ha2Ugb25seSB0aGUgc3VwZXJpbXBvc2VkIChzYW1lIHBvc2l0aW9uKSBvbmVzXG5cdFx0XHQvLyBBZGQgaW4gdGhlIGV4dHJhcyBhdCB0aGUgZW5kIGxhdGVyXG5cdFx0XHRzdXBlcmltcG9zZWRfcG9zaXRpb25zID0gbmV3X3Bvcy5zbGljZSgwLCBvbGRfcG9zLmxlbmd0aCk7XG5cdFx0XHRzdXBlcmltcG9zZWRfdmFsdWVzID0gbmV3X3ZhbHMuc2xpY2UoMCwgb2xkX3ZhbHMubGVuZ3RoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gQXhpcyBoYXZlIHRvIGJlIHJlZHVjZWRcblx0XHRcdC8vIEZha2UgaXQgYnkgbW92aW5nIGFsbCBjdXJyZW50IGV4dHJhIGF4aXMgdG8gdGhlIGxhc3QgcG9zaXRpb25cblx0XHRcdC8vIFlvdSdsbCBuZWVkIGZpbGxlciBwb3NpdGlvbnMgYW5kIHZhbHVlcyBpbiB0aGUgbmV3IGFycmF5c1xuXHRcdFx0Y29uc3QgZmlsbGVyX3ZhbHMgPSBuZXcgQXJyYXkoTWF0aC5hYnMobm9fb2ZfZXh0cmFzKSkuZmlsbChcIlwiKTtcblx0XHRcdHN1cGVyaW1wb3NlZF92YWx1ZXMgPSBuZXdfdmFscy5jb25jYXQoZmlsbGVyX3ZhbHMpO1xuXG5cdFx0XHRjb25zdCBmaWxsZXJfcG9zID0gbmV3IEFycmF5KE1hdGguYWJzKG5vX29mX2V4dHJhcykpLmZpbGwobGFzdF9saW5lX3Bvcyk7XG5cdFx0XHRzdXBlcmltcG9zZWRfcG9zaXRpb25zID0gbmV3X3Bvcy5jb25jYXQoZmlsbGVyX3Bvcyk7XG5cdFx0fVxuXG5cdFx0c3VwZXJpbXBvc2VkX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRhZGRfYW5kX2FuaW1hdGVfbGluZSh2YWx1ZSwgb2xkX3Bvc1tpXSwgc3VwZXJpbXBvc2VkX3Bvc2l0aW9uc1tpXSwgaSwgZ3JvdXApO1xuXHRcdH0pO1xuXG5cdFx0aWYobm9fb2ZfZXh0cmFzID4gMCkge1xuXHRcdFx0Ly8gQWRkIGluIGV4dHJhIGF4aXMgaW4gdGhlIGVuZFxuXHRcdFx0Ly8gYW5kIHRoZW4gYW5pbWF0ZSB0byBuZXcgcG9zaXRpb25zXG5cdFx0XHRjb25zdCBleHRyYV92YWx1ZXMgPSBuZXdfdmFscy5zbGljZShvbGRfdmFscy5sZW5ndGgpO1xuXHRcdFx0Y29uc3QgZXh0cmFfcG9zaXRpb25zID0gbmV3X3Bvcy5zbGljZShvbGRfcG9zLmxlbmd0aCk7XG5cblx0XHRcdGV4dHJhX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRcdGFkZF9hbmRfYW5pbWF0ZV9saW5lKHZhbHVlLCBsYXN0X2xpbmVfcG9zLCBleHRyYV9wb3NpdGlvbnNbaV0sIGksIGdyb3VwKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdG1ha2VfeF9saW5lKGhlaWdodCwgdGV4dF9zdGFydF9hdCwgcG9pbnQsIGxhYmVsX2NsYXNzLCBheGlzX2xpbmVfY2xhc3MsIHhfcG9zKSB7XG5cdFx0bGV0IGFsbG93ZWRfc3BhY2UgPSB0aGlzLmF2Z191bml0X3dpZHRoICogMS41O1xuXG5cdFx0aWYodGhpcy5nZXRfc3Ryd2lkdGgocG9pbnQpID4gYWxsb3dlZF9zcGFjZSkge1xuXHRcdFx0bGV0IGFsbG93ZWRfbGV0dGVycyA9IGFsbG93ZWRfc3BhY2UgLyA4O1xuXHRcdFx0cG9pbnQgPSBwb2ludC5zbGljZSgwLCBhbGxvd2VkX2xldHRlcnMtMykgKyBcIiAuLi5cIjtcblx0XHR9XG5cblx0XHRsZXQgbGluZSA9ICQuY3JlYXRlU1ZHKCdsaW5lJywge1xuXHRcdFx0eDE6IDAsXG5cdFx0XHR4MjogMCxcblx0XHRcdHkxOiAwLFxuXHRcdFx0eTI6IGhlaWdodFxuXHRcdH0pO1xuXG5cdFx0bGV0IHRleHQgPSAkLmNyZWF0ZVNWRygndGV4dCcsIHtcblx0XHRcdGNsYXNzTmFtZTogbGFiZWxfY2xhc3MsXG5cdFx0XHR4OiAwLFxuXHRcdFx0eTogdGV4dF9zdGFydF9hdCxcblx0XHRcdGR5OiAnLjcxZW0nLFxuXHRcdFx0aW5uZXJIVE1MOiBwb2ludFxuXHRcdH0pO1xuXG5cdFx0bGV0IHhfbGV2ZWwgPSAkLmNyZWF0ZVNWRygnZycsIHtcblx0XHRcdGNsYXNzTmFtZTogYHRpY2sgJHtheGlzX2xpbmVfY2xhc3N9YCxcblx0XHRcdHRyYW5zZm9ybTogYHRyYW5zbGF0ZSgkeyB4X3BvcyB9LCAwKWBcblx0XHR9KTtcblxuXHRcdHhfbGV2ZWwuYXBwZW5kQ2hpbGQobGluZSk7XG5cdFx0eF9sZXZlbC5hcHBlbmRDaGlsZCh0ZXh0KTtcblxuXHRcdHJldHVybiB4X2xldmVsO1xuXHR9XG5cblx0bWFrZV95X2xpbmUoc3RhcnRfYXQsIHdpZHRoLCB0ZXh0X2VuZF9hdCwgcG9pbnQsIGxhYmVsX2NsYXNzLCBheGlzX2xpbmVfY2xhc3MsIHlfcG9zLCBkYXJrZXI9ZmFsc2UsIGxpbmVfdHlwZT1cIlwiKSB7XG5cdFx0bGV0IGxpbmUgPSAkLmNyZWF0ZVNWRygnbGluZScsIHtcblx0XHRcdGNsYXNzTmFtZTogbGluZV90eXBlID09PSBcImRhc2hlZFwiID8gXCJkYXNoZWRcIjogXCJcIixcblx0XHRcdHgxOiBzdGFydF9hdCxcblx0XHRcdHgyOiB3aWR0aCxcblx0XHRcdHkxOiAwLFxuXHRcdFx0eTI6IDBcblx0XHR9KTtcblxuXHRcdGxldCB0ZXh0ID0gJC5jcmVhdGVTVkcoJ3RleHQnLCB7XG5cdFx0XHRjbGFzc05hbWU6IGxhYmVsX2NsYXNzLFxuXHRcdFx0eDogdGV4dF9lbmRfYXQsXG5cdFx0XHR5OiAwLFxuXHRcdFx0ZHk6ICcuMzJlbScsXG5cdFx0XHRpbm5lckhUTUw6IHBvaW50K1wiXCJcblx0XHR9KTtcblxuXHRcdGxldCB5X2xldmVsID0gJC5jcmVhdGVTVkcoJ2cnLCB7XG5cdFx0XHRjbGFzc05hbWU6IGB0aWNrICR7YXhpc19saW5lX2NsYXNzfWAsXG5cdFx0XHR0cmFuc2Zvcm06IGB0cmFuc2xhdGUoMCwgJHt5X3Bvc30pYFxuXHRcdH0pO1xuXG5cdFx0aWYoZGFya2VyKSB7XG5cdFx0XHRsaW5lLnN0eWxlLnN0cm9rZSA9IFwicmdiYSgyNywgMzEsIDM1LCAwLjYpXCI7XG5cdFx0fVxuXG5cdFx0eV9sZXZlbC5hcHBlbmRDaGlsZChsaW5lKTtcblx0XHR5X2xldmVsLmFwcGVuZENoaWxkKHRleHQpO1xuXG5cdFx0cmV0dXJuIHlfbGV2ZWw7XG5cdH1cblxuXHRhZGRfYW5kX2FuaW1hdGVfeV9saW5lKHZhbHVlLCBvbGRfcG9zLCBuZXdfcG9zLCBpLCBncm91cCwgdHlwZSwgc3BlY2lmaWM9ZmFsc2UpIHtcblx0XHRsZXQgW3dpZHRoLCB0ZXh0X2VuZF9hdCwgYXhpc19saW5lX2NsYXNzLCBzdGFydF9hdF0gPSB0aGlzLmdldF95X2F4aXNfbGluZV9wcm9wcyhzcGVjaWZpYyk7XG5cdFx0bGV0IGF4aXNfbGFiZWxfY2xhc3MgPSAhc3BlY2lmaWMgPyAneS12YWx1ZS10ZXh0JyA6ICdzcGVjaWZpYy12YWx1ZSc7XG5cdFx0dmFsdWUgPSAhc3BlY2lmaWMgPyB2YWx1ZSA6ICh2YWx1ZStcIlwiKS50b1VwcGVyQ2FzZSgpO1xuXHRcdGNvbnN0IHlfbGluZSA9IHRoaXMubWFrZV95X2xpbmUoXG5cdFx0XHRzdGFydF9hdCxcblx0XHRcdHdpZHRoLFxuXHRcdFx0dGV4dF9lbmRfYXQsXG5cdFx0XHR2YWx1ZSxcblx0XHRcdGF4aXNfbGFiZWxfY2xhc3MsXG5cdFx0XHRheGlzX2xpbmVfY2xhc3MsXG5cdFx0XHRvbGRfcG9zLCAgLy8gb2xkIHBvc2l0aW9uXG5cdFx0XHQodmFsdWUgPT09IDAgJiYgaSAhPT0gMCksIC8vIE5vbi1maXJzdCBaZXJvIGxpbmVcblx0XHRcdHR5cGVcblx0XHQpO1xuXG5cdFx0Z3JvdXAuYXBwZW5kQ2hpbGQoeV9saW5lKTtcblxuXHRcdHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZSAmJiB0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUucHVzaChbXG5cdFx0XHR7dW5pdDogeV9saW5lLCBhcnJheTogWzBdLCBpbmRleDogMH0sXG5cdFx0XHR7dHJhbnNmb3JtOiBgMCwgJHsgbmV3X3BvcyB9YH0sXG5cdFx0XHQyNTAsXG5cdFx0XHRcImVhc2VpblwiLFxuXHRcdFx0XCJ0cmFuc2xhdGVcIixcblx0XHRcdHt0cmFuc2Zvcm06IGAwLCAkeyBvbGRfcG9zIH1gfVxuXHRcdF0pO1xuXHR9XG5cblx0Z2V0X3lfYXhpc19wb2ludHMoYXJyYXkpIHtcblx0XHQvLyoqKiBXaGVyZSB0aGUgbWFnaWMgaGFwcGVucyAqKipcblxuXHRcdC8vIENhbGN1bGF0ZXMgYmVzdC1maXQgeSBpbnRlcnZhbHMgZnJvbSBnaXZlbiB2YWx1ZXNcblx0XHQvLyBhbmQgcmV0dXJucyB0aGUgaW50ZXJ2YWwgYXJyYXlcblxuXHRcdC8vIFRPRE86IEZyYWN0aW9uc1xuXG5cdFx0bGV0IG1heF9ib3VuZCwgbWluX2JvdW5kLCBwb3Nfbm9fb2ZfcGFydHMsIG5lZ19ub19vZl9wYXJ0cywgcGFydF9zaXplOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG5cblx0XHQvLyBDcml0aWNhbCB2YWx1ZXNcblx0XHRsZXQgbWF4X3ZhbCA9IHBhcnNlSW50KE1hdGgubWF4KC4uLmFycmF5KSk7XG5cdFx0bGV0IG1pbl92YWwgPSBwYXJzZUludChNYXRoLm1pbiguLi5hcnJheSkpO1xuXHRcdGlmKG1pbl92YWwgPj0gMCkge1xuXHRcdFx0bWluX3ZhbCA9IDA7XG5cdFx0fVxuXG5cdFx0bGV0IGdldF9wYXJhbXMgPSAodmFsdWUxLCB2YWx1ZTIpID0+IHtcblx0XHRcdGxldCBib3VuZDEsIGJvdW5kMiwgbm9fb2ZfcGFydHNfMSwgbm9fb2ZfcGFydHNfMiwgaW50ZXJ2YWxfc2l6ZTtcblx0XHRcdGlmKCh2YWx1ZTErXCJcIikubGVuZ3RoIDw9IDEpIHtcblx0XHRcdFx0W2JvdW5kMSwgbm9fb2ZfcGFydHNfMV0gPSBbMTAsIDVdO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0W2JvdW5kMSwgbm9fb2ZfcGFydHNfMV0gPSB0aGlzLmNhbGNfdXBwZXJfYm91bmRfYW5kX25vX29mX3BhcnRzKHZhbHVlMSk7XG5cdFx0XHR9XG5cblx0XHRcdGludGVydmFsX3NpemUgPSBib3VuZDEgLyBub19vZl9wYXJ0c18xO1xuXHRcdFx0bm9fb2ZfcGFydHNfMiA9IHRoaXMuY2FsY19ub19vZl9wYXJ0cyh2YWx1ZTIsIGludGVydmFsX3NpemUpO1xuXHRcdFx0Ym91bmQyID0gbm9fb2ZfcGFydHNfMiAqIGludGVydmFsX3NpemU7XG5cblx0XHRcdHJldHVybiBbYm91bmQxLCBib3VuZDIsIG5vX29mX3BhcnRzXzEsIG5vX29mX3BhcnRzXzIsIGludGVydmFsX3NpemVdO1xuXHRcdH07XG5cblx0XHRjb25zdCBhYnNfbWluX3ZhbCA9IG1pbl92YWwgKiAtMTtcblx0XHRpZihhYnNfbWluX3ZhbCA8PSBtYXhfdmFsKSB7XG5cdFx0XHQvLyBHZXQgdGhlIHBvc2l0aXZlIHJlZ2lvbiBpbnRlcnZhbHNcblx0XHRcdC8vIHRoZW4gY2FsYyBuZWdhdGl2ZSBvbmVzIGFjY29yZGluZ2x5XG5cdFx0XHRbbWF4X2JvdW5kLCBtaW5fYm91bmQsIHBvc19ub19vZl9wYXJ0cywgbmVnX25vX29mX3BhcnRzLCBwYXJ0X3NpemVdXG5cdFx0XHRcdD0gZ2V0X3BhcmFtcyhtYXhfdmFsLCBhYnNfbWluX3ZhbCk7XG5cdFx0XHRpZihhYnNfbWluX3ZhbCA9PT0gMCkge1xuXHRcdFx0XHRtaW5fYm91bmQgPSAwOyBuZWdfbm9fb2ZfcGFydHMgPSAwO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBHZXQgdGhlIG5lZ2F0aXZlIHJlZ2lvbiBoZXJlIGZpcnN0XG5cdFx0XHRbbWluX2JvdW5kLCBtYXhfYm91bmQsIG5lZ19ub19vZl9wYXJ0cywgcG9zX25vX29mX3BhcnRzLCBwYXJ0X3NpemVdXG5cdFx0XHRcdD0gZ2V0X3BhcmFtcyhhYnNfbWluX3ZhbCwgbWF4X3ZhbCk7XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBib3RoIHJlZ2lvbiBwYXJ0cyBldmVuXG5cdFx0aWYocG9zX25vX29mX3BhcnRzICUgMiAhPT0gMCAmJiBuZWdfbm9fb2ZfcGFydHMgPiAwKSBwb3Nfbm9fb2ZfcGFydHMrKztcblx0XHRpZihuZWdfbm9fb2ZfcGFydHMgJSAyICE9PSAwKSB7XG5cdFx0XHQvLyBldmVyeSBpbmNyZWFzZSBpbiBub19vZl9wYXJ0cyBlbnRhaWxzIGFuIGluY3JlYXNlIGluIGNvcnJlc3BvbmRpbmcgYm91bmRcblx0XHRcdC8vIGV4Y2VwdCBoZXJlLCBpdCBoYXBwZW5zIGltcGxpY2l0bHkgYWZ0ZXIgZXZlcnkgY2FsY19ub19vZl9wYXJ0cygpIGNhbGxcblx0XHRcdG5lZ19ub19vZl9wYXJ0cysrO1xuXHRcdFx0bWluX2JvdW5kICs9IHBhcnRfc2l6ZTtcblx0XHR9XG5cblx0XHRsZXQgbm9fb2ZfcGFydHMgPSBwb3Nfbm9fb2ZfcGFydHMgKyBuZWdfbm9fb2ZfcGFydHM7XG5cdFx0aWYobm9fb2ZfcGFydHMgPiA1KSB7XG5cdFx0XHRub19vZl9wYXJ0cyAvPSAyO1xuXHRcdFx0cGFydF9zaXplICo9IDI7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZ2V0X2ludGVydmFscyhcblx0XHRcdCgtMSkgKiBtaW5fYm91bmQsXG5cdFx0XHRwYXJ0X3NpemUsXG5cdFx0XHRub19vZl9wYXJ0c1xuXHRcdCk7XG5cdH1cblxuXHRnZXRfaW50ZXJ2YWxzKHN0YXJ0LCBpbnRlcnZhbF9zaXplLCBjb3VudCkge1xuXHRcdGxldCBpbnRlcnZhbHMgPSBbXTtcblx0XHRmb3IodmFyIGkgPSAwOyBpIDw9IGNvdW50OyBpKyspe1xuXHRcdFx0aW50ZXJ2YWxzLnB1c2goc3RhcnQpO1xuXHRcdFx0c3RhcnQgKz0gaW50ZXJ2YWxfc2l6ZTtcblx0XHR9XG5cdFx0cmV0dXJuIGludGVydmFscztcblx0fVxuXG5cdGNhbGNfdXBwZXJfYm91bmRfYW5kX25vX29mX3BhcnRzKG1heF92YWwpIHtcblx0XHQvLyBHaXZlbiBhIHBvc2l0aXZlIHZhbHVlLCBjYWxjdWxhdGVzIGEgbmljZS1udW1iZXIgdXBwZXIgYm91bmRcblx0XHQvLyBhbmQgYSBjb25zZXF1ZW50IG9wdGltYWwgbnVtYmVyIG9mIHBhcnRzXG5cblx0XHRjb25zdCBwYXJ0X3NpemUgPSBNYXRoLnBvdygxMCwgKChtYXhfdmFsK1wiXCIpLmxlbmd0aCAtIDEpKTtcblx0XHRjb25zdCBub19vZl9wYXJ0cyA9IHRoaXMuY2FsY19ub19vZl9wYXJ0cyhtYXhfdmFsLCBwYXJ0X3NpemUpO1xuXG5cdFx0Ly8gVXNlIGl0IHRvIGdldCBhIG5pY2UgZXZlbiB1cHBlciBib3VuZFxuXHRcdGNvbnN0IHVwcGVyX2JvdW5kID0gcGFydF9zaXplICogbm9fb2ZfcGFydHM7XG5cblx0XHRyZXR1cm4gW3VwcGVyX2JvdW5kLCBub19vZl9wYXJ0c107XG5cdH1cblxuXHRjYWxjX25vX29mX3BhcnRzKHZhbHVlLCBkaXZpc29yKSB7XG5cdFx0Ly8gdmFsdWUgc2hvdWxkIGJlIGEgcG9zaXRpdmUgbnVtYmVyLCBkaXZpc29yIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gMFxuXHRcdC8vIHJldHVybnMgYW4gZXZlbiBubyBvZiBwYXJ0c1xuXHRcdGxldCBub19vZl9wYXJ0cyA9IE1hdGguY2VpbCh2YWx1ZSAvIGRpdmlzb3IpO1xuXHRcdGlmKG5vX29mX3BhcnRzICUgMiAhPT0gMCkgbm9fb2ZfcGFydHMrKzsgLy8gTWFrZSBpdCBhbiBldmVuIG51bWJlclxuXG5cdFx0cmV0dXJuIG5vX29mX3BhcnRzO1xuXHR9XG5cblx0Z2V0X29wdGltYWxfbm9fb2ZfcGFydHMobm9fb2ZfcGFydHMpIHtcblx0XHQvLyBha2EgRGl2aWRlIGJ5IDIgaWYgdG9vIGxhcmdlXG5cdFx0cmV0dXJuIChub19vZl9wYXJ0cyA8IDUpID8gbm9fb2ZfcGFydHMgOiBub19vZl9wYXJ0cyAvIDI7XG5cdH1cblxuXHRzZXRfYXZnX3VuaXRfd2lkdGhfYW5kX3hfb2Zmc2V0KCkge1xuXHRcdC8vIFNldCB0aGUgLi4uIHlvdSBnZXQgaXRcblx0XHR0aGlzLmF2Z191bml0X3dpZHRoID0gdGhpcy53aWR0aC8odGhpcy54Lmxlbmd0aCAtIDEpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSAwO1xuXHR9XG5cblx0Z2V0X2FsbF95X3ZhbHVlcygpIHtcblx0XHRsZXQgYWxsX3ZhbHVlcyA9IFtdO1xuXG5cdFx0Ly8gQWRkIGluIGFsbCB0aGUgeSB2YWx1ZXMgaW4gdGhlIGRhdGFzZXRzXG5cdFx0dGhpcy55Lm1hcChkID0+IHtcblx0XHRcdGFsbF92YWx1ZXMgPSBhbGxfdmFsdWVzLmNvbmNhdChkLnZhbHVlcyk7XG5cdFx0fSk7XG5cblx0XHQvLyBBZGQgaW4gYWxsIHRoZSBzcGVjaWZpYyB2YWx1ZXNcblx0XHRyZXR1cm4gYWxsX3ZhbHVlcy5jb25jYXQodGhpcy5zcGVjaWZpY192YWx1ZXMubWFwKGQgPT4gZC52YWx1ZSkpO1xuXHR9XG5cblx0Y2FsY195X2RlcGVuZGVuY2llcygpIHtcblx0XHR0aGlzLnlfbWluX3RvcHMgPSBuZXcgQXJyYXkodGhpcy54X2F4aXNfcG9zaXRpb25zLmxlbmd0aCkuZmlsbCg5OTk5KTtcblx0XHR0aGlzLnkubWFwKGQgPT4ge1xuXHRcdFx0ZC55X3RvcHMgPSBkLnZhbHVlcy5tYXAoIHZhbCA9PiBmbG9hdF8yKHRoaXMuemVyb19saW5lIC0gdmFsICogdGhpcy5tdWx0aXBsaWVyKSk7XG5cdFx0XHRkLnlfdG9wcy5tYXAoICh5X3RvcCwgaSkgPT4ge1xuXHRcdFx0XHRpZih5X3RvcCA8IHRoaXMueV9taW5fdG9wc1tpXSkge1xuXHRcdFx0XHRcdHRoaXMueV9taW5fdG9wc1tpXSA9IHlfdG9wO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdGdldF9iYXJfaGVpZ2h0X2FuZF95X2F0dHIoeV90b3ApIHtcblx0XHRsZXQgaGVpZ2h0LCB5O1xuXHRcdGlmICh5X3RvcCA8PSB0aGlzLnplcm9fbGluZSkge1xuXHRcdFx0aGVpZ2h0ID0gdGhpcy56ZXJvX2xpbmUgLSB5X3RvcDtcblx0XHRcdHkgPSB5X3RvcDtcblxuXHRcdFx0Ly8gSW4gY2FzZSBvZiBpbnZpc2libGUgYmFyc1xuXHRcdFx0aWYoaGVpZ2h0ID09PSAwKSB7XG5cdFx0XHRcdGhlaWdodCA9IHRoaXMuaGVpZ2h0ICogMC4wMTtcblx0XHRcdFx0eSAtPSBoZWlnaHQ7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGhlaWdodCA9IHlfdG9wIC0gdGhpcy56ZXJvX2xpbmU7XG5cdFx0XHR5ID0gdGhpcy56ZXJvX2xpbmU7XG5cblx0XHRcdC8vIEluIGNhc2Ugb2YgaW52aXNpYmxlIGJhcnNcblx0XHRcdGlmKGhlaWdodCA9PT0gMCkge1xuXHRcdFx0XHRoZWlnaHQgPSB0aGlzLmhlaWdodCAqIDAuMDE7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtoZWlnaHQsIHldO1xuXHR9XG5cblx0c2V0dXBfdXRpbHMoKSB7XG5cdFx0dGhpcy5kcmF3ID0ge1xuXHRcdFx0J2Jhcic6ICh4LCB5X3RvcCwgYXJncywgY29sb3IsIGluZGV4LCBub19vZl9kYXRhc2V0cykgPT4ge1xuXHRcdFx0XHRsZXQgdG90YWxfd2lkdGggPSB0aGlzLmF2Z191bml0X3dpZHRoIC0gYXJncy5zcGFjZV93aWR0aDtcblx0XHRcdFx0bGV0IHN0YXJ0X3ggPSB4IC0gdG90YWxfd2lkdGgvMjtcblxuXHRcdFx0XHRsZXQgd2lkdGggPSB0b3RhbF93aWR0aCAvIG5vX29mX2RhdGFzZXRzO1xuXHRcdFx0XHRsZXQgY3VycmVudF94ID0gc3RhcnRfeCArIHdpZHRoICogaW5kZXg7XG5cblx0XHRcdFx0bGV0IFtoZWlnaHQsIHldID0gdGhpcy5nZXRfYmFyX2hlaWdodF9hbmRfeV9hdHRyKHlfdG9wKTtcblxuXHRcdFx0XHRyZXR1cm4gJC5jcmVhdGVTVkcoJ3JlY3QnLCB7XG5cdFx0XHRcdFx0Y2xhc3NOYW1lOiBgYmFyIG1pbmkgZmlsbCAke2NvbG9yfWAsXG5cdFx0XHRcdFx0eDogY3VycmVudF94LFxuXHRcdFx0XHRcdHk6IHksXG5cdFx0XHRcdFx0d2lkdGg6IHdpZHRoLFxuXHRcdFx0XHRcdGhlaWdodDogaGVpZ2h0XG5cdFx0XHRcdH0pO1xuXG5cdFx0XHR9LFxuXHRcdFx0J2RvdCc6ICh4LCB5LCBhcmdzLCBjb2xvcikgPT4ge1xuXHRcdFx0XHRyZXR1cm4gJC5jcmVhdGVTVkcoJ2NpcmNsZScsIHtcblx0XHRcdFx0XHRjbGFzc05hbWU6IGBmaWxsICR7Y29sb3J9YCxcblx0XHRcdFx0XHRjeDogeCxcblx0XHRcdFx0XHRjeTogeSxcblx0XHRcdFx0XHRyOiBhcmdzLnJhZGl1c1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhpcy5hbmltYXRlID0ge1xuXHRcdFx0J2Jhcic6IChiYXJfb2JqLCB4LCB5X3RvcCwgaW5kZXgpID0+IHtcblx0XHRcdFx0bGV0IHN0YXJ0ID0geCAtIHRoaXMuYXZnX3VuaXRfd2lkdGgvNDtcblx0XHRcdFx0bGV0IHdpZHRoID0gKHRoaXMuYXZnX3VuaXRfd2lkdGgvMikvdGhpcy55Lmxlbmd0aDtcblx0XHRcdFx0bGV0IFtoZWlnaHQsIHldID0gdGhpcy5nZXRfYmFyX2hlaWdodF9hbmRfeV9hdHRyKHlfdG9wKTtcblxuXHRcdFx0XHR4ID0gc3RhcnQgKyAod2lkdGggKiBpbmRleCk7XG5cblx0XHRcdFx0cmV0dXJuIFtiYXJfb2JqLCB7d2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodCwgeDogeCwgeTogeX0sIDI1MCwgXCJlYXNlaW5cIl07XG5cdFx0XHRcdC8vIGJhci5hbmltYXRlKHtoZWlnaHQ6IGFyZ3MubmV3X2hlaWdodCwgeTogeV90b3B9LCAyNTAsIG1pbmEuZWFzZWluKTtcblx0XHRcdH0sXG5cdFx0XHQnZG90JzogKGRvdF9vYmosIHgsIHlfdG9wKSA9PiB7XG5cdFx0XHRcdHJldHVybiBbZG90X29iaiwge2N4OiB4LCBjeTogeV90b3B9LCAzMDAsIFwiZWFzZWluXCJdO1xuXHRcdFx0XHQvLyBkb3QuYW5pbWF0ZSh7Y3k6IHlfdG9wfSwgMjUwLCBtaW5hLmVhc2Vpbik7XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxufVxuXG5jbGFzcyBCYXJDaGFydCBleHRlbmRzIEF4aXNDaGFydCB7XG5cdGNvbnN0cnVjdG9yKGFyZ3MpIHtcblx0XHRzdXBlcihhcmdzKTtcblxuXHRcdHRoaXMudHlwZSA9ICdiYXInO1xuXHRcdHRoaXMueF9heGlzX21vZGUgPSBhcmdzLnhfYXhpc19tb2RlIHx8ICd0aWNrJztcblx0XHR0aGlzLnlfYXhpc19tb2RlID0gYXJncy55X2F4aXNfbW9kZSB8fCAnc3Bhbic7XG5cdFx0dGhpcy5zZXR1cCgpO1xuXHR9XG5cblx0c2V0dXBfdmFsdWVzKCkge1xuXHRcdHN1cGVyLnNldHVwX3ZhbHVlcygpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSB0aGlzLmF2Z191bml0X3dpZHRoO1xuXHRcdHRoaXMudW5pdF9hcmdzID0ge1xuXHRcdFx0dHlwZTogJ2JhcicsXG5cdFx0XHRhcmdzOiB7XG5cdFx0XHRcdHNwYWNlX3dpZHRoOiB0aGlzLmF2Z191bml0X3dpZHRoLzIsXG5cdFx0XHR9XG5cdFx0fTtcblx0fVxuXG5cdG1ha2Vfb3ZlcmxheSgpIHtcblx0XHQvLyBKdXN0IG1ha2Ugb25lIG91dCBvZiB0aGUgZmlyc3QgZWxlbWVudFxuXHRcdGxldCBpbmRleCA9IHRoaXMueC5sZW5ndGggLSAxO1xuXHRcdGxldCB1bml0ID0gdGhpcy55WzBdLnN2Z191bml0c1tpbmRleF07XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KGluZGV4KTtcblxuXHRcdGlmKHRoaXMub3ZlcmxheSkge1xuXHRcdFx0dGhpcy5vdmVybGF5LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5vdmVybGF5KTtcblx0XHR9XG5cblx0XHR0aGlzLm92ZXJsYXkgPSB1bml0LmNsb25lTm9kZSgpO1xuXHRcdHRoaXMub3ZlcmxheS5zdHlsZS5maWxsID0gJyMwMDAwMDAnO1xuXHRcdHRoaXMub3ZlcmxheS5zdHlsZS5vcGFjaXR5ID0gJzAuNCc7XG5cdFx0dGhpcy5kcmF3X2FyZWEuYXBwZW5kQ2hpbGQodGhpcy5vdmVybGF5KTtcblx0fVxuXG5cdGJpbmRfb3ZlcmxheSgpIHtcblx0XHQvLyBvbiBldmVudCwgdXBkYXRlIG92ZXJsYXlcblx0XHR0aGlzLnBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdkYXRhLXNlbGVjdCcsIChlKSA9PiB7XG5cdFx0XHR0aGlzLnVwZGF0ZV9vdmVybGF5KGUuc3ZnX3VuaXQpO1xuXHRcdH0pO1xuXHR9XG5cblx0dXBkYXRlX292ZXJsYXkodW5pdCkge1xuXHRcdGxldCBhdHRyaWJ1dGVzID0gW107XG5cdFx0T2JqZWN0LmtleXModW5pdC5hdHRyaWJ1dGVzKS5tYXAoaW5kZXggPT4ge1xuXHRcdFx0YXR0cmlidXRlcy5wdXNoKHVuaXQuYXR0cmlidXRlc1tpbmRleF0pO1xuXHRcdH0pO1xuXG5cdFx0YXR0cmlidXRlcy5maWx0ZXIoYXR0ciA9PiBhdHRyLnNwZWNpZmllZCkubWFwKGF0dHIgPT4ge1xuXHRcdFx0dGhpcy5vdmVybGF5LnNldEF0dHJpYnV0ZShhdHRyLm5hbWUsIGF0dHIubm9kZVZhbHVlKTtcblx0XHR9KTtcblx0fVxuXG5cdG9uX2xlZnRfYXJyb3coKSB7XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KHRoaXMuY3VycmVudF9pbmRleCAtIDEpO1xuXHR9XG5cblx0b25fcmlnaHRfYXJyb3coKSB7XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KHRoaXMuY3VycmVudF9pbmRleCArIDEpO1xuXHR9XG5cblx0c2V0X2F2Z191bml0X3dpZHRoX2FuZF94X29mZnNldCgpIHtcblx0XHR0aGlzLmF2Z191bml0X3dpZHRoID0gdGhpcy53aWR0aC8odGhpcy54Lmxlbmd0aCArIDEpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSB0aGlzLmF2Z191bml0X3dpZHRoO1xuXHR9XG59XG5cbmNsYXNzIExpbmVDaGFydCBleHRlbmRzIEF4aXNDaGFydCB7XG5cdGNvbnN0cnVjdG9yKGFyZ3MpIHtcblx0XHRzdXBlcihhcmdzKTtcblx0XHRpZihPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykgIT09IExpbmVDaGFydC5wcm90b3R5cGUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR0aGlzLnR5cGUgPSAnbGluZSc7XG5cdFx0dGhpcy5yZWdpb25fZmlsbCA9IGFyZ3MucmVnaW9uX2ZpbGw7XG5cdFx0dGhpcy54X2F4aXNfbW9kZSA9IGFyZ3MueF9heGlzX21vZGUgfHwgJ3NwYW4nO1xuXHRcdHRoaXMueV9heGlzX21vZGUgPSBhcmdzLnlfYXhpc19tb2RlIHx8ICdzcGFuJztcblxuXHRcdHRoaXMuc2V0dXAoKTtcblx0fVxuXG5cdHNldHVwX2dyYXBoX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5zZXR1cF9wYXRoX2dyb3VwcygpO1xuXHRcdHN1cGVyLnNldHVwX2dyYXBoX2NvbXBvbmVudHMoKTtcblx0fVxuXG5cdHNldHVwX3BhdGhfZ3JvdXBzKCkge1xuXHRcdHRoaXMucGF0aHNfZ3JvdXBzID0gW107XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0dGhpcy5wYXRoc19ncm91cHNbaV0gPSAkLmNyZWF0ZVNWRygnZycsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAncGF0aC1ncm91cCBwYXRoLWdyb3VwLScgKyBpLFxuXHRcdFx0XHRpbnNpZGU6IHRoaXMuZHJhd19hcmVhXG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdHNldHVwX3ZhbHVlcygpIHtcblx0XHRzdXBlci5zZXR1cF92YWx1ZXMoKTtcblx0XHR0aGlzLnVuaXRfYXJncyA9IHtcblx0XHRcdHR5cGU6ICdkb3QnLFxuXHRcdFx0YXJnczogeyByYWRpdXM6IDggfVxuXHRcdH07XG5cdH1cblxuXHRtYWtlX3BhdGhzKCkge1xuXHRcdHRoaXMueS5tYXAoKGQsIGkpID0+IHtcblx0XHRcdHRoaXMubWFrZV9wYXRoKGQsIGksIHRoaXMueF9heGlzX3Bvc2l0aW9ucywgZC55X3RvcHMsIGQuY29sb3IgfHwgdGhpcy5jb2xvcnNbaV0pO1xuXHRcdH0pO1xuXHR9XG5cblx0bWFrZV9wYXRoKGQsIGksIHhfcG9zaXRpb25zLCB5X3Bvc2l0aW9ucywgY29sb3IpIHtcblx0XHRsZXQgcG9pbnRzX2xpc3QgPSB5X3Bvc2l0aW9ucy5tYXAoKHksIGkpID0+ICh4X3Bvc2l0aW9uc1tpXSArICcsJyArIHkpKTtcblx0XHRsZXQgcG9pbnRzX3N0ciA9IHBvaW50c19saXN0LmpvaW4oXCJMXCIpO1xuXG5cdFx0dGhpcy5wYXRoc19ncm91cHNbaV0udGV4dENvbnRlbnQgPSAnJztcblxuXHRcdGQucGF0aCA9ICQuY3JlYXRlU1ZHKCdwYXRoJywge1xuXHRcdFx0aW5zaWRlOiB0aGlzLnBhdGhzX2dyb3Vwc1tpXSxcblx0XHRcdGNsYXNzTmFtZTogYHN0cm9rZSAke2NvbG9yfWAsXG5cdFx0XHRkOiBcIk1cIitwb2ludHNfc3RyXG5cdFx0fSk7XG5cblx0XHRpZih0aGlzLnJlZ2lvbl9maWxsKSB7XG5cdFx0XHRsZXQgZ3JhZGllbnRfaWQgPSdwYXRoLWZpbGwtZ3JhZGllbnQnICsgJy0nICsgY29sb3I7XG5cblx0XHRcdHRoaXMuZ3JhZGllbnRfZGVmID0gJC5jcmVhdGVTVkcoJ2xpbmVhckdyYWRpZW50Jywge1xuXHRcdFx0XHRpbnNpZGU6IHRoaXMuc3ZnX2RlZnMsXG5cdFx0XHRcdGlkOiBncmFkaWVudF9pZCxcblx0XHRcdFx0eDE6IDAsXG5cdFx0XHRcdHgyOiAwLFxuXHRcdFx0XHR5MTogMCxcblx0XHRcdFx0eTI6IDFcblx0XHRcdH0pO1xuXG5cdFx0XHRsZXQgc2V0X2dyYWRpZW50X3N0b3AgPSAoZ3JhZF9lbGVtLCBvZmZzZXQsIGNvbG9yLCBvcGFjaXR5KSA9PiB7XG5cdFx0XHRcdCQuY3JlYXRlU1ZHKCdzdG9wJywge1xuXHRcdFx0XHRcdCdjbGFzc05hbWUnOiAnc3RvcC1jb2xvciAnICsgY29sb3IsXG5cdFx0XHRcdFx0J2luc2lkZSc6IGdyYWRfZWxlbSxcblx0XHRcdFx0XHQnb2Zmc2V0Jzogb2Zmc2V0LFxuXHRcdFx0XHRcdCdzdG9wLW9wYWNpdHknOiBvcGFjaXR5XG5cdFx0XHRcdH0pO1xuXHRcdFx0fTtcblxuXHRcdFx0c2V0X2dyYWRpZW50X3N0b3AodGhpcy5ncmFkaWVudF9kZWYsIFwiMCVcIiwgY29sb3IsIDAuNCk7XG5cdFx0XHRzZXRfZ3JhZGllbnRfc3RvcCh0aGlzLmdyYWRpZW50X2RlZiwgXCI1MCVcIiwgY29sb3IsIDAuMik7XG5cdFx0XHRzZXRfZ3JhZGllbnRfc3RvcCh0aGlzLmdyYWRpZW50X2RlZiwgXCIxMDAlXCIsIGNvbG9yLCAwKTtcblxuXHRcdFx0ZC5yZWdpb25fcGF0aCA9ICQuY3JlYXRlU1ZHKCdwYXRoJywge1xuXHRcdFx0XHRpbnNpZGU6IHRoaXMucGF0aHNfZ3JvdXBzW2ldLFxuXHRcdFx0XHRjbGFzc05hbWU6IGByZWdpb24tZmlsbGAsXG5cdFx0XHRcdGQ6IFwiTVwiICsgYDAsJHt0aGlzLnplcm9fbGluZX1MYCArIHBvaW50c19zdHIgKyBgTCR7dGhpcy53aWR0aH0sJHt0aGlzLnplcm9fbGluZX1gLFxuXHRcdFx0fSk7XG5cblx0XHRcdGQucmVnaW9uX3BhdGguc3R5bGUuc3Ryb2tlID0gXCJub25lXCI7XG5cdFx0XHRkLnJlZ2lvbl9wYXRoLnN0eWxlLmZpbGwgPSBgdXJsKCMke2dyYWRpZW50X2lkfSlgO1xuXHRcdH1cblx0fVxufVxuXG5jbGFzcyBQZXJjZW50YWdlQ2hhcnQgZXh0ZW5kcyBDaGFydCB7XG5cdGNvbnN0cnVjdG9yKGFyZ3MpIHtcblx0XHRzdXBlcihhcmdzKTtcblx0XHR0aGlzLnR5cGUgPSAncGVyY2VudGFnZSc7XG5cblx0XHR0aGlzLmdldF95X2xhYmVsID0gdGhpcy5mb3JtYXRfbGFtYmRhcy55X2xhYmVsO1xuXHRcdHRoaXMuZ2V0X3hfdG9vbHRpcCA9IHRoaXMuZm9ybWF0X2xhbWJkYXMueF90b29sdGlwO1xuXHRcdHRoaXMuZ2V0X3lfdG9vbHRpcCA9IHRoaXMuZm9ybWF0X2xhbWJkYXMueV90b29sdGlwO1xuXG5cdFx0dGhpcy5tYXhfc2xpY2VzID0gMTA7XG5cdFx0dGhpcy5tYXhfbGVnZW5kX3BvaW50cyA9IDY7XG5cblx0XHR0aGlzLmNvbG9ycyA9IGFyZ3MuY29sb3JzO1xuXG5cdFx0aWYoIXRoaXMuY29sb3JzIHx8IHRoaXMuY29sb3JzLmxlbmd0aCA8IHRoaXMuZGF0YS5sYWJlbHMubGVuZ3RoKSB7XG5cdFx0XHR0aGlzLmNvbG9ycyA9IFsnbGlnaHQtYmx1ZScsICdibHVlJywgJ3Zpb2xldCcsICdyZWQnLCAnb3JhbmdlJyxcblx0XHRcdFx0J3llbGxvdycsICdncmVlbicsICdsaWdodC1ncmVlbicsICdwdXJwbGUnLCAnbWFnZW50YSddO1xuXHRcdH1cblxuXHRcdHRoaXMuc2V0dXAoKTtcblx0fVxuXG5cdG1ha2VfY2hhcnRfYXJlYSgpIHtcblx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIuY2xhc3NOYW1lICs9ICcgJyArICdncmFwaC1mb2N1cy1tYXJnaW4nO1xuXHRcdHRoaXMuY2hhcnRfd3JhcHBlci5zdHlsZS5tYXJnaW5Ub3AgPSAnNDVweCc7XG5cblx0XHR0aGlzLnN0YXRzX3dyYXBwZXIuY2xhc3NOYW1lICs9ICcgJyArICdncmFwaC1mb2N1cy1tYXJnaW4nO1xuXHRcdHRoaXMuc3RhdHNfd3JhcHBlci5zdHlsZS5tYXJnaW5Cb3R0b20gPSAnMzBweCc7XG5cdFx0dGhpcy5zdGF0c193cmFwcGVyLnN0eWxlLnBhZGRpbmdUb3AgPSAnMHB4Jztcblx0fVxuXG5cdG1ha2VfZHJhd19hcmVhKCkge1xuXHRcdHRoaXMuY2hhcnRfZGl2ID0gJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdGNsYXNzTmFtZTogJ2RpdicsXG5cdFx0XHRpbnNpZGU6IHRoaXMuY2hhcnRfd3JhcHBlcixcblx0XHRcdHdpZHRoOiB0aGlzLmJhc2Vfd2lkdGgsXG5cdFx0XHRoZWlnaHQ6IHRoaXMuYmFzZV9oZWlnaHRcblx0XHR9KTtcblxuXHRcdHRoaXMuY2hhcnQgPSAkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0Y2xhc3NOYW1lOiAncHJvZ3Jlc3MtY2hhcnQnLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmNoYXJ0X2RpdlxuXHRcdH0pO1xuXHR9XG5cblx0c2V0dXBfY29tcG9uZW50cygpIHtcblx0XHR0aGlzLnBlcmNlbnRhZ2VfYmFyID0gJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdGNsYXNzTmFtZTogJ3Byb2dyZXNzJyxcblx0XHRcdGluc2lkZTogdGhpcy5jaGFydFxuXHRcdH0pO1xuXHR9XG5cblx0c2V0dXBfdmFsdWVzKCkge1xuXHRcdHRoaXMuc2xpY2VfdG90YWxzID0gW107XG5cdFx0bGV0IGFsbF90b3RhbHMgPSB0aGlzLmRhdGEubGFiZWxzLm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0bGV0IHRvdGFsID0gMDtcblx0XHRcdHRoaXMuZGF0YS5kYXRhc2V0cy5tYXAoZSA9PiB7XG5cdFx0XHRcdHRvdGFsICs9IGUudmFsdWVzW2ldO1xuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gW3RvdGFsLCBkXTtcblx0XHR9KS5maWx0ZXIoZCA9PiB7IHJldHVybiBkWzBdID4gMDsgfSk7IC8vIGtlZXAgb25seSBwb3NpdGl2ZSByZXN1bHRzXG5cblx0XHRsZXQgdG90YWxzID0gYWxsX3RvdGFscztcblxuXHRcdGlmKGFsbF90b3RhbHMubGVuZ3RoID4gdGhpcy5tYXhfc2xpY2VzKSB7XG5cdFx0XHRhbGxfdG90YWxzLnNvcnQoKGEsIGIpID0+IHsgcmV0dXJuIGJbMF0gLSBhWzBdOyB9KTtcblxuXHRcdFx0dG90YWxzID0gYWxsX3RvdGFscy5zbGljZSgwLCB0aGlzLm1heF9zbGljZXMtMSk7XG5cdFx0XHRsZXQgb3RoZXJzID0gYWxsX3RvdGFscy5zbGljZSh0aGlzLm1heF9zbGljZXMtMSk7XG5cblx0XHRcdGxldCBzdW1fb2Zfb3RoZXJzID0gMDtcblx0XHRcdG90aGVycy5tYXAoZCA9PiB7c3VtX29mX290aGVycyArPSBkWzBdO30pO1xuXG5cdFx0XHR0b3RhbHMucHVzaChbc3VtX29mX290aGVycywgJ1Jlc3QnXSk7XG5cblx0XHRcdHRoaXMuY29sb3JzW3RoaXMubWF4X3NsaWNlcy0xXSA9ICdncmV5Jztcblx0XHR9XG5cblx0XHR0aGlzLmxhYmVscyA9IFtdO1xuXHRcdHRvdGFscy5tYXAoZCA9PiB7XG5cdFx0XHR0aGlzLnNsaWNlX3RvdGFscy5wdXNoKGRbMF0pO1xuXHRcdFx0dGhpcy5sYWJlbHMucHVzaChkWzFdKTtcblx0XHR9KTtcblxuXHRcdHRoaXMubGVnZW5kX3RvdGFscyA9IHRoaXMuc2xpY2VfdG90YWxzLnNsaWNlKDAsIHRoaXMubWF4X2xlZ2VuZF9wb2ludHMpO1xuXHR9XG5cblx0c2V0dXBfdXRpbHMoKSB7IH1cblxuXHRtYWtlX2dyYXBoX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5ncmFuZF90b3RhbCA9IHRoaXMuc2xpY2VfdG90YWxzLnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApO1xuXHRcdHRoaXMuc2xpY2VzID0gW107XG5cdFx0dGhpcy5zbGljZV90b3RhbHMubWFwKCh0b3RhbCwgaSkgPT4ge1xuXHRcdFx0bGV0IHNsaWNlID0gJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiBgcHJvZ3Jlc3MtYmFyIGJhY2tncm91bmQgJHt0aGlzLmNvbG9yc1tpXX1gLFxuXHRcdFx0XHRzdHlsZTogYHdpZHRoOiAke3RvdGFsKjEwMC90aGlzLmdyYW5kX3RvdGFsfSVgLFxuXHRcdFx0XHRpbnNpZGU6IHRoaXMucGVyY2VudGFnZV9iYXJcblx0XHRcdH0pO1xuXHRcdFx0dGhpcy5zbGljZXMucHVzaChzbGljZSk7XG5cdFx0fSk7XG5cdH1cblxuXHRiaW5kX3Rvb2x0aXAoKSB7XG5cdFx0dGhpcy5zbGljZXMubWFwKChzbGljZSwgaSkgPT4ge1xuXHRcdFx0c2xpY2UuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsICgpID0+IHtcblx0XHRcdFx0bGV0IGdfb2ZmID0gJC5vZmZzZXQodGhpcy5jaGFydF93cmFwcGVyKSwgcF9vZmYgPSAkLm9mZnNldChzbGljZSk7XG5cblx0XHRcdFx0bGV0IHggPSBwX29mZi5sZWZ0IC0gZ19vZmYubGVmdCArIHNsaWNlLm9mZnNldFdpZHRoLzI7XG5cdFx0XHRcdGxldCB5ID0gcF9vZmYudG9wIC0gZ19vZmYudG9wIC0gNjtcblx0XHRcdFx0bGV0IHRpdGxlID0gKHRoaXMuZm9ybWF0dGVkX2xhYmVscyAmJiB0aGlzLmZvcm1hdHRlZF9sYWJlbHMubGVuZ3RoPjBcblx0XHRcdFx0XHQ/IHRoaXMuZm9ybWF0dGVkX2xhYmVsc1tpXSA6IHRoaXMubGFiZWxzW2ldKSArICc6ICc7XG5cdFx0XHRcdGxldCBwZXJjZW50ID0gKHRoaXMuc2xpY2VfdG90YWxzW2ldKjEwMC90aGlzLmdyYW5kX3RvdGFsKS50b0ZpeGVkKDEpO1xuXG5cdFx0XHRcdHRoaXMudGlwLnNldF92YWx1ZXMoeCwgeSwgdGl0bGUsIHBlcmNlbnQgKyBcIiVcIik7XG5cdFx0XHRcdHRoaXMudGlwLnNob3dfdGlwKCk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdHNob3dfc3VtbWFyeSgpIHtcblx0XHRsZXQgeF92YWx1ZXMgPSB0aGlzLmZvcm1hdHRlZF9sYWJlbHMgJiYgdGhpcy5mb3JtYXR0ZWRfbGFiZWxzLmxlbmd0aCA+IDBcblx0XHRcdD8gdGhpcy5mb3JtYXR0ZWRfbGFiZWxzIDogdGhpcy5sYWJlbHM7XG5cdFx0dGhpcy5sZWdlbmRfdG90YWxzLm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0aWYoZCkge1xuXHRcdFx0XHRsZXQgc3RhdHMgPSAkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0XHRcdGNsYXNzTmFtZTogJ3N0YXRzJyxcblx0XHRcdFx0XHRpbnNpZGU6IHRoaXMuc3RhdHNfd3JhcHBlclxuXHRcdFx0XHR9KTtcblx0XHRcdFx0c3RhdHMuaW5uZXJIVE1MID0gYDxzcGFuIGNsYXNzPVwiaW5kaWNhdG9yICR7dGhpcy5jb2xvcnNbaV19XCI+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJ0ZXh0LW11dGVkXCI+JHt4X3ZhbHVlc1tpXX06PC9zcGFuPlxuXHRcdFx0XHRcdCR7ZH1cblx0XHRcdFx0PC9zcGFuPmA7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn1cblxuY2xhc3MgSGVhdE1hcCBleHRlbmRzIENoYXJ0IHtcblx0Y29uc3RydWN0b3Ioe1xuXHRcdHN0YXJ0ID0gJycsXG5cdFx0ZG9tYWluID0gJycsXG5cdFx0c3ViZG9tYWluID0gJycsXG5cdFx0ZGF0YSA9IHt9LFxuXHRcdGRpc2NyZXRlX2RvbWFpbnMgPSAwLFxuXHRcdGNvdW50X2xhYmVsID0gJydcblx0fSkge1xuXHRcdHN1cGVyKGFyZ3VtZW50c1swXSk7XG5cblx0XHR0aGlzLnR5cGUgPSAnaGVhdG1hcCc7XG5cblx0XHR0aGlzLmRvbWFpbiA9IGRvbWFpbjtcblx0XHR0aGlzLnN1YmRvbWFpbiA9IHN1YmRvbWFpbjtcblx0XHR0aGlzLmRhdGEgPSBkYXRhO1xuXHRcdHRoaXMuZGlzY3JldGVfZG9tYWlucyA9IGRpc2NyZXRlX2RvbWFpbnM7XG5cdFx0dGhpcy5jb3VudF9sYWJlbCA9IGNvdW50X2xhYmVsO1xuXG5cdFx0bGV0IHRvZGF5ID0gbmV3IERhdGUoKTtcblx0XHR0aGlzLnN0YXJ0ID0gc3RhcnQgfHwgdGhpcy5hZGRfZGF5cyh0b2RheSwgMzY1KTtcblxuXHRcdHRoaXMubGVnZW5kX2NvbG9ycyA9IFsnI2ViZWRmMCcsICcjYzZlNDhiJywgJyM3YmM5NmYnLCAnIzIzOWEzYicsICcjMTk2MTI3J107XG5cblx0XHR0aGlzLnRyYW5zbGF0ZV94ID0gMDtcblx0XHR0aGlzLnNldHVwKCk7XG5cdH1cblxuXHRzZXR1cF9iYXNlX3ZhbHVlcygpIHtcblx0XHR0aGlzLnRvZGF5ID0gbmV3IERhdGUoKTtcblxuXHRcdGlmKCF0aGlzLnN0YXJ0KSB7XG5cdFx0XHR0aGlzLnN0YXJ0ID0gbmV3IERhdGUoKTtcblx0XHRcdHRoaXMuc3RhcnQuc2V0RnVsbFllYXIoIHRoaXMuc3RhcnQuZ2V0RnVsbFllYXIoKSAtIDEgKTtcblx0XHR9XG5cdFx0dGhpcy5maXJzdF93ZWVrX3N0YXJ0ID0gbmV3IERhdGUodGhpcy5zdGFydC50b0RhdGVTdHJpbmcoKSk7XG5cdFx0dGhpcy5sYXN0X3dlZWtfc3RhcnQgPSBuZXcgRGF0ZSh0aGlzLnRvZGF5LnRvRGF0ZVN0cmluZygpKTtcblx0XHRpZih0aGlzLmZpcnN0X3dlZWtfc3RhcnQuZ2V0RGF5KCkgIT09IDcpIHtcblx0XHRcdHRoaXMuYWRkX2RheXModGhpcy5maXJzdF93ZWVrX3N0YXJ0LCAoLTEpICogdGhpcy5maXJzdF93ZWVrX3N0YXJ0LmdldERheSgpKTtcblx0XHR9XG5cdFx0aWYodGhpcy5sYXN0X3dlZWtfc3RhcnQuZ2V0RGF5KCkgIT09IDcpIHtcblx0XHRcdHRoaXMuYWRkX2RheXModGhpcy5sYXN0X3dlZWtfc3RhcnQsICgtMSkgKiB0aGlzLmxhc3Rfd2Vla19zdGFydC5nZXREYXkoKSk7XG5cdFx0fVxuXHRcdHRoaXMubm9fb2ZfY29scyA9IHRoaXMuZ2V0X3dlZWtzX2JldHdlZW4odGhpcy5maXJzdF93ZWVrX3N0YXJ0ICsgJycsIHRoaXMubGFzdF93ZWVrX3N0YXJ0ICsgJycpICsgMTtcblx0fVxuXG5cdHNldF93aWR0aCgpIHtcblx0XHR0aGlzLmJhc2Vfd2lkdGggPSAodGhpcy5ub19vZl9jb2xzKSAqIDEyO1xuXG5cdFx0aWYodGhpcy5kaXNjcmV0ZV9kb21haW5zKSB7XG5cdFx0XHR0aGlzLmJhc2Vfd2lkdGggKz0gKDEyICogMTIpO1xuXHRcdH1cblx0fVxuXG5cdHNldHVwX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5kb21haW5fbGFiZWxfZ3JvdXAgPSAkLmNyZWF0ZVNWRyhcImdcIiwge1xuXHRcdFx0Y2xhc3NOYW1lOiBcImRvbWFpbi1sYWJlbC1ncm91cCBjaGFydC1sYWJlbFwiLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmRyYXdfYXJlYVxuXHRcdH0pO1xuXHRcdHRoaXMuZGF0YV9ncm91cHMgPSAkLmNyZWF0ZVNWRyhcImdcIiwge1xuXHRcdFx0Y2xhc3NOYW1lOiBcImRhdGEtZ3JvdXBzXCIsXG5cdFx0XHRpbnNpZGU6IHRoaXMuZHJhd19hcmVhLFxuXHRcdFx0dHJhbnNmb3JtOiBgdHJhbnNsYXRlKDAsIDIwKWBcblx0XHR9KTtcblx0fVxuXG5cdHNldHVwX3ZhbHVlcygpIHtcblx0XHR0aGlzLmRvbWFpbl9sYWJlbF9ncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdHRoaXMuZGF0YV9ncm91cHMudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLmRpc3RyaWJ1dGlvbiA9IHRoaXMuZ2V0X2Rpc3RyaWJ1dGlvbih0aGlzLmRhdGEsIHRoaXMubGVnZW5kX2NvbG9ycyk7XG5cdFx0dGhpcy5tb250aF9uYW1lcyA9IFtcIkphbnVhcnlcIiwgXCJGZWJydWFyeVwiLCBcIk1hcmNoXCIsIFwiQXByaWxcIiwgXCJNYXlcIiwgXCJKdW5lXCIsXG5cdFx0XHRcIkp1bHlcIiwgXCJBdWd1c3RcIiwgXCJTZXB0ZW1iZXJcIiwgXCJPY3RvYmVyXCIsIFwiTm92ZW1iZXJcIiwgXCJEZWNlbWJlclwiXG5cdFx0XTtcblxuXHRcdHRoaXMucmVuZGVyX2FsbF93ZWVrc19hbmRfc3RvcmVfeF92YWx1ZXModGhpcy5ub19vZl9jb2xzKTtcblx0fVxuXG5cdHJlbmRlcl9hbGxfd2Vla3NfYW5kX3N0b3JlX3hfdmFsdWVzKG5vX29mX3dlZWtzKSB7XG5cdFx0bGV0IGN1cnJlbnRfd2Vla19zdW5kYXkgPSBuZXcgRGF0ZSh0aGlzLmZpcnN0X3dlZWtfc3RhcnQpO1xuXHRcdHRoaXMud2Vla19jb2wgPSAwO1xuXHRcdHRoaXMuY3VycmVudF9tb250aCA9IGN1cnJlbnRfd2Vla19zdW5kYXkuZ2V0TW9udGgoKTtcblxuXHRcdHRoaXMubW9udGhzID0gW3RoaXMuY3VycmVudF9tb250aCArICcnXTtcblx0XHR0aGlzLm1vbnRoX3dlZWtzID0ge30sIHRoaXMubW9udGhfc3RhcnRfcG9pbnRzID0gW107XG5cdFx0dGhpcy5tb250aF93ZWVrc1t0aGlzLmN1cnJlbnRfbW9udGhdID0gMDtcblx0XHR0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cy5wdXNoKDEzKTtcblxuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCBub19vZl93ZWVrczsgaSsrKSB7XG5cdFx0XHRsZXQgZGF0YV9ncm91cCwgbW9udGhfY2hhbmdlID0gMDtcblx0XHRcdGxldCBkYXkgPSBuZXcgRGF0ZShjdXJyZW50X3dlZWtfc3VuZGF5KTtcblxuXHRcdFx0W2RhdGFfZ3JvdXAsIG1vbnRoX2NoYW5nZV0gPSB0aGlzLmdldF93ZWVrX3NxdWFyZXNfZ3JvdXAoZGF5LCB0aGlzLndlZWtfY29sKTtcblx0XHRcdHRoaXMuZGF0YV9ncm91cHMuYXBwZW5kQ2hpbGQoZGF0YV9ncm91cCk7XG5cdFx0XHR0aGlzLndlZWtfY29sICs9IDEgKyBwYXJzZUludCh0aGlzLmRpc2NyZXRlX2RvbWFpbnMgJiYgbW9udGhfY2hhbmdlKTtcblx0XHRcdHRoaXMubW9udGhfd2Vla3NbdGhpcy5jdXJyZW50X21vbnRoXSsrO1xuXHRcdFx0aWYobW9udGhfY2hhbmdlKSB7XG5cdFx0XHRcdHRoaXMuY3VycmVudF9tb250aCA9ICh0aGlzLmN1cnJlbnRfbW9udGggKyAxKSAlIDEyO1xuXHRcdFx0XHR0aGlzLm1vbnRocy5wdXNoKHRoaXMuY3VycmVudF9tb250aCArICcnKTtcblx0XHRcdFx0dGhpcy5tb250aF93ZWVrc1t0aGlzLmN1cnJlbnRfbW9udGhdID0gMTtcblx0XHRcdH1cblx0XHRcdHRoaXMuYWRkX2RheXMoY3VycmVudF93ZWVrX3N1bmRheSwgNyk7XG5cdFx0fVxuXHRcdHRoaXMucmVuZGVyX21vbnRoX2xhYmVscygpO1xuXHR9XG5cblx0Z2V0X3dlZWtfc3F1YXJlc19ncm91cChjdXJyZW50X2RhdGUsIGluZGV4KSB7XG5cdFx0Y29uc3Qgbm9fb2Zfd2Vla2RheXMgPSA3O1xuXHRcdGNvbnN0IHNxdWFyZV9zaWRlID0gMTA7XG5cdFx0Y29uc3QgY2VsbF9wYWRkaW5nID0gMjtcblx0XHRjb25zdCBzdGVwID0gMTtcblxuXHRcdGxldCBtb250aF9jaGFuZ2UgPSAwO1xuXHRcdGxldCB3ZWVrX2NvbF9jaGFuZ2UgPSAwO1xuXG5cdFx0bGV0IGRhdGFfZ3JvdXAgPSAkLmNyZWF0ZVNWRyhcImdcIiwge1xuXHRcdFx0Y2xhc3NOYW1lOiBcImRhdGEtZ3JvdXBcIixcblx0XHRcdGluc2lkZTogdGhpcy5kYXRhX2dyb3Vwc1xuXHRcdH0pO1xuXG5cdFx0Zm9yKHZhciB5ID0gMCwgaSA9IDA7IGkgPCBub19vZl93ZWVrZGF5czsgaSArPSBzdGVwLCB5ICs9IChzcXVhcmVfc2lkZSArIGNlbGxfcGFkZGluZykpIHtcblx0XHRcdGxldCBkYXRhX3ZhbHVlID0gMDtcblx0XHRcdGxldCBjb2xvcl9pbmRleCA9IDA7XG5cblx0XHRcdGxldCB0aW1lc3RhbXAgPSBNYXRoLmZsb29yKGN1cnJlbnRfZGF0ZS5nZXRUaW1lKCkvMTAwMCkudG9GaXhlZCgxKTtcblxuXHRcdFx0aWYodGhpcy5kYXRhW3RpbWVzdGFtcF0pIHtcblx0XHRcdFx0ZGF0YV92YWx1ZSA9IHRoaXMuZGF0YVt0aW1lc3RhbXBdO1xuXHRcdFx0XHRjb2xvcl9pbmRleCA9IHRoaXMuZ2V0X21heF9jaGVja3BvaW50KGRhdGFfdmFsdWUsIHRoaXMuZGlzdHJpYnV0aW9uKTtcblx0XHRcdH1cblxuXHRcdFx0aWYodGhpcy5kYXRhW01hdGgucm91bmQodGltZXN0YW1wKV0pIHtcblx0XHRcdFx0ZGF0YV92YWx1ZSA9IHRoaXMuZGF0YVtNYXRoLnJvdW5kKHRpbWVzdGFtcCldO1xuXHRcdFx0XHRjb2xvcl9pbmRleCA9IHRoaXMuZ2V0X21heF9jaGVja3BvaW50KGRhdGFfdmFsdWUsIHRoaXMuZGlzdHJpYnV0aW9uKTtcblx0XHRcdH1cblxuXHRcdFx0bGV0IHggPSAxMyArIChpbmRleCArIHdlZWtfY29sX2NoYW5nZSkgKiAxMjtcblxuXHRcdFx0JC5jcmVhdGVTVkcoXCJyZWN0XCIsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAnZGF5Jyxcblx0XHRcdFx0aW5zaWRlOiBkYXRhX2dyb3VwLFxuXHRcdFx0XHR4OiB4LFxuXHRcdFx0XHR5OiB5LFxuXHRcdFx0XHR3aWR0aDogc3F1YXJlX3NpZGUsXG5cdFx0XHRcdGhlaWdodDogc3F1YXJlX3NpZGUsXG5cdFx0XHRcdGZpbGw6ICB0aGlzLmxlZ2VuZF9jb2xvcnNbY29sb3JfaW5kZXhdLFxuXHRcdFx0XHQnZGF0YS1kYXRlJzogdGhpcy5nZXRfZGRfbW1feXl5eShjdXJyZW50X2RhdGUpLFxuXHRcdFx0XHQnZGF0YS12YWx1ZSc6IGRhdGFfdmFsdWUsXG5cdFx0XHRcdCdkYXRhLWRheSc6IGN1cnJlbnRfZGF0ZS5nZXREYXkoKVxuXHRcdFx0fSk7XG5cblx0XHRcdGxldCBuZXh0X2RhdGUgPSBuZXcgRGF0ZShjdXJyZW50X2RhdGUpO1xuXHRcdFx0dGhpcy5hZGRfZGF5cyhuZXh0X2RhdGUsIDEpO1xuXHRcdFx0aWYobmV4dF9kYXRlLmdldE1vbnRoKCkgLSBjdXJyZW50X2RhdGUuZ2V0TW9udGgoKSkge1xuXHRcdFx0XHRtb250aF9jaGFuZ2UgPSAxO1xuXHRcdFx0XHRpZih0aGlzLmRpc2NyZXRlX2RvbWFpbnMpIHtcblx0XHRcdFx0XHR3ZWVrX2NvbF9jaGFuZ2UgPSAxO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5tb250aF9zdGFydF9wb2ludHMucHVzaCgxMyArIChpbmRleCArIHdlZWtfY29sX2NoYW5nZSkgKiAxMik7XG5cdFx0XHR9XG5cdFx0XHRjdXJyZW50X2RhdGUgPSBuZXh0X2RhdGU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtkYXRhX2dyb3VwLCBtb250aF9jaGFuZ2VdO1xuXHR9XG5cblx0cmVuZGVyX21vbnRoX2xhYmVscygpIHtcblx0XHQvLyB0aGlzLmZpcnN0X21vbnRoX2xhYmVsID0gMTtcblx0XHQvLyBpZiAodGhpcy5maXJzdF93ZWVrX3N0YXJ0LmdldERhdGUoKSA+IDgpIHtcblx0XHQvLyBcdHRoaXMuZmlyc3RfbW9udGhfbGFiZWwgPSAwO1xuXHRcdC8vIH1cblx0XHQvLyB0aGlzLmxhc3RfbW9udGhfbGFiZWwgPSAxO1xuXG5cdFx0Ly8gbGV0IGZpcnN0X21vbnRoID0gdGhpcy5tb250aHMuc2hpZnQoKTtcblx0XHQvLyBsZXQgZmlyc3RfbW9udGhfc3RhcnQgPSB0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cy5zaGlmdCgpO1xuXHRcdC8vIHJlbmRlciBmaXJzdCBtb250aCBpZlxuXG5cdFx0Ly8gbGV0IGxhc3RfbW9udGggPSB0aGlzLm1vbnRocy5wb3AoKTtcblx0XHQvLyBsZXQgbGFzdF9tb250aF9zdGFydCA9IHRoaXMubW9udGhfc3RhcnRfcG9pbnRzLnBvcCgpO1xuXHRcdC8vIHJlbmRlciBsYXN0IG1vbnRoIGlmXG5cblx0XHR0aGlzLm1vbnRocy5zaGlmdCgpO1xuXHRcdHRoaXMubW9udGhfc3RhcnRfcG9pbnRzLnNoaWZ0KCk7XG5cdFx0dGhpcy5tb250aHMucG9wKCk7XG5cdFx0dGhpcy5tb250aF9zdGFydF9wb2ludHMucG9wKCk7XG5cblx0XHR0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cy5tYXAoKHN0YXJ0LCBpKSA9PiB7XG5cdFx0XHRsZXQgbW9udGhfbmFtZSA9ICB0aGlzLm1vbnRoX25hbWVzW3RoaXMubW9udGhzW2ldXS5zdWJzdHJpbmcoMCwgMyk7XG5cblx0XHRcdCQuY3JlYXRlU1ZHKCd0ZXh0Jywge1xuXHRcdFx0XHRjbGFzc05hbWU6ICd5LXZhbHVlLXRleHQnLFxuXHRcdFx0XHRpbnNpZGU6IHRoaXMuZG9tYWluX2xhYmVsX2dyb3VwLFxuXHRcdFx0XHR4OiBzdGFydCArIDEyLFxuXHRcdFx0XHR5OiAxMCxcblx0XHRcdFx0ZHk6ICcuMzJlbScsXG5cdFx0XHRcdGlubmVySFRNTDogbW9udGhfbmFtZVxuXHRcdFx0fSk7XG5cblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfZ3JhcGhfY29tcG9uZW50cygpIHtcblx0XHRBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChcblx0XHRcdHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5ncmFwaC1zdGF0cy1jb250YWluZXIsIC5zdWItdGl0bGUsIC50aXRsZScpXG5cdFx0KS5tYXAoZCA9PiB7XG5cdFx0XHRkLnN0eWxlLmRpc3BsYXkgPSAnTm9uZSc7XG5cdFx0fSk7XG5cdFx0dGhpcy5jaGFydF93cmFwcGVyLnN0eWxlLm1hcmdpblRvcCA9ICcwcHgnO1xuXHRcdHRoaXMuY2hhcnRfd3JhcHBlci5zdHlsZS5wYWRkaW5nVG9wID0gJzBweCc7XG5cdH1cblxuXHRiaW5kX3Rvb2x0aXAoKSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmRhdGEtZ3JvdXAgLmRheVwiKVxuXHRcdCkubWFwKGVsID0+IHtcblx0XHRcdGVsLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCAoZSkgPT4ge1xuXHRcdFx0XHRsZXQgY291bnQgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKTtcblx0XHRcdFx0bGV0IGRhdGVfcGFydHMgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtZGF0ZScpLnNwbGl0KCctJyk7XG5cblx0XHRcdFx0bGV0IG1vbnRoID0gdGhpcy5tb250aF9uYW1lc1twYXJzZUludChkYXRlX3BhcnRzWzFdKS0xXS5zdWJzdHJpbmcoMCwgMyk7XG5cblx0XHRcdFx0bGV0IGdfb2ZmID0gdGhpcy5jaGFydF93cmFwcGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCBwX29mZiA9IGUudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG5cdFx0XHRcdGxldCB3aWR0aCA9IHBhcnNlSW50KGUudGFyZ2V0LmdldEF0dHJpYnV0ZSgnd2lkdGgnKSk7XG5cdFx0XHRcdGxldCB4ID0gcF9vZmYubGVmdCAtIGdfb2ZmLmxlZnQgKyAod2lkdGgrMikvMjtcblx0XHRcdFx0bGV0IHkgPSBwX29mZi50b3AgLSBnX29mZi50b3AgLSAod2lkdGgrMikvMjtcblx0XHRcdFx0bGV0IHZhbHVlID0gY291bnQgKyAnICcgKyB0aGlzLmNvdW50X2xhYmVsO1xuXHRcdFx0XHRsZXQgbmFtZSA9ICcgb24gJyArIG1vbnRoICsgJyAnICsgZGF0ZV9wYXJ0c1swXSArICcsICcgKyBkYXRlX3BhcnRzWzJdO1xuXG5cdFx0XHRcdHRoaXMudGlwLnNldF92YWx1ZXMoeCwgeSwgbmFtZSwgdmFsdWUsIFtdLCAxKTtcblx0XHRcdFx0dGhpcy50aXAuc2hvd190aXAoKTtcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0dXBkYXRlKGRhdGEpIHtcblx0XHR0aGlzLmRhdGEgPSBkYXRhO1xuXHRcdHRoaXMuc2V0dXBfdmFsdWVzKCk7XG5cdFx0dGhpcy5iaW5kX3Rvb2x0aXAoKTtcblx0fVxuXG5cdGdldF9kaXN0cmlidXRpb24oZGF0YT17fSwgbWFwcGVyX2FycmF5KSB7XG5cdFx0bGV0IGRhdGFfdmFsdWVzID0gT2JqZWN0LmtleXMoZGF0YSkubWFwKGtleSA9PiBkYXRhW2tleV0pO1xuXHRcdGxldCBkYXRhX21heF92YWx1ZSA9IE1hdGgubWF4KC4uLmRhdGFfdmFsdWVzKTtcblxuXHRcdGxldCBkaXN0cmlidXRpb25fc3RlcCA9IDEgLyAobWFwcGVyX2FycmF5Lmxlbmd0aCAtIDEpO1xuXHRcdGxldCBkaXN0cmlidXRpb24gPSBbXTtcblxuXHRcdG1hcHBlcl9hcnJheS5tYXAoKGNvbG9yLCBpKSA9PiB7XG5cdFx0XHRsZXQgY2hlY2twb2ludCA9IGRhdGFfbWF4X3ZhbHVlICogKGRpc3RyaWJ1dGlvbl9zdGVwICogaSk7XG5cdFx0XHRkaXN0cmlidXRpb24ucHVzaChjaGVja3BvaW50KTtcblx0XHR9KTtcblxuXHRcdHJldHVybiBkaXN0cmlidXRpb247XG5cdH1cblxuXHRnZXRfbWF4X2NoZWNrcG9pbnQodmFsdWUsIGRpc3RyaWJ1dGlvbikge1xuXHRcdHJldHVybiBkaXN0cmlidXRpb24uZmlsdGVyKChkLCBpKSA9PiB7XG5cdFx0XHRpZihpID09PSAxKSB7XG5cdFx0XHRcdHJldHVybiBkaXN0cmlidXRpb25bMF0gPCB2YWx1ZTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBkIDw9IHZhbHVlO1xuXHRcdH0pLmxlbmd0aCAtIDE7XG5cdH1cblxuXHQvLyBUT0RPOiBkYXRlIHV0aWxzLCBtb3ZlIHRoZXNlIG91dFxuXG5cdC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xMTI1MjE2Ny82NDk1MDQzXG5cdHRyZWF0X2FzX3V0YyhkYXRlX3N0cikge1xuXHRcdGxldCByZXN1bHQgPSBuZXcgRGF0ZShkYXRlX3N0cik7XG5cdFx0cmVzdWx0LnNldE1pbnV0ZXMocmVzdWx0LmdldE1pbnV0ZXMoKSAtIHJlc3VsdC5nZXRUaW1lem9uZU9mZnNldCgpKTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0Z2V0X2RkX21tX3l5eXkoZGF0ZSkge1xuXHRcdGxldCBkZCA9IGRhdGUuZ2V0RGF0ZSgpO1xuXHRcdGxldCBtbSA9IGRhdGUuZ2V0TW9udGgoKSArIDE7IC8vIGdldE1vbnRoKCkgaXMgemVyby1iYXNlZFxuXHRcdHJldHVybiBbXG5cdFx0XHQoZGQ+OSA/ICcnIDogJzAnKSArIGRkLFxuXHRcdFx0KG1tPjkgPyAnJyA6ICcwJykgKyBtbSxcblx0XHRcdGRhdGUuZ2V0RnVsbFllYXIoKVxuXHRcdF0uam9pbignLScpO1xuXHR9XG5cblx0Z2V0X3dlZWtzX2JldHdlZW4oc3RhcnRfZGF0ZV9zdHIsIGVuZF9kYXRlX3N0cikge1xuXHRcdHJldHVybiBNYXRoLmNlaWwodGhpcy5nZXRfZGF5c19iZXR3ZWVuKHN0YXJ0X2RhdGVfc3RyLCBlbmRfZGF0ZV9zdHIpIC8gNyk7XG5cdH1cblxuXHRnZXRfZGF5c19iZXR3ZWVuKHN0YXJ0X2RhdGVfc3RyLCBlbmRfZGF0ZV9zdHIpIHtcblx0XHRsZXQgbWlsbGlzZWNvbmRzX3Blcl9kYXkgPSAyNCAqIDYwICogNjAgKiAxMDAwO1xuXHRcdHJldHVybiAodGhpcy50cmVhdF9hc191dGMoZW5kX2RhdGVfc3RyKSAtIHRoaXMudHJlYXRfYXNfdXRjKHN0YXJ0X2RhdGVfc3RyKSkgLyBtaWxsaXNlY29uZHNfcGVyX2RheTtcblx0fVxuXG5cdC8vIG11dGF0ZXNcblx0YWRkX2RheXMoZGF0ZSwgbnVtYmVyX29mX2RheXMpIHtcblx0XHRkYXRlLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgKyBudW1iZXJfb2ZfZGF5cyk7XG5cdH1cblxuXHRnZXRfbW9udGhfbmFtZSgpIHt9XG59XG5cbmNsYXNzIFN2Z1RpcCB7XG5cdGNvbnN0cnVjdG9yKHtcblx0XHRwYXJlbnQgPSBudWxsXG5cdH0pIHtcblx0XHR0aGlzLnBhcmVudCA9IHBhcmVudDtcblx0XHR0aGlzLnRpdGxlX25hbWUgPSAnJztcblx0XHR0aGlzLnRpdGxlX3ZhbHVlID0gJyc7XG5cdFx0dGhpcy5saXN0X3ZhbHVlcyA9IFtdO1xuXHRcdHRoaXMudGl0bGVfdmFsdWVfZmlyc3QgPSAwO1xuXG5cdFx0dGhpcy54ID0gMDtcblx0XHR0aGlzLnkgPSAwO1xuXG5cdFx0dGhpcy50b3AgPSAwO1xuXHRcdHRoaXMubGVmdCA9IDA7XG5cblx0XHR0aGlzLnNldHVwKCk7XG5cdH1cblxuXHRzZXR1cCgpIHtcblx0XHR0aGlzLm1ha2VfdG9vbHRpcCgpO1xuXHR9XG5cblx0cmVmcmVzaCgpIHtcblx0XHR0aGlzLmZpbGwoKTtcblx0XHR0aGlzLmNhbGNfcG9zaXRpb24oKTtcblx0XHQvLyB0aGlzLnNob3dfdGlwKCk7XG5cdH1cblxuXHRtYWtlX3Rvb2x0aXAoKSB7XG5cdFx0dGhpcy5jb250YWluZXIgPSAkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0aW5zaWRlOiB0aGlzLnBhcmVudCxcblx0XHRcdGNsYXNzTmFtZTogJ2dyYXBoLXN2Zy10aXAgY29tcGFyaXNvbicsXG5cdFx0XHRpbm5lckhUTUw6IGA8c3BhbiBjbGFzcz1cInRpdGxlXCI+PC9zcGFuPlxuXHRcdFx0XHQ8dWwgY2xhc3M9XCJkYXRhLXBvaW50LWxpc3RcIj48L3VsPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwic3ZnLXBvaW50ZXJcIj48L2Rpdj5gXG5cdFx0fSk7XG5cdFx0dGhpcy5oaWRlX3RpcCgpO1xuXG5cdFx0dGhpcy50aXRsZSA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy50aXRsZScpO1xuXHRcdHRoaXMuZGF0YV9wb2ludF9saXN0ID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcignLmRhdGEtcG9pbnQtbGlzdCcpO1xuXG5cdFx0dGhpcy5wYXJlbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsICgpID0+IHtcblx0XHRcdHRoaXMuaGlkZV90aXAoKTtcblx0XHR9KTtcblx0fVxuXG5cdGZpbGwoKSB7XG5cdFx0bGV0IHRpdGxlO1xuXHRcdGlmKHRoaXMudGl0bGVfdmFsdWVfZmlyc3QpIHtcblx0XHRcdHRpdGxlID0gYDxzdHJvbmc+JHt0aGlzLnRpdGxlX3ZhbHVlfTwvc3Ryb25nPiR7dGhpcy50aXRsZV9uYW1lfWA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRpdGxlID0gYCR7dGhpcy50aXRsZV9uYW1lfTxzdHJvbmc+JHt0aGlzLnRpdGxlX3ZhbHVlfTwvc3Ryb25nPmA7XG5cdFx0fVxuXHRcdHRoaXMudGl0bGUuaW5uZXJIVE1MID0gdGl0bGU7XG5cdFx0dGhpcy5kYXRhX3BvaW50X2xpc3QuaW5uZXJIVE1MID0gJyc7XG5cblx0XHR0aGlzLmxpc3RfdmFsdWVzLm1hcCgoc2V0KSA9PiB7XG5cdFx0XHRsZXQgbGkgPSAkLmNyZWF0ZSgnbGknLCB7XG5cdFx0XHRcdGNsYXNzTmFtZTogYGJvcmRlci10b3AgJHtzZXQuY29sb3IgfHwgJ2JsYWNrJ31gLFxuXHRcdFx0XHRpbm5lckhUTUw6IGA8c3Ryb25nIHN0eWxlPVwiZGlzcGxheTogYmxvY2s7XCI+JHtzZXQudmFsdWUgPyBzZXQudmFsdWUgOiAnJyB9PC9zdHJvbmc+XG5cdFx0XHRcdFx0JHtzZXQudGl0bGUgPyBzZXQudGl0bGUgOiAnJyB9YFxuXHRcdFx0fSk7XG5cblx0XHRcdHRoaXMuZGF0YV9wb2ludF9saXN0LmFwcGVuZENoaWxkKGxpKTtcblx0XHR9KTtcblx0fVxuXG5cdGNhbGNfcG9zaXRpb24oKSB7XG5cdFx0dGhpcy50b3AgPSB0aGlzLnkgLSB0aGlzLmNvbnRhaW5lci5vZmZzZXRIZWlnaHQ7XG5cdFx0dGhpcy5sZWZ0ID0gdGhpcy54IC0gdGhpcy5jb250YWluZXIub2Zmc2V0V2lkdGgvMjtcblx0XHRsZXQgbWF4X2xlZnQgPSB0aGlzLnBhcmVudC5vZmZzZXRXaWR0aCAtIHRoaXMuY29udGFpbmVyLm9mZnNldFdpZHRoO1xuXG5cdFx0bGV0IHBvaW50ZXIgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcuc3ZnLXBvaW50ZXInKTtcblxuXHRcdGlmKHRoaXMubGVmdCA8IDApIHtcblx0XHRcdHBvaW50ZXIuc3R5bGUubGVmdCA9IGBjYWxjKDUwJSAtICR7LTEgKiB0aGlzLmxlZnR9cHgpYDtcblx0XHRcdHRoaXMubGVmdCA9IDA7XG5cdFx0fSBlbHNlIGlmKHRoaXMubGVmdCA+IG1heF9sZWZ0KSB7XG5cdFx0XHRsZXQgZGVsdGEgPSB0aGlzLmxlZnQgLSBtYXhfbGVmdDtcblx0XHRcdHBvaW50ZXIuc3R5bGUubGVmdCA9IGBjYWxjKDUwJSArICR7ZGVsdGF9cHgpYDtcblx0XHRcdHRoaXMubGVmdCA9IG1heF9sZWZ0O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwb2ludGVyLnN0eWxlLmxlZnQgPSBgNTAlYDtcblx0XHR9XG5cdH1cblxuXHRzZXRfdmFsdWVzKHgsIHksIHRpdGxlX25hbWUgPSAnJywgdGl0bGVfdmFsdWUgPSAnJywgbGlzdF92YWx1ZXMgPSBbXSwgdGl0bGVfdmFsdWVfZmlyc3QgPSAwKSB7XG5cdFx0dGhpcy50aXRsZV9uYW1lID0gdGl0bGVfbmFtZTtcblx0XHR0aGlzLnRpdGxlX3ZhbHVlID0gdGl0bGVfdmFsdWU7XG5cdFx0dGhpcy5saXN0X3ZhbHVlcyA9IGxpc3RfdmFsdWVzO1xuXHRcdHRoaXMueCA9IHg7XG5cdFx0dGhpcy55ID0geTtcblx0XHR0aGlzLnRpdGxlX3ZhbHVlX2ZpcnN0ID0gdGl0bGVfdmFsdWVfZmlyc3Q7XG5cdFx0dGhpcy5yZWZyZXNoKCk7XG5cdH1cblxuXHRoaWRlX3RpcCgpIHtcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS50b3AgPSAnMHB4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gJzBweCc7XG5cdFx0dGhpcy5jb250YWluZXIuc3R5bGUub3BhY2l0eSA9ICcwJztcblx0fVxuXG5cdHNob3dfdGlwKCkge1xuXHRcdHRoaXMuY29udGFpbmVyLnN0eWxlLnRvcCA9IHRoaXMudG9wICsgJ3B4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gdGhpcy5sZWZ0ICsgJ3B4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5vcGFjaXR5ID0gJzEnO1xuXHR9XG59XG4iXSwibmFtZXMiOlsiJCIsImV4cHIiLCJjb24iLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJmaW5kTm9kZUluZGV4Iiwibm9kZSIsImkiLCJwcmV2aW91c1NpYmxpbmciLCJjcmVhdGUiLCJ0YWciLCJvIiwiZWxlbWVudCIsImNyZWF0ZUVsZW1lbnQiLCJ2YWwiLCJhcHBlbmRDaGlsZCIsInJlZiIsInBhcmVudE5vZGUiLCJpbnNlcnRCZWZvcmUiLCJzZXRBdHRyaWJ1dGUiLCJjcmVhdGVTVkciLCJjcmVhdGVFbGVtZW50TlMiLCJydW5TVkdBbmltYXRpb24iLCJzdmdfY29udGFpbmVyIiwiZWxlbWVudHMiLCJuZXdfZWxlbWVudHMiLCJhbmltX2VsZW1lbnRzIiwibWFwIiwib2JqIiwicGFyZW50IiwidW5pdCIsImFuaW1fZWxlbWVudCIsIm5ld19lbGVtZW50IiwiYW5pbWF0ZVNWRyIsInB1c2giLCJyZXBsYWNlQ2hpbGQiLCJhcnJheSIsImluZGV4Iiwib2JqZWN0Iiwia2V5IiwiYW5pbV9zdmciLCJjbG9uZU5vZGUiLCJwcm9wcyIsImR1ciIsImVhc2luZ190eXBlIiwidHlwZSIsInVuZGVmaW5lZCIsIm9sZF92YWx1ZXMiLCJlYXNpbmciLCJhdHRyaWJ1dGVOYW1lIiwiYW5pbWF0ZV9lbGVtZW50IiwiY3VycmVudF92YWx1ZSIsImdldEF0dHJpYnV0ZSIsInZhbHVlIiwiYW5pbV9hdHRyIiwib2Zmc2V0IiwicmVjdCIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsInRvcCIsImRvY3VtZW50RWxlbWVudCIsInNjcm9sbFRvcCIsImJvZHkiLCJsZWZ0Iiwic2Nyb2xsTGVmdCIsImlzRWxlbWVudEluVmlld3BvcnQiLCJlbCIsImJvdHRvbSIsIndpbmRvdyIsImlubmVySGVpZ2h0IiwiY2xpZW50SGVpZ2h0IiwicmlnaHQiLCJpbm5lcldpZHRoIiwiY2xpZW50V2lkdGgiLCJiaW5kIiwiZXZlbnQiLCJjYWxsYmFjayIsInNwbGl0IiwiZm9yRWFjaCIsImFkZEV2ZW50TGlzdGVuZXIiLCJ1bmJpbmQiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiZmlyZSIsInRhcmdldCIsInByb3BlcnRpZXMiLCJldnQiLCJjcmVhdGVFdmVudCIsImluaXRFdmVudCIsImoiLCJkaXNwYXRjaEV2ZW50IiwiZmxvYXRfMiIsImQiLCJwYXJzZUZsb2F0IiwidG9GaXhlZCIsImFycmF5c19lcXVhbCIsImFycjEiLCJhcnIyIiwibGVuZ3RoIiwiYXJlX2VxdWFsIiwiQ2hhcnQiLCJoZWlnaHQiLCJ0aXRsZSIsInN1YnRpdGxlIiwiZGF0YSIsImZvcm1hdF9sYW1iZGFzIiwic3VtbWFyeSIsImlzX25hdmlnYWJsZSIsIk9iamVjdCIsImdldFByb3RvdHlwZU9mIiwicHJvdG90eXBlIiwiTGluZUNoYXJ0IiwiYXJndW1lbnRzIiwiQmFyQ2hhcnQiLCJQZXJjZW50YWdlQ2hhcnQiLCJIZWF0TWFwIiwicmF3X2NoYXJ0X2FyZ3MiLCJzcGVjaWZpY192YWx1ZXMiLCJjdXJyZW50X2luZGV4IiwiY2hhcnRfdHlwZXMiLCJzZXRfbWFyZ2lucyIsImluY2x1ZGVzIiwiZXJyb3IiLCJjb21wYXRpYmxlX3R5cGVzIiwiYmFzZV9oZWlnaHQiLCJ0cmFuc2xhdGVfeCIsInRyYW5zbGF0ZV95IiwiYmluZF93aW5kb3dfZXZlbnRzIiwicmVmcmVzaCIsImluaXQiLCJzZXR1cF9iYXNlX3ZhbHVlcyIsInNldF93aWR0aCIsInNldHVwX2NvbnRhaW5lciIsInNldHVwX2NvbXBvbmVudHMiLCJzZXR1cF92YWx1ZXMiLCJzZXR1cF91dGlscyIsIm1ha2VfZ3JhcGhfY29tcG9uZW50cyIsIm1ha2VfdG9vbHRpcCIsInNob3dfY3VzdG9tX3N1bW1hcnkiLCJzaG93X3N1bW1hcnkiLCJzZXR1cF9uYXZpZ2F0aW9uIiwic3BlY2lhbF92YWx1ZXNfd2lkdGgiLCJnZXRfc3Ryd2lkdGgiLCJiYXNlX3dpZHRoIiwib2Zmc2V0V2lkdGgiLCJ3aWR0aCIsImNvbnRhaW5lciIsImlubmVySFRNTCIsImNoYXJ0X3dyYXBwZXIiLCJzdGF0c193cmFwcGVyIiwibWFrZV9jaGFydF9hcmVhIiwibWFrZV9kcmF3X2FyZWEiLCJzdmciLCJzdmdfZGVmcyIsImRyYXdfYXJlYSIsInRpcCIsIlN2Z1RpcCIsImJpbmRfdG9vbHRpcCIsInN0YXRzIiwiY29sb3IiLCJtYWtlX292ZXJsYXkiLCJiaW5kX292ZXJsYXkiLCJlIiwia2V5Q29kZSIsIm9uX2xlZnRfYXJyb3ciLCJvbl9yaWdodF9hcnJvdyIsIm9uX3VwX2Fycm93Iiwib25fZG93bl9hcnJvdyIsIm9uX2VudGVyX2tleSIsImRhdGFfcG9pbnQiLCJ5IiwiZGF0YV9rZXkiLCJzbGljZSIsImxhYmVsIiwieCIsImdldF9kYXRhX3BvaW50Iiwic3RyaW5nIiwiQXhpc0NoYXJ0IiwiYXJncyIsImxhYmVscyIsImRhdGFzZXRzIiwiZ2V0X3lfbGFiZWwiLCJ5X2xhYmVsIiwiZ2V0X3lfdG9vbHRpcCIsInlfdG9vbHRpcCIsImdldF94X3Rvb2x0aXAiLCJ4X3Rvb2x0aXAiLCJjb2xvcnMiLCJ6ZXJvX2xpbmUiLCJ2YWx1ZXMiLCJpc05hTiIsInNldHVwX3giLCJzZXR1cF95Iiwic2V0X2F2Z191bml0X3dpZHRoX2FuZF94X29mZnNldCIsInhfYXhpc19wb3NpdGlvbnMiLCJ4X29sZF9heGlzX3Bvc2l0aW9ucyIsInhfb2Zmc2V0IiwiYXZnX3VuaXRfd2lkdGgiLCJ5X2F4aXNfdmFsdWVzIiwieV9vbGRfYXhpc192YWx1ZXMiLCJnZXRfYWxsX3lfdmFsdWVzIiwieV9zdW1zIiwiY29uY2F0IiwiZ2V0X3lfYXhpc19wb2ludHMiLCJ5X3B0cyIsInZhbHVlX3JhbmdlIiwibXVsdGlwbGllciIsIm9sZF9tdWx0aXBsaWVyIiwiemVyb19pbmRleCIsImluZGV4T2YiLCJpbnRlcnZhbCIsImludGVydmFsX2hlaWdodCIsIm9sZF96ZXJvX2xpbmUiLCJzZXR1cF9tYXJrZXJfY29tcG9uZW50cyIsInNldHVwX2FnZ3JlZ2F0aW9uX2NvbXBvbmVudHMiLCJzZXR1cF9ncmFwaF9jb21wb25lbnRzIiwieV9heGlzX2dyb3VwIiwiY2xhc3NOYW1lIiwiaW5zaWRlIiwieF9heGlzX2dyb3VwIiwic3BlY2lmaWNfeV9ncm91cCIsInN1bV9ncm91cCIsImF2ZXJhZ2VfZ3JvdXAiLCJzdmdfdW5pdHNfZ3JvdXBzIiwibWFrZV95X2F4aXMiLCJtYWtlX3hfYXhpcyIsImRyYXdfZ3JhcGgiLCJtYWtlX3lfc3BlY2lmaWNzIiwiYW5pbWF0ZSIsInN0YXJ0X2F0IiwidGV4dF9zdGFydF9hdCIsImF4aXNfbGluZV9jbGFzcyIsInhfYXhpc19tb2RlIiwibWFrZV9hbmltX3hfYXhpcyIsInRleHRDb250ZW50IiwicG9pbnQiLCJtYWtlX3hfbGluZSIsIm1ha2VfYW5pbV95X2F4aXMiLCJtYWtlX2FuaW1feV9zcGVjaWZpY3MiLCJnZXRfeV9heGlzX2xpbmVfcHJvcHMiLCJ0ZXh0X2VuZF9hdCIsIm1ha2VfeV9saW5lIiwic3BlY2lmaWMiLCJ5X2F4aXNfbW9kZSIsImRyYXdfbmV3X2dyYXBoX2FuZF9hbmltYXRlIiwic3ZnX3VuaXRzIiwibWFrZV9wYXRoIiwieV90b3BzIiwibWFrZV9uZXdfdW5pdHMiLCJBcnJheSIsImZpbGwiLCJ1cGRhdGVfdmFsdWVzIiwibWFrZV9uZXdfdW5pdHNfZm9yX2RhdGFzZXQiLCJ4X3ZhbHVlcyIsInlfdmFsdWVzIiwiZGF0YXNldF9pbmRleCIsIm5vX29mX2RhdGFzZXRzIiwiZ3JvdXAiLCJ1bml0X2FyZ3MiLCJkYXRhX3VuaXQiLCJkcmF3IiwidG9VcHBlckNhc2UiLCJsaW5lX3R5cGUiLCJyZWxYIiwicGFnZVgiLCJyZWxZIiwicGFnZVkiLCJtYXBfdG9vbHRpcF94X3Bvc2l0aW9uX2FuZF9zaG93IiwiaGlkZV90aXAiLCJ4X3ZhbCIsInlfbWluX3RvcHMiLCJmb3JtYXR0ZWQiLCJzZXQiLCJzZXRfdmFsdWVzIiwic2hvd190aXAiLCJ1cGRhdGluZyIsInN1bV91bml0cyIsIm9sZF9zcGVjaWZpY192YWx1ZXMiLCJzdW0iLCJhdmVyYWdlIiwiaW5kaWNlc190b19yZW1vdmUiLCJhdXRvIiwidW5zaGlmdCIsInNwbGljZSIsIm5ld195IiwibmV3X3giLCJlbGVtZW50c190b19hbmltYXRlIiwib2xkX3hfdmFsdWVzIiwib2xkX3lfYXhpc190b3BzIiwib2xkX3lfdmFsdWVzIiwibm9fb2ZfZXh0cmFfcHRzIiwiY2FsY195X2RlcGVuZGVuY2llcyIsImFuaW1hdGVfZ3JhcGhzIiwicnVuX2FuaW1hdGlvbiIsInlfcG9pbnQiLCJ4X3BvaW50IiwiZGF0YV9zZXQiLCJyZW1vdmVDaGlsZCIsImNhbGNfb2xkX2FuZF9uZXdfcG9zdGlvbnMiLCJvbGRfeCIsIm9sZF95IiwicGF0aCIsImFuaW1hdGVfcGF0aCIsImFuaW1hdGVfdW5pdHMiLCJuZXdfcG9pbnRzX2xpc3QiLCJuZXdfcGF0aF9zdHIiLCJqb2luIiwicGF0aF9hcmdzIiwicmVnaW9uX3BhdGgiLCJyZWdfc3RhcnRfcHQiLCJyZWdfZW5kX3B0IiwicmVnaW9uX2FyZ3MiLCJsYXN0X29sZF94X3BvcyIsImxhc3Rfb2xkX3lfcG9zIiwibGFzdF9uZXdfeF9wb3MiLCJsYXN0X25ld195X3BvcyIsImZpbGxlcl94IiwiTWF0aCIsImFicyIsImZpbGxlcl95Iiwib2xkX3BvcyIsIm5ld19wb3MiLCJvbGRfdmFscyIsIm5ld192YWxzIiwibGFzdF9saW5lX3BvcyIsImFkZF9hbmRfYW5pbWF0ZV9saW5lIiwieF9saW5lIiwidHJhbnNmb3JtIiwibWFrZV9uZXdfYXhpc19hbmltX2xpbmVzIiwiYWRkX2FuZF9hbmltYXRlX3lfbGluZSIsInN1cGVyaW1wb3NlZF9wb3NpdGlvbnMiLCJzdXBlcmltcG9zZWRfdmFsdWVzIiwibm9fb2ZfZXh0cmFzIiwiZmlsbGVyX3ZhbHMiLCJmaWxsZXJfcG9zIiwiZXh0cmFfdmFsdWVzIiwiZXh0cmFfcG9zaXRpb25zIiwibGFiZWxfY2xhc3MiLCJ4X3BvcyIsImFsbG93ZWRfc3BhY2UiLCJhbGxvd2VkX2xldHRlcnMiLCJsaW5lIiwidGV4dCIsInhfbGV2ZWwiLCJ5X3BvcyIsImRhcmtlciIsInlfbGV2ZWwiLCJzdHlsZSIsInN0cm9rZSIsImF4aXNfbGFiZWxfY2xhc3MiLCJ5X2xpbmUiLCJtYXhfYm91bmQiLCJtaW5fYm91bmQiLCJwb3Nfbm9fb2ZfcGFydHMiLCJuZWdfbm9fb2ZfcGFydHMiLCJwYXJ0X3NpemUiLCJtYXhfdmFsIiwicGFyc2VJbnQiLCJtYXgiLCJtaW5fdmFsIiwibWluIiwiZ2V0X3BhcmFtcyIsInZhbHVlMSIsInZhbHVlMiIsImJvdW5kMSIsImJvdW5kMiIsIm5vX29mX3BhcnRzXzEiLCJub19vZl9wYXJ0c18yIiwiaW50ZXJ2YWxfc2l6ZSIsImNhbGNfdXBwZXJfYm91bmRfYW5kX25vX29mX3BhcnRzIiwiY2FsY19ub19vZl9wYXJ0cyIsImFic19taW5fdmFsIiwibm9fb2ZfcGFydHMiLCJnZXRfaW50ZXJ2YWxzIiwic3RhcnQiLCJjb3VudCIsImludGVydmFscyIsInBvdyIsInVwcGVyX2JvdW5kIiwiZGl2aXNvciIsImNlaWwiLCJhbGxfdmFsdWVzIiwieV90b3AiLCJ0b3RhbF93aWR0aCIsInNwYWNlX3dpZHRoIiwic3RhcnRfeCIsImN1cnJlbnRfeCIsImdldF9iYXJfaGVpZ2h0X2FuZF95X2F0dHIiLCJyYWRpdXMiLCJiYXJfb2JqIiwiZG90X29iaiIsImN4IiwiY3kiLCJzZXR1cCIsInVwZGF0ZV9jdXJyZW50X2RhdGFfcG9pbnQiLCJvdmVybGF5Iiwib3BhY2l0eSIsInVwZGF0ZV9vdmVybGF5Iiwic3ZnX3VuaXQiLCJhdHRyaWJ1dGVzIiwia2V5cyIsImZpbHRlciIsImF0dHIiLCJzcGVjaWZpZWQiLCJuYW1lIiwibm9kZVZhbHVlIiwicmVnaW9uX2ZpbGwiLCJzZXR1cF9wYXRoX2dyb3VwcyIsInBhdGhzX2dyb3VwcyIsInhfcG9zaXRpb25zIiwieV9wb3NpdGlvbnMiLCJwb2ludHNfbGlzdCIsInBvaW50c19zdHIiLCJncmFkaWVudF9pZCIsImdyYWRpZW50X2RlZiIsInNldF9ncmFkaWVudF9zdG9wIiwiZ3JhZF9lbGVtIiwibWF4X3NsaWNlcyIsIm1heF9sZWdlbmRfcG9pbnRzIiwibWFyZ2luVG9wIiwibWFyZ2luQm90dG9tIiwicGFkZGluZ1RvcCIsImNoYXJ0X2RpdiIsImNoYXJ0IiwicGVyY2VudGFnZV9iYXIiLCJzbGljZV90b3RhbHMiLCJhbGxfdG90YWxzIiwidG90YWwiLCJ0b3RhbHMiLCJzb3J0IiwiYSIsImIiLCJvdGhlcnMiLCJzdW1fb2Zfb3RoZXJzIiwibGVnZW5kX3RvdGFscyIsImdyYW5kX3RvdGFsIiwicmVkdWNlIiwic2xpY2VzIiwiZ19vZmYiLCJwX29mZiIsImZvcm1hdHRlZF9sYWJlbHMiLCJwZXJjZW50IiwiZG9tYWluIiwic3ViZG9tYWluIiwiZGlzY3JldGVfZG9tYWlucyIsImNvdW50X2xhYmVsIiwidG9kYXkiLCJEYXRlIiwiYWRkX2RheXMiLCJsZWdlbmRfY29sb3JzIiwic2V0RnVsbFllYXIiLCJnZXRGdWxsWWVhciIsImZpcnN0X3dlZWtfc3RhcnQiLCJ0b0RhdGVTdHJpbmciLCJsYXN0X3dlZWtfc3RhcnQiLCJnZXREYXkiLCJub19vZl9jb2xzIiwiZ2V0X3dlZWtzX2JldHdlZW4iLCJkb21haW5fbGFiZWxfZ3JvdXAiLCJkYXRhX2dyb3VwcyIsImRpc3RyaWJ1dGlvbiIsImdldF9kaXN0cmlidXRpb24iLCJtb250aF9uYW1lcyIsInJlbmRlcl9hbGxfd2Vla3NfYW5kX3N0b3JlX3hfdmFsdWVzIiwibm9fb2Zfd2Vla3MiLCJjdXJyZW50X3dlZWtfc3VuZGF5Iiwid2Vla19jb2wiLCJjdXJyZW50X21vbnRoIiwiZ2V0TW9udGgiLCJtb250aHMiLCJtb250aF93ZWVrcyIsIm1vbnRoX3N0YXJ0X3BvaW50cyIsImRhdGFfZ3JvdXAiLCJtb250aF9jaGFuZ2UiLCJkYXkiLCJnZXRfd2Vla19zcXVhcmVzX2dyb3VwIiwicmVuZGVyX21vbnRoX2xhYmVscyIsImN1cnJlbnRfZGF0ZSIsIm5vX29mX3dlZWtkYXlzIiwic3F1YXJlX3NpZGUiLCJjZWxsX3BhZGRpbmciLCJzdGVwIiwid2Vla19jb2xfY2hhbmdlIiwiZGF0YV92YWx1ZSIsImNvbG9yX2luZGV4IiwidGltZXN0YW1wIiwiZmxvb3IiLCJnZXRUaW1lIiwiZ2V0X21heF9jaGVja3BvaW50Iiwicm91bmQiLCJnZXRfZGRfbW1feXl5eSIsIm5leHRfZGF0ZSIsInNoaWZ0IiwicG9wIiwibW9udGhfbmFtZSIsInN1YnN0cmluZyIsImNhbGwiLCJxdWVyeVNlbGVjdG9yQWxsIiwiZGlzcGxheSIsImRhdGVfcGFydHMiLCJtb250aCIsIm1hcHBlcl9hcnJheSIsImRhdGFfdmFsdWVzIiwiZGF0YV9tYXhfdmFsdWUiLCJkaXN0cmlidXRpb25fc3RlcCIsImNoZWNrcG9pbnQiLCJkYXRlX3N0ciIsInJlc3VsdCIsInNldE1pbnV0ZXMiLCJnZXRNaW51dGVzIiwiZ2V0VGltZXpvbmVPZmZzZXQiLCJkYXRlIiwiZGQiLCJnZXREYXRlIiwibW0iLCJzdGFydF9kYXRlX3N0ciIsImVuZF9kYXRlX3N0ciIsImdldF9kYXlzX2JldHdlZW4iLCJtaWxsaXNlY29uZHNfcGVyX2RheSIsInRyZWF0X2FzX3V0YyIsIm51bWJlcl9vZl9kYXlzIiwic2V0RGF0ZSIsInRpdGxlX25hbWUiLCJ0aXRsZV92YWx1ZSIsImxpc3RfdmFsdWVzIiwidGl0bGVfdmFsdWVfZmlyc3QiLCJjYWxjX3Bvc2l0aW9uIiwiZGF0YV9wb2ludF9saXN0IiwibGkiLCJvZmZzZXRIZWlnaHQiLCJtYXhfbGVmdCIsInBvaW50ZXIiLCJkZWx0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQWUsU0FBU0EsQ0FBVCxDQUFXQyxJQUFYLEVBQWlCQyxHQUFqQixFQUFzQjtRQUM3QixPQUFPRCxJQUFQLEtBQWdCLFFBQWhCLEdBQTBCLENBQUNDLE9BQU9DLFFBQVIsRUFBa0JDLGFBQWxCLENBQWdDSCxJQUFoQyxDQUExQixHQUFrRUEsUUFBUSxJQUFqRjs7O0FBR0RE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
diff --git a/docs/assets/js/index.js b/docs/assets/js/index.js
index 18a3e80..3c01309 100755
--- a/docs/assets/js/index.js
+++ b/docs/assets/js/index.js
@@ -141,7 +141,7 @@ let heatmap_data = {
// Charts
// ================================================================================
-let bar_composite_chart = new frappe.chart.FrappeChart ({
+let bar_composite_chart = new Chart ({
parent: "#chart-composite-1",
data: bar_composite_data,
type: 'bar',
@@ -150,7 +150,7 @@ let bar_composite_chart = new frappe.chart.FrappeChart ({
// region_fill: 1
})
-let line_composite_chart = new frappe.chart.FrappeChart ({
+let line_composite_chart = new Chart ({
parent: "#chart-composite-2",
data: line_composite_data,
type: 'line',
@@ -161,7 +161,7 @@ bar_composite_chart.parent.addEventListener('data-select', (e) => {
line_composite_chart.update_values([more_line_data[e.index]]);
});
-let type_chart = new frappe.chart.FrappeChart({
+let type_chart = new Chart({
parent: "#chart-types",
data: type_data,
type: 'bar',
@@ -170,7 +170,7 @@ let type_chart = new frappe.chart.FrappeChart({
// y_axis_mode: 'tick'
});
-let update_chart = new frappe.chart.FrappeChart({
+let update_chart = new Chart({
parent: "#chart-update",
data: update_data,
type: 'line',
@@ -178,7 +178,7 @@ let update_chart = new frappe.chart.FrappeChart({
region_fill: 1
});
-let events_chart = new frappe.chart.FrappeChart({
+let events_chart = new Chart({
parent: "#chart-events",
data: events_data,
type: 'bar',
@@ -186,14 +186,14 @@ let events_chart = new frappe.chart.FrappeChart({
is_navigable: 1,
});
-let aggr_chart = new frappe.chart.FrappeChart({
+let aggr_chart = new Chart({
parent: "#chart-aggr",
data: aggr_data,
type: 'bar',
height: 250
});
-let heatmap = new frappe.chart.FrappeChart({
+let heatmap = new Chart({
parent: "#chart-heatmap",
data: heatmap_data,
type: 'heatmap',
@@ -226,7 +226,7 @@ Array.prototype.slice.call(
let chart_update_buttons = document.querySelector('.chart-update-buttons');
chart_update_buttons.querySelector('[data-update="random"]').addEventListener("click", (e) => {
- $$.shuffle(update_data_all_indices);
+ shuffle(update_data_all_indices);
update_chart.update_values(
[{values: get_update_data(update_data_all_values)}],
get_update_data(update_data_all_labels)
@@ -267,3 +267,25 @@ document.querySelector('[data-aggregation="average"]').addEventListener("click",
e.target.innerHTML = "Show Average";
}
});
+
+function shuffle(array) {
+ // https://stackoverflow.com/a/2450976/6495043
+ // Awesomeness: https://bost.ocks.org/mike/shuffle/
+
+ var currentIndex = array.length, temporaryValue, randomIndex;
+
+ // While there remain elements to shuffle...
+ while (0 !== currentIndex) {
+
+ // Pick a remaining element...
+ randomIndex = Math.floor(Math.random() * currentIndex);
+ currentIndex -= 1;
+
+ // And swap it with the current element.
+ temporaryValue = array[currentIndex];
+ array[currentIndex] = array[randomIndex];
+ array[randomIndex] = temporaryValue;
+ }
+
+ return array;
+}
diff --git a/docs/index.html b/docs/index.html
index 8666583..e3f1fd5 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -14,7 +14,7 @@
-
+
@@ -155,7 +155,9 @@
-
+
+
+