made with requirebin
Last active
November 14, 2017 22:40
-
-
Save jtenner/d7d0641580f74ec913bc190aad43aa9e to your computer and use it in GitHub Desktop.
requirebin sketch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const rbush = require( "rbush" ); | |
| const ctx = document.createElement( "canvas" ).getContext( "2d" ); | |
| const width = ctx.canvas.width = 800; | |
| const height = ctx.canvas.height = 600; | |
| const e2d = require( "e2d" ); | |
| document.body.appendChild( ctx.canvas ); | |
| const tree = rbush(); | |
| const rects = []; | |
| for ( let i = 0; i < 100; i++ ) { | |
| const rectWidth = 10 + Math.random() * 90; | |
| const rectHeight = 10 + Math.random() * 90; | |
| const minX = 0 + Math.random() * ( width - rectWidth ); | |
| const minY = 0 + Math.random() * ( height - rectHeight ); | |
| const maxX = minX + rectWidth; | |
| const maxY = minY + rectHeight; | |
| const rect = { | |
| rectWidth, | |
| rectHeight, | |
| minX, | |
| minY, | |
| maxX, | |
| maxY, | |
| fill: e2d.fillRect( minX, minY, rectWidth, rectHeight ), | |
| }; | |
| rects.push( e2d.strokeRect( minX, minY, rectWidth, rectHeight ) ); | |
| tree.insert( rect ); | |
| } | |
| e2d.initialize( ctx ); | |
| e2d.raf(frame => { | |
| const { x, y } = e2d.mouseData( ctx ); | |
| const mouseRect = e2d.fillStyle( "red", e2d.strokeRect( x - 10, y - 10, 20, 20 ) ); | |
| e2d.render( | |
| e2d.clearRect( width, height ), | |
| tree.search({ | |
| minX: x - 10, | |
| minY: y - 10, | |
| maxX: x + 10, | |
| maxY: y + 10 | |
| }).map(z => z.fill), | |
| mouseRect, | |
| rects, | |
| ctx | |
| ); | |
| }); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| setTimeout(function(){ | |
| ;require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | |
| 'use strict'; | |
| module.exports = partialSort; | |
| // Floyd-Rivest selection algorithm: | |
| // Rearrange items so that all items in the [left, k] range are smaller than all items in (k, right]; | |
| // The k-th element will have the (k - left + 1)th smallest value in [left, right] | |
| function partialSort(arr, k, left, right, compare) { | |
| left = left || 0; | |
| right = right || (arr.length - 1); | |
| compare = compare || defaultCompare; | |
| while (right > left) { | |
| if (right - left > 600) { | |
| var n = right - left + 1; | |
| var m = k - left + 1; | |
| var z = Math.log(n); | |
| var s = 0.5 * Math.exp(2 * z / 3); | |
| var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); | |
| var newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); | |
| var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); | |
| partialSort(arr, k, newLeft, newRight, compare); | |
| } | |
| var t = arr[k]; | |
| var i = left; | |
| var j = right; | |
| swap(arr, left, k); | |
| if (compare(arr[right], t) > 0) swap(arr, left, right); | |
| while (i < j) { | |
| swap(arr, i, j); | |
| i++; | |
| j--; | |
| while (compare(arr[i], t) < 0) i++; | |
| while (compare(arr[j], t) > 0) j--; | |
| } | |
| if (compare(arr[left], t) === 0) swap(arr, left, j); | |
| else { | |
| j++; | |
| swap(arr, j, right); | |
| } | |
| if (j <= k) left = j + 1; | |
| if (k <= j) right = j - 1; | |
| } | |
| } | |
| function swap(arr, i, j) { | |
| var tmp = arr[i]; | |
| arr[i] = arr[j]; | |
| arr[j] = tmp; | |
| } | |
| function defaultCompare(a, b) { | |
| return a < b ? -1 : a > b ? 1 : 0; | |
| } | |
| },{}],"rbush":[function(require,module,exports){ | |
| 'use strict'; | |
| module.exports = rbush; | |
| var quickselect = require('quickselect'); | |
| function rbush(maxEntries, format) { | |
| if (!(this instanceof rbush)) return new rbush(maxEntries, format); | |
| // max entries in a node is 9 by default; min node fill is 40% for best performance | |
| this._maxEntries = Math.max(4, maxEntries || 9); | |
| this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4)); | |
| if (format) { | |
| this._initFormat(format); | |
| } | |
| this.clear(); | |
| } | |
| rbush.prototype = { | |
| all: function () { | |
| return this._all(this.data, []); | |
| }, | |
| search: function (bbox) { | |
| var node = this.data, | |
| result = [], | |
| toBBox = this.toBBox; | |
| if (!intersects(bbox, node)) return result; | |
| var nodesToSearch = [], | |
| i, len, child, childBBox; | |
| while (node) { | |
| for (i = 0, len = node.children.length; i < len; i++) { | |
| child = node.children[i]; | |
| childBBox = node.leaf ? toBBox(child) : child; | |
| if (intersects(bbox, childBBox)) { | |
| if (node.leaf) result.push(child); | |
| else if (contains(bbox, childBBox)) this._all(child, result); | |
| else nodesToSearch.push(child); | |
| } | |
| } | |
| node = nodesToSearch.pop(); | |
| } | |
| return result; | |
| }, | |
| collides: function (bbox) { | |
| var node = this.data, | |
| toBBox = this.toBBox; | |
| if (!intersects(bbox, node)) return false; | |
| var nodesToSearch = [], | |
| i, len, child, childBBox; | |
| while (node) { | |
| for (i = 0, len = node.children.length; i < len; i++) { | |
| child = node.children[i]; | |
| childBBox = node.leaf ? toBBox(child) : child; | |
| if (intersects(bbox, childBBox)) { | |
| if (node.leaf || contains(bbox, childBBox)) return true; | |
| nodesToSearch.push(child); | |
| } | |
| } | |
| node = nodesToSearch.pop(); | |
| } | |
| return false; | |
| }, | |
| load: function (data) { | |
| if (!(data && data.length)) return this; | |
| if (data.length < this._minEntries) { | |
| for (var i = 0, len = data.length; i < len; i++) { | |
| this.insert(data[i]); | |
| } | |
| return this; | |
| } | |
| // recursively build the tree with the given data from stratch using OMT algorithm | |
| var node = this._build(data.slice(), 0, data.length - 1, 0); | |
| if (!this.data.children.length) { | |
| // save as is if tree is empty | |
| this.data = node; | |
| } else if (this.data.height === node.height) { | |
| // split root if trees have the same height | |
| this._splitRoot(this.data, node); | |
| } else { | |
| if (this.data.height < node.height) { | |
| // swap trees if inserted one is bigger | |
| var tmpNode = this.data; | |
| this.data = node; | |
| node = tmpNode; | |
| } | |
| // insert the small tree into the large tree at appropriate level | |
| this._insert(node, this.data.height - node.height - 1, true); | |
| } | |
| return this; | |
| }, | |
| insert: function (item) { | |
| if (item) this._insert(item, this.data.height - 1); | |
| return this; | |
| }, | |
| clear: function () { | |
| this.data = createNode([]); | |
| return this; | |
| }, | |
| remove: function (item, equalsFn) { | |
| if (!item) return this; | |
| var node = this.data, | |
| bbox = this.toBBox(item), | |
| path = [], | |
| indexes = [], | |
| i, parent, index, goingUp; | |
| // depth-first iterative tree traversal | |
| while (node || path.length) { | |
| if (!node) { // go up | |
| node = path.pop(); | |
| parent = path[path.length - 1]; | |
| i = indexes.pop(); | |
| goingUp = true; | |
| } | |
| if (node.leaf) { // check current node | |
| index = findItem(item, node.children, equalsFn); | |
| if (index !== -1) { | |
| // item found, remove the item and condense tree upwards | |
| node.children.splice(index, 1); | |
| path.push(node); | |
| this._condense(path); | |
| return this; | |
| } | |
| } | |
| if (!goingUp && !node.leaf && contains(node, bbox)) { // go down | |
| path.push(node); | |
| indexes.push(i); | |
| i = 0; | |
| parent = node; | |
| node = node.children[0]; | |
| } else if (parent) { // go right | |
| i++; | |
| node = parent.children[i]; | |
| goingUp = false; | |
| } else node = null; // nothing found | |
| } | |
| return this; | |
| }, | |
| toBBox: function (item) { return item; }, | |
| compareMinX: compareNodeMinX, | |
| compareMinY: compareNodeMinY, | |
| toJSON: function () { return this.data; }, | |
| fromJSON: function (data) { | |
| this.data = data; | |
| return this; | |
| }, | |
| _all: function (node, result) { | |
| var nodesToSearch = []; | |
| while (node) { | |
| if (node.leaf) result.push.apply(result, node.children); | |
| else nodesToSearch.push.apply(nodesToSearch, node.children); | |
| node = nodesToSearch.pop(); | |
| } | |
| return result; | |
| }, | |
| _build: function (items, left, right, height) { | |
| var N = right - left + 1, | |
| M = this._maxEntries, | |
| node; | |
| if (N <= M) { | |
| // reached leaf level; return leaf | |
| node = createNode(items.slice(left, right + 1)); | |
| calcBBox(node, this.toBBox); | |
| return node; | |
| } | |
| if (!height) { | |
| // target height of the bulk-loaded tree | |
| height = Math.ceil(Math.log(N) / Math.log(M)); | |
| // target number of root entries to maximize storage utilization | |
| M = Math.ceil(N / Math.pow(M, height - 1)); | |
| } | |
| node = createNode([]); | |
| node.leaf = false; | |
| node.height = height; | |
| // split the items into M mostly square tiles | |
| var N2 = Math.ceil(N / M), | |
| N1 = N2 * Math.ceil(Math.sqrt(M)), | |
| i, j, right2, right3; | |
| multiSelect(items, left, right, N1, this.compareMinX); | |
| for (i = left; i <= right; i += N1) { | |
| right2 = Math.min(i + N1 - 1, right); | |
| multiSelect(items, i, right2, N2, this.compareMinY); | |
| for (j = i; j <= right2; j += N2) { | |
| right3 = Math.min(j + N2 - 1, right2); | |
| // pack each entry recursively | |
| node.children.push(this._build(items, j, right3, height - 1)); | |
| } | |
| } | |
| calcBBox(node, this.toBBox); | |
| return node; | |
| }, | |
| _chooseSubtree: function (bbox, node, level, path) { | |
| var i, len, child, targetNode, area, enlargement, minArea, minEnlargement; | |
| while (true) { | |
| path.push(node); | |
| if (node.leaf || path.length - 1 === level) break; | |
| minArea = minEnlargement = Infinity; | |
| for (i = 0, len = node.children.length; i < len; i++) { | |
| child = node.children[i]; | |
| area = bboxArea(child); | |
| enlargement = enlargedArea(bbox, child) - area; | |
| // choose entry with the least area enlargement | |
| if (enlargement < minEnlargement) { | |
| minEnlargement = enlargement; | |
| minArea = area < minArea ? area : minArea; | |
| targetNode = child; | |
| } else if (enlargement === minEnlargement) { | |
| // otherwise choose one with the smallest area | |
| if (area < minArea) { | |
| minArea = area; | |
| targetNode = child; | |
| } | |
| } | |
| } | |
| node = targetNode || node.children[0]; | |
| } | |
| return node; | |
| }, | |
| _insert: function (item, level, isNode) { | |
| var toBBox = this.toBBox, | |
| bbox = isNode ? item : toBBox(item), | |
| insertPath = []; | |
| // find the best node for accommodating the item, saving all nodes along the path too | |
| var node = this._chooseSubtree(bbox, this.data, level, insertPath); | |
| // put the item into the node | |
| node.children.push(item); | |
| extend(node, bbox); | |
| // split on node overflow; propagate upwards if necessary | |
| while (level >= 0) { | |
| if (insertPath[level].children.length > this._maxEntries) { | |
| this._split(insertPath, level); | |
| level--; | |
| } else break; | |
| } | |
| // adjust bboxes along the insertion path | |
| this._adjustParentBBoxes(bbox, insertPath, level); | |
| }, | |
| // split overflowed node into two | |
| _split: function (insertPath, level) { | |
| var node = insertPath[level], | |
| M = node.children.length, | |
| m = this._minEntries; | |
| this._chooseSplitAxis(node, m, M); | |
| var splitIndex = this._chooseSplitIndex(node, m, M); | |
| var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex)); | |
| newNode.height = node.height; | |
| newNode.leaf = node.leaf; | |
| calcBBox(node, this.toBBox); | |
| calcBBox(newNode, this.toBBox); | |
| if (level) insertPath[level - 1].children.push(newNode); | |
| else this._splitRoot(node, newNode); | |
| }, | |
| _splitRoot: function (node, newNode) { | |
| // split root node | |
| this.data = createNode([node, newNode]); | |
| this.data.height = node.height + 1; | |
| this.data.leaf = false; | |
| calcBBox(this.data, this.toBBox); | |
| }, | |
| _chooseSplitIndex: function (node, m, M) { | |
| var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index; | |
| minOverlap = minArea = Infinity; | |
| for (i = m; i <= M - m; i++) { | |
| bbox1 = distBBox(node, 0, i, this.toBBox); | |
| bbox2 = distBBox(node, i, M, this.toBBox); | |
| overlap = intersectionArea(bbox1, bbox2); | |
| area = bboxArea(bbox1) + bboxArea(bbox2); | |
| // choose distribution with minimum overlap | |
| if (overlap < minOverlap) { | |
| minOverlap = overlap; | |
| index = i; | |
| minArea = area < minArea ? area : minArea; | |
| } else if (overlap === minOverlap) { | |
| // otherwise choose distribution with minimum area | |
| if (area < minArea) { | |
| minArea = area; | |
| index = i; | |
| } | |
| } | |
| } | |
| return index; | |
| }, | |
| // sorts node children by the best axis for split | |
| _chooseSplitAxis: function (node, m, M) { | |
| var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX, | |
| compareMinY = node.leaf ? this.compareMinY : compareNodeMinY, | |
| xMargin = this._allDistMargin(node, m, M, compareMinX), | |
| yMargin = this._allDistMargin(node, m, M, compareMinY); | |
| // if total distributions margin value is minimal for x, sort by minX, | |
| // otherwise it's already sorted by minY | |
| if (xMargin < yMargin) node.children.sort(compareMinX); | |
| }, | |
| // total margin of all possible split distributions where each node is at least m full | |
| _allDistMargin: function (node, m, M, compare) { | |
| node.children.sort(compare); | |
| var toBBox = this.toBBox, | |
| leftBBox = distBBox(node, 0, m, toBBox), | |
| rightBBox = distBBox(node, M - m, M, toBBox), | |
| margin = bboxMargin(leftBBox) + bboxMargin(rightBBox), | |
| i, child; | |
| for (i = m; i < M - m; i++) { | |
| child = node.children[i]; | |
| extend(leftBBox, node.leaf ? toBBox(child) : child); | |
| margin += bboxMargin(leftBBox); | |
| } | |
| for (i = M - m - 1; i >= m; i--) { | |
| child = node.children[i]; | |
| extend(rightBBox, node.leaf ? toBBox(child) : child); | |
| margin += bboxMargin(rightBBox); | |
| } | |
| return margin; | |
| }, | |
| _adjustParentBBoxes: function (bbox, path, level) { | |
| // adjust bboxes along the given tree path | |
| for (var i = level; i >= 0; i--) { | |
| extend(path[i], bbox); | |
| } | |
| }, | |
| _condense: function (path) { | |
| // go through the path, removing empty nodes and updating bboxes | |
| for (var i = path.length - 1, siblings; i >= 0; i--) { | |
| if (path[i].children.length === 0) { | |
| if (i > 0) { | |
| siblings = path[i - 1].children; | |
| siblings.splice(siblings.indexOf(path[i]), 1); | |
| } else this.clear(); | |
| } else calcBBox(path[i], this.toBBox); | |
| } | |
| }, | |
| _initFormat: function (format) { | |
| // data format (minX, minY, maxX, maxY accessors) | |
| // uses eval-type function compilation instead of just accepting a toBBox function | |
| // because the algorithms are very sensitive to sorting functions performance, | |
| // so they should be dead simple and without inner calls | |
| var compareArr = ['return a', ' - b', ';']; | |
| this.compareMinX = new Function('a', 'b', compareArr.join(format[0])); | |
| this.compareMinY = new Function('a', 'b', compareArr.join(format[1])); | |
| this.toBBox = new Function('a', | |
| 'return {minX: a' + format[0] + | |
| ', minY: a' + format[1] + | |
| ', maxX: a' + format[2] + | |
| ', maxY: a' + format[3] + '};'); | |
| } | |
| }; | |
| function findItem(item, items, equalsFn) { | |
| if (!equalsFn) return items.indexOf(item); | |
| for (var i = 0; i < items.length; i++) { | |
| if (equalsFn(item, items[i])) return i; | |
| } | |
| return -1; | |
| } | |
| // calculate node's bbox from bboxes of its children | |
| function calcBBox(node, toBBox) { | |
| distBBox(node, 0, node.children.length, toBBox, node); | |
| } | |
| // min bounding rectangle of node children from k to p-1 | |
| function distBBox(node, k, p, toBBox, destNode) { | |
| if (!destNode) destNode = createNode(null); | |
| destNode.minX = Infinity; | |
| destNode.minY = Infinity; | |
| destNode.maxX = -Infinity; | |
| destNode.maxY = -Infinity; | |
| for (var i = k, child; i < p; i++) { | |
| child = node.children[i]; | |
| extend(destNode, node.leaf ? toBBox(child) : child); | |
| } | |
| return destNode; | |
| } | |
| function extend(a, b) { | |
| a.minX = Math.min(a.minX, b.minX); | |
| a.minY = Math.min(a.minY, b.minY); | |
| a.maxX = Math.max(a.maxX, b.maxX); | |
| a.maxY = Math.max(a.maxY, b.maxY); | |
| return a; | |
| } | |
| function compareNodeMinX(a, b) { return a.minX - b.minX; } | |
| function compareNodeMinY(a, b) { return a.minY - b.minY; } | |
| function bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); } | |
| function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); } | |
| function enlargedArea(a, b) { | |
| return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) * | |
| (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY)); | |
| } | |
| function intersectionArea(a, b) { | |
| var minX = Math.max(a.minX, b.minX), | |
| minY = Math.max(a.minY, b.minY), | |
| maxX = Math.min(a.maxX, b.maxX), | |
| maxY = Math.min(a.maxY, b.maxY); | |
| return Math.max(0, maxX - minX) * | |
| Math.max(0, maxY - minY); | |
| } | |
| function contains(a, b) { | |
| return a.minX <= b.minX && | |
| a.minY <= b.minY && | |
| b.maxX <= a.maxX && | |
| b.maxY <= a.maxY; | |
| } | |
| function intersects(a, b) { | |
| return b.minX <= a.maxX && | |
| b.minY <= a.maxY && | |
| b.maxX >= a.minX && | |
| b.maxY >= a.minY; | |
| } | |
| function createNode(children) { | |
| return { | |
| children: children, | |
| height: 1, | |
| leaf: true, | |
| minX: Infinity, | |
| minY: Infinity, | |
| maxX: -Infinity, | |
| maxY: -Infinity | |
| }; | |
| } | |
| // sort an array so that items come in groups of n unsorted items, with groups sorted between each other; | |
| // combines selection algorithm with binary divide & conquer approach | |
| function multiSelect(arr, left, right, n, compare) { | |
| var stack = [left, right], | |
| mid; | |
| while (stack.length) { | |
| right = stack.pop(); | |
| left = stack.pop(); | |
| if (right - left <= n) continue; | |
| mid = left + Math.ceil((right - left) / n / 2) * n; | |
| quickselect(arr, mid, left, right, compare); | |
| stack.push(left, mid, mid, right); | |
| } | |
| } | |
| },{"quickselect":1}]},{},[]) | |
| //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIm5vZGVfbW9kdWxlcy9xdWlja3NlbGVjdC9pbmRleC5qcyIsInJidXNoIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBwYXJ0aWFsU29ydDtcblxuLy8gRmxveWQtUml2ZXN0IHNlbGVjdGlvbiBhbGdvcml0aG06XG4vLyBSZWFycmFuZ2UgaXRlbXMgc28gdGhhdCBhbGwgaXRlbXMgaW4gdGhlIFtsZWZ0LCBrXSByYW5nZSBhcmUgc21hbGxlciB0aGFuIGFsbCBpdGVtcyBpbiAoaywgcmlnaHRdO1xuLy8gVGhlIGstdGggZWxlbWVudCB3aWxsIGhhdmUgdGhlIChrIC0gbGVmdCArIDEpdGggc21hbGxlc3QgdmFsdWUgaW4gW2xlZnQsIHJpZ2h0XVxuXG5mdW5jdGlvbiBwYXJ0aWFsU29ydChhcnIsIGssIGxlZnQsIHJpZ2h0LCBjb21wYXJlKSB7XG4gICAgbGVmdCA9IGxlZnQgfHwgMDtcbiAgICByaWdodCA9IHJpZ2h0IHx8IChhcnIubGVuZ3RoIC0gMSk7XG4gICAgY29tcGFyZSA9IGNvbXBhcmUgfHwgZGVmYXVsdENvbXBhcmU7XG5cbiAgICB3aGlsZSAocmlnaHQgPiBsZWZ0KSB7XG4gICAgICAgIGlmIChyaWdodCAtIGxlZnQgPiA2MDApIHtcbiAgICAgICAgICAgIHZhciBuID0gcmlnaHQgLSBsZWZ0ICsgMTtcbiAgICAgICAgICAgIHZhciBtID0gayAtIGxlZnQgKyAxO1xuICAgICAgICAgICAgdmFyIHogPSBNYXRoLmxvZyhuKTtcbiAgICAgICAgICAgIHZhciBzID0gMC41ICogTWF0aC5leHAoMiAqIHogLyAzKTtcbiAgICAgICAgICAgIHZhciBzZCA9IDAuNSAqIE1hdGguc3FydCh6ICogcyAqIChuIC0gcykgLyBuKSAqIChtIC0gbiAvIDIgPCAwID8gLTEgOiAxKTtcbiAgICAgICAgICAgIHZhciBuZXdMZWZ0ID0gTWF0aC5tYXgobGVmdCwgTWF0aC5mbG9vcihrIC0gbSAqIHMgLyBuICsgc2QpKTtcbiAgICAgICAgICAgIHZhciBuZXdSaWdodCA9IE1hdGgubWluKHJpZ2h0LCBNYXRoLmZsb29yKGsgKyAobiAtIG0pICogcyAvIG4gKyBzZCkpO1xuICAgICAgICAgICAgcGFydGlhbFNvcnQoYXJyLCBrLCBuZXdMZWZ0LCBuZXdSaWdodCwgY29tcGFyZSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdCA9IGFycltrXTtcbiAgICAgICAgdmFyIGkgPSBsZWZ0O1xuICAgICAgICB2YXIgaiA9IHJpZ2h0O1xuXG4gICAgICAgIHN3YXAoYXJyLCBsZWZ0LCBrKTtcbiAgICAgICAgaWYgKGNvbXBhcmUoYXJyW3JpZ2h0XSwgdCkgPiAwKSBzd2FwKGFyciwgbGVmdCwgcmlnaHQpO1xuXG4gICAgICAgIHdoaWxlIChpIDwgaikge1xuICAgICAgICAgICAgc3dhcChhcnIsIGksIGopO1xuICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgai0tO1xuICAgICAgICAgICAgd2hpbGUgKGNvbXBhcmUoYXJyW2ldLCB0KSA8IDApIGkrKztcbiAgICAgICAgICAgIHdoaWxlIChjb21wYXJlKGFycltqXSwgdCkgPiAwKSBqLS07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29tcGFyZShhcnJbbGVmdF0sIHQpID09PSAwKSBzd2FwKGFyciwgbGVmdCwgaik7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaisrO1xuICAgICAgICAgICAgc3dhcChhcnIsIGosIHJpZ2h0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChqIDw9IGspIGxlZnQgPSBqICsgMTtcbiAgICAgICAgaWYgKGsgPD0gaikgcmlnaHQgPSBqIC0gMTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHN3YXAoYXJyLCBpLCBqKSB7XG4gICAgdmFyIHRtcCA9IGFycltpXTtcbiAgICBhcnJbaV0gPSBhcnJbal07XG4gICAgYXJyW2pdID0gdG1wO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0Q29tcGFyZShhLCBiKSB7XG4gICAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiAwO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJidXNoO1xuXG52YXIgcXVpY2tzZWxlY3QgPSByZXF1aXJlKCdxdWlja3NlbGVjdCcpO1xuXG5mdW5jdGlvbiByYnVzaChtYXhFbnRyaWVzLCBmb3JtYXQpIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgcmJ1c2gpKSByZXR1cm4gbmV3IHJidXNoKG1heEVudHJpZXMsIGZvcm1hdCk7XG5cbiAgICAvLyBtYXggZW50cmllcyBpbiBhIG5vZGUgaXMgOSBieSBkZWZhdWx0OyBtaW4gbm9kZSBmaWxsIGlzIDQwJSBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoaXMuX21heEVudHJpZXMgPSBNYXRoLm1heCg0LCBtYXhFbnRyaWVzIHx8IDkpO1xuICAgIHRoaXMuX21pbkVudHJpZXMgPSBNYXRoLm1heCgyLCBNYXRoLmNlaWwodGhpcy5fbWF4RW50cmllcyAqIDAuNCkpO1xuXG4gICAgaWYgKGZvcm1hdCkge1xuICAgICAgICB0aGlzLl9pbml0Rm9ybWF0KGZvcm1hdCk7XG4gICAgfVxuXG4gICAgdGhpcy5jbGVhcigpO1xufVxuXG5yYnVzaC5wcm90b3R5cGUgPSB7XG5cbiAgICBhbGw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FsbCh0aGlzLmRhdGEsIFtdKTtcbiAgICB9LFxuXG4gICAgc2VhcmNoOiBmdW5jdGlvbiAoYmJveCkge1xuXG4gICAgICAgIHZhciBub2RlID0gdGhpcy5kYXRhLFxuICAgICAgICAgICAgcmVzdWx0ID0gW10sXG4gICAgICAgICAgICB0b0JCb3ggPSB0aGlzLnRvQkJveDtcblxuICAgICAgICBpZiAoIWludGVyc2VjdHMoYmJveCwgbm9kZSkpIHJldHVybiByZXN1bHQ7XG5cbiAgICAgICAgdmFyIG5vZGVzVG9TZWFyY2ggPSBbXSxcbiAgICAgICAgICAgIGksIGxlbiwgY2hpbGQsIGNoaWxkQkJveDtcblxuICAgICAgICB3aGlsZSAobm9kZSkge1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuXG4gICAgICAgICAgICAgICAgY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgICAgIGNoaWxkQkJveCA9IG5vZGUubGVhZiA/IHRvQkJveChjaGlsZCkgOiBjaGlsZDtcblxuICAgICAgICAgICAgICAgIGlmIChpbnRlcnNlY3RzKGJib3gsIGNoaWxkQkJveCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUubGVhZikgcmVzdWx0LnB1c2goY2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjb250YWlucyhiYm94LCBjaGlsZEJCb3gpKSB0aGlzLl9hbGwoY2hpbGQsIHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2Ugbm9kZXNUb1NlYXJjaC5wdXNoKGNoaWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBub2RlID0gbm9kZXNUb1NlYXJjaC5wb3AoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIGNvbGxpZGVzOiBmdW5jdGlvbiAoYmJveCkge1xuXG4gICAgICAgIHZhciBub2RlID0gdGhpcy5kYXRhLFxuICAgICAgICAgICAgdG9CQm94ID0gdGhpcy50b0JCb3g7XG5cbiAgICAgICAgaWYgKCFpbnRlcnNlY3RzKGJib3gsIG5vZGUpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgdmFyIG5vZGVzVG9TZWFyY2ggPSBbXSxcbiAgICAgICAgICAgIGksIGxlbiwgY2hpbGQsIGNoaWxkQkJveDtcblxuICAgICAgICB3aGlsZSAobm9kZSkge1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuXG4gICAgICAgICAgICAgICAgY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgICAgIGNoaWxkQkJveCA9IG5vZGUubGVhZiA/IHRvQkJveChjaGlsZCkgOiBjaGlsZDtcblxuICAgICAgICAgICAgICAgIGlmIChpbnRlcnNlY3RzKGJib3gsIGNoaWxkQkJveCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUubGVhZiB8fCBjb250YWlucyhiYm94LCBjaGlsZEJCb3gpKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgbm9kZXNUb1NlYXJjaC5wdXNoKGNoaWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBub2RlID0gbm9kZXNUb1NlYXJjaC5wb3AoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9LFxuXG4gICAgbG9hZDogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgaWYgKCEoZGF0YSAmJiBkYXRhLmxlbmd0aCkpIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChkYXRhLmxlbmd0aCA8IHRoaXMuX21pbkVudHJpZXMpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBkYXRhLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnNlcnQoZGF0YVtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJlY3Vyc2l2ZWx5IGJ1aWxkIHRoZSB0cmVlIHdpdGggdGhlIGdpdmVuIGRhdGEgZnJvbSBzdHJhdGNoIHVzaW5nIE9NVCBhbGdvcml0aG1cbiAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl9idWlsZChkYXRhLnNsaWNlKCksIDAsIGRhdGEubGVuZ3RoIC0gMSwgMCk7XG5cbiAgICAgICAgaWYgKCF0aGlzLmRhdGEuY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICAgICAgICAvLyBzYXZlIGFzIGlzIGlmIHRyZWUgaXMgZW1wdHlcbiAgICAgICAgICAgIHRoaXMuZGF0YSA9IG5vZGU7XG5cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmRhdGEuaGVpZ2h0ID09PSBub2RlLmhlaWdodCkge1xuICAgICAgICAgICAgLy8gc3BsaXQgcm9vdCBpZiB0cmVlcyBoYXZlIHRoZSBzYW1lIGhlaWdodFxuICAgICAgICAgICAgdGhpcy5fc3BsaXRSb290KHRoaXMuZGF0YSwgbm9kZSk7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGEuaGVpZ2h0IDwgbm9kZS5oZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAvLyBzd2FwIHRyZWVzIGlmIGluc2VydGVkIG9uZSBpcyBiaWdnZXJcbiAgICAgICAgICAgICAgICB2YXIgdG1wTm9kZSA9IHRoaXMuZGF0YTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEgPSBub2RlO1xuICAgICAgICAgICAgICAgIG5vZGUgPSB0bXBOb2RlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBpbnNlcnQgdGhlIHNtYWxsIHRyZWUgaW50byB0aGUgbGFyZ2UgdHJlZSBhdCBhcHByb3ByaWF0ZSBsZXZlbFxuICAgICAgICAgICAgdGhpcy5faW5zZXJ0KG5vZGUsIHRoaXMuZGF0YS5oZWlnaHQgLSBub2RlLmhlaWdodCAtIDEsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGluc2VydDogZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgaWYgKGl0ZW0pIHRoaXMuX2luc2VydChpdGVtLCB0aGlzLmRhdGEuaGVpZ2h0IC0gMSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBjbGVhcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmRhdGEgPSBjcmVhdGVOb2RlKFtdKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIHJlbW92ZTogZnVuY3Rpb24gKGl0ZW0sIGVxdWFsc0ZuKSB7XG4gICAgICAgIGlmICghaXRlbSkgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgdmFyIG5vZGUgPSB0aGlzLmRhdGEsXG4gICAgICAgICAgICBiYm94ID0gdGhpcy50b0JCb3goaXRlbSksXG4gICAgICAgICAgICBwYXRoID0gW10sXG4gICAgICAgICAgICBpbmRleGVzID0gW10sXG4gICAgICAgICAgICBpLCBwYXJlbnQsIGluZGV4LCBnb2luZ1VwO1xuXG4gICAgICAgIC8vIGRlcHRoLWZpcnN0IGl0ZXJhdGl2ZSB0cmVlIHRyYXZlcnNhbFxuICAgICAgICB3aGlsZSAobm9kZSB8fCBwYXRoLmxlbmd0aCkge1xuXG4gICAgICAgICAgICBpZiAoIW5vZGUpIHsgLy8gZ28gdXBcbiAgICAgICAgICAgICAgICBub2RlID0gcGF0aC5wb3AoKTtcbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXRoW3BhdGgubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgaSA9IGluZGV4ZXMucG9wKCk7XG4gICAgICAgICAgICAgICAgZ29pbmdVcCA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChub2RlLmxlYWYpIHsgLy8gY2hlY2sgY3VycmVudCBub2RlXG4gICAgICAgICAgICAgICAgaW5kZXggPSBmaW5kSXRlbShpdGVtLCBub2RlLmNoaWxkcmVuLCBlcXVhbHNGbik7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGl0ZW0gZm91bmQsIHJlbW92ZSB0aGUgaXRlbSBhbmQgY29uZGVuc2UgdHJlZSB1cHdhcmRzXG4gICAgICAgICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAgICAgcGF0aC5wdXNoKG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jb25kZW5zZShwYXRoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWdvaW5nVXAgJiYgIW5vZGUubGVhZiAmJiBjb250YWlucyhub2RlLCBiYm94KSkgeyAvLyBnbyBkb3duXG4gICAgICAgICAgICAgICAgcGF0aC5wdXNoKG5vZGUpO1xuICAgICAgICAgICAgICAgIGluZGV4ZXMucHVzaChpKTtcbiAgICAgICAgICAgICAgICBpID0gMDtcbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBub2RlO1xuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLmNoaWxkcmVuWzBdO1xuXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmVudCkgeyAvLyBnbyByaWdodFxuICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgICAgICBub2RlID0gcGFyZW50LmNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgICAgIGdvaW5nVXAgPSBmYWxzZTtcblxuICAgICAgICAgICAgfSBlbHNlIG5vZGUgPSBudWxsOyAvLyBub3RoaW5nIGZvdW5kXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgdG9CQm94OiBmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbTsgfSxcblxuICAgIGNvbXBhcmVNaW5YOiBjb21wYXJlTm9kZU1pblgsXG4gICAgY29tcGFyZU1pblk6IGNvbXBhcmVOb2RlTWluWSxcblxuICAgIHRvSlNPTjogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5kYXRhOyB9LFxuXG4gICAgZnJvbUpTT046IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBfYWxsOiBmdW5jdGlvbiAobm9kZSwgcmVzdWx0KSB7XG4gICAgICAgIHZhciBub2Rlc1RvU2VhcmNoID0gW107XG4gICAgICAgIHdoaWxlIChub2RlKSB7XG4gICAgICAgICAgICBpZiAobm9kZS5sZWFmKSByZXN1bHQucHVzaC5hcHBseShyZXN1bHQsIG5vZGUuY2hpbGRyZW4pO1xuICAgICAgICAgICAgZWxzZSBub2Rlc1RvU2VhcmNoLnB1c2guYXBwbHkobm9kZXNUb1NlYXJjaCwgbm9kZS5jaGlsZHJlbik7XG5cbiAgICAgICAgICAgIG5vZGUgPSBub2Rlc1RvU2VhcmNoLnBvcCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIF9idWlsZDogZnVuY3Rpb24gKGl0ZW1zLCBsZWZ0LCByaWdodCwgaGVpZ2h0KSB7XG5cbiAgICAgICAgdmFyIE4gPSByaWdodCAtIGxlZnQgKyAxLFxuICAgICAgICAgICAgTSA9IHRoaXMuX21heEVudHJpZXMsXG4gICAgICAgICAgICBub2RlO1xuXG4gICAgICAgIGlmIChOIDw9IE0pIHtcbiAgICAgICAgICAgIC8vIHJlYWNoZWQgbGVhZiBsZXZlbDsgcmV0dXJuIGxlYWZcbiAgICAgICAgICAgIG5vZGUgPSBjcmVhdGVOb2RlKGl0ZW1zLnNsaWNlKGxlZnQsIHJpZ2h0ICsgMSkpO1xuICAgICAgICAgICAgY2FsY0JCb3gobm9kZSwgdGhpcy50b0JCb3gpO1xuICAgICAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWhlaWdodCkge1xuICAgICAgICAgICAgLy8gdGFyZ2V0IGhlaWdodCBvZiB0aGUgYnVsay1sb2FkZWQgdHJlZVxuICAgICAgICAgICAgaGVpZ2h0ID0gTWF0aC5jZWlsKE1hdGgubG9nKE4pIC8gTWF0aC5sb2coTSkpO1xuXG4gICAgICAgICAgICAvLyB0YXJnZXQgbnVtYmVyIG9mIHJvb3QgZW50cmllcyB0byBtYXhpbWl6ZSBzdG9yYWdlIHV0aWxpemF0aW9uXG4gICAgICAgICAgICBNID0gTWF0aC5jZWlsKE4gLyBNYXRoLnBvdyhNLCBoZWlnaHQgLSAxKSk7XG4gICAgICAgIH1cblxuICAgICAgICBub2RlID0gY3JlYXRlTm9kZShbXSk7XG4gICAgICAgIG5vZGUubGVhZiA9IGZhbHNlO1xuICAgICAgICBub2RlLmhlaWdodCA9IGhlaWdodDtcblxuICAgICAgICAvLyBzcGxpdCB0aGUgaXRlbXMgaW50byBNIG1vc3RseSBzcXVhcmUgdGlsZXNcblxuICAgICAgICB2YXIgTjIgPSBNYXRoLmNlaWwoTiAvIE0pLFxuICAgICAgICAgICAgTjEgPSBOMiAqIE1hdGguY2VpbChNYXRoLnNxcnQoTSkpLFxuICAgICAgICAgICAgaSwgaiwgcmlnaHQyLCByaWdodDM7XG5cbiAgICAgICAgbXVsdGlTZWxlY3QoaXRlbXMsIGxlZnQsIHJpZ2h0LCBOMSwgdGhpcy5jb21wYXJlTWluWCk7XG5cbiAgICAgICAgZm9yIChpID0gbGVmdDsgaSA8PSByaWdodDsgaSArPSBOMSkge1xuXG4gICAgICAgICAgICByaWdodDIgPSBNYXRoLm1pbihpICsgTjEgLSAxLCByaWdodCk7XG5cbiAgICAgICAgICAgIG11bHRpU2VsZWN0KGl0ZW1zLCBpLCByaWdodDIsIE4yLCB0aGlzLmNvbXBhcmVNaW5ZKTtcblxuICAgICAgICAgICAgZm9yIChqID0gaTsgaiA8PSByaWdodDI7IGogKz0gTjIpIHtcblxuICAgICAgICAgICAgICAgIHJpZ2h0MyA9IE1hdGgubWluKGogKyBOMiAtIDEsIHJpZ2h0Mik7XG5cbiAgICAgICAgICAgICAgICAvLyBwYWNrIGVhY2ggZW50cnkgcmVjdXJzaXZlbHlcbiAgICAgICAgICAgICAgICBub2RlLmNoaWxkcmVuLnB1c2godGhpcy5fYnVpbGQoaXRlbXMsIGosIHJpZ2h0MywgaGVpZ2h0IC0gMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY2FsY0JCb3gobm9kZSwgdGhpcy50b0JCb3gpO1xuXG4gICAgICAgIHJldHVybiBub2RlO1xuICAgIH0sXG5cbiAgICBfY2hvb3NlU3VidHJlZTogZnVuY3Rpb24gKGJib3gsIG5vZGUsIGxldmVsLCBwYXRoKSB7XG5cbiAgICAgICAgdmFyIGksIGxlbiwgY2hpbGQsIHRhcmdldE5vZGUsIGFyZWEsIGVubGFyZ2VtZW50LCBtaW5BcmVhLCBtaW5FbmxhcmdlbWVudDtcblxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgcGF0aC5wdXNoKG5vZGUpO1xuXG4gICAgICAgICAgICBpZiAobm9kZS5sZWFmIHx8IHBhdGgubGVuZ3RoIC0gMSA9PT0gbGV2ZWwpIGJyZWFrO1xuXG4gICAgICAgICAgICBtaW5BcmVhID0gbWluRW5sYXJnZW1lbnQgPSBJbmZpbml0eTtcblxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGNoaWxkID0gbm9kZS5jaGlsZHJlbltpXTtcbiAgICAgICAgICAgICAgICBhcmVhID0gYmJveEFyZWEoY2hpbGQpO1xuICAgICAgICAgICAgICAgIGVubGFyZ2VtZW50ID0gZW5sYXJnZWRBcmVhKGJib3gsIGNoaWxkKSAtIGFyZWE7XG5cbiAgICAgICAgICAgICAgICAvLyBjaG9vc2UgZW50cnkgd2l0aCB0aGUgbGVhc3QgYXJlYSBlbmxhcmdlbWVudFxuICAgICAgICAgICAgICAgIGlmIChlbmxhcmdlbWVudCA8IG1pbkVubGFyZ2VtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIG1pbkVubGFyZ2VtZW50ID0gZW5sYXJnZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIG1pbkFyZWEgPSBhcmVhIDwgbWluQXJlYSA/IGFyZWEgOiBtaW5BcmVhO1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXROb2RlID0gY2hpbGQ7XG5cbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVubGFyZ2VtZW50ID09PSBtaW5FbmxhcmdlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UgY2hvb3NlIG9uZSB3aXRoIHRoZSBzbWFsbGVzdCBhcmVhXG4gICAgICAgICAgICAgICAgICAgIGlmIChhcmVhIDwgbWluQXJlYSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWluQXJlYSA9IGFyZWE7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXROb2RlID0gY2hpbGQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG5vZGUgPSB0YXJnZXROb2RlIHx8IG5vZGUuY2hpbGRyZW5bMF07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICB9LFxuXG4gICAgX2luc2VydDogZnVuY3Rpb24gKGl0ZW0sIGxldmVsLCBpc05vZGUpIHtcblxuICAgICAgICB2YXIgdG9CQm94ID0gdGhpcy50b0JCb3gsXG4gICAgICAgICAgICBiYm94ID0gaXNOb2RlID8gaXRlbSA6IHRvQkJveChpdGVtKSxcbiAgICAgICAgICAgIGluc2VydFBhdGggPSBbXTtcblxuICAgICAgICAvLyBmaW5kIHRoZSBiZXN0IG5vZGUgZm9yIGFjY29tbW9kYXRpbmcgdGhlIGl0ZW0sIHNhdmluZyBhbGwgbm9kZXMgYWxvbmcgdGhlIHBhdGggdG9vXG4gICAgICAgIHZhciBub2RlID0gdGhpcy5fY2hvb3NlU3VidHJlZShiYm94LCB0aGlzLmRhdGEsIGxldmVsLCBpbnNlcnRQYXRoKTtcblxuICAgICAgICAvLyBwdXQgdGhlIGl0ZW0gaW50byB0aGUgbm9kZVxuICAgICAgICBub2RlLmNoaWxkcmVuLnB1c2goaXRlbSk7XG4gICAgICAgIGV4dGVuZChub2RlLCBiYm94KTtcblxuICAgICAgICAvLyBzcGxpdCBvbiBub2RlIG92ZXJmbG93OyBwcm9wYWdhdGUgdXB3YXJkcyBpZiBuZWNlc3NhcnlcbiAgICAgICAgd2hpbGUgKGxldmVsID49IDApIHtcbiAgICAgICAgICAgIGlmIChpbnNlcnRQYXRoW2xldmVsXS5jaGlsZHJlbi5sZW5ndGggPiB0aGlzLl9tYXhFbnRyaWVzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3BsaXQoaW5zZXJ0UGF0aCwgbGV2ZWwpO1xuICAgICAgICAgICAgICAgIGxldmVsLS07XG4gICAgICAgICAgICB9IGVsc2UgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGp1c3QgYmJveGVzIGFsb25nIHRoZSBpbnNlcnRpb24gcGF0aFxuICAgICAgICB0aGlzLl9hZGp1c3RQYXJlbnRCQm94ZXMoYmJveCwgaW5zZXJ0UGF0aCwgbGV2ZWwpO1xuICAgIH0sXG5cbiAgICAvLyBzcGxpdCBvdmVyZmxvd2VkIG5vZGUgaW50byB0d29cbiAgICBfc3BsaXQ6IGZ1bmN0aW9uIChpbnNlcnRQYXRoLCBsZXZlbCkge1xuXG4gICAgICAgIHZhciBub2RlID0gaW5zZXJ0UGF0aFtsZXZlbF0sXG4gICAgICAgICAgICBNID0gbm9kZS5jaGlsZHJlbi5sZW5ndGgsXG4gICAgICAgICAgICBtID0gdGhpcy5fbWluRW50cmllcztcblxuICAgICAgICB0aGlzLl9jaG9vc2VTcGxpdEF4aXMobm9kZSwgbSwgTSk7XG5cbiAgICAgICAgdmFyIHNwbGl0SW5kZXggPSB0aGlzLl9jaG9vc2VTcGxpdEluZGV4KG5vZGUsIG0sIE0pO1xuXG4gICAgICAgIHZhciBuZXdOb2RlID0gY3JlYXRlTm9kZShub2RlLmNoaWxkcmVuLnNwbGljZShzcGxpdEluZGV4LCBub2RlLmNoaWxkcmVuLmxlbmd0aCAtIHNwbGl0SW5kZXgpKTtcbiAgICAgICAgbmV3Tm9kZS5oZWlnaHQgPSBub2RlLmhlaWdodDtcbiAgICAgICAgbmV3Tm9kZS5sZWFmID0gbm9kZS5sZWFmO1xuXG4gICAgICAgIGNhbGNCQm94KG5vZGUsIHRoaXMudG9CQm94KTtcbiAgICAgICAgY2FsY0JCb3gobmV3Tm9kZSwgdGhpcy50b0JCb3gpO1xuXG4gICAgICAgIGlmIChsZXZlbCkgaW5zZXJ0UGF0aFtsZXZlbCAtIDFdLmNoaWxkcmVuLnB1c2gobmV3Tm9kZSk7XG4gICAgICAgIGVsc2UgdGhpcy5fc3BsaXRSb290KG5vZGUsIG5ld05vZGUpO1xuICAgIH0sXG5cbiAgICBfc3BsaXRSb290OiBmdW5jdGlvbiAobm9kZSwgbmV3Tm9kZSkge1xuICAgICAgICAvLyBzcGxpdCByb290IG5vZGVcbiAgICAgICAgdGhpcy5kYXRhID0gY3JlYXRlTm9kZShbbm9kZSwgbmV3Tm9kZV0pO1xuICAgICAgICB0aGlzLmRhdGEuaGVpZ2h0ID0gbm9kZS5oZWlnaHQgKyAxO1xuICAgICAgICB0aGlzLmRhdGEubGVhZiA9IGZhbHNlO1xuICAgICAgICBjYWxjQkJveCh0aGlzLmRhdGEsIHRoaXMudG9CQm94KTtcbiAgICB9LFxuXG4gICAgX2Nob29zZVNwbGl0SW5kZXg6IGZ1bmN0aW9uIChub2RlLCBtLCBNKSB7XG5cbiAgICAgICAgdmFyIGksIGJib3gxLCBiYm94Miwgb3ZlcmxhcCwgYXJlYSwgbWluT3ZlcmxhcCwgbWluQXJlYSwgaW5kZXg7XG5cbiAgICAgICAgbWluT3ZlcmxhcCA9IG1pbkFyZWEgPSBJbmZpbml0eTtcblxuICAgICAgICBmb3IgKGkgPSBtOyBpIDw9IE0gLSBtOyBpKyspIHtcbiAgICAgICAgICAgIGJib3gxID0gZGlzdEJCb3gobm9kZSwgMCwgaSwgdGhpcy50b0JCb3gpO1xuICAgICAgICAgICAgYmJveDIgPSBkaXN0QkJveChub2RlLCBpLCBNLCB0aGlzLnRvQkJveCk7XG5cbiAgICAgICAgICAgIG92ZXJsYXAgPSBpbnRlcnNlY3Rpb25BcmVhKGJib3gxLCBiYm94Mik7XG4gICAgICAgICAgICBhcmVhID0gYmJveEFyZWEoYmJveDEpICsgYmJveEFyZWEoYmJveDIpO1xuXG4gICAgICAgICAgICAvLyBjaG9vc2UgZGlzdHJpYnV0aW9uIHdpdGggbWluaW11bSBvdmVybGFwXG4gICAgICAgICAgICBpZiAob3ZlcmxhcCA8IG1pbk92ZXJsYXApIHtcbiAgICAgICAgICAgICAgICBtaW5PdmVybGFwID0gb3ZlcmxhcDtcbiAgICAgICAgICAgICAgICBpbmRleCA9IGk7XG5cbiAgICAgICAgICAgICAgICBtaW5BcmVhID0gYXJlYSA8IG1pbkFyZWEgPyBhcmVhIDogbWluQXJlYTtcblxuICAgICAgICAgICAgfSBlbHNlIGlmIChvdmVybGFwID09PSBtaW5PdmVybGFwKSB7XG4gICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGNob29zZSBkaXN0cmlidXRpb24gd2l0aCBtaW5pbXVtIGFyZWFcbiAgICAgICAgICAgICAgICBpZiAoYXJlYSA8IG1pbkFyZWEpIHtcbiAgICAgICAgICAgICAgICAgICAgbWluQXJlYSA9IGFyZWE7XG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgfSxcblxuICAgIC8vIHNvcnRzIG5vZGUgY2hpbGRyZW4gYnkgdGhlIGJlc3QgYXhpcyBmb3Igc3BsaXRcbiAgICBfY2hvb3NlU3BsaXRBeGlzOiBmdW5jdGlvbiAobm9kZSwgbSwgTSkge1xuXG4gICAgICAgIHZhciBjb21wYXJlTWluWCA9IG5vZGUubGVhZiA/IHRoaXMuY29tcGFyZU1pblggOiBjb21wYXJlTm9kZU1pblgsXG4gICAgICAgICAgICBjb21wYXJlTWluWSA9IG5vZGUubGVhZiA/IHRoaXMuY29tcGFyZU1pblkgOiBjb21wYXJlTm9kZU1pblksXG4gICAgICAgICAgICB4TWFyZ2luID0gdGhpcy5fYWxsRGlzdE1hcmdpbihub2RlLCBtLCBNLCBjb21wYXJlTWluWCksXG4gICAgICAgICAgICB5TWFyZ2luID0gdGhpcy5fYWxsRGlzdE1hcmdpbihub2RlLCBtLCBNLCBjb21wYXJlTWluWSk7XG5cbiAgICAgICAgLy8gaWYgdG90YWwgZGlzdHJpYnV0aW9ucyBtYXJnaW4gdmFsdWUgaXMgbWluaW1hbCBmb3IgeCwgc29ydCBieSBtaW5YLFxuICAgICAgICAvLyBvdGhlcndpc2UgaXQncyBhbHJlYWR5IHNvcnRlZCBieSBtaW5ZXG4gICAgICAgIGlmICh4TWFyZ2luIDwgeU1hcmdpbikgbm9kZS5jaGlsZHJlbi5zb3J0KGNvbXBhcmVNaW5YKTtcbiAgICB9LFxuXG4gICAgLy8gdG90YWwgbWFyZ2luIG9mIGFsbCBwb3NzaWJsZSBzcGxpdCBkaXN0cmlidXRpb25zIHdoZXJlIGVhY2ggbm9kZSBpcyBhdCBsZWFzdCBtIGZ1bGxcbiAgICBfYWxsRGlzdE1hcmdpbjogZnVuY3Rpb24gKG5vZGUsIG0sIE0sIGNvbXBhcmUpIHtcblxuICAgICAgICBub2RlLmNoaWxkcmVuLnNvcnQoY29tcGFyZSk7XG5cbiAgICAgICAgdmFyIHRvQkJveCA9IHRoaXMudG9CQm94LFxuICAgICAgICAgICAgbGVmdEJCb3ggPSBkaXN0QkJveChub2RlLCAwLCBtLCB0b0JCb3gpLFxuICAgICAgICAgICAgcmlnaHRCQm94ID0gZGlzdEJCb3gobm9kZSwgTSAtIG0sIE0sIHRvQkJveCksXG4gICAgICAgICAgICBtYXJnaW4gPSBiYm94TWFyZ2luKGxlZnRCQm94KSArIGJib3hNYXJnaW4ocmlnaHRCQm94KSxcbiAgICAgICAgICAgIGksIGNoaWxkO1xuXG4gICAgICAgIGZvciAoaSA9IG07IGkgPCBNIC0gbTsgaSsrKSB7XG4gICAgICAgICAgICBjaGlsZCA9IG5vZGUuY2hpbGRyZW5baV07XG4gICAgICAgICAgICBleHRlbmQobGVmdEJCb3gsIG5vZGUubGVhZiA/IHRvQkJveChjaGlsZCkgOiBjaGlsZCk7XG4gICAgICAgICAgICBtYXJnaW4gKz0gYmJveE1hcmdpbihsZWZ0QkJveCk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGkgPSBNIC0gbSAtIDE7IGkgPj0gbTsgaS0tKSB7XG4gICAgICAgICAgICBjaGlsZCA9IG5vZGUuY2hpbGRyZW5baV07XG4gICAgICAgICAgICBleHRlbmQocmlnaHRCQm94LCBub2RlLmxlYWYgPyB0b0JCb3goY2hpbGQpIDogY2hpbGQpO1xuICAgICAgICAgICAgbWFyZ2luICs9IGJib3hNYXJnaW4ocmlnaHRCQm94KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtYXJnaW47XG4gICAgfSxcblxuICAgIF9hZGp1c3RQYXJlbnRCQm94ZXM6IGZ1bmN0aW9uIChiYm94LCBwYXRoLCBsZXZlbCkge1xuICAgICAgICAvLyBhZGp1c3QgYmJveGVzIGFsb25nIHRoZSBnaXZlbiB0cmVlIHBhdGhcbiAgICAgICAgZm9yICh2YXIgaSA9IGxldmVsOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgZXh0ZW5kKHBhdGhbaV0sIGJib3gpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIF9jb25kZW5zZTogZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgLy8gZ28gdGhyb3VnaCB0aGUgcGF0aCwgcmVtb3ZpbmcgZW1wdHkgbm9kZXMgYW5kIHVwZGF0aW5nIGJib3hlc1xuICAgICAgICBmb3IgKHZhciBpID0gcGF0aC5sZW5ndGggLSAxLCBzaWJsaW5nczsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGlmIChwYXRoW2ldLmNoaWxkcmVuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBzaWJsaW5ncyA9IHBhdGhbaSAtIDFdLmNoaWxkcmVuO1xuICAgICAgICAgICAgICAgICAgICBzaWJsaW5ncy5zcGxpY2Uoc2libGluZ3MuaW5kZXhPZihwYXRoW2ldKSwgMSk7XG5cbiAgICAgICAgICAgICAgICB9IGVsc2UgdGhpcy5jbGVhcigpO1xuXG4gICAgICAgICAgICB9IGVsc2UgY2FsY0JCb3gocGF0aFtpXSwgdGhpcy50b0JCb3gpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIF9pbml0Rm9ybWF0OiBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gICAgICAgIC8vIGRhdGEgZm9ybWF0IChtaW5YLCBtaW5ZLCBtYXhYLCBtYXhZIGFjY2Vzc29ycylcblxuICAgICAgICAvLyB1c2VzIGV2YWwtdHlwZSBmdW5jdGlvbiBjb21waWxhdGlvbiBpbnN0ZWFkIG9mIGp1c3QgYWNjZXB0aW5nIGEgdG9CQm94IGZ1bmN0aW9uXG4gICAgICAgIC8vIGJlY2F1c2UgdGhlIGFsZ29yaXRobXMgYXJlIHZlcnkgc2Vuc2l0aXZlIHRvIHNvcnRpbmcgZnVuY3Rpb25zIHBlcmZvcm1hbmNlLFxuICAgICAgICAvLyBzbyB0aGV5IHNob3VsZCBiZSBkZWFkIHNpbXBsZSBhbmQgd2l0aG91dCBpbm5lciBjYWxsc1xuXG4gICAgICAgIHZhciBjb21wYXJlQXJyID0gWydyZXR1cm4gYScsICcgLSBiJywgJzsnXTtcblxuICAgICAgICB0aGlzLmNvbXBhcmVNaW5YID0gbmV3IEZ1bmN0aW9uKCdhJywgJ2InLCBjb21wYXJlQXJyLmpvaW4oZm9ybWF0WzBdKSk7XG4gICAgICAgIHRoaXMuY29tcGFyZU1pblkgPSBuZXcgRnVuY3Rpb24oJ2EnLCAnYicsIGNvbXBhcmVBcnIuam9pbihmb3JtYXRbMV0pKTtcblxuICAgICAgICB0aGlzLnRvQkJveCA9IG5ldyBGdW5jdGlvbignYScsXG4gICAgICAgICAgICAncmV0dXJuIHttaW5YOiBhJyArIGZvcm1hdFswXSArXG4gICAgICAgICAgICAnLCBtaW5ZOiBhJyArIGZvcm1hdFsxXSArXG4gICAgICAgICAgICAnLCBtYXhYOiBhJyArIGZvcm1hdFsyXSArXG4gICAgICAgICAgICAnLCBtYXhZOiBhJyArIGZvcm1hdFszXSArICd9OycpO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIGZpbmRJdGVtKGl0ZW0sIGl0ZW1zLCBlcXVhbHNGbikge1xuICAgIGlmICghZXF1YWxzRm4pIHJldHVybiBpdGVtcy5pbmRleE9mKGl0ZW0pO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoZXF1YWxzRm4oaXRlbSwgaXRlbXNbaV0pKSByZXR1cm4gaTtcbiAgICB9XG4gICAgcmV0dXJuIC0xO1xufVxuXG4vLyBjYWxjdWxhdGUgbm9kZSdzIGJib3ggZnJvbSBiYm94ZXMgb2YgaXRzIGNoaWxkcmVuXG5mdW5jdGlvbiBjYWxjQkJveChub2RlLCB0b0JCb3gpIHtcbiAgICBkaXN0QkJveChub2RlLCAwLCBub2RlLmNoaWxkcmVuLmxlbmd0aCwgdG9CQm94LCBub2RlKTtcbn1cblxuLy8gbWluIGJvdW5kaW5nIHJlY3RhbmdsZSBvZiBub2RlIGNoaWxkcmVuIGZyb20gayB0byBwLTFcbmZ1bmN0aW9uIGRpc3RCQm94KG5vZGUsIGssIHAsIHRvQkJveCwgZGVzdE5vZGUpIHtcbiAgICBpZiAoIWRlc3ROb2RlKSBkZXN0Tm9kZSA9IGNyZWF0ZU5vZGUobnVsbCk7XG4gICAgZGVzdE5vZGUubWluWCA9IEluZmluaXR5O1xuICAgIGRlc3ROb2RlLm1pblkgPSBJbmZpbml0eTtcbiAgICBkZXN0Tm9kZS5tYXhYID0gLUluZmluaXR5O1xuICAgIGRlc3ROb2RlLm1heFkgPSAtSW5maW5pdHk7XG5cbiAgICBmb3IgKHZhciBpID0gaywgY2hpbGQ7IGkgPCBwOyBpKyspIHtcbiAgICAgICAgY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ldO1xuICAgICAgICBleHRlbmQoZGVzdE5vZGUsIG5vZGUubGVhZiA/IHRvQkJveChjaGlsZCkgOiBjaGlsZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRlc3ROb2RlO1xufVxuXG5mdW5jdGlvbiBleHRlbmQoYSwgYikge1xuICAgIGEubWluWCA9IE1hdGgubWluKGEubWluWCwgYi5taW5YKTtcbiAgICBhLm1pblkgPSBNYXRoLm1pbihhLm1pblksIGIubWluWSk7XG4gICAgYS5tYXhYID0gTWF0aC5tYXgoYS5tYXhYLCBiLm1heFgpO1xuICAgIGEubWF4WSA9IE1hdGgubWF4KGEubWF4WSwgYi5tYXhZKTtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gY29tcGFyZU5vZGVNaW5YKGEsIGIpIHsgcmV0dXJuIGEubWluWCAtIGIubWluWDsgfVxuZnVuY3Rpb24gY29tcGFyZU5vZGVNaW5ZKGEsIGIpIHsgcmV0dXJuIGEubWluWSAtIGIubWluWTsgfVxuXG5mdW5jdGlvbiBiYm94QXJlYShhKSAgIHsgcmV0dXJuIChhLm1heFggLSBhLm1pblgpICogKGEubWF4WSAtIGEubWluWSk7IH1cbmZ1bmN0aW9uIGJib3hNYXJnaW4oYSkgeyByZXR1cm4gKGEubWF4WCAtIGEubWluWCkgKyAoYS5tYXhZIC0gYS5taW5ZKTsgfVxuXG5mdW5jdGlvbiBlbmxhcmdlZEFyZWEoYSwgYikge1xuICAgIHJldHVybiAoTWF0aC5tYXgoYi5tYXhYLCBhLm1heFgpIC0gTWF0aC5taW4oYi5taW5YLCBhLm1pblgpKSAqXG4gICAgICAgICAgIChNYXRoLm1heChiLm1heFksIGEubWF4WSkgLSBNYXRoLm1pbihiLm1pblksIGEubWluWSkpO1xufVxuXG5mdW5jdGlvbiBpbnRlcnNlY3Rpb25BcmVhKGEsIGIpIHtcbiAgICB2YXIgbWluWCA9IE1hdGgubWF4KGEubWluWCwgYi5taW5YKSxcbiAgICAgICAgbWluWSA9IE1hdGgubWF4KGEubWluWSwgYi5taW5ZKSxcbiAgICAgICAgbWF4WCA9IE1hdGgubWluKGEubWF4WCwgYi5tYXhYKSxcbiAgICAgICAgbWF4WSA9IE1hdGgubWluKGEubWF4WSwgYi5tYXhZKTtcblxuICAgIHJldHVybiBNYXRoLm1heCgwLCBtYXhYIC0gbWluWCkgKlxuICAgICAgICAgICBNYXRoLm1heCgwLCBtYXhZIC0gbWluWSk7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zKGEsIGIpIHtcbiAgICByZXR1cm4gYS5taW5YIDw9IGIubWluWCAmJlxuICAgICAgICAgICBhLm1pblkgPD0gYi5taW5ZICYmXG4gICAgICAgICAgIGIubWF4WCA8PSBhLm1heFggJiZcbiAgICAgICAgICAgYi5tYXhZIDw9IGEubWF4WTtcbn1cblxuZnVuY3Rpb24gaW50ZXJzZWN0cyhhLCBiKSB7XG4gICAgcmV0dXJuIGIubWluWCA8PSBhLm1heFggJiZcbiAgICAgICAgICAgYi5taW5ZIDw9IGEubWF4WSAmJlxuICAgICAgICAgICBiLm1heFggPj0gYS5taW5YICYmXG4gICAgICAgICAgIGIubWF4WSA+PSBhLm1pblk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU5vZGUoY2hpbGRyZW4pIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBjaGlsZHJlbjogY2hpbGRyZW4sXG4gICAgICAgIGhlaWdodDogMSxcbiAgICAgICAgbGVhZjogdHJ1ZSxcbiAgICAgICAgbWluWDogSW5maW5pdHksXG4gICAgICAgIG1pblk6IEluZmluaXR5LFxuICAgICAgICBtYXhYOiAtSW5maW5pdHksXG4gICAgICAgIG1heFk6IC1JbmZpbml0eVxuICAgIH07XG59XG5cbi8vIHNvcnQgYW4gYXJyYXkgc28gdGhhdCBpdGVtcyBjb21lIGluIGdyb3VwcyBvZiBuIHVuc29ydGVkIGl0ZW1zLCB3aXRoIGdyb3VwcyBzb3J0ZWQgYmV0d2VlbiBlYWNoIG90aGVyO1xuLy8gY29tYmluZXMgc2VsZWN0aW9uIGFsZ29yaXRobSB3aXRoIGJpbmFyeSBkaXZpZGUgJiBjb25xdWVyIGFwcHJvYWNoXG5cbmZ1bmN0aW9uIG11bHRpU2VsZWN0KGFyciwgbGVmdCwgcmlnaHQsIG4sIGNvbXBhcmUpIHtcbiAgICB2YXIgc3RhY2sgPSBbbGVmdCwgcmlnaHRdLFxuICAgICAgICBtaWQ7XG5cbiAgICB3aGlsZSAoc3RhY2subGVuZ3RoKSB7XG4gICAgICAgIHJpZ2h0ID0gc3RhY2sucG9wKCk7XG4gICAgICAgIGxlZnQgPSBzdGFjay5wb3AoKTtcblxuICAgICAgICBpZiAocmlnaHQgLSBsZWZ0IDw9IG4pIGNvbnRpbnVlO1xuXG4gICAgICAgIG1pZCA9IGxlZnQgKyBNYXRoLmNlaWwoKHJpZ2h0IC0gbGVmdCkgLyBuIC8gMikgKiBuO1xuICAgICAgICBxdWlja3NlbGVjdChhcnIsIG1pZCwgbGVmdCwgcmlnaHQsIGNvbXBhcmUpO1xuXG4gICAgICAgIHN0YWNrLnB1c2gobGVmdCwgbWlkLCBtaWQsIHJpZ2h0KTtcbiAgICB9XG59XG4iXX0= | |
| require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"e2d":[function(require,module,exports){ | |
| (function webpackUniversalModuleDefinition(root, factory) { | |
| if(typeof exports === 'object' && typeof module === 'object') | |
| module.exports = factory(); | |
| else if(typeof define === 'function' && define.amd) | |
| define([], factory); | |
| else if(typeof exports === 'object') | |
| exports["e2d"] = factory(); | |
| else | |
| root["e2d"] = factory(); | |
| })(this, function() { | |
| return /******/ (function(modules) { // webpackBootstrap | |
| /******/ // The module cache | |
| /******/ var installedModules = {}; | |
| /******/ // The require function | |
| /******/ function __webpack_require__(moduleId) { | |
| /******/ // Check if module is in cache | |
| /******/ if(installedModules[moduleId]) | |
| /******/ return installedModules[moduleId].exports; | |
| /******/ // Create a new module (and put it into the cache) | |
| /******/ var module = installedModules[moduleId] = { | |
| /******/ i: moduleId, | |
| /******/ l: false, | |
| /******/ exports: {} | |
| /******/ }; | |
| /******/ // Execute the module function | |
| /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | |
| /******/ // Flag the module as loaded | |
| /******/ module.l = true; | |
| /******/ // Return the exports of the module | |
| /******/ return module.exports; | |
| /******/ } | |
| /******/ // expose the modules object (__webpack_modules__) | |
| /******/ __webpack_require__.m = modules; | |
| /******/ // expose the module cache | |
| /******/ __webpack_require__.c = installedModules; | |
| /******/ // identity function for calling harmony imports with the correct context | |
| /******/ __webpack_require__.i = function(value) { return value; }; | |
| /******/ // define getter function for harmony exports | |
| /******/ __webpack_require__.d = function(exports, name, getter) { | |
| /******/ if(!__webpack_require__.o(exports, name)) { | |
| /******/ Object.defineProperty(exports, name, { | |
| /******/ configurable: false, | |
| /******/ enumerable: true, | |
| /******/ get: getter | |
| /******/ }); | |
| /******/ } | |
| /******/ }; | |
| /******/ // getDefaultExport function for compatibility with non-harmony modules | |
| /******/ __webpack_require__.n = function(module) { | |
| /******/ var getter = module && module.__esModule ? | |
| /******/ function getDefault() { return module['default']; } : | |
| /******/ function getModuleExports() { return module; }; | |
| /******/ __webpack_require__.d(getter, 'a', getter); | |
| /******/ return getter; | |
| /******/ }; | |
| /******/ // Object.prototype.hasOwnProperty.call | |
| /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | |
| /******/ // __webpack_public_path__ | |
| /******/ __webpack_require__.p = ""; | |
| /******/ // Load entry module and return exports | |
| /******/ return __webpack_require__(__webpack_require__.s = 58); | |
| /******/ }) | |
| /************************************************************************/ | |
| /******/ ([ | |
| /* 0 */ | |
| /***/ function(module, exports) { | |
| class Instruction { | |
| constructor(type, props) { | |
| this.type = type; | |
| this.props = props; | |
| return Object.seal(this); | |
| } | |
| } | |
| Object.seal(Instruction); | |
| Object.seal(Instruction.prototype); | |
| module.exports = Instruction; | |
| /***/ }, | |
| /* 1 */ | |
| /***/ function(module, exports) { | |
| let transformPoints = (points, matrix) => { | |
| let result = [], | |
| x, y; | |
| for(let i = 0; i < points.length; i++) { | |
| [x, y] = points[i]; | |
| result.push([ | |
| matrix[0] * x + matrix[2] * y + matrix[4], | |
| matrix[1] * x + matrix[3] * y + matrix[5] | |
| ]); | |
| } | |
| return result; | |
| }; | |
| module.exports = transformPoints; | |
| /***/ }, | |
| /* 2 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0), | |
| cache = new Instruction('beginPath'); | |
| let beginPath = () => cache; | |
| module.exports = beginPath; | |
| /***/ }, | |
| /* 3 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let cache = new Instruction('closePath'); | |
| let closePath = () => cache; | |
| module.exports = closePath; | |
| /***/ }, | |
| /* 4 */ | |
| /***/ function(module, exports) { | |
| let cycleMouseData = (ctx) => { | |
| let mouseData = ctx.canvas[Symbol.for('mouseData')]; | |
| if (mouseData) { | |
| mouseData.dx = mouseData.x - mouseData.previousX; | |
| mouseData.dy = mouseData.y - mouseData.previousY; | |
| mouseData.previousX = mouseData.x; | |
| mouseData.previousY = mouseData.y; | |
| mouseData.clicked = 0; | |
| } | |
| }; | |
| module.exports = cycleMouseData; | |
| /***/ }, | |
| /* 5 */ | |
| /***/ function(module, exports) { | |
| let det = 0; | |
| let invertMatrix = ([a, b, c, d, e, f]) => ( | |
| det = 1 / (a * d - c * b), | |
| [ | |
| d * det, | |
| -c * det, | |
| -b * det, | |
| a * det, | |
| (b * f - e * d) * det, | |
| (e * b - a * f) * det | |
| ] | |
| ); | |
| module.exports = invertMatrix; | |
| /***/ }, | |
| /* 6 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let lineTo = (x, y) => new Instruction('lineTo', { x, y }); | |
| module.exports = lineTo; | |
| /***/ }, | |
| /* 7 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let moveTo = (x, y) => new Instruction('moveTo', { x, y }); | |
| module.exports = moveTo; | |
| /***/ }, | |
| /* 8 */ | |
| /***/ function(module, exports) { | |
| let pointInRect = ([px, py], [[x, y], [width, height]]) => px > x && py > y && px < width && py < height; | |
| module.exports = pointInRect; | |
| /***/ }, | |
| /* 9 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('restore'); | |
| let setTransform = (matrix, ...children) => [ | |
| new Instruction('setTransform', [ | |
| matrix[0], | |
| matrix[1], | |
| matrix[2], | |
| matrix[3], | |
| matrix[4], | |
| matrix[5] | |
| ]), | |
| children, | |
| end | |
| ]; | |
| module.exports = setTransform; | |
| /***/ }, | |
| /* 10 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let pointInPolygon = __webpack_require__(57); | |
| let transformPoints = __webpack_require__(1); | |
| let invertMatrix = __webpack_require__(5); | |
| let pointInRect = __webpack_require__(8); | |
| let matrix = new Float64Array(6); | |
| module.exports = (ctx) => { | |
| let regions = ctx.canvas[Symbol.for('regions')], | |
| mousePoints = ctx.canvas[Symbol.for('mousePoints')], | |
| mouseData = ctx.canvas[Symbol.for('mouseData')], | |
| results = {}; | |
| //the mouse might have held still, add the current mouse position | |
| if (mousePoints.length === 0) { | |
| mousePoints.push([mouseData.x, mouseData.y, mouseData.state]); | |
| } | |
| for(let region of regions) { | |
| //invert the region matrix and transform the mouse points | |
| let transformedMousePoints = transformPoints(mousePoints, invertMatrix(region.matrix)); | |
| //the mouse points are now relative to the mouse region | |
| if (!region.polygon) { | |
| for (let mousePoint of transformedMousePoints) { | |
| if (pointInRect(mousePoint, region.points)) { | |
| region.hover = true; | |
| region.clicked = !!mouseData.clicked; | |
| results[region.id] = region; | |
| break; | |
| } | |
| } | |
| continue; | |
| } | |
| //loop over each point until one is matched | |
| for(let mousePoint of transformedMousePoints) { | |
| if (pointInPolygon(mousePoint, region.points)) { | |
| region.hover = true; | |
| region.clicked = !!mouseData.clicked; | |
| results[region.id] = region; | |
| break; | |
| } | |
| } | |
| } | |
| return results; | |
| }; | |
| /***/ }, | |
| /* 11 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0), | |
| pi2 = Math.PI * 2; | |
| let arc = (...args) => { | |
| let [x, y, r, startAngle, endAngle, counterclockwise] = args; | |
| let props = { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2, counterclockwise: false }; | |
| if (args.length > 3) { | |
| props.startAngle = startAngle; | |
| props.endAngle = endAngle; | |
| props.counterclockwise = !!counterclockwise; | |
| } | |
| if (args.length > 1){ | |
| props.x = x; | |
| props.y = y; | |
| props.r = r; | |
| } | |
| return new Instruction("arc", props); | |
| }; | |
| module.exports = arc; | |
| /***/ }, | |
| /* 12 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let arcTo = (x1, y1, x2, y2, r) => new Instruction('arcTo', { x1, y1, x2, y2, r }); | |
| module.exports = arcTo; | |
| /***/ }, | |
| /* 13 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let bezierCurveTo = (cp1x, cp1y, cp2x, cp2y, x, y) => new Instruction('bezierCurveTo', { | |
| cp1x, | |
| cp1y, | |
| cp2x, | |
| cp2y, | |
| x, | |
| y | |
| }); | |
| module.exports = bezierCurveTo; | |
| /***/ }, | |
| /* 14 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let clearRect = (...args) => new Instruction('clearRect', | |
| args.length > 2 ? | |
| { x: args[0], y: args[1], width: args[2], height: args[3] } : | |
| { x: 0, y: 0, width: args[0], height: args[1] } | |
| ); | |
| module.exports = clearRect; | |
| /***/ }, | |
| /* 15 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let begin = new Instruction('beginClip'), | |
| performClip = new Instruction('clip'), | |
| end = new Instruction('endClip'); | |
| let clip = (path, ...children) => [ | |
| begin, | |
| path, | |
| performClip, | |
| children, | |
| end | |
| ]; | |
| module.exports = clip; | |
| /***/ }, | |
| /* 16 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let cache = new Instruction('clipPath'); | |
| let clipPath = () => cache; | |
| module.exports = clipPath; | |
| /***/ }, | |
| /* 17 */ | |
| /***/ function(module, exports) { | |
| let createRegularPolygon = (radius = 0, position = [0, 0], sides = 3) => { | |
| let polygon = []; | |
| for(let i = 0; i < sides; i++) { | |
| polygon.push([ | |
| position[0] + radius * Math.cos(Math.PI * 2 * i / sides), | |
| position[1] + radius * Math.sin(Math.PI * 2 * i / sides) | |
| ]); | |
| } | |
| return polygon; | |
| }; | |
| module.exports = createRegularPolygon; | |
| /***/ }, | |
| /* 18 */ | |
| /***/ function(module, exports) { | |
| let concat = [].concat; | |
| let createWrapper = (...args) => { | |
| for(let i = 0; i < args.length; i++) { | |
| //parse and flatten the arguments | |
| while (args[i] && args[i].constructor === Array) { | |
| args = concat.apply([], args).filter(Boolean); | |
| } | |
| if (!args[i]) { | |
| continue; | |
| } | |
| let { type } = args[i]; | |
| if (type === 'placeholder') { | |
| // i is set to the placeholder index now | |
| //now grab all the elements to the left of the placeHolder | |
| let left = args.splice(0, i); | |
| //remove the placeHolder from the array | |
| args.shift(); | |
| return (...children) => [left, children, args]; | |
| } | |
| } | |
| throw new Error('Could not find placeholder, did you forget the e2d.placeHolder() call?'); | |
| }; | |
| module.exports = concat; | |
| /***/ }, | |
| /* 19 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let drawImage = (...args) => { | |
| let [img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight] = args; | |
| if (args.length === 9) { | |
| return new Instruction('drawImageSource', { | |
| img, | |
| sx, | |
| sy, | |
| sWidth, | |
| sHeight, | |
| dx, | |
| dy, | |
| dWidth, | |
| dHeight | |
| }); | |
| } | |
| if (args.length >= 5) { | |
| return new Instruction('drawImageSize', { | |
| img, | |
| dx: sx, | |
| dy: sy, | |
| dWidth: sWidth, | |
| dHeight: sHeight | |
| }); | |
| } | |
| if (args.length >= 3) { | |
| return new Instruction('drawImage', { | |
| img, | |
| dx: sx, | |
| dy: sy | |
| }); | |
| } | |
| return new Instruction('drawImage', { | |
| img, | |
| dx: 0, | |
| dy: 0 | |
| }); | |
| }; | |
| module.exports = drawImage; | |
| /***/ }, | |
| /* 20 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0), | |
| pi2 = Math.PI * 2; | |
| let ellipse = (...args) => { | |
| let [x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise] = args; | |
| let props = { x: 0, y: 0, radiusX: x, radiusY: y, rotation: 0, startAngle: 0, endAngle: pi2, anticlockwise: false }; | |
| if (args.length > 5) { | |
| props.startAngle = startAngle; | |
| props.endAngle = endAngle; | |
| props.anticlockwise = !!anticlockwise; | |
| } | |
| if (args.length > 4) { | |
| props.rotation = rotation; | |
| } | |
| if (args.length > 2){ | |
| props.x = x; | |
| props.y = y; | |
| props.radiusX = radiusX; | |
| props.radiusY = radiusY; | |
| } | |
| return new Instruction("ellipse", props); | |
| }; | |
| module.exports = ellipse; | |
| /***/ }, | |
| /* 21 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let cache = new Instruction('fill'); | |
| let fill = () => cache; | |
| module.exports = fill; | |
| /***/ }, | |
| /* 22 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0), | |
| pi2 = Math.PI * 2; | |
| let fillArc = (...args) => { | |
| let [x, y, r, startAngle, endAngle, counterclockwise] = args; | |
| let props = { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2, counterclockwise: false }; | |
| if (args.length > 3) { | |
| props.startAngle = startAngle; | |
| props.endAngle = endAngle; | |
| props.counterclockwise = !!counterclockwise; | |
| } | |
| if (args.length >= 2) { | |
| props.x = x; | |
| props.y = y; | |
| props.r = r; | |
| } | |
| return new Instruction("fillArc", props); | |
| }; | |
| module.exports = fillArc; | |
| /***/ }, | |
| /* 23 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let fillRect = (...args) => new Instruction('fillRect', | |
| args.length > 2 ? | |
| { x: args[0], y: args[1], width: args[2], height: args[3] } : | |
| { x: 0, y: 0, width: args[0], height: args[1] } | |
| ); | |
| module.exports = fillRect; | |
| /***/ }, | |
| /* 24 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('endFillStyle'); | |
| let fillStyle = (value, ...children) => [ | |
| new Instruction('fillStyle', { value }), | |
| children, | |
| end | |
| ]; | |
| module.exports = fillStyle; | |
| /***/ }, | |
| /* 25 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let fillText = (...args) => { | |
| let [text, x, y, maxWidth] = args; | |
| if (args.length < 4) { | |
| maxWidth = null; | |
| } | |
| if (args.length < 3) { | |
| x = 0; | |
| y = 0; | |
| } | |
| return new Instruction('fillText', { text, x, y, maxWidth }); | |
| }; | |
| module.exports = fillText; | |
| /***/ }, | |
| /* 26 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('endGlobalAlpha'); | |
| let globalAlpha = (value, ...children) => [ | |
| new Instruction('globalAlpha', { value }), | |
| children, | |
| end | |
| ]; | |
| module.exports = globalAlpha; | |
| /***/ }, | |
| /* 27 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| var Instruction = __webpack_require__(0); | |
| let end = new Instruction('endGlobalCompositeOperation'); | |
| let globalCompositeOperation = (value, ...children) => [ | |
| new Instruction('globalCompositeOperation', { value }), | |
| children, | |
| end | |
| ]; | |
| module.exports = globalCompositeOperation; | |
| /***/ }, | |
| /* 28 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let hitRect = (id, ...args) => { | |
| let [x, y, width, height] = args; | |
| if (args.length <= 3) { | |
| width = x; | |
| height = y; | |
| x = 0; | |
| y = 0; | |
| } | |
| return new Instruction('hitRect', { | |
| id, | |
| points: [ | |
| [x, y], | |
| [x + width, y + height] | |
| ] | |
| }); | |
| }; | |
| module.exports = hitRect; | |
| /***/ }, | |
| /* 29 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let hitRegion = (id, points) => new Instruction('hitRegion', { id, points }); | |
| module.exports = hitRegion; | |
| /***/ }, | |
| /* 30 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('endImageSmoothingEnabled'); | |
| let imageSmoothingEnabled = (value, ...children) => [ | |
| new Instruction('imageSmoothingEnabled', { value }), | |
| children, | |
| end | |
| ]; | |
| module.exports = imageSmoothingEnabled; | |
| /***/ }, | |
| /* 31 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let keycode = __webpack_require__(56); | |
| module.exports = (ctx) => { | |
| let { canvas } = ctx; | |
| //mouseData | |
| canvas[Symbol.for('mouseData')] = { | |
| x: 0, | |
| y: 0, | |
| dx: 0, | |
| dy: 0, | |
| previousX: 0, | |
| previousY: 0, | |
| state: false, | |
| clicked: 0 | |
| }; | |
| let keys = canvas[Symbol.for('keyData')] = {}; | |
| for (let name in keycode.code) { | |
| if (keycode.code.hasOwnProperty(name)) { | |
| keys[name] = false; | |
| } | |
| } | |
| //mouse regions | |
| canvas[Symbol.for('regions')] = []; | |
| canvas[Symbol.for('mousePoints')] = []; | |
| //make the canvas receive touch and mouse events | |
| canvas.tabIndex = 1; | |
| let mouseMove = (evt) => { | |
| let { clientX, clientY } = evt; | |
| //get left and top coordinates | |
| let { left, top } = canvas.getBoundingClientRect(); | |
| let mouseData = canvas[Symbol.for('mouseData')]; | |
| let point = [clientX - left, clientY - top, mouseData.state]; | |
| mouseData.x = point[0]; | |
| mouseData.y = point[1]; | |
| let points = canvas[Symbol.for('mousePoints')]; | |
| points.push(point); | |
| //store the last 100 stored positions for hover detection | |
| if (points.length > 100) { | |
| points.splice(0, points.length - 100); | |
| } | |
| evt.preventDefault(); | |
| return false; | |
| }; | |
| canvas.addEventListener('mousemove', (evt) => mouseMove(evt)); | |
| canvas.addEventListener('mousedown', (evt) => { | |
| let { target } = evt; | |
| if (target === canvas) { | |
| let mouseData = canvas[Symbol.for('mouseData')]; | |
| if (!mouseData.state) { | |
| mouseData.clicked += 1; | |
| } | |
| mouseData.state = true; | |
| return mouseMove(evt); | |
| } | |
| }); | |
| canvas.addEventListener('mouseup', (evt) => { | |
| let mouseData = canvas[Symbol.for('mouseData')]; | |
| mouseData.state = false; | |
| return mouseMove(evt); | |
| }); | |
| canvas.addEventListener('keydown', (evt) => { | |
| canvas[Symbol.for('keyData')][keycode(evt.keyCode)] = true; | |
| evt.preventDefault(); | |
| return false; | |
| }); | |
| canvas.addEventListener('keyup', (evt) => { | |
| canvas[Symbol.for('keyData')][keycode(evt.keyCode)] = false; | |
| evt.preventDefault(); | |
| return false; | |
| }); | |
| }; | |
| /***/ }, | |
| /* 32 */ | |
| /***/ function(module, exports) { | |
| module.exports = (ctx) => ctx.canvas[Symbol.for('keyData')]; | |
| /***/ }, | |
| /* 33 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('endLineStyle'); | |
| let lineStyle = (value, ...children) => { | |
| value = value || {}; | |
| var result = { | |
| lineWidth: null, | |
| lineCap: null, | |
| lineJoin: null, | |
| miterLimit: null, | |
| lineDash: null, | |
| lineDashOffset: null | |
| }; | |
| if (typeof value.lineWidth !== 'undefined') { | |
| result.lineWidth = value.lineWidth; | |
| } | |
| if (typeof value.lineCap !== 'undefined') { | |
| result.lineCap = value.lineCap; | |
| } | |
| if (typeof value.lineJoin !== 'undefined') { | |
| result.lineJoin = value.lineJoin; | |
| } | |
| if (typeof value.miterLimit !== 'undefined') { | |
| result.miterLimit = value.miterLimit; | |
| } | |
| if (typeof value.lineDash !== 'undefined') { | |
| result.lineDash = value.lineDash || []; | |
| } | |
| if (typeof value.lineDashOffset !== 'undefined') { | |
| result.lineDashOffset = value.lineDashOffset; | |
| } | |
| return [ | |
| new Instruction('lineStyle', result), | |
| children, | |
| end | |
| ]; | |
| }; | |
| module.exports = lineStyle; | |
| /***/ }, | |
| /* 34 */ | |
| /***/ function(module, exports) { | |
| module.exports = (ctx) => ctx.canvas[Symbol.for('mouseData')]; | |
| /***/ }, | |
| /* 35 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let moveTo = __webpack_require__(7), lineTo = __webpack_require__(6); | |
| let moveToLineTo = (point, index) => index === 0 ? | |
| moveTo(point[0], point[1]) : | |
| lineTo(point[0], point[1]); | |
| module.exports = moveToLineTo; | |
| /***/ }, | |
| /* 36 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let beginPath = __webpack_require__(2)(), | |
| closePath = __webpack_require__(3)(); | |
| let path = (...children) => [ | |
| beginPath, | |
| children, | |
| closePath | |
| ]; | |
| module.exports = path; | |
| /***/ }, | |
| /* 37 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let cache = new Instruction('placeholder'); | |
| let placeHolder = () => cache; | |
| module.exports = placeHolder; | |
| /***/ }, | |
| /* 38 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let quadraticCurveTo = (cpx, cpy, x, y) => new Instruction('quadraticCurveTo', { | |
| cpx, | |
| cpy, | |
| x, | |
| y | |
| }); | |
| module.exports = quadraticCurveTo; | |
| /***/ }, | |
| /* 39 */ | |
| /***/ function(module, exports) { | |
| let raf = (func) => { | |
| requestAnimationFrame(() => raf(func)); | |
| return func(); | |
| }; | |
| module.exports = raf; | |
| /***/ }, | |
| /* 40 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let rect = (...args) => new Instruction('rect', | |
| args.length > 2 ? | |
| { x: args[0], y: args[1], width: args[2], height: args[3] } : | |
| { x: 0, y: 0, width: args[0], height: args[1] } | |
| ); | |
| module.exports = rect; | |
| /***/ }, | |
| /* 41 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| //initialize all the properties | |
| let identity = [1, 0, 0, 1, 0, 0], | |
| matrix = new Float64Array(identity), | |
| fillStyleStack = [], | |
| strokeStyleStack = [], | |
| lineStyleStack = [], | |
| textStyleStack = [], | |
| shadowStyleStack = [], | |
| globalCompositeOperationStack = [], | |
| globalAlphaStack = [], | |
| imageSmoothingEnabledStack = [], | |
| transformStack = new Float64Array(501 * 6), | |
| transformStackIndex = 6, | |
| concat = [].concat, | |
| supportsEllipse = false; | |
| if (typeof CanvasRenderingContext2D !== 'undefined') { | |
| supportsEllipse = CanvasRenderingContext2D.prototype.hasOwnProperty('ellipse'); | |
| } | |
| //transform points function | |
| const transformPoints = __webpack_require__(1); | |
| const cycleMouseData = __webpack_require__(4); | |
| const increaseTransformStackSize = () => { | |
| let cache = transformStack; | |
| transformStack = new Float64Array(transformStack.length + 600); //add 100 more | |
| transformStack.set(cache); | |
| return this; | |
| }; | |
| transformStack.set(identity); | |
| const PI2 = Math.PI * 2; | |
| let empty = (target) => target && target.splice(0, target.length); | |
| module.exports = (...args) => { | |
| let children = args.slice(0, -1), | |
| ctx = args[args.length - 1]; | |
| let regions = ctx.canvas[Symbol.for('regions')], | |
| mousePoints = ctx.canvas[Symbol.for('mousePoints')], | |
| extensions = ctx.canvas[Symbol.for('extensions')]; | |
| let cache; | |
| cycleMouseData(ctx); | |
| empty(regions); | |
| empty(mousePoints); | |
| let len = children.length; | |
| //flatten children during the loop process to save cpu | |
| for (let i = 0; i < len; i++) { | |
| let child = children[i]; | |
| //flattening algorithm | |
| if (child && child.constructor === Array) { | |
| children = concat.apply([], children); | |
| child = children[i]; | |
| //repeat as necessary | |
| while (child && child.constructor === Array) { | |
| children = concat.apply([], children); | |
| child = children[i]; | |
| } | |
| len = children.length; | |
| } | |
| //child must be truthy | |
| if (!child) { | |
| continue; | |
| } | |
| let { props, type } = child; | |
| if (type === 'transform') { | |
| //copy transformStack values to matrix | |
| matrix[0] = transformStack[transformStackIndex - 6]; | |
| matrix[1] = transformStack[transformStackIndex - 5]; | |
| matrix[2] = transformStack[transformStackIndex - 4]; | |
| matrix[3] = transformStack[transformStackIndex - 3]; | |
| matrix[4] = transformStack[transformStackIndex - 2]; | |
| matrix[5] = transformStack[transformStackIndex - 1]; | |
| //increase the index | |
| transformStackIndex += 6; | |
| if (transformStackIndex > transformStack.length) { | |
| increaseTransformStackSize(); | |
| } | |
| //perform the transform math | |
| transformStack[transformStackIndex - 6] = //d | |
| matrix[0] * props[0] + matrix[2] * props[1]; | |
| transformStack[transformStackIndex - 5] = //b | |
| matrix[1] * props[0] + matrix[3] * props[1]; | |
| transformStack[transformStackIndex - 4] = //c | |
| matrix[0] * props[2] + matrix[2] * props[3]; | |
| transformStack[transformStackIndex - 3] = //d | |
| matrix[1] * props[2] + matrix[3] * props[3]; | |
| transformStack[transformStackIndex - 2] = //e | |
| matrix[0] * props[4] + matrix[2] * props[5] + matrix[4]; | |
| transformStack[transformStackIndex - 1] = //f | |
| matrix[1] * props[4] + matrix[3] * props[5] + matrix[5]; | |
| //modify the ctx | |
| ctx.setTransform( | |
| transformStack[transformStackIndex - 6], | |
| transformStack[transformStackIndex - 5], | |
| transformStack[transformStackIndex - 4], | |
| transformStack[transformStackIndex - 3], | |
| transformStack[transformStackIndex - 2], | |
| transformStack[transformStackIndex - 1] | |
| ); | |
| continue; | |
| } | |
| if (type === 'setTransform') { | |
| transformStackIndex += 6; | |
| if (transformStackIndex > transformStack.length) { | |
| increaseTransformStackSize(); | |
| } | |
| transformStack[transformStackIndex - 6] = props[0];//a | |
| transformStack[transformStackIndex - 5] = props[1];//b | |
| transformStack[transformStackIndex - 4] = props[2];//c | |
| transformStack[transformStackIndex - 3] = props[3];//d | |
| transformStack[transformStackIndex - 2] = props[4];//e | |
| transformStack[transformStackIndex - 1] = props[5];//f | |
| ctx.setTransform(props[0], props[1], props[2], props[3], props[4], props[5]); | |
| continue; | |
| } | |
| if (type === 'scale') { | |
| matrix[0] = transformStack[transformStackIndex - 6]; | |
| matrix[1] = transformStack[transformStackIndex - 5]; | |
| matrix[2] = transformStack[transformStackIndex - 4]; | |
| matrix[3] = transformStack[transformStackIndex - 3]; | |
| matrix[4] = transformStack[transformStackIndex - 2]; | |
| matrix[5] = transformStack[transformStackIndex - 1]; | |
| transformStackIndex += 6; | |
| if (transformStackIndex > transformStack.length) { | |
| increaseTransformStackSize(); | |
| } | |
| transformStack[transformStackIndex - 6] = matrix[0] * props.x; //a | |
| transformStack[transformStackIndex - 5] = matrix[1] * props.x; //b | |
| transformStack[transformStackIndex - 4] = matrix[2] * props.y; //c | |
| transformStack[transformStackIndex - 3] = matrix[3] * props.y; //d | |
| transformStack[transformStackIndex - 2] = matrix[4]; //e | |
| transformStack[transformStackIndex - 1] = matrix[5]; //f | |
| ctx.setTransform( | |
| transformStack[transformStackIndex - 6], | |
| transformStack[transformStackIndex - 5], | |
| transformStack[transformStackIndex - 4], | |
| transformStack[transformStackIndex - 3], | |
| transformStack[transformStackIndex - 2], | |
| transformStack[transformStackIndex - 1] | |
| ); | |
| continue; | |
| } | |
| if (type === 'translate') { | |
| matrix[0] = transformStack[transformStackIndex - 6]; | |
| matrix[1] = transformStack[transformStackIndex - 5]; | |
| matrix[2] = transformStack[transformStackIndex - 4]; | |
| matrix[3] = transformStack[transformStackIndex - 3]; | |
| matrix[4] = transformStack[transformStackIndex - 2]; | |
| matrix[5] = transformStack[transformStackIndex - 1]; | |
| transformStackIndex += 6; | |
| if (transformStackIndex > transformStack.length) { | |
| increaseTransformStackSize(); | |
| } | |
| transformStack[transformStackIndex - 6] = matrix[0]; //a | |
| transformStack[transformStackIndex - 5] = matrix[1]; //b | |
| transformStack[transformStackIndex - 4] = matrix[2]; //c | |
| transformStack[transformStackIndex - 3] = matrix[3]; //d | |
| transformStack[transformStackIndex - 2] = matrix[4] + matrix[0] * props.x + matrix[2] * props.y; //e | |
| transformStack[transformStackIndex - 1] = matrix[5] + matrix[1] * props.x + matrix[3] * props.y; //f | |
| ctx.setTransform( | |
| transformStack[transformStackIndex - 6], | |
| transformStack[transformStackIndex - 5], | |
| transformStack[transformStackIndex - 4], | |
| transformStack[transformStackIndex - 3], | |
| transformStack[transformStackIndex - 2], | |
| transformStack[transformStackIndex - 1] | |
| ); | |
| continue; | |
| } | |
| if (type === 'rotate') { | |
| matrix[0] = transformStack[transformStackIndex - 6]; | |
| matrix[1] = transformStack[transformStackIndex - 5]; | |
| matrix[2] = transformStack[transformStackIndex - 4]; | |
| matrix[3] = transformStack[transformStackIndex - 3]; | |
| matrix[4] = transformStack[transformStackIndex - 2]; | |
| matrix[5] = transformStack[transformStackIndex - 1]; | |
| transformStackIndex += 6; | |
| if (transformStackIndex > transformStack.length) { | |
| increaseTransformStackSize(); | |
| } | |
| transformStack[transformStackIndex - 6] = | |
| matrix[0] * props.cos + matrix[2] * props.sin; //a | |
| transformStack[transformStackIndex - 5] = | |
| matrix[1] * props.cos + matrix[3] * props.sin; //b | |
| transformStack[transformStackIndex - 4] = | |
| matrix[0] * -props.sin + matrix[2] * props.cos; //c | |
| transformStack[transformStackIndex - 3] = | |
| matrix[1] * -props.sin + matrix[3] * props.cos; //d | |
| transformStack[transformStackIndex - 2] = matrix[4]; //e | |
| transformStack[transformStackIndex - 1] = matrix[5];//f | |
| ctx.setTransform( | |
| transformStack[transformStackIndex - 6], | |
| transformStack[transformStackIndex - 5], | |
| transformStack[transformStackIndex - 4], | |
| transformStack[transformStackIndex - 3], | |
| transformStack[transformStackIndex - 2], | |
| transformStack[transformStackIndex - 1] | |
| ); | |
| continue; | |
| } | |
| if (type === 'skewX') { | |
| matrix[0] = transformStack[transformStackIndex - 6]; | |
| matrix[1] = transformStack[transformStackIndex - 5]; | |
| matrix[2] = transformStack[transformStackIndex - 4]; | |
| matrix[3] = transformStack[transformStackIndex - 3]; | |
| matrix[4] = transformStack[transformStackIndex - 2]; | |
| matrix[5] = transformStack[transformStackIndex - 1]; | |
| transformStackIndex += 6; | |
| if (transformStackIndex > transformStack.length) { | |
| increaseTransformStackSize(); | |
| } | |
| transformStack[transformStackIndex - 6] = matrix[0]; //a | |
| transformStack[transformStackIndex - 5] = matrix[1]; //b | |
| transformStack[transformStackIndex - 4] = //c | |
| matrix[0] * props.x + matrix[2]; | |
| transformStack[transformStackIndex - 3] = //d | |
| matrix[1] * props.x + matrix[3]; | |
| transformStack[transformStackIndex - 2] = matrix[4]; //e | |
| transformStack[transformStackIndex - 1] = matrix[5]; //f | |
| ctx.setTransform( | |
| transformStack[transformStackIndex - 6], | |
| transformStack[transformStackIndex - 5], | |
| transformStack[transformStackIndex - 4], | |
| transformStack[transformStackIndex - 3], | |
| transformStack[transformStackIndex - 2], | |
| transformStack[transformStackIndex - 1] | |
| ); | |
| continue; | |
| } | |
| if (type === 'skewY') { | |
| matrix[0] = transformStack[transformStackIndex - 6]; | |
| matrix[1] = transformStack[transformStackIndex - 5]; | |
| matrix[2] = transformStack[transformStackIndex - 4]; | |
| matrix[3] = transformStack[transformStackIndex - 3]; | |
| matrix[4] = transformStack[transformStackIndex - 2]; | |
| matrix[5] = transformStack[transformStackIndex - 1]; | |
| transformStackIndex += 6; | |
| if (transformStackIndex > transformStack.length) { | |
| increaseTransformStackSize(); | |
| } | |
| transformStack[transformStackIndex - 6] = | |
| matrix[0] * 1 + matrix[2] * props.y; //a | |
| transformStack[transformStackIndex - 5] = | |
| matrix[1] * 1 + matrix[3] * props.y; //b | |
| transformStack[transformStackIndex - 4] = matrix[2]; //c | |
| transformStack[transformStackIndex - 3] = matrix[3]; //d | |
| transformStack[transformStackIndex - 2] = matrix[4]; //e | |
| transformStack[transformStackIndex - 1] = matrix[5]; //f | |
| ctx.setTransform( | |
| transformStack[transformStackIndex - 6], | |
| transformStack[transformStackIndex - 5], | |
| transformStack[transformStackIndex - 4], | |
| transformStack[transformStackIndex - 3], | |
| transformStack[transformStackIndex - 2], | |
| transformStack[transformStackIndex - 1] | |
| ); | |
| continue; | |
| } | |
| if (type === 'restore') { | |
| transformStackIndex -= 6; | |
| matrix[0] = transformStack[transformStackIndex - 6]; | |
| matrix[1] = transformStack[transformStackIndex - 5]; | |
| matrix[2] = transformStack[transformStackIndex - 4]; | |
| matrix[3] = transformStack[transformStackIndex - 3]; | |
| matrix[4] = transformStack[transformStackIndex - 2]; | |
| matrix[5] = transformStack[transformStackIndex - 1]; | |
| ctx.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); | |
| continue; | |
| } | |
| if (type === 'fillRect') { | |
| ctx.fillRect(props.x, props.y, props.width, props.height); | |
| continue; | |
| } | |
| if (type === 'strokeRect') { | |
| ctx.strokeRect(props.x, props.y, props.width, props.height); | |
| continue; | |
| } | |
| if (type === 'clearRect') { | |
| ctx.clearRect(props.x, props.y, props.width, props.height); | |
| continue; | |
| } | |
| if (type === 'rect') { | |
| ctx.rect(props.x, props.y, props.width, props.height); | |
| continue; | |
| } | |
| if (type === 'fillStyle') { | |
| fillStyleStack.push(ctx.fillStyle); | |
| ctx.fillStyle = props.value; | |
| continue; | |
| } | |
| if (type === 'strokeStyle') { | |
| strokeStyleStack.push(ctx.strokeStyle); | |
| ctx.strokeStyle = props.value; | |
| continue; | |
| } | |
| if (type === 'endFillStyle') { | |
| ctx.fillStyle = fillStyleStack.pop(); | |
| continue; | |
| } | |
| if (type === 'endStrokeStyle') { | |
| ctx.strokeStyle = strokeStyleStack.pop(); | |
| continue; | |
| } | |
| if (type === 'lineStyle') { | |
| lineStyleStack.push({ | |
| lineWidth: ctx.lineWidth, | |
| lineCap: ctx.lineCap, | |
| lineJoin: ctx.lineJoin, | |
| miterLimit: ctx.miterLimit, | |
| lineDash: ctx.getLineDash(), | |
| lineDashOffset: ctx.lineDashOffset | |
| }); | |
| if (props.lineWidth !== null) { | |
| ctx.lineWidth = props.lineWidth; | |
| } | |
| if (props.lineCap !== null) { | |
| ctx.lineCap = props.lineCap; | |
| } | |
| if (props.lineJoin !== null) { | |
| ctx.lineJoin = props.lineJoin; | |
| } | |
| if (props.miterLimit !== null) { | |
| ctx.miterLimit = props.miterLimit; | |
| } | |
| if (props.lineDash !== null) { | |
| ctx.setLineDash(props.lineDash); | |
| } | |
| if (props.lineDashOffset !== null) { | |
| ctx.lineDashOffset = props.lineDashOffset; | |
| } | |
| continue; | |
| } | |
| if (type === 'endLineStyle') { | |
| cache = lineStyleStack.pop(); | |
| ctx.lineWidth = cache.lineWidth; | |
| ctx.lineCap = cache.lineCap; | |
| ctx.lineJoin = cache.lineJoin; | |
| ctx.miterLimit = cache.miterLimit; | |
| ctx.setLineDash(cache.lineDash); | |
| ctx.lineDashOffset = cache.lineDashOffset; | |
| continue; | |
| } | |
| if (type === 'textStyle') { | |
| textStyleStack.push({ | |
| font: ctx.font, | |
| textAlign: ctx.textAlign, | |
| textBaseline: ctx.textBaseline, | |
| direction: ctx.direction | |
| }); | |
| if (props.font !== null) { | |
| ctx.font = props.font; | |
| } | |
| if (props.textAlign !== null) { | |
| ctx.textAlign = props.textAlign; | |
| } | |
| if (props.textBaseline !== null) { | |
| ctx.textBaseline = props.textBaseline; | |
| } | |
| if (props.direction !== null) { | |
| ctx.direction = props.direction; | |
| } | |
| continue; | |
| } | |
| if (type === 'endTextStyle') { | |
| cache = textStyleStack.pop(); | |
| ctx.font = cache.font; | |
| ctx.textAlign = cache.textAlign; | |
| ctx.textBaseline = cache.textBaseline; | |
| ctx.direction = cache.direction; | |
| continue; | |
| } | |
| if (type === 'shadowStyle') { | |
| shadowStyleStack.push({ | |
| shadowBlur: ctx.shadowBlur, | |
| shadowColor: ctx.shadowColor, | |
| shadowOffsetX: ctx.shadowOffsetX, | |
| shadowOffsetY: ctx.shadowOffsetY | |
| }); | |
| if (props.shadowBlur !== null) { | |
| ctx.shadowBlur = props.shadowBlur; | |
| } | |
| if (props.shadowColor !== null) { | |
| ctx.shadowColor = props.shadowColor; | |
| } | |
| if (props.shadowOffsetX !== null) { | |
| ctx.shadowOffsetX = props.shadowOffsetX; | |
| } | |
| if (props.shadowOffsetY !== null) { | |
| ctx.shadowOffsetY = props.shadowOffsetY; | |
| } | |
| continue; | |
| } | |
| if (type === 'endShadowStyle') { | |
| cache = shadowStyleStack.pop(); | |
| ctx.shadowBlur = cache.shadowBlur; | |
| ctx.shadowColor = cache.shadowColor; | |
| ctx.shadowOffsetX = cache.shadowOffsetX; | |
| ctx.shadowOffsetY = cache.shadowOffsetY; | |
| continue; | |
| } | |
| if (type === 'strokeText') { | |
| if (props.maxWidth) { | |
| ctx.strokeText(props.text, props.x, props.y, props.maxWidth); | |
| continue; | |
| } | |
| ctx.strokeText(props.text, props.x, props.y); | |
| continue; | |
| } | |
| if (type === 'fillText') { | |
| if (props.maxWidth) { | |
| ctx.fillText(props.text, props.x, props.y, props.maxWidth); | |
| continue; | |
| } | |
| ctx.fillText(props.text, props.x, props.y); | |
| continue; | |
| } | |
| if (type === 'drawImage') { | |
| ctx.drawImage(props.img, props.dx, props.dy); | |
| continue; | |
| } | |
| if (type === 'drawImageSize') { | |
| ctx.drawImage(props.img, props.dx, props.dy, props.dWidth, props.dHeight); | |
| continue; | |
| } | |
| if (type === 'drawImageSource') { | |
| ctx.drawImage(props.img, props.sx, props.sy, props.sWidth, props.sHeight, props.dx, props.dy, props.dWidth, props.dHeight); | |
| continue; | |
| } | |
| if (type === 'strokeArc') { | |
| ctx.beginPath(); | |
| ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, props.counterclockwise); | |
| ctx.closePath(); | |
| ctx.stroke(); | |
| continue; | |
| } | |
| if (type === 'fillArc') { | |
| ctx.beginPath(); | |
| ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, props.counterclockwise); | |
| ctx.closePath(); | |
| ctx.fill(); | |
| continue; | |
| } | |
| if (type === 'moveTo') { | |
| ctx.moveTo(props.x, props.y); | |
| continue; | |
| } | |
| if (type === 'lineTo') { | |
| ctx.lineTo(props.x, props.y); | |
| continue; | |
| } | |
| if (type === 'bezierCurveTo') { | |
| ctx.bezierCurveTo(props.cp1x, props.cp1y, props.cp2x, props.cp2y, props.x, props.y); | |
| continue; | |
| } | |
| if (type === 'quadraticCurveTo') { | |
| ctx.quadraticCurveTo(props.cpx, props.cpy, props.x, props.y); | |
| continue; | |
| } | |
| if (type === 'arc') { | |
| ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, props.counterclockwise); | |
| continue; | |
| } | |
| if (type === 'arcTo') { | |
| ctx.arcTo(props.x1, props.y1, props.x2, props.y2, props.r); | |
| continue; | |
| } | |
| if (type === 'ellipse') { | |
| //if the method is provided by the browser | |
| if (supportsEllipse) { | |
| ctx.ellipse( | |
| props.x, | |
| props.y, | |
| props.radiusX, | |
| props.radiusY, | |
| props.rotation, | |
| props.startAngle, | |
| props.endAngle, | |
| props.anticlockwise | |
| ); | |
| continue; | |
| } | |
| ctx.save(); | |
| ctx.translate(props.x, props.y); | |
| ctx.rotate(props.rotation); | |
| ctx.scale(props.radiusX, props.radiusY); | |
| ctx.arc(0, 0, 1, props.startAngle, props.endAngle, props.anticlockwise); | |
| ctx.restore(); | |
| continue; | |
| } | |
| if (type === 'globalCompositeOperation') { | |
| globalCompositeOperationStack.push(ctx.globalCompositeOperation); | |
| ctx.globalCompositeOperation = props.value; | |
| continue; | |
| } | |
| if (type === 'endGlobalCompositeOperation') { | |
| ctx.globalCompositeOperation = globalCompositeOperationStack.pop(); | |
| continue; | |
| } | |
| if (type === 'fill') { | |
| ctx.fill(); | |
| continue; | |
| } | |
| if (type === 'stroke') { | |
| ctx.stroke(); | |
| continue; | |
| } | |
| if (type === 'beginClip') { | |
| ctx.save(); | |
| ctx.beginPath(); | |
| continue; | |
| } | |
| if (type === 'clip') { | |
| ctx.clip(); | |
| continue; | |
| } | |
| if (type === 'endClip') { | |
| ctx.restore(); | |
| continue; | |
| } | |
| if (type === 'beginPath') { | |
| ctx.beginPath(); | |
| continue; | |
| } | |
| if (type === 'closePath') { | |
| ctx.closePath(); | |
| continue; | |
| } | |
| if (type === 'globalAlpha') { | |
| globalAlphaStack.push(ctx.globalAlpha); | |
| ctx.globalAlpha *= props.value; | |
| continue; | |
| } | |
| if (type === 'endGlobalAlpha') { | |
| ctx.globalAlpha = globalAlphaStack.pop(); | |
| continue; | |
| } | |
| if (type === 'hitRect' && regions) { | |
| cache = [ | |
| transformStack[transformStackIndex - 6], | |
| transformStack[transformStackIndex - 5], | |
| transformStack[transformStackIndex - 4], | |
| transformStack[transformStackIndex - 3], | |
| transformStack[transformStackIndex - 2], | |
| transformStack[transformStackIndex - 1] | |
| ]; | |
| regions.push({ | |
| id: props.id, | |
| points: props.points, | |
| matrix: cache, | |
| //rectangle! | |
| polygon: false, | |
| hover: false, | |
| touched: false, | |
| clicked: false | |
| }); | |
| } | |
| if (type === 'hitRegion' && regions) { | |
| cache = [ | |
| transformStack[transformStackIndex - 6], | |
| transformStack[transformStackIndex - 5], | |
| transformStack[transformStackIndex - 4], | |
| transformStack[transformStackIndex - 3], | |
| transformStack[transformStackIndex - 2], | |
| transformStack[transformStackIndex - 1] | |
| ]; | |
| regions.push({ | |
| id: props.id, | |
| points: props.points, | |
| matrix: cache, | |
| polygon: true, | |
| hover: false, | |
| touched: false, | |
| clicked: false | |
| }); | |
| continue; | |
| } | |
| if (type === 'imageSmoothingEnabled') { | |
| imageSmoothingEnabledStack.push(ctx.imageSmoothingEnabled); | |
| ctx.imageSmoothingEnabled = props.value; | |
| continue; | |
| } | |
| if (type === 'endImageSmoothingEnabled') { | |
| ctx.imageSmoothingEnabled = imageSmoothingEnabledStack.pop(); | |
| continue; | |
| } | |
| if (extensions && extensions[type]) { | |
| extensions[type](props, ctx); | |
| continue; | |
| } | |
| } | |
| }; | |
| /***/ }, | |
| /* 42 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let setTransform = __webpack_require__(9); | |
| let resetTransform = (...children) => setTransform([1, 0, 0, 1, 0, 0], children); | |
| module.exports = resetTransform; | |
| /***/ }, | |
| /* 43 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('restore'); | |
| let rotate = (r, ...children) => [ | |
| new Instruction('rotate', { cos: Math.cos(r), sin: Math.sin(r) }), | |
| children, | |
| end | |
| ]; | |
| module.exports = rotate; | |
| /***/ }, | |
| /* 44 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('restore'); | |
| let scale = (x, y, ...children) => { | |
| if (typeof y !== 'number') { | |
| children = [y].concat(children); | |
| y = x; | |
| } | |
| return [ | |
| new Instruction('scale', { x, y }), | |
| children, | |
| end | |
| ]; | |
| }; | |
| module.exports = scale; | |
| /***/ }, | |
| /* 45 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('endShadowStyle'); | |
| let shadowStyle = (value, ...children) => { | |
| value = value || {}; | |
| var result = { | |
| shadowBlur: null, | |
| shadowColor: null, | |
| shadowOffsetX: null, | |
| shadowOffsetY: null | |
| }; | |
| if (typeof value.shadowBlur !== 'undefined') { | |
| result.shadowBlur = value.shadowBlur; | |
| } | |
| if (typeof value.shadowColor !== 'undefined') { | |
| result.shadowColor = value.shadowColor; | |
| } | |
| if (typeof value.shadowOffsetX !== 'undefined') { | |
| result.shadowOffsetX = value.shadowOffsetX; | |
| } | |
| if (typeof value.direction !== 'undefined') { | |
| result.shadowOffsetY = value.shadowOffsetY; | |
| } | |
| return [ | |
| new Instruction('shadowStyle', value), | |
| children, | |
| end | |
| ]; | |
| }; | |
| module.exports = shadowStyle; | |
| /***/ }, | |
| /* 46 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('restore'); | |
| let skewX = (x, ...children) => [ | |
| new Instruction('skewX', { x: Math.tan(x) }), | |
| children, | |
| end | |
| ]; | |
| module.exports = skewX; | |
| /***/ }, | |
| /* 47 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('restore'); | |
| let skewY = (x, ...children) => [ | |
| new Instruction('skewY', { y: Math.tan(y) }), | |
| children, | |
| end | |
| ]; | |
| module.exports = skewY; | |
| /***/ }, | |
| /* 48 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let cache = new Instruction('stroke'); | |
| let stroke = () => cache; | |
| module.exports = stroke; | |
| /***/ }, | |
| /* 49 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0), | |
| pi2 = Math.PI * 2; | |
| let strokeArc = (...args) => { | |
| let [x, y, r, startAngle, endAngle, counterclockwise] = args; | |
| let props = { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2, counterclockwise: false }; | |
| if (args.length > 3) { | |
| props.startAngle = startAngle; | |
| props.endAngle = endAngle; | |
| props.counterclockwise = !!counterclockwise; | |
| } | |
| if (args.length > 1){ | |
| props.x = x; | |
| props.y = y; | |
| props.r = r; | |
| } | |
| return new Instruction("strokeArc", props); | |
| }; | |
| module.exports = strokeArc; | |
| /***/ }, | |
| /* 50 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let strokeRect = (...args) => new Instruction('strokeRect', | |
| args.length > 2 ? | |
| { x: args[0], y: args[1], width: args[2], height: args[3] } : | |
| { x: 0, y: 0, width: args[0], height: args[1] } | |
| ); | |
| module.exports = strokeRect; | |
| /***/ }, | |
| /* 51 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('endStrokeStyle'); | |
| let strokeStyle = (value, ...children) => [ | |
| new Instruction('strokeStyle', { value }), | |
| children, | |
| end | |
| ]; | |
| module.exports = strokeStyle; | |
| /***/ }, | |
| /* 52 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let strokeText = (...args) => { | |
| let [text, x, y, maxWidth] = args; | |
| if (args.length < 4) { | |
| maxWidth = null; | |
| } | |
| if (args.length < 3) { | |
| x = 0; | |
| y = 0; | |
| } | |
| return new Instruction('strokeText', { | |
| text, | |
| x, | |
| y, | |
| maxWidth | |
| }); | |
| }; | |
| module.exports = strokeText; | |
| /***/ }, | |
| /* 53 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('endTextStyle'); | |
| let textStyle = (value, ...children) => { | |
| value = value || {}; | |
| var result = { | |
| font: null, | |
| textAlign: null, | |
| textBaseline: null, | |
| direction: null | |
| }; | |
| if (typeof value.font !== 'undefined') { | |
| result.font = value.font; | |
| } | |
| if (typeof value.textAlign !== 'undefined') { | |
| result.textAlign = value.textAlign; | |
| } | |
| if (typeof value.textBaseline !== 'undefined') { | |
| result.textBaseline = value.textBaseline; | |
| } | |
| if (typeof value.direction !== 'undefined') { | |
| result.direction = value.direction; | |
| } | |
| return [ | |
| new Instruction('textStyle', result), | |
| children, | |
| end | |
| ]; | |
| }; | |
| module.exports = textStyle; | |
| /***/ }, | |
| /* 54 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('restore'); | |
| let transform = (values, ...children) => { | |
| return [ | |
| new Instruction('transform',[ | |
| values[0], | |
| values[1], | |
| values[2], | |
| values[3], | |
| values[4], | |
| values[5] | |
| ]), | |
| children, | |
| end | |
| ]; | |
| }; | |
| module.exports = transform; | |
| /***/ }, | |
| /* 55 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| let Instruction = __webpack_require__(0); | |
| let end = new Instruction('restore'); | |
| let translate = (x, y, ...children) => [ | |
| new Instruction('translate', { x: x, y: y }), | |
| children, | |
| end | |
| ]; | |
| module.exports = translate; | |
| /***/ }, | |
| /* 56 */ | |
| /***/ function(module, exports) { | |
| // Source: http://jsfiddle.net/vWx8V/ | |
| // http://stackoverflow.com/questions/5603195/full-list-of-javascript-keycodes | |
| /** | |
| * Conenience method returns corresponding value for given keyName or keyCode. | |
| * | |
| * @param {Mixed} keyCode {Number} or keyName {String} | |
| * @return {Mixed} | |
| * @api public | |
| */ | |
| exports = module.exports = function(searchInput) { | |
| // Keyboard Events | |
| if (searchInput && 'object' === typeof searchInput) { | |
| var hasKeyCode = searchInput.which || searchInput.keyCode || searchInput.charCode | |
| if (hasKeyCode) searchInput = hasKeyCode | |
| } | |
| // Numbers | |
| if ('number' === typeof searchInput) return names[searchInput] | |
| // Everything else (cast to string) | |
| var search = String(searchInput) | |
| // check codes | |
| var foundNamedKey = codes[search.toLowerCase()] | |
| if (foundNamedKey) return foundNamedKey | |
| // check aliases | |
| var foundNamedKey = aliases[search.toLowerCase()] | |
| if (foundNamedKey) return foundNamedKey | |
| // weird character? | |
| if (search.length === 1) return search.charCodeAt(0) | |
| return undefined | |
| } | |
| /** | |
| * Get by name | |
| * | |
| * exports.code['enter'] // => 13 | |
| */ | |
| var codes = exports.code = exports.codes = { | |
| 'backspace': 8, | |
| 'tab': 9, | |
| 'enter': 13, | |
| 'shift': 16, | |
| 'ctrl': 17, | |
| 'alt': 18, | |
| 'pause/break': 19, | |
| 'caps lock': 20, | |
| 'esc': 27, | |
| 'space': 32, | |
| 'page up': 33, | |
| 'page down': 34, | |
| 'end': 35, | |
| 'home': 36, | |
| 'left': 37, | |
| 'up': 38, | |
| 'right': 39, | |
| 'down': 40, | |
| 'insert': 45, | |
| 'delete': 46, | |
| 'command': 91, | |
| 'left command': 91, | |
| 'right command': 93, | |
| 'numpad *': 106, | |
| 'numpad +': 107, | |
| 'numpad -': 109, | |
| 'numpad .': 110, | |
| 'numpad /': 111, | |
| 'num lock': 144, | |
| 'scroll lock': 145, | |
| 'my computer': 182, | |
| 'my calculator': 183, | |
| ';': 186, | |
| '=': 187, | |
| ',': 188, | |
| '-': 189, | |
| '.': 190, | |
| '/': 191, | |
| '`': 192, | |
| '[': 219, | |
| '\\': 220, | |
| ']': 221, | |
| "'": 222 | |
| } | |
| // Helper aliases | |
| var aliases = exports.aliases = { | |
| 'windows': 91, | |
| '⇧': 16, | |
| '⌥': 18, | |
| '⌃': 17, | |
| '⌘': 91, | |
| 'ctl': 17, | |
| 'control': 17, | |
| 'option': 18, | |
| 'pause': 19, | |
| 'break': 19, | |
| 'caps': 20, | |
| 'return': 13, | |
| 'escape': 27, | |
| 'spc': 32, | |
| 'pgup': 33, | |
| 'pgdn': 34, | |
| 'ins': 45, | |
| 'del': 46, | |
| 'cmd': 91 | |
| } | |
| /*! | |
| * Programatically add the following | |
| */ | |
| // lower case chars | |
| for (i = 97; i < 123; i++) codes[String.fromCharCode(i)] = i - 32 | |
| // numbers | |
| for (var i = 48; i < 58; i++) codes[i - 48] = i | |
| // function keys | |
| for (i = 1; i < 13; i++) codes['f'+i] = i + 111 | |
| // numpad keys | |
| for (i = 0; i < 10; i++) codes['numpad '+i] = i + 96 | |
| /** | |
| * Get by code | |
| * | |
| * exports.name[13] // => 'Enter' | |
| */ | |
| var names = exports.names = exports.title = {} // title for backward compat | |
| // Create reverse mapping | |
| for (i in codes) names[codes[i]] = i | |
| // Add aliases | |
| for (var alias in aliases) { | |
| codes[alias] = aliases[alias] | |
| } | |
| /***/ }, | |
| /* 57 */ | |
| /***/ function(module, exports) { | |
| module.exports = function (point, vs) { | |
| // ray-casting algorithm based on | |
| // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html | |
| var x = point[0], y = point[1]; | |
| var inside = false; | |
| for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) { | |
| var xi = vs[i][0], yi = vs[i][1]; | |
| var xj = vs[j][0], yj = vs[j][1]; | |
| var intersect = ((yi > y) != (yj > y)) | |
| && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); | |
| if (intersect) inside = !inside; | |
| } | |
| return inside; | |
| }; | |
| /***/ }, | |
| /* 58 */ | |
| /***/ function(module, exports, __webpack_require__) { | |
| module.exports = { | |
| 'activeRegions': __webpack_require__(10), | |
| 'arc': __webpack_require__(11), | |
| 'arcTo': __webpack_require__(12), | |
| 'beginPath': __webpack_require__(2), | |
| 'bezierCurveTo': __webpack_require__(13), | |
| 'clearRect': __webpack_require__(14), | |
| 'clip': __webpack_require__(15), | |
| 'clipPath': __webpack_require__(16), | |
| 'closePath': __webpack_require__(3), | |
| 'createRegularPolygon': __webpack_require__(17), | |
| 'createWrapper': __webpack_require__(18), | |
| 'cycleMouseData': __webpack_require__(4), | |
| 'drawImage': __webpack_require__(19), | |
| 'ellipse': __webpack_require__(20), | |
| 'fill': __webpack_require__(21), | |
| 'fillArc': __webpack_require__(22), | |
| 'fillRect': __webpack_require__(23), | |
| 'fillStyle': __webpack_require__(24), | |
| 'fillText': __webpack_require__(25), | |
| 'globalAlpha': __webpack_require__(26), | |
| 'globalCompositeOperation': __webpack_require__(27), | |
| 'hitRect': __webpack_require__(28), | |
| 'hitRegion': __webpack_require__(29), | |
| 'imageSmoothingEnabled': __webpack_require__(30), | |
| 'initialize': __webpack_require__(31), | |
| 'Instruction': __webpack_require__(0), | |
| 'invertMatrix': __webpack_require__(5), | |
| 'keyData': __webpack_require__(32), | |
| 'lineStyle': __webpack_require__(33), | |
| 'lineTo': __webpack_require__(6), | |
| 'mouseData': __webpack_require__(34), | |
| 'moveTo': __webpack_require__(7), | |
| 'moveToLineTo': __webpack_require__(35), | |
| 'path': __webpack_require__(36), | |
| 'placeHolder': __webpack_require__(37), | |
| 'pointInRect': __webpack_require__(8), | |
| 'quadraticCurveTo': __webpack_require__(38), | |
| 'raf': __webpack_require__(39), | |
| 'rect': __webpack_require__(40), | |
| 'render': __webpack_require__(41), | |
| 'resetTransform': __webpack_require__(42), | |
| 'rotate': __webpack_require__(43), | |
| 'scale': __webpack_require__(44), | |
| 'setTransform': __webpack_require__(9), | |
| 'shadowStyle': __webpack_require__(45), | |
| 'skewX': __webpack_require__(46), | |
| 'skewY': __webpack_require__(47), | |
| 'stroke': __webpack_require__(48), | |
| 'strokeArc': __webpack_require__(49), | |
| 'strokeRect': __webpack_require__(50), | |
| 'strokeStyle': __webpack_require__(51), | |
| 'strokeText': __webpack_require__(52), | |
| 'textStyle': __webpack_require__(53), | |
| 'transform': __webpack_require__(54), | |
| 'transformPoints': __webpack_require__(1), | |
| 'translate': __webpack_require__(55) | |
| }; | |
| /***/ } | |
| /******/ ]); | |
| }); | |
| },{}]},{},[]) | |
| //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImUyZCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcImUyZFwiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJlMmRcIl0gPSBmYWN0b3J5KCk7XG59KSh0aGlzLCBmdW5jdGlvbigpIHtcbnJldHVybiAvKioqKioqLyAoZnVuY3Rpb24obW9kdWxlcykgeyAvLyB3ZWJwYWNrQm9vdHN0cmFwXG4vKioqKioqLyBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuLyoqKioqKi8gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuLyoqKioqKi8gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbi8qKioqKiovIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbi8qKioqKiovIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbi8qKioqKiovIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuXG4vKioqKioqLyBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbi8qKioqKiovIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4vKioqKioqLyBcdFx0XHRpOiBtb2R1bGVJZCxcbi8qKioqKiovIFx0XHRcdGw6IGZhbHNlLFxuLyoqKioqKi8gXHRcdFx0ZXhwb3J0czoge31cbi8qKioqKiovIFx0XHR9O1xuXG4vKioqKioqLyBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4vKioqKioqLyBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbi8qKioqKiovIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4vKioqKioqLyBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4vKioqKioqLyBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbi8qKioqKiovIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4vKioqKioqLyBcdH1cblxuXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbi8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuLyoqKioqKi8gXHQvLyBpZGVudGl0eSBmdW5jdGlvbiBmb3IgY2FsbGluZyBoYXJtb255IGltcG9ydHMgd2l0aCB0aGUgY29ycmVjdCBjb250ZXh0XG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uaSA9IGZ1bmN0aW9uKHZhbHVlKSB7IHJldHVybiB2YWx1ZTsgfTtcblxuLyoqKioqKi8gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4vKioqKioqLyBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuLyoqKioqKi8gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbi8qKioqKiovIFx0XHRcdFx0Y29uZmlndXJhYmxlOiBmYWxzZSxcbi8qKioqKiovIFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcbi8qKioqKiovIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbi8qKioqKiovIFx0XHRcdH0pO1xuLyoqKioqKi8gXHRcdH1cbi8qKioqKiovIFx0fTtcblxuLyoqKioqKi8gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbi8qKioqKiovIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbi8qKioqKiovIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4vKioqKioqLyBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuLyoqKioqKi8gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbi8qKioqKiovIFx0XHRyZXR1cm4gZ2V0dGVyO1xuLyoqKioqKi8gXHR9O1xuXG4vKioqKioqLyBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbi8qKioqKiovIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuLyoqKioqKi8gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbi8qKioqKiovIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gNTgpO1xuLyoqKioqKi8gfSlcbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKioqKioqLyAoW1xuLyogMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmNsYXNzIEluc3RydWN0aW9uIHtcclxuICBjb25zdHJ1Y3Rvcih0eXBlLCBwcm9wcykge1xyXG4gICAgdGhpcy50eXBlID0gdHlwZTtcclxuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcclxuICAgIHJldHVybiBPYmplY3Quc2VhbCh0aGlzKTtcclxuICB9XHJcbn1cclxuXHJcbk9iamVjdC5zZWFsKEluc3RydWN0aW9uKTtcclxuT2JqZWN0LnNlYWwoSW5zdHJ1Y3Rpb24ucHJvdG90eXBlKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gSW5zdHJ1Y3Rpb247XHJcblxuXG4vKioqLyB9LFxuLyogMSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmxldCB0cmFuc2Zvcm1Qb2ludHMgPSAocG9pbnRzLCBtYXRyaXgpID0+IHtcclxuICBsZXQgcmVzdWx0ID0gW10sXHJcbiAgICAgIHgsIHk7XHJcblxyXG4gIGZvcihsZXQgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcclxuICAgIFt4LCB5XSA9IHBvaW50c1tpXTtcclxuICAgIHJlc3VsdC5wdXNoKFtcclxuICAgICAgbWF0cml4WzBdICogeCArIG1hdHJpeFsyXSAqIHkgKyBtYXRyaXhbNF0sXHJcbiAgICAgIG1hdHJpeFsxXSAqIHggKyBtYXRyaXhbM10gKiB5ICsgbWF0cml4WzVdXHJcbiAgICBdKTtcclxuICB9XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdHJhbnNmb3JtUG9pbnRzO1xyXG5cblxuLyoqKi8gfSxcbi8qIDIgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApLFxyXG4gIGNhY2hlID0gbmV3IEluc3RydWN0aW9uKCdiZWdpblBhdGgnKTtcclxuXHJcbmxldCBiZWdpblBhdGggPSAoKSA9PiBjYWNoZTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYmVnaW5QYXRoO1xuXG4vKioqLyB9LFxuLyogMyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbignY2xvc2VQYXRoJyk7XHJcblxyXG5sZXQgY2xvc2VQYXRoID0gKCkgPT4gY2FjaGU7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsb3NlUGF0aDtcclxuXG5cbi8qKiovIH0sXG4vKiA0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHJcbmxldCBjeWNsZU1vdXNlRGF0YSA9IChjdHgpID0+IHtcclxuICBsZXQgbW91c2VEYXRhID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZURhdGEnKV07XHJcbiAgaWYgKG1vdXNlRGF0YSkge1xyXG4gICAgbW91c2VEYXRhLmR4ID0gbW91c2VEYXRhLnggLSBtb3VzZURhdGEucHJldmlvdXNYO1xyXG4gICAgbW91c2VEYXRhLmR5ID0gbW91c2VEYXRhLnkgLSBtb3VzZURhdGEucHJldmlvdXNZO1xyXG5cclxuICAgIG1vdXNlRGF0YS5wcmV2aW91c1ggPSBtb3VzZURhdGEueDtcclxuICAgIG1vdXNlRGF0YS5wcmV2aW91c1kgPSBtb3VzZURhdGEueTtcclxuXHJcbiAgICBtb3VzZURhdGEuY2xpY2tlZCA9IDA7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjeWNsZU1vdXNlRGF0YTtcblxuLyoqKi8gfSxcbi8qIDUgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5sZXQgZGV0ID0gMDtcclxubGV0IGludmVydE1hdHJpeCA9IChbYSwgYiwgYywgZCwgZSwgZl0pID0+IChcclxuICBkZXQgPSAxIC8gKGEgKiBkIC0gYyAqIGIpLFxyXG4gIFtcclxuICAgIGQgKiBkZXQsXHJcbiAgICAtYyAqIGRldCxcclxuICAgIC1iICogZGV0LFxyXG4gICAgYSAqIGRldCxcclxuICAgIChiICogZiAtIGUgKiBkKSAqIGRldCxcclxuICAgIChlICogYiAtIGEgKiBmKSAqIGRldFxyXG4gIF1cclxuKTtcclxuIG1vZHVsZS5leHBvcnRzID0gaW52ZXJ0TWF0cml4O1xuXG4vKioqLyB9LFxuLyogNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgbGluZVRvID0gKHgsIHkpID0+IG5ldyBJbnN0cnVjdGlvbignbGluZVRvJywgeyB4LCB5IH0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBsaW5lVG87XHJcblxuXG4vKioqLyB9LFxuLyogNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgbW92ZVRvID0gKHgsIHkpID0+IG5ldyBJbnN0cnVjdGlvbignbW92ZVRvJywgeyB4LCB5IH0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBtb3ZlVG87XHJcblxuXG4vKioqLyB9LFxuLyogOCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmxldCBwb2ludEluUmVjdCA9IChbcHgsIHB5XSwgW1t4LCB5XSwgW3dpZHRoLCBoZWlnaHRdXSkgPT4gcHggPiB4ICYmIHB5ID4geSAmJiBweCA8IHdpZHRoICYmIHB5IDwgaGVpZ2h0O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBwb2ludEluUmVjdDtcblxuLyoqKi8gfSxcbi8qIDkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5sZXQgZW5kID0gbmV3IEluc3RydWN0aW9uKCdyZXN0b3JlJyk7XHJcblxyXG5sZXQgc2V0VHJhbnNmb3JtID0gKG1hdHJpeCwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ3NldFRyYW5zZm9ybScsIFtcclxuICAgIG1hdHJpeFswXSxcclxuICAgIG1hdHJpeFsxXSxcclxuICAgIG1hdHJpeFsyXSxcclxuICAgIG1hdHJpeFszXSxcclxuICAgIG1hdHJpeFs0XSxcclxuICAgIG1hdHJpeFs1XVxyXG4gIF0pLFxyXG4gIGNoaWxkcmVuLFxyXG4gIGVuZFxyXG5dO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzZXRUcmFuc2Zvcm07XG5cbi8qKiovIH0sXG4vKiAxMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBwb2ludEluUG9seWdvbiA9IF9fd2VicGFja19yZXF1aXJlX18oNTcpO1xyXG5sZXQgdHJhbnNmb3JtUG9pbnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKTtcclxubGV0IGludmVydE1hdHJpeCA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7XHJcbmxldCBwb2ludEluUmVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oOCk7XHJcblxyXG5sZXQgbWF0cml4ID0gbmV3IEZsb2F0NjRBcnJheSg2KTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gKGN0eCkgPT4ge1xyXG4gIGxldCByZWdpb25zID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdyZWdpb25zJyldLFxyXG4gICAgbW91c2VQb2ludHMgPSBjdHguY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlUG9pbnRzJyldLFxyXG4gICAgbW91c2VEYXRhID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZURhdGEnKV0sXHJcbiAgICByZXN1bHRzID0ge307XHJcblxyXG4gIC8vdGhlIG1vdXNlIG1pZ2h0IGhhdmUgaGVsZCBzdGlsbCwgYWRkIHRoZSBjdXJyZW50IG1vdXNlIHBvc2l0aW9uXHJcbiAgaWYgKG1vdXNlUG9pbnRzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgbW91c2VQb2ludHMucHVzaChbbW91c2VEYXRhLngsIG1vdXNlRGF0YS55LCBtb3VzZURhdGEuc3RhdGVdKTtcclxuICB9XHJcblxyXG4gIGZvcihsZXQgcmVnaW9uIG9mIHJlZ2lvbnMpIHtcclxuXHJcbiAgICAvL2ludmVydCB0aGUgcmVnaW9uIG1hdHJpeCBhbmQgdHJhbnNmb3JtIHRoZSBtb3VzZSBwb2ludHNcclxuICAgIGxldCB0cmFuc2Zvcm1lZE1vdXNlUG9pbnRzID0gdHJhbnNmb3JtUG9pbnRzKG1vdXNlUG9pbnRzLCBpbnZlcnRNYXRyaXgocmVnaW9uLm1hdHJpeCkpO1xyXG4gICAgLy90aGUgbW91c2UgcG9pbnRzIGFyZSBub3cgcmVsYXRpdmUgdG8gdGhlIG1vdXNlIHJlZ2lvblxyXG5cclxuICAgIGlmICghcmVnaW9uLnBvbHlnb24pIHtcclxuICAgICAgZm9yIChsZXQgbW91c2VQb2ludCBvZiB0cmFuc2Zvcm1lZE1vdXNlUG9pbnRzKSB7XHJcbiAgICAgICAgaWYgKHBvaW50SW5SZWN0KG1vdXNlUG9pbnQsIHJlZ2lvbi5wb2ludHMpKSB7XHJcbiAgICAgICAgICByZWdpb24uaG92ZXIgPSB0cnVlO1xyXG4gICAgICAgICAgcmVnaW9uLmNsaWNrZWQgPSAhIW1vdXNlRGF0YS5jbGlja2VkO1xyXG4gICAgICAgICAgcmVzdWx0c1tyZWdpb24uaWRdID0gcmVnaW9uO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vbG9vcCBvdmVyIGVhY2ggcG9pbnQgdW50aWwgb25lIGlzIG1hdGNoZWRcclxuICAgIGZvcihsZXQgbW91c2VQb2ludCBvZiB0cmFuc2Zvcm1lZE1vdXNlUG9pbnRzKSB7XHJcbiAgICAgIGlmIChwb2ludEluUG9seWdvbihtb3VzZVBvaW50LCByZWdpb24ucG9pbnRzKSkge1xyXG4gICAgICAgIHJlZ2lvbi5ob3ZlciA9IHRydWU7XHJcbiAgICAgICAgcmVnaW9uLmNsaWNrZWQgPSAhIW1vdXNlRGF0YS5jbGlja2VkO1xyXG4gICAgICAgIHJlc3VsdHNbcmVnaW9uLmlkXSA9IHJlZ2lvbjtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gcmVzdWx0cztcclxufTtcblxuLyoqKi8gfSxcbi8qIDExICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKSxcclxuICAgIHBpMiA9IE1hdGguUEkgKiAyO1xyXG5cclxubGV0IGFyYyA9ICguLi5hcmdzKSA9PiB7XHJcbiAgbGV0ICBbeCwgeSwgciwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGNvdW50ZXJjbG9ja3dpc2VdID0gYXJncztcclxuICBsZXQgcHJvcHMgPSB7IHg6IDAsIHk6IDAsIHI6IHgsIHN0YXJ0QW5nbGU6IDAsIGVuZEFuZ2xlOiBwaTIsIGNvdW50ZXJjbG9ja3dpc2U6IGZhbHNlIH07XHJcblxyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPiAzKSB7XHJcbiAgICBwcm9wcy5zdGFydEFuZ2xlID0gc3RhcnRBbmdsZTtcclxuICAgIHByb3BzLmVuZEFuZ2xlID0gZW5kQW5nbGU7XHJcbiAgICBwcm9wcy5jb3VudGVyY2xvY2t3aXNlID0gISFjb3VudGVyY2xvY2t3aXNlO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID4gMSl7XHJcbiAgICBwcm9wcy54ID0geDtcclxuICAgIHByb3BzLnkgPSB5O1xyXG4gICAgcHJvcHMuciA9IHI7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwiYXJjXCIsICBwcm9wcyk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGFyYztcclxuXG5cbi8qKiovIH0sXG4vKiAxMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgYXJjVG8gPSAoeDEsIHkxLCB4MiwgeTIsIHIpID0+IG5ldyBJbnN0cnVjdGlvbignYXJjVG8nLCB7IHgxLCB5MSwgeDIsIHkyLCByIH0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBhcmNUbztcclxuXG5cbi8qKiovIH0sXG4vKiAxMyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgYmV6aWVyQ3VydmVUbyA9IChjcDF4LCBjcDF5LCBjcDJ4LCBjcDJ5LCB4LCB5KSA9PiBuZXcgSW5zdHJ1Y3Rpb24oJ2JlemllckN1cnZlVG8nLCB7XHJcbiAgY3AxeCxcclxuICBjcDF5LFxyXG4gIGNwMngsXHJcbiAgY3AyeSxcclxuICB4LFxyXG4gIHlcclxufSk7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBiZXppZXJDdXJ2ZVRvO1xyXG5cblxuLyoqKi8gfSxcbi8qIDE0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBjbGVhclJlY3QgPSAoLi4uYXJncykgPT4gbmV3IEluc3RydWN0aW9uKCdjbGVhclJlY3QnLFxyXG4gIGFyZ3MubGVuZ3RoID4gMiA/XHJcbiAgICB7IHg6IGFyZ3NbMF0sIHk6IGFyZ3NbMV0sIHdpZHRoOiBhcmdzWzJdLCBoZWlnaHQ6IGFyZ3NbM10gfSA6XHJcbiAgICB7IHg6IDAsIHk6IDAsIHdpZHRoOiBhcmdzWzBdLCBoZWlnaHQ6IGFyZ3NbMV0gfVxyXG4pO1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY2xlYXJSZWN0O1xyXG5cblxuLyoqKi8gfSxcbi8qIDE1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBiZWdpbiA9IG5ldyBJbnN0cnVjdGlvbignYmVnaW5DbGlwJyksXHJcbiAgcGVyZm9ybUNsaXAgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2NsaXAnKSxcclxuICBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZENsaXAnKTtcclxuXHJcbmxldCBjbGlwID0gKHBhdGgsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgYmVnaW4sXHJcbiAgcGF0aCxcclxuICBwZXJmb3JtQ2xpcCxcclxuICBjaGlsZHJlbixcclxuICBlbmRcclxuXTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY2xpcDtcclxuXG5cbi8qKiovIH0sXG4vKiAxNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbignY2xpcFBhdGgnKTtcclxuXHJcbmxldCBjbGlwUGF0aCA9ICgpID0+IGNhY2hlO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjbGlwUGF0aDtcclxuXG5cbi8qKiovIH0sXG4vKiAxNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmxldCBjcmVhdGVSZWd1bGFyUG9seWdvbiA9IChyYWRpdXMgPSAwLCBwb3NpdGlvbiA9IFswLCAwXSwgc2lkZXMgPSAzKSA9PiB7XHJcbiAgbGV0IHBvbHlnb24gPSBbXTtcclxuICBmb3IobGV0IGkgPSAwOyBpIDwgc2lkZXM7IGkrKykge1xyXG4gICAgcG9seWdvbi5wdXNoKFtcclxuICAgICAgcG9zaXRpb25bMF0gKyByYWRpdXMgKiBNYXRoLmNvcyhNYXRoLlBJICogMiAqIGkgLyBzaWRlcyksXHJcbiAgICAgIHBvc2l0aW9uWzFdICsgcmFkaXVzICogTWF0aC5zaW4oTWF0aC5QSSAqIDIgKiBpIC8gc2lkZXMpXHJcbiAgICBdKTtcclxuICB9XHJcbiAgcmV0dXJuIHBvbHlnb247XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVJlZ3VsYXJQb2x5Z29uO1xyXG5cblxuLyoqKi8gfSxcbi8qIDE4ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxubGV0IGNvbmNhdCA9IFtdLmNvbmNhdDtcclxuXHJcbmxldCBjcmVhdGVXcmFwcGVyID0gKC4uLmFyZ3MpID0+IHtcclxuICBmb3IobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xyXG4gICAgLy9wYXJzZSBhbmQgZmxhdHRlbiB0aGUgYXJndW1lbnRzXHJcbiAgICB3aGlsZSAoYXJnc1tpXSAmJiBhcmdzW2ldLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICBhcmdzID0gY29uY2F0LmFwcGx5KFtdLCBhcmdzKS5maWx0ZXIoQm9vbGVhbik7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFhcmdzW2ldKSB7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCB7IHR5cGUgfSA9IGFyZ3NbaV07XHJcbiAgICBpZiAodHlwZSA9PT0gJ3BsYWNlaG9sZGVyJykge1xyXG4gICAgICAvLyBpIGlzIHNldCB0byB0aGUgcGxhY2Vob2xkZXIgaW5kZXggbm93XHJcblxyXG4gICAgICAvL25vdyBncmFiIGFsbCB0aGUgZWxlbWVudHMgdG8gdGhlIGxlZnQgb2YgdGhlIHBsYWNlSG9sZGVyXHJcbiAgICAgIGxldCBsZWZ0ID0gYXJncy5zcGxpY2UoMCwgaSk7XHJcblxyXG4gICAgICAvL3JlbW92ZSB0aGUgcGxhY2VIb2xkZXIgZnJvbSB0aGUgYXJyYXlcclxuICAgICAgYXJncy5zaGlmdCgpO1xyXG5cclxuICAgICAgcmV0dXJuICguLi5jaGlsZHJlbikgPT4gW2xlZnQsIGNoaWxkcmVuLCBhcmdzXTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGZpbmQgcGxhY2Vob2xkZXIsIGRpZCB5b3UgZm9yZ2V0IHRoZSBlMmQucGxhY2VIb2xkZXIoKSBjYWxsPycpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjb25jYXQ7XHJcblxuXG4vKioqLyB9LFxuLyogMTkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5cclxubGV0IGRyYXdJbWFnZSA9ICguLi5hcmdzKSA9PiB7XHJcbiAgbGV0IFtpbWcsIHN4LCBzeSwgc1dpZHRoLCBzSGVpZ2h0LCBkeCwgZHksIGRXaWR0aCwgZEhlaWdodF0gPSBhcmdzO1xyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPT09IDkpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdJbWFnZVNvdXJjZScsIHtcclxuICAgICAgaW1nLFxyXG4gICAgICBzeCxcclxuICAgICAgc3ksXHJcbiAgICAgIHNXaWR0aCxcclxuICAgICAgc0hlaWdodCxcclxuICAgICAgZHgsXHJcbiAgICAgIGR5LFxyXG4gICAgICBkV2lkdGgsXHJcbiAgICAgIGRIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID49IDUpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdJbWFnZVNpemUnLCB7XHJcbiAgICAgIGltZyxcclxuICAgICAgZHg6IHN4LFxyXG4gICAgICBkeTogc3ksXHJcbiAgICAgIGRXaWR0aDogc1dpZHRoLFxyXG4gICAgICBkSGVpZ2h0OiBzSGVpZ2h0XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA+PSAzKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdkcmF3SW1hZ2UnLCB7XHJcbiAgICAgIGltZyxcclxuICAgICAgZHg6IHN4LFxyXG4gICAgICBkeTogc3lcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZHJhd0ltYWdlJywge1xyXG4gICAgaW1nLFxyXG4gICAgZHg6IDAsXHJcbiAgICBkeTogMFxyXG4gIH0pO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBkcmF3SW1hZ2U7XHJcblxuXG4vKioqLyB9LFxuLyogMjAgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApLFxyXG4gICAgcGkyID0gTWF0aC5QSSAqIDI7XHJcblxyXG5sZXQgZWxsaXBzZSA9ICguLi5hcmdzKSA9PiB7XHJcbiAgbGV0IFt4LCB5LCByYWRpdXNYLCByYWRpdXNZLCByb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGFudGljbG9ja3dpc2VdID0gYXJncztcclxuXHJcbiAgbGV0IHByb3BzID0geyB4OiAwLCB5OiAwLCByYWRpdXNYOiB4LCByYWRpdXNZOiB5LCByb3RhdGlvbjogMCwgc3RhcnRBbmdsZTogMCwgZW5kQW5nbGU6IHBpMiwgYW50aWNsb2Nrd2lzZTogZmFsc2UgfTtcclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID4gNSkge1xyXG4gICAgcHJvcHMuc3RhcnRBbmdsZSA9IHN0YXJ0QW5nbGU7XHJcbiAgICBwcm9wcy5lbmRBbmdsZSA9IGVuZEFuZ2xlO1xyXG4gICAgcHJvcHMuYW50aWNsb2Nrd2lzZSA9ICEhYW50aWNsb2Nrd2lzZTtcclxuICB9XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA+IDQpIHtcclxuICAgIHByb3BzLnJvdGF0aW9uID0gcm90YXRpb247XHJcbiAgfVxyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPiAyKXtcclxuICAgIHByb3BzLnggPSB4O1xyXG4gICAgcHJvcHMueSA9IHk7XHJcbiAgICBwcm9wcy5yYWRpdXNYID0gcmFkaXVzWDtcclxuICAgIHByb3BzLnJhZGl1c1kgPSByYWRpdXNZO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcImVsbGlwc2VcIiwgIHByb3BzKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZWxsaXBzZTtcclxuXG5cbi8qKiovIH0sXG4vKiAyMSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbignZmlsbCcpO1xyXG5cclxubGV0IGZpbGwgPSAoKSA9PiBjYWNoZTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbDtcclxuXG5cbi8qKiovIH0sXG4vKiAyMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblxyXG5cclxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKSxcclxuICAgIHBpMiA9IE1hdGguUEkgKiAyO1xyXG5cclxubGV0IGZpbGxBcmMgPSAoLi4uYXJncykgPT4ge1xyXG4gIGxldCBbeCwgeSwgciwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGNvdW50ZXJjbG9ja3dpc2VdID0gYXJncztcclxuICBsZXQgcHJvcHMgPSB7IHg6IDAsIHk6IDAsIHI6IHgsIHN0YXJ0QW5nbGU6IDAsIGVuZEFuZ2xlOiBwaTIsIGNvdW50ZXJjbG9ja3dpc2U6IGZhbHNlIH07XHJcblxyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPiAzKSB7XHJcbiAgICBwcm9wcy5zdGFydEFuZ2xlID0gc3RhcnRBbmdsZTtcclxuICAgIHByb3BzLmVuZEFuZ2xlID0gZW5kQW5nbGU7XHJcbiAgICBwcm9wcy5jb3VudGVyY2xvY2t3aXNlID0gISFjb3VudGVyY2xvY2t3aXNlO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID49IDIpIHtcclxuICAgIHByb3BzLnggPSB4O1xyXG4gICAgcHJvcHMueSA9IHk7XHJcbiAgICBwcm9wcy5yID0gcjtcclxuICB9XHJcblxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oXCJmaWxsQXJjXCIsICBwcm9wcyk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZpbGxBcmM7XHJcblxuXG4vKioqLyB9LFxuLyogMjMgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5cclxubGV0IGZpbGxSZWN0ID0gKC4uLmFyZ3MpID0+IG5ldyBJbnN0cnVjdGlvbignZmlsbFJlY3QnLFxyXG4gIGFyZ3MubGVuZ3RoID4gMiA/XHJcbiAgICB7IHg6IGFyZ3NbMF0sIHk6IGFyZ3NbMV0sIHdpZHRoOiBhcmdzWzJdLCBoZWlnaHQ6IGFyZ3NbM10gfSA6XHJcbiAgICB7IHg6IDAsIHk6IDAsIHdpZHRoOiBhcmdzWzBdLCBoZWlnaHQ6IGFyZ3NbMV0gfVxyXG4pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsUmVjdDtcclxuXG5cbi8qKiovIH0sXG4vKiAyNCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZEZpbGxTdHlsZScpO1xyXG5cclxubGV0IGZpbGxTdHlsZSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignZmlsbFN0eWxlJywgeyB2YWx1ZSB9KSxcclxuICAgIGNoaWxkcmVuLFxyXG4gICAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZpbGxTdHlsZTtcclxuXG5cbi8qKiovIH0sXG4vKiAyNSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgZmlsbFRleHQgPSAoLi4uYXJncykgPT4ge1xyXG4gIGxldCBbdGV4dCwgeCwgeSwgbWF4V2lkdGhdID0gYXJncztcclxuICBpZiAoYXJncy5sZW5ndGggPCA0KSB7XHJcbiAgICBtYXhXaWR0aCA9IG51bGw7XHJcbiAgfVxyXG4gIGlmIChhcmdzLmxlbmd0aCA8IDMpIHtcclxuICAgIHggPSAwO1xyXG4gICAgeSA9IDA7XHJcbiAgfVxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2ZpbGxUZXh0JywgeyB0ZXh0LCB4LCB5LCBtYXhXaWR0aCB9KTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbFRleHQ7XG5cbi8qKiovIH0sXG4vKiAyNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblxyXG5cclxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbignZW5kR2xvYmFsQWxwaGEnKTtcclxuXHJcbmxldCBnbG9iYWxBbHBoYSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ2dsb2JhbEFscGhhJywgeyB2YWx1ZSB9KSxcclxuICBjaGlsZHJlbixcclxuICBlbmRcclxuXTtcclxubW9kdWxlLmV4cG9ydHMgPSBnbG9iYWxBbHBoYTtcclxuXG5cbi8qKiovIH0sXG4vKiAyNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblxyXG5cclxudmFyIEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZEdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbicpO1xyXG5cclxubGV0IGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ2dsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbicsIHsgdmFsdWUgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbjtcclxuXG5cbi8qKiovIH0sXG4vKiAyOCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgaGl0UmVjdCA9IChpZCwgLi4uYXJncykgPT4ge1xyXG4gIGxldCBbeCwgeSwgd2lkdGgsIGhlaWdodF0gPSBhcmdzO1xyXG4gIGlmIChhcmdzLmxlbmd0aCA8PSAzKSB7XHJcbiAgICB3aWR0aCA9IHg7XHJcbiAgICBoZWlnaHQgPSB5O1xyXG4gICAgeCA9IDA7XHJcbiAgICB5ID0gMDtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignaGl0UmVjdCcsIHtcclxuICAgIGlkLFxyXG4gICAgcG9pbnRzOiBbXHJcbiAgICAgIFt4LCB5XSxcclxuICAgICAgW3ggKyB3aWR0aCwgeSArIGhlaWdodF1cclxuICAgIF1cclxuICB9KTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gaGl0UmVjdDtcblxuLyoqKi8gfSxcbi8qIDI5ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBoaXRSZWdpb24gPSAoaWQsIHBvaW50cykgPT4gbmV3IEluc3RydWN0aW9uKCdoaXRSZWdpb24nLCB7IGlkLCBwb2ludHMgfSk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGhpdFJlZ2lvbjtcclxuXG5cbi8qKiovIH0sXG4vKiAzMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZEltYWdlU21vb3RoaW5nRW5hYmxlZCcpO1xyXG5cclxubGV0IGltYWdlU21vb3RoaW5nRW5hYmxlZCA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ2ltYWdlU21vb3RoaW5nRW5hYmxlZCcsIHsgdmFsdWUgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcbm1vZHVsZS5leHBvcnRzID0gaW1hZ2VTbW9vdGhpbmdFbmFibGVkO1xyXG5cblxuLyoqKi8gfSxcbi8qIDMxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IGtleWNvZGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDU2KTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gKGN0eCkgPT4ge1xyXG4gIGxldCB7IGNhbnZhcyB9ID0gY3R4O1xyXG5cclxuICAvL21vdXNlRGF0YVxyXG4gIGNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZURhdGEnKV0gPSB7XHJcbiAgICB4OiAwLFxyXG4gICAgeTogMCxcclxuICAgIGR4OiAwLFxyXG4gICAgZHk6IDAsXHJcbiAgICBwcmV2aW91c1g6IDAsXHJcbiAgICBwcmV2aW91c1k6IDAsXHJcbiAgICBzdGF0ZTogZmFsc2UsXHJcbiAgICBjbGlja2VkOiAwXHJcbiAgfTtcclxuXHJcbiAgbGV0IGtleXMgPSBjYW52YXNbU3ltYm9sLmZvcigna2V5RGF0YScpXSA9IHt9O1xyXG5cclxuICBmb3IgKGxldCBuYW1lIGluIGtleWNvZGUuY29kZSkge1xyXG4gICAgaWYgKGtleWNvZGUuY29kZS5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xyXG4gICAgICBrZXlzW25hbWVdID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvL21vdXNlIHJlZ2lvbnNcclxuICBjYW52YXNbU3ltYm9sLmZvcigncmVnaW9ucycpXSA9IFtdO1xyXG4gIGNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZVBvaW50cycpXSA9IFtdO1xyXG5cclxuICAvL21ha2UgdGhlIGNhbnZhcyByZWNlaXZlIHRvdWNoIGFuZCBtb3VzZSBldmVudHNcclxuICBjYW52YXMudGFiSW5kZXggPSAxO1xyXG5cclxuICBsZXQgbW91c2VNb3ZlID0gKGV2dCkgPT4ge1xyXG4gICAgbGV0IHsgY2xpZW50WCwgY2xpZW50WSB9ID0gZXZ0O1xyXG4gICAgLy9nZXQgbGVmdCBhbmQgdG9wIGNvb3JkaW5hdGVzXHJcbiAgICBsZXQgeyBsZWZ0LCB0b3AgfSA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgICBsZXQgbW91c2VEYXRhID0gY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlRGF0YScpXTtcclxuXHJcbiAgICBsZXQgcG9pbnQgPSBbY2xpZW50WCAtIGxlZnQsIGNsaWVudFkgLSB0b3AsIG1vdXNlRGF0YS5zdGF0ZV07XHJcblxyXG4gICAgbW91c2VEYXRhLnggPSBwb2ludFswXTtcclxuICAgIG1vdXNlRGF0YS55ID0gcG9pbnRbMV07XHJcblxyXG4gICAgbGV0IHBvaW50cyA9IGNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZVBvaW50cycpXTtcclxuXHJcbiAgICBwb2ludHMucHVzaChwb2ludCk7XHJcblxyXG4gICAgLy9zdG9yZSB0aGUgbGFzdCAxMDAgc3RvcmVkIHBvc2l0aW9ucyBmb3IgaG92ZXIgZGV0ZWN0aW9uXHJcbiAgICBpZiAocG9pbnRzLmxlbmd0aCA+IDEwMCkge1xyXG4gICAgICBwb2ludHMuc3BsaWNlKDAsIHBvaW50cy5sZW5ndGggLSAxMDApO1xyXG4gICAgfVxyXG5cclxuICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH07XHJcblxyXG4gIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCAoZXZ0KSA9PiBtb3VzZU1vdmUoZXZ0KSk7XHJcbiAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChldnQpID0+IHtcclxuICAgIGxldCB7IHRhcmdldCB9ID0gZXZ0O1xyXG4gICAgaWYgKHRhcmdldCA9PT0gY2FudmFzKSB7XHJcbiAgICAgIGxldCBtb3VzZURhdGEgPSBjYW52YXNbU3ltYm9sLmZvcignbW91c2VEYXRhJyldO1xyXG5cclxuICAgICAgaWYgKCFtb3VzZURhdGEuc3RhdGUpIHtcclxuICAgICAgICBtb3VzZURhdGEuY2xpY2tlZCArPSAxO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBtb3VzZURhdGEuc3RhdGUgPSB0cnVlO1xyXG4gICAgICByZXR1cm4gbW91c2VNb3ZlKGV2dCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoZXZ0KSA9PiB7XHJcbiAgICBsZXQgbW91c2VEYXRhID0gY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlRGF0YScpXTtcclxuICAgIG1vdXNlRGF0YS5zdGF0ZSA9IGZhbHNlO1xyXG4gICAgcmV0dXJuIG1vdXNlTW92ZShldnQpO1xyXG4gIH0pO1xyXG4gIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgKGV2dCkgPT4ge1xyXG4gICAgY2FudmFzW1N5bWJvbC5mb3IoJ2tleURhdGEnKV1ba2V5Y29kZShldnQua2V5Q29kZSldID0gdHJ1ZTtcclxuICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH0pO1xyXG4gIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdrZXl1cCcsIChldnQpID0+IHtcclxuICAgIGNhbnZhc1tTeW1ib2wuZm9yKCdrZXlEYXRhJyldW2tleWNvZGUoZXZ0LmtleUNvZGUpXSA9IGZhbHNlO1xyXG4gICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfSk7XHJcbn07XG5cbi8qKiovIH0sXG4vKiAzMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gKGN0eCkgPT4gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdrZXlEYXRhJyldO1xuXG4vKioqLyB9LFxuLyogMzMgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5sZXQgZW5kID0gbmV3IEluc3RydWN0aW9uKCdlbmRMaW5lU3R5bGUnKTtcclxuXHJcbmxldCBsaW5lU3R5bGUgPSAodmFsdWUsIC4uLmNoaWxkcmVuKSA9PiB7XHJcblxyXG4gIHZhbHVlID0gdmFsdWUgfHwge307XHJcbiAgdmFyIHJlc3VsdCA9IHtcclxuICAgIGxpbmVXaWR0aDogbnVsbCxcclxuICAgIGxpbmVDYXA6IG51bGwsXHJcbiAgICBsaW5lSm9pbjogbnVsbCxcclxuICAgIG1pdGVyTGltaXQ6IG51bGwsXHJcbiAgICBsaW5lRGFzaDogbnVsbCxcclxuICAgIGxpbmVEYXNoT2Zmc2V0OiBudWxsXHJcbiAgfTtcclxuXHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5saW5lV2lkdGggIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZVdpZHRoID0gdmFsdWUubGluZVdpZHRoO1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLmxpbmVDYXAgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZUNhcCA9IHZhbHVlLmxpbmVDYXA7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUubGluZUpvaW4gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZUpvaW4gPSB2YWx1ZS5saW5lSm9pbjtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5taXRlckxpbWl0ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0Lm1pdGVyTGltaXQgPSB2YWx1ZS5taXRlckxpbWl0O1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLmxpbmVEYXNoICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LmxpbmVEYXNoID0gdmFsdWUubGluZURhc2ggfHwgW107XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUubGluZURhc2hPZmZzZXQgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZURhc2hPZmZzZXQgPSB2YWx1ZS5saW5lRGFzaE9mZnNldDtcclxuICB9XHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignbGluZVN0eWxlJywgcmVzdWx0KSxcclxuICAgIGNoaWxkcmVuLFxyXG4gICAgZW5kXHJcbiAgXTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbGluZVN0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxubW9kdWxlLmV4cG9ydHMgPSAoY3R4KSA9PiBjdHguY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlRGF0YScpXTtcblxuLyoqKi8gfSxcbi8qIDM1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IG1vdmVUbyA9IF9fd2VicGFja19yZXF1aXJlX18oNyksIGxpbmVUbyA9IF9fd2VicGFja19yZXF1aXJlX18oNik7XHJcblxyXG5sZXQgbW92ZVRvTGluZVRvID0gKHBvaW50LCBpbmRleCkgPT4gaW5kZXggPT09IDAgP1xyXG4gIG1vdmVUbyhwb2ludFswXSwgcG9pbnRbMV0pIDpcclxuICBsaW5lVG8ocG9pbnRbMF0sIHBvaW50WzFdKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbW92ZVRvTGluZVRvO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IGJlZ2luUGF0aCA9IF9fd2VicGFja19yZXF1aXJlX18oMikoKSxcclxuICAgIGNsb3NlUGF0aCA9IF9fd2VicGFja19yZXF1aXJlX18oMykoKTtcclxuXHJcbmxldCBwYXRoID0gKC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgYmVnaW5QYXRoLFxyXG4gIGNoaWxkcmVuLFxyXG4gIGNsb3NlUGF0aFxyXG5dO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBwYXRoO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbigncGxhY2Vob2xkZXInKTtcclxubGV0IHBsYWNlSG9sZGVyID0gKCkgPT4gY2FjaGU7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHBsYWNlSG9sZGVyO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM4ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBxdWFkcmF0aWNDdXJ2ZVRvID0gKGNweCwgY3B5LCB4LCB5KSA9PiBuZXcgSW5zdHJ1Y3Rpb24oJ3F1YWRyYXRpY0N1cnZlVG8nLCB7XHJcbiAgY3B4LFxyXG4gIGNweSxcclxuICB4LFxyXG4gIHlcclxufSk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHF1YWRyYXRpY0N1cnZlVG87XHJcblxuXG4vKioqLyB9LFxuLyogMzkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5sZXQgcmFmID0gKGZ1bmMpID0+IHtcclxuICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gcmFmKGZ1bmMpKTtcclxuICByZXR1cm4gZnVuYygpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByYWY7XG5cbi8qKiovIH0sXG4vKiA0MCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgcmVjdCA9ICguLi5hcmdzKSA9PiBuZXcgSW5zdHJ1Y3Rpb24oJ3JlY3QnLFxyXG4gIGFyZ3MubGVuZ3RoID4gMiA/XHJcbiAgICB7IHg6IGFyZ3NbMF0sIHk6IGFyZ3NbMV0sIHdpZHRoOiBhcmdzWzJdLCBoZWlnaHQ6IGFyZ3NbM10gfSA6XHJcbiAgICB7IHg6IDAsIHk6IDAsIHdpZHRoOiBhcmdzWzBdLCBoZWlnaHQ6IGFyZ3NbMV0gfVxyXG4pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByZWN0O1xyXG5cblxuLyoqKi8gfSxcbi8qIDQxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHJcbi8vaW5pdGlhbGl6ZSBhbGwgdGhlIHByb3BlcnRpZXNcclxuXHJcbmxldCBpZGVudGl0eSA9IFsxLCAwLCAwLCAxLCAwLCAwXSxcclxuICBtYXRyaXggPSBuZXcgRmxvYXQ2NEFycmF5KGlkZW50aXR5KSxcclxuICBmaWxsU3R5bGVTdGFjayA9IFtdLFxyXG4gIHN0cm9rZVN0eWxlU3RhY2sgPSBbXSxcclxuICBsaW5lU3R5bGVTdGFjayA9IFtdLFxyXG4gIHRleHRTdHlsZVN0YWNrID0gW10sXHJcbiAgc2hhZG93U3R5bGVTdGFjayA9IFtdLFxyXG4gIGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvblN0YWNrID0gW10sXHJcbiAgZ2xvYmFsQWxwaGFTdGFjayA9IFtdLFxyXG4gIGltYWdlU21vb3RoaW5nRW5hYmxlZFN0YWNrID0gW10sXHJcbiAgdHJhbnNmb3JtU3RhY2sgPSBuZXcgRmxvYXQ2NEFycmF5KDUwMSAqIDYpLFxyXG4gIHRyYW5zZm9ybVN0YWNrSW5kZXggPSA2LFxyXG4gIGNvbmNhdCA9IFtdLmNvbmNhdCxcclxuICBzdXBwb3J0c0VsbGlwc2UgPSBmYWxzZTtcclxuXHJcbmlmICh0eXBlb2YgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEICE9PSAndW5kZWZpbmVkJykge1xyXG4gIHN1cHBvcnRzRWxsaXBzZSA9IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkoJ2VsbGlwc2UnKTtcclxufVxyXG5cclxuLy90cmFuc2Zvcm0gcG9pbnRzIGZ1bmN0aW9uXHJcbmNvbnN0IHRyYW5zZm9ybVBvaW50cyA9IF9fd2VicGFja19yZXF1aXJlX18oMSk7XHJcbmNvbnN0IGN5Y2xlTW91c2VEYXRhID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTtcclxuXHJcbmNvbnN0IGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplID0gKCkgPT4ge1xyXG4gIGxldCBjYWNoZSA9IHRyYW5zZm9ybVN0YWNrO1xyXG4gIHRyYW5zZm9ybVN0YWNrID0gbmV3IEZsb2F0NjRBcnJheSh0cmFuc2Zvcm1TdGFjay5sZW5ndGggKyA2MDApOyAvL2FkZCAxMDAgbW9yZVxyXG4gIHRyYW5zZm9ybVN0YWNrLnNldChjYWNoZSk7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG50cmFuc2Zvcm1TdGFjay5zZXQoaWRlbnRpdHkpO1xyXG5cclxuY29uc3QgUEkyID0gTWF0aC5QSSAqIDI7XHJcblxyXG5sZXQgZW1wdHkgPSAodGFyZ2V0KSA9PiB0YXJnZXQgJiYgdGFyZ2V0LnNwbGljZSgwLCB0YXJnZXQubGVuZ3RoKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gKC4uLmFyZ3MpID0+IHtcclxuICBsZXQgY2hpbGRyZW4gPSBhcmdzLnNsaWNlKDAsIC0xKSxcclxuICAgY3R4ID0gYXJnc1thcmdzLmxlbmd0aCAtIDFdO1xyXG5cclxuICBsZXQgcmVnaW9ucyA9IGN0eC5jYW52YXNbU3ltYm9sLmZvcigncmVnaW9ucycpXSxcclxuICAgIG1vdXNlUG9pbnRzID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZVBvaW50cycpXSxcclxuICAgIGV4dGVuc2lvbnMgPSBjdHguY2FudmFzW1N5bWJvbC5mb3IoJ2V4dGVuc2lvbnMnKV07XHJcblxyXG4gIGxldCBjYWNoZTtcclxuXHJcbiAgY3ljbGVNb3VzZURhdGEoY3R4KTtcclxuXHJcbiAgZW1wdHkocmVnaW9ucyk7XHJcbiAgZW1wdHkobW91c2VQb2ludHMpO1xyXG5cclxuICBsZXQgbGVuID0gY2hpbGRyZW4ubGVuZ3RoO1xyXG5cclxuICAvL2ZsYXR0ZW4gY2hpbGRyZW4gZHVyaW5nIHRoZSBsb29wIHByb2Nlc3MgdG8gc2F2ZSBjcHVcclxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBsZXQgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuXHJcbiAgICAvL2ZsYXR0ZW5pbmcgYWxnb3JpdGhtXHJcbiAgICBpZiAoY2hpbGQgJiYgY2hpbGQuY29uc3RydWN0b3IgPT09IEFycmF5KSB7XHJcbiAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgIGNoaWxkID0gY2hpbGRyZW5baV07XHJcblxyXG4gICAgICAvL3JlcGVhdCBhcyBuZWNlc3NhcnlcclxuICAgICAgd2hpbGUgKGNoaWxkICYmIGNoaWxkLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuICAgICAgfVxyXG5cclxuICAgICAgbGVuID0gY2hpbGRyZW4ubGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIC8vY2hpbGQgbXVzdCBiZSB0cnV0aHlcclxuICAgIGlmICghY2hpbGQpIHtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHsgcHJvcHMsIHR5cGUgfSA9IGNoaWxkO1xyXG5cclxuICAgIGlmICh0eXBlID09PSAndHJhbnNmb3JtJykge1xyXG5cclxuICAgICAgLy9jb3B5IHRyYW5zZm9ybVN0YWNrIHZhbHVlcyB0byBtYXRyaXhcclxuICAgICAgbWF0cml4WzBdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV07XHJcbiAgICAgIG1hdHJpeFsyXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl07XHJcbiAgICAgIG1hdHJpeFs1XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuXHJcbiAgICAgIC8vaW5jcmVhc2UgdGhlIGluZGV4XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvL3BlcmZvcm0gdGhlIHRyYW5zZm9ybSBtYXRoXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9IC8vZFxyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzWzBdICsgbWF0cml4WzJdICogcHJvcHNbMV07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IC8vYlxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzWzBdICsgbWF0cml4WzNdICogcHJvcHNbMV07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IC8vY1xyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzWzJdICsgbWF0cml4WzJdICogcHJvcHNbM107XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9IC8vZFxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzWzJdICsgbWF0cml4WzNdICogcHJvcHNbM107XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IC8vZVxyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzWzRdICsgbWF0cml4WzJdICogcHJvcHNbNV0gKyBtYXRyaXhbNF07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IC8vZlxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzWzRdICsgbWF0cml4WzNdICogcHJvcHNbNV0gKyBtYXRyaXhbNV07XHJcblxyXG4gICAgICAvL21vZGlmeSB0aGUgY3R4XHJcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0oXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNF0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMV1cclxuICAgICAgKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzZXRUcmFuc2Zvcm0nKSB7XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0gPSBwcm9wc1swXTsvL2FcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdID0gcHJvcHNbMV07Ly9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IHByb3BzWzJdOy8vY1xyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10gPSBwcm9wc1szXTsvL2RcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdID0gcHJvcHNbNF07Ly9lXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IHByb3BzWzVdOy8vZlxyXG4gICAgICBjdHguc2V0VHJhbnNmb3JtKHByb3BzWzBdLCBwcm9wc1sxXSwgcHJvcHNbMl0sIHByb3BzWzNdLCBwcm9wc1s0XSwgcHJvcHNbNV0pO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzY2FsZScpIHtcclxuICAgICAgbWF0cml4WzBdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV07XHJcbiAgICAgIG1hdHJpeFsyXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl07XHJcbiAgICAgIG1hdHJpeFs1XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0gPSBtYXRyaXhbMF0gKiBwcm9wcy54OyAvL2FcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdID0gbWF0cml4WzFdICogcHJvcHMueDsgLy9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IG1hdHJpeFsyXSAqIHByb3BzLnk7IC8vY1xyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10gPSBtYXRyaXhbM10gKiBwcm9wcy55OyAvL2RcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdID0gbWF0cml4WzRdOyAvL2VcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gbWF0cml4WzVdOyAvL2ZcclxuXHJcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0oXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNF0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMV1cclxuICAgICAgKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAndHJhbnNsYXRlJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCArPSA2O1xyXG4gICAgICBpZiAodHJhbnNmb3JtU3RhY2tJbmRleCA+IHRyYW5zZm9ybVN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9IG1hdHJpeFswXTsgLy9hXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IG1hdHJpeFsxXTsgLy9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IG1hdHJpeFsyXTsgLy9jXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9IG1hdHJpeFszXTsgLy9kXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IG1hdHJpeFs0XSArIG1hdHJpeFswXSAqIHByb3BzLnggKyBtYXRyaXhbMl0gKiBwcm9wcy55OyAvL2VcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gbWF0cml4WzVdICsgbWF0cml4WzFdICogcHJvcHMueCArIG1hdHJpeFszXSAqIHByb3BzLnk7IC8vZlxyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICApO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3JvdGF0ZScpIHtcclxuICAgICAgbWF0cml4WzBdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV07XHJcbiAgICAgIG1hdHJpeFsyXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl07XHJcbiAgICAgIG1hdHJpeFs1XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0gPVxyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzLmNvcyArIG1hdHJpeFsyXSAqIHByb3BzLnNpbjsgLy9hXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9XHJcbiAgICAgICAgbWF0cml4WzFdICogcHJvcHMuY29zICsgbWF0cml4WzNdICogcHJvcHMuc2luOyAvL2JcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdID1cclxuICAgICAgICBtYXRyaXhbMF0gKiAtcHJvcHMuc2luICsgbWF0cml4WzJdICogcHJvcHMuY29zOyAvL2NcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdID1cclxuICAgICAgICBtYXRyaXhbMV0gKiAtcHJvcHMuc2luICsgbWF0cml4WzNdICogcHJvcHMuY29zOyAvL2RcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdID0gbWF0cml4WzRdOyAvL2VcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gbWF0cml4WzVdOy8vZlxyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICApO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3NrZXdYJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCArPSA2O1xyXG4gICAgICBpZiAodHJhbnNmb3JtU3RhY2tJbmRleCA+IHRyYW5zZm9ybVN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9IG1hdHJpeFswXTsgLy9hXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IG1hdHJpeFsxXTsgLy9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IC8vY1xyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzLnggKyBtYXRyaXhbMl07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9IC8vZFxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzLnggKyBtYXRyaXhbM107XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IG1hdHJpeFs0XTsgLy9lXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IG1hdHJpeFs1XTsgLy9mXHJcblxyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICApO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3NrZXdZJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCArPSA2O1xyXG4gICAgICBpZiAodHJhbnNmb3JtU3RhY2tJbmRleCA+IHRyYW5zZm9ybVN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9XHJcbiAgICAgICAgbWF0cml4WzBdICogMSArIG1hdHJpeFsyXSAqIHByb3BzLnk7IC8vYVxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0gPVxyXG4gICAgICAgIG1hdHJpeFsxXSAqIDEgKyBtYXRyaXhbM10gKiBwcm9wcy55OyAvL2JcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdID0gbWF0cml4WzJdOyAvL2NcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdID0gbWF0cml4WzNdOyAvL2RcclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IG1hdHJpeFs0XTsgLy9lXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IG1hdHJpeFs1XTsgLy9mXHJcblxyXG4gICAgICBjdHguc2V0VHJhbnNmb3JtKFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAncmVzdG9yZScpIHtcclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCAtPSA2O1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShtYXRyaXhbMF0sIG1hdHJpeFsxXSwgbWF0cml4WzJdLCBtYXRyaXhbM10sIG1hdHJpeFs0XSwgbWF0cml4WzVdKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsUmVjdCcpIHtcclxuICAgICAgY3R4LmZpbGxSZWN0KHByb3BzLngsIHByb3BzLnksIHByb3BzLndpZHRoLCBwcm9wcy5oZWlnaHQpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3N0cm9rZVJlY3QnKSB7XHJcbiAgICAgIGN0eC5zdHJva2VSZWN0KHByb3BzLngsIHByb3BzLnksIHByb3BzLndpZHRoLCBwcm9wcy5oZWlnaHQpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2NsZWFyUmVjdCcpIHtcclxuICAgICAgY3R4LmNsZWFyUmVjdChwcm9wcy54LCBwcm9wcy55LCBwcm9wcy53aWR0aCwgcHJvcHMuaGVpZ2h0KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdyZWN0Jykge1xyXG4gICAgICBjdHgucmVjdChwcm9wcy54LCBwcm9wcy55LCBwcm9wcy53aWR0aCwgcHJvcHMuaGVpZ2h0KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsU3R5bGUnKSB7XHJcbiAgICAgIGZpbGxTdHlsZVN0YWNrLnB1c2goY3R4LmZpbGxTdHlsZSk7XHJcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBwcm9wcy52YWx1ZTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzdHJva2VTdHlsZScpIHtcclxuICAgICAgc3Ryb2tlU3R5bGVTdGFjay5wdXNoKGN0eC5zdHJva2VTdHlsZSk7XHJcbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9IHByb3BzLnZhbHVlO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZEZpbGxTdHlsZScpIHtcclxuICAgICAgY3R4LmZpbGxTdHlsZSA9IGZpbGxTdHlsZVN0YWNrLnBvcCgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRTdHJva2VTdHlsZScpIHtcclxuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gc3Ryb2tlU3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZSA9PT0gJ2xpbmVTdHlsZScpIHtcclxuICAgICAgbGluZVN0eWxlU3RhY2sucHVzaCh7XHJcbiAgICAgICAgbGluZVdpZHRoOiBjdHgubGluZVdpZHRoLFxyXG4gICAgICAgIGxpbmVDYXA6IGN0eC5saW5lQ2FwLFxyXG4gICAgICAgIGxpbmVKb2luOiBjdHgubGluZUpvaW4sXHJcbiAgICAgICAgbWl0ZXJMaW1pdDogY3R4Lm1pdGVyTGltaXQsXHJcbiAgICAgICAgbGluZURhc2g6IGN0eC5nZXRMaW5lRGFzaCgpLFxyXG4gICAgICAgIGxpbmVEYXNoT2Zmc2V0OiBjdHgubGluZURhc2hPZmZzZXRcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBpZiAocHJvcHMubGluZVdpZHRoICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IHByb3BzLmxpbmVXaWR0aDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZUNhcCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5saW5lQ2FwID0gcHJvcHMubGluZUNhcDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZUpvaW4gIT09IG51bGwpIHtcclxuICAgICAgICBjdHgubGluZUpvaW4gPSBwcm9wcy5saW5lSm9pbjtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubWl0ZXJMaW1pdCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5taXRlckxpbWl0ID0gcHJvcHMubWl0ZXJMaW1pdDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZURhc2ggIT09IG51bGwpIHtcclxuICAgICAgICBjdHguc2V0TGluZURhc2gocHJvcHMubGluZURhc2gpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAocHJvcHMubGluZURhc2hPZmZzZXQgIT09IG51bGwpIHtcclxuICAgICAgICBjdHgubGluZURhc2hPZmZzZXQgPSBwcm9wcy5saW5lRGFzaE9mZnNldDtcclxuICAgICAgfVxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZExpbmVTdHlsZScpIHtcclxuICAgICAgY2FjaGUgPSBsaW5lU3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LmxpbmVXaWR0aCA9IGNhY2hlLmxpbmVXaWR0aDtcclxuICAgICAgY3R4LmxpbmVDYXAgPSBjYWNoZS5saW5lQ2FwO1xyXG4gICAgICBjdHgubGluZUpvaW4gPSBjYWNoZS5saW5lSm9pbjtcclxuICAgICAgY3R4Lm1pdGVyTGltaXQgPSBjYWNoZS5taXRlckxpbWl0O1xyXG4gICAgICBjdHguc2V0TGluZURhc2goY2FjaGUubGluZURhc2gpO1xyXG4gICAgICBjdHgubGluZURhc2hPZmZzZXQgPSBjYWNoZS5saW5lRGFzaE9mZnNldDtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICd0ZXh0U3R5bGUnKSB7XHJcbiAgICAgIHRleHRTdHlsZVN0YWNrLnB1c2goe1xyXG4gICAgICAgIGZvbnQ6IGN0eC5mb250LFxyXG4gICAgICAgIHRleHRBbGlnbjogY3R4LnRleHRBbGlnbixcclxuICAgICAgICB0ZXh0QmFzZWxpbmU6IGN0eC50ZXh0QmFzZWxpbmUsXHJcbiAgICAgICAgZGlyZWN0aW9uOiBjdHguZGlyZWN0aW9uXHJcbiAgICAgIH0pO1xyXG4gICAgICBpZiAocHJvcHMuZm9udCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5mb250ID0gcHJvcHMuZm9udDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMudGV4dEFsaWduICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnRleHRBbGlnbiA9IHByb3BzLnRleHRBbGlnbjtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMudGV4dEJhc2VsaW5lICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnRleHRCYXNlbGluZSA9IHByb3BzLnRleHRCYXNlbGluZTtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMuZGlyZWN0aW9uICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmRpcmVjdGlvbiA9IHByb3BzLmRpcmVjdGlvbjtcclxuICAgICAgfVxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZFRleHRTdHlsZScpIHtcclxuICAgICAgY2FjaGUgPSB0ZXh0U3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LmZvbnQgPSBjYWNoZS5mb250O1xyXG4gICAgICBjdHgudGV4dEFsaWduID0gY2FjaGUudGV4dEFsaWduO1xyXG4gICAgICBjdHgudGV4dEJhc2VsaW5lID0gY2FjaGUudGV4dEJhc2VsaW5lO1xyXG4gICAgICBjdHguZGlyZWN0aW9uID0gY2FjaGUuZGlyZWN0aW9uO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3NoYWRvd1N0eWxlJykge1xyXG4gICAgICBzaGFkb3dTdHlsZVN0YWNrLnB1c2goe1xyXG4gICAgICAgIHNoYWRvd0JsdXI6IGN0eC5zaGFkb3dCbHVyLFxyXG4gICAgICAgIHNoYWRvd0NvbG9yOiBjdHguc2hhZG93Q29sb3IsXHJcbiAgICAgICAgc2hhZG93T2Zmc2V0WDogY3R4LnNoYWRvd09mZnNldFgsXHJcbiAgICAgICAgc2hhZG93T2Zmc2V0WTogY3R4LnNoYWRvd09mZnNldFlcclxuICAgICAgfSk7XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dCbHVyICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd0JsdXIgPSBwcm9wcy5zaGFkb3dCbHVyO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dDb2xvciAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5zaGFkb3dDb2xvciA9IHByb3BzLnNoYWRvd0NvbG9yO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dPZmZzZXRYICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBwcm9wcy5zaGFkb3dPZmZzZXRYO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dPZmZzZXRZICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFkgPSBwcm9wcy5zaGFkb3dPZmZzZXRZO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kU2hhZG93U3R5bGUnKSB7XHJcbiAgICAgIGNhY2hlID0gc2hhZG93U3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LnNoYWRvd0JsdXIgPSBjYWNoZS5zaGFkb3dCbHVyO1xyXG4gICAgICBjdHguc2hhZG93Q29sb3IgPSBjYWNoZS5zaGFkb3dDb2xvcjtcclxuICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBjYWNoZS5zaGFkb3dPZmZzZXRYO1xyXG4gICAgICBjdHguc2hhZG93T2Zmc2V0WSA9IGNhY2hlLnNoYWRvd09mZnNldFk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc3Ryb2tlVGV4dCcpIHtcclxuICAgICAgaWYgKHByb3BzLm1heFdpZHRoKSB7XHJcbiAgICAgICAgY3R4LnN0cm9rZVRleHQocHJvcHMudGV4dCwgcHJvcHMueCwgcHJvcHMueSwgcHJvcHMubWF4V2lkdGgpO1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5zdHJva2VUZXh0KHByb3BzLnRleHQsIHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxUZXh0Jykge1xyXG4gICAgICBpZiAocHJvcHMubWF4V2lkdGgpIHtcclxuICAgICAgICBjdHguZmlsbFRleHQocHJvcHMudGV4dCwgcHJvcHMueCwgcHJvcHMueSwgcHJvcHMubWF4V2lkdGgpO1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5maWxsVGV4dChwcm9wcy50ZXh0LCBwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdkcmF3SW1hZ2UnKSB7XHJcbiAgICAgIGN0eC5kcmF3SW1hZ2UocHJvcHMuaW1nLCBwcm9wcy5keCwgcHJvcHMuZHkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2RyYXdJbWFnZVNpemUnKSB7XHJcbiAgICAgIGN0eC5kcmF3SW1hZ2UocHJvcHMuaW1nLCBwcm9wcy5keCwgcHJvcHMuZHksIHByb3BzLmRXaWR0aCwgcHJvcHMuZEhlaWdodCk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZHJhd0ltYWdlU291cmNlJykge1xyXG4gICAgICBjdHguZHJhd0ltYWdlKHByb3BzLmltZywgcHJvcHMuc3gsIHByb3BzLnN5LCBwcm9wcy5zV2lkdGgsIHByb3BzLnNIZWlnaHQsIHByb3BzLmR4LCBwcm9wcy5keSwgcHJvcHMuZFdpZHRoLCBwcm9wcy5kSGVpZ2h0KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzdHJva2VBcmMnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgcHJvcHMuY291bnRlcmNsb2Nrd2lzZSk7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY3R4LnN0cm9rZSgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxBcmMnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgcHJvcHMuY291bnRlcmNsb2Nrd2lzZSk7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY3R4LmZpbGwoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdtb3ZlVG8nKSB7XHJcbiAgICAgIGN0eC5tb3ZlVG8ocHJvcHMueCwgcHJvcHMueSk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnbGluZVRvJykge1xyXG4gICAgICBjdHgubGluZVRvKHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2JlemllckN1cnZlVG8nKSB7XHJcbiAgICAgIGN0eC5iZXppZXJDdXJ2ZVRvKHByb3BzLmNwMXgsIHByb3BzLmNwMXksIHByb3BzLmNwMngsIHByb3BzLmNwMnksIHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3F1YWRyYXRpY0N1cnZlVG8nKSB7XHJcbiAgICAgIGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHByb3BzLmNweCwgcHJvcHMuY3B5LCBwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdhcmMnKSB7XHJcbiAgICAgIGN0eC5hcmMocHJvcHMueCwgcHJvcHMueSwgcHJvcHMuciwgcHJvcHMuc3RhcnRBbmdsZSwgcHJvcHMuZW5kQW5nbGUsIHByb3BzLmNvdW50ZXJjbG9ja3dpc2UpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2FyY1RvJykge1xyXG4gICAgICBjdHguYXJjVG8ocHJvcHMueDEsIHByb3BzLnkxLCBwcm9wcy54MiwgcHJvcHMueTIsIHByb3BzLnIpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VsbGlwc2UnKSB7XHJcbiAgICAgIC8vaWYgdGhlIG1ldGhvZCBpcyBwcm92aWRlZCBieSB0aGUgYnJvd3NlclxyXG4gICAgICBpZiAoc3VwcG9ydHNFbGxpcHNlKSB7XHJcbiAgICAgICAgY3R4LmVsbGlwc2UoXHJcbiAgICAgICAgICBwcm9wcy54LFxyXG4gICAgICAgICAgcHJvcHMueSxcclxuICAgICAgICAgIHByb3BzLnJhZGl1c1gsXHJcbiAgICAgICAgICBwcm9wcy5yYWRpdXNZLFxyXG4gICAgICAgICAgcHJvcHMucm90YXRpb24sXHJcbiAgICAgICAgICBwcm9wcy5zdGFydEFuZ2xlLFxyXG4gICAgICAgICAgcHJvcHMuZW5kQW5nbGUsXHJcbiAgICAgICAgICBwcm9wcy5hbnRpY2xvY2t3aXNlXHJcbiAgICAgICAgKTtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjdHgucm90YXRlKHByb3BzLnJvdGF0aW9uKTtcclxuICAgICAgY3R4LnNjYWxlKHByb3BzLnJhZGl1c1gsIHByb3BzLnJhZGl1c1kpO1xyXG4gICAgICBjdHguYXJjKDAsIDAsIDEsIHByb3BzLnN0YXJ0QW5nbGUsIHByb3BzLmVuZEFuZ2xlLCBwcm9wcy5hbnRpY2xvY2t3aXNlKTtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdnbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSB7XHJcbiAgICAgIGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvblN0YWNrLnB1c2goY3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbik7XHJcbiAgICAgIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSBwcm9wcy52YWx1ZTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRHbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSB7XHJcbiAgICAgIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSBnbG9iYWxDb21wb3NpdGVPcGVyYXRpb25TdGFjay5wb3AoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsJykge1xyXG4gICAgICBjdHguZmlsbCgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3N0cm9rZScpIHtcclxuICAgICAgY3R4LnN0cm9rZSgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2JlZ2luQ2xpcCcpIHtcclxuICAgICAgY3R4LnNhdmUoKTtcclxuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2NsaXAnKSB7XHJcbiAgICAgIGN0eC5jbGlwKCk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kQ2xpcCcpIHtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdiZWdpblBhdGgnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdjbG9zZVBhdGgnKSB7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdnbG9iYWxBbHBoYScpIHtcclxuICAgICAgZ2xvYmFsQWxwaGFTdGFjay5wdXNoKGN0eC5nbG9iYWxBbHBoYSk7XHJcbiAgICAgIGN0eC5nbG9iYWxBbHBoYSAqPSBwcm9wcy52YWx1ZTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRHbG9iYWxBbHBoYScpIHtcclxuICAgICAgY3R4Lmdsb2JhbEFscGhhID0gZ2xvYmFsQWxwaGFTdGFjay5wb3AoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdoaXRSZWN0JyAmJiByZWdpb25zKSB7XHJcbiAgICAgIGNhY2hlID0gW1xyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdXHJcbiAgICAgIF07XHJcblxyXG4gICAgICByZWdpb25zLnB1c2goe1xyXG4gICAgICAgIGlkOiBwcm9wcy5pZCxcclxuICAgICAgICBwb2ludHM6IHByb3BzLnBvaW50cyxcclxuICAgICAgICBtYXRyaXg6IGNhY2hlLFxyXG4gICAgICAgIC8vcmVjdGFuZ2xlIVxyXG4gICAgICAgIHBvbHlnb246IGZhbHNlLFxyXG4gICAgICAgIGhvdmVyOiBmYWxzZSxcclxuICAgICAgICB0b3VjaGVkOiBmYWxzZSxcclxuICAgICAgICBjbGlja2VkOiBmYWxzZVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2hpdFJlZ2lvbicgJiYgcmVnaW9ucykge1xyXG4gICAgICBjYWNoZSA9IFtcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICBdO1xyXG5cclxuICAgICAgcmVnaW9ucy5wdXNoKHtcclxuICAgICAgICBpZDogcHJvcHMuaWQsXHJcbiAgICAgICAgcG9pbnRzOiBwcm9wcy5wb2ludHMsXHJcbiAgICAgICAgbWF0cml4OiBjYWNoZSxcclxuICAgICAgICBwb2x5Z29uOiB0cnVlLFxyXG4gICAgICAgIGhvdmVyOiBmYWxzZSxcclxuICAgICAgICB0b3VjaGVkOiBmYWxzZSxcclxuICAgICAgICBjbGlja2VkOiBmYWxzZVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnaW1hZ2VTbW9vdGhpbmdFbmFibGVkJykge1xyXG4gICAgICBpbWFnZVNtb290aGluZ0VuYWJsZWRTdGFjay5wdXNoKGN0eC5pbWFnZVNtb290aGluZ0VuYWJsZWQpO1xyXG4gICAgICBjdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gcHJvcHMudmFsdWU7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZEltYWdlU21vb3RoaW5nRW5hYmxlZCcpIHtcclxuICAgICAgY3R4LmltYWdlU21vb3RoaW5nRW5hYmxlZCA9IGltYWdlU21vb3RoaW5nRW5hYmxlZFN0YWNrLnBvcCgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZXh0ZW5zaW9ucyAmJiBleHRlbnNpb25zW3R5cGVdKSB7XHJcbiAgICAgIGV4dGVuc2lvbnNbdHlwZV0ocHJvcHMsIGN0eCk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG4gIH1cclxufTtcblxuLyoqKi8gfSxcbi8qIDQyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IHNldFRyYW5zZm9ybSA9IF9fd2VicGFja19yZXF1aXJlX18oOSk7XHJcblxyXG5sZXQgcmVzZXRUcmFuc2Zvcm0gPSAoLi4uY2hpbGRyZW4pID0+IHNldFRyYW5zZm9ybShbMSwgMCwgMCwgMSwgMCwgMF0sIGNoaWxkcmVuKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcmVzZXRUcmFuc2Zvcm07XG5cbi8qKiovIH0sXG4vKiA0MyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ3Jlc3RvcmUnKTtcclxuXHJcbmxldCByb3RhdGUgPSAociwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ3JvdGF0ZScsIHsgY29zOiBNYXRoLmNvcyhyKSwgc2luOiBNYXRoLnNpbihyKSB9KSxcclxuICBjaGlsZHJlbixcclxuICBlbmRcclxuXTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcm90YXRlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHNjYWxlID0gKHgsIHksIC4uLmNoaWxkcmVuKSA9PiB7XHJcbiAgaWYgKHR5cGVvZiB5ICE9PSAnbnVtYmVyJykge1xyXG4gICAgY2hpbGRyZW4gPSBbeV0uY29uY2F0KGNoaWxkcmVuKTtcclxuICAgIHkgPSB4O1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignc2NhbGUnLCB7IHgsIHkgfSksXHJcbiAgICBjaGlsZHJlbixcclxuICAgIGVuZFxyXG4gIF07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNjYWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbignZW5kU2hhZG93U3R5bGUnKTtcclxuXHJcbmxldCBzaGFkb3dTdHlsZSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IHtcclxuICB2YWx1ZSA9IHZhbHVlIHx8IHt9O1xyXG4gIHZhciByZXN1bHQgPSB7XHJcbiAgICBzaGFkb3dCbHVyOiBudWxsLFxyXG4gICAgc2hhZG93Q29sb3I6IG51bGwsXHJcbiAgICBzaGFkb3dPZmZzZXRYOiBudWxsLFxyXG4gICAgc2hhZG93T2Zmc2V0WTogbnVsbFxyXG4gIH07XHJcblxyXG4gIGlmICh0eXBlb2YgdmFsdWUuc2hhZG93Qmx1ciAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5zaGFkb3dCbHVyID0gdmFsdWUuc2hhZG93Qmx1cjtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5zaGFkb3dDb2xvciAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5zaGFkb3dDb2xvciA9IHZhbHVlLnNoYWRvd0NvbG9yO1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLnNoYWRvd09mZnNldFggIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuc2hhZG93T2Zmc2V0WCA9IHZhbHVlLnNoYWRvd09mZnNldFg7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUuZGlyZWN0aW9uICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LnNoYWRvd09mZnNldFkgPSB2YWx1ZS5zaGFkb3dPZmZzZXRZO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignc2hhZG93U3R5bGUnLCB2YWx1ZSksXHJcbiAgICBjaGlsZHJlbixcclxuICAgIGVuZFxyXG4gIF07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNoYWRvd1N0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHNrZXdYID0gKHgsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgbmV3IEluc3RydWN0aW9uKCdza2V3WCcsIHsgeDogTWF0aC50YW4oeCkgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNrZXdYO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHNrZXdZID0gKHgsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgbmV3IEluc3RydWN0aW9uKCdza2V3WScsIHsgeTogTWF0aC50YW4oeSkgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNrZXdZO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ4ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGNhY2hlID0gbmV3IEluc3RydWN0aW9uKCdzdHJva2UnKTtcclxuXHJcbmxldCBzdHJva2UgPSAoKSA9PiBjYWNoZTtcclxubW9kdWxlLmV4cG9ydHMgPSBzdHJva2U7XHJcblxuXG4vKioqLyB9LFxuLyogNDkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApLFxyXG4gICAgcGkyID0gTWF0aC5QSSAqIDI7XHJcblxyXG5sZXQgc3Ryb2tlQXJjID0gKC4uLmFyZ3MpID0+IHtcclxuICBsZXQgW3gsIHksIHIsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBjb3VudGVyY2xvY2t3aXNlXSA9IGFyZ3M7XHJcbiAgbGV0IHByb3BzID0geyB4OiAwLCB5OiAwLCByOiB4LCBzdGFydEFuZ2xlOiAwLCBlbmRBbmdsZTogcGkyLCBjb3VudGVyY2xvY2t3aXNlOiBmYWxzZSB9O1xyXG5cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID4gMykge1xyXG4gICAgcHJvcHMuc3RhcnRBbmdsZSA9IHN0YXJ0QW5nbGU7XHJcbiAgICBwcm9wcy5lbmRBbmdsZSA9IGVuZEFuZ2xlO1xyXG4gICAgcHJvcHMuY291bnRlcmNsb2Nrd2lzZSA9ICEhY291bnRlcmNsb2Nrd2lzZTtcclxuICB9XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA+IDEpe1xyXG4gICAgcHJvcHMueCA9IHg7XHJcbiAgICBwcm9wcy55ID0geTtcclxuICAgIHByb3BzLnIgPSByO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcInN0cm9rZUFyY1wiLCAgcHJvcHMpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzdHJva2VBcmM7XHJcblxuXG4vKioqLyB9LFxuLyogNTAgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5cclxubGV0IHN0cm9rZVJlY3QgPSAoLi4uYXJncykgPT4gbmV3IEluc3RydWN0aW9uKCdzdHJva2VSZWN0JyxcclxuICBhcmdzLmxlbmd0aCA+IDIgP1xyXG4gICAgeyB4OiBhcmdzWzBdLCB5OiBhcmdzWzFdLCB3aWR0aDogYXJnc1syXSwgaGVpZ2h0OiBhcmdzWzNdIH0gOlxyXG4gICAgeyB4OiAwLCB5OiAwLCB3aWR0aDogYXJnc1swXSwgaGVpZ2h0OiBhcmdzWzFdIH1cclxuKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3Ryb2tlUmVjdDtcclxuXG5cbi8qKiovIH0sXG4vKiA1MSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZFN0cm9rZVN0eWxlJyk7XHJcblxyXG5sZXQgc3Ryb2tlU3R5bGUgPSAodmFsdWUsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgbmV3IEluc3RydWN0aW9uKCdzdHJva2VTdHlsZScsIHsgdmFsdWUgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHN0cm9rZVN0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDUyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBzdHJva2VUZXh0ID0gKC4uLmFyZ3MpID0+IHtcclxuICBsZXQgW3RleHQsIHgsIHksIG1heFdpZHRoXSA9IGFyZ3M7XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA8IDQpIHtcclxuICAgIG1heFdpZHRoID0gbnVsbDtcclxuICB9XHJcbiAgaWYgKGFyZ3MubGVuZ3RoIDwgMykge1xyXG4gICAgeCA9IDA7XHJcbiAgICB5ID0gMDtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignc3Ryb2tlVGV4dCcsIHtcclxuICAgIHRleHQsXHJcbiAgICB4LFxyXG4gICAgeSxcclxuICAgIG1heFdpZHRoXHJcbiAgfSk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHN0cm9rZVRleHQ7XG5cbi8qKiovIH0sXG4vKiA1MyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZFRleHRTdHlsZScpO1xyXG5cclxubGV0IHRleHRTdHlsZSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IHtcclxuICB2YWx1ZSA9IHZhbHVlIHx8IHt9O1xyXG4gIHZhciByZXN1bHQgPSB7XHJcbiAgICBmb250OiBudWxsLFxyXG4gICAgdGV4dEFsaWduOiBudWxsLFxyXG4gICAgdGV4dEJhc2VsaW5lOiBudWxsLFxyXG4gICAgZGlyZWN0aW9uOiBudWxsXHJcbiAgfTtcclxuXHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5mb250ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LmZvbnQgPSB2YWx1ZS5mb250O1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLnRleHRBbGlnbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC50ZXh0QWxpZ24gPSB2YWx1ZS50ZXh0QWxpZ247XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUudGV4dEJhc2VsaW5lICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LnRleHRCYXNlbGluZSA9IHZhbHVlLnRleHRCYXNlbGluZTtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5kaXJlY3Rpb24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuZGlyZWN0aW9uID0gdmFsdWUuZGlyZWN0aW9uO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbigndGV4dFN0eWxlJywgcmVzdWx0KSxcclxuICAgIGNoaWxkcmVuLFxyXG4gICAgZW5kXHJcbiAgXTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdGV4dFN0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDU0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHRyYW5zZm9ybSA9ICh2YWx1ZXMsIC4uLmNoaWxkcmVuKSA9PiB7XHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbigndHJhbnNmb3JtJyxbXHJcbiAgICAgIHZhbHVlc1swXSxcclxuICAgICAgdmFsdWVzWzFdLFxyXG4gICAgICB2YWx1ZXNbMl0sXHJcbiAgICAgIHZhbHVlc1szXSxcclxuICAgICAgdmFsdWVzWzRdLFxyXG4gICAgICB2YWx1ZXNbNV1cclxuICAgIF0pLFxyXG4gICAgY2hpbGRyZW4sXHJcbiAgICBlbmRcclxuICBdO1xyXG59O1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdHJhbnNmb3JtO1xyXG5cblxuLyoqKi8gfSxcbi8qIDU1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHRyYW5zbGF0ZSA9ICh4LCB5LCAuLi5jaGlsZHJlbikgPT4gW1xyXG4gIG5ldyBJbnN0cnVjdGlvbigndHJhbnNsYXRlJywgeyB4OiB4LCB5OiB5IH0pLFxyXG4gIGNoaWxkcmVuLFxyXG4gIGVuZFxyXG5dO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB0cmFuc2xhdGU7XHJcblxuXG4vKioqLyB9LFxuLyogNTYgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG4vLyBTb3VyY2U6IGh0dHA6Ly9qc2ZpZGRsZS5uZXQvdld4OFYvXG4vLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzU2MDMxOTUvZnVsbC1saXN0LW9mLWphdmFzY3JpcHQta2V5Y29kZXNcblxuLyoqXG4gKiBDb25lbmllbmNlIG1ldGhvZCByZXR1cm5zIGNvcnJlc3BvbmRpbmcgdmFsdWUgZm9yIGdpdmVuIGtleU5hbWUgb3Iga2V5Q29kZS5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBrZXlDb2RlIHtOdW1iZXJ9IG9yIGtleU5hbWUge1N0cmluZ31cbiAqIEByZXR1cm4ge01peGVkfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzZWFyY2hJbnB1dCkge1xuICAvLyBLZXlib2FyZCBFdmVudHNcbiAgaWYgKHNlYXJjaElucHV0ICYmICdvYmplY3QnID09PSB0eXBlb2Ygc2VhcmNoSW5wdXQpIHtcbiAgICB2YXIgaGFzS2V5Q29kZSA9IHNlYXJjaElucHV0LndoaWNoIHx8IHNlYXJjaElucHV0LmtleUNvZGUgfHwgc2VhcmNoSW5wdXQuY2hhckNvZGVcbiAgICBpZiAoaGFzS2V5Q29kZSkgc2VhcmNoSW5wdXQgPSBoYXNLZXlDb2RlXG4gIH1cblxuICAvLyBOdW1iZXJzXG4gIGlmICgnbnVtYmVyJyA9PT0gdHlwZW9mIHNlYXJjaElucHV0KSByZXR1cm4gbmFtZXNbc2VhcmNoSW5wdXRdXG5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIChjYXN0IHRvIHN0cmluZylcbiAgdmFyIHNlYXJjaCA9IFN0cmluZyhzZWFyY2hJbnB1dClcblxuICAvLyBjaGVjayBjb2Rlc1xuICB2YXIgZm91bmROYW1lZEtleSA9IGNvZGVzW3NlYXJjaC50b0xvd2VyQ2FzZSgpXVxuICBpZiAoZm91bmROYW1lZEtleSkgcmV0dXJuIGZvdW5kTmFtZWRLZXlcblxuICAvLyBjaGVjayBhbGlhc2VzXG4gIHZhciBmb3VuZE5hbWVkS2V5ID0gYWxpYXNlc1tzZWFyY2gudG9Mb3dlckNhc2UoKV1cbiAgaWYgKGZvdW5kTmFtZWRLZXkpIHJldHVybiBmb3VuZE5hbWVkS2V5XG5cbiAgLy8gd2VpcmQgY2hhcmFjdGVyP1xuICBpZiAoc2VhcmNoLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHNlYXJjaC5jaGFyQ29kZUF0KDApXG5cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIEdldCBieSBuYW1lXG4gKlxuICogICBleHBvcnRzLmNvZGVbJ2VudGVyJ10gLy8gPT4gMTNcbiAqL1xuXG52YXIgY29kZXMgPSBleHBvcnRzLmNvZGUgPSBleHBvcnRzLmNvZGVzID0ge1xuICAnYmFja3NwYWNlJzogOCxcbiAgJ3RhYic6IDksXG4gICdlbnRlcic6IDEzLFxuICAnc2hpZnQnOiAxNixcbiAgJ2N0cmwnOiAxNyxcbiAgJ2FsdCc6IDE4LFxuICAncGF1c2UvYnJlYWsnOiAxOSxcbiAgJ2NhcHMgbG9jayc6IDIwLFxuICAnZXNjJzogMjcsXG4gICdzcGFjZSc6IDMyLFxuICAncGFnZSB1cCc6IDMzLFxuICAncGFnZSBkb3duJzogMzQsXG4gICdlbmQnOiAzNSxcbiAgJ2hvbWUnOiAzNixcbiAgJ2xlZnQnOiAzNyxcbiAgJ3VwJzogMzgsXG4gICdyaWdodCc6IDM5LFxuICAnZG93bic6IDQwLFxuICAnaW5zZXJ0JzogNDUsXG4gICdkZWxldGUnOiA0NixcbiAgJ2NvbW1hbmQnOiA5MSxcbiAgJ2xlZnQgY29tbWFuZCc6IDkxLFxuICAncmlnaHQgY29tbWFuZCc6IDkzLFxuICAnbnVtcGFkIConOiAxMDYsXG4gICdudW1wYWQgKyc6IDEwNyxcbiAgJ251bXBhZCAtJzogMTA5LFxuICAnbnVtcGFkIC4nOiAxMTAsXG4gICdudW1wYWQgLyc6IDExMSxcbiAgJ251bSBsb2NrJzogMTQ0LFxuICAnc2Nyb2xsIGxvY2snOiAxNDUsXG4gICdteSBjb21wdXRlcic6IDE4MixcbiAgJ215IGNhbGN1bGF0b3InOiAxODMsXG4gICc7JzogMTg2LFxuICAnPSc6IDE4NyxcbiAgJywnOiAxODgsXG4gICctJzogMTg5LFxuICAnLic6IDE5MCxcbiAgJy8nOiAxOTEsXG4gICdgJzogMTkyLFxuICAnWyc6IDIxOSxcbiAgJ1xcXFwnOiAyMjAsXG4gICddJzogMjIxLFxuICBcIidcIjogMjIyXG59XG5cbi8vIEhlbHBlciBhbGlhc2VzXG5cbnZhciBhbGlhc2VzID0gZXhwb3J0cy5hbGlhc2VzID0ge1xuICAnd2luZG93cyc6IDkxLFxuICAn4oenJzogMTYsXG4gICfijKUnOiAxOCxcbiAgJ+KMgyc6IDE3LFxuICAn4oyYJzogOTEsXG4gICdjdGwnOiAxNyxcbiAgJ2NvbnRyb2wnOiAxNyxcbiAgJ29wdGlvbic6IDE4LFxuICAncGF1c2UnOiAxOSxcbiAgJ2JyZWFrJzogMTksXG4gICdjYXBzJzogMjAsXG4gICdyZXR1cm4nOiAxMyxcbiAgJ2VzY2FwZSc6IDI3LFxuICAnc3BjJzogMzIsXG4gICdwZ3VwJzogMzMsXG4gICdwZ2RuJzogMzQsXG4gICdpbnMnOiA0NSxcbiAgJ2RlbCc6IDQ2LFxuICAnY21kJzogOTFcbn1cblxuXG4vKiFcbiAqIFByb2dyYW1hdGljYWxseSBhZGQgdGhlIGZvbGxvd2luZ1xuICovXG5cbi8vIGxvd2VyIGNhc2UgY2hhcnNcbmZvciAoaSA9IDk3OyBpIDwgMTIzOyBpKyspIGNvZGVzW1N0cmluZy5mcm9tQ2hhckNvZGUoaSldID0gaSAtIDMyXG5cbi8vIG51bWJlcnNcbmZvciAodmFyIGkgPSA0ODsgaSA8IDU4OyBpKyspIGNvZGVzW2kgLSA0OF0gPSBpXG5cbi8vIGZ1bmN0aW9uIGtleXNcbmZvciAoaSA9IDE7IGkgPCAxMzsgaSsrKSBjb2Rlc1snZicraV0gPSBpICsgMTExXG5cbi8vIG51bXBhZCBrZXlzXG5mb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykgY29kZXNbJ251bXBhZCAnK2ldID0gaSArIDk2XG5cbi8qKlxuICogR2V0IGJ5IGNvZGVcbiAqXG4gKiAgIGV4cG9ydHMubmFtZVsxM10gLy8gPT4gJ0VudGVyJ1xuICovXG5cbnZhciBuYW1lcyA9IGV4cG9ydHMubmFtZXMgPSBleHBvcnRzLnRpdGxlID0ge30gLy8gdGl0bGUgZm9yIGJhY2t3YXJkIGNvbXBhdFxuXG4vLyBDcmVhdGUgcmV2ZXJzZSBtYXBwaW5nXG5mb3IgKGkgaW4gY29kZXMpIG5hbWVzW2NvZGVzW2ldXSA9IGlcblxuLy8gQWRkIGFsaWFzZXNcbmZvciAodmFyIGFsaWFzIGluIGFsaWFzZXMpIHtcbiAgY29kZXNbYWxpYXNdID0gYWxpYXNlc1thbGlhc11cbn1cblxuXG4vKioqLyB9LFxuLyogNTcgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChwb2ludCwgdnMpIHtcbiAgICAvLyByYXktY2FzdGluZyBhbGdvcml0aG0gYmFzZWQgb25cbiAgICAvLyBodHRwOi8vd3d3LmVjc2UucnBpLmVkdS9Ib21lcGFnZXMvd3JmL1Jlc2VhcmNoL1Nob3J0X05vdGVzL3BucG9seS5odG1sXG4gICAgXG4gICAgdmFyIHggPSBwb2ludFswXSwgeSA9IHBvaW50WzFdO1xuICAgIFxuICAgIHZhciBpbnNpZGUgPSBmYWxzZTtcbiAgICBmb3IgKHZhciBpID0gMCwgaiA9IHZzLmxlbmd0aCAtIDE7IGkgPCB2cy5sZW5ndGg7IGogPSBpKyspIHtcbiAgICAgICAgdmFyIHhpID0gdnNbaV1bMF0sIHlpID0gdnNbaV1bMV07XG4gICAgICAgIHZhciB4aiA9IHZzW2pdWzBdLCB5aiA9IHZzW2pdWzFdO1xuICAgICAgICBcbiAgICAgICAgdmFyIGludGVyc2VjdCA9ICgoeWkgPiB5KSAhPSAoeWogPiB5KSlcbiAgICAgICAgICAgICYmICh4IDwgKHhqIC0geGkpICogKHkgLSB5aSkgLyAoeWogLSB5aSkgKyB4aSk7XG4gICAgICAgIGlmIChpbnRlcnNlY3QpIGluc2lkZSA9ICFpbnNpZGU7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBpbnNpZGU7XG59O1xuXG5cbi8qKiovIH0sXG4vKiA1OCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAnYWN0aXZlUmVnaW9ucyc6IF9fd2VicGFja19yZXF1aXJlX18oMTApLFxuICAnYXJjJzogX193ZWJwYWNrX3JlcXVpcmVfXygxMSksXG4gICdhcmNUbyc6IF9fd2VicGFja19yZXF1aXJlX18oMTIpLFxuICAnYmVnaW5QYXRoJzogX193ZWJwYWNrX3JlcXVpcmVfXygyKSxcbiAgJ2JlemllckN1cnZlVG8nOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDEzKSxcbiAgJ2NsZWFyUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oMTQpLFxuICAnY2xpcCc6IF9fd2VicGFja19yZXF1aXJlX18oMTUpLFxuICAnY2xpcFBhdGgnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDE2KSxcbiAgJ2Nsb3NlUGF0aCc6IF9fd2VicGFja19yZXF1aXJlX18oMyksXG4gICdjcmVhdGVSZWd1bGFyUG9seWdvbic6IF9fd2VicGFja19yZXF1aXJlX18oMTcpLFxuICAnY3JlYXRlV3JhcHBlcic6IF9fd2VicGFja19yZXF1aXJlX18oMTgpLFxuICAnY3ljbGVNb3VzZURhdGEnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpLFxuICAnZHJhd0ltYWdlJzogX193ZWJwYWNrX3JlcXVpcmVfXygxOSksXG4gICdlbGxpcHNlJzogX193ZWJwYWNrX3JlcXVpcmVfXygyMCksXG4gICdmaWxsJzogX193ZWJwYWNrX3JlcXVpcmVfXygyMSksXG4gICdmaWxsQXJjJzogX193ZWJwYWNrX3JlcXVpcmVfXygyMiksXG4gICdmaWxsUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oMjMpLFxuICAnZmlsbFN0eWxlJzogX193ZWJwYWNrX3JlcXVpcmVfXygyNCksXG4gICdmaWxsVGV4dCc6IF9fd2VicGFja19yZXF1aXJlX18oMjUpLFxuICAnZ2xvYmFsQWxwaGEnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDI2KSxcbiAgJ2dsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbic6IF9fd2VicGFja19yZXF1aXJlX18oMjcpLFxuICAnaGl0UmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oMjgpLFxuICAnaGl0UmVnaW9uJzogX193ZWJwYWNrX3JlcXVpcmVfXygyOSksXG4gICdpbWFnZVNtb290aGluZ0VuYWJsZWQnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDMwKSxcbiAgJ2luaXRpYWxpemUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDMxKSxcbiAgJ0luc3RydWN0aW9uJzogX193ZWJwYWNrX3JlcXVpcmVfXygwKSxcbiAgJ2ludmVydE1hdHJpeCc6IF9fd2VicGFja19yZXF1aXJlX18oNSksXG4gICdrZXlEYXRhJzogX193ZWJwYWNrX3JlcXVpcmVfXygzMiksXG4gICdsaW5lU3R5bGUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDMzKSxcbiAgJ2xpbmVUbyc6IF9fd2VicGFja19yZXF1aXJlX18oNiksXG4gICdtb3VzZURhdGEnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM0KSxcbiAgJ21vdmVUbyc6IF9fd2VicGFja19yZXF1aXJlX18oNyksXG4gICdtb3ZlVG9MaW5lVG8nOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM1KSxcbiAgJ3BhdGgnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM2KSxcbiAgJ3BsYWNlSG9sZGVyJzogX193ZWJwYWNrX3JlcXVpcmVfXygzNyksXG4gICdwb2ludEluUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oOCksXG4gICdxdWFkcmF0aWNDdXJ2ZVRvJzogX193ZWJwYWNrX3JlcXVpcmVfXygzOCksXG4gICdyYWYnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM5KSxcbiAgJ3JlY3QnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQwKSxcbiAgJ3JlbmRlcic6IF9fd2VicGFja19yZXF1aXJlX18oNDEpLFxuICAncmVzZXRUcmFuc2Zvcm0nOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQyKSxcbiAgJ3JvdGF0ZSc6IF9fd2VicGFja19yZXF1aXJlX18oNDMpLFxuICAnc2NhbGUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ0KSxcbiAgJ3NldFRyYW5zZm9ybSc6IF9fd2VicGFja19yZXF1aXJlX18oOSksXG4gICdzaGFkb3dTdHlsZSc6IF9fd2VicGFja19yZXF1aXJlX18oNDUpLFxuICAnc2tld1gnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ2KSxcbiAgJ3NrZXdZJzogX193ZWJwYWNrX3JlcXVpcmVfXyg0NyksXG4gICdzdHJva2UnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ4KSxcbiAgJ3N0cm9rZUFyYyc6IF9fd2VicGFja19yZXF1aXJlX18oNDkpLFxuICAnc3Ryb2tlUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oNTApLFxuICAnc3Ryb2tlU3R5bGUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDUxKSxcbiAgJ3N0cm9rZVRleHQnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDUyKSxcbiAgJ3RleHRTdHlsZSc6IF9fd2VicGFja19yZXF1aXJlX18oNTMpLFxuICAndHJhbnNmb3JtJzogX193ZWJwYWNrX3JlcXVpcmVfXyg1NCksXG4gICd0cmFuc2Zvcm1Qb2ludHMnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpLFxuICAndHJhbnNsYXRlJzogX193ZWJwYWNrX3JlcXVpcmVfXyg1NSlcbn07XG5cbi8qKiovIH1cbi8qKioqKiovIF0pO1xufSk7Il19 | |
| const rbush = require( "rbush" ); | |
| const ctx = document.createElement( "canvas" ).getContext( "2d" ); | |
| const width = ctx.canvas.width = 800; | |
| const height = ctx.canvas.height = 600; | |
| const e2d = require( "e2d" ); | |
| document.body.appendChild( ctx.canvas ); | |
| const tree = rbush(); | |
| const rects = []; | |
| for ( let i = 0; i < 100; i++ ) { | |
| const rectWidth = 10 + Math.random() * 90; | |
| const rectHeight = 10 + Math.random() * 90; | |
| const minX = 0 + Math.random() * ( width - rectWidth ); | |
| const minY = 0 + Math.random() * ( height - rectHeight ); | |
| const maxX = minX + rectWidth; | |
| const maxY = minY + rectHeight; | |
| const rect = { | |
| rectWidth, | |
| rectHeight, | |
| minX, | |
| minY, | |
| maxX, | |
| maxY, | |
| fill: e2d.fillRect( minX, minY, rectWidth, rectHeight ), | |
| }; | |
| rects.push( e2d.strokeRect( minX, minY, rectWidth, rectHeight ) ); | |
| tree.insert( rect ); | |
| } | |
| e2d.initialize( ctx ); | |
| e2d.raf(frame => { | |
| const { x, y } = e2d.mouseData( ctx ); | |
| const mouseRect = e2d.fillStyle( "red", e2d.strokeRect( x - 10, y - 10, 20, 20 ) ); | |
| e2d.render( | |
| e2d.clearRect( width, height ), | |
| tree.search({ | |
| minX: x - 10, | |
| minY: y - 10, | |
| maxX: x + 10, | |
| maxY: y + 10 | |
| }).map(z => z.fill), | |
| mouseRect, | |
| rects, | |
| ctx | |
| ); | |
| }); | |
| ;}, 0) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "name": "requirebin-sketch", | |
| "version": "1.0.0", | |
| "dependencies": { | |
| "rbush": "2.0.1", | |
| "e2d": "4.0.0-rc.1" | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!-- contents of this file will be placed inside the <body> --> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!-- contents of this file will be placed inside the <head> --> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment